diff options
Diffstat (limited to '')
43 files changed, 44073 insertions, 0 deletions
diff --git a/doc/CONTRIBUTORS b/doc/CONTRIBUTORS new file mode 100644 index 0000000..44e0d35 --- /dev/null +++ b/doc/CONTRIBUTORS @@ -0,0 +1,245 @@ +The following list of people, sorted by last name, have contributed +code or patches to this implementation of sudo since I began +maintaining it in 1993. This list is known to be incomplete--if +you believe you should be listed, please send a note to sudo@sudo.ws. + + Ackeret, Matt + Adler, Mark + Allbery, Russ + Anderson, Jamie + Andrew, Nick + Andric, Dimitry + Barron, Danny + Bates, Tom + Behan, Zdeněk + Bellis, Ray + Benali, Elias + Beverly, Jamie + Boardman, Spider + Bos, Sander + Bostley, P.J. + Bowes, Keith + Boyce, Keith Garry + Brantley, Michael + Braun, Rob + Březina, Pavel + Brooks, Piete + Brown, Jerry + Burr, Michael E + Burton, Ross + Bussjaeger, Andreas + Calvin, Gary + Campbell, Aaron + Chazelas, Stephane + Cheloha, Scott + Čížek, Vítězslav + Coleman, Chris + Corzine, Deven T. + Cusack, Frank + Dai, Wei + Dill, David + Earickson, Jeff + Eckhardt, Drew + Edgington, Ben + Esipovich, Marc + Espie, Marc + Faigon, Ariel + Farrell, Brian + Fobes, Steve + Frysinger, Mike + G., Daniel Richard + Gailly, Jean-loup + Gelman, Stephen + Gerraty, Simon J. + Graber, Stephane + Guillory, B. + Hayman, Randy M. + Henke, Joachim + Hideaki, Yoshifuji + Hieb, Dave + Holloway, Nick + Hoover, Adam + Hunter, Michael T. + Hutchings, Ben + Irrgang, Eric + Jackson, Brian + Jackson, John R. + Jackson, Richard L., Jr. + Janssen, Mark + Jepeway, Chris + Jorge, Joel Peláe + Jover, Guillem + Juhani, Timo + Kikuchi, Ayamura + Kadow, Kevin + Kasal, Stepan + Kienenberger, Mike + King, Dale + King, Michael + Klyachkin, Andrey + Knoble, Jim + Knox, Tim + Komarnitsky, Alek O. + Kondrashov, Nikolai + Kopeček, Daniel + Kranenburg, Paul + Krause, David + Lakin, Eric + Larsen, Case + Levin, Dmitry V. + Libby, Kendall + Lobbes, Phillip E. + McIntyre, Jason + MacKenzie, David J. + McLaughlin, Tom + Makey, Jeff + Mallayya, Sangamesh + Manner, Róbert + Marchionna, Michael D. + Markham, Paul + Martinian, Emin + Meskes, Michael + Michael, David + Miller, Todd C. + Minier, Loïc + Moffat, Darren + Moldung, Jan Thomas + Morris, Charles + Mueller, Andreas + Müller, Dworkin + Nieusma, Jeff + Nikitser, Peter A. + Nussel, Ludwig + Orbán, László + Ouellet, Jean-Philippe + Paquet, Eric + Paradis, Chantal + Pasteleurs, Frederic + Percival, Ted + Perera, Andres + Peron, Christian S.J. + Peschel, Aaron + Peslyak, Alexander + Peterson, Toby + Pettenò, Diego Elio + Pickett, Joel + Plotnick, Alex + de Raadt, Theo + Rasch, Gudleik + Reid, Steve + Richards, Matt + Rossum, Guido van + Rouillard, John P. + Rowe, William A., Jr. + Roy, Alain + Ruusamäe, Elan + Ryabinkin, Eygene + Sato, Yuichi + Sánchez, Wilfredo + Sanders, Miguel + Sasaki, Kan + Saucier, Jean-Francois + Schoenfeld, Patrick + Schuring, Arno + Schwarze, Ingo + Scott, Dougal + Sieger, Nick + Simon, Thor Lancelot + Slemko, Marc + Smith, Andy + Sobrado, Igor + Soulen, Steven + Spangler, Aaron + Spradling, Cloyce D. + Spradling, Michael + Stier, Matthew + Stoeckmann, Tobias + Street, Russell + Stritzky, Tilo + Stroucken, Michael + Tarrall, Robert + Thomas, Matthew + Todd, Giles + Toft, Martin + Torek, Chris + Tucker, Darren + Uhl, Robert + Uzel, Petr + Valery, Reznic + Van Dinter, Theo + Venckus, Martynas + de Vries, Maarten + Wagner, Klaus + Walsh, Dan + Warburton, John + Webb, Kirk + Wetzel, Timm + Wieringen, Marco van + Wilk, Jakub + Winiger, Gary + Wood, David + Zacarias, Gustavo + Zolnowsky, John + +The following people have worked to translate sudo into +other languages as part of the Translation Project, see +https://translationproject.org for more details. + + Albuquerque, Pedro + Blättermann, Mario + Bogusz, Jakub + Buo-ren, Lin + Casagrande, Milo + Castro, Felipe + Cho, Seong-ho + Chornoivan, Yuri + Diéguez, Francisco + Fontenelle, Rafael + García-Fontes, Walter + Gezer, Volkan + Hamasaki, Takeshi + Hamming, Peter + Hansen, Joe + Hantrais, Frédéric + Hein, Jochen + Hufthammer, Karl Ove + Jerovšek, Damir + Karvonen, Jorma + Kazik, Dušan + Kelemen, Gábor + Keçeci, Mehmet + Košir, Klemen + Kozlov, Yuri + Kramer, Jakob + Krznar, Tomislav + Marchal, Frédéric + Margevičius, Algimantas + Maryanov, Pavel + Florentina Mușat + Nurmi, Lauri + Nikolić, Miroslav + Nylander, Daniel + Pan, Yi-Jyun + Písař, Petr + Puente, Enol + Putanec, Božidar + Quân, Trần Ngọc + Rasmussen, Sebastian + Regueiro, Leandro + Sarıer, Özgür + Sendón, Abel + Șerbănescu, Daniel + Sikrom, Åka + Spingos, Dimitris + Taniguchi, Yasuaki + Tomat, Fábio + Úr, Balázs + Uranga, Mikel Olasagasti + Vorotnikov, Artem + Wang, Wylmer + Yang, Boyuan + +The following people designed the artwork used on the sudo website: + + Shield logo: Badger, Trent + Sandwich logo: Stillman, Mark diff --git a/doc/HISTORY b/doc/HISTORY new file mode 100644 index 0000000..0ad9512 --- /dev/null +++ b/doc/HISTORY @@ -0,0 +1,76 @@ +A Brief History of Sudo: + +The Early Years + +Sudo was first conceived and implemented by Bob Coggeshall and Cliff Spencer +around 1980 at the Department of Computer Science at SUNY/Buffalo. It ran on +a VAX-11/750 running 4.1BSD. An updated version, credited to Phil Betchel, +Cliff Spencer, Gretchen Phillips, John LoVerso and Don Gworek, was posted to +the net.sources Usenet newsgroup in December of 1985. + +Sudo at CU-Boulder + +In the Summer of 1986, Garth Snyder released an enhanced version of sudo. +For the next 5 years, sudo was fed and watered by a handful of folks at +CU-Boulder, including Bob Coggeshall, Bob Manchek, and Trent Hein. + +Root Group Sudo + +In 1991, Dave Hieb and Jeff Nieusma wrote a new version of sudo with an +enhanced sudoers format under contract to a consulting firm called "The Root +Group". This version was later released under the GNU public license. + +CU Sudo + +In 1994, after maintaining sudo informally within CU-Boulder for some time, +Todd C. Miller made a public release of "CU sudo" (version 1.3) with bug +fixes and support for more operating systems. The "CU" was added to +differentiate it from the "official" version from "The Root Group". + +In 1995, a new parser for the sudoers file was contributed by Chris Jepeway. +The new parser was a proper grammar (unlike the old one) and could work with +both sudo and visudo (previously they had slightly different parsers). + +In 1996, Todd, who had been maintaining sudo for several years in his spare +time, moved distribution of sudo from a CU-Boulder ftp site to his domain, +courtesan.com. + +Just Plain Sudo + +In 1999, the "CU" prefix was dropped from the name since there had been no +formal release of sudo from "The Root Group" since 1991 (the original +authors now work elsewhere). As of version 1.6, Sudo no longer contains any +of the original "Root Group" code and is available under an ISC-style +license. + +In 2001, the sudo web site, ftp site and mailing lists were moved from +courtesan.com to the sudo.ws domain (sudo.org was already taken). + +LDAP Integration + +In 2003, Nationwide Mutual Insurance Company contributed code written by +Aaron Spangler to store the sudoers data in LDAP. These changes were +incorporated into Sudo 1.6.8. + +New Parser + +In 2005, Todd rewrote the sudoers parser to better support the features that +had been added in the past ten years. This new parser removes some +limitations of the previous one, removes ordering constraints and adds +support for including multiple sudoers files. + +Quest Sponsorship + +In 2010, Quest Software began sponsoring Sudo development by hiring +Todd to work on Sudo as part of his full-time job. This enabled +the addition of I/O logging, the plugin interface, additional +regression tests, support for binary packages and more regular +releases. + +Present Day + +Sudo, in its current form, is maintained by: + + Todd C. Miller <Todd.Miller@sudo.ws> + +Todd continues to enhance sudo and fix bugs. diff --git a/doc/LICENSE b/doc/LICENSE new file mode 100644 index 0000000..60f193f --- /dev/null +++ b/doc/LICENSE @@ -0,0 +1,347 @@ +Sudo is distributed under the following license: + + Copyright (c) 1994-1996, 1998-2021 + 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. + + Sponsored in part by the Defense Advanced Research Projects + Agency (DARPA) and Air Force Research Laboratory, Air Force + Materiel Command, USAF, under agreement number F39502-99-1-0512. + +The Python plugin bindings bear the following license: + + Copyright (c) 2019-2020 Robert Manner <robert.manner@oneidentity.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The files hostcheck.c and hostcheck.h bear the following license: + + Copyright (c) 2020 Laszlo Orban <laszlo.orban@oneidentity.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The file redblack.c bears the following license: + + Copyright (c) 2001 Emin Martinian + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that neither the name of Emin + Martinian nor the names of any contributors are be used to endorse or + promote products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The file sssd.c bears the following license: + + Copyright (c) 2011 Daniel Kopecek <dkopecek@redhat.com> + + This code is derived from software contributed by Aaron Spangler. + + 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. + +The files bsm_audit.c and bsm_audit.h bear the following license: + + Copyright (c) 2009 Christian S.J. Peron + + 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. + +The files solaris_audit.c and solaris_audit.h bear the following license: + + Copyright (c) 2014, Oracle and/or its affiliates. + + 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. + +The file reallocarray.c bears the following license: + + Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> + + 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. + +The files getcwd.c, glob.c, glob.h, snprintf.c and sudo_queue.h bear the +following license: + + Copyright (c) 1989, 1990, 1991, 1993 + The Regents of the University of California. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + +The file fnmatch.c bears the following license: + + Copyright (c) 2011, VMware, Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the VMware, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The file getopt_long.c bears the following license: + + Copyright (c) 2000 The NetBSD Foundation, Inc. + All rights reserved. + + This code is derived from software contributed to The NetBSD Foundation + by Dieter Baron and Thomas Klausner. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +The file inet_pton.c bears the following license: + + Copyright (c) 1996 by Internet Software Consortium. + + 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + CONSORTIUM 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. + +The file arc4random.c bears the following license: + + Copyright (c) 1996, David Mazieres <dm@uun.org> + Copyright (c) 2008, Damien Miller <djm@openbsd.org> + Copyright (c) 2013, Markus Friedl <markus@openbsd.org> + Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org> + + 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. + +The file arc4random_uniform.c bears the following license: + + Copyright (c) 2008, Damien Miller <djm@openbsd.org> + + 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. + +The file getentropy.c bears the following license: + + Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org> + Copyright (c) 2014 Bob Beck <beck@obtuse.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +The embedded copy of zlib bears the following license: + + Copyright (C) 1995-2017 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 + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +The embedded copy of protobuf-c bears the following license: + + Copyright (c) 2008-2018, Dave Benson and the protobuf-c authors. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..e5e89de --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,421 @@ +# +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2010-2015, 2017-2020 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. +# +# @configure_input@ +# + +#### Start of system configuration section. #### + +srcdir = @srcdir@ +abs_srcdir = @abs_srcdir@ +top_srcdir = @top_srcdir@ +abs_top_srcdir = @abs_top_srcdir@ +top_builddir = @top_builddir@ +abs_top_builddir = @abs_top_builddir@ +docdir = @docdir@ +scriptdir = $(top_srcdir)/scripts + +# Tools to use +SED = @SED@ +IGOR = igor +MANDOC = @MANDOCPROG@ +MANCOMPRESS = @MANCOMPRESS@ +MANCOMPRESSEXT = @MANCOMPRESSEXT@ +TR = @TRPROG@ + +# Our install program supports extra flags... +INSTALL = $(SHELL) $(top_srcdir)/install-sh -c +INSTALL_OWNER = -o $(install_uid) -g $(install_gid) + +# Where to install things... +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +sbindir = @sbindir@ +sysconfdir = @sysconfdir@ +libexecdir = @libexecdir@ +datarootdir = @datarootdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ + +# Directory in which to install the man page +mantype = @MANTYPE@ +mansectsu = @mansectsu@ +mansectform = @mansectform@ +mandirexe = $(mandir)/@MANDIRTYPE@1 +mandirsu = $(mandir)/@MANDIRTYPE@$(mansectsu) +mandirform = $(mandir)/@MANDIRTYPE@$(mansectform) + +# User and group ids the installed files should be "owned" by +install_uid = 0 +install_gid = 0 + +# Set to non-empty for development mode +DEVEL = @DEVEL@ + +#### End of system configuration section. #### + +SHELL = @SHELL@ + +DOCS = ./cvtsudoers.$(mantype) ./sudo.$(mantype) ./sudo.conf.$(mantype) \ + ./sudo_logsrvd.$(mantype) ./sudo_logsrv.proto.$(mantype) \ + ./sudo_logsrvd.conf.$(mantype) ./sudo_plugin.$(mantype) \ + ./sudo_plugin_python.$(mantype) ./sudo_sendlog.$(mantype) \ + ./sudoers.$(mantype) ./sudoers.ldap.$(mantype) \ + ./sudoers_timestamp.$(mantype) \ + ./sudoreplay.$(mantype) ./visudo.$(mantype) + +DEVDOCS = $(srcdir)/cvtsudoers.man.in $(srcdir)/sudo.conf.man.in \ + $(srcdir)/sudo.man.in $(srcdir)/sudo_logsrvd.man.in \ + $(srcdir)/sudo_logsrv.proto.man.in \ + $(srcdir)/sudo_logsrvd.conf.man.in \ + $(srcdir)/sudo_plugin.man.in $(srcdir)/sudo_plugin_python.man.in \ + $(srcdir)/sudo_sendlog.man.in $(srcdir)/sudoers.ldap.man.in \ + $(srcdir)/sudoers.man.in $(srcdir)/sudoers_timestamp.man.in \ + $(srcdir)/sudoreplay.man.in $(srcdir)/visudo.man.in + +OTHER_DOCS = $(top_srcdir)/ChangeLog $(top_srcdir)/README \ + $(top_srcdir)/NEWS $(srcdir)/HISTORY $(srcdir)/CONTRIBUTORS \ + $(srcdir)/LICENSE $(srcdir)/TROUBLESHOOTING $(srcdir)/UPGRADE + +OTHER_DOCS_LDAP = $(top_srcdir)/README.LDAP $(srcdir)/schema.* + +VERSION = @PACKAGE_VERSION@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ + +all: $(DEVDOCS) $(DOCS) + +igor: all + @if [ "$(mantype)" != "mdoc" ]; then \ + echo "make igor only supported for mdoc manuals" 1>&2; \ + exit 1; \ + else \ + rval=0; \ + for m in $(DOCS); do \ + echo $(IGOR) -D $$m; \ + $(IGOR) -D $$m || rval=`expr $$rval + $$?`; \ + done; \ + exit $$rval; \ + fi + +lint: all + @if [ "$(mantype)" != "mdoc" ]; then \ + echo "make lint only supported for mdoc manuals" 1>&2; \ + exit 1; \ + else \ + rval=0; \ + for m in $(DOCS); do \ + echo $(MANDOC) -Tlint -Wstyle $$m; \ + $(MANDOC) -Tlint -Wstyle $$m || rval=`expr $$rval + $$?`; \ + done; \ + exit $$rval; \ + fi + +depend: + +Makefile: $(srcdir)/Makefile.in + cd $(top_builddir) && ./config.status --file doc/Makefile + +.SUFFIXES: .man + +$(srcdir)/sudo.man.in: $(srcdir)/sudo.mdoc.in $(srcdir)/sudo.man.in.sed + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e 's/^\(\.nr [A-Z][A-Z]\) .[A-Z][A-Z]MAN./\1 1/' -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -f $(srcdir)/sudo.man.in.sed > $@; \ + fi + +fixman.sed: $(srcdir)/fixman.sh + $(SHELL) $(srcdir)/fixman.sh $@ + +./sudo.man: $(top_builddir)/config.status $(srcdir)/sudo.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo.man.in | $(SED) -f fixman.sed > $@ + +./sudo.mdoc: $(top_builddir)/config.status $(srcdir)/sudo.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/visudo.man.in: $(srcdir)/visudo.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/visudo.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "VISUDO" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./visudo.man: $(top_builddir)/config.status $(srcdir)/visudo.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/visudo.man.in | $(SED) -f fixman.sed > $@ + +./visudo.mdoc: $(top_builddir)/config.status $(srcdir)/visudo.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo.conf.man.in: $(srcdir)/sudo.conf.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e 's/^\(\.nr [A-Z][A-Z]\) .[A-Z][A-Z]MAN./\1 1/' -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo.conf.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO.CONF" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -f $(srcdir)/sudo.conf.man.in.sed > $@; \ + fi + +./sudo.conf.man: $(top_builddir)/config.status $(srcdir)/sudo.conf.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo.conf.man.in | $(SED) -f fixman.sed > $@ + +./sudo.conf.mdoc: $(top_builddir)/config.status $(srcdir)/sudo.conf.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudoers.man.in: $(srcdir)/sudoers.mdoc.in $(srcdir)/sudoers.man.in.sed + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e 's/^\(\.nr [A-Z][A-Z]\) .[A-Z][A-Z]MAN./\1 1/' -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" -f $(srcdir)/sudoers.man.in.sed> $@; \ + fi + +./sudoers.man: $(top_builddir)/config.status $(srcdir)/sudoers.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.man.in | $(SED) -f fixman.sed > $@ + +./sudoers.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers.mdoc.in $(srcdir)/fixmdoc.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.mdoc.in | $(SED) -f $(srcdir)/fixmdoc.sed > $@ + +$(srcdir)/sudoers.ldap.man.in: $(srcdir)/sudoers.ldap.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers.ldap.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS.LDAP" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudoers.ldap.man: $(top_builddir)/config.status $(srcdir)/sudoers.ldap.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers.ldap.man.in | $(SED) -f fixman.sed > $@ + +./sudoers.ldap.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers.ldap.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudoers_timestamp.man.in: $(srcdir)/sudoers_timestamp.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoers_timestamp.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOERS_TIMESTAMP" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudoers_timestamp.man: $(top_builddir)/config.status $(srcdir)/sudoers_timestamp.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoers_timestamp.man.in | $(SED) -f fixman.sed > $@ + +./sudoers_timestamp.mdoc: $(top_builddir)/config.status $(srcdir)/sudoers_timestamp.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/cvtsudoers.man.in: $(srcdir)/cvtsudoers.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/cvtsudoers.mdoc.in | $(MANDOC) -Tman | $(SED) -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./cvtsudoers.man: $(top_builddir)/config.status $(srcdir)/cvtsudoers.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/cvtsudoers.man.in | $(SED) -f fixman.sed > $@ + +./cvtsudoers.mdoc: $(top_builddir)/config.status $(srcdir)/cvtsudoers.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudoreplay.man.in: $(srcdir)/sudoreplay.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudoreplay.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDOREPLAY" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudoreplay.man: $(top_builddir)/config.status $(srcdir)/sudoreplay.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudoreplay.man.in | $(SED) -f fixman.sed > $@ + +./sudoreplay.mdoc: $(top_builddir)/config.status $(srcdir)/sudoreplay.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_logsrvd.man.in: $(srcdir)/sudo_logsrvd.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_logsrvd.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_LOGSRVD" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudo_logsrvd.man: $(top_builddir)/config.status $(srcdir)/sudo_logsrvd.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_logsrvd.man.in | $(SED) -f fixman.sed > $@ + +./sudo_logsrvd.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_logsrvd.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_logsrv.proto.man.in: $(srcdir)/sudo_logsrv.proto.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_logsrv.proto.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_LOGSRV.PROTO" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(5)/($$mansectform)/g" > $@; \ + fi + +./sudo_logsrv.proto.man: $(top_builddir)/config.status $(srcdir)/sudo_logsrv.proto.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_logsrv.proto.man.in | $(SED) -f fixman.sed > $@ + +./sudo_logsrv.proto.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_logsrv.proto.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_logsrvd.conf.man.in: $(srcdir)/sudo_logsrvd.conf.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_logsrvd.conf.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_LOGSRVD.CONF" \)"5"\(.*\)/\1"'$$mansectform'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(5)/($$mansectform)/g" > $@; \ + fi + +./sudo_logsrvd.conf.man: $(top_builddir)/config.status $(srcdir)/sudo_logsrvd.conf.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_logsrvd.conf.man.in | $(SED) -f fixman.sed > $@ + +./sudo_logsrvd.conf.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_logsrvd.conf.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_plugin.man.in: $(srcdir)/sudo_plugin.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_plugin.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_PLUGIN" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudo_plugin.man: $(top_builddir)/config.status $(srcdir)/sudo_plugin.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_plugin.man.in | $(SED) -f fixman.sed > $@ + +./sudo_plugin.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_plugin.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_plugin_python.man.in: $(srcdir)/sudo_plugin_python.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_plugin_python.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_PLUGIN" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudo_plugin_python.man: $(top_builddir)/config.status $(srcdir)/sudo_plugin_python.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_plugin_python.man.in | $(SED) -f fixman.sed > $@ + +./sudo_plugin_python.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_plugin_python.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +$(srcdir)/sudo_sendlog.man.in: $(srcdir)/sudo_sendlog.mdoc.in + @if [ -n "$(DEVEL)" ]; then \ + echo "Generating $@"; \ + mansectsu=`echo @MANSECTSU@|$(TR) A-Z a-z`; \ + mansectform=`echo @MANSECTFORM@|$(TR) A-Z a-z`; \ + $(SED) -e "s/$$mansectsu/8/g" -e "s/$$mansectform/5/g" $(srcdir)/sudo_sendlog.mdoc.in | $(MANDOC) -Tman | $(SED) -e 's/^\(\.TH "SUDO_SENDLOG" \)"8"\(.*\)/\1"'$$mansectsu'"\2/' -e "s/(5)/($$mansectform)/g" -e "s/(8)/($$mansectsu)/g" > $@; \ + fi + +./sudo_sendlog.man: $(top_builddir)/config.status $(srcdir)/sudo_sendlog.man.in fixman.sed + (cd $(top_builddir) && $(SHELL) config.status --file=-) < $(srcdir)/sudo_sendlog.man.in | $(SED) -f fixman.sed > $@ + +./sudo_sendlog.mdoc: $(top_builddir)/config.status $(srcdir)/sudo_sendlog.mdoc.in + cd $(top_builddir) && $(SHELL) config.status --file=doc/$@ + +pre-install: + +install: install-doc + +install-dirs: + $(SHELL) $(scriptdir)/mkinstalldirs $(DESTDIR)$(docdir) \ + $(DESTDIR)$(mandirexe) $(DESTDIR)$(mandirform) $(DESTDIR)$(mandirsu) + +install-binaries: + +install-includes: + +install-doc: install-dirs + for f in $(OTHER_DOCS); do $(INSTALL) $(INSTALL_OWNER) -m 0644 $$f $(DESTDIR)$(docdir); done + @LDAP@for f in $(OTHER_DOCS_LDAP); do $(INSTALL) $(INSTALL_OWNER) -m 0644 $$f $(DESTDIR)$(docdir); done + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./cvtsudoers.$(mantype) $(DESTDIR)$(mandirexe)/cvtsudoers.1 + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo.$(mantype) $(DESTDIR)$(mandirsu)/sudo.$(mansectsu) + @LOGSRV@$(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_logsrvd.$(mantype) $(DESTDIR)$(mandirsu)/sudo_logsrvd.$(mansectsu) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_plugin.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu) + @PYTHON_PLUGIN@$(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_plugin_python.$(mantype) $(DESTDIR)$(mandirsu)/sudo_plugin_python.$(mansectsu) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_sendlog.$(mantype) $(DESTDIR)$(mandirsu)/sudo_sendlog.$(mansectsu) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudoreplay.$(mantype) $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./visudo.$(mantype) $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo.conf.$(mantype) $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) + @LOGSRV@$(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_logsrv.proto.$(mantype) $(DESTDIR)$(mandirform)/sudo_logsrv.proto.$(mansectform) + @LOGSRV@$(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudo_logsrvd.conf.$(mantype) $(DESTDIR)$(mandirform)/sudo_logsrvd.conf.$(mansectform) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudoers.$(mantype) $(DESTDIR)$(mandirform)/sudoers.$(mansectform) + $(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudoers_timestamp.$(mantype) $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform) + @LDAP@$(INSTALL) $(INSTALL_OWNER) -m 0644 ./sudoers.ldap.$(mantype) $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) + @if test -n "$(MANCOMPRESS)"; then \ + for f in $(mandirexe)/cvtsudoers.1 $(mandirsu)/sudo.$(mansectsu) $(mandirsu)/sudo_logsrvd.$(mansectsu) $(mandirsu)/sudo_plugin.$(mansectsu) $(mandirsu)/sudo_plugin_python.$(mansectsu) $(mandirsu)/sudo_sendlog.$(mansectsu) $(mandirsu)/sudoreplay.$(mansectsu) $(mandirsu)/visudo.$(mansectsu) $(mandirform)/sudo.conf.$(mansectform) $(mandirform)/sudo_logsrv.proto.$(mansectform) $(mandirform)/sudo_logsrvd.conf.$(mansectform) $(mandirform)/sudoers.$(mansectform) $(mandirform)/sudoers_timestamp.$(mansectform) $(mandirform)/sudoers.ldap.$(mansectform); do \ + if test -f $(DESTDIR)$$f; then \ + echo $(MANCOMPRESS) -f $(DESTDIR)$$f; \ + $(MANCOMPRESS) -f $(DESTDIR)$$f; \ + fi; \ + done; \ + rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ + echo ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ + ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \ + else \ + rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ + echo ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ + ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \ + fi + +install-plugin: + +uninstall: + -rm -rf $(DESTDIR)$(docdir) + -rm -f $(DESTDIR)$(mandirexe)/cvtsudoers.1 \ + $(DESTDIR)$(mandirsu)/sudo.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudo_logsrvd.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudo_plugin.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudo_plugin_python.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudo_sendlog.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/sudoreplay.$(mansectsu) \ + $(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \ + $(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \ + $(DESTDIR)$(mandirform)/sudo_logsrv.proto.$(mansectform) \ + $(DESTDIR)$(mandirform)/sudo_logsrvd.conf.$(mansectform) \ + $(DESTDIR)$(mandirform)/sudoers.$(mansectform) \ + $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform) + $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) + +splint: + +cppcheck: + +pvs-log-files: + +pvs-studio: + +check: + +clean: + -rm -f fixman.sed + +mostlyclean: clean + +distclean: clean + -rm -rf Makefile config.log *.man *.mdoc + +clobber: distclean + +realclean: distclean + +cleandir: distclean diff --git a/doc/TROUBLESHOOTING b/doc/TROUBLESHOOTING new file mode 100644 index 0000000..bc7f1a6 --- /dev/null +++ b/doc/TROUBLESHOOTING @@ -0,0 +1,295 @@ +Troubleshooting tips and FAQ for Sudo +===================================== + +Q) When I run configure, it says "C compiler cannot create executables". +A) This usually means you either don't have a working compiler. This + could be due to the lack of a license or that some component of the + compiler suite could not be found. Check config.log for clues as + to why this is happening. On many systems, compiler components live + in /usr/ccs/bin which may not be in your PATH environment variable. + +Q) When I run configure, it says "sudo requires the 'ar' utility to build". +A) As part of the build process, sudo creates a temporary library containing + objects that are shared amongst the different sudo executables. + On Unix systems, the "ar" utility is used to do this. This error + indicates that "ar" is missing on your system. On Solaris systems, + you may need to install the SUNWbtool package. On other systems + "ar" may be included in the GNU binutils package. + +Q) Sudo compiles and installs OK but when I try to run it I get: + /usr/local/bin/sudo must be owned by uid 0 and have the setuid bit set +A) Sudo must be setuid root to do its work. Either /usr/local/bin/sudo + is not owned by uid 0 or the setuid bit is not set. This should have + been done for you by "make install" but you can fix it manually by + running the following as root: + # chown root /usr/local/bin/sudo; chmod 4755 /usr/local/bin/sudo + +Q) Sudo compiles and installs OK but when I try to run it I get: + effective uid is not 0, is /usr/local/bin/sudo on a file system with the + 'nosuid' option set or an NFS file system without root privileges? +A) The owner and permissions on the sudo binary appear to be OK but when + sudo ran, the setuid bit did not have an effect. There are two common + causes for this. The first is that the file system the sudo binary + is located on is mounted with the 'nosuid' mount option, which disables + setuid binaries. The output of the "mount" command should tell you if + the file system is mounted with the 'nosuid' option. The other possible + cause is that sudo is installed on an NFS-mounted file system that is + exported without root privileges. By default, NFS file systems are + exported with uid 0 mapped to a non-privileged uid (usually -2). You + should be able to determine whether sudo is located on an NFS-mounted + filesystem by running "df `which sudo'". + +Q) Sudo never gives me a chance to enter a password using PAM, it just + says 'Sorry, try again.' three times and exits. +A) You didn't setup PAM to work with sudo. On RedHat Linux or Fedora + Core this generally means installing the sample pam.conf file as + /etc/pam.d/sudo. See the example pam.conf file for hints on what + to use for other Linux systems. + +Q) Sudo says 'Account expired or PAM config lacks an "account" + section for sudo, contact your system administrator' and exits + but I know my account has not expired. +A) Your PAM config lacks an "account" specification. On Linux this + usually means you are missing a line like: + account required pam_unix.so + in /etc/pam.d/sudo. + +Q) Sudo is setup to log via syslog(3) but I'm not getting any log + messages. +A) Make sure you have an entry in your syslog.conf file to save + the sudo messages (see the example syslog.conf file). The default + log facility is authpriv (changeable via configure or in sudoers). + Don't forget to send a SIGHUP to your syslogd so that it re-reads + its conf file. Also, remember that syslogd does *not* create + log files, you need to create the file before syslogd will log + to it (ie: touch /var/log/sudo). + Note: the facility (e.g. "auth.debug") must be separated from the + destination (e.g. "/var/log/auth" or "@loghost") by + tabs, *not* spaces. This is a common error. + +Q) When sudo asks me for my password it never accepts what I enter even + though I know I entered my password correctly. +A) If you are not using pam and your system uses shadow passwords, + it is possible that sudo didn't properly detect that shadow + passwords are in use. Take a look at the generated config.h + file and verify that the C function used for shadow password + look ups was detected. For instance, for SVR4-style shadow + passwords, HAVE_GETSPNAM should be defined (you can search for + the string "shadow passwords" in config.h with your editor). + Note that there is no define for 4.4BSD-based shadow passwords + since that just uses the standard getpw* routines. + +Q) Can sudo use the ssh agent for authentication instead of asking + for the user's Unix password? +A) Not directly, but you can use a PAM module like pam_ssh_agent_auth + or pam_ssh for this purpose. + +Q) I don't want the sudoers file in /etc, how can I specify where it + should go? +A) Use the --sysconfdir option to configure. Ie: + configure --sysconfdir=/dir/you/want/sudoers/in + +Q) Can I put the sudoers file in NIS/NIS+ or do I have to have a + copy on each machine? +A) There is no support for making an NIS/NIS+ map/table out of + the sudoers file at this time. You can distribute the sudoers + file via rsync or rdist. It is also possible to NFS-mount the + sudoers file. If you use LDAP at your site you may be interested + in sudo's LDAP sudoers support, see the README.LDAP file and the + sudoers.ldap manual. + +Q) I don't run sendmail on my machine. Does this mean that I cannot + use sudo? +A) No, you just need to disable mailing with a line like: + Defaults !mailerpath + in your sudoers file or run configure with the --without-sendmail + option. + +Q) When I run visudo it uses vi as the editor and I hate vi. How + can I make it use another editor? +A) You can specify the editor to use in visudo in the sudoers file. + See the "editor" and "env_editor" entries in the sudoers manual. + The defaults can also be set at configure time using the + --with-editor and --with-env-editor configure options. + +Q) Sudo appears to be removing some variables from the environment, why? +A) By default, sudo runs commands with a new, minimal environment. + The "env_keep" setting in sudoers can be used to control which + environment variables are preserved from the invoking user's + environment via the "env_keep" setting in sudoers. + + While it is possible to disable the "env_reset" setting, which + will preserve all environment variables that don't match a black + list, doing so is strongly discouraged. See the "Command + environment" section of the sudoers manual for more information. + +Q) Why does sudo reset the HOME environment variable? +A) Many programs use the HOME environment variable to locate + configuration and data files. Often, these configuration files + are treated as trusted input that affects how the program operates. + By controlling the configuration files, a user may be able to + cause the program to execute other commands without sudo's + restrictions or logging. + + Some programs perform extra checks when the real and effective + user-IDs differ, but because sudo runs commands with all user-IDs + set to the target user, these checks are insufficient. + + While it is possible to preserve the value of the HOME environment + variable by adding it to the "env_keep" list in the sudoers file, + doing so is strongly discouraged. Users wishing to edit files + with sudo should run sudoedit (or sudo -e) to get their accustomed + editor configuration instead of invoking the editor directly. + +Q) How can I keep sudo from asking for a password? +A) To specify this on a per-user (and per-command) basis, use the + 'NOPASSWD' tag right before the command list in sudoers. See + the sudoers man page and examples/sudoers for details. To disable + passwords completely, add !authenticate" to the Defaults line + in /etc/sudoers. You can also turn off authentication on a + per-user or per-host basis using a user or host-specific Defaults + entry in sudoers. To hard-code the global default, you can + configure with the --without-passwd option. + +Q) When I run configure, it dies with the following error: + "no acceptable cc found in $PATH". +A) /usr/ucb/cc was the only C compiler that configure could find. + You need to tell configure the path to the "real" C compiler + via the --with-CC option. On Solaris, the path is probably + something like "/opt/SUNWspro/SC4.0/bin/cc". If you have gcc + that will also work. + +Q) When I run configure, it dies with the following error: + Fatal Error: config.cache exists from another platform! + Please remove it and re-run configure. +A) configure caches the results of its tests in a file called + config.cache to make re-running configure speedy. However, + if you are building sudo for a different platform the results + in config.cache will be wrong so you need to remove config.cache. + You can do this by "rm config.cache" or "make realclean". + Note that "make realclean" will also remove any object files + and configure temp files that are laying around as well. + +Q) I built sudo on a Solaris 11 (or higher) machine but the resulting + binary doesn't work older Solaris versions. Why? +A) Starting with Solaris 11, asprintf(3) is included in the standard + C library. To build a version of sudo on a Solaris 11 machine that + will run on an older Solaris release, edit config.h and comment out + the lines: + #define HAVE_ASPRINTF 1 + #define HAVE_VASPRINTF 1 + and run make. + +Q) When I run "visudo" it says "sudoers file busy, try again later." + and doesn't do anything. +A) Someone else is currently editing the sudoers file with visudo. + +Q) When I try to use "cd" with sudo it says "cd: command not found". +A) "cd" is a shell built-in command, you can't run it as a command + since a child process (sudo) cannot affect the current working + directory of the parent (your shell). + +Q) When I try to use "cd" with sudo the command completes without + errors but nothing happens. +A) Even though "cd" is a shell built-in command, some operating systems + include a /usr/bin/cd command for some reason. A standalone + "cd" command is totally useless since a child process (cd) cannot + affect the current working directory of the parent (your shell). + Thus, "sudo cd /foo" will start a child process, change the + directory and immediately exit without doing anything useful. + +Q) When I run sudo it says I am not allowed to run the command as root + but I don't want to run it as root, I want to run it as another user. + My sudoers file entry looks like: + bob ALL=(oracle) ALL +A) The default user sudo tries to run things as is always root, even if + the invoking user can only run commands as a single, specific user. + This may change in the future but at the present time you have to + work around this using the 'runas_default' option in sudoers. + For example: + Defaults:bob runas_default=oracle + would achieve the desired result for the preceding sudoers fragment. + +Q) When I try to run sudo via ssh, I get the error: + sudo: a terminal is required to read the password; either use the -S + option to read from standard input or configure an askpass helper +A) If sudo needs to authenticate a user, it requires access to the user's + terminal to disable echo so the password is not displayed to the screen. + The above message indicates that no terminal was present. + + When running a command via ssh, a terminal is not allocated by default + which can cause this message. The "-t" option to ssh will force it to + allocate a tty. Alternately, you may be able to use the ssh-askpass + utility to prompt for the password if X11 forwarding is enabled and an + askpass helper is configured in the sudo.conf file. If you do not mind + your password being echoed to the screen, you may use sudo's -S option + to read the password from the standard input. Alternately, you may set + the "visiblepw" sudoers option which will allow the password to be entered + even when echo cannot be disabled, though this is not recommended. + +Q) When I try to use SSL-enabled LDAP with sudo I get an error: + unable to initialize SSL cert and key db: security library: bad database. + you must set TLS_CERT in /etc/ldap.conf to use SSL +A) On systems that use a Mozilla-derived LDAP SDK there must be a + certificate database in place to use SSL-encrypted LDAP connections. + This file is usually /var/ldap/cert8.db or /etc/ldap/cert8.db. + The actual number after "cert" will vary, depending on the version + of the LDAP SDK that is being used. If you do not have a certificate + database you can either copy one from a mozilla-derived browser, such + as firefox, or create one using the "certutil" command. You can run + "certutil" as follows and press the <return> (or <enter>) key at the + password prompt: + # certutil -N -d /var/ldap + Enter a password which will be used to encrypt your keys. + The password should be at least 8 characters long, + and should contain at least one non-alphabetic character. + + Enter new password: <return> + Re-enter password: <return> + +Q) On HP-UX, the umask setting in sudoers has no effect. +A) If your /etc/pam.conf file has the libpam_hpsec.so.1 session module + enabled, you may need to a add line like the following to pam.conf: + sudo session required libpam_hpsec.so.1 bypass_umask + +Q) When I run "sudo -i shell_alias" I get "command not found" even + though the alias is defined in my shell startup files. +A) Commands run via "sudo -i" are executed by the shell in + non-interactive mode. The bash shell will only parse aliases in + interactive mode unless the "expand_aliases" shell option is + set. If you add "shopt -s expand_aliases" to your .bash_profile + (or .profile if using that instead) the aliases should now be + available to "sudo -i". + +Q) When I run sudo on AIX I get the following error: + setuidx(ID_EFFECTIVE|ID_REAL|ID_SAVED, ROOT_UID): Operation not permitted. +A) AIX's Enhanced RBAC is preventing sudo from running. To fix + this, add the following entry to /etc/security/privcmds (adjust + the path to sudo as needed) and run the setkst command as root: + + /usr/local/bin/sudo: + accessauths = ALLOW_ALL + innateprivs = PV_DAC_GID,PV_DAC_R,PV_DAC_UID,PV_DAC_X,PV_FS_CHOWN,PV_PROC_PRIO,PV_NET_PORT,PV_NET_CNTL,PV_SU_UID + secflags = FSF_EPS + +Q) Sudo configures and builds without error but when I run it I get + a Segmentation fault. +A) If you are on a Linux system, the first thing to try is to run + configure with the --disable-pie option, then "make clean" and + "make". If that fixes the problem then your operating system + does not properly support position independent executables. + Please send a message to sudo@sudo.ws with system details such + as the Linux distro, kernel version and CPU architecture. + +Q) When I run configure I get the following error: + dlopen present but libtool doesn't appear to support your platform. +A) Libtool doesn't know how to support dynamic linking on the operating + system you are building for. If you are cross-compiling, you need to + specify the operating system, not just the CPU type. For example: + --host powerpc-unknown-linux + instead of just: + --host powerpc + +Q) How do you pronounce `sudo'? +A) The official pronunciation is soo-doo (for su "do"). However, an + alternate pronunciation, a homophone of "pseudo", is also common. diff --git a/doc/UPGRADE b/doc/UPGRADE new file mode 100644 index 0000000..7d03777 --- /dev/null +++ b/doc/UPGRADE @@ -0,0 +1,534 @@ +Notes on upgrading from an older release +======================================== + +o Upgrading from a version prior to 1.9.3: + + Due to the addition of the CHROOT and CWD options, it is no + longer possible to declare an alias with one of those names. + If a sudoers file has an alias with one of those names, sudo + and visudo will report a syntax error with a message like + "syntax error: unexpected CHROOT, expecting ALIAS". + + Starting with version 1.9.3, sudoers rules must end in either + a newline or the end-of-file. This makes it possible to provide + better error messages. Previously, it was possible to include + multiple rules on a single line, separated by white space. + + Starting with version 1.9.3, sudo will attempt to recover from + a syntax error in the sudoers file by discarding the portion + of the line that contains the error until the end of the line. + To restore the historic behavior of refusing to run when a + syntax error is encountered, add "error_recovery=false" as a + plugin option in sudo.conf for the "sudoers_audit" plugin, (or + "sudoers_policy" if there is no "sudoers_audit" plugin configured). + +o Upgrading from a version prior to 1.9.1: + + Starting with version 1.9.1, sudoers plugin arguments in sudo.conf + should be specified for the "sudoers_audit" plugin, not + "sudoers_policy". This is because the sudoers file is now + opened and parsed by the "sudoers_audit" plugin. Previously, + this was done by the "sudoers_policy" plugin. The use of an + audit plugin makes it possible for the sudoers module to detect + when a command has been rejected by an approval plugin and only + log commands that are allowed by both policy and approval + plugins. + +o Upgrading from a version prior to 1.8.30: + + Starting with version 1.8.30, sudo will no longer allow commands + to be run as a user or group ID that is not in the password or + group databases by default. Previously, sudo would always allow + unknown user or group IDs if the sudoers entry permitted it, + including via the "ALL" alias. The old behavior can be restored + by setting the new "allow_unknown_runas_id" Defaults setting + in the sudoers file. + +o Upgrading from a version prior to 1.8.29: + + Starting with version 1.8.29, if the umask is explicitly set + in sudoers, that value is used regardless of the umask specified + by PAM or login.conf. However, if the umask is not explicitly + set in sudoers, PAM or login.conf may now override the default + sudoers umask. Previously, the sudoers umask always overrode + the umask set by PAM, which was not the documented behavior. + +o Upgrading from a version prior to 1.8.28: + + Starting with version 1.8.28, sudo stores the signal that caused + a command to be suspended or resumed as a string in the I/O log + timing file. The version of sudoreplay included with sudo + 1.8.28 can process either type of I/O log file but older versions + of sudoreplay are unable to replay the newer logs. + + Starting with version 1.8.28, sudoedit honors the umask and + umask_override settings in sudoers. Previously, the user's + umask was used as-is. + +o Upgrading from a version prior to 1.8.26: + + Starting with version 1.8.26, sudo no long sets the USERNAME + environment variable when running commands. This is a non-standard + environment variable that was set on some older Linux systems. + Sudo still sets the LOGNAME, USER and, on AIX systems, LOGIN + environment variables. + + Handling of the LOGNAME, USER (and on AIX, LOGIN) environment + variables has changed slightly in version 1.8.26. Sudo now + treats those variables as a single unit. This means that if + one variable is preserved or removed from the environment using + env_keep, env_check or env_delete, the others are too. + +o Upgrading from a version prior to 1.8.23: + + In sudo 1.8.23 the "sudoers2ldif" script and the "visudo -x" + functionality has been superseded by the "cvtsudoers" utility. + The cvtsudoers utility is intended to be a drop-in replacement + for "sudoers2ldif". Because it uses the same parser as sudo + and visudo, cvtsudoers can perform a more accurate conversion + than sudoers2ldif could. + + To convert a sudoers file to JSON, the format option must be + specified. For example, instead of: + + visudo -f sudoers_file -x output_file + + one would use: + + cvtsudoers -f json -o output_file sudoers_file + + Note that unlike "visudo -x", "cvtsudoers" reads from the + standard input by default. Also, the base DN may be specified + on the command line, if desired, using the -b option. + +o Upgrading from a version prior to 1.8.20: + + Due to the addition of the TIMEOUT, NOTBEFORE and NOTAFTTER + options, it is no longer possible to declare an alias with one + of those names. If a sudoers file has an alias with one of + those names, sudo and visudo will report a syntax error with a + message like "syntax error: unexpected TIMEOUT, expecting ALIAS". + + Starting with version 1.9.3, sudoers rules must end in either + Prior to version 1.8.20, when log_input, log_output or use_pty + were enabled, if any of the standard input, output or error + were not connected to a terminal, sudo would use a pipe. The + pipe allows sudo to interpose itself between the old standard + input, output or error and log the contents. Beginning with + version 1.8.20, a pipe is only used when I/O logging is enabled. + If use_pty is set without log_input or log_output, no pipe will + be used. Additionally, if log_input is set without log_output, + a pipe is only used for the standard input. Likewise, if + log_output is set without log_input, a pipe is only used for + the standard output and standard error. This results in a + noticeable change in behavior if the use_pty flag is set and no + terminal is present when running commands such as scripts that + execute other commands asynchronously (in the background). + Previously, sudo would exit immediately, causing background + commands to terminate with a broken pipe if they attempt to + write to the standard output or standard error. As of version + 1.8.20, a pipe will not be used in this case so the command + will no longer be terminated. + +o Upgrading from a version prior to 1.8.16: + + When editing files with sudoedit, files in a directory that is + writable by the invoking user may no longer be edited by default. + Also, sudoedit will refuse to follow a symbolic link in the + path to be edited if that directory containing the link is + writable by the user. This behavior can be disabled by negating + the sudoedit_checkdir sudoers option, which is now enabled by + default. + +o Upgrading from a version prior to 1.8.15: + + Prior to version 1.8.15, when env_reset was enabled (the default) + and the -s option was not used, the SHELL environment variable + was set to the shell of the invoking user. In 1.8.15 and above, + when env_reset is enabled and the -s option is not used, SHELL + is set based on the target user. + + When editing files with sudoedit, symbolic links will no longer + be followed by default. The old behavior can be restored by + enabling the sudoedit_follow option in sudoers or on a per-command + basis with the FOLLOW and NOFOLLOW tags. + + Prior to version 1.8.15, groups listed in sudoers that were not + found in the system group database were passed to the group + plugin, if any. Starting with 1.8.15, only groups of the form + %:group are resolved via the group plugin by default. The old + behavior can be restored by using the always_query_group_plugin + sudoers option. + + Locking of the time stamp file has changed in sudo 1.8.15. + Previously, the user's entire time stamp file was locked while + retrieving and updating a time stamp record. Now, only a single + record, specific to the tty or parent process ID, is locked. + This lock is held while the user enters their password. If + sudo is suspended at the password prompt (or run in the + background), the lock is dropped until sudo is resumed, at which + point it will be reacquired. This allows sudo to be used in a + pipeline even when a password is required--only one instance + of sudo will prompt for a password. + +o Upgrading from a version prior to 1.8.14: + + On HP-UX, sudo will no longer check for "plugin.sl" if "plugin.so" + is specified but does not exist. This was a temporary hack for + backward compatibility with Sudo 1.8.6 and below when the + plugin path name was not listed in sudo.conf. A plugin path + name that explicitly ends in ".sl" will still work as expected. + +o Upgrading from a version prior to 1.8.12: + + On Solaris, sudo is now able to determine the NIS domain name. + As a result, if you had previously been using netgroups that + do not include the domain, you will need to either set the + domain in the entry or leave the domain part of the tuple blank. + + For example, the following will no longer work: + my-hosts (foo,-,-) (bar,-,-) (baz,-,-) + and should be changed to: + my-hosts (foo,-,) (bar,-,) (baz,-,) + +o Upgrading from a version prior to 1.8.10: + + The time stamp file format has changed in sudo 1.8.10. There + is now a single time stamp file for each user, even when tty-based + time stamps are used. Each time stamp file may contain multiple + records to support tty-based time stamps as well as multiple + authentication users. On systems that support it, monotonic + time is stored instead of wall clock time. As a result, it is + important that the time stamp files not persist when the system + reboots. For this reason, the default location for the time + stamp files has changed back to a directory located in /var/run. + Systems that do not have /var/run (e.g. AIX) or that do not clear + it on boot (e.g. HP-UX) will need to clear the time stamp + directory via a start up script. Such a script is installed by + default on AIX and HP-UX systems. + + Because there is now a single time stamp file per user, the -K + option will remove all of the user's time stamps, not just the + time stamp for the current terminal. + + Lecture status is now stored separately from the time stamps + in a separate directory: /var/db/sudo/lectured, /var/lib/sudo/lectured + or /var/adm/sudo/lectured depending on what is present on the + system. + + LDAP-based sudoers now uses a default search filter of + (objectClass=sudoRole) for more efficient queries. It is + possible to disable the default search filter by specifying + SUDOERS_SEARCH_FILTER in ldap.conf but omitting a value. + +o Upgrading from a version prior to 1.8.7: + + Sudo now stores its libexec files in a "sudo" sub-directory + instead of in libexec itself. For backward compatibility, if + the plugin is not found in the default plugin directory, sudo + will check the parent directory default directory ends in "/sudo". + + The default sudo plugins now all use the .so extension, regardless + of the extension used by system shared libraries. For backward + compatibility, sudo on HP-UX will also search for a plugin with + an .sl extension if the .so version is not found. + + Handling of users belonging to a large number of groups has + changed. Previously, sudo would only use the group list from + the kernel unless the system_group plugin was enabled in sudoers. + Now, sudo will query the groups database if the user belongs + to the maximum number of groups supported by the kernel. See + the group_source and max_groups settings in the sudo.conf manual + for details. + +o Upgrading from a version prior to 1.8.2: + + When matching Unix groups in the sudoers file, sudo will now + match based on the name of the group as it appears in sudoers + instead of the group-ID. This can substantially reduce the + number of group lookups for sudoers files that contain a large + number of groups. There are a few side effects of this change. + + 1) Unix groups with different names but the same group-ID are + can no longer be used interchangeably. Sudo will look up all + of a user's groups by group-ID and use the resulting group + names when matching sudoers entries. If there are multiple + groups with the same ID, the group name returned by the + system getgrgid() library function is the name that will be + used when matching sudoers entries. + + 2) Unix group names specified in the sudoers file that are + longer than the system maximum will no longer match. For + instance, if there is a Unix group "fireflie" on a system + where group names are limited to eight characters, "%fireflies" + in sudoers will no longer match "fireflie". Previously, a + lookup by name of the group "fireflies" would have matched + the "fireflie" group on most systems. + + The legacy group matching behavior may be restored by enabling + the match_group_by_gid Defaults option in sudoers available + in sudo 1.8.18 and higher. + +o Upgrading from a version prior to 1.8.1: + + Changes in the sudoers parser could result in parse errors for + existing sudoers file. These changes cause certain erroneous + entries to be flagged as errors where before they allowed. + Changes include: + + Combining multiple Defaults entries with a backslash. E.g. + + Defaults set_path \ + Defaults syslog + + which should be: + + Defaults set_path + Defaults syslog + + Also, double-quoted strings with a missing end-quote are now + detected and result in an error. Previously, text starting a + double quote and ending with a newline was ignored. E.g. + + Defaults set_path"foo + + In previous versions of sudo, the `"foo' portion would have + been ignored. + + To avoid problems, sudo 1.8.1's "make install" will not install + a new sudo binary if the existing sudoers file has errors. + + In Sudo 1.8.1 the "noexec" functionality has moved out of the + sudoers policy plugin and into the sudo front-end. As a result, + the path to the noexec file is now specified in the sudo.conf + file instead of the sudoers file. If you have a sudoers file + that uses the "noexec_file" option, you will need to move the + definition to the sudo.conf file instead. + + Old style in /etc/sudoers: + Defaults noexec_file=/usr/local/libexec/sudo_noexec.so + + New style in /etc/sudo.conf: + Path noexec /usr/local/libexec/sudo_noexec.so + +o Upgrading from a version prior to 1.8.0: + + Starting with version 1.8.0, sudo uses a modular framework to + support policy and I/O logging plugins. The default policy + plugin is "sudoers" which provides the traditional sudoers + evaluation and I/O logging. Plugins are typically located in + /usr/libexec or /usr/local/libexec, though this is system-dependent. + The sudoers plugin is named "sudoers.so" on most systems. + + The sudo.conf file, usually stored in /etc, is used to configure + plugins. This file is optional--if no plugins are specified + in sudo.conf, the "sudoers" plugin is used. See the example + sudo.conf file in the doc directory or refer to the updated + sudo manual to see how to configure sudo.conf. + + The "askpass" setting has moved from the sudoers file to the + sudo.conf file. If you have a sudoers file that uses the + "askpass" option, you will need to move the definition to the + sudo.conf file. + + Old style in /etc/sudoers: + Defaults askpass=/usr/X11R6/bin/ssh-askpass + + New style in /etc/sudo.conf: + Path askpass /usr/X11R6/bin/ssh-askpass + +o Upgrading from a version prior to 1.7.5: + + Sudo 1.7.5 includes an updated LDAP schema with support for + the sudoNotBefore, sudoNotAfter and sudoOrder attributes. + + The sudoNotBefore and sudoNotAfter attribute support is only + used when the SUDOERS_TIMED setting is enabled in ldap.conf. + If enabled, those attributes are used directly when constructing + an LDAP filter. As a result, your LDAP server must have the + updated schema if you want to use sudoNotBefore and sudoNotAfter. + + The sudoOrder support does not affect the LDAP filter sudo + constructs and so there is no need to explicitly enable it in + ldap.conf. If the sudoOrder attribute is not present in an + entry, a value of 0 is used. If no entries contain sudoOrder + attributes, the results are in whatever order the LDAP server + returns them, as in past versions of sudo. + + Older versions of sudo will simply ignore the new attributes + if they are present in an entry. There are no compatibility + problems using the updated schema with older versions of sudo. + +o Upgrading from a version prior to 1.7.4: + + Starting with sudo 1.7.4, the time stamp files have moved from + /var/run/sudo to either /var/db/sudo, /var/lib/sudo or /var/adm/sudo. + The directories are checked for existence in that order. This + prevents users from receiving the sudo lecture every time the + system reboots. Time stamp files older than the boot time are + ignored on systems where it is possible to determine this. + + Additionally, the tty_tickets sudoers option is now enabled by + default. To restore the old behavior (single time stamp per user), + add a line like: + Defaults !tty_tickets + to sudoers or use the --without-tty-tickets configure option. + + The HOME and MAIL environment variables are now reset based on the + target user's password database entry when the env_reset sudoers option + is enabled (which is the case in the default configuration). Users + wishing to preserve the original values should use a sudoers entry like: + Defaults env_keep += HOME + to preserve the old value of HOME and + Defaults env_keep += MAIL + to preserve the old value of MAIL. + + NOTE: preserving HOME has security implications since many programs + use it when searching for configuration files. Adding HOME to env_keep + may enable a user to run unrestricted commands via sudo. + + The default syslog facility has changed from "local2" to "authpriv" + (or "auth" if the operating system doesn't have "authpriv"). + The --with-logfac configure option can be used to change this + or it can be changed in the sudoers file. + +o Upgrading from a version prior to 1.7.0: + + Starting with sudo 1.7.0, comments in the sudoers file must not + have a digit or minus sign immediately after the comment character + ('#'). Otherwise, the comment may be interpreted as a user or + group-ID. + + When sudo is build with LDAP support the /etc/nsswitch.conf file is + now used to determine the sudoers sea ch order. sudo will default to + only using /etc/sudoers unless /etc/nsswitch.conf says otherwise. + This can be changed with an nsswitch.conf line, e.g.: + sudoers: ldap files + Would case LDAP to be searched first, then the sudoers file. + To restore the pre-1.7.0 behavior, run configure with the + --with-nsswitch=no flag. + + Sudo now ignores user .ldaprc files as well as system LDAP defaults. + All LDAP configuration is now in /etc/ldap.conf (or whichever file + was specified by configure's --with-ldap-conf-file option). + If you are using TLS, you may now need to specify: + tls_checkpeer no + in sudo's ldap.conf unless ldap.conf references a valid certificate + authority file(s). + + Please also see the NEWS file for a list of new features in + sudo 1.7.0. + +o Upgrading from a version prior to 1.6.9: + + Starting with sudo 1.6.9, if an OS supports a modular authentication + method such as PAM, it will be used by default by configure. + + Environment variable handling has changed significantly in sudo + 1.6.9. Prior to version 1.6.9, sudo would preserve the user's + environment, pruning out potentially dangerous variables. + Beginning with sudo 1.6.9, the environment is reset to a default + set of values with only a small number of "safe" variables + preserved. To preserve specific environment variables, add + them to the "env_keep" list in sudoers. E.g. + + Defaults env_keep += "EDITOR" + + The old behavior can be restored by negating the "env_reset" + option in sudoers. E.g. + + Defaults !env_reset + + There have also been changes to how the "env_keep" and + "env_check" options behave. + + Prior to sudo 1.6.9, the TERM and PATH environment variables + would always be preserved even if the env_keep option was + redefined. That is no longer the case. Consequently, if + env_keep is set with "=" and not simply appended to (i.e. using + "+="), PATH and TERM must be explicitly included in the list + of environment variables to keep. The LOGNAME, SHELL, USER, + and USERNAME environment variables are still always set. + + Additionally, the env_check setting previously had no effect + when env_reset was set (which is now on by default). Starting + with sudo 1.6.9, environment variables listed in env_check are + also preserved in the env_reset case, provided that they do not + contain a '/' or '%' character. Note that it is not necessary + to also list a variable in env_keep--having it in env_check is + sufficient. + + The default lists of variables to be preserved and/or checked + are displayed when sudo is run by root with the -V flag. + +o Upgrading from a version prior to 1.6.8: + + Prior to sudo 1.6.8, if /var/run did not exist, sudo would put + the time stamp files in /tmp/.odus. As of sudo 1.6.8, the + time stamp files will be placed in /var/adm/sudo or /usr/adm/sudo + if there is no /var/run directory. This directory will be + created if it does not already exist. + + Previously, a sudoers entry that explicitly prohibited running + a command as a certain user did not override a previous entry + allowing the same command. This has been fixed in sudo 1.6.8 + such that the last match is now used (as it is documented). + Hopefully no one was depending on the previous (buggy) behavior. + +o Upgrading from a version prior to 1.6: + + As of sudo 1.6, parsing of runas entries and the NOPASSWD tag + has changed. Prior to 1.6, a runas specifier applied only to + a single command directly following it. Likewise, the NOPASSWD + tag only allowed the command directly following it to be run + without a password. Starting with sudo 1.6, both the runas + specifier and the NOPASSWD tag are "sticky" for an entire + command list. So, given the following line in sudo < 1.6 + + millert ALL=(daemon) NOPASSWD:/usr/bin/whoami,/bin/ls + + millert would be able to run /usr/bin/whoami as user daemon + without a password and /bin/ls as root with a password. + + As of sudo 1.6, the same line now means that millert is able + to run run both /usr/bin/whoami and /bin/ls as user daemon + without a password. To expand on this, take the following + example: + + millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, (root) /bin/ls, \ + /sbin/dump + + millert can run /usr/bin/whoami as daemon and /bin/ls and + /sbin/dump as root. No password need be given for either + command. In other words, the "(root)" sets the default runas + user to root for the rest of the list. If we wanted to require + a password for /bin/ls and /sbin/dump the line could be written + as: + + millert ALL=(daemon) NOPASSWD:/usr/bin/whoami, \ + (root) PASSWD:/bin/ls, /sbin/dump + + Additionally, sudo now uses a per-user time stamp directory + instead of a time stamp file. This allows tty time stamps to + simply be files within the user's time stamp dir. For the + default, non-tty case, the time stamp on the directory itself + is used. + + Also, the temporary file used by visudo is now /etc/sudoers.tmp + since some versions of vipw on systems with shadow passwords use + /etc/stmp for the temporary shadow file. + +o Upgrading from a version prior to 1.5: + + By default, sudo expects the sudoers file to be mode 0440 and + to be owned by user and group 0. This differs from version 1.4 + and below which expected the sudoers file to be mode 0400 and + to be owned by root. Doing a `make install' will set the sudoers + file to the new mode and group. If sudo encounters a sudoers + file with the old permissions it will attempt to update it to + the new scheme. You cannot, however, use a sudoers file with + the new permissions with an old sudo binary. It is suggested + that if have a means of distributing sudo you distribute the + new binaries first, then the new sudoers file (or you can leave + sudoers as is and sudo will fix the permissions itself as long + as sudoers is on a local file system). diff --git a/doc/cvtsudoers.man.in b/doc/cvtsudoers.man.in new file mode 100644 index 0000000..f1a8e91 --- /dev/null +++ b/doc/cvtsudoers.man.in @@ -0,0 +1,513 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2018 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. +.\" +.TH "CVTSUDOERS" "1" "December 11, 2018" "Sudo @PACKAGE_VERSION@" "General Commands Manual" +.nh +.if n .ad l +.SH "NAME" +\fBcvtsudoers\fR +\- convert between sudoers file formats +.SH "SYNOPSIS" +.HP 11n +\fBcvtsudoers\fR +[\fB\-ehMpV\fR] +[\fB\-b\fR\ \fIdn\fR] +[\fB\-c\fR\ \fIconf_file\fR] +[\fB\-d\fR\ \fIdeftypes\fR] +[\fB\-f\fR\ \fIoutput_format\fR] +[\fB\-i\fR\ \fIinput_format\fR] +[\fB\-I\fR\ \fIincrement\fR] +[\fB\-m\fR\ \fIfilter\fR] +[\fB\-o\fR\ \fIoutput_file\fR] +[\fB\-O\fR\ \fIstart_point\fR] +[\fB\-P\fR\ \fIpadding\fR] +[\fB\-s\fR\ \fIsections\fR] +[\fIinput_file\fR] +.SH "DESCRIPTION" +\fBcvtsudoers\fR +can be used to convert between +\fIsudoers\fR +security policy file formats. +The default input format is sudoers. +The default output format is LDIF. +It is only possible to convert a +\fIsudoers\fR +file that is syntactically correct. +.PP +If no +\fIinput_file\fR +is specified, or if it is +\(oq-\(cq, +the policy is read from the standard input. +By default, the result is written to the standard output. +.PP +The options are as follows: +.TP 12n +\fB\-b\fR \fIdn\fR, \fB\--base\fR=\fIdn\fR +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. +If this option is not specified, the value of the +\fRSUDOERS_BASE\fR +environment variable will be used instead. +Only necessary when converting to LDIF format. +.TP 12n +\fB\-c\fR \fIconf_file\fR, \fB\--config\fR=\fIconf_file\fR +Specify the path to the configuration file. +Defaults to +\fI@sysconfdir@/cvtsudoers.conf\fR. +.TP 12n +\fB\-d\fR \fIdeftypes\fR, \fB\--defaults\fR=\fIdeftypes\fR +Only convert +\fRDefaults\fR +entries of the specified types. +One or more +\fRDefaults\fR +types may be specified, separated by a comma +(\(oq\&,\(cq). +The supported types are: +.PP +.RS 12n +.PD 0 +.TP 10n +all +All Defaults entries. +.PD +.TP 10n +global +Global Defaults entries that are applied regardless of +user, runas, host or command. +.TP 10n +user +Per-user Defaults entries. +.TP 10n +runas +Per-runas user Defaults entries. +.TP 10n +host +Per-host Defaults entries. +.TP 10n +command +Per-command Defaults entries. +.PP +See the +\fBDefaults\fR +section in +sudoers(@mansectform@) +for more information. +.sp +If the +\fB\-d\fR +option is not specified, all +\fRDefaults\fR +entries will be converted. +.RE +.TP 12n +\fB\-e\fR, \fB\--expand-aliases\fR +Expand aliases in +\fIinput_file\fR. +Aliases are preserved by default when the output +\fIformat\fR +is JSON or sudoers. +.TP 12n +\fB\-f\fR \fIoutput_format\fR, \fB\--output-format\fR=\fIoutput_format\fR +Specify the output format (case-insensitive). +The following formats are supported: +.PP +.RS 12n +.PD 0 +.TP 10n +JSON +JSON (JavaScript Object Notation) files are usually easier for +third-party applications to consume than the traditional +\fIsudoers\fR +format. +The various values have explicit types which removes much of the +ambiguity of the +\fIsudoers\fR +format. +.PD +.TP 10n +LDIF +LDIF (LDAP Data Interchange Format) files can be imported into an LDAP +server for use with +sudoers.ldap(@mansectform@). +.sp +Conversion to LDIF has the following limitations: +.PP +.RS 10n +.PD 0 +.TP 3n +\fB\(bu\fR +Command, host, runas and user-specific Defaults lines cannot be +translated as they don't have an equivalent in the sudoers LDAP schema. +.PD +.TP 3n +\fB\(bu\fR +Command, host, runas and user aliases are not supported by the +sudoers LDAP schema so they are expanded during the conversion. +.PD 0 +.PP +.RE +.PD +.TP 10n +sudoers +Traditional sudoers format. +A new sudoers file will be reconstructed from the parsed input file. +Comments are not preserved and data from any include files will be +output inline. +.PD 0 +.PP +.RE +.PD +.TP 12n +\fB\-h\fR, \fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-i\fR \fIinput_format\fR, \fB\--input-format\fR=\fIinput_format\fR +Specify the input format. +The following formats are supported: +.PP +.RS 12n +.PD 0 +.TP 10n +LDIF +LDIF (LDAP Data Interchange Format) files can be exported from an LDAP +server to convert security policies used by +sudoers.ldap(@mansectform@). +If a base DN (distinguished name) is specified, only sudoRole objects +that match the base DN will be processed. +Not all sudoOptions specified in a sudoRole can be translated from +LDIF to sudoers format. +.PD +.TP 10n +sudoers +Traditional sudoers format. +This is the default input format. +.PD 0 +.PP +.RE +.PD +.TP 12n +\fB\-I\fR \fIincrement\fR, \fB\--increment\fR=\fIincrement\fR +When generating LDIF output, increment each sudoOrder attribute by +the specified number. +Defaults to an increment of 1. +.TP 12n +\fB\-m\fR \fIfilter\fR, \fB\--match\fR=\fIfilter\fR +Only output rules that match the specified +\fIfilter\fR. +A +\fIfilter\fR +expression is made up of one or more +\fBkey =\fR \fIvalue\fR +pairs, separated by a comma +(\(oq\&,\(cq). +The +\fBkey\fR +may be +\(lquser\(rq, +\(lqgroup\(rq +or +\(lqhost\(rq. +For example, +\fBuser\fR = \fIoperator\fR +or +\fBhost\fR = \fIwww\fR. +An upper-case User_Alias or Host_Alias may be specified as the +\(lquser\(rq +or +\(lqhost\(rq. +.sp +A matching +\fIsudoers\fR +rule may also include users, groups and hosts that are not part of the +\fIfilter\fR. +This can happen when a rule includes multiple users, groups or hosts. +To prune out any non-matching user, group or host from the rules, the +\fB\-p\fR +option may be used. +.sp +By default, the password and group databases are not consulted when matching +against the filter so the users and groups do not need to be present +on the local system (see the +\fB\-M\fR +option). +Only aliases that are referenced by the filtered policy rules will +be displayed. +.TP 12n +\fB\-M\fR, \fB\--match-local\fR +When the +\fB\-m\fR +option is also specified, use password and group database information +when matching users and groups in the filter. +Only users and groups in the filter that exist on the local system will match, +and a user's groups will automatically be added to the filter. +If the +\fB\-M\fR +is +\fInot\fR +specified, users and groups in the filter do not need to exist on the +local system, but all groups used for matching must be explicitly listed +in the filter. +.TP 12n +\fB\-o\fR \fIoutput_file\fR, \fB\--output\fR=\fIoutput_file\fR +Write the converted output to +\fIoutput_file\fR. +If no +\fIoutput_file\fR +is specified, or if it is +\(oq-\(cq, +the converted +\fIsudoers\fR +policy will be written to the standard output. +.TP 12n +\fB\-O\fR \fIstart_point\fR, \fB\--order-start\fR=\fIstart_point\fR +When generating LDIF output, use the number specified by +\fIstart_point\fR +in the sudoOrder attribute of the first sudoRole object. +Subsequent sudoRole object use a sudoOrder value generated by adding an +\fIincrement\fR, +see the +\fB\-I\fR +option for details. +Defaults to a starting point of 1. +A starting point of 0 will disable the generation of sudoOrder +attributes in the resulting LDIF file. +.TP 12n +\fB\-p\fR, \fB\--prune-matches\fR +When the +\fB\-m\fR +option is also specified, +\fBcvtsudoers\fR +will prune out non-matching users, groups and hosts from +matching entries. +.TP 12n +\fB\-P\fR \fIpadding\fR, \fB\--padding\fR=\fIpadding\fR +When generating LDIF output, construct the initial sudoOrder value by +concatenating +\fIorder_start\fR +and +\fIincrement\fR, +padding the +\fIincrement\fR +with zeros until it consists of +\fIpadding\fR +digits. +For example, if +\fIorder_start\fR +is 1027, +\fIpadding\fR +is 3, and +\fIincrement\fR +is 1, the value of sudoOrder for the first entry will be 1027000, +followed by 1027001, 1027002, etc. +If the number of sudoRole entries is larger than the padding would allow, +\fBcvtsudoers\fR +will exit with an error. +By default, no padding is performed. +.TP 12n +\fB\-s\fR \fIsections\fR, \fB\--suppress\fR=\fIsections\fR +Suppress the output of specific +\fIsections\fR +of the security policy. +One or more section names may be specified, separated by a comma +(\(oq\&,\(cq). +The supported section name are: +\fBdefaults\fR, +\fBaliases\fR +and +\fBprivileges\fR +(which may be shortened to +\fBprivs\fR). +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBcvtsudoers\fR +and +\fIsudoers\fR +grammar versions and exit. +.PP +Options in the form +\(lqkeyword = value\(rq +may also be specified in a configuration file, +\fI@sysconfdir@/cvtsudoers.conf\fR +by default. +The following keywords are recognized: +.TP 6n +\fBdefaults =\fR \fIdeftypes\fR +See the description of the +\fB\-d\fR +command line option. +.TP 6n +\fBexpand_aliases =\fR \fIyes\fR | \fIno\fR +See the description of the +\fB\-e\fR +command line option. +.TP 6n +\fBinput_format =\fR \fIldif\fR | \fIsudoers\fR +See the description of the +\fB\-i\fR +command line option. +.TP 6n +\fBmatch =\fR \fIfilter\fR +See the description of the +\fB\-m\fR +command line option. +.TP 6n +\fBorder_increment =\fR \fIincrement\fR +See the description of the +\fB\-I\fR +command line option. +.TP 6n +\fBorder_start =\fR \fIstart_point\fR +See the description of the +\fB\-O\fR +command line option. +.TP 6n +\fBoutput_format =\fR \fIjson\fR | \fIldif\fR | \fIsudoers\fR +See the description of the +\fB\-f\fR +command line option. +.TP 6n +\fBpadding =\fR \fIpadding\fR +See the description of the +\fB\-P\fR +command line option. +.TP 6n +\fBprune_matches =\fR \fIyes\fR | \fIno\fR +See the description of the +\fB\-p\fR +command line option. +.TP 6n +\fBsudoers_base =\fR \fIdn\fR +See the description of the +\fB\-b\fR +command line option. +.TP 6n +\fBsuppress =\fR \fIsections\fR +See the description of the +\fB\-s\fR +command line option. +.PP +Options on the command line will override values from the +configuration file. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/cvtsudoers.conf\fR +default configuration for cvtsudoers +.SH "EXAMPLES" +Convert +\fI/etc/sudoers\fR +to LDIF (LDAP Data Interchange Format) where the +\fIldap.conf\fR +file uses a +\fIsudoers_base\fR +of my-domain,dc=com, storing the result in +\fIsudoers.ldif\fR: +.nf +.sp +.RS 6n +$ cvtsudoers -b ou=SUDOers,dc=my-domain,dc=com -o sudoers.ldif \e + /etc/sudoers +.RE +.fi +.PP +Convert +\fI/etc/sudoers\fR +to JSON format, storing the result in +\fIsudoers.json\fR: +.nf +.sp +.RS 6n +$ cvtsudoers -f json -o sudoers.json /etc/sudoers +.RE +.fi +.PP +Parse +\fI/etc/sudoers\fR +and display only rules that match user +\fIambrose\fR +on host +\fIhastur\fR: +.nf +.sp +.RS 6n +$ cvtsudoers -f sudoers -m user=ambrose,host=hastur /etc/sudoers +.RE +.fi +.PP +Same as above, but expand aliases and prune out any non-matching +users and hosts from the expanded entries. +.nf +.sp +.RS 6n +$ cvtsudoers -ep -f sudoers -m user=ambrose,host=hastur /etc/sudoers +.RE +.fi +.PP +Convert +\fIsudoers.ldif\fR +from LDIF to traditional +\fIsudoers\fR +format: +.nf +.sp +.RS 6n +$ cvtsudoers -i ldif -f sudoers -o sudoers.new sudoers.ldif +.RE +.fi +.SH "SEE ALSO" +sudoers(@mansectform@), +sudoers.ldap(@mansectform@), +sudo(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBcvtsudoers\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBcvtsudoers\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/cvtsudoers.mdoc.in b/doc/cvtsudoers.mdoc.in new file mode 100644 index 0000000..b24f363 --- /dev/null +++ b/doc/cvtsudoers.mdoc.in @@ -0,0 +1,439 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2018 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. +.\" +.Dd December 11, 2018 +.Dt CVTSUDOERS 1 +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm cvtsudoers +.Nd convert between sudoers file formats +.Sh SYNOPSIS +.Nm cvtsudoers +.Op Fl ehMpV +.Op Fl b Ar dn +.Op Fl c Ar conf_file +.Op Fl d Ar deftypes +.Op Fl f Ar output_format +.Op Fl i Ar input_format +.Op Fl I Ar increment +.Op Fl m Ar filter +.Op Fl o Ar output_file +.Op Fl O Ar start_point +.Op Fl P Ar padding +.Op Fl s Ar sections +.Op Ar input_file +.Sh DESCRIPTION +.Nm +can be used to convert between +.Em sudoers +security policy file formats. +The default input format is sudoers. +The default output format is LDIF. +It is only possible to convert a +.Em sudoers +file that is syntactically correct. +.Pp +If no +.Ar input_file +is specified, or if it is +.Ql - , +the policy is read from the standard input. +By default, the result is written to the standard output. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl b Ar dn , Fl -base Ns = Ns Ar dn +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 . +If this option is not specified, the value of the +.Ev SUDOERS_BASE +environment variable will be used instead. +Only necessary when converting to LDIF format. +.It Fl c Ar conf_file , Fl -config Ns = Ns Ar conf_file +Specify the path to the configuration file. +Defaults to +.Pa @sysconfdir@/cvtsudoers.conf . +.It Fl d Ar deftypes , Fl -defaults Ns = Ns Ar deftypes +Only convert +.Li Defaults +entries of the specified types. +One or more +.Li Defaults +types may be specified, separated by a comma +.Pq Ql \&, . +The supported types are: +.Bl -tag -width 8n +.It all +All Defaults entries. +.It global +Global Defaults entries that are applied regardless of +user, runas, host or command. +.It user +Per-user Defaults entries. +.It runas +Per-runas user Defaults entries. +.It host +Per-host Defaults entries. +.It command +Per-command Defaults entries. +.El +.Pp +See the +.Sy Defaults +section in +.Xr sudoers @mansectform@ +for more information. +.Pp +If the +.Fl d +option is not specified, all +.Li Defaults +entries will be converted. +.It Fl e , Fl -expand-aliases +Expand aliases in +.Ar input_file . +Aliases are preserved by default when the output +.Ar format +is JSON or sudoers. +.It Fl f Ar output_format , Fl -output-format Ns = Ns Ar output_format +Specify the output format (case-insensitive). +The following formats are supported: +.Bl -tag -width 8n +.It JSON +JSON (JavaScript Object Notation) files are usually easier for +third-party applications to consume than the traditional +.Em sudoers +format. +The various values have explicit types which removes much of the +ambiguity of the +.Em sudoers +format. +.It LDIF +LDIF (LDAP Data Interchange Format) files can be imported into an LDAP +server for use with +.Xr sudoers.ldap @mansectform@ . +.Pp +Conversion to LDIF has the following limitations: +.Bl -bullet -width 1n +.It +Command, host, runas and user-specific Defaults lines cannot be +translated as they don't have an equivalent in the sudoers LDAP schema. +.It +Command, host, runas and user aliases are not supported by the +sudoers LDAP schema so they are expanded during the conversion. +.El +.It sudoers +Traditional sudoers format. +A new sudoers file will be reconstructed from the parsed input file. +Comments are not preserved and data from any include files will be +output inline. +.El +.It Fl h , Fl -help +Display a short help message to the standard output and exit. +.It Fl i Ar input_format , Fl -input-format Ns = Ns Ar input_format +Specify the input format. +The following formats are supported: +.Bl -tag -width 8n +.It LDIF +LDIF (LDAP Data Interchange Format) files can be exported from an LDAP +server to convert security policies used by +.Xr sudoers.ldap @mansectform@ . +If a base DN (distinguished name) is specified, only sudoRole objects +that match the base DN will be processed. +Not all sudoOptions specified in a sudoRole can be translated from +LDIF to sudoers format. +.It sudoers +Traditional sudoers format. +This is the default input format. +.El +.It Fl I Ar increment , Fl -increment Ns = Ns Ar increment +When generating LDIF output, increment each sudoOrder attribute by +the specified number. +Defaults to an increment of 1. +.It Fl m Ar filter , Fl -match Ns = Ns Ar filter +Only output rules that match the specified +.Ar filter . +A +.Ar filter +expression is made up of one or more +.Sy key = Ar value +pairs, separated by a comma +.Pq Ql \&, . +The +.Sy key +may be +.Dq user , +.Dq group +or +.Dq host . +For example, +.Sy user No = Ar operator +or +.Sy host No = Ar www . +An upper-case User_Alias or Host_Alias may be specified as the +.Dq user +or +.Dq host . +.Pp +A matching +.Em sudoers +rule may also include users, groups and hosts that are not part of the +.Ar filter . +This can happen when a rule includes multiple users, groups or hosts. +To prune out any non-matching user, group or host from the rules, the +.Fl p +option may be used. +.Pp +By default, the password and group databases are not consulted when matching +against the filter so the users and groups do not need to be present +on the local system (see the +.Fl M +option). +Only aliases that are referenced by the filtered policy rules will +be displayed. +.It Fl M , Fl -match-local +When the +.Fl m +option is also specified, use password and group database information +when matching users and groups in the filter. +Only users and groups in the filter that exist on the local system will match, +and a user's groups will automatically be added to the filter. +If the +.Fl M +is +.Em not +specified, users and groups in the filter do not need to exist on the +local system, but all groups used for matching must be explicitly listed +in the filter. +.It Fl o Ar output_file , Fl -output Ns = Ns Ar output_file +Write the converted output to +.Ar output_file . +If no +.Ar output_file +is specified, or if it is +.Ql - , +the converted +.Em sudoers +policy will be written to the standard output. +.It Fl O Ar start_point , Fl -order-start Ns = Ns Ar start_point +When generating LDIF output, use the number specified by +.Ar start_point +in the sudoOrder attribute of the first sudoRole object. +Subsequent sudoRole object use a sudoOrder value generated by adding an +.Ar increment , +see the +.Fl I +option for details. +Defaults to a starting point of 1. +A starting point of 0 will disable the generation of sudoOrder +attributes in the resulting LDIF file. +.It Fl p , Fl -prune-matches +When the +.Fl m +option is also specified, +.Nm +will prune out non-matching users, groups and hosts from +matching entries. +.It Fl P Ar padding , Fl -padding Ns = Ns Ar padding +When generating LDIF output, construct the initial sudoOrder value by +concatenating +.Ar order_start +and +.Ar increment , +padding the +.Ar increment +with zeros until it consists of +.Ar padding +digits. +For example, if +.Ar order_start +is 1027, +.Ar padding +is 3, and +.Ar increment +is 1, the value of sudoOrder for the first entry will be 1027000, +followed by 1027001, 1027002, etc. +If the number of sudoRole entries is larger than the padding would allow, +.Nm +will exit with an error. +By default, no padding is performed. +.It Fl s Ar sections , Fl -suppress Ns = Ns Ar sections +Suppress the output of specific +.Ar sections +of the security policy. +One or more section names may be specified, separated by a comma +.Pq Ql \&, . +The supported section name are: +.Sy defaults , +.Sy aliases +and +.Sy privileges +(which may be shortened to +.Sy privs ) . +.It Fl V , -version +Print the +.Nm +and +.Em sudoers +grammar versions and exit. +.El +.Pp +Options in the form +.Dq keyword = value +may also be specified in a configuration file, +.Pa @sysconfdir@/cvtsudoers.conf +by default. +The following keywords are recognized: +.Bl -tag -width 4n +.It Sy defaults = Ar deftypes +See the description of the +.Fl d +command line option. +.It Sy expand_aliases = Ar yes | no +See the description of the +.Fl e +command line option. +.It Sy input_format = Ar ldif | sudoers +See the description of the +.Fl i +command line option. +.It Sy match = Ar filter +See the description of the +.Fl m +command line option. +.It Sy order_increment = Ar increment +See the description of the +.Fl I +command line option. +.It Sy order_start = Ar start_point +See the description of the +.Fl O +command line option. +.It Sy output_format = Ar json | ldif | sudoers +See the description of the +.Fl f +command line option. +.It Sy padding = Ar padding +See the description of the +.Fl P +command line option. +.It Sy prune_matches = Ar yes | no +See the description of the +.Fl p +command line option. +.It Sy sudoers_base = Ar dn +See the description of the +.Fl b +command line option. +.It Sy suppress = Ar sections +See the description of the +.Fl s +command line option. +.El +.Pp +Options on the command line will override values from the +configuration file. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/cvtsudoers.conf +default configuration for cvtsudoers +.El +.Sh EXAMPLES +Convert +.Pa /etc/sudoers +to LDIF (LDAP Data Interchange Format) where the +.Pa ldap.conf +file uses a +.Em sudoers_base +of my-domain,dc=com, storing the result in +.Pa sudoers.ldif : +.Bd -literal -offset indent +$ cvtsudoers -b ou=SUDOers,dc=my-domain,dc=com -o sudoers.ldif \e + /etc/sudoers +.Ed +.Pp +Convert +.Pa /etc/sudoers +to JSON format, storing the result in +.Pa sudoers.json : +.Bd -literal -offset indent +$ cvtsudoers -f json -o sudoers.json /etc/sudoers +.Ed +.Pp +Parse +.Pa /etc/sudoers +and display only rules that match user +.Em ambrose +on host +.Em hastur : +.Bd -literal -offset indent +$ cvtsudoers -f sudoers -m user=ambrose,host=hastur /etc/sudoers +.Ed +.Pp +Same as above, but expand aliases and prune out any non-matching +users and hosts from the expanded entries. +.Bd -literal -offset indent +$ cvtsudoers -ep -f sudoers -m user=ambrose,host=hastur /etc/sudoers +.Ed +.Pp +Convert +.Pa sudoers.ldif +from LDIF to traditional +.Em sudoers +format: +.Bd -literal -offset indent +$ cvtsudoers -i ldif -f sudoers -o sudoers.new sudoers.ldif +.Ed +.Sh SEE ALSO +.Xr sudoers @mansectform@ , +.Xr sudoers.ldap @mansectform@ , +.Xr sudo @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/fixman.sh b/doc/fixman.sh new file mode 100755 index 0000000..c22b58c --- /dev/null +++ b/doc/fixman.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# SPDX-License-Identifier: ISC +# +# Copyright (c) 2012-2014, 2017 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. +# + +OUTFILE="$1" +rm -f "$OUTFILE" +> "$OUTFILE" + +# HP-UX friendly header/footer for all man pages +if [ X"`uname 2>&1`" = X"HP-UX" ]; then + cat >>"$OUTFILE" <<-'EOF' + s/^\.TH \("[^"]*"\) \("[^"]*"\) "\([^"]*\)" "\([^"]*\)" \("[^"]*"\)/.TH \1 \2\ + .ds )H \4\ + .ds ]W \3/ +EOF +fi + +# Replace "0 minutes" with "unlimited" +cat >>"$OUTFILE" <<-'EOF' + /^\\fR0\\fR$/ { + N + s/^\\fR0\\fR\nminutes\.$/unlimited./ + } +EOF diff --git a/doc/fixmdoc.sed b/doc/fixmdoc.sed new file mode 100644 index 0000000..3d57216 --- /dev/null +++ b/doc/fixmdoc.sed @@ -0,0 +1,5 @@ +# Replace "0 minutes" with "unlimited" +/^\.Li 0$/ { + N + s/^\.Li 0\nminutes\.$/unlimited./ +} diff --git a/doc/schema.ActiveDirectory b/doc/schema.ActiveDirectory new file mode 100644 index 0000000..f488eef --- /dev/null +++ b/doc/schema.ActiveDirectory @@ -0,0 +1,255 @@ +#
+# Active Directory Schema for sudo configuration (sudoers)
+#
+# To extend your Active Directory schema, run one of the following command
+# on your Windows DC (default port - Active Directory):
+#
+# ldifde -i -f schema.ActiveDirectory -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# or on your Windows DC if using another port (with Active Directory LightWeight Directory Services / ADAM-Active Directory Application Mode)
+# Port 50000 by example (or any other port specified when defining the ADLDS/ADAM instance
+#
+# ldifde -i -f schema.ActiveDirectory -t 50000 -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# or
+#
+# ldifde -i -f schema.ActiveDirectory -s server:port -c "CN=Schema,CN=Configuration,DC=X" #schemaNamingContext
+#
+# Can add username domain and password
+#
+# -b username domain password
+#
+# Can create Log file in current or any directory
+#
+# -j .
+#
+
+dn: CN=sudoUser,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoUser
+distinguishedName: CN=sudoUser,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.1
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoUser
+adminDescription: User(s) who may run sudo
+oMSyntax: 22
+searchFlags: 1
+lDAPDisplayName: sudoUser
+name: sudoUser
+schemaIDGUID:: JrGcaKpnoU+0s+HgeFjAbg==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoHost,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoHost
+distinguishedName: CN=sudoHost,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.2
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoHost
+adminDescription: Host(s) who may run sudo
+oMSyntax: 22
+lDAPDisplayName: sudoHost
+name: sudoHost
+schemaIDGUID:: d0TTjg+Y6U28g/Y+ns2k4w==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoCommand,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoCommand
+distinguishedName: CN=sudoCommand,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.3
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoCommand
+adminDescription: Command(s) to be executed by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoCommand
+name: sudoCommand
+schemaIDGUID:: D6QR4P5UyUen3RGYJCHCPg==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAs,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAs
+distinguishedName: CN=sudoRunAs,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.4
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAs
+adminDescription: User(s) impersonated by sudo (deprecated)
+oMSyntax: 22
+lDAPDisplayName: sudoRunAs
+name: sudoRunAs
+schemaIDGUID:: CP98mCQTyUKKxGrQeM80hQ==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoOption,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoOption
+distinguishedName: CN=sudoOption,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.5
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoOption
+adminDescription: Option(s) followed by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoOption
+name: sudoOption
+schemaIDGUID:: ojaPzBBlAEmsvrHxQctLnA==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAsUser,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAsUser
+distinguishedName: CN=sudoRunAsUser,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.6
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAsUser
+adminDescription: User(s) impersonated by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoRunAsUser
+name: sudoRunAsUser
+schemaIDGUID:: 9C52yPYd3RG3jMR2VtiVkw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoRunAsGroup,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoRunAsGroup
+distinguishedName: CN=sudoRunAsGroup,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.7
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoRunAsGroup
+adminDescription: Groups(s) impersonated by sudo
+oMSyntax: 22
+lDAPDisplayName: sudoRunAsGroup
+name: sudoRunAsGroup
+schemaIDGUID:: xJhSt/Yd3RGJPTB1VtiVkw==
+objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+
+dn: CN=sudoNotBefore,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoNotBefore
+distinguishedName: CN=sudoNotBefore,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.8
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoNotBefore
+adminDescription: Start of time interval for which the entry is valid
+oMSyntax: 24
+lDAPDisplayName: sudoNotBefore
+name: sudoNotBefore
+schemaIDGUID:: dm1HnRfY4RGf4gopYYhwmw== +objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+ +dn: CN=sudoNotAfter,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoNotAfter
+distinguishedName: CN=sudoNotAfter,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.9
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoNotAfter
+adminDescription: End of time interval for which the entry is valid
+oMSyntax: 24
+lDAPDisplayName: sudoNotAfter
+name: sudoNotAfter
+schemaIDGUID:: OAr/pBfY4RG9dBIpYYhwmw== +objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+ +dn: CN=sudoOrder,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: attributeSchema
+cn: sudoOrder
+distinguishedName: CN=sudoOrder,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+attributeID: 1.3.6.1.4.1.15953.9.1.10
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: sudoOrder
+adminDescription: an integer to order the sudoRole entries
+oMSyntax: 2
+lDAPDisplayName: sudoOrder
+name: sudoOrder
+schemaIDGUID:: 0J8yrRfY4RGIYBUpYYhwmw== +objectCategory: CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=X
+ +dn:
+changetype: modify
+add: schemaUpdateNow
+schemaUpdateNow: 1
+-
+
+dn: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
+changetype: add
+objectClass: top
+objectClass: classSchema
+cn: sudoRole
+distinguishedName: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
+instanceType: 4
+possSuperiors: container
+possSuperiors: top
+subClassOf: top
+governsID: 1.3.6.1.4.1.15953.9.2.1
+mayContain: sudoCommand
+mayContain: sudoHost
+mayContain: sudoOption
+mayContain: sudoRunAs
+mayContain: sudoRunAsUser
+mayContain: sudoRunAsGroup
+mayContain: sudoUser
+mayContain: sudoNotBefore
+mayContain: sudoNotAfter
+mayContain: sudoOrder
+rDNAttID: cn
+showInAdvancedViewOnly: FALSE
+adminDisplayName: sudoRole
+adminDescription: Sudoer Entries
+objectClassCategory: 1
+lDAPDisplayName: sudoRole
+name: sudoRole
+schemaIDGUID:: SQn432lnZ0+ukbdh3+gN3w==
+systemOnly: FALSE
+objectCategory: CN=Class-Schema,CN=Schema,CN=Configuration,DC=X
+defaultObjectCategory: CN=sudoRole,CN=Schema,CN=Configuration,DC=X
diff --git a/doc/schema.OpenLDAP b/doc/schema.OpenLDAP new file mode 100644 index 0000000..e1d525f --- /dev/null +++ b/doc/schema.OpenLDAP @@ -0,0 +1,78 @@ +# +# OpenLDAP schema file for Sudo +# Save as /etc/openldap/schema/sudo.schema and restart slapd. +# For a version that uses online configuration, see schema.olcSudo. +# + +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +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 ) + +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +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 ) + +objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL + DESC 'Sudoer Entries' + MUST ( cn ) + MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ + sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ + sudoNotAfter $ description ) + ) diff --git a/doc/schema.iPlanet b/doc/schema.iPlanet new file mode 100644 index 0000000..e512864 --- /dev/null +++ b/doc/schema.iPlanet @@ -0,0 +1,12 @@ +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.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.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 ) +objectClasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ description ) X-ORIGIN 'SUDO' ) diff --git a/doc/schema.olcSudo b/doc/schema.olcSudo new file mode 100644 index 0000000..8748dfc --- /dev/null +++ b/doc/schema.olcSudo @@ -0,0 +1,79 @@ +dn: cn=sudoschema,cn=schema,cn=config +objectClass: olcSchemaConfig +cn: sudoschema +# +# OpenLDAP schema file for Sudo in on-line configuration (OLC) format. +# Import using ldapadd or another suitable LDAP browser. +# Converted to OLC format by Frederic Pasteleurs <frederic@askarel.be> +# +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 ) +# +olcattributetypes: ( 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 ) +# +olcattributetypes: ( 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 ) +# +olcattributetypes: ( 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 ) +# +olcattributetypes: ( 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 ) +# +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 ) +# +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 ) +# +olcattributetypes: ( 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 ) +# +olcattributetypes: ( 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 ) +# +olcattributeTypes: ( 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 ) +# +olcobjectclasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL + DESC 'Sudoer Entries' + MUST ( cn ) + MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoOrder $ sudoNotBefore $ sudoNotAfter $ + description ) + ) diff --git a/doc/sudo.conf.man.in b/doc/sudo.conf.man.in new file mode 100644 index 0000000..36a3c00 --- /dev/null +++ b/doc/sudo.conf.man.in @@ -0,0 +1,864 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2010-2020 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. +.\" +.nr SL @SEMAN@ +.TH "SUDO.CONF" "@mansectform@" "December 5, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo.conf\fR +\- configuration for sudo front end +.SH "DESCRIPTION" +The +\fBsudo.conf\fR +file is used to configure the +\fBsudo\fR +front end. +It specifies the security policy and I/O logging plugins, debug flags +as well as plugin-agnostic path names and settings. +.PP +The +\fBsudo.conf\fR +file supports the following directives, described in detail below. +.TP 10n +Plugin +a security policy or I/O logging plugin +.TP 10n +Path +a plugin-agnostic path +.TP 10n +Set +a front end setting, such as +\fIdisable_coredump\fR +or +\fIgroup_source\fR +.TP 10n +Debug +debug flags to aid in debugging +\fBsudo\fR, +\fBsudoreplay\fR, +\fBvisudo\fR, +and the +\fBsudoers\fR +plugin. +.PP +The pound sign +(\(oq#\(cq) +is used to indicate a comment. +Both the comment character and any text after it, up to the end of +the line, are ignored. +.PP +Long lines can be continued with a backslash +(\(oq\e\(cq) +as the last character on the line. +Note that leading white space is removed from the beginning of lines +even when the continuation character is used. +.PP +Non-comment lines that don't begin with +\fRPlugin\fR, +\fRPath\fR, +\fRDebug\fR, +or +\fRSet\fR +are silently ignored. +.PP +The +\fBsudo.conf\fR +file is always parsed in the +\(lq\fRC\fR\(rq +locale. +.SS "Plugin configuration" +\fBsudo\fR +supports a plugin architecture for security policies and input/output +logging. +Third parties can develop and distribute their own policy and I/O +logging plugins to work seamlessly with the +\fBsudo\fR +front end. +Plugins are dynamically loaded based on the contents of +\fBsudo.conf\fR. +.PP +A +\fRPlugin\fR +line consists of the +\fRPlugin\fR +keyword, followed by the +\fIsymbol_name\fR +and the +\fIpath\fR +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, +or +\fRpolicy_plugin\fR +struct contained in the plugin. +If a plugin implements multiple plugin types, there must be a +\fRPlugin\fR +line for each unique symbol name. +The +\fIpath\fR +may be fully qualified or relative. +If not fully qualified, it is relative to the directory +specified by the +\fIplugin_dir\fR +\fRPath\fR +setting, which defaults to +\fI@plugindir@\fR. +In other words: +.nf +.sp +.RS 6n +Plugin sudoers_policy sudoers.so +.RE +.fi +.PP +is equivalent to: +.nf +.sp +.RS 6n +Plugin sudoers_policy @plugindir@/sudoers.so +.RE +.fi +.PP +If the plugin was compiled statically into the +\fBsudo\fR +binary instead of being installed as a dynamic shared object, the +\fIpath\fR +should be specified without a leading directory, +as it does not actually exist in the file system. +For example: +.nf +.sp +.RS 6n +Plugin sudoers_policy sudoers.so +.RE +.fi +.PP +Starting with +\fBsudo\fR +1.8.5, any additional parameters after the +\fIpath\fR +are passed as arguments to the plugin's +\fIopen\fR +function. +For example, to override the compile-time default sudoers file mode: +.nf +.sp +.RS 6n +Plugin sudoers_policy sudoers.so sudoers_mode=0440 +.RE +.fi +.PP +See the +sudoers(@mansectform@) +manual for a list of supported arguments. +.PP +The same dynamic shared object may contain multiple plugins, +each with a different symbol name. +The file must be owned by uid 0 and only writable by its owner. +Because of ambiguities that arise from composite policies, only a single +policy plugin may be specified. +This limitation does not apply to I/O plugins. +.PP +If no +\fBsudo.conf\fR +file is present, or if it contains no +\fRPlugin\fR +lines, the +\fBsudoers\fR +plugin will be used as the default security policy, for I/O logging +(if enabled by the policy) and for auditing. +This is equivalent to the following: +.nf +.sp +.RS 6n +Plugin sudoers_policy sudoers.so +Plugin sudoers_io sudoers.so +Plugin sudoers_audit sudoers.so +.RE +.fi +.PP +Starting with +\fBsudo\fR +version 1.9.1, some of the logging functionality of the +\fBsudoers\fR +plugin has been moved from the policy plugin to an audit plugin. +To maintain compatibility with +\fBsudo.conf\fR +files from older +\fBsudo\fR +versions, if +\fBsudoers\fR +is configured as the security policy, it will be used as an audit +plugin as well. +This guarantees that the logging behavior will be consistnet with that of +\fBsudo\fR +versions 1.9.0 and below. +.PP +For more information on the +\fBsudo\fR +plugin architecture, see the +sudo_plugin(@mansectform@) +manual. +.SS "Path settings" +A +\fRPath\fR +line consists of the +\fRPath\fR +keyword, followed by the name of the path to set and its value. +For example: +.nf +.sp +.RS 6n +Path noexec @noexec_file@ +Path askpass /usr/X11R6/bin/ssh-askpass +.RE +.fi +.PP +If no path name is specified, features relying on the specified +setting will be disabled. +Disabling +\fRPath\fR +settings is only supported in +\fBsudo\fR +version 1.8.16 and higher. +.PP +The following plugin-agnostic paths may be set in the +\fI@sysconfdir@/sudo.conf\fR +file: +.TP 10n +askpass +The fully qualified path to a helper program used to read the user's +password when no terminal is available. +This may be the case when +\fBsudo\fR +is executed from a graphical (as opposed to text-based) application. +The program specified by +\fIaskpass\fR +should display the argument passed to it as the prompt and write +the user's password to the standard output. +The value of +\fIaskpass\fR +may be overridden by the +\fRSUDO_ASKPASS\fR +environment variable. +.TP 10n +devsearch +.br +An ordered, colon-separated search path of directories to look in for +device nodes. +This is used when mapping the process's tty device number to a device name +on systems that do not provide such a mechanism. +Sudo will +\fInot\fR +recurse into sub-directories. +If terminal devices may be located in a sub-directory of +\fI/dev\fR, +that path must be explicitly listed in +\fIdevsearch\fR. +The default value is +\fR/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev\fR +.sp +This option is ignored on systems that support either the +\fBdevname\fR() +or +\fB_ttyname_dev\fR() +functions, for example +BSD, +macOS and Solaris. +.TP 10n +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(), +\fBexecvP\fR(), +\fBexecvp\fR(), +\fBexecvpe\fR(), +\fBfexecve\fR(), +\fBpopen\fR(), +\fBposix_spawn\fR(), +\fBposix_spawnp\fR(), +\fBsystem\fR(), +and +\fBwordexp\fR() +library functions that prevent the execution of further commands. +This is used to implement the +\fInoexec\fR +functionality on systems that support +\fRLD_PRELOAD\fR +or its equivalent. +The default value is +\fI@noexec_file@\fR. +.TP 10n +plugin_dir +The default directory to use when searching for plugins +that are specified without a fully qualified path name. +The default value is +\fI@plugindir@\fR. +.if \n(SL \{\ +.TP 10n +sesh +The fully-qualified path to the +\fBsesh\fR +binary. +This setting is only used when +\fBsudo\fR +is built with SELinux support. +The default value is +\fI@sesh_file@\fR. +.\} +.SS "Other settings" +The +\fBsudo.conf\fR +file also supports the following front end settings: +.TP 10n +disable_coredump +Core dumps of +\fBsudo\fR +itself are disabled by default to prevent the disclosure of potentially +sensitive information. +To aid in debugging +\fBsudo\fR +crashes, you may wish to re-enable core dumps by setting +\(lqdisable_coredump\(rq +to false in +\fBsudo.conf\fR +as follows: +.nf +.sp +.RS 16n +Set disable_coredump false +.RE +.fi +.RS 10n +.sp +All modern operating systems place restrictions on core dumps +from set-user-ID processes like +\fBsudo\fR +so this option can be enabled without compromising security. +To actually get a +\fBsudo\fR +core file you will likely need to enable core dumps for set-user-ID processes. +On +BSD +and Linux systems this is accomplished in the +sysctl(@mansectsu@) +command. +On Solaris, the +coreadm(1m) +command is used to configure core dump behavior. +.sp +This setting is only available in +\fBsudo\fR +version 1.8.4 and higher. +.RE +.TP 10n +developer_mode +By default +\fBsudo\fR +refuses to load plugins which can be modified by other than the root user. +The plugin should be owned by root and write access permissions should be +disabled for +\(lqgroup\(rq +and +\(lqother\(rq\&. +To make development of a plugin easier, you can disable that by setting +\(lqdeveloper_mode\(rq +option to true in +\fBsudo.conf\fR +as follows: +.nf +.sp +.RS 16n +Set developer_mode true +.RE +.fi +.RS 10n +.sp +Please note that this creates a security risk, so it is not recommended +on critical systems such as a desktop machine for daily use, but is intended +to be used in development environments (VM, container, etc). +Before enabling developer mode, ensure you understand the implications. +.sp +This setting is only available in +\fBsudo\fR +version 1.9.0 and higher. +.RE +.TP 10n +group_source +\fBsudo\fR +passes the invoking user's group list to the policy and I/O plugins. +On most systems, there is an upper limit to the number of groups that +a user may belong to simultaneously (typically 16 for compatibility +with NFS). +On systems with the +getconf(1) +utility, running: +.RS 16n +getconf NGROUPS_MAX +.RE +.RS 10n +will return the maximum number of groups. +.sp +However, it is still possible to be a member of a larger number of +groups--they simply won't be included in the group list returned +by the kernel for the user. +Starting with +\fBsudo\fR +version 1.8.7, if the user's kernel group list has the maximum number +of entries, +\fBsudo\fR +will consult the group database directly to determine the group list. +This makes it possible for the security policy to perform matching by group +name even when the user is a member of more than the maximum number of groups. +.sp +The +\fIgroup_source\fR +setting allows the administrator to change this default behavior. +Supported values for +\fIgroup_source\fR +are: +.TP 10n +static +Use the static group list that the kernel returns. +Retrieving the group list this way is very fast but it is subject +to an upper limit as described above. +It is +\(lqstatic\(rq +in that it does not reflect changes to the group database made +after the user logs in. +This was the default behavior prior to +\fBsudo\fR +1.8.7. +.TP 10n +dynamic +Always query the group database directly. +It is +\(lqdynamic\(rq +in that changes made to the group database after the user logs in +will be reflected in the group list. +On some systems, querying the group database for all of a user's +groups can be time consuming when querying a network-based group +database. +Most operating systems provide an efficient method of performing +such queries. +Currently, +\fBsudo\fR +supports efficient group queries on AIX, +BSD, +HP-UX, Linux and Solaris. +.TP 10n +adaptive +Only query the group database if the static group list returned +by the kernel has the maximum number of entries. +This is the default behavior in +\fBsudo\fR +1.8.7 and higher. +.PP +For example, to cause +\fBsudo\fR +to only use the kernel's static list of groups for the user: +.nf +.sp +.RS 16n +Set group_source static +.RE +.fi +.sp +This setting is only available in +\fBsudo\fR +version 1.8.7 and higher. +.RE +.TP 10n +max_groups +The maximum number of user groups to retrieve from the group database. +Values less than one will be ignored. +This setting is only used when querying the group database directly. +It is intended to be used on systems where it is not possible to detect +when the array to be populated with group entries is not sufficiently large. +By default, +\fBsudo\fR +will allocate four times the system's maximum number of groups (see above) +and retry with double that number if the group database query fails. +.sp +This setting is only available in +\fBsudo\fR +version 1.8.7 and higher. +It should not be required in +\fBsudo\fR +versions 1.8.24 and higher and may be removed in a later release. +.TP 10n +probe_interfaces +By default, +\fBsudo\fR +will probe the system's network interfaces and pass the IP address +of each enabled interface to the policy plugin. +This makes it possible for the plugin to match rules based on the IP address +without having to query DNS. +On Linux systems with a large number of virtual interfaces, this may +take a non-negligible amount of time. +If IP-based matching is not required, network interface probing +can be disabled as follows: +.nf +.sp +.RS 16n +Set probe_interfaces false +.RE +.fi +.RS 10n +.sp +This setting is only available in +\fBsudo\fR +version 1.8.10 and higher. +.RE +.SS "Debug flags" +\fBsudo\fR +versions 1.8.4 and higher support a flexible debugging framework +that can help track down what +\fBsudo\fR +is doing internally if there is a problem. +.PP +A +\fRDebug\fR +line consists of the +\fRDebug\fR +keyword, followed by the name of the program (or plugin) to debug +(\fBsudo\fR, \fBvisudo\fR, \fBsudoreplay\fR, \fBsudoers\fR), +the debug file name and a comma-separated list of debug flags. +The debug flag syntax used by +\fBsudo\fR +and the +\fBsudoers\fR +plugin is +\fIsubsystem\fR@\fIpriority\fR +but a plugin is free to use a different format so long as it does +not include a comma +(\(oq\&,\(cq). +.PP +For example: +.nf +.sp +.RS 6n +Debug sudo /var/log/sudo_debug all@warn,plugin@info +.RE +.fi +.PP +would log all debugging statements at the +\fIwarn\fR +level and higher in addition to those at the +\fIinfo\fR +level for the plugin subsystem. +.PP +As of +\fBsudo\fR +1.8.12, multiple +\fRDebug\fR +entries may be specified per program. +Older versions of +\fBsudo\fR +only support a single +\fRDebug\fR +entry per program. +Plugin-specific +\fRDebug\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) +or by the plugin's fully-qualified path name. +Previously, the +\fBsudoers\fR +plugin shared the same +\fRDebug\fR +entry as the +\fBsudo\fR +front end and could not be configured separately. +.PP +The following priorities are supported, in order of decreasing severity: +\fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR +and +\fIdebug\fR. +Each priority, when specified, also includes all priorities higher +than it. +For example, a priority of +\fInotice\fR +would include debug messages logged at +\fInotice\fR +and higher. +.PP +The priorities +\fItrace\fR +and +\fIdebug\fR +also include function call tracing which logs when a function is +entered and when it returns. +For example, the following trace is for the +\fBget_user_groups\fR() +function located in src/sudo.c: +.nf +.sp +.RS 6n +sudo[123] -> get_user_groups @ src/sudo.c:385 +sudo[123] <- get_user_groups @ src/sudo.c:429 := groups=10,0,5 +.RE +.fi +.PP +When the function is entered, indicated by a right arrow +\(oq->\(cq, +the program, process ID, function, source file and line number +are logged. +When the function returns, indicated by a left arrow +\(oq<-\(cq, +the same information is logged along with the return value. +In this case, the return value is a string. +.PP +The following subsystems are used by the +\fBsudo\fR +front-end: +.TP 12n +\fIall\fR +matches every subsystem +.TP 12n +\fIargs\fR +command line argument processing +.TP 12n +\fIconv\fR +user conversation +.TP 12n +\fIedit\fR +sudoedit +.TP 12n +\fIevent\fR +event subsystem +.TP 12n +\fIexec\fR +command execution +.TP 12n +\fImain\fR +\fBsudo\fR +main function +.TP 12n +\fInetif\fR +network interface handling +.TP 12n +\fIpcomm\fR +communication with the plugin +.TP 12n +\fIplugin\fR +plugin configuration +.TP 12n +\fIpty\fR +pseudo-terminal related code +.TP 12n +\fIselinux\fR +SELinux-specific handling +.TP 12n +\fIutil\fR +utility functions +.TP 12n +\fIutmp\fR +utmp handling +.PP +The +sudoers(@mansectform@) +plugin includes support for additional subsystems. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +\fBsudo\fR +front end configuration +.SH "EXAMPLES" +.nf +.RS 0n +# +# Default @sysconfdir@/sudo.conf file +# +# Sudo plugins: +# Plugin plugin_name plugin_path plugin_options ... +# +# The plugin_path is relative to @plugindir@ unless +# fully qualified. +# The plugin_name corresponds to a global symbol in the plugin +# that contains the plugin interface structure. +# The plugin_options are optional. +# +# The sudoers plugin is used by default if no Plugin lines are present. +#Plugin sudoers_policy sudoers.so +#Plugin sudoers_io sudoers.so +#Plugin sudoers_audit sudoers.so + +# +# Sudo askpass: +# Path askpass /path/to/askpass +# +# An askpass helper program may be specified to provide a graphical +# password prompt for "sudo -A" support. Sudo does not ship with its +# own askpass program but can use the OpenSSH askpass. +# +# Use the OpenSSH askpass +#Path askpass /usr/X11R6/bin/ssh-askpass +# +# Use the Gnome OpenSSH askpass +#Path askpass /usr/libexec/openssh/gnome-ssh-askpass + +# +# Sudo device search path: +# Path devsearch /dev/path1:/dev/path2:/dev +# +# A colon-separated list of paths to check when searching for a user's +# terminal device. +# +#Path devsearch /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev + +# +# Sudo noexec: +# Path noexec /path/to/sudo_noexec.so +# +# Path to a shared library containing replacements for the execv(), +# execve() and fexecve() library functions that just return an error. +# This is used to implement the "noexec" functionality on systems that +# support LD_PRELOAD or its equivalent. +# +# The compiled-in value is usually sufficient and should only be changed +# if you rename or move the sudo_noexec.so file. +# +#Path noexec @plugindir@/sudo_noexec.so + +# +# Sudo plugin directory: +# Path plugin_dir /path/to/plugins +# +# The default directory to use when searching for plugins that are +# specified without a fully qualified path name. +# +#Path plugin_dir @plugindir@ + +# +# Sudo developer mode: +# Set developer_mode true|false +# +# Allow loading of plugins that are owned by non-root or are writable +# by "group" or "other". Should only be used during plugin development. +#Set developer_mode true + +# +# Core dumps: +# Set disable_coredump true|false +# +# By default, sudo disables core dumps while it is executing (they +# are re-enabled for the command that is run). +# To aid in debugging sudo problems, you may wish to enable core +# dumps by setting "disable_coredump" to false. +# +#Set disable_coredump false + +# +# User groups: +# Set group_source static|dynamic|adaptive +# +# Sudo passes the user's group list to the policy plugin. +# If the user is a member of the maximum number of groups (usually 16), +# sudo will query the group database directly to be sure to include +# the full list of groups. +# +# On some systems, this can be expensive so the behavior is configurable. +# The "group_source" setting has three possible values: +# static - use the user's list of groups returned by the kernel. +# dynamic - query the group database to find the list of groups. +# adaptive - if user is in less than the maximum number of groups. +# use the kernel list, else query the group database. +# +#Set group_source static + +# +# Sudo interface probing: +# Set probe_interfaces true|false +# +# By default, sudo will probe the system's network interfaces and +# pass the IP address of each enabled interface to the policy plugin. +# On systems with a large number of virtual interfaces this may take +# a noticeable amount of time. +# +#Set probe_interfaces false + +# +# Sudo debug files: +# Debug program /path/to/debug_log subsystem@priority[,subsyste@priority] +# +# Sudo and related programs support logging debug information to a file. +# The program is typically sudo, sudoers.so, sudoreplay or visudo. +# +# Subsystems vary based on the program; "all" matches all subsystems. +# Priority may be crit, err, warn, notice, diag, info, trace or debug. +# Multiple subsystem@priority may be specified, separated by a comma. +# +#Debug sudo /var/log/sudo_debug all@debug +#Debug sudoers.so /var/log/sudoers_debug all@debug +.RE +.fi +.SH "SEE ALSO" +sudo_plugin(@mansectform@), +sudoers(@mansectform@), +sudo(@mansectsu@) +.SH "HISTORY" +See the HISTORY file in the +\fBsudo\fR +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo.conf.man.in.sed b/doc/sudo.conf.man.in.sed new file mode 100644 index 0000000..2534bc8 --- /dev/null +++ b/doc/sudo.conf.man.in.sed @@ -0,0 +1,15 @@ +s/^\(.TH .*\)/.nr SL @SEMAN@\ +\1/ + +/^\.TP 10n$/ { + N + /^.TP 10n\nsesh$/ { + i\ +.if \\n(SL \\{\\ + } +} + +/^\\fI@sesh_file@\\fR\.$/ { + a\ +.\\} +} diff --git a/doc/sudo.conf.mdoc.in b/doc/sudo.conf.mdoc.in new file mode 100644 index 0000000..2d572e5 --- /dev/null +++ b/doc/sudo.conf.mdoc.in @@ -0,0 +1,796 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2010-2020 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. +.\" +.nr SL @SEMAN@ +.Dd December 5, 2020 +.Dt SUDO.CONF @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo.conf +.Nd configuration for sudo front end +.Sh DESCRIPTION +The +.Nm sudo.conf +file is used to configure the +.Nm sudo +front end. +It specifies the security policy and I/O logging plugins, debug flags +as well as plugin-agnostic path names and settings. +.Pp +The +.Nm +file supports the following directives, described in detail below. +.Bl -tag -width 8n +.It Plugin +a security policy or I/O logging plugin +.It Path +a plugin-agnostic path +.It Set +a front end setting, such as +.Em disable_coredump +or +.Em group_source +.It Debug +debug flags to aid in debugging +.Nm sudo , +.Nm sudoreplay , +.Nm visudo , +and the +.Nm sudoers +plugin. +.El +.Pp +The pound sign +.Pq Ql # +is used to indicate a comment. +Both the comment character and any text after it, up to the end of +the line, are ignored. +.Pp +Long lines can be continued with a backslash +.Pq Ql \e +as the last character on the line. +Note that leading white space is removed from the beginning of lines +even when the continuation character is used. +.Pp +Non-comment lines that don't begin with +.Li Plugin , +.Li Path , +.Li Debug , +or +.Li Set +are silently ignored. +.Pp +The +.Nm +file is always parsed in the +.Dq Li C +locale. +.Ss Plugin configuration +.Nm sudo +supports a plugin architecture for security policies and input/output +logging. +Third parties can develop and distribute their own policy and I/O +logging plugins to work seamlessly with the +.Nm sudo +front end. +Plugins are dynamically loaded based on the contents of +.Nm . +.Pp +A +.Li Plugin +line consists of the +.Li Plugin +keyword, followed by the +.Em symbol_name +and the +.Em path +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 , +or +.Li policy_plugin +struct contained in the plugin. +If a plugin implements multiple plugin types, there must be a +.Li Plugin +line for each unique symbol name. +The +.Em path +may be fully qualified or relative. +If not fully qualified, it is relative to the directory +specified by the +.Em plugin_dir +.Li Path +setting, which defaults to +.Pa @plugindir@ . +In other words: +.Bd -literal -offset indent +Plugin sudoers_policy sudoers.so +.Ed +.Pp +is equivalent to: +.Bd -literal -offset indent +Plugin sudoers_policy @plugindir@/sudoers.so +.Ed +.Pp +If the plugin was compiled statically into the +.Nm sudo +binary instead of being installed as a dynamic shared object, the +.Em path +should be specified without a leading directory, +as it does not actually exist in the file system. +For example: +.Bd -literal -offset indent +Plugin sudoers_policy sudoers.so +.Ed +.Pp +Starting with +.Nm sudo +1.8.5, any additional parameters after the +.Em path +are passed as arguments to the plugin's +.Em open +function. +For example, to override the compile-time default sudoers file mode: +.Bd -literal -offset indent +Plugin sudoers_policy sudoers.so sudoers_mode=0440 +.Ed +.Pp +See the +.Xr sudoers @mansectform@ +manual for a list of supported arguments. +.Pp +The same dynamic shared object may contain multiple plugins, +each with a different symbol name. +The file must be owned by uid 0 and only writable by its owner. +Because of ambiguities that arise from composite policies, only a single +policy plugin may be specified. +This limitation does not apply to I/O plugins. +.Pp +If no +.Nm +file is present, or if it contains no +.Li Plugin +lines, the +.Nm sudoers +plugin will be used as the default security policy, for I/O logging +(if enabled by the policy) and for auditing. +This is equivalent to the following: +.Bd -literal -offset indent +Plugin sudoers_policy sudoers.so +Plugin sudoers_io sudoers.so +Plugin sudoers_audit sudoers.so +.Ed +.Pp +Starting with +.Nm sudo +version 1.9.1, some of the logging functionality of the +.Nm sudoers +plugin has been moved from the policy plugin to an audit plugin. +To maintain compatibility with +.Nm +files from older +.Nm sudo +versions, if +.Nm sudoers +is configured as the security policy, it will be used as an audit +plugin as well. +This guarantees that the logging behavior will be consistnet with that of +.Nm sudo +versions 1.9.0 and below. +.Pp +For more information on the +.Nm sudo +plugin architecture, see the +.Xr sudo_plugin @mansectform@ +manual. +.Ss Path settings +A +.Li Path +line consists of the +.Li Path +keyword, followed by the name of the path to set and its value. +For example: +.Bd -literal -offset indent +Path noexec @noexec_file@ +Path askpass /usr/X11R6/bin/ssh-askpass +.Ed +.Pp +If no path name is specified, features relying on the specified +setting will be disabled. +Disabling +.Li Path +settings is only supported in +.Nm sudo +version 1.8.16 and higher. +.Pp +The following plugin-agnostic paths may be set in the +.Pa @sysconfdir@/sudo.conf +file: +.Bl -tag -width 8n +.It askpass +The fully qualified path to a helper program used to read the user's +password when no terminal is available. +This may be the case when +.Nm sudo +is executed from a graphical (as opposed to text-based) application. +The program specified by +.Em askpass +should display the argument passed to it as the prompt and write +the user's password to the standard output. +The value of +.Em askpass +may be overridden by the +.Ev SUDO_ASKPASS +environment variable. +.It devsearch +An ordered, colon-separated search path of directories to look in for +device nodes. +This is used when mapping the process's tty device number to a device name +on systems that do not provide such a mechanism. +Sudo will +.Em not +recurse into sub-directories. +If terminal devices may be located in a sub-directory of +.Pa /dev , +that path must be explicitly listed in +.Em devsearch . +The default value is +.Li /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev +.Pp +This option is ignored on systems that support either the +.Fn devname +or +.Fn _ttyname_dev +functions, for example +.Bx , +macOS and Solaris. +.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 execvP , +.Fn execvp , +.Fn execvpe , +.Fn fexecve , +.Fn popen , +.Fn posix_spawn , +.Fn posix_spawnp , +.Fn system , +and +.Fn wordexp +library functions that prevent the execution of further commands. +This is used to implement the +.Em noexec +functionality on systems that support +.Ev LD_PRELOAD +or its equivalent. +The default value is +.Pa @noexec_file@ . +.It plugin_dir +The default directory to use when searching for plugins +that are specified without a fully qualified path name. +The default value is +.Pa @plugindir@ . +.if \n(SL \{\ +.It sesh +The fully-qualified path to the +.Nm sesh +binary. +This setting is only used when +.Nm sudo +is built with SELinux support. +The default value is +.Pa @sesh_file@ . +.\} +.El +.Ss Other settings +The +.Nm +file also supports the following front end settings: +.Bl -tag -width 8n +.It disable_coredump +Core dumps of +.Nm sudo +itself are disabled by default to prevent the disclosure of potentially +sensitive information. +To aid in debugging +.Nm sudo +crashes, you may wish to re-enable core dumps by setting +.Dq disable_coredump +to false in +.Nm +as follows: +.Bd -literal -offset indent +Set disable_coredump false +.Ed +.Pp +All modern operating systems place restrictions on core dumps +from set-user-ID processes like +.Nm sudo +so this option can be enabled without compromising security. +To actually get a +.Nm sudo +core file you will likely need to enable core dumps for set-user-ID processes. +On +.Bx +and Linux systems this is accomplished in the +.Xr sysctl 8 +command. +On Solaris, the +.Xr coreadm 1m +command is used to configure core dump behavior. +.Pp +This setting is only available in +.Nm sudo +version 1.8.4 and higher. +.It developer_mode +By default +.Nm sudo +refuses to load plugins which can be modified by other than the root user. +The plugin should be owned by root and write access permissions should be +disabled for +.Dq group +and +.Sm off +.Dq other +\&. +.Sm on +To make development of a plugin easier, you can disable that by setting +.Dq developer_mode +option to true in +.Nm sudo.conf +as follows: +.Bd -literal -offset indent +Set developer_mode true +.Ed +.Pp +Please note that this creates a security risk, so it is not recommended +on critical systems such as a desktop machine for daily use, but is intended +to be used in development environments (VM, container, etc). +Before enabling developer mode, ensure you understand the implications. +.Pp +This setting is only available in +.Nm sudo +version 1.9.0 and higher. +.It group_source +.Nm sudo +passes the invoking user's group list to the policy and I/O plugins. +On most systems, there is an upper limit to the number of groups that +a user may belong to simultaneously (typically 16 for compatibility +with NFS). +On systems with the +.Xr getconf 1 +utility, running: +.Dl getconf NGROUPS_MAX +will return the maximum number of groups. +.Pp +However, it is still possible to be a member of a larger number of +groups--they simply won't be included in the group list returned +by the kernel for the user. +Starting with +.Nm sudo +version 1.8.7, if the user's kernel group list has the maximum number +of entries, +.Nm sudo +will consult the group database directly to determine the group list. +This makes it possible for the security policy to perform matching by group +name even when the user is a member of more than the maximum number of groups. +.Pp +The +.Em group_source +setting allows the administrator to change this default behavior. +Supported values for +.Em group_source +are: +.Bl -tag -width 8n +.It static +Use the static group list that the kernel returns. +Retrieving the group list this way is very fast but it is subject +to an upper limit as described above. +It is +.Dq static +in that it does not reflect changes to the group database made +after the user logs in. +This was the default behavior prior to +.Nm sudo +1.8.7. +.It dynamic +Always query the group database directly. +It is +.Dq dynamic +in that changes made to the group database after the user logs in +will be reflected in the group list. +On some systems, querying the group database for all of a user's +groups can be time consuming when querying a network-based group +database. +Most operating systems provide an efficient method of performing +such queries. +Currently, +.Nm sudo +supports efficient group queries on AIX, +.Bx , +HP-UX, Linux and Solaris. +.It adaptive +Only query the group database if the static group list returned +by the kernel has the maximum number of entries. +This is the default behavior in +.Nm sudo +1.8.7 and higher. +.El +.Pp +For example, to cause +.Nm sudo +to only use the kernel's static list of groups for the user: +.Bd -literal -offset indent +Set group_source static +.Ed +.Pp +This setting is only available in +.Nm sudo +version 1.8.7 and higher. +.It max_groups +The maximum number of user groups to retrieve from the group database. +Values less than one will be ignored. +This setting is only used when querying the group database directly. +It is intended to be used on systems where it is not possible to detect +when the array to be populated with group entries is not sufficiently large. +By default, +.Nm sudo +will allocate four times the system's maximum number of groups (see above) +and retry with double that number if the group database query fails. +.Pp +This setting is only available in +.Nm sudo +version 1.8.7 and higher. +It should not be required in +.Nm sudo +versions 1.8.24 and higher and may be removed in a later release. +.It probe_interfaces +By default, +.Nm sudo +will probe the system's network interfaces and pass the IP address +of each enabled interface to the policy plugin. +This makes it possible for the plugin to match rules based on the IP address +without having to query DNS. +On Linux systems with a large number of virtual interfaces, this may +take a non-negligible amount of time. +If IP-based matching is not required, network interface probing +can be disabled as follows: +.Bd -literal -offset indent +Set probe_interfaces false +.Ed +.Pp +This setting is only available in +.Nm sudo +version 1.8.10 and higher. +.El +.Ss Debug flags +.Nm sudo +versions 1.8.4 and higher support a flexible debugging framework +that can help track down what +.Nm sudo +is doing internally if there is a problem. +.Pp +A +.Li Debug +line consists of the +.Li Debug +keyword, followed by the name of the program (or plugin) to debug +.Pq Nm sudo , Nm visudo , Nm sudoreplay , Nm sudoers , +the debug file name and a comma-separated list of debug flags. +The debug flag syntax used by +.Nm sudo +and the +.Nm sudoers +plugin is +.Em subsystem Ns @ Ns Em priority +but a plugin is free to use a different format so long as it does +not include a comma +.Pq Ql \&, . +.Pp +For example: +.Bd -literal -offset indent +Debug sudo /var/log/sudo_debug all@warn,plugin@info +.Ed +.Pp +would log all debugging statements at the +.Em warn +level and higher in addition to those at the +.Em info +level for the plugin subsystem. +.Pp +As of +.Nm sudo +1.8.12, multiple +.Li Debug +entries may be specified per program. +Older versions of +.Nm sudo +only support a single +.Li Debug +entry per program. +Plugin-specific +.Li 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 ) +or by the plugin's fully-qualified path name. +Previously, the +.Nm sudoers +plugin shared the same +.Li Debug +entry as the +.Nm sudo +front end and could not be configured separately. +.Pp +The following priorities are supported, in order of decreasing severity: +.Em crit , err , warn , notice , diag , info , trace +and +.Em debug . +Each priority, when specified, also includes all priorities higher +than it. +For example, a priority of +.Em notice +would include debug messages logged at +.Em notice +and higher. +.Pp +The priorities +.Em trace +and +.Em debug +also include function call tracing which logs when a function is +entered and when it returns. +For example, the following trace is for the +.Fn get_user_groups +function located in src/sudo.c: +.Bd -literal -offset indent +sudo[123] -> get_user_groups @ src/sudo.c:385 +sudo[123] <- get_user_groups @ src/sudo.c:429 := groups=10,0,5 +.Ed +.Pp +When the function is entered, indicated by a right arrow +.Ql -> , +the program, process ID, function, source file and line number +are logged. +When the function returns, indicated by a left arrow +.Ql <- , +the same information is logged along with the return value. +In this case, the return value is a string. +.Pp +The following subsystems are used by the +.Nm sudo +front-end: +.Bl -tag -width Fl +.It Em all +matches every subsystem +.It Em args +command line argument processing +.It Em conv +user conversation +.It Em edit +sudoedit +.It Em event +event subsystem +.It Em exec +command execution +.It Em main +.Nm sudo +main function +.It Em netif +network interface handling +.It Em pcomm +communication with the plugin +.It Em plugin +plugin configuration +.It Em pty +pseudo-terminal related code +.It Em selinux +SELinux-specific handling +.It Em util +utility functions +.It Em utmp +utmp handling +.El +.Pp +The +.Xr sudoers @mansectform@ +plugin includes support for additional subsystems. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +.Nm sudo +front end configuration +.El +.Sh EXAMPLES +.Bd -literal +# +# Default @sysconfdir@/sudo.conf file +# +# Sudo plugins: +# Plugin plugin_name plugin_path plugin_options ... +# +# The plugin_path is relative to @plugindir@ unless +# fully qualified. +# The plugin_name corresponds to a global symbol in the plugin +# that contains the plugin interface structure. +# The plugin_options are optional. +# +# The sudoers plugin is used by default if no Plugin lines are present. +#Plugin sudoers_policy sudoers.so +#Plugin sudoers_io sudoers.so +#Plugin sudoers_audit sudoers.so + +# +# Sudo askpass: +# Path askpass /path/to/askpass +# +# An askpass helper program may be specified to provide a graphical +# password prompt for "sudo -A" support. Sudo does not ship with its +# own askpass program but can use the OpenSSH askpass. +# +# Use the OpenSSH askpass +#Path askpass /usr/X11R6/bin/ssh-askpass +# +# Use the Gnome OpenSSH askpass +#Path askpass /usr/libexec/openssh/gnome-ssh-askpass + +# +# Sudo device search path: +# Path devsearch /dev/path1:/dev/path2:/dev +# +# A colon-separated list of paths to check when searching for a user's +# terminal device. +# +#Path devsearch /dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev + +# +# Sudo noexec: +# Path noexec /path/to/sudo_noexec.so +# +# Path to a shared library containing replacements for the execv(), +# execve() and fexecve() library functions that just return an error. +# This is used to implement the "noexec" functionality on systems that +# support LD_PRELOAD or its equivalent. +# +# The compiled-in value is usually sufficient and should only be changed +# if you rename or move the sudo_noexec.so file. +# +#Path noexec @plugindir@/sudo_noexec.so + +# +# Sudo plugin directory: +# Path plugin_dir /path/to/plugins +# +# The default directory to use when searching for plugins that are +# specified without a fully qualified path name. +# +#Path plugin_dir @plugindir@ + +# +# Sudo developer mode: +# Set developer_mode true|false +# +# Allow loading of plugins that are owned by non-root or are writable +# by "group" or "other". Should only be used during plugin development. +#Set developer_mode true + +# +# Core dumps: +# Set disable_coredump true|false +# +# By default, sudo disables core dumps while it is executing (they +# are re-enabled for the command that is run). +# To aid in debugging sudo problems, you may wish to enable core +# dumps by setting "disable_coredump" to false. +# +#Set disable_coredump false + +# +# User groups: +# Set group_source static|dynamic|adaptive +# +# Sudo passes the user's group list to the policy plugin. +# If the user is a member of the maximum number of groups (usually 16), +# sudo will query the group database directly to be sure to include +# the full list of groups. +# +# On some systems, this can be expensive so the behavior is configurable. +# The "group_source" setting has three possible values: +# static - use the user's list of groups returned by the kernel. +# dynamic - query the group database to find the list of groups. +# adaptive - if user is in less than the maximum number of groups. +# use the kernel list, else query the group database. +# +#Set group_source static + +# +# Sudo interface probing: +# Set probe_interfaces true|false +# +# By default, sudo will probe the system's network interfaces and +# pass the IP address of each enabled interface to the policy plugin. +# On systems with a large number of virtual interfaces this may take +# a noticeable amount of time. +# +#Set probe_interfaces false + +# +# Sudo debug files: +# Debug program /path/to/debug_log subsystem@priority[,subsyste@priority] +# +# Sudo and related programs support logging debug information to a file. +# The program is typically sudo, sudoers.so, sudoreplay or visudo. +# +# Subsystems vary based on the program; "all" matches all subsystems. +# Priority may be crit, err, warn, notice, diag, info, trace or debug. +# Multiple subsystem@priority may be specified, separated by a comma. +# +#Debug sudo /var/log/sudo_debug all@debug +#Debug sudoers.so /var/log/sudoers_debug all@debug +.Ed +.Sh SEE ALSO +.Xr sudo_plugin @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ +.Sh HISTORY +See the HISTORY file in the +.Nm sudo +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo.man.in b/doc/sudo.man.in new file mode 100644 index 0000000..46dcc67 --- /dev/null +++ b/doc/sudo.man.in @@ -0,0 +1,1495 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1994-1996, 1998-2005, 2007-2020 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.nr SL @SEMAN@ +.nr BA @BAMAN@ +.nr LC @LCMAN@ +.nr PS @PSMAN@ +.TH "SUDO" "@mansectsu@" "September 1, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo\fR, +\fBsudoedit\fR +\- execute a command as another user +.SH "SYNOPSIS" +.HP 5n +\fBsudo\fR +\fB\-h\fR\ |\ \fB\-K\fR\ |\ \fB\-k\fR\ |\ \fB\-V\fR +.br +.PD 0 +.HP 5n +\fBsudo\fR +\fB\-v\fR +[\fB\-ABknS\fR] +.if \n(BA [\fB\-a\fR\ \fItype\fR] +[\fB\-g\fR\ \fIgroup\fR] +[\fB\-h\fR\ \fIhost\fR] +[\fB\-p\fR\ \fIprompt\fR] +[\fB\-u\fR\ \fIuser\fR] +.br +.HP 5n +\fBsudo\fR +\fB\-l\fR +[\fB\-ABknS\fR] +.if \n(BA [\fB\-a\fR\ \fItype\fR] +[\fB\-g\fR\ \fIgroup\fR] +[\fB\-h\fR\ \fIhost\fR] +[\fB\-p\fR\ \fIprompt\fR] +[\fB\-U\fR\ \fIuser\fR] +[\fB\-u\fR\ \fIuser\fR] +[\fIcommand\fR] +.br +.HP 5n +\fBsudo\fR +[\fB\-ABbEHnPS\fR] +.if \n(BA [\fB\-a\fR\ \fItype\fR] +[\fB\-C\fR\ \fInum\fR] +.if \n(LC [\fB\-c\fR\ \fIclass\fR] +[\fB\-D\fR\ \fIdirectory\fR] +[\fB\-g\fR\ \fIgroup\fR] +[\fB\-h\fR\ \fIhost\fR] +[\fB\-p\fR\ \fIprompt\fR] +[\fB\-R\fR\ \fIdirectory\fR] +.if \n(SL [\fB\-r\fR\ \fIrole\fR] +.if \n(SL [\fB\-t\fR\ \fItype\fR] +[\fB\-T\fR\ \fItimeout\fR] +[\fB\-u\fR\ \fIuser\fR] +[\fIVAR\fR=\fIvalue\fR] +[\fB\-i\fR\ |\ \fB\-s\fR] +[\fIcommand\fR] +.br +.HP 9n +\fBsudoedit\fR +[\fB\-ABknS\fR] +.if \n(BA [\fB\-a\fR\ \fItype\fR] +[\fB\-C\fR\ \fInum\fR] +.if \n(LC [\fB\-c\fR\ \fIclass\fR] +[\fB\-D\fR\ \fIdirectory\fR] +[\fB\-g\fR\ \fIgroup\fR] +[\fB\-h\fR\ \fIhost\fR] +[\fB\-p\fR\ \fIprompt\fR] +[\fB\-R\fR\ \fIdirectory\fR] +.if \n(SL [\fB\-r\fR\ \fIrole\fR] +.if \n(SL [\fB\-t\fR\ \fItype\fR] +[\fB\-T\fR\ \fItimeout\fR] +[\fB\-u\fR\ \fIuser\fR] +\fIfile\ ...\fR +.PD +.SH "DESCRIPTION" +\fBsudo\fR +allows a permitted user to execute a +\fIcommand\fR +as the superuser or another user, as specified by the security +policy. +The invoking user's real +(\fInot\fR effective) +user-ID is used to determine the user name with which +to query the security policy. +.PP +\fBsudo\fR +supports a plugin architecture for security policies and input/output +logging. +Third parties can develop and distribute their own policy and I/O +logging plugins to work seamlessly with the +\fBsudo\fR +front end. +The default security policy is +\fIsudoers\fR, +which is configured via the file +\fI@sysconfdir@/sudoers\fR, +or via LDAP. +See the +\fIPlugins\fR +section for more information. +.PP +The security policy determines what privileges, if any, a user has +to run +\fBsudo\fR. +The policy may require that users authenticate themselves with a +password or another authentication mechanism. +If authentication is required, +\fBsudo\fR +will exit if the user's password is not entered within a configurable +time limit. +This limit is policy-specific; the default password prompt timeout +for the +\fIsudoers\fR +security policy is +\fR@password_timeout@\fR +minutes. +.PP +Security policies may support credential caching to allow the user +to run +\fBsudo\fR +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. +See the +\fItimestamp_type\fR +and +\fItimestamp_timeout\fR +options in +sudoers(@mansectform@) +for more information. +By running +\fBsudo\fR +with the +\fB\-v\fR +option, a user can update the cached credentials without running a +\fIcommand\fR. +.PP +On systems where +\fBsudo\fR +is the primary method of gaining superuser privileges, it is imperative +to avoid syntax errors in the security policy configuration files. +For the default security policy, +sudoers(@mansectform@), +changes to the configuration files should be made using the +visudo(@mansectsu@) +utility which will ensure that no syntax errors are introduced. +.PP +When invoked as +\fBsudoedit\fR, +the +\fB\-e\fR +option (described below), is implied. +.PP +Security policies may log successful and failed attempts to use +\fBsudo\fR. +If an I/O plugin is configured, the running command's input and +output may be logged as well. +.PP +The options are as follows: +.TP 12n +\fB\-A\fR, \fB\--askpass\fR +Normally, if +\fBsudo\fR +requires a password, it will read it from the user's terminal. +If the +\fB\-A\fR (\fIaskpass\fR) +option is specified, a (possibly graphical) helper program is +executed to read the user's password and output the password to the +standard output. +If the +\fRSUDO_ASKPASS\fR +environment variable is set, it specifies the path to the helper +program. +Otherwise, if +sudo.conf(@mansectform@) +contains a line specifying the askpass program, that value will be +used. +For example: +.nf +.sp +.RS 16n +# Path to askpass helper program +Path askpass /usr/X11R6/bin/ssh-askpass +.RE +.fi +.RS 12n +.sp +If no askpass program is available, +\fBsudo\fR +will exit with an error. +.RE +.if \n(BA \{\ +.TP 12n +\fB\-a\fR \fItype\fR, \fB\--auth-type\fR=\fItype\fR +Use the specified +BSD +authentication +\fItype\fR +when validating the user, if allowed by +\fI/etc/login.conf\fR. +The system administrator may specify a list of sudo-specific +authentication methods by adding an +\(lqauth-sudo\(rq +entry in +\fI/etc/login.conf\fR. +This option is only available on systems that support +BSD +authentication. +.\} +.TP 12n +\fB\-B\fR, \fB\--bell\fR +Ring the bell as part of the password promp when a terminal is present. +This option has no effect if an askpass program is used. +.TP 12n +\fB\-b\fR, \fB\--background\fR +Run the given command in the background. +Note that it is not possible to use shell job control to manipulate +background processes started by +\fBsudo\fR. +Most interactive commands will fail to work properly in background +mode. +.TP 12n +\fB\-C\fR \fInum\fR, \fB\--close-from\fR=\fInum\fR +Close all file descriptors greater than or equal to +\fInum\fR +before executing a command. +Values less than three are not permitted. +By default, +\fBsudo\fR +will close all open file descriptors other than standard input, +standard output and standard error when executing a command. +The security policy may restrict the user's ability to use this option. +The +\fIsudoers\fR +policy only permits use of the +\fB\-C\fR +option when the administrator has enabled the +\fIclosefrom_override\fR +option. +.if \n(LC \{\ +.TP 12n +\fB\-c\fR \fIclass\fR, \fB\--login-class\fR=\fIclass\fR +Run the command with resource limits and scheduling priority of +the specified login +\fIclass\fR. +The +\fIclass\fR +argument can be either a class name as defined in +\fI/etc/login.conf\fR, +or a single +\(oq\-\(cq +character. +If +\fIclass\fR +is +\fB-\fR, +the default login class of the target user will be used. +Otherwise, the command must be run as the superuser (user-ID 0), or +\fBsudo\fR +must be run from a shell that is already running as the superuser. +If the command is being run as a login shell, additional +\fI/etc/login.conf\fR +settings, such as the umask and environment variables, will +be applied, if present. +This option is only available on systems with +BSD +login classes. +.\} +.TP 12n +\fB\-D\fR \fIdirectory\fR, \fB\--chdir\fR=\fIdirectory\fR +Run the command in the specified +\fIdirectory\fR +instead of the current working directory. +The security policy may return an error if the user does not have +permission to specify the working directory. +.TP 12n +\fB\-E\fR, \fB\--preserve-env\fR +Indicates to the security policy that the user wishes to +preserve their existing environment variables. +The security policy may return an error if the user does not have +permission to preserve the environment. +.TP 12n +\fB\--preserve-env=list\fR +Indicates to the security policy that the user wishes to add the +comma-separated list of environment variables to those preserved +from the user's environment. +The security policy may return an error if the user does not have +permission to preserve the environment. +This option may be specified multiple times. +.TP 12n +\fB\-e\fR, \fB\--edit\fR +Edit one or more files instead of running a command. +In lieu of a path name, the string "sudoedit" is used when consulting +the security policy. +If the user is authorized by the policy, the following steps are +taken: +.RS 16n +.TP 5n +1.\& +Temporary copies are made of the files to be edited with the owner +set to the invoking user. +.TP 5n +2.\& +The editor specified by the policy is run to edit the temporary +files. +The +\fIsudoers\fR +policy uses the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +and +\fREDITOR\fR +environment variables (in that order). +If none of +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +are set, the first program listed in the +\fIeditor\fR +sudoers(@mansectform@) +option is used. +.TP 5n +3.\& +If they have been modified, the temporary files are copied back to +their original location and the temporary versions are removed. +.RE +.RS 12n +.sp +To help prevent the editing of unauthorized files, the following +restrictions are enforced unless explicitly allowed by the security policy: +.RS 16n +.TP 3n +\fB\(bu\fR +Symbolic links may not be edited (version 1.8.15 and higher). +.TP 3n +\fB\(bu\fR +Symbolic links along the path to be edited are not followed when the +parent directory is writable by the invoking user unless that user +is root (version 1.8.16 and higher). +.TP 3n +\fB\(bu\fR +Files located in a directory that is writable by the invoking user may +not be edited unless that user is root (version 1.8.16 and higher). +.RE +.sp +Users are never allowed to edit device special files. +.sp +If the specified file does not exist, it will be created. +Note that unlike most commands run by +\fIsudo\fR, +the editor is run with the invoking user's environment unmodified. +If the temporary file becomes empty after editing, the user will +be prompted before it is installed. +If, for some reason, +\fBsudo\fR +is unable to update a file with its edited version, the user will +receive a warning and the edited copy will remain in a temporary +file. +.RE +.TP 12n +\fB\-g\fR \fIgroup\fR, \fB\--group\fR=\fIgroup\fR +Run the command with the primary group set to +\fIgroup\fR +instead of the primary group specified by the target +user's password database entry. +The +\fIgroup\fR +may be either a group name or a numeric group-ID +(GID) +prefixed with the +\(oq#\(cq +character (e.g., +\fR#0\fR +for GID 0). +When running a command as a GID, many shells require that the +\(oq#\(cq +be escaped with a backslash +(\(oq\e\(cq). +If no +\fB\-u\fR +option is specified, the command will be run as the invoking user. +In either case, the primary group will be set to +\fIgroup\fR. +The +\fIsudoers\fR +policy permits any of the target user's groups to be specified via +the +\fB\-g\fR +option as long as the +\fB\-P\fR +option is not in use. +.TP 12n +\fB\-H\fR, \fB\--set-home\fR +Request that the security policy set the +\fRHOME\fR +environment variable to the home directory specified by the target +user's password database entry. +Depending on the policy, this may be the default behavior. +.TP 12n +\fB\-h\fR, \fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-h\fR \fIhost\fR, \fB\--host\fR=\fIhost\fR +Run the command on the specified +\fIhost\fR +if the security policy plugin supports remote commands. +Note that the +\fIsudoers\fR +plugin does not currently support running remote commands. +This may also be used in conjunction with the +\fB\-l\fR +option to list a user's privileges for the remote host. +.TP 12n +\fB\-i\fR, \fB\--login\fR +Run the shell specified by the target user's password database entry +as a login shell. +This means that login-specific resource files such as +\fI.profile\fR, +\fI.bash_profile\fR +or +\fI.login\fR +will be read by the shell. +If a command is specified, it is passed to the shell for execution +via the shell's +\fB\-c\fR +option. +If no command is specified, an interactive shell is executed. +\fBsudo\fR +attempts to change to that user's home directory before running the +shell. +The command is run with an environment similar to the one +a user would receive at log in. +Note that most shells behave differently when a command is specified +as compared to an interactive session; consult the shell's manual +for details. +The +\fICommand environment\fR +section in the +sudoers(@mansectform@) +manual documents how the +\fB\-i\fR +option affects the environment in which a command is run when the +\fIsudoers\fR +policy is in use. +.TP 12n +\fB\-K\fR, \fB\--remove-timestamp\fR +Similar to the +\fB\-k\fR +option, except that it removes the user's cached credentials entirely +and may not be used in conjunction with a command or other option. +This option does not require a password. +Not all security policies support credential caching. +.TP 12n +\fB\-k\fR, \fB\--reset-timestamp\fR +When used without a command, invalidates the user's cached credentials. +In other words, the next time +\fBsudo\fR +is run a password will be required. +This option does not require a password and was added to allow a +user to revoke +\fBsudo\fR +permissions from a +\fI.logout\fR +file. +.sp +When used in conjunction with a command or an option that may require +a password, this option will cause +\fBsudo\fR +to ignore the user's cached credentials. +As a result, +\fBsudo\fR +will prompt for a password (if one is required by the security +policy) and will not update the user's cached credentials. +.sp +Not all security policies support credential caching. +.TP 12n +\fB\-l\fR, \fB\--list\fR +If no +\fIcommand\fR +is specified, +list the allowed (and forbidden) commands for the +invoking user (or the user specified by the +\fB\-U\fR +option) on the current host. +A longer list format is used if this option is specified multiple times +and the security policy supports a verbose output format. +.sp +If a +\fIcommand\fR +is specified and is permitted by the security policy, the fully-qualified +path to the command is displayed along with any command line +arguments. +If a +\fIcommand\fR +is specified but not allowed by the policy, +\fBsudo\fR +will exit with a status value of 1. +.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, +\fBsudo\fR +will display an error message and exit. +.TP 12n +\fB\-P\fR, \fB\--preserve-groups\fR +Preserve the invoking user's group vector unaltered. +By default, the +\fIsudoers\fR +policy will initialize the group vector to the list of groups the +target user is a member of. +The real and effective group-IDs, however, are still set to match +the target user. +.TP 12n +\fB\-p\fR \fIprompt\fR, \fB\--prompt\fR=\fIprompt\fR +Use a custom password prompt with optional escape sequences. +The following percent +(\(oq%\(cq) +escape sequences are supported by the +\fIsudoers\fR +policy: +.PP +.RS 12n +.PD 0 +.TP 4n +\fR%H\fR +expanded to the host name including the domain name (on if the +machine's host name is fully qualified or the +\fIfqdn\fR +option is set in +sudoers(@mansectform@)) +.PD +.TP 4n +\fR%h\fR +expanded to the local host name without the domain name +.TP 4n +\fR%p\fR +expanded to the name of the user whose password is being requested +(respects the +\fIrootpw\fR, +\fItargetpw\fR, +and +\fIrunaspw\fR +flags in +sudoers(@mansectform@)) +.TP 4n +\fR\&%U\fR +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 +expanded to the invoking user's login name +.TP 4n +\fR%%\fR +two consecutive +\(oq%\(cq +characters are collapsed into a single +\(oq%\(cq +character +.PP +The custom prompt will override the default prompt specified by either +the security policy or the +\fRSUDO_PROMPT\fR +environment variable. +On systems that use PAM, the custom prompt will also override the prompt +specified by a PAM module unless the +\fIpassprompt_override\fR +flag is disabled in +\fIsudoers\fR. +.RE +.TP 12n +\fB\-R\fR \fIdirectory\fR, \fB\--chroot\fR=\fIdirectory\fR +Change to the specified root +\fIdirectory\fR +(see +chroot(@mansectsu@)) +before running the command. +The security policy may return an error if the user does not have +permission to specify the root directory. +.if \n(SL \{\ +.TP 12n +\fB\-r\fR \fIrole\fR, \fB\--role\fR=\fIrole\fR +Run the command with an SELinux security context that includes +the specified +\fIrole\fR. +.\} +.TP 12n +\fB\-S\fR, \fB\--stdin\fR +Write the prompt to the standard error and read the password from the +standard input instead of using the terminal device. +.TP 12n +\fB\-s\fR, \fB\--shell\fR +Run the shell specified by the +\fRSHELL\fR +environment variable if it is set or the shell specified by the +invoking user's password database entry. +If a command is specified, it is passed to the shell for execution +via the shell's +\fB\-c\fR +option. +If no command is specified, an interactive shell is executed. +Note that most shells behave differently when a command is specified +as compared to an interactive session; consult the shell's manual +for details. +.if \n(SL \{\ +.TP 12n +\fB\-t\fR \fItype\fR, \fB\--type\fR=\fItype\fR +Run the command with an SELinux security context that includes +the specified +\fItype\fR. +If no +\fItype\fR +is specified, the default type is derived from the role. +.\} +.TP 12n +\fB\-U\fR \fIuser\fR, \fB\--other-user\fR=\fIuser\fR +Used in conjunction with the +\fB\-l\fR +option to list the privileges for +\fIuser\fR +instead of for the invoking user. +The security policy may restrict listing other users' privileges. +The +\fIsudoers\fR +policy only allows root or a user with the +\fRALL\fR +privilege on the current host to use this option. +.TP 12n +\fB\-T\fR \fItimeout\fR, \fB\--command-timeout\fR=\fItimeout\fR +Used to set a timeout for the command. +If the timeout expires before the command has exited, the +command will be terminated. +The security policy may restrict the ability to set command timeouts. +The +\fIsudoers\fR +policy requires that user-specified timeouts be explicitly enabled. +.TP 12n +\fB\-u\fR \fIuser\fR, \fB\--user\fR=\fIuser\fR +Run the command as a user other than the default target user +(usually +\fIroot\fR). +The +\fIuser\fR +may be either a user name or a numeric user-ID +(UID) +prefixed with the +\(oq#\(cq +character (e.g., +\fR#0\fR +for UID 0). +When running commands as a UID, many shells require that the +\(oq#\(cq +be escaped with a backslash +(\(oq\e\(cq). +Some security policies may restrict UIDs +to those listed in the password database. +The +\fIsudoers\fR +policy allows UIDs that are not in the password database as long as the +\fItargetpw\fR +option is not set. +Other security policies may not support this. +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBsudo\fR +version string as well as the version string of the security +policy plugin and any I/O plugins. +If the invoking user is already root the +\fB\-V\fR +option will display the arguments passed to configure when +\fBsudo\fR +was built and plugins may display more verbose information such as +default options. +.TP 12n +\fB\-v\fR, \fB\--validate\fR +Update the user's cached credentials, authenticating the user +if necessary. +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. +Not all security policies support cached credentials. +.TP 12n +\fB\--\fR +The +\fB\--\fR +option indicates that +\fBsudo\fR +should stop processing command line arguments. +.PP +Options that take a value may only be specified once unless +otherwise indicated in the description. +This is to help guard against problems caused by poorly written +scripts that invoke +\fBsudo\fR +with user-controlled input. +.PP +Environment variables to be set for the command may also be passed +on the command line in the form of +\fIVAR\fR=\fIvalue\fR, +e.g., +\fRLD_LIBRARY_PATH\fR=\fI/usr/local/pkg/lib\fR. +Variables passed on the command line are subject to restrictions +imposed by the security policy plugin. +The +\fIsudoers\fR +policy subjects variables passed on the command line to the same +restrictions as normal environment variables with one important +exception. +If the +\fIsetenv\fR +option is set in +\fIsudoers\fR, +the command to be run has the +\fRSETENV\fR +tag set or the command matched is +\fRALL\fR, +the user may set variables that would otherwise be forbidden. +See +sudoers(@mansectform@) +for more information. +.SH "COMMAND EXECUTION" +When +\fBsudo\fR +executes a command, the security policy specifies the execution +environment for the command. +Typically, the real and effective user and group and IDs are set to +match those of the target user, as specified in the password database, +and the group vector is initialized based on the group database +(unless the +\fB\-P\fR +option was specified). +.PP +The following parameters may be specified by security policy: +.TP 3n +\fB\(bu\fR +real and effective user-ID +.TP 3n +\fB\(bu\fR +real and effective group-ID +.TP 3n +\fB\(bu\fR +supplementary group-IDs +.TP 3n +\fB\(bu\fR +the environment list +.TP 3n +\fB\(bu\fR +current working directory +.TP 3n +\fB\(bu\fR +file creation mode mask (umask) +.if \n(SL \{\ +.TP 3n +\fB\(bu\fR +SELinux role and type +.\} +.if \n(PS \{\ +.TP 3n +\fB\(bu\fR +Solaris project +.\} +.if \n(PS \{\ +.TP 3n +\fB\(bu\fR +Solaris privileges +.\} +.if \n(LC \{\ +.TP 3n +\fB\(bu\fR +BSD +login class +.\} +.TP 3n +\fB\(bu\fR +scheduling priority (aka nice value) +.SS "Process model" +There are two distinct ways +\fBsudo\fR +can run a command. +.PP +If an I/O logging plugin is configured or if the security policy +explicitly requests it, a new pseudo-terminal +(\(lqpty\(rq) +is allocated and +fork(2) +is used to create a second +\fBsudo\fR +process, referred to as the +\fImonitor\fR. +The +\fImonitor\fR +creates a new terminal session with itself as the leader and the pty as its +controlling terminal, calls +fork(2), +sets up the execution environment as described above, and then uses the +execve(2) +system call to run the command in the child process. +The +\fImonitor\fR +exists to relay job control signals between the user's +existing terminal and the pty the command is being run in. +This makes it possible to suspend and resume the command. +Without the monitor, the command would be in what POSIX terms an +\(lqorphaned process group\(rq +and it would not receive any job control signals from the kernel. +When the command exits or is terminated by a signal, the +\fImonitor\fR +passes the command's exit status to the main +\fBsudo\fR +process and exits. +After receiving the command's exit status, the main +\fBsudo\fR +passes the command's exit status to the security policy's close function +and exits. +.PP +If no pty is used, +\fBsudo\fR +calls +fork(2), +sets up the execution environment as described above, and uses the +execve(2) +system call to run the command in the child process. +The main +\fBsudo\fR +process waits until the command has completed, then passes the +command's exit status to the security policy's close function and exits. +As a special case, if the policy plugin does not define a close +function, +\fBsudo\fR +will execute the command directly instead of calling +fork(2) +first. +The +\fIsudoers\fR +policy plugin will only define a close function when I/O logging +is enabled, a pty is required, or the +\fIpam_session\fR +or +\fIpam_setcred\fR +options are enabled. +Note that +\fIpam_session\fR +and +\fIpam_setcred\fR +are enabled by default on systems using PAM. +.PP +On systems that use PAM, the security policy's close function +is responsible for closing the PAM session. +It may also log the command's exit status. +.SS "Signal handling" +When the command is run as a child of the +\fBsudo\fR +process, +\fBsudo\fR +will relay signals it receives to the command. +The +\fRSIGINT\fR +and +\fRSIGQUIT\fR +signals are only relayed when the command is being run in a new pty +or when the signal was sent by a user process, not the kernel. +This prevents the command from receiving +\fRSIGINT\fR +twice each time the user enters control-C. +Some signals, such as +\fRSIGSTOP\fR +and +\fRSIGKILL\fR, +cannot be caught and thus will not be relayed to the command. +As a general rule, +\fRSIGTSTP\fR +should be used instead of +\fRSIGSTOP\fR +when you wish to suspend a command being run by +\fBsudo\fR. +.PP +As a special case, +\fBsudo\fR +will not relay signals that were sent by the command it is running. +This prevents the command from accidentally killing itself. +On some systems, the +reboot(@mansectsu@) +command sends +\fRSIGTERM\fR +to all non-system processes other than itself before rebooting +the system. +This prevents +\fBsudo\fR +from relaying the +\fRSIGTERM\fR +signal it received back to +reboot(@mansectsu@), +which might then exit before the system was actually rebooted, +leaving it in a half-dead state similar to single user mode. +Note, however, that this check only applies to the command run by +\fBsudo\fR +and not any other processes that the command may create. +As a result, running a script that calls +reboot(@mansectsu@) +or +shutdown(@mansectsu@) +via +\fBsudo\fR +may cause the system to end up in this undefined state unless the +reboot(@mansectsu@) +or +shutdown(@mansectsu@) +are run using the +\fBexec\fR() +family of functions instead of +\fBsystem\fR() +(which interposes a shell between the command and the calling process). +.PP +If no I/O logging plugins are loaded and the policy plugin has not +defined a +\fBclose\fR() +function, set a command timeout or required that the command be +run in a new pty, +\fBsudo\fR +may execute the command directly instead of running it as a child process. +.SS "Plugins" +Plugins may be specified via +\fRPlugin\fR +directives in the +sudo.conf(@mansectform@) +file. +They may be loaded as dynamic shared objects (on systems that support them), +or compiled directly into the +\fBsudo\fR +binary. +If no +sudo.conf(@mansectform@) +file is present, or if it doesn't contain any +\fRPlugin\fR +lines, +\fBsudo\fR +will use +sudoers(@mansectform@) +for the policy, auditing and I/O logging plugins. +See the +sudo.conf(@mansectform@) +manual for details of the +\fI@sysconfdir@/sudo.conf\fR +file and the +sudo_plugin(@mansectform@) +manual for more information about the +\fBsudo\fR +plugin architecture. +.SH "EXIT VALUE" +Upon successful execution of a command, the exit status from +\fBsudo\fR +will be the exit status of the program that was executed. +If the command terminated due to receipt of a signal, +\fBsudo\fR +will send itself the same signal that terminated the command. +.PP +If the +\fB\-l\fR +option was specified without a command, +\fBsudo\fR +will exit with a value of 0 if the user is allowed to run +\fBsudo\fR +and they authenticated successfully (as required by the security policy). +If a command is specified with the +\fB\-l\fR +option, the exit value will only be 0 if the command is permitted by the +security policy, otherwise it will be 1. +.PP +If there is an authentication failure, a configuration/permission +problem or if the given command cannot be executed, +\fBsudo\fR +exits with a value of 1. +In the latter case, the error string is printed to the standard error. +If +\fBsudo\fR +cannot +stat(2) +one or more entries in the user's +\fRPATH\fR, +an error is printed to the standard error. +(If the directory does not exist or if it is not really a directory, +the entry is ignored and no error is printed.) +This should not happen under normal circumstances. +The most common reason for +stat(2) +to return +\(lqpermission denied\(rq +is if you are running an automounter and one of the directories in +your +\fRPATH\fR +is on a machine that is currently unreachable. +.SH "SECURITY NOTES" +\fBsudo\fR +tries to be safe when executing external commands. +.PP +To prevent command spoofing, +\fBsudo\fR +checks "." and "" (both denoting current directory) last when +searching for a command in the user's +\fRPATH\fR +(if one or both are in the +\fRPATH\fR). +Note, however, that the actual +\fRPATH\fR +environment variable is +\fInot\fR +modified and is passed unchanged to the program that +\fBsudo\fR +executes. +.PP +Users should +\fInever\fR +be granted +\fBsudo\fR +privileges to execute files that are writable by the user or +that reside in a directory that is writable by the user. +If the user can modify or replace the command there is no way +to limit what additional commands they can run. +.PP +Please note that +\fBsudo\fR +will normally only log the command it explicitly runs. +If a user runs a command such as +\fRsudo su\fR +or +\fRsudo sh\fR, +subsequent commands run from that shell are not subject to +\fBsudo\fR's +security policy. +The same is true for commands that offer shell escapes (including +most editors). +If I/O logging is enabled, subsequent commands will have their input and/or +output logged, but there will not be traditional logs for those commands. +Because of this, care must be taken when giving users access to commands via +\fBsudo\fR +to verify that the command does not inadvertently give the user an +effective root shell. +For more information, please see the +\fIPreventing shell escapes\fR +section in +sudoers(@mansectform@). +.PP +To prevent the disclosure of potentially sensitive information, +\fBsudo\fR +disables core dumps by default while it is executing (they are +re-enabled for the command that is run). +This historical practice dates from a time when most operating +systems allowed set-user-ID processes to dump core by default. +To aid in debugging +\fBsudo\fR +crashes, you may wish to re-enable core dumps by setting +\(lqdisable_coredump\(rq +to false in the +sudo.conf(@mansectform@) +file as follows: +.nf +.sp +.RS 6n +Set disable_coredump false +.RE +.fi +.PP +See the +sudo.conf(@mansectform@) +manual for more information. +.SH "ENVIRONMENT" +\fBsudo\fR +utilizes the following environment variables. +The security policy has control over the actual content of the command's +environment. +.TP 17n +\fREDITOR\fR +Default editor to use in +\fB\-e\fR +(sudoedit) mode if neither +\fRSUDO_EDITOR\fR +nor +\fRVISUAL\fR +is set. +.TP 17n +\fRMAIL\fR +Set to the mail spool of the target user when the +\fB\-i\fR +option is specified or when +\fIenv_reset\fR +is enabled in +\fIsudoers\fR +(unless +\fRMAIL\fR +is present in the +\fIenv_keep\fR +list). +.TP 17n +\fRHOME\fR +Set to the home directory of the target user when the +\fB\-i\fR +or +\fB\-H\fR +options are specified, when the +\fB\-s\fR +option is specified and +\fIset_home\fR +is set in +\fIsudoers\fR, +when +\fIalways_set_home\fR +is enabled in +\fIsudoers\fR, +or when +\fIenv_reset\fR +is enabled in +\fIsudoers\fR +and +\fIHOME\fR +is not present in the +\fIenv_keep\fR +list. +.TP 17n +\fRLOGNAME\fR +Set to the login name of the target user when the +\fB\-i\fR +option is specified, when the +\fIset_logname\fR +option is enabled in +\fIsudoers\fR +or when the +\fIenv_reset\fR +option is enabled in +\fIsudoers\fR +(unless +\fRLOGNAME\fR +is present in the +\fIenv_keep\fR +list). +.TP 17n +\fRPATH\fR +May be overridden by the security policy. +.TP 17n +\fRSHELL\fR +Used to determine shell to run with +\fB\-s\fR +option. +.TP 17n +\fRSUDO_ASKPASS\fR +Specifies the path to a helper program used to read the password +if no terminal is available or if the +\fB\-A\fR +option is specified. +.TP 17n +\fRSUDO_COMMAND\fR +Set to the command run by sudo, including command line arguments. +The command line arguments are truncated at 4096 characters to +prevent a potential execution error. +.TP 17n +\fRSUDO_EDITOR\fR +Default editor to use in +\fB\-e\fR +(sudoedit) mode. +.TP 17n +\fRSUDO_GID\fR +Set to the group-ID of the user who invoked sudo. +.TP 17n +\fRSUDO_PROMPT\fR +Used as the default password prompt unless +the +\fB\-p\fR +option was specified. +.TP 17n +\fRSUDO_PS1\fR +If set, +\fRPS1\fR +will be set to its value for the program being run. +.TP 17n +\fRSUDO_UID\fR +Set to the user-ID of the user who invoked sudo. +.TP 17n +\fRSUDO_USER\fR +Set to the login name of the user who invoked sudo. +.TP 17n +\fRUSER\fR +Set to the same value as +\fRLOGNAME\fR, +described above. +.TP 17n +\fRVISUAL\fR +Default editor to use in +\fB\-e\fR +(sudoedit) mode if +\fRSUDO_EDITOR\fR +is not set. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +\fBsudo\fR +front end configuration +.SH "EXAMPLES" +Note: the following examples assume a properly configured security +policy. +.PP +To get a file listing of an unreadable directory: +.nf +.sp +.RS 6n +$ sudo ls /usr/local/protected +.RE +.fi +.PP +To list the home directory of user yaz on a machine where the file +system holding ~yaz is not exported as root: +.nf +.sp +.RS 6n +$ sudo -u yaz ls ~yaz +.RE +.fi +.PP +To edit the +\fIindex.html\fR +file as user www: +.nf +.sp +.RS 6n +$ sudoedit -u www ~www/htdocs/index.html +.RE +.fi +.PP +To view system logs only accessible to root and users in the adm +group: +.nf +.sp +.RS 6n +$ sudo -g adm more /var/log/syslog +.RE +.fi +.PP +To run an editor as jim with a different primary group: +.nf +.sp +.RS 6n +$ sudoedit -u jim -g audio ~jim/sound.txt +.RE +.fi +.PP +To shut down a machine: +.nf +.sp +.RS 6n +$ sudo shutdown -r +15 "quick reboot" +.RE +.fi +.PP +To make a usage listing of the directories in the /home partition. +Note that this runs the commands in a sub-shell to make the +\fRcd\fR +and file redirection work. +.nf +.sp +.RS 6n +$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE" +.RE +.fi +.SH "DIAGNOSTICS" +Error messages produced by +\fBsudo\fR +include: +.TP 6n +\fRediting files in a writable directory is not permitted\fR +By default, +\fBsudoedit\fR +does not permit editing a file when any of the parent directories are writable +by the invoking user. +This avoids a race condition that could allow the user to overwrite +an arbitrary file. +See the +\fIsudoedit_checkdir\fR +option in +sudoers(@mansectform@) +for more information. +.TP 6n +\fRediting symbolic links is not permitted\fR +By default, +\fBsudoedit\fR +does not follow symbolic links when opening files. +See the +\fIsudoedit_follow\fR +option in +sudoers(@mansectform@) +for more information. +.TP 6n +\fReffective uid is not 0, is sudo installed setuid root?\fR +\fBsudo\fR +was not run with root privileges. +The +\fBsudo\fR +binary must be owned by the root user and have the set-user-ID bit set. +Also, it must not be located on a file system mounted with the +\(oqnosuid\(cq +option or on an NFS file system that maps uid 0 to an unprivileged uid. +.TP 6n +\fReffective uid is not 0, is sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?\fR +\fBsudo\fR +was not run with root privileges. +The +\fBsudo\fR +binary has the proper owner and permissions but it still did not run +with root privileges. +The most common reason for this is that the file system the +\fBsudo\fR +binary is located on is mounted with the +\(oqnosuid\(cq +option or it is an NFS file system that maps uid 0 to an unprivileged uid. +.TP 6n +\fRfatal error, unable to load plugins\fR +An error occurred while loading or initializing the plugins specified in +sudo.conf(@mansectform@). +.TP 6n +\fRinvalid environment variable name\fR +One or more environment variable names specified via the +\fB\-E\fR +option contained an equal sign +(\(oq=\(cq). +The arguments to the +\fB\-E\fR +option should be environment variable names without an associated value. +.TP 6n +\fRno password was provided\fR +When +\fBsudo\fR +tried to read the password, it did not receive any characters. +This may happen if no terminal is available (or the +\fB\-S\fR +option is specified) and the standard input has been redirected from +\fI/dev/null\fR. +.TP 6n +\fRa terminal is required to read the password\fR +\fBsudo\fR +needs to read the password but there is no mechanism available for it +to do so. +A terminal is not present to read the password from, +\fBsudo\fR +has not been configured to read from the standard input, +the +\fB\-S\fR +option was not used, and no askpass helper has been specified either via the +sudo.conf(@mansectform@) +file or the +\fRSUDO_ASKPASS\fR +environment variable. +.TP 6n +\fRno writable temporary directory found\fR +\fBsudoedit\fR +was unable to find a usable temporary directory in which to store its +intermediate files. +.TP 6n +\fRsudo must be owned by uid 0 and have the setuid bit set\fR +\fBsudo\fR +was not run with root privileges. +The +\fBsudo\fR +binary does not have the correct owner or permissions. +It must be owned by the root user and have the set-user-ID bit set. +.TP 6n +\fRsudoedit is not supported on this platform\fR +It is only possible to run +\fBsudoedit\fR +on systems that support setting the effective user-ID. +.TP 6n +\fRtimed out reading password\fR +The user did not enter a password before the password timeout +(5 minutes by default) expired. +.TP 6n +\fRyou do not exist in the passwd database\fR +Your user-ID does not appear in the system passwd database. +.TP 6n +\fRyou may not specify environment variables in edit mode\fR +It is only possible to specify environment variables when running +a command. +When editing a file, the editor is run with the user's environment unmodified. +.SH "SEE ALSO" +su(1), +stat(2), +login_cap(3), +passwd(@mansectform@), +sudo.conf(@mansectform@), +sudo_plugin(@mansectform@), +sudoers(@mansectform@), +sudoers_timestamp(@mansectform@), +sudoreplay(@mansectsu@), +visudo(@mansectsu@) +.SH "HISTORY" +See the HISTORY file in the +\fBsudo\fR +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "CAVEATS" +There is no easy way to prevent a user from gaining a root shell +if that user is allowed to run arbitrary commands via +\fBsudo\fR. +Also, many programs (such as editors) allow the user to run commands +via shell escapes, thus avoiding +\fBsudo\fR's +checks. +However, on most systems it is possible to prevent shell escapes with the +sudoers(@mansectform@) +plugin's +\fInoexec\fR +functionality. +.PP +It is not meaningful to run the +\fRcd\fR +command directly via sudo, e.g., +.nf +.sp +.RS 6n +$ sudo cd /usr/local/protected +.RE +.fi +.PP +since when the command exits the parent process (your shell) will +still be the same. +Please see the +\fIEXAMPLES\fR +section for more information. +.PP +Running shell scripts via +\fBsudo\fR +can expose the same kernel bugs that make set-user-ID shell scripts +unsafe on some operating systems (if your OS has a /dev/fd/ directory, +set-user-ID shell scripts are generally safe). +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo.man.in.sed b/doc/sudo.man.in.sed new file mode 100644 index 0000000..432dd74 --- /dev/null +++ b/doc/sudo.man.in.sed @@ -0,0 +1,76 @@ +s/^\(.TH .*\)/.nr SL @SEMAN@\ +.nr BA @BAMAN@\ +.nr LC @LCMAN@\ +.nr PS @PSMAN@\ +\1/ + +s/^\(\[\\fB\\-a\\fR.*\\fItype\\fR\]\) *$/.if \\n(BA \1/ +s/^\(\[\\fB\\-c\\fR.*\\fIclass\\fR\]\) *$/.if \\n(LC \1/ +s/^\(\[\\fB\\-r\\fR.*\\fIrole\\fR\]\) *$/.if \\n(SL \1/ +s/^\(\[\\fB\\-t\\fR.*\\fItype\\fR\]\) *$/.if \\n(SL \1/ + +/^\.TP 12n$/ { + N + /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/,/^\.TP 12n/ { + /^\.TP 12n/ { + /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/i\ +.if \\n(BA \\{\\ + /^\.TP 12n\n\\fB\\-a\\fR.*\\fItype\\fR$/!i\ +.\\} + } + } + /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/,/^\.TP 12n/ { + /^\.TP 12n/ { + /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/i\ +.if \\n(LC \\{\\ + /^\.TP 12n\n\\fB\\-c\\fR.*\\fIclass\\fR$/!i\ +.\\} + } + } + /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/,/^\.TP 12n/ { + /^\.TP 12n/ { + /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/i\ +.if \\n(SL \\{\\ + /^\.TP 12n\n\\fB\\-r\\fR.*\\fIrole\\fR$/!i\ +.\\} + } + } + /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/,/^\.TP 12n/ { + /^\.TP 12n/ { + /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/i\ +.if \\n(SL \\{\\ + /^\.TP 12n\n\\fB\\-t\\fR.*\\fItype\\fR$/!i\ +.\\} + } + } +} + +/^\.TP 3n$/ { + N + N + /^.TP 3n\n\\fB\\(bu\\fR\nSELinux role and type$/ { + i\ +.if \\n(SL \\{\\ + a\ +.\\} + } + /^.TP 3n\n\\fB\\(bu\\fR\nSolaris project$/ { + i\ +.if \\n(PS \\{\\ + a\ +.\\} + } + /^.TP 3n\n\\fB\\(bu\\fR\nSolaris privileges$/ { + i\ +.if \\n(PS \\{\\ + a\ +.\\} + } + /^.TP 3n\n\\fB\\(bu\\fR\nBSD$/ { + N + i\ +.if \\n(LC \\{\\ + a\ +.\\} + } +} diff --git a/doc/sudo.mdoc.in b/doc/sudo.mdoc.in new file mode 100644 index 0000000..fd2d205 --- /dev/null +++ b/doc/sudo.mdoc.in @@ -0,0 +1,1383 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1994-1996, 1998-2005, 2007-2020 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.nr SL @SEMAN@ +.nr BA @BAMAN@ +.nr LC @LCMAN@ +.nr PS @PSMAN@ +.Dd September 1, 2020 +.Dt SUDO @mansectsu@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo , +.Nm sudoedit +.Nd execute a command as another user +.Sh SYNOPSIS +.Nm sudo +.Fl h | K | k | V +.Nm sudo +.Fl v +.Op Fl ABknS +.if \n(BA \{\ +.Op Fl a Ar type +.\} +.Op Fl g Ar group +.Op Fl h Ar host +.Op Fl p Ar prompt +.Op Fl u Ar user +.Nm sudo +.Fl l +.Op Fl ABknS +.if \n(BA \{\ +.Op Fl a Ar type +.\} +.Op Fl g Ar group +.Op Fl h Ar host +.Op Fl p Ar prompt +.Op Fl U Ar user +.Op Fl u Ar user +.Op Ar command +.Nm sudo +.Op Fl ABbEHnPS +.if \n(BA \{\ +.Op Fl a Ar type +.\} +.Op Fl C Ar num +.if \n(LC \{\ +.Op Fl c Ar class +.\} +.Op Fl D Ar directory +.Op Fl g Ar group +.Op Fl h Ar host +.Op Fl p Ar prompt +.Op Fl R Ar directory +.if \n(SL \{\ +.Op Fl r Ar role +.Op Fl t Ar type +.\} +.Op Fl T Ar timeout +.Op Fl u Ar user +.Op Ar VAR Ns = Ns Ar value +.Op Fl i | s +.Op Ar command +.Nm sudoedit +.Op Fl ABknS +.if \n(BA \{\ +.Op Fl a Ar type +.\} +.Op Fl C Ar num +.if \n(LC \{\ +.Op Fl c Ar class +.\} +.Op Fl D Ar directory +.Op Fl g Ar group +.Op Fl h Ar host +.Op Fl p Ar prompt +.Op Fl R Ar directory +.if \n(SL \{\ +.Op Fl r Ar role +.Op Fl t Ar type +.\} +.Op Fl T Ar timeout +.Op Fl u Ar user +.Ar +.Sh DESCRIPTION +.Nm +allows a permitted user to execute a +.Ar command +as the superuser or another user, as specified by the security +policy. +The invoking user's real +.Pq Em not No effective +user-ID is used to determine the user name with which +to query the security policy. +.Pp +.Nm +supports a plugin architecture for security policies and input/output +logging. +Third parties can develop and distribute their own policy and I/O +logging plugins to work seamlessly with the +.Nm +front end. +The default security policy is +.Em sudoers , +which is configured via the file +.Pa @sysconfdir@/sudoers , +or via LDAP. +See the +.Sx Plugins +section for more information. +.Pp +The security policy determines what privileges, if any, a user has +to run +.Nm . +The policy may require that users authenticate themselves with a +password or another authentication mechanism. +If authentication is required, +.Nm +will exit if the user's password is not entered within a configurable +time limit. +This limit is policy-specific; the default password prompt timeout +for the +.Em sudoers +security policy is +.Li @password_timeout@ +minutes. +.Pp +Security policies may support credential caching to allow the user +to run +.Nm +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. +See the +.Em timestamp_type +and +.Em timestamp_timeout +options in +.Xr sudoers @mansectform@ +for more information. +By running +.Nm +with the +.Fl v +option, a user can update the cached credentials without running a +.Ar command . +.Pp +On systems where +.Nm +is the primary method of gaining superuser privileges, it is imperative +to avoid syntax errors in the security policy configuration files. +For the default security policy, +.Xr sudoers @mansectform@ , +changes to the configuration files should be made using the +.Xr visudo @mansectsu@ +utility which will ensure that no syntax errors are introduced. +.Pp +When invoked as +.Nm sudoedit , +the +.Fl e +option (described below), is implied. +.Pp +Security policies may log successful and failed attempts to use +.Nm . +If an I/O plugin is configured, the running command's input and +output may be logged as well. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl A , -askpass +Normally, if +.Nm +requires a password, it will read it from the user's terminal. +If the +.Fl A Pq Em askpass +option is specified, a (possibly graphical) helper program is +executed to read the user's password and output the password to the +standard output. +If the +.Ev SUDO_ASKPASS +environment variable is set, it specifies the path to the helper +program. +Otherwise, if +.Xr sudo.conf @mansectform@ +contains a line specifying the askpass program, that value will be +used. +For example: +.Bd -literal -offset 4n +# Path to askpass helper program +Path askpass /usr/X11R6/bin/ssh-askpass +.Ed +.Pp +If no askpass program is available, +.Nm +will exit with an error. +.if \n(BA \{\ +.It Fl a Ar type , Fl -auth-type Ns = Ns Ar type +Use the specified +.Bx +authentication +.Ar type +when validating the user, if allowed by +.Pa /etc/login.conf . +The system administrator may specify a list of sudo-specific +authentication methods by adding an +.Dq auth-sudo +entry in +.Pa /etc/login.conf . +This option is only available on systems that support +.Bx +authentication. +.\} +.It Fl B , -bell +Ring the bell as part of the password promp when a terminal is present. +This option has no effect if an askpass program is used. +.It Fl b , -background +Run the given command in the background. +Note that it is not possible to use shell job control to manipulate +background processes started by +.Nm . +Most interactive commands will fail to work properly in background +mode. +.It Fl C Ar num , Fl -close-from Ns = Ns Ar num +Close all file descriptors greater than or equal to +.Ar num +before executing a command. +Values less than three are not permitted. +By default, +.Nm +will close all open file descriptors other than standard input, +standard output and standard error when executing a command. +The security policy may restrict the user's ability to use this option. +The +.Em sudoers +policy only permits use of the +.Fl C +option when the administrator has enabled the +.Em closefrom_override +option. +.if \n(LC \{\ +.It Fl c Ar class , Fl -login-class Ns = Ns Ar class +Run the command with resource limits and scheduling priority of +the specified login +.Ar class . +The +.Ar class +argument can be either a class name as defined in +.Pa /etc/login.conf , +or a single +.Ql \- +character. +If +.Ar class +is +.Cm - , +the default login class of the target user will be used. +Otherwise, the command must be run as the superuser (user-ID 0), or +.Nm +must be run from a shell that is already running as the superuser. +If the command is being run as a login shell, additional +.Pa /etc/login.conf +settings, such as the umask and environment variables, will +be applied, if present. +This option is only available on systems with +.Bx +login classes. +.\} +.It Fl D Ar directory , Fl -chdir Ns = Ns Ar directory +Run the command in the specified +.Ar directory +instead of the current working directory. +The security policy may return an error if the user does not have +permission to specify the working directory. +.It Fl E , -preserve-env +Indicates to the security policy that the user wishes to +preserve their existing environment variables. +The security policy may return an error if the user does not have +permission to preserve the environment. +.It Fl -preserve-env=list +Indicates to the security policy that the user wishes to add the +comma-separated list of environment variables to those preserved +from the user's environment. +The security policy may return an error if the user does not have +permission to preserve the environment. +This option may be specified multiple times. +.It Fl e , -edit +Edit one or more files instead of running a command. +In lieu of a path name, the string "sudoedit" is used when consulting +the security policy. +If the user is authorized by the policy, the following steps are +taken: +.Bl -enum -offset 4 +.It +Temporary copies are made of the files to be edited with the owner +set to the invoking user. +.It +The editor specified by the policy is run to edit the temporary +files. +The +.Em sudoers +policy uses the +.Ev SUDO_EDITOR , +.Ev VISUAL +and +.Ev EDITOR +environment variables (in that order). +If none of +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +are set, the first program listed in the +.Em editor +.Xr sudoers @mansectform@ +option is used. +.It +If they have been modified, the temporary files are copied back to +their original location and the temporary versions are removed. +.El +.Pp +To help prevent the editing of unauthorized files, the following +restrictions are enforced unless explicitly allowed by the security policy: +.Bl -bullet -offset 4 -width 1n +.It +Symbolic links may not be edited (version 1.8.15 and higher). +.It +Symbolic links along the path to be edited are not followed when the +parent directory is writable by the invoking user unless that user +is root (version 1.8.16 and higher). +.It +Files located in a directory that is writable by the invoking user may +not be edited unless that user is root (version 1.8.16 and higher). +.El +.Pp +Users are never allowed to edit device special files. +.Pp +If the specified file does not exist, it will be created. +Note that unlike most commands run by +.Em sudo , +the editor is run with the invoking user's environment unmodified. +If the temporary file becomes empty after editing, the user will +be prompted before it is installed. +If, for some reason, +.Nm +is unable to update a file with its edited version, the user will +receive a warning and the edited copy will remain in a temporary +file. +.It Fl g Ar group , Fl -group Ns = Ns Ar group +Run the command with the primary group set to +.Ar group +instead of the primary group specified by the target +user's password database entry. +The +.Ar group +may be either a group name or a numeric group-ID +.Pq GID +prefixed with the +.Ql # +character (e.g., +.Li #0 +for GID 0). +When running a command as a GID, many shells require that the +.Ql # +be escaped with a backslash +.Pq Ql \e . +If no +.Fl u +option is specified, the command will be run as the invoking user. +In either case, the primary group will be set to +.Ar group . +The +.Em sudoers +policy permits any of the target user's groups to be specified via +the +.Fl g +option as long as the +.Fl P +option is not in use. +.It Fl H , -set-home +Request that the security policy set the +.Ev HOME +environment variable to the home directory specified by the target +user's password database entry. +Depending on the policy, this may be the default behavior. +.It Fl h , -help +Display a short help message to the standard output and exit. +.It Fl h Ar host , Fl -host Ns = Ns Ar host +Run the command on the specified +.Ar host +if the security policy plugin supports remote commands. +Note that the +.Em sudoers +plugin does not currently support running remote commands. +This may also be used in conjunction with the +.Fl l +option to list a user's privileges for the remote host. +.It Fl i , -login +Run the shell specified by the target user's password database entry +as a login shell. +This means that login-specific resource files such as +.Pa .profile , +.Pa .bash_profile +or +.Pa .login +will be read by the shell. +If a command is specified, it is passed to the shell for execution +via the shell's +.Fl c +option. +If no command is specified, an interactive shell is executed. +.Nm +attempts to change to that user's home directory before running the +shell. +The command is run with an environment similar to the one +a user would receive at log in. +Note that most shells behave differently when a command is specified +as compared to an interactive session; consult the shell's manual +for details. +The +.Em Command environment +section in the +.Xr sudoers @mansectform@ +manual documents how the +.Fl i +option affects the environment in which a command is run when the +.Em sudoers +policy is in use. +.It Fl K , -remove-timestamp +Similar to the +.Fl k +option, except that it removes the user's cached credentials entirely +and may not be used in conjunction with a command or other option. +This option does not require a password. +Not all security policies support credential caching. +.It Fl k , -reset-timestamp +When used without a command, invalidates the user's cached credentials. +In other words, the next time +.Nm +is run a password will be required. +This option does not require a password and was added to allow a +user to revoke +.Nm +permissions from a +.Pa .logout +file. +.Pp +When used in conjunction with a command or an option that may require +a password, this option will cause +.Nm +to ignore the user's cached credentials. +As a result, +.Nm +will prompt for a password (if one is required by the security +policy) and will not update the user's cached credentials. +.Pp +Not all security policies support credential caching. +.It Fl l , Fl -list +If no +.Ar command +is specified, +list the allowed (and forbidden) commands for the +invoking user (or the user specified by the +.Fl U +option) on the current host. +A longer list format is used if this option is specified multiple times +and the security policy supports a verbose output format. +.Pp +If a +.Ar command +is specified and is permitted by the security policy, the fully-qualified +path to the command is displayed along with any command line +arguments. +If a +.Ar command +is specified but not allowed by the policy, +.Nm +will exit with a status value of 1. +.It Fl n , -non-interactive +Avoid prompting the user for input of any kind. +If a password is required for the command to run, +.Nm +will display an error message and exit. +.It Fl P , -preserve-groups +Preserve the invoking user's group vector unaltered. +By default, the +.Em sudoers +policy will initialize the group vector to the list of groups the +target user is a member of. +The real and effective group-IDs, however, are still set to match +the target user. +.It Fl p Ar prompt , Fl -prompt Ns = Ns Ar prompt +Use a custom password prompt with optional escape sequences. +The following percent +.Pq Ql % +escape sequences are supported by the +.Em sudoers +policy: +.Bl -tag -width 2n +.It Li %H +expanded to the host name including the domain name (on if the +machine's host name is fully qualified or the +.Em fqdn +option is set in +.Xr sudoers @mansectform@ ) +.It Li %h +expanded to the local host name without the domain name +.It Li %p +expanded to the name of the user whose password is being requested +(respects the +.Em rootpw , +.Em targetpw , +and +.Em runaspw +flags in +.Xr sudoers @mansectform@ ) +.It Li \&%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 +expanded to the invoking user's login name +.It Li %% +two consecutive +.Ql % +characters are collapsed into a single +.Ql % +character +.El +.Pp +The custom prompt will override the default prompt specified by either +the security policy or the +.Ev SUDO_PROMPT +environment variable. +On systems that use PAM, the custom prompt will also override the prompt +specified by a PAM module unless the +.Em passprompt_override +flag is disabled in +.Em sudoers . +.It Fl R Ar directory , Fl -chroot Ns = Ns Ar directory +Change to the specified root +.Ar directory +(see +.Xr chroot @mansectsu@ ) +before running the command. +The security policy may return an error if the user does not have +permission to specify the root directory. +.if \n(SL \{\ +.It Fl r Ar role , Fl -role Ns = Ns Ar role +Run the command with an SELinux security context that includes +the specified +.Ar role . +.\} +.It Fl S , -stdin +Write the prompt to the standard error and read the password from the +standard input instead of using the terminal device. +.It Fl s , -shell +Run the shell specified by the +.Ev SHELL +environment variable if it is set or the shell specified by the +invoking user's password database entry. +If a command is specified, it is passed to the shell for execution +via the shell's +.Fl c +option. +If no command is specified, an interactive shell is executed. +Note that most shells behave differently when a command is specified +as compared to an interactive session; consult the shell's manual +for details. +.if \n(SL \{\ +.It Fl t Ar type , Fl -type Ns = Ns Ar type +Run the command with an SELinux security context that includes +the specified +.Ar type . +If no +.Ar type +is specified, the default type is derived from the role. +.\} +.It Fl U Ar user , Fl -other-user Ns = Ns Ar user +Used in conjunction with the +.Fl l +option to list the privileges for +.Ar user +instead of for the invoking user. +The security policy may restrict listing other users' privileges. +The +.Em sudoers +policy only allows root or a user with the +.Li ALL +privilege on the current host to use this option. +.It Fl T Ar timeout , Fl -command-timeout Ns = Ns Ar timeout +Used to set a timeout for the command. +If the timeout expires before the command has exited, the +command will be terminated. +The security policy may restrict the ability to set command timeouts. +The +.Em sudoers +policy requires that user-specified timeouts be explicitly enabled. +.It Fl u Ar user , Fl -user Ns = Ns Ar user +Run the command as a user other than the default target user +(usually +.Em root ) . +The +.Ar user +may be either a user name or a numeric user-ID +.Pq UID +prefixed with the +.Ql # +character (e.g., +.Li #0 +for UID 0). +When running commands as a UID, many shells require that the +.Ql # +be escaped with a backslash +.Pq Ql \e . +Some security policies may restrict UIDs +to those listed in the password database. +The +.Em sudoers +policy allows UIDs that are not in the password database as long as the +.Em targetpw +option is not set. +Other security policies may not support this. +.It Fl V , -version +Print the +.Nm +version string as well as the version string of the security +policy plugin and any I/O plugins. +If the invoking user is already root the +.Fl V +option will display the arguments passed to configure when +.Nm +was built and plugins may display more verbose information such as +default options. +.It Fl v , -validate +Update the user's cached credentials, authenticating the user +if necessary. +For the +.Em sudoers +plugin, this extends the +.Nm +timeout for another +.Li @timeout@ +minutes by default, but does not run a command. +Not all security policies support cached credentials. +.It Fl - +The +.Fl - +option indicates that +.Nm +should stop processing command line arguments. +.El +.Pp +Options that take a value may only be specified once unless +otherwise indicated in the description. +This is to help guard against problems caused by poorly written +scripts that invoke +.Nm sudo +with user-controlled input. +.Pp +Environment variables to be set for the command may also be passed +on the command line in the form of +.Ar VAR Ns = Ns Ar value , +e.g., +.Ev LD_LIBRARY_PATH Ns = Ns Pa /usr/local/pkg/lib . +Variables passed on the command line are subject to restrictions +imposed by the security policy plugin. +The +.Em sudoers +policy subjects variables passed on the command line to the same +restrictions as normal environment variables with one important +exception. +If the +.Em setenv +option is set in +.Em sudoers , +the command to be run has the +.Li SETENV +tag set or the command matched is +.Li ALL , +the user may set variables that would otherwise be forbidden. +See +.Xr sudoers @mansectform@ +for more information. +.Sh COMMAND EXECUTION +When +.Nm +executes a command, the security policy specifies the execution +environment for the command. +Typically, the real and effective user and group and IDs are set to +match those of the target user, as specified in the password database, +and the group vector is initialized based on the group database +(unless the +.Fl P +option was specified). +.Pp +The following parameters may be specified by security policy: +.Bl -bullet -width 1n +.It +real and effective user-ID +.It +real and effective group-ID +.It +supplementary group-IDs +.It +the environment list +.It +current working directory +.It +file creation mode mask (umask) +.if \n(SL \{\ +.It +SELinux role and type +.\} +.if \n(PS \{\ +.It +Solaris project +.It +Solaris privileges +.\} +.if \n(LC \{\ +.It +.Bx +login class +.\} +.It +scheduling priority (aka nice value) +.El +.Ss Process model +There are two distinct ways +.Nm +can run a command. +.Pp +If an I/O logging plugin is configured or if the security policy +explicitly requests it, a new pseudo-terminal +.Pq Dq pty +is allocated and +.Xr fork 2 +is used to create a second +.Nm +process, referred to as the +.Em monitor . +The +.Em monitor +creates a new terminal session with itself as the leader and the pty as its +controlling terminal, calls +.Xr fork 2 , +sets up the execution environment as described above, and then uses the +.Xr execve 2 +system call to run the command in the child process. +The +.Em monitor +exists to relay job control signals between the user's +existing terminal and the pty the command is being run in. +This makes it possible to suspend and resume the command. +Without the monitor, the command would be in what POSIX terms an +.Dq orphaned process group +and it would not receive any job control signals from the kernel. +When the command exits or is terminated by a signal, the +.Em monitor +passes the command's exit status to the main +.Nm +process and exits. +After receiving the command's exit status, the main +.Nm +passes the command's exit status to the security policy's close function +and exits. +.Pp +If no pty is used, +.Nm +calls +.Xr fork 2 , +sets up the execution environment as described above, and uses the +.Xr execve 2 +system call to run the command in the child process. +The main +.Nm +process waits until the command has completed, then passes the +command's exit status to the security policy's close function and exits. +As a special case, if the policy plugin does not define a close +function, +.Nm +will execute the command directly instead of calling +.Xr fork 2 +first. +The +.Em sudoers +policy plugin will only define a close function when I/O logging +is enabled, a pty is required, or the +.Em pam_session +or +.Em pam_setcred +options are enabled. +Note that +.Em pam_session +and +.Em pam_setcred +are enabled by default on systems using PAM. +.Pp +On systems that use PAM, the security policy's close function +is responsible for closing the PAM session. +It may also log the command's exit status. +.Ss Signal handling +When the command is run as a child of the +.Nm +process, +.Nm +will relay signals it receives to the command. +The +.Dv SIGINT +and +.Dv SIGQUIT +signals are only relayed when the command is being run in a new pty +or when the signal was sent by a user process, not the kernel. +This prevents the command from receiving +.Dv SIGINT +twice each time the user enters control-C. +Some signals, such as +.Dv SIGSTOP +and +.Dv SIGKILL , +cannot be caught and thus will not be relayed to the command. +As a general rule, +.Dv SIGTSTP +should be used instead of +.Dv SIGSTOP +when you wish to suspend a command being run by +.Nm . +.Pp +As a special case, +.Nm +will not relay signals that were sent by the command it is running. +This prevents the command from accidentally killing itself. +On some systems, the +.Xr reboot @mansectsu@ +command sends +.Dv SIGTERM +to all non-system processes other than itself before rebooting +the system. +This prevents +.Nm +from relaying the +.Dv SIGTERM +signal it received back to +.Xr reboot @mansectsu@ , +which might then exit before the system was actually rebooted, +leaving it in a half-dead state similar to single user mode. +Note, however, that this check only applies to the command run by +.Nm +and not any other processes that the command may create. +As a result, running a script that calls +.Xr reboot @mansectsu@ +or +.Xr shutdown @mansectsu@ +via +.Nm +may cause the system to end up in this undefined state unless the +.Xr reboot @mansectsu@ +or +.Xr shutdown @mansectsu@ +are run using the +.Fn exec +family of functions instead of +.Fn system +(which interposes a shell between the command and the calling process). +.Pp +If no I/O logging plugins are loaded and the policy plugin has not +defined a +.Fn close +function, set a command timeout or required that the command be +run in a new pty, +.Nm +may execute the command directly instead of running it as a child process. +.Ss Plugins +Plugins may be specified via +.Li Plugin +directives in the +.Xr sudo.conf @mansectform@ +file. +They may be loaded as dynamic shared objects (on systems that support them), +or compiled directly into the +.Nm +binary. +If no +.Xr sudo.conf @mansectform@ +file is present, or if it doesn't contain any +.Li Plugin +lines, +.Nm +will use +.Xr sudoers @mansectform@ +for the policy, auditing and I/O logging plugins. +See the +.Xr sudo.conf @mansectform@ +manual for details of the +.Pa @sysconfdir@/sudo.conf +file and the +.Xr sudo_plugin @mansectform@ +manual for more information about the +.Nm +plugin architecture. +.Sh EXIT VALUE +Upon successful execution of a command, the exit status from +.Nm +will be the exit status of the program that was executed. +If the command terminated due to receipt of a signal, +.Nm +will send itself the same signal that terminated the command. +.Pp +If the +.Fl l +option was specified without a command, +.Nm +will exit with a value of 0 if the user is allowed to run +.Nm +and they authenticated successfully (as required by the security policy). +If a command is specified with the +.Fl l +option, the exit value will only be 0 if the command is permitted by the +security policy, otherwise it will be 1. +.Pp +If there is an authentication failure, a configuration/permission +problem or if the given command cannot be executed, +.Nm +exits with a value of 1. +In the latter case, the error string is printed to the standard error. +If +.Nm +cannot +.Xr stat 2 +one or more entries in the user's +.Ev PATH , +an error is printed to the standard error. +(If the directory does not exist or if it is not really a directory, +the entry is ignored and no error is printed.) +This should not happen under normal circumstances. +The most common reason for +.Xr stat 2 +to return +.Dq permission denied +is if you are running an automounter and one of the directories in +your +.Ev PATH +is on a machine that is currently unreachable. +.Sh SECURITY NOTES +.Nm +tries to be safe when executing external commands. +.Pp +To prevent command spoofing, +.Nm +checks "." and "" (both denoting current directory) last when +searching for a command in the user's +.Ev PATH +(if one or both are in the +.Ev PATH ) . +Note, however, that the actual +.Ev PATH +environment variable is +.Em not +modified and is passed unchanged to the program that +.Nm +executes. +.Pp +Users should +.Em never +be granted +.Nm +privileges to execute files that are writable by the user or +that reside in a directory that is writable by the user. +If the user can modify or replace the command there is no way +to limit what additional commands they can run. +.Pp +Please note that +.Nm +will normally only log the command it explicitly runs. +If a user runs a command such as +.Li sudo su +or +.Li sudo sh , +subsequent commands run from that shell are not subject to +.Nm sudo Ns 's +security policy. +The same is true for commands that offer shell escapes (including +most editors). +If I/O logging is enabled, subsequent commands will have their input and/or +output logged, but there will not be traditional logs for those commands. +Because of this, care must be taken when giving users access to commands via +.Nm +to verify that the command does not inadvertently give the user an +effective root shell. +For more information, please see the +.Em Preventing shell escapes +section in +.Xr sudoers @mansectform@ . +.Pp +To prevent the disclosure of potentially sensitive information, +.Nm +disables core dumps by default while it is executing (they are +re-enabled for the command that is run). +This historical practice dates from a time when most operating +systems allowed set-user-ID processes to dump core by default. +To aid in debugging +.Nm +crashes, you may wish to re-enable core dumps by setting +.Dq disable_coredump +to false in the +.Xr sudo.conf @mansectform@ +file as follows: +.Bd -literal -offset indent +Set disable_coredump false +.Ed +.Pp +See the +.Xr sudo.conf @mansectform@ +manual for more information. +.Sh ENVIRONMENT +.Nm +utilizes the following environment variables. +The security policy has control over the actual content of the command's +environment. +.Bl -tag -width 15n +.It Ev EDITOR +Default editor to use in +.Fl e +(sudoedit) mode if neither +.Ev SUDO_EDITOR +nor +.Ev VISUAL +is set. +.It Ev MAIL +Set to the mail spool of the target user when the +.Fl i +option is specified or when +.Em env_reset +is enabled in +.Em sudoers +(unless +.Ev MAIL +is present in the +.Em env_keep +list). +.It Ev HOME +Set to the home directory of the target user when the +.Fl i +or +.Fl H +options are specified, when the +.Fl s +option is specified and +.Em set_home +is set in +.Em sudoers , +when +.Em always_set_home +is enabled in +.Em sudoers , +or when +.Em env_reset +is enabled in +.Em sudoers +and +.Em HOME +is not present in the +.Em env_keep +list. +.It Ev LOGNAME +Set to the login name of the target user when the +.Fl i +option is specified, when the +.Em set_logname +option is enabled in +.Em sudoers +or when the +.Em env_reset +option is enabled in +.Em sudoers +(unless +.Ev LOGNAME +is present in the +.Em env_keep +list). +.It Ev PATH +May be overridden by the security policy. +.It Ev SHELL +Used to determine shell to run with +.Fl s +option. +.It Ev SUDO_ASKPASS +Specifies the path to a helper program used to read the password +if no terminal is available or if the +.Fl A +option is specified. +.It Ev SUDO_COMMAND +Set to the command run by sudo, including command line arguments. +The command line arguments are truncated at 4096 characters to +prevent a potential execution error. +.It Ev SUDO_EDITOR +Default editor to use in +.Fl e +(sudoedit) mode. +.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 +.Fl p +option was specified. +.It Ev SUDO_PS1 +If set, +.Ev PS1 +will be set to its value for the program being run. +.It Ev SUDO_UID +Set to the user-ID of the user who invoked sudo. +.It Ev SUDO_USER +Set to the login name of the user who invoked sudo. +.It Ev USER +Set to the same value as +.Ev LOGNAME , +described above. +.It Ev VISUAL +Default editor to use in +.Fl e +(sudoedit) mode if +.Ev SUDO_EDITOR +is not set. +.El +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +.Nm +front end configuration +.El +.Sh EXAMPLES +Note: the following examples assume a properly configured security +policy. +.Pp +To get a file listing of an unreadable directory: +.Bd -literal -offset indent +$ sudo ls /usr/local/protected +.Ed +.Pp +To list the home directory of user yaz on a machine where the file +system holding ~yaz is not exported as root: +.Bd -literal -offset indent +$ sudo -u yaz ls ~yaz +.Ed +.Pp +To edit the +.Pa index.html +file as user www: +.Bd -literal -offset indent +$ sudoedit -u www ~www/htdocs/index.html +.Ed +.Pp +To view system logs only accessible to root and users in the adm +group: +.Bd -literal -offset indent +$ sudo -g adm more /var/log/syslog +.Ed +.Pp +To run an editor as jim with a different primary group: +.Bd -literal -offset indent +$ sudoedit -u jim -g audio ~jim/sound.txt +.Ed +.Pp +To shut down a machine: +.Bd -literal -offset indent +$ sudo shutdown -r +15 "quick reboot" +.Ed +.Pp +To make a usage listing of the directories in the /home partition. +Note that this runs the commands in a sub-shell to make the +.Li cd +and file redirection work. +.Bd -literal -offset indent +$ sudo sh -c "cd /home ; du -s * | sort -rn > USAGE" +.Ed +.Sh DIAGNOSTICS +Error messages produced by +.Nm +include: +.Bl -tag -width 4n +.It Li editing files in a writable directory is not permitted +By default, +.Nm sudoedit +does not permit editing a file when any of the parent directories are writable +by the invoking user. +This avoids a race condition that could allow the user to overwrite +an arbitrary file. +See the +.Em sudoedit_checkdir +option in +.Xr sudoers @mansectform@ +for more information. +.It Li editing symbolic links is not permitted +By default, +.Nm sudoedit +does not follow symbolic links when opening files. +See the +.Em sudoedit_follow +option in +.Xr sudoers @mansectform@ +for more information. +.It Li effective uid is not 0, is sudo installed setuid root? +.Nm +was not run with root privileges. +The +.Nm +binary must be owned by the root user and have the set-user-ID bit set. +Also, it must not be located on a file system mounted with the +.Sq nosuid +option or on an NFS file system that maps uid 0 to an unprivileged uid. +.It Li effective uid is not 0, is sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges? +.Nm +was not run with root privileges. +The +.Nm +binary has the proper owner and permissions but it still did not run +with root privileges. +The most common reason for this is that the file system the +.Nm +binary is located on is mounted with the +.Sq nosuid +option or it is an NFS file system that maps uid 0 to an unprivileged uid. +.It Li fatal error, unable to load plugins +An error occurred while loading or initializing the plugins specified in +.Xr sudo.conf @mansectform@ . +.It Li invalid environment variable name +One or more environment variable names specified via the +.Fl E +option contained an equal sign +.Pq Ql = . +The arguments to the +.Fl E +option should be environment variable names without an associated value. +.It Li no password was provided +When +.Nm +tried to read the password, it did not receive any characters. +This may happen if no terminal is available (or the +.Fl S +option is specified) and the standard input has been redirected from +.Pa /dev/null . +.It Li a terminal is required to read the password +.Nm +needs to read the password but there is no mechanism available for it +to do so. +A terminal is not present to read the password from, +.Nm +has not been configured to read from the standard input, +the +.Fl S +option was not used, and no askpass helper has been specified either via the +.Xr sudo.conf @mansectform@ +file or the +.Ev SUDO_ASKPASS +environment variable. +.It Li no writable temporary directory found +.Nm sudoedit +was unable to find a usable temporary directory in which to store its +intermediate files. +.It Li sudo must be owned by uid 0 and have the setuid bit set +.Nm +was not run with root privileges. +The +.Nm +binary does not have the correct owner or permissions. +It must be owned by the root user and have the set-user-ID bit set. +.It Li sudoedit is not supported on this platform +It is only possible to run +.Nm sudoedit +on systems that support setting the effective user-ID. +.It Li timed out reading password +The user did not enter a password before the password timeout +(5 minutes by default) expired. +.It Li you do not exist in the passwd database +Your user-ID does not appear in the system passwd database. +.It Li you may not specify environment variables in edit mode +It is only possible to specify environment variables when running +a command. +When editing a file, the editor is run with the user's environment unmodified. +.El +.Sh SEE ALSO +.Xr su 1 , +.Xr stat 2 , +.Xr login_cap 3 , +.Xr passwd @mansectform@ , +.Xr sudo.conf @mansectform@ , +.Xr sudo_plugin @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudoers_timestamp @mansectform@ , +.Xr sudoreplay @mansectsu@ , +.Xr visudo @mansectsu@ +.Sh HISTORY +See the HISTORY file in the +.Nm +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.Sh AUTHORS +Many people have worked on +.Nm +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm . +.Sh CAVEATS +There is no easy way to prevent a user from gaining a root shell +if that user is allowed to run arbitrary commands via +.Nm . +Also, many programs (such as editors) allow the user to run commands +via shell escapes, thus avoiding +.Nm sudo Ns 's +checks. +However, on most systems it is possible to prevent shell escapes with the +.Xr sudoers @mansectform@ +plugin's +.Em noexec +functionality. +.Pp +It is not meaningful to run the +.Li cd +command directly via sudo, e.g., +.Bd -literal -offset indent +$ sudo cd /usr/local/protected +.Ed +.Pp +since when the command exits the parent process (your shell) will +still be the same. +Please see the +.Sx EXAMPLES +section for more information. +.Pp +Running shell scripts via +.Nm +can expose the same kernel bugs that make set-user-ID shell scripts +unsafe on some operating systems (if your OS has a /dev/fd/ directory, +set-user-ID shell scripts are generally safe). +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrv.proto.man.in b/doc/sudo_logsrv.proto.man.in new file mode 100644 index 0000000..32c67c5 --- /dev/null +++ b/doc/sudo_logsrv.proto.man.in @@ -0,0 +1,899 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.TH "SUDO_LOGSRV.PROTO" "@mansectform@" "November 6, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_logsrv.proto\fR +\- Sudo log server protocol +.SH "DESCRIPTION" +Starting with version 1.9.0, +\fBsudo\fR +supports sending event and I/O logs to a log server. +The protocol used is written in Google's Protocol Buffers domain +specific language. +The +\fIEXAMPLES\fR +section includes a complete description of the protocol in Protocol +Buffers format. +.PP +Because there is no way to determine message boundaries when using +Protocol Buffers, the wire size of each message is sent immediately +preceding the message itself as a 32-bit unsigned integer in network +byte order. +This is referred to as +\(lqlength-prefix framing\(rq +and is how Google suggests handling the lack of message delimiters. +.PP +The protocol is made up of two basic messages, +\fIClientMessage\fR +and +\fIServerMessage\fR, +described below. +The server must accept messages up to two megabytes in size. +The server may return an error if the client tries to send a message +larger than two megabytes. +.SH "Client Messages" +A +\fIClientMessage\fR +is a container used to encapsulate all the possible message types +a client may send to the server. +.nf +.sp +.RS 0n +message ClientMessage { + oneof type { + AcceptMessage accept_msg = 1; + RejectMessage reject_msg = 2; + ExitMessage exit_msg = 3; + RestartMessage restart_msg = 4; + AlertMessage alert_msg = 5; + IoBuffer ttyin_buf = 6; + IoBuffer ttyout_buf = 7; + IoBuffer stdin_buf = 8; + IoBuffer stdout_buf = 9; + IoBuffer stderr_buf = 10; + ChangeWindowSize winsize_event = 11; + CommandSuspend suspend_event = 12; + ClientHello hello_msg = 13; + } +} +.RE +.fi +.PP +The different +\fIClientMessage\fR +sub-messages the client may sent to the server are described below. +.SS "TimeSpec" +.nf +.RS 0n +message TimeSpec { + int64 tv_sec = 1; + int32 tv_nsec = 2; +} +.RE +.fi +.PP +A +\fITimeSpec\fR +is the equivalent of a POSIX +\fRstruct timespec\fR, +containing seconds and nanoseconds members. +The +\fItv_sec\fR +member is a 64-bit integer to support dates after the year 2038. +.SS "InfoMessage" +.nf +.RS 0n +message InfoMessage { + message StringList { + repeated string strings = 1; + } + message NumberList { + repeated int64 numbers = 1; + } + string key = 1; + oneof value { + int64 numval = 2; + string strval = 3; + StringList strlistval = 4; + NumberList numlistval = 5; + } +} +.RE +.fi +.PP +An +\fIInfoMessage\fR +is used to represent information about the invoking user as well as the +execution environment the command runs in the form of key-value pairs. +The key is always a string but the value may be a 64-bit integer, +a string, an array of strings or an array of 64-bit integers. +The event log data is composed of +\fIInfoMessage\fR +entries. +See the +\fIEVENT LOG VARIABLES\fR +section for more information. +.SS "ClientHello hello_msg" +.nf +.RS 0n +message ClientHello { + string client_id = 1; +} +.RE +.fi +.PP +A +\fIClientHello\fR +message consists of client information that may be sent to the +server when the client first connects. +.TP 8n +client_id +A free-form client description. +This usually includes the name and version of the client implementation. +.SS "AcceptMessage accept_msg" +.nf +.RS 0n +message AcceptMessage { + TimeSpec submit_time = 1; + repeated InfoMessage info_msgs = 2; + bool expect_iobufs = 3; +} +.RE +.fi +.PP +An +\fIAcceptMessage\fR +is sent by the client when a command is allowed by the security policy. +It contains the following members: +.TP 8n +submit_time +The wall clock time when the command was submitted to the security policy. +.TP 8n +info_msgs +An array of +\fIInfoMessage\fR +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry and may also be +used by server to determine where and how the I/O log is stored. +.TP 8n +expect_iobufs +Set to true if the server should expect +\fIIoBuffer\fR +messages to follow (for I/O logging) or false if the server should only +store the event log. +.PP +If an +\fIAcceptMessage\fR +is sent, the client must not send a +\fIRejectMessage\fR +or +\fIRestartMessage\fR. +.SS "RejectMessage reject_msg" +.nf +.RS 0n +message RejectMessage { + TimeSpec submit_time = 1; + string reason = 2; + repeated InfoMessage info_msgs = 3; +} +.RE +.fi +.PP +A +\fIRejectMessage\fR +is sent by the client when a command is denied by the security policy. +It contains the following members: +.TP 8n +submit_time +The wall clock time when the command was submitted to the security policy. +.TP 8n +reason +The reason the security policy gave for denying the command. +.TP 8n +info_msgs +An array of +\fIInfoMessage\fR +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. +.PP +If a +\fIRejectMessage\fR +is sent, the client must not send an +\fIAcceptMessage\fR +or +\fIRestartMessage\fR. +.SS "ExitMessage exit_msg" +.nf +.RS 0n +message ExitMessage { + TimeSpec run_time = 1; + int32 exit_value = 2; + bool dumped_core = 3; + string signal = 4; + string error = 5; +} +.PP +.RE +.fi +An +\fIExitMessage\fR +is sent by the client after the command has exited or has been +terminated by a signal. +It contains the following members: +.TP 8n +run_time +The total amount of elapsed time since the command started, +calculated using a monotonic clock where possible. +This is not the wall clock time. +.TP 8n +exit_value +The command's exit value in the range 0-255. +.TP 8n +dumped_core +True if the command was terminated by a signal and dumped core. +.TP 8n +signal +If the command was terminated by a signal, this is set to the +name of the signal without the leading +\(lqSIG\(rq. +For example, +\fRINT\fR, +\fRTERM\fR, +\fRKILL\fR, +\fRSEGV\fR. +.TP 8n +error +A message from the client indicating that the command was terminated +unexpectedly due to an error. +.PP +When performing I/O logging, the client should wait for a +\fIcommit_point\fR +corresponding to the final +\fIIoBuffer\fR +before closing the connection unless the final +\fIcommit_point\fR +has already been received. +.SS "RestartMessage restart_msg" +.nf +.RS 0n +message RestartMessage { + string log_id = 1; + TimeSpec resume_point = 2; +} +.RE +.fi +.PP +A +\fIRestartMessage\fR +is sent by the client to resume sending an existing I/O log that +was previously interrupted. +It contains the following members: +.TP 8n +log_id +The the server-side name for an I/O log that was previously +sent to the client by the server. +This may be a path name on the server or some other kind of server-side +identifier. +.TP 8n +resume_point +The point in time after which to resume the I/O log. +This is in the form of a +\fITimeSpec\fR +representing the amount of time since the command started, not +the wall clock time. +The +\fIresume_point\fR +should correspond to a +\fIcommit_point\fR +previously sent to the client by the server. +If the server receives a +\fIRestartMessage\fR +containing a +\fIresume_point\fR +it has not previously seen, an error will be returned to the client +and the connection will be dropped. +.PP +If a +\fIRestartMessage\fR +is sent, the client must not send an +\fIAcceptMessage\fR +or +\fIRejectMessage\fR. +.SS "AlertMessage alert_msg" +.nf +.RS 0n +message AlertMessage { + TimeSpec alert_time = 1; + string reason = 2; + repeated InfoMessage info_msgs = 3; +} +.RE +.fi +.PP +An +\fIAlertMessage\fR +is sent by the client to indicate a problem detected by the security +policy while the command is running that should be stored in the event log. +It contains the following members: +.TP 8n +alert_time +The wall clock time when the alert occurred. +.TP 8n +reason +The reason for the alert. +.TP 8n +info_msgs +An optional array of +\fIInfoMessage\fR +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. +.SS "IoBuffer ttyin_buf | ttyout_buf | stdin_buf | stdout_buf | stderr_buf" +.nf +.RS 0n +message IoBuffer { + TimeSpec delay = 1; + bytes data = 2; +} +.RE +.fi +.PP +An +\fIIoBuffer\fR +is used to represent data from terminal input, terminal +output, standard input, standard output or standard error. +It contains the following members: +.TP 8n +delay +The elapsed time since the last record in the form of a +\fITimeSpec\fR. +The +\fIdelay\fR +should be calculated using a monotonic clock where possible. +.TP 8n +data +The binary I/O log data from terminal input, terminal output, +standard input, standard output or standard error. +.SS "ChangeWindowSize winsize_event" +.nf +.RS 0n +message ChangeWindowSize { + TimeSpec delay = 1; + int32 rows = 2; + int32 cols = 3; +} +.RE +.fi +.PP +A +\fIChangeWindowSize\fR +message is sent by the client when the terminal running the command +changes size. +It contains the following members: +.TP 8n +delay +The elapsed time since the last record in the form of a +\fITimeSpec\fR. +The +\fIdelay\fR +should be calculated using a monotonic clock where possible. +.TP 8n +rows +The new number of terminal rows. +.TP 8n +cols +The new number of terminal columns. +.SS "CommandSuspend suspend_event" +.nf +.RS 0n +message CommandSuspend { + TimeSpec delay = 1; + string signal = 2; +} +.RE +.fi +.PP +A +\fICommandSuspend\fR +message is sent by the client when the command is either suspended +or resumed. +It contains the following members: +.TP 8n +delay +The elapsed time since the last record in the form of a +\fITimeSpec\fR. +The +\fIdelay\fR +should be calculated using a monotonic clock where possible. +.TP 8n +signal +The signal name without the leading +\(lqSIG\(rq. +For example, +\fRSTOP\fR, +\fRTSTP\fR, +\fRCONT\fR. +.SH "Server Messages" +A +\fIServerMessage\fR +is a container used to encapsulate all the possible message types +the server may send to a client. +.nf +.sp +.RS 0n +message ServerMessage { + oneof type { + ServerHello hello = 1; + TimeSpec commit_point = 2; + string log_id = 3; + string error = 4; + string abort = 5; + } +} +.RE +.fi +.PP +The different +\fIServerMessage\fR +sub-messages the server may sent to the client are described below. +.SS "ServerHello hello" +.nf +.RS 0n +message ServerHello { + string server_id = 1; + string redirect = 2; + repeated string servers = 3; +} +.RE +.fi +.PP +The +\fIServerHello\fR +message consists of server information sent when the client first connects. +It contains the following members: +.TP 8n +server_id +A free-form server description. +Usually this includes the name and version of the implementation +running on the log server. +This member is always present. +.TP 8n +redirect +A host and port separated by a colon +(\(oq\(cq): +that the client should connect to instead. +The host may be a host name, an IPv4 address, or an IPv6 address +in square brackets. +This may be used for server load balancing. +The server will disconnect after sending the +\fIServerHello\fR +when it includes a +\fBredirect\fR. +.TP 8n +servers +.br +A list of other known log servers. +This can be used to implement log server redundancy and allows the +client to discover all other log servers simply by connecting to +one known server. +This member may be omitted when there is only a single log server. +.SS "TimeSpec commit_point" +A periodic time stamp sent by the server to indicate when I/O log +buffers have been committed to storage. +This message is not sent after every +\fIIoBuffer\fR +but rather at a server-configurable interval. +When the server receives an +\fIExitMessage\fR, +it will respond with a +\fIcommit_point\fR +corresponding to the last received +\fIIoBuffer\fR +before closing the connection. +.SS "string log_id" +The server-side ID of the I/O log being stored, sent in response +to an +\fIAcceptMessage\fR +where +\fIexpect_iobufs\fR +is true. +.SS "string error" +A fatal server-side error. +The server will close the connection after sending the +\fIerror\fR +message. +.SS "string abort" +An +\fIabort\fR +message from the server indicates that the client should kill the +command and terminate the session. +It may be used to implement simple server-side policy. +The server will close the connection after sending the +\fIabort\fR +message. +.SH "Protocol flow of control" +The expected protocol flow is as follows: +.TP 5n +1.\& +Client connects to the first available server. +If the client is configured to use TLS, a TLS handshake will be +attempted. +.TP 5n +2.\& +Client sends +\fIClientHello\fR. +This is currently optional but allows the server to detect a +non-TLS connection on the TLS port. +.TP 5n +3.\& +Server sends +\fIServerHello\fR. +.TP 5n +4.\& +Client responds with either +\fIAcceptMessage\fR, +\fIRejectMessage\fR, +or +\fIRestartMessage\fR. +.TP 5n +5.\& +If client sent a +\fIAcceptMessage\fR +with +\fIexpect_iobufs\fR +set, server creates a new I/O log and responds with a +\fIlog_id\fR. +.TP 5n +6.\& +Client sends zero or more +\fIIoBuffer\fR +messages. +.TP 5n +7.\& +Server periodically responds to +\fIIoBuffer\fR +messages with a +\fIcommit_point\fR. +.TP 5n +8.\& +Client sends an +\fIExitMessage\fR +when the command exits or is killed. +.TP 5n +9.\& +Server sends the final +\fIcommit_point\fR +if one is pending. +.TP 5n +10.\& +Server closes the connection. +After receiving the final +\fIcommit_point\fR, +the client shuts down its side of the TLS connection if TLS +is in use, and closes the connection. +.TP 5n +11.\& +Server shuts down its side of the TLS connection if TLS is in use, +and closes the connection. +.PP +At any point, the server may send an +\fIerror\fR +or +\fIabort\fR +message to the client at which point the server will close the +connection. +If an +\fIabort\fR +message is received, the client should terminate the running command. +.SH "EVENT LOG VARIABLES" +\fIAcceptMessage\fR, +\fIAlertMessage\fR +and +\fIRejectMessage\fR +classes contain an array of +\fIInfoMessage\fR +that should contain information about the user who submitted the command +as well as information about the execution environment of the command +if it was accepted. +.PP +Some variables have a +\fIclient\fR, +\fIrun\fR, +or +\fIsubmit\fR +prefix. +These prefixes are used to eliminate ambiguity for variables that +could apply to the client program, the user submitting the command, +or the command being run. +Variables with a +\fIclient\fR +prefix pertain to the program performing the connection to the log +server, for example +\fBsudo\fR. +Variables with a +\fIrun\fR +prefix pertain to the command that the user requested be run. +Variables with a +\fIsubmit\fR +prefix pertain to the user submitting the request +(the user running \fBsudo\fR). +.PP +The following +\fIInfoMessage\fR +entries are required: +.TS +l l l. +.PP +\fBKey\fR \fBType\fR \fBDescription\fR +.PP +command string command that was submitted +.PP +runuser string name of user the command was run as +.PP +submithost string name of host the command was submitted on +.PP +submituser string name of user submitting the command +.TE +.PP +The following +\fIInfoMessage\fR +entries are recognized, but not required: +.TS +l l l. +.PP +\fBKey\fR \fBType\fR \fBDescription\fR +.PP +clientargv StringList client's original argument vector +.PP +clientpid int64 client's process ID +.PP +clientppid int64 client's parent process ID +.PP +clientsid int64 client's terminal session ID +.PP +columns int64 number of columns in the terminal +.PP +lines int64 number of lines in the terminal +.PP +runargv StringList argument vector of command to run +.PP +runchroot string root directory of command to run +.PP +runcwd string running command's working directory +.PP +runenv StringList the running command's environment +.PP +rungid int64 primary group-ID of the command +.PP +rungids NumberList supplementary group-IDs for the command +.PP +rungroup string primary group name of the command +.PP +rungroups StringList supplementary group names for the command +.PP +runuid int64 run user's user-ID +.PP +submitcwd string submit user's current working directory +.PP +submitenv StringList the submit user's environment +.PP +submitgid int64 submit user's primary group-ID +.PP +submitgids NumberList submit user's supplementary group-IDs +.PP +submitgroup string submitting user's primary group name +.PP +submitgroups StringList submit user's supplementary group names +.PP +submituid int64 submit user's user-ID +.PP +ttyname string the terminal the command was submitted from +.TE +.PP +The server must accept other variables not listed above but may +ignore them. +.SH "EXAMPLES" +The Protocol Buffers description of the log server protocol is included +in full below. +Note that this uses the newer +\(lqproto3\(rq +syntax. +.nf +.sp +.RS 0n +syntax = "proto3"; + +/* + * Client message to the server. Messages on the wire are + * prefixed with a 32-bit size in network byte order. + */ +message ClientMessage { + oneof type { + AcceptMessage accept_msg = 1; + RejectMessage reject_msg = 2; + ExitMessage exit_msg = 3; + RestartMessage restart_msg = 4; + AlertMessage alert_msg = 5; + IoBuffer ttyin_buf = 6; + IoBuffer ttyout_buf = 7; + IoBuffer stdin_buf = 8; + IoBuffer stdout_buf = 9; + IoBuffer stderr_buf = 10; + ChangeWindowSize winsize_event = 11; + CommandSuspend suspend_event = 12; + } +} + +/* Equivalent of POSIX struct timespec */ +message TimeSpec { + int64 tv_sec = 1; /* seconds */ + int32 tv_nsec = 2; /* nanoseconds */ +} + +/* I/O buffer with keystroke data */ +message IoBuffer { + TimeSpec delay = 1; /* elapsed time since last record */ + bytes data = 2; /* keystroke data */ +} + +/* + * Key/value pairs, like Privilege Manager struct info. + * The value may be a number, a string, or a list of strings. + */ +message InfoMessage { + message StringList { + repeated string strings = 1; + } + message NumberList { + repeated int64 numbers = 1; + } + string key = 1; + oneof value { + int64 numval = 2; + string strval = 3; + StringList strlistval = 4; + NumberList numlistval = 5; + } +} + +/* + * Event log data for command accepted by the policy. + */ +message AcceptMessage { + TimeSpec submit_time = 1; /* when command was submitted */ + repeated InfoMessage info_msgs = 2; /* key,value event log data */ + bool expect_iobufs = 3; /* true if I/O logging enabled */ +} + +/* + * Event log data for command rejected by the policy. + */ +message RejectMessage { + TimeSpec submit_time = 1; /* when command was submitted */ + string reason = 2; /* reason command was rejected */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ +} + +/* Message sent by client when command exits. */ +/* Might revisit runtime and use end_time instead */ +message ExitMessage { + TimeSpec run_time = 1; /* total elapsed run time */ + int32 exit_value = 2; /* 0-255 */ + bool dumped_core = 3; /* true if command dumped core */ + string signal = 4; /* signal name if killed by signal */ + string error = 5; /* if killed due to other error */ +} + +/* Alert message, policy module-specific. */ +message AlertMessage { + TimeSpec alert_time = 1; /* time alert message occurred */ + string reason = 2; /* policy alert error string */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ +} + +/* Used to restart an existing I/O log on the server. */ +message RestartMessage { + string log_id = 1; /* ID of log being restarted */ + TimeSpec resume_point = 2; /* resume point (elapsed time) */ +} + +/* Window size change event. */ +message ChangeWindowSize { + TimeSpec delay = 1; /* elapsed time since last record */ + int32 rows = 2; /* new number of rows */ + int32 cols = 3; /* new number of columns */ +} + +/* Command suspend/resume event. */ +message CommandSuspend { + TimeSpec delay = 1; /* elapsed time since last record */ + string signal = 2; /* signal that caused suspend/resume */ +} + +/* + * Server messages to the client. Messages on the wire are + * prefixed with a 32-bit size in network byte order. + */ +message ServerMessage { + oneof type { + ServerHello hello = 1; /* server hello message */ + TimeSpec commit_point = 2; /* cumulative time of records stored */ + string log_id = 3; /* ID of server-side I/O log */ + string error = 4; /* error message from server */ + string abort = 5; /* abort message, kill command */ + } +} + +/* Hello message from server when client connects. */ +message ServerHello { + string server_id = 1; /* free-form server description */ + string redirect = 2; /* optional redirect if busy */ + repeated string servers = 3; /* optional list of known servers */ +} +.RE +.fi +.SH "SEE ALSO" +sudo_logsrvd.conf(@mansectform@), +sudoers(@mansectform@), +sudo(8), +sudo_logsrvd(8) +.PP +\fIProtocol Buffers\fR, +https://developers.google.com/protocol-buffers/. +.SH "HISTORY" +See the HISTORY file in the +\fBsudo\fR +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrv.proto.mdoc.in b/doc/sudo_logsrv.proto.mdoc.in new file mode 100644 index 0000000..ef9953a --- /dev/null +++ b/doc/sudo_logsrv.proto.mdoc.in @@ -0,0 +1,817 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.Dd November 6, 2020 +.Dt SUDO_LOGSRV.PROTO @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_logsrv.proto +.Nd Sudo log server protocol +.Sh DESCRIPTION +Starting with version 1.9.0, +.Nm sudo +supports sending event and I/O logs to a log server. +The protocol used is written in Google's Protocol Buffers domain +specific language. +The +.Sx EXAMPLES +section includes a complete description of the protocol in Protocol +Buffers format. +.Pp +Because there is no way to determine message boundaries when using +Protocol Buffers, the wire size of each message is sent immediately +preceding the message itself as a 32-bit unsigned integer in network +byte order. +This is referred to as +.Dq length-prefix framing +and is how Google suggests handling the lack of message delimiters. +.Pp +The protocol is made up of two basic messages, +.Em ClientMessage +and +.Em ServerMessage , +described below. +The server must accept messages up to two megabytes in size. +The server may return an error if the client tries to send a message +larger than two megabytes. +.Sh Client Messages +A +.Em ClientMessage +is a container used to encapsulate all the possible message types +a client may send to the server. +.Bd -literal +message ClientMessage { + oneof type { + AcceptMessage accept_msg = 1; + RejectMessage reject_msg = 2; + ExitMessage exit_msg = 3; + RestartMessage restart_msg = 4; + AlertMessage alert_msg = 5; + IoBuffer ttyin_buf = 6; + IoBuffer ttyout_buf = 7; + IoBuffer stdin_buf = 8; + IoBuffer stdout_buf = 9; + IoBuffer stderr_buf = 10; + ChangeWindowSize winsize_event = 11; + CommandSuspend suspend_event = 12; + ClientHello hello_msg = 13; + } +} +.Ed +.Pp +The different +.Em ClientMessage +sub-messages the client may sent to the server are described below. +.Ss TimeSpec +.Bd -literal +message TimeSpec { + int64 tv_sec = 1; + int32 tv_nsec = 2; +} +.Ed +.Pp +A +.Em TimeSpec +is the equivalent of a POSIX +.Li struct timespec , +containing seconds and nanoseconds members. +The +.Em tv_sec +member is a 64-bit integer to support dates after the year 2038. +.Ss InfoMessage +.Bd -literal +message InfoMessage { + message StringList { + repeated string strings = 1; + } + message NumberList { + repeated int64 numbers = 1; + } + string key = 1; + oneof value { + int64 numval = 2; + string strval = 3; + StringList strlistval = 4; + NumberList numlistval = 5; + } +} +.Ed +.Pp +An +.Em InfoMessage +is used to represent information about the invoking user as well as the +execution environment the command runs in the form of key-value pairs. +The key is always a string but the value may be a 64-bit integer, +a string, an array of strings or an array of 64-bit integers. +The event log data is composed of +.Em InfoMessage +entries. +See the +.Sx EVENT LOG VARIABLES +section for more information. +.Ss ClientHello hello_msg +.Bd -literal +message ClientHello { + string client_id = 1; +} +.Ed +.Pp +A +.Em ClientHello +message consists of client information that may be sent to the +server when the client first connects. +.Bl -tag -width Ds +.It client_id +A free-form client description. +This usually includes the name and version of the client implementation. +.El +.Ss AcceptMessage accept_msg +.Bd -literal +message AcceptMessage { + TimeSpec submit_time = 1; + repeated InfoMessage info_msgs = 2; + bool expect_iobufs = 3; +} +.Ed +.Pp +An +.Em AcceptMessage +is sent by the client when a command is allowed by the security policy. +It contains the following members: +.Bl -tag -width Ds +.It submit_time +The wall clock time when the command was submitted to the security policy. +.It info_msgs +An array of +.Em InfoMessage +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry and may also be +used by server to determine where and how the I/O log is stored. +.It expect_iobufs +Set to true if the server should expect +.Em IoBuffer +messages to follow (for I/O logging) or false if the server should only +store the event log. +.El +.Pp +If an +.Em AcceptMessage +is sent, the client must not send a +.Em RejectMessage +or +.Em RestartMessage . +.Ss RejectMessage reject_msg +.Bd -literal +message RejectMessage { + TimeSpec submit_time = 1; + string reason = 2; + repeated InfoMessage info_msgs = 3; +} +.Ed +.Pp +A +.Em RejectMessage +is sent by the client when a command is denied by the security policy. +It contains the following members: +.Bl -tag -width Ds +.It submit_time +The wall clock time when the command was submitted to the security policy. +.It reason +The reason the security policy gave for denying the command. +.It info_msgs +An array of +.Em InfoMessage +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. +.El +.Pp +If a +.Em RejectMessage +is sent, the client must not send an +.Em AcceptMessage +or +.Em RestartMessage . +.Ss ExitMessage exit_msg +.Bd -literal +message ExitMessage { + TimeSpec run_time = 1; + int32 exit_value = 2; + bool dumped_core = 3; + string signal = 4; + string error = 5; +} +.Pp +.Ed +An +.Em ExitMessage +is sent by the client after the command has exited or has been +terminated by a signal. +It contains the following members: +.Bl -tag -width Ds +.It run_time +The total amount of elapsed time since the command started, +calculated using a monotonic clock where possible. +This is not the wall clock time. +.It exit_value +The command's exit value in the range 0-255. +.It dumped_core +True if the command was terminated by a signal and dumped core. +.It signal +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 . +.It error +A message from the client indicating that the command was terminated +unexpectedly due to an error. +.El +.Pp +When performing I/O logging, the client should wait for a +.Em commit_point +corresponding to the final +.Em IoBuffer +before closing the connection unless the final +.Em commit_point +has already been received. +.Ss RestartMessage restart_msg +.Bd -literal +message RestartMessage { + string log_id = 1; + TimeSpec resume_point = 2; +} +.Ed +.Pp +A +.Em RestartMessage +is sent by the client to resume sending an existing I/O log that +was previously interrupted. +It contains the following members: +.Bl -tag -width Ds +.It log_id +The the server-side name for an I/O log that was previously +sent to the client by the server. +This may be a path name on the server or some other kind of server-side +identifier. +.It resume_point +The point in time after which to resume the I/O log. +This is in the form of a +.Em TimeSpec +representing the amount of time since the command started, not +the wall clock time. +The +.Em resume_point +should correspond to a +.Em commit_point +previously sent to the client by the server. +If the server receives a +.Em RestartMessage +containing a +.Em resume_point +it has not previously seen, an error will be returned to the client +and the connection will be dropped. +.El +.Pp +If a +.Em RestartMessage +is sent, the client must not send an +.Em AcceptMessage +or +.Em RejectMessage . +.Ss AlertMessage alert_msg +.Bd -literal +message AlertMessage { + TimeSpec alert_time = 1; + string reason = 2; + repeated InfoMessage info_msgs = 3; +} +.Ed +.Pp +An +.Em AlertMessage +is sent by the client to indicate a problem detected by the security +policy while the command is running that should be stored in the event log. +It contains the following members: +.Bl -tag -width Ds +.It alert_time +The wall clock time when the alert occurred. +.It reason +The reason for the alert. +.It info_msgs +An optional array of +.Em InfoMessage +describing the user who submitted the command as well as the execution +environment of the command. +This information is used to generate an event log entry. +.El +.Ss IoBuffer ttyin_buf | ttyout_buf | stdin_buf | stdout_buf | stderr_buf +.Bd -literal +message IoBuffer { + TimeSpec delay = 1; + bytes data = 2; +} +.Ed +.Pp +An +.Em IoBuffer +is used to represent data from terminal input, terminal +output, standard input, standard output or standard error. +It contains the following members: +.Bl -tag -width Ds +.It delay +The elapsed time since the last record in the form of a +.Em TimeSpec . +The +.Em delay +should be calculated using a monotonic clock where possible. +.It data +The binary I/O log data from terminal input, terminal output, +standard input, standard output or standard error. +.El +.Ss ChangeWindowSize winsize_event +.Bd -literal +message ChangeWindowSize { + TimeSpec delay = 1; + int32 rows = 2; + int32 cols = 3; +} +.Ed +.Pp +A +.Em ChangeWindowSize +message is sent by the client when the terminal running the command +changes size. +It contains the following members: +.Bl -tag -width Ds +.It delay +The elapsed time since the last record in the form of a +.Em TimeSpec . +The +.Em delay +should be calculated using a monotonic clock where possible. +.It rows +The new number of terminal rows. +.It cols +The new number of terminal columns. +.El +.Ss CommandSuspend suspend_event +.Bd -literal +message CommandSuspend { + TimeSpec delay = 1; + string signal = 2; +} +.Ed +.Pp +A +.Em CommandSuspend +message is sent by the client when the command is either suspended +or resumed. +It contains the following members: +.Bl -tag -width Ds +.It delay +The elapsed time since the last record in the form of a +.Em TimeSpec . +The +.Em delay +should be calculated using a monotonic clock where possible. +.It signal +The signal name without the leading +.Dq SIG . +For example, +.Li STOP , +.Li TSTP , +.Li CONT . +.El +.Sh Server Messages +A +.Em ServerMessage +is a container used to encapsulate all the possible message types +the server may send to a client. +.Bd -literal +message ServerMessage { + oneof type { + ServerHello hello = 1; + TimeSpec commit_point = 2; + string log_id = 3; + string error = 4; + string abort = 5; + } +} +.Ed +.Pp +The different +.Em ServerMessage +sub-messages the server may sent to the client are described below. +.Ss ServerHello hello +.Bd -literal +message ServerHello { + string server_id = 1; + string redirect = 2; + repeated string servers = 3; +} +.Ed +.Pp +The +.Em ServerHello +message consists of server information sent when the client first connects. +It contains the following members: +.Bl -tag -width Ds +.It server_id +A free-form server description. +Usually this includes the name and version of the implementation +running on the log server. +This member is always present. +.It redirect +A host and port separated by a colon +.Pq Ql : +that the client should connect to instead. +The host may be a host name, an IPv4 address, or an IPv6 address +in square brackets. +This may be used for server load balancing. +The server will disconnect after sending the +.Em ServerHello +when it includes a +.Sy redirect . +.It servers +A list of other known log servers. +This can be used to implement log server redundancy and allows the +client to discover all other log servers simply by connecting to +one known server. +This member may be omitted when there is only a single log server. +.El +.Ss TimeSpec commit_point +A periodic time stamp sent by the server to indicate when I/O log +buffers have been committed to storage. +This message is not sent after every +.Em IoBuffer +but rather at a server-configurable interval. +When the server receives an +.Em ExitMessage , +it will respond with a +.Em commit_point +corresponding to the last received +.Em IoBuffer +before closing the connection. +.Ss string log_id +The server-side ID of the I/O log being stored, sent in response +to an +.Em AcceptMessage +where +.Em expect_iobufs +is true. +.Ss string error +A fatal server-side error. +The server will close the connection after sending the +.Em error +message. +.Ss string abort +An +.Em abort +message from the server indicates that the client should kill the +command and terminate the session. +It may be used to implement simple server-side policy. +The server will close the connection after sending the +.Em abort +message. +.Sh Protocol flow of control +The expected protocol flow is as follows: +.Bl -enum +.It +Client connects to the first available server. +If the client is configured to use TLS, a TLS handshake will be +attempted. +.It +Client sends +.Em ClientHello . +This is currently optional but allows the server to detect a +non-TLS connection on the TLS port. +.It +Server sends +.Em ServerHello . +.It +Client responds with either +.Em AcceptMessage , +.Em RejectMessage , +or +.Em RestartMessage . +.It +If client sent a +.Em AcceptMessage +with +.Em expect_iobufs +set, server creates a new I/O log and responds with a +.Em log_id . +.It +Client sends zero or more +.Em IoBuffer +messages. +.It +Server periodically responds to +.Em IoBuffer +messages with a +.Em commit_point . +.It +Client sends an +.Em ExitMessage +when the command exits or is killed. +.It +Server sends the final +.Em commit_point +if one is pending. +.It +Server closes the connection. +After receiving the final +.Em commit_point , +the client shuts down its side of the TLS connection if TLS +is in use, and closes the connection. +.It +Server shuts down its side of the TLS connection if TLS is in use, +and closes the connection. +.El +.Pp +At any point, the server may send an +.Em error +or +.Em abort +message to the client at which point the server will close the +connection. +If an +.Em abort +message is received, the client should terminate the running command. +.Sh EVENT LOG VARIABLES +.Em AcceptMessage , +.Em AlertMessage +and +.Em RejectMessage +classes contain an array of +.Em InfoMessage +that should contain information about the user who submitted the command +as well as information about the execution environment of the command +if it was accepted. +.Pp +Some variables have a +.Em client , +.Em run , +or +.Em submit +prefix. +These prefixes are used to eliminate ambiguity for variables that +could apply to the client program, the user submitting the command, +or the command being run. +Variables with a +.Em client +prefix pertain to the program performing the connection to the log +server, for example +.Nm sudo . +Variables with a +.Em run +prefix pertain to the command that the user requested be run. +Variables with a +.Em submit +prefix pertain to the user submitting the request +.Pq the user running Nm sudo . +.Pp +The following +.Em InfoMessage +entries are required: +.Bl -column "submitgroup" "stringlist" "name of host the command was submitted on" +.It Sy Key Ta Sy Type Ta Sy Description +.It command Ta string Ta command that was submitted +.It runuser Ta string Ta name of user the command was run as +.It submithost Ta string Ta name of host the command was submitted on +.It submituser Ta string Ta name of user submitting the command +.El +.Pp +The following +.Em InfoMessage +entries are recognized, but not required: +.Bl -column "submitgroup" "stringlist" "name of host the command was submitted on" +.It Sy Key Ta Sy Type Ta Sy Description +.It clientargv Ta StringList Ta client's original argument vector +.It clientpid Ta int64 Ta client's process ID +.It clientppid Ta int64 Ta client's parent process ID +.It clientsid Ta int64 Ta client's terminal session ID +.It columns Ta int64 Ta number of columns in the terminal +.It lines Ta int64 Ta number of lines in the terminal +.It runargv Ta StringList Ta argument vector of command to run +.It runchroot Ta string Ta root directory of command to run +.It runcwd Ta string Ta running command's working directory +.It runenv Ta StringList Ta the running command's environment +.It rungid Ta int64 Ta primary group-ID of the command +.It rungids Ta NumberList Ta supplementary group-IDs for the command +.It rungroup Ta string Ta primary group name of the command +.It rungroups Ta StringList Ta supplementary group names for the command +.It runuid Ta int64 Ta run user's user-ID +.It submitcwd Ta string Ta submit user's current working directory +.It submitenv Ta StringList Ta the submit user's environment +.It submitgid Ta int64 Ta submit user's primary group-ID +.It submitgids Ta NumberList Ta submit user's supplementary group-IDs +.It submitgroup Ta string Ta submitting user's primary group name +.It submitgroups Ta StringList Ta submit user's supplementary group names +.It submituid Ta int64 Ta submit user's user-ID +.It ttyname Ta string Ta the terminal the command was submitted from +.El +.Pp +The server must accept other variables not listed above but may +ignore them. +.Sh EXAMPLES +The Protocol Buffers description of the log server protocol is included +in full below. +Note that this uses the newer +.Dq proto3 +syntax. +.Bd -literal +syntax = "proto3"; + +/* + * Client message to the server. Messages on the wire are + * prefixed with a 32-bit size in network byte order. + */ +message ClientMessage { + oneof type { + AcceptMessage accept_msg = 1; + RejectMessage reject_msg = 2; + ExitMessage exit_msg = 3; + RestartMessage restart_msg = 4; + AlertMessage alert_msg = 5; + IoBuffer ttyin_buf = 6; + IoBuffer ttyout_buf = 7; + IoBuffer stdin_buf = 8; + IoBuffer stdout_buf = 9; + IoBuffer stderr_buf = 10; + ChangeWindowSize winsize_event = 11; + CommandSuspend suspend_event = 12; + } +} + +/* Equivalent of POSIX struct timespec */ +message TimeSpec { + int64 tv_sec = 1; /* seconds */ + int32 tv_nsec = 2; /* nanoseconds */ +} + +/* I/O buffer with keystroke data */ +message IoBuffer { + TimeSpec delay = 1; /* elapsed time since last record */ + bytes data = 2; /* keystroke data */ +} + +/* + * Key/value pairs, like Privilege Manager struct info. + * The value may be a number, a string, or a list of strings. + */ +message InfoMessage { + message StringList { + repeated string strings = 1; + } + message NumberList { + repeated int64 numbers = 1; + } + string key = 1; + oneof value { + int64 numval = 2; + string strval = 3; + StringList strlistval = 4; + NumberList numlistval = 5; + } +} + +/* + * Event log data for command accepted by the policy. + */ +message AcceptMessage { + TimeSpec submit_time = 1; /* when command was submitted */ + repeated InfoMessage info_msgs = 2; /* key,value event log data */ + bool expect_iobufs = 3; /* true if I/O logging enabled */ +} + +/* + * Event log data for command rejected by the policy. + */ +message RejectMessage { + TimeSpec submit_time = 1; /* when command was submitted */ + string reason = 2; /* reason command was rejected */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ +} + +/* Message sent by client when command exits. */ +/* Might revisit runtime and use end_time instead */ +message ExitMessage { + TimeSpec run_time = 1; /* total elapsed run time */ + int32 exit_value = 2; /* 0-255 */ + bool dumped_core = 3; /* true if command dumped core */ + string signal = 4; /* signal name if killed by signal */ + string error = 5; /* if killed due to other error */ +} + +/* Alert message, policy module-specific. */ +message AlertMessage { + TimeSpec alert_time = 1; /* time alert message occurred */ + string reason = 2; /* policy alert error string */ + repeated InfoMessage info_msgs = 3; /* key,value event log data */ +} + +/* Used to restart an existing I/O log on the server. */ +message RestartMessage { + string log_id = 1; /* ID of log being restarted */ + TimeSpec resume_point = 2; /* resume point (elapsed time) */ +} + +/* Window size change event. */ +message ChangeWindowSize { + TimeSpec delay = 1; /* elapsed time since last record */ + int32 rows = 2; /* new number of rows */ + int32 cols = 3; /* new number of columns */ +} + +/* Command suspend/resume event. */ +message CommandSuspend { + TimeSpec delay = 1; /* elapsed time since last record */ + string signal = 2; /* signal that caused suspend/resume */ +} + +/* + * Server messages to the client. Messages on the wire are + * prefixed with a 32-bit size in network byte order. + */ +message ServerMessage { + oneof type { + ServerHello hello = 1; /* server hello message */ + TimeSpec commit_point = 2; /* cumulative time of records stored */ + string log_id = 3; /* ID of server-side I/O log */ + string error = 4; /* error message from server */ + string abort = 5; /* abort message, kill command */ + } +} + +/* Hello message from server when client connects. */ +message ServerHello { + string server_id = 1; /* free-form server description */ + string redirect = 2; /* optional redirect if busy */ + repeated string servers = 3; /* optional list of known servers */ +} +.Ed +.Sh SEE ALSO +.Xr sudo_logsrvd.conf @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr sudo_logsrvd @mansectsu@ +.Rs +.%T Protocol Buffers +.%U https://developers.google.com/protocol-buffers/ +.Re +.Sh HISTORY +See the HISTORY file in the +.Nm sudo +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrvd.conf.man.in b/doc/sudo_logsrvd.conf.man.in new file mode 100644 index 0000000..8c752e9 --- /dev/null +++ b/doc/sudo_logsrvd.conf.man.in @@ -0,0 +1,769 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.TH "SUDO_LOGSRVD.CONF" "@mansectform@" "November 24, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_logsrvd.conf\fR +\- configuration for sudo_logsrvd +.SH "DESCRIPTION" +The +\fBsudo_logsrvd.conf\fR +file is used to configure the +\fBsudo_logsrvd\fR +log server. +It uses an INI-style format made up of sections in square brackets and +\(lqkey = value\(rq +pairs specific to each section below the section name. +Depending on the key, values may be integers, booleans or strings. +Section and key names are not case sensitive, but values are. +.PP +The pound sign +(\(oq#\(cq) +is used to indicate a comment. +Both the comment character and any text after it, up to the end of +the line, are ignored. +Lines beginning with a semi-colon +(\(oq\&;\(cq) +are also ignored. +.PP +Long lines can be continued with a backslash +(\(oq\e\(cq) +as the last character on the line. +Note that leading white space is removed from the beginning of lines +even when the continuation character is used. +.PP +The +\fIEXAMPLES\fR +section contains a copy of the default +\fBsudo_logsrvd.conf\fR +file. +.PP +The following configuration sections are recognized: +.PP +.RS 6n +.PD 0 +.TP 4n +\fB\(bu\fR +server +.TP 4n +\fB\(bu\fR +iolog +.TP 4n +\fB\(bu\fR +eventlog +.TP 4n +\fB\(bu\fR +syslog +.TP 4n +\fB\(bu\fR +logfile +.RE +.PD +.PP +Each section is described in detail below. +.SS "server" +The +\fIserver\fR +section configures the address and port the server will listen on. +The following keys are recognized: +.TP 10n +listen_address = host[:port][(tls)] +The host name or IP address, optional port to listen on and +an optional Transport Layer Security (TLS) flag in parentheses. +.sp +The host may be a host name, an IPv4 address, an IPv6 address +in square brackets or the wild card entry +\(oq*\(cq. +A host setting of +\(oq*\(cq +will cause +\fBsudo_logsrvd\fR +to listen on all configured network interfaces. +.sp +If the optional tls flag is present, +\fBsudo_logsrvd\fR +will secure the connection with TLS version 1.2 or 1.3. +Versions of TLS prior to 1.2 are not supported. +See +sudo_logsrvd(8) +for details on generating TLS keys and certificates. +.sp +If a port is specified, it may either be a port number or a known +service name as defined by the system service name database. +If no port is specified, port 30343 will be used for plaintext +connections and port 30344 will be used for TLS connections. +.sp +The default value is: +.nf +.RS 16n +listen_address = *:30343 +listen_address = *:30344(tls) +.RE +.fi +.RS 10n +which will listen on all configured network interfaces for both +plaintext and TLS connections. +Multiple +\fIlisten_address\fR +lines may be specified to listen on more than one port or interface. +.RE +.TP 10n +pid_file = path +The path to the file containing the process ID of the running +\fBsudo_logsrvd\fR. +If set to an empty value, or if +\fBsudo_logsrvd\fR +is run with the +\fB\-n\fR +option, no +\fIpid_file\fR +will be created. +If +\fIpid_file\fR +refers to a symbolic link, it will be ignored. +The default value is +\fI@rundir@/sudo_logsrvd.pid\fR. +.TP 10n +tcp_keepalive = boolean +If true, +\fBsudo_logsrvd\fR +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, the connection will be closed. +.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. +.TP 10n +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 +when authenticating clients. +The default is to use +\fI/etc/ssl/sudo/cacert.pem\fR +if it exists, otherwise the system's default certificate authority +database is used. +.TP 10n +tls_cert = path +The path to the server's certificate file, in PEM format. +The default value is +\fI/etc/ssl/sudo/certs/logsrvd_cert.pem\fR. +.TP 10n +tls_checkpeer = bool +If true, client certificates will be validated by the server; +clients without a valid certificate will be unable to connect. +If false, no validation of client certificates will be performed. +It true and client certificates are created using a private certificate +authority, the +\fItls_cacert\fR +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. +.TP 10n +tls_ciphers_v12 = string +A list of ciphers to use for connections secured by TLS version 1.2 only, +separated by a colon +\(oq:\&\(cq. +See the +\fICIPHER LIST FORMAT\fR +section in +openssl-ciphers(1) +for full details. +The default value is +\fRHIGH:!aNULL\fR +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. +.TP 10n +tls_ciphers_v13 = string +A list of ciphers to use for connections secured by TLS version 1.3 only, +separated by a colon +\(oq:\&\(cq. +Supported cipher suites depend on the version of OpenSSL used, +but should include the following: +.sp +.RS 16n +.PD 0 +.TP 10n +TLS_AES_128_GCM_SHA256 +.TP 10n +TLS_AES_256_GCM_SHA384 +.TP 10n +TLS_CHACHA20_POLY1305_SHA256 +.TP 10n +TLS_AES_128_CCM_SHA256 +.TP 10n +TLS_AES_128_CCM_8_SHA256 +.RE +.RS 10n +.sp +The default cipher suite is TLS_AES_256_GCM_SHA384. +.RE +.PD +.TP 10n +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: +.nf +.sp +.RS 10n +openssl dhparam -out /etc/sudo_logsrvd_dhparams.pem 2048 +.RE +.fi +.RS 10n +.sp +By default, +\fBsudo_logsrvd\fR +will use the OpenSSL defaults for Diffie-Hellman key generation. +.RE +.TP 10n +tls_key = path +The path to the server's private key file, in PEM format. +The default value is +\fI/etc/ssl/sudo/private/logsrvd_key.pem\fR. +.TP 10n +tls_verify = bool +If true, the server certificate will be verified at startup and +clients will authenticate the server by verifying its certificate +and identity. +If false, no verification is performed of the server certificate +by the server or the client. +When using self-signed certificates without a certificate authority, +this setting should be set to false. +The default value is true. +.SS "iolog" +The +\fIiolog\fR +section configures I/O log parameters. +These settings are identical to the I/O configuration in +sudoers(@mansectform@). +The following keys are recognized: +.TP 10n +iolog_compress = boolean +If set, I/O logs will be compressed using +\fBzlib\fR. +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. +.TP 10n +iolog_dir = path +The top-level directory to use when constructing the path +name for the I/O log directory. +The session sequence number, if any, is stored in the directory. +The default value is +\fI@iolog_dir@\fR. +.sp +The following percent +(\(oq%\(cq) +escape sequences are supported: +.PP +.RS 10n +.PD 0 +.TP 6n +\fR%{seq}\fR +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 +expanded to the invoking user's login name +.TP 6n +\fR%{group}\fR +expanded to the name of the invoking user's real group-ID +.TP 6n +\fR%{runas_user}\fR +expanded to the login name of the user the command will +be run as (e.g., root) +.TP 6n +\fR%{runas_group}\fR +expanded to the group name of the user the command will +be run as (e.g., wheel) +.TP 6n +\fR%{hostname}\fR +expanded to the local host name without the domain name +.TP 6n +\fR%{command}\fR +expanded to the base name of the command being run +.PP +In addition, any escape sequences supported by the system's +strftime(3) +function will be expanded. +.sp +To include a literal +\(oq%\(cq +character, the string +\(oq%%\(cq +should be used. +.RE +.TP 10n +iolog_file = path +The path name, relative to +\fIiolog_dir\fR, +in which to store I/O logs. +Note that +\fIiolog_file\fR +may contain directory components. +The default value is +\fR%{seq}\fR. +.sp +See the +\fIiolog_dir\fR +setting above for a list of supported percent +(\(oq%\(cq) +escape sequences. +.sp +In addition to the escape sequences, path names that end in six or +more +\fRX\fRs +will have the +\fRX\fRs +replaced with a unique combination of digits and letters, similar to the +mktemp(3) +function. +.sp +If the path created by concatenating +\fIiolog_dir\fR +and +\fIiolog_file\fR +already exists, the existing I/O log file will be truncated and +overwritten unless +\fIiolog_file\fR +ends in six or +more +\fRX\fRs. +.TP 10n +iolog_flush = boolean +If set, I/O log data is flushed to disk after each write instead of +buffering it. +This makes it possible to view the logs in real-time as the program is +executing but may significantly reduce the effectiveness +of I/O log compression. +The default value is +\fRtrue\fR. +.TP 10n +iolog_group = name +The group name to look up when setting the group-ID on new I/O log +files and directories. +If +\fIiolog_group\fR +is not set, +the primary group-ID of the user specified by +\fIiolog_user is used.\fR +If neither +\fIiolog_group\fR +nor +\fIiolog_user\fR +are set, I/O log files and directories are created with group-ID 0. +.TP 10n +iolog_mode = mode +The file mode to use when creating I/O log files. +Mode bits for read and write permissions for owner, group or other +are honored, everything else is ignored. +The file permissions will always include the owner read and +write bits, even if they are not present in the specified mode. +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. +.TP 10n +iolog_user = name +The user name to look up when setting the owner of new +I/O log files and directories. +If +\fIiolog_group\fR +is set, it will be used instead of the user's primary group-ID. +By default, I/O log files and directories are created with user and +group-ID 0. +.TP 10n +maxseq = number +The maximum sequence number that will be substituted for the +\(lq\fR%{seq}\fR\(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 +is in base 36, +\fImaxseq\fR +itself should be expressed in decimal. +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. +.SS "eventlog" +The +\fIeventlog\fR +section configures how (and if) security policy events are logged. +.TP 6n +log_type = string +Where to log accept, reject and alert events reported by the policy. +Supported values are +\fIsyslog\fR, +\fIlogfile\fR, +and +\fInone\fR. +The default value is +\fIsyslog\fR. +.TP 6n +log_format = string +The event log format. +Supported log formats are +\(lqsudo\(rq +for traditional sudo-style logs and +\(lqjson\(rq +for JSON-format logs. +The JSON log entries contain the full contents of the accept, reject +and alert messages. +The default value is +\fIsudo\fR. +.SS "syslog" +The +\fIsyslog\fR +section configures how events are logged via +syslog(3). +.TP 6n +facility = string +Syslog facility if syslog is being used for logging. +Defaults to +\fR@logfac@\fR. +.sp +The following syslog facilities are supported: +\fBauthpriv\fR +(if your +OS supports it), +\fBauth\fR, +\fBdaemon\fR, +\fBuser\fR, +\fBlocal0\fR, +\fBlocal1\fR, +\fBlocal2\fR, +\fBlocal3\fR, +\fBlocal4\fR, +\fBlocal5\fR, +\fBlocal6\fR, +and +\fBlocal7\fR. +.TP 6n +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. +.sp +The following syslog priorities are supported: +\fBalert\fR, +\fBcrit\fR, +\fBdebug\fR, +\fBemerg\fR, +\fBerr\fR, +\fBinfo\fR, +\fBnotice\fR, +\fBwarning\fR, +and +\fBnone\fR. +Setting it to a value of +\fBnone\fR +will disable logging of successful commands. +.TP 6n +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. +.sp +See +\fIaccept_priority\fR +for the list of supported syslog priorities. +.TP 6n +alert_priority = string +Syslog priority to use for event log alert messages received from the client. +Defaults to +\fR@badpri@\fR. +.sp +See +\fIaccept_priority\fR +for the list of supported syslog priorities. +.TP 6n +maxlen = number +On many systems, +syslog(3) +has a relatively small log buffer. +IETF RFC 5424 states that syslog servers must support messages of +at least 480 bytes and should support messages up to 2048 bytes. +By default, +\fBsudo_logsrvd\fR +creates log messages up to 960 bytes which corresponds to the +historic +BSD +syslog implementation which used a 1024 byte buffer +to store the message, date, hostname and program name. +.sp +To prevent syslog messages from being truncated, +\fBsudo_logsrvd\fR +will split up sudo-style log messages that are larger than +\fImaxlen\fR +bytes. +When a message is split, additional parts will include the string +\(lq(command continued)\(rq +after the user name and before the continued command line arguments. +JSON-format log entries are never split and are not affected by +\fImaxlen\fR. +.SS "logfile" +The +\fIlogfile\fR +section consists of settings related to logging to a plain file +(not syslog). +.TP 6n +path = string +The path to the file-based event log. +This path must be fully-qualified and start with a +\(oq/\(cq +character. +The default value is +\fI@logpath@\fR. +.TP 6n +time_format = string +The string used when formatting the date and time for file-based event logs. +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 +which produces dates like +\(lqOct 3 07:15:24\(rq +in the C locale. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo_logsrvd.conf\fR +Sudo log server configuration file +.SH "EXAMPLES" +.nf +.RS 0n +# +# sudo logsrv configuration +# + +[server] +# The host name or IP address and port to listen on with an optional TLS +# flag. If no port is specified, port 30343 will be used for plaintext +# connections and port 30344 will be used to TLS connections. +# The following forms are accepted: +# listen_address = hostname(tls) +# listen_address = hostname:port(tls) +# listen_address = IPv4_address(tls) +# listen_address = IPv4_address:port(tls) +# listen_address = [IPv6_address](tls) +# listen_address = [IPv6_address]:port(tls) +# +# The (tls) suffix should be omitted for plaintext connections. +# +# Multiple listen_address settings may be specified. +# The default is to listen on all addresses. +#listen_address = *:30343 +#listen_address = *:30344(tls) + +# The file containing the ID of the running sudo_logsrvd process. +#pid_file = @rundir@/sudo_logsrvd.pid + +# If set, enable the SO_KEEPALIVE socket option on the connected socket. +#tcp_keepalive = true + +# The amount of time, in seconds, the server will wait for the client to +# respond. A value of 0 will disable the timeout. The default value is 30. +#timeout = 30 + +# If set, server certificate will be verified at server startup and +# also connecting clients will perform server authentication by +# verifying the server's certificate and identity. +#tls_verify = true + +# Whether to verify client certificates for TLS connections. +# By default client certs are not checked. +#tls_checkpeer = false + +# Path to the certificate authority bundle file in PEM format. +# Required if 'tls_verify' or 'tls_checkpeer' is set. +#tls_cacert = /etc/ssl/sudo/cacert.pem + +# Path to the server's certificate file in PEM format. +# Required for TLS connections. +#tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem + +# Path to the server's private key file in PEM format. +# Required for TLS connections. +#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem + +# TLS cipher list (see "CIPHER LIST FORMAT" in the openssl-ciphers manual). +# NOTE that this setting is only effective if the negotiated protocol +# is TLS version 1.2. +# The default cipher list is HIGH:!aNULL. +#tls_ciphers_v12 = HIGH:!aNULL + +# TLS cipher list if the negotiated protocol is TLS version 1.3. +# The default cipher list is TLS_AES_256_GCM_SHA384. +#tls_ciphers_v13 = TLS_AES_256_GCM_SHA384 + +# Path to the Diffie-Hellman parameter file in PEM format. +# If not set, the server will use the OpenSSL defaults. +#tls_dhparams = /etc/ssl/sudo/logsrvd_dhparams.pem + +[iolog] +# The top-level directory to use when constructing the path name for the +# I/O log directory. The session sequence number, if any, is stored here. +#iolog_dir = /var/log/sudo-io + +# The path name, relative to iolog_dir, in which to store I/O logs. +# Note that iolog_file may contain directory components. +#iolog_file = %{seq} + +# If set, I/O logs will be compressed using zlib. Enabling compression can +# make it harder to view the logs in real-time as the program is executing. +#iolog_compress = false + +# If set, I/O log data is flushed to disk after each write instead of +# buffering it. This makes it possible to view the logs in real-time +# as the program is executing but reduces the effectiveness of compression. +#iolog_flush = true + +# The group to use when creating new I/O log files and directories. +# If iolog_group is not set, the primary group-ID of the user specified +# by iolog_user is used. If neither iolog_group nor iolog_user +# are set, I/O log files and directories are created with group-ID 0. +#iolog_group = wheel + +# The user to use when setting the user-ID and group-ID of new I/O +# log files and directories. If iolog_group is set, it will be used +# instead of the user's primary group-ID. By default, I/O log files +# and directories are created with user and group-ID 0. +#iolog_user = root + +# The file mode to use when creating I/O log files. The file permissions +# will always include the owner read and write bits, even if they are +# not present in the specified mode. When creating I/O log directories, +# search (execute) bits are added to match the read and write bits +# specified by iolog_mode. +#iolog_mode = 0600 + +# The maximum sequence number that will be substituted for the "%{seq}" +# escape in the I/O log file. While the value substituted for "%{seq}" +# is in base 36, maxseq itself should be expressed in decimal. Values +# larger than 2176782336 (which corresponds to the base 36 sequence +# number "ZZZZZZ") will be silently truncated to 2176782336. +#maxseq = 2176782336 + +[eventlog] +# Where to log accept, reject and alert events. +# Accepted values are syslog, logfile, or none. +# Defaults to syslog +#log_type = syslog + +# Event log format. +# Currently only sudo-style event logs are supported. +#log_format = sudo + +[syslog] +# The maximum length of a syslog payload. +# On many systems, syslog(3) has a relatively small log buffer. +# IETF RFC 5424 states that syslog servers must support messages +# of at least 480 bytes and should support messages up to 2048 bytes. +# Messages larger than this value will be split into multiple messages. +#maxlen = 960 + +# The syslog facility to use for event log messages. +# The following syslog facilities are supported: authpriv (if your OS +# supports it), auth, daemon, user, local0, local1, local2, local3, +# local4, local5, local6, and local7. +#facility = authpriv + +# Syslog priority to use for event log accept messages, when the command +# is allowed by the security policy. The following syslog priorities are +# supported: alert, crit, debug, emerg, err, info, notice, warning, none. +#accept_priority = notice + +# Syslog priority to use for event log reject messages, when the command +# is not allowed by the security policy. +#reject_priority = alert + +# Syslog priority to use for event log alert messages reported by the +# client. +#alert_priority = alert + +[logfile] +# The path to the file-based event log. +# This path must be fully-qualified and start with a '/' character. +#path = /var/log/sudo + +# The format string used when formatting the date and time for +# file-based event logs. Formatting is performed via strftime(3) so +# any format string supported by that function is allowed. +#time_format = %h %e %T +.RE +.fi +.SH "SEE ALSO" +strftime(3), +sudo.conf(@mansectform@), +sudoers(@mansectform@), +sudo(8), +sudo_logsrvd(8) +.SH "HISTORY" +See the HISTORY file in the +\fBsudo\fR +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrvd.conf.mdoc.in b/doc/sudo_logsrvd.conf.mdoc.in new file mode 100644 index 0000000..f3e883a --- /dev/null +++ b/doc/sudo_logsrvd.conf.mdoc.in @@ -0,0 +1,712 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.Dd November 24, 2020 +.Dt SUDO_LOGSRVD.CONF @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_logsrvd.conf +.Nd configuration for sudo_logsrvd +.Sh DESCRIPTION +The +.Nm sudo_logsrvd.conf +file is used to configure the +.Nm sudo_logsrvd +log server. +It uses an INI-style format made up of sections in square brackets and +.Dq key = value +pairs specific to each section below the section name. +Depending on the key, values may be integers, booleans or strings. +Section and key names are not case sensitive, but values are. +.Pp +The pound sign +.Pq Ql # +is used to indicate a comment. +Both the comment character and any text after it, up to the end of +the line, are ignored. +Lines beginning with a semi-colon +.Pq Ql \&; +are also ignored. +.Pp +Long lines can be continued with a backslash +.Pq Ql \e +as the last character on the line. +Note that leading white space is removed from the beginning of lines +even when the continuation character is used. +.Pp +The +.Sx EXAMPLES +section contains a copy of the default +.Nm +file. +.Pp +The following configuration sections are recognized: +.Pp +.Bl -bullet -compact -offset indent +.It +server +.It +iolog +.It +eventlog +.It +syslog +.It +logfile +.El +.Pp +Each section is described in detail below. +.Ss server +The +.Em server +section configures the address and port the server will listen on. +The following keys are recognized: +.Bl -tag -width 8n +.It listen_address = host Ns Oo : Ns port Oc Ns Op (tls) +The host name or IP address, optional port to listen on and +an optional Transport Layer Security (TLS) flag in parentheses. +.Pp +The host may be a host name, an IPv4 address, an IPv6 address +in square brackets or the wild card entry +.Ql * . +A host setting of +.Ql * +will cause +.Nm sudo_logsrvd +to listen on all configured network interfaces. +.Pp +If the optional tls flag is present, +.Nm sudo_logsrvd +will secure the connection with TLS version 1.2 or 1.3. +Versions of TLS prior to 1.2 are not supported. +See +.Xr sudo_logsrvd @mansectsu@ +for details on generating TLS keys and certificates. +.Pp +If a port is specified, it may either be a port number or a known +service name as defined by the system service name database. +If no port is specified, port 30343 will be used for plaintext +connections and port 30344 will be used for TLS connections. +.Pp +The default value is: +.Bd -literal -compact -offset indent +listen_address = *:30343 +listen_address = *:30344(tls) +.Ed +which will listen on all configured network interfaces for both +plaintext and TLS connections. +Multiple +.Em listen_address +lines may be specified to listen on more than one port or interface. +.It pid_file = path +The path to the file containing the process ID of the running +.Nm sudo_logsrvd . +If set to an empty value, or if +.Nm sudo_logsrvd +is run with the +.Fl n +option, no +.Em pid_file +will be created. +If +.Em pid_file +refers to a symbolic link, it will be ignored. +The default value is +.Pa @rundir@/sudo_logsrvd.pid . +.It tcp_keepalive = boolean +If true, +.Nm sudo_logsrvd +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, the connection will be closed. +.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. +.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 +when authenticating clients. +The default is to use +.Pa /etc/ssl/sudo/cacert.pem +if it exists, otherwise the system's default certificate authority +database is used. +.It tls_cert = path +The path to the server's certificate file, in PEM format. +The default value is +.Pa /etc/ssl/sudo/certs/logsrvd_cert.pem . +.It tls_checkpeer = bool +If true, client certificates will be validated by the server; +clients without a valid certificate will be unable to connect. +If false, no validation of client certificates will be performed. +It true and client certificates are created using a private certificate +authority, the +.Em tls_cacert +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 . +.It tls_ciphers_v12 = string +A list of ciphers to use for connections secured by TLS version 1.2 only, +separated by a colon +.Ql :\& . +See the +.Sx CIPHER LIST FORMAT +section in +.Xr openssl-ciphers 1 +for full details. +The default value is +.Li 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. +.It tls_ciphers_v13 = string +A list of ciphers to use for connections secured by TLS version 1.3 only, +separated by a colon +.Ql :\& . +Supported cipher suites depend on the version of OpenSSL used, +but should include the following: +.Pp +.Bl -tag -compact -width 8n -offset indent +.It TLS_AES_128_GCM_SHA256 +.It TLS_AES_256_GCM_SHA384 +.It TLS_CHACHA20_POLY1305_SHA256 +.It TLS_AES_128_CCM_SHA256 +.It TLS_AES_128_CCM_8_SHA256 +.El +.Pp +The default cipher suite is 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: +.Bd -literal +openssl dhparam -out /etc/sudo_logsrvd_dhparams.pem 2048 +.Ed +.Pp +By default, +.Nm sudo_logsrvd +will use the OpenSSL defaults for Diffie-Hellman key generation. +.It tls_key = path +The path to the server's private key file, in PEM format. +The default value is +.Pa /etc/ssl/sudo/private/logsrvd_key.pem . +.It tls_verify = bool +If true, the server certificate will be verified at startup and +clients will authenticate the server by verifying its certificate +and identity. +If false, no verification is performed of the server certificate +by the server or the client. +When using self-signed certificates without a certificate authority, +this setting should be set to false. +The default value is true. +.El +.Ss iolog +The +.Em iolog +section configures I/O log parameters. +These settings are identical to the I/O configuration in +.Xr sudoers @mansectform@ . +The following keys are recognized: +.Bl -tag -width 8n +.It iolog_compress = boolean +If set, I/O logs will be compressed using +.Sy zlib . +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 . +.It iolog_dir = path +The top-level directory to use when constructing the path +name for the I/O log directory. +The session sequence number, if any, is stored in the directory. +The default value is +.Pa @iolog_dir@ . +.Pp +The following percent +.Pq Ql % +escape sequences are supported: +.Bl -tag -width 4n +.It Li %{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} +expanded to the invoking user's login name +.It Li %{group} +expanded to the name of the invoking user's real group-ID +.It Li %{runas_user} +expanded to the login name of the user the command will +be run as (e.g., root) +.It Li %{runas_group} +expanded to the group name of the user the command will +be run as (e.g., wheel) +.It Li %{hostname} +expanded to the local host name without the domain name +.It Li %{command} +expanded to the base name of the command being run +.El +.Pp +In addition, any escape sequences supported by the system's +.Xr strftime 3 +function will be expanded. +.Pp +To include a literal +.Ql % +character, the string +.Ql %% +should be used. +.It iolog_file = path +The path name, relative to +.Em iolog_dir , +in which to store I/O logs. +Note that +.Em iolog_file +may contain directory components. +The default value is +.Li %{seq} . +.Pp +See the +.Em iolog_dir +setting above for a list of supported percent +.Pq Ql % +escape sequences. +.Pp +In addition to the escape sequences, path names that end in six or +more +.Li X Ns s +will have the +.Li X Ns s +replaced with a unique combination of digits and letters, similar to the +.Xr mktemp 3 +function. +.Pp +If the path created by concatenating +.Em iolog_dir +and +.Em iolog_file +already exists, the existing I/O log file will be truncated and +overwritten unless +.Em iolog_file +ends in six or +more +.Li X Ns s . +.It iolog_flush = boolean +If set, I/O log data is flushed to disk after each write instead of +buffering it. +This makes it possible to view the logs in real-time as the program is +executing but may significantly reduce the effectiveness +of I/O log compression. +The default value is +.Li true . +.It iolog_group = name +The group name to look up when setting the group-ID on new I/O log +files and directories. +If +.Em iolog_group +is not set, +the primary group-ID of the user specified by +.Em iolog_user is used. +If neither +.Em iolog_group +nor +.Em iolog_user +are set, I/O log files and directories are created with group-ID 0. +.It iolog_mode = mode +The file mode to use when creating I/O log files. +Mode bits for read and write permissions for owner, group or other +are honored, everything else is ignored. +The file permissions will always include the owner read and +write bits, even if they are not present in the specified mode. +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 . +.It iolog_user = name +The user name to look up when setting the owner of new +I/O log files and directories. +If +.Em iolog_group +is set, it will be used instead of the user's primary group-ID. +By default, I/O log files and directories are created with user and +group-ID 0. +.It maxseq = number +The maximum sequence number that will be substituted for the +.Dq Li %{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} +is in base 36, +.Em maxseq +itself should be expressed in decimal. +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. +.El +.Ss eventlog +The +.Em eventlog +section configures how (and if) security policy events are logged. +.Bl -tag -width 4n +.It log_type = string +Where to log accept, reject and alert events reported by the policy. +Supported values are +.Em syslog , +.Em logfile , +and +.Em none . +The default value is +.Em syslog . +.It log_format = string +The event log format. +Supported log formats are +.Dq sudo +for traditional sudo-style logs and +.Dq json +for JSON-format logs. +The JSON log entries contain the full contents of the accept, reject +and alert messages. +The default value is +.Em sudo . +.El +.Ss syslog +The +.Em syslog +section configures how events are logged via +.Xr syslog 3 . +.Bl -tag -width 4n +.It facility = string +Syslog facility if syslog is being used for logging. +Defaults to +.Li @logfac@ . +.Pp +The following syslog facilities are supported: +.Sy authpriv +(if your +OS supports it), +.Sy auth , +.Sy daemon , +.Sy user , +.Sy local0 , +.Sy local1 , +.Sy local2 , +.Sy local3 , +.Sy local4 , +.Sy local5 , +.Sy local6 , +and +.Sy local7 . +.It accept_priority = string +Syslog priority to use when the user is allowed to run a command and +authentication is successful. +Defaults to +.Li @goodpri@ . +.Pp +The following syslog priorities are supported: +.Sy alert , +.Sy crit , +.Sy debug , +.Sy emerg , +.Sy err , +.Sy info , +.Sy notice , +.Sy warning , +and +.Sy none . +Setting it to a value of +.Sy none +will disable logging of successful commands. +.It reject_priority = string +Syslog priority to use when the user is not allowed to run a command or +when authentication is unsuccessful. +Defaults to +.Li @badpri@ . +.Pp +See +.Em accept_priority +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@ . +.Pp +See +.Em accept_priority +for the list of supported syslog priorities. +.It maxlen = number +On many systems, +.Xr syslog 3 +has a relatively small log buffer. +IETF RFC 5424 states that syslog servers must support messages of +at least 480 bytes and should support messages up to 2048 bytes. +By default, +.Nm sudo_logsrvd +creates log messages up to 960 bytes which corresponds to the +historic +.Bx +syslog implementation which used a 1024 byte buffer +to store the message, date, hostname and program name. +.Pp +To prevent syslog messages from being truncated, +.Nm sudo_logsrvd +will split up sudo-style log messages that are larger than +.Em maxlen +bytes. +When a message is split, additional parts will include the string +.Dq Pq command continued +after the user name and before the continued command line arguments. +JSON-format log entries are never split and are not affected by +.Em maxlen . +.El +.Ss logfile +The +.Em logfile +section consists of settings related to logging to a plain file +(not syslog). +.Bl -tag -width 4n +.It path = string +The path to the file-based event log. +This path must be fully-qualified and start with a +.Sq / +character. +The default value is +.Pa @logpath@ . +.It time_format = string +The string used when formatting the date and time for file-based event logs. +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" +which produces dates like +.Dq Oct 3 07:15:24 +in the C locale. +.El +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo_logsrvd.conf +Sudo log server configuration file +.El +.Sh EXAMPLES +.Bd -literal +# +# sudo logsrv configuration +# + +[server] +# The host name or IP address and port to listen on with an optional TLS +# flag. If no port is specified, port 30343 will be used for plaintext +# connections and port 30344 will be used to TLS connections. +# The following forms are accepted: +# listen_address = hostname(tls) +# listen_address = hostname:port(tls) +# listen_address = IPv4_address(tls) +# listen_address = IPv4_address:port(tls) +# listen_address = [IPv6_address](tls) +# listen_address = [IPv6_address]:port(tls) +# +# The (tls) suffix should be omitted for plaintext connections. +# +# Multiple listen_address settings may be specified. +# The default is to listen on all addresses. +#listen_address = *:30343 +#listen_address = *:30344(tls) + +# The file containing the ID of the running sudo_logsrvd process. +#pid_file = @rundir@/sudo_logsrvd.pid + +# If set, enable the SO_KEEPALIVE socket option on the connected socket. +#tcp_keepalive = true + +# The amount of time, in seconds, the server will wait for the client to +# respond. A value of 0 will disable the timeout. The default value is 30. +#timeout = 30 + +# If set, server certificate will be verified at server startup and +# also connecting clients will perform server authentication by +# verifying the server's certificate and identity. +#tls_verify = true + +# Whether to verify client certificates for TLS connections. +# By default client certs are not checked. +#tls_checkpeer = false + +# Path to the certificate authority bundle file in PEM format. +# Required if 'tls_verify' or 'tls_checkpeer' is set. +#tls_cacert = /etc/ssl/sudo/cacert.pem + +# Path to the server's certificate file in PEM format. +# Required for TLS connections. +#tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem + +# Path to the server's private key file in PEM format. +# Required for TLS connections. +#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem + +# TLS cipher list (see "CIPHER LIST FORMAT" in the openssl-ciphers manual). +# NOTE that this setting is only effective if the negotiated protocol +# is TLS version 1.2. +# The default cipher list is HIGH:!aNULL. +#tls_ciphers_v12 = HIGH:!aNULL + +# TLS cipher list if the negotiated protocol is TLS version 1.3. +# The default cipher list is TLS_AES_256_GCM_SHA384. +#tls_ciphers_v13 = TLS_AES_256_GCM_SHA384 + +# Path to the Diffie-Hellman parameter file in PEM format. +# If not set, the server will use the OpenSSL defaults. +#tls_dhparams = /etc/ssl/sudo/logsrvd_dhparams.pem + +[iolog] +# The top-level directory to use when constructing the path name for the +# I/O log directory. The session sequence number, if any, is stored here. +#iolog_dir = /var/log/sudo-io + +# The path name, relative to iolog_dir, in which to store I/O logs. +# Note that iolog_file may contain directory components. +#iolog_file = %{seq} + +# If set, I/O logs will be compressed using zlib. Enabling compression can +# make it harder to view the logs in real-time as the program is executing. +#iolog_compress = false + +# If set, I/O log data is flushed to disk after each write instead of +# buffering it. This makes it possible to view the logs in real-time +# as the program is executing but reduces the effectiveness of compression. +#iolog_flush = true + +# The group to use when creating new I/O log files and directories. +# If iolog_group is not set, the primary group-ID of the user specified +# by iolog_user is used. If neither iolog_group nor iolog_user +# are set, I/O log files and directories are created with group-ID 0. +#iolog_group = wheel + +# The user to use when setting the user-ID and group-ID of new I/O +# log files and directories. If iolog_group is set, it will be used +# instead of the user's primary group-ID. By default, I/O log files +# and directories are created with user and group-ID 0. +#iolog_user = root + +# The file mode to use when creating I/O log files. The file permissions +# will always include the owner read and write bits, even if they are +# not present in the specified mode. When creating I/O log directories, +# search (execute) bits are added to match the read and write bits +# specified by iolog_mode. +#iolog_mode = 0600 + +# The maximum sequence number that will be substituted for the "%{seq}" +# escape in the I/O log file. While the value substituted for "%{seq}" +# is in base 36, maxseq itself should be expressed in decimal. Values +# larger than 2176782336 (which corresponds to the base 36 sequence +# number "ZZZZZZ") will be silently truncated to 2176782336. +#maxseq = 2176782336 + +[eventlog] +# Where to log accept, reject and alert events. +# Accepted values are syslog, logfile, or none. +# Defaults to syslog +#log_type = syslog + +# Event log format. +# Currently only sudo-style event logs are supported. +#log_format = sudo + +[syslog] +# The maximum length of a syslog payload. +# On many systems, syslog(3) has a relatively small log buffer. +# IETF RFC 5424 states that syslog servers must support messages +# of at least 480 bytes and should support messages up to 2048 bytes. +# Messages larger than this value will be split into multiple messages. +#maxlen = 960 + +# The syslog facility to use for event log messages. +# The following syslog facilities are supported: authpriv (if your OS +# supports it), auth, daemon, user, local0, local1, local2, local3, +# local4, local5, local6, and local7. +#facility = authpriv + +# Syslog priority to use for event log accept messages, when the command +# is allowed by the security policy. The following syslog priorities are +# supported: alert, crit, debug, emerg, err, info, notice, warning, none. +#accept_priority = notice + +# Syslog priority to use for event log reject messages, when the command +# is not allowed by the security policy. +#reject_priority = alert + +# Syslog priority to use for event log alert messages reported by the +# client. +#alert_priority = alert + +[logfile] +# The path to the file-based event log. +# This path must be fully-qualified and start with a '/' character. +#path = /var/log/sudo + +# The format string used when formatting the date and time for +# file-based event logs. Formatting is performed via strftime(3) so +# any format string supported by that function is allowed. +#time_format = %h %e %T +.Ed +.Sh SEE ALSO +.Xr strftime 3 , +.Xr sudo.conf @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr sudo_logsrvd @mansectsu@ +.Sh HISTORY +See the HISTORY file in the +.Nm sudo +distribution (https://www.sudo.ws/history.html) for a brief +history of sudo. +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrvd.man.in b/doc/sudo_logsrvd.man.in new file mode 100644 index 0000000..2eae8d2 --- /dev/null +++ b/doc/sudo_logsrvd.man.in @@ -0,0 +1,438 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.TH "SUDO_LOGSRVD" "@mansectsu@" "March 28, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_logsrvd\fR +\- sudo event and I/O log server +.SH "SYNOPSIS" +.HP 13n +\fBsudo_logsrvd\fR +[\fB\-hnV\fR] +[\fB\-f\fR\ \fIfile\fR] +[\fB\-R\fR\ \fIpercentage\fR] +.SH "DESCRIPTION" +\fBsudo_logsrvd\fR +is a high-performance log server that accepts event and I/O logs from +\fBsudo\fR. +It can be used to implement centralized logging of +\fBsudo\fR +logs. +Event log entries may be logged either via +syslog(3) +or to a file. +I/O Logs created by +\fBsudo_logsrvd\fR +can be replayed via the +sudoreplay(@mansectsu@) +utility in the same way as logs generated directly by the +\fBsudoers\fR +plugin. +.PP +The server also supports restarting interrupted log transfers. +To distinguish completed I/O logs from incomplete ones, the +I/O log timing file is set to be read-only when the log is complete. +.PP +Configuration parameters for +\fBsudo_logsrvd\fR +may be specified in the +sudo_logsrvd.conf(@mansectform@) +file. +.PP +The options are as follows: +.TP 12n +\fB\-f\fR, \fB\--file\fR +Read configuration from +\fIfile\fR +instead of the default, +\fI@sysconfdir@/sudo_logsrvd.conf\fR. +.TP 12n +\fB\-h\fR, \fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-n\fR, \fB\--no-fork\fR +Run +\fBsudo_logsrvd\fR +in the foreground instead of detaching from the terminal and becoming +a daemon. +.TP 12n +\fB\-R\fR, \fB\--random-drop\fR +For each message, there is a +\fIpercentage\fR +chance that the server will drop the connection. +This is only intended for debugging the ability of a +client to restart a connection. +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBsudo_logsrvd\fR +version and exit. +.SS "Securing server connections" +The I/O log data sent to +\fBsudo_logsrvd\fR +may contain sensitive information such as passwords and should be +secured using Transport Layer Security (TLS). +Doing so requires having a signed certificate on the server and, if +\fItls_checkpeer\fR +is enabled in +sudo_logsrvd.conf(@mansectform@), +a signed certificate on the client as well. +.PP +The certificates can either be signed by a well-known Certificate +Authority (CA), or a private CA can be used. +Instructions for creating a private CA are included below in the +\fIEXAMPLES\fR +section. +.SS "Debugging sudo_logsrvd" +\fBsudo_logsrvd\fR +supports a flexible debugging framework that is configured via +\fRDebug\fR +lines in the +sudo.conf(@mansectform@) +file. +.PP +For more information on configuring +sudo.conf(@mansectform@), +please refer to its manual. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +Sudo front end configuration +.TP 26n +\fI@sysconfdir@/sudo_logsrvd.conf\fR +Sudo log server configuration file +.TP 26n +\fI@iolog_dir@\fR +Default I/O log file location +.TP 26n +\fI@rundir@/sudo_logsrvd.pid\fR +.br +Process ID file for +\fBsudo_logsrvd\fR +.SH "EXAMPLES" +.SS "Creating self-signed certificates" +Unless you are using certificates signed by a well-known Certificate +Authority (or a local enterprise CA), you will need to create your +own CA that can sign the certificates used by +\fBsudo_logsrvd\fR, +\fBsudo_sendlog\fR, +and the +\fBsudoers\fR +plugin. +The following steps use the +openssl(1) +command to create keys and certificates. +.SS "Initial setup" +First, we need to create a directory structure to store the +files for the CA. +We'll create a new directory hierarchy in +\fI/etc/ssl/sudo\fR +for this purpose. +.nf +.sp +.RS 6n +# mkdir /etc/ssl/sudo +# cd /etc/ssl/sudo +# mkdir certs csr newcerts private +# chmod 700 private +# touch index.txt +# echo 1000 > serial +.RE +.fi +.PP +The serial and index.txt files are used to keep track of signed certificates. +.PP +Next, we need to make a copy of the openssl.conf file and customize +it for our new CA. +The path to openssl.cnf is system-dependent but +\fI/etc/ssl/openssl.cnf\fR +is the most common location. +You will need to adjust the example below if it has a different location on +your system. +.nf +.sp +.RS 6n +# cp /etc/ssl/openssl.cnf . +.RE +.fi +.PP +Now edit the +\fIopenssl.cnf\fR +file in the current directory and make sure it contains +\(lqca\(rq +and +\(lqCA_default\(rq +sections. +Those sections should include the following settings: +.nf +.sp +.RS 6n +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = /etc/ssl/sudo +certs = $dir/certs +database = $dir/index.txt +certificate = $dir/cacert.pem +serial = $dir/serial +.RE +.fi +.PP +If your +\fIopenssl.conf\fR +file already has a +\(lqCA_default\(rq +section, you may only need to modify the +\(lqdir\(rq +setting. +.SS "Creating the CA key and certificate" +In order to create and sign our own certificates, we need to create +a private key and a certificate for the root of the CA. +First, create the private key and protect it with a pass phrase: +.nf +.sp +.RS 6n +# openssl genrsa -aes256 -out private/cakey.pem 4096 +# chmod 400 private/cakey.pem +.RE +.fi +.PP +Next, generate the root certificate, using appropriate values for +the site-specific fields: +.nf +.sp +.RS 6n +# openssl req -config openssl.cnf -key private/cakey.pem \e + -new -x509 -days 7300 -sha256 -extensions v3_ca \e + -out cacert.pem + +Enter pass phrase for private/cakey.pem: +You are about to be asked to enter information that will be +incorporated into your certificate request. +What you are about to enter is what is called a Distinguished Name +or a DN. +There are quite a few fields but you can leave some blank. +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:Colorado +Locality Name (eg, city) []: +Organization Name (eg, company) [Internet Widgits Pty Ltd]:sudo +Organizational Unit Name (eg, section) []:sudo Certificate Authority +Common Name (e.g., server FQDN or YOUR name) []:sudo Root CA +Email Address []: + +# chmod 444 cacert.pem +.RE +.fi +.PP +Finally, verify the root certificate: +.nf +.sp +.RS 6n +# openssl x509 -noout -text -in cacert.pem +.RE +.fi +.SS "Creating and signing certificates" +The server and client certificates will be signed by the previously +created root CA. +Usually, the root CA is not used to sign server/client certificates +directly. +Instead, intermediate certificates are created and signed with the +root CA and the intermediate certs are used to sign CSRs (Certificate +Signing Request). +In this example we'll skip this part for simplicity's sake and sign the +CSRs with the root CA. +.PP +First, generate the private key without a pass phrase. +.nf +.sp +.RS 6n +# openssl genrsa -out private/logsrvd_key.pem 2048 +# chmod 400 private/logsrvd_key.pem +.RE +.fi +.PP +Next, create a certificate signing request (CSR) for the server's certificate. +The organization name must match the name given in the root certificate. +The common name should be either the server's IP address or a fully +qualified domain name. +.nf +.sp +.RS 6n +# openssl req -config openssl.cnf -key private/logsrvd_key.pem -new \e + -sha256 -out csr/logsrvd_csr.pem + +Enter pass phrase for private/logsrvd_key.pem: +You are about to be asked to enter information that will be +incorporated into your certificate request. +What you are about to enter is what is called a Distinguished Name +or a DN. +There are quite a few fields but you can leave some blank. +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:Colorado +Locality Name (eg, city) []: +Organization Name (eg, company) [Internet Widgits Pty Ltd]:sudo +Organizational Unit Name (eg, section) []:sudo log server +Common Name (e.g., server FQDN or YOUR name) []:logserver.example.com +Email Address []: + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +.RE +.fi +.PP +Now sign the CSR that was just created: +.nf +.sp +.RS 6n +# openssl ca -config openssl.cnf -days 375 -notext -md sha256 \e + -in csr/logsrvd_csr.pem -out certs/logsrvd_cert.pem + +Using configuration from openssl.cnf +Enter pass phrase for ./private/cakey.pem: +Check that the request matches the signature +Signature ok +Certificate Details: + Serial Number: 4096 (0x1000) + Validity + Not Before: Nov 11 14:05:05 2019 GMT + Not After : Nov 20 14:05:05 2020 GMT + Subject: + countryName = US + stateOrProvinceName = Colorado + organizationName = sudo + organizationalUnitName = sudo log server + commonName = logserve.example.com + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 4C:50:F9:D0:BE:1A:4C:B2:AC:90:76:56:C7:9E:16:AE:E6:9E:E5:B5 + X509v3 Authority Key Identifier: + keyid:D7:91:24:16:B1:03:06:65:1A:7A:6E:CF:51:E9:5C:CB:7A:95:3E:0C + +Certificate is to be certified until Nov 20 14:05:05 2020 GMT (375 days) +Sign the certificate? [y/n]:y + +1 out of 1 certificate requests certified, commit? [y/n]y +Write out database with 1 new entries +Data Base Updated +.RE +.fi +.PP +Finally, verify the new certificate: +.nf +.sp +.RS 6n +# openssl verify -CAfile cacert.pem certs/logsrvd_cert.pem +certs/logsrvd_cert.pem: OK +.RE +.fi +.PP +The +\fI/etc/ssl/sudo/certs\fR +directory now contains a signed and verified certificate for use with +\fBsudo_logsrvd\fR. +.PP +To generate a client certificate, repeat the process above using +a different file name. +.SS "Configuring sudo_logsrvd to use TLS" +To use TLS for client/server communication, both +\fBsudo_logsrvd\fR +and the +\fBsudoers\fR +plugin need to be configured to use TLS. +Configuring +\fBsudo_logsrvd\fR +for TLS requires the following settings, assuming the same path +names used earlier: +.nf +.sp +.RS 6n +# If set, secure connections with TLS 1.2 or 1.3. +tls = true + +# Path to the certificate authority bundle file in PEM format. +tls_cacert = /etc/ssl/sudo/cacert.pem + +# Path to the server's certificate file in PEM format. +tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem + +# Path to the server's private key file in PEM format. +tls_key = /etc/ssl/sudo/private/logsrvd_key.pem +.RE +.fi +.PP +The root CA cert +(\fIcacert.pem\fR) +must be installed on the system running +\fBsudo_logsrvd\fR. +If peer authentication is enabled on the client, a copy of +\fIcacert.pem\fR +must be present on the client system too. +.SH "SEE ALSO" +sudo.conf(@mansectform@), +sudo_logsrvd.conf(@mansectform@), +sudoers(@mansectform@), +sudo(@mansectsu@), +sudo_sendlog(@mansectsu@), +sudoreplay(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo_logsrvd\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo_logsrvd\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_logsrvd.mdoc.in b/doc/sudo_logsrvd.mdoc.in new file mode 100644 index 0000000..9d436c7 --- /dev/null +++ b/doc/sudo_logsrvd.mdoc.in @@ -0,0 +1,396 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.Dd March 28, 2020 +.Dt SUDO_LOGSRVD @mansectsu@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_logsrvd +.Nd sudo event and I/O log server +.Sh SYNOPSIS +.Nm sudo_logsrvd +.Op Fl hnV +.Op Fl f Ar file +.Op Fl R Ar percentage +.Sh DESCRIPTION +.Nm +is a high-performance log server that accepts event and I/O logs from +.Nm sudo . +It can be used to implement centralized logging of +.Nm sudo +logs. +Event log entries may be logged either via +.Xr syslog 3 +or to a file. +I/O Logs created by +.Nm +can be replayed via the +.Xr sudoreplay @mansectsu@ +utility in the same way as logs generated directly by the +.Nm sudoers +plugin. +.Pp +The server also supports restarting interrupted log transfers. +To distinguish completed I/O logs from incomplete ones, the +I/O log timing file is set to be read-only when the log is complete. +.Pp +Configuration parameters for +.Nm +may be specified in the +.Xr sudo_logsrvd.conf @mansectform@ +file. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl f , -file +Read configuration from +.Ar file +instead of the default, +.Pa @sysconfdir@/sudo_logsrvd.conf . +.It Fl h , -help +Display a short help message to the standard output and exit. +.It Fl n , -no-fork +Run +.Nm +in the foreground instead of detaching from the terminal and becoming +a daemon. +.It Fl R , -random-drop +For each message, there is a +.Ar percentage +chance that the server will drop the connection. +This is only intended for debugging the ability of a +client to restart a connection. +.It Fl V , -version +Print the +.Nm +version and exit. +.El +.Ss Securing server connections +The I/O log data sent to +.Nm +may contain sensitive information such as passwords and should be +secured using Transport Layer Security (TLS). +Doing so requires having a signed certificate on the server and, if +.Em tls_checkpeer +is enabled in +.Xr sudo_logsrvd.conf @mansectform@ , +a signed certificate on the client as well. +.Pp +The certificates can either be signed by a well-known Certificate +Authority (CA), or a private CA can be used. +Instructions for creating a private CA are included below in the +.Sx EXAMPLES +section. +.Ss Debugging sudo_logsrvd +.Nm +supports a flexible debugging framework that is configured via +.Li Debug +lines in the +.Xr sudo.conf @mansectform@ +file. +.Pp +For more information on configuring +.Xr sudo.conf @mansectform@ , +please refer to its manual. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +Sudo front end configuration +.It Pa @sysconfdir@/sudo_logsrvd.conf +Sudo log server configuration file +.It Pa @iolog_dir@ +Default I/O log file location +.It Pa @rundir@/sudo_logsrvd.pid +Process ID file for +.Nm +.El +.Sh EXAMPLES +.Ss Creating self-signed certificates +Unless you are using certificates signed by a well-known Certificate +Authority (or a local enterprise CA), you will need to create your +own CA that can sign the certificates used by +.Nm , +.Nm sudo_sendlog , +and the +.Nm sudoers +plugin. +The following steps use the +.Xr openssl 1 +command to create keys and certificates. +.Ss Initial setup +First, we need to create a directory structure to store the +files for the CA. +We'll create a new directory hierarchy in +.Pa /etc/ssl/sudo +for this purpose. +.Bd -literal -offset indent +# mkdir /etc/ssl/sudo +# cd /etc/ssl/sudo +# mkdir certs csr newcerts private +# chmod 700 private +# touch index.txt +# echo 1000 > serial +.Ed +.Pp +The serial and index.txt files are used to keep track of signed certificates. +.Pp +Next, we need to make a copy of the openssl.conf file and customize +it for our new CA. +The path to openssl.cnf is system-dependent but +.Pa /etc/ssl/openssl.cnf +is the most common location. +You will need to adjust the example below if it has a different location on +your system. +.Bd -literal -offset indent +# cp /etc/ssl/openssl.cnf . +.Ed +.Pp +Now edit the +.Pa openssl.cnf +file in the current directory and make sure it contains +.Dq ca +and +.Dq CA_default +sections. +Those sections should include the following settings: +.Bd -literal -offset indent +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = /etc/ssl/sudo +certs = $dir/certs +database = $dir/index.txt +certificate = $dir/cacert.pem +serial = $dir/serial +.Ed +.Pp +If your +.Pa openssl.conf +file already has a +.Dq CA_default +section, you may only need to modify the +.Dq dir +setting. +.Ss Creating the CA key and certificate +In order to create and sign our own certificates, we need to create +a private key and a certificate for the root of the CA. +First, create the private key and protect it with a pass phrase: +.Bd -literal -offset indent +# openssl genrsa -aes256 -out private/cakey.pem 4096 +# chmod 400 private/cakey.pem +.Ed +.Pp +Next, generate the root certificate, using appropriate values for +the site-specific fields: +.Bd -literal -offset indent +# openssl req -config openssl.cnf -key private/cakey.pem \e + -new -x509 -days 7300 -sha256 -extensions v3_ca \e + -out cacert.pem + +Enter pass phrase for private/cakey.pem: +You are about to be asked to enter information that will be +incorporated into your certificate request. +What you are about to enter is what is called a Distinguished Name +or a DN. +There are quite a few fields but you can leave some blank. +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:Colorado +Locality Name (eg, city) []: +Organization Name (eg, company) [Internet Widgits Pty Ltd]:sudo +Organizational Unit Name (eg, section) []:sudo Certificate Authority +Common Name (e.g., server FQDN or YOUR name) []:sudo Root CA +Email Address []: + +# chmod 444 cacert.pem +.Ed +.Pp +Finally, verify the root certificate: +.Bd -literal -offset indent +# openssl x509 -noout -text -in cacert.pem +.Ed +.Ss Creating and signing certificates +The server and client certificates will be signed by the previously +created root CA. +Usually, the root CA is not used to sign server/client certificates +directly. +Instead, intermediate certificates are created and signed with the +root CA and the intermediate certs are used to sign CSRs (Certificate +Signing Request). +In this example we'll skip this part for simplicity's sake and sign the +CSRs with the root CA. +.Pp +First, generate the private key without a pass phrase. +.Bd -literal -offset indent +# openssl genrsa -out private/logsrvd_key.pem 2048 +# chmod 400 private/logsrvd_key.pem +.Ed +.Pp +Next, create a certificate signing request (CSR) for the server's certificate. +The organization name must match the name given in the root certificate. +The common name should be either the server's IP address or a fully +qualified domain name. +.Bd -literal -offset indent +# openssl req -config openssl.cnf -key private/logsrvd_key.pem -new \e + -sha256 -out csr/logsrvd_csr.pem + +Enter pass phrase for private/logsrvd_key.pem: +You are about to be asked to enter information that will be +incorporated into your certificate request. +What you are about to enter is what is called a Distinguished Name +or a DN. +There are quite a few fields but you can leave some blank. +For some fields there will be a default value, +If you enter '.', the field will be left blank. +----- +Country Name (2 letter code) [AU]:US +State or Province Name (full name) [Some-State]:Colorado +Locality Name (eg, city) []: +Organization Name (eg, company) [Internet Widgits Pty Ltd]:sudo +Organizational Unit Name (eg, section) []:sudo log server +Common Name (e.g., server FQDN or YOUR name) []:logserver.example.com +Email Address []: + +Please enter the following 'extra' attributes +to be sent with your certificate request +A challenge password []: +An optional company name []: +.Ed +.Pp +Now sign the CSR that was just created: +.Bd -literal -offset indent +# openssl ca -config openssl.cnf -days 375 -notext -md sha256 \e + -in csr/logsrvd_csr.pem -out certs/logsrvd_cert.pem + +Using configuration from openssl.cnf +Enter pass phrase for ./private/cakey.pem: +Check that the request matches the signature +Signature ok +Certificate Details: + Serial Number: 4096 (0x1000) + Validity + Not Before: Nov 11 14:05:05 2019 GMT + Not After : Nov 20 14:05:05 2020 GMT + Subject: + countryName = US + stateOrProvinceName = Colorado + organizationName = sudo + organizationalUnitName = sudo log server + commonName = logserve.example.com + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 4C:50:F9:D0:BE:1A:4C:B2:AC:90:76:56:C7:9E:16:AE:E6:9E:E5:B5 + X509v3 Authority Key Identifier: + keyid:D7:91:24:16:B1:03:06:65:1A:7A:6E:CF:51:E9:5C:CB:7A:95:3E:0C + +Certificate is to be certified until Nov 20 14:05:05 2020 GMT (375 days) +Sign the certificate? [y/n]:y + +1 out of 1 certificate requests certified, commit? [y/n]y +Write out database with 1 new entries +Data Base Updated +.Ed +.Pp +Finally, verify the new certificate: +.Bd -literal -offset indent +# openssl verify -CAfile cacert.pem certs/logsrvd_cert.pem +certs/logsrvd_cert.pem: OK +.Ed +.Pp +The +.Pa /etc/ssl/sudo/certs +directory now contains a signed and verified certificate for use with +.Nm sudo_logsrvd . +.Pp +To generate a client certificate, repeat the process above using +a different file name. +.Ss Configuring sudo_logsrvd to use TLS +To use TLS for client/server communication, both +.Nm +and the +.Nm sudoers +plugin need to be configured to use TLS. +Configuring +.Nm +for TLS requires the following settings, assuming the same path +names used earlier: +.Bd -literal -offset indent +# If set, secure connections with TLS 1.2 or 1.3. +tls = true + +# Path to the certificate authority bundle file in PEM format. +tls_cacert = /etc/ssl/sudo/cacert.pem + +# Path to the server's certificate file in PEM format. +tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem + +# Path to the server's private key file in PEM format. +tls_key = /etc/ssl/sudo/private/logsrvd_key.pem +.Ed +.Pp +The root CA cert +.Pq Pa cacert.pem +must be installed on the system running +.Nm . +If peer authentication is enabled on the client, a copy of +.Pa cacert.pem +must be present on the client system too. +.Sh SEE ALSO +.Xr sudo.conf @mansectform@ , +.Xr sudo_logsrvd.conf @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr sudo_sendlog @mansectsu@ , +.Xr sudoreplay @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_plugin.man.in b/doc/sudo_plugin.man.in new file mode 100644 index 0000000..712a714 --- /dev/null +++ b/doc/sudo_plugin.man.in @@ -0,0 +1,5147 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2009-2020 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. +.\" +.TH "SUDO_PLUGIN" "5" "November 17, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_plugin\fR +\- Sudo Plugin API +.SH "DESCRIPTION" +Starting with version 1.8, +\fBsudo\fR +supports a plugin API +for policy and session logging. +Plugins may be compiled as dynamic shared objects (the default on +systems that support them) or compiled statically into the +\fBsudo\fR +binary itself. +By default, the +\fBsudoers\fR +policy plugin and an associated I/O logging plugin are used. +Via the plugin API, +\fBsudo\fR +can be configured to use alternate policy and/or I/O logging plugins +provided by third parties. +The plugins to be used are specified in the +sudo.conf(@mansectform@) +file. +.PP +The API is versioned with a major and minor number. +The minor version number is incremented when additions are made. +The major number is incremented when incompatible changes are made. +A plugin should be check the version passed to it and make sure that the +major version matches. +.PP +The plugin API is defined by the +\fRsudo_plugin.h\fR +header file. +.SS "Policy plugin API" +A policy plugin must declare and populate a +\fRpolicy_plugin\fR +struct in the global scope. +This structure contains pointers to the functions that implement the +\fBsudo\fR +policy checks. +The name of the symbol should be specified in +sudo.conf(@mansectform@) +along with a path to the plugin so that +\fBsudo\fR +can load it. +.nf +.sp +.RS 0n +struct policy_plugin { +#define SUDO_POLICY_PLUGIN 1 + 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 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); + int (*show_version)(int verbose); + int (*check_policy)(int argc, char * const argv[], + 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); + int (*validate)(const char **errstr); + void (*invalidate)(int remove); + int (*init_session)(struct passwd *pwd, char **user_env[], + const char **errstr); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + struct sudo_plugin_event * (*event_alloc)(void); +}; +.RE +.fi +.PP +The policy_plugin struct has the following fields: +.TP 6n +type +The +\fRtype\fR +field should always be set to SUDO_POLICY_PLUGIN. +.TP 6n +version +The +\fRversion\fR +field should be set to +\fRSUDO_API_VERSION\fR. +.sp +This allows +\fBsudo\fR +to determine the API version the plugin was +built against. +.TP 6n +open +.nf +.RS 6n +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t plugin_printf, char * const settings[], + char * const user_info[], char * const user_env[], + char * const plugin_options[], const char **errstr); +.RE +.fi +.RS 6n +.sp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +\fBsudo\fR +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +version +The version passed in by +\fBsudo\fR +allows the plugin to determine the +major and minor version number of the plugin API supported by +\fBsudo\fR. +.TP 6n +conversation +A pointer to the +\fBconversation\fR() +function that can be used by the plugin to interact with the user (see +\fIConversation API\fR +for details). +Returns 0 on success and \-1 on failure. +.TP 6n +plugin_printf +A pointer to a +\fBprintf\fR()-style +function that may be used to display informational or error messages (see +\fIConversation API\fR +for details). +Returns the number of characters printed on success and \-1 on failure. +.TP 6n +settings +A vector of user-supplied +\fBsudo\fR +settings in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +These settings correspond to options the user specified when running +\fBsudo\fR. +As such, they will only be present when the corresponding option has +been specified on the command line. +.sp +When parsing +\fIsettings\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +The following values may be set by +\fBsudo\fR: +.PP +.RS 6n +.PD 0 +.TP 6n +bsdauth_type=string +Authentication type, if specified by the +\fB\-a\fR +option, to use on +systems where +BSD +authentication is supported. +.PD +.TP 6n +closefrom=number +If specified, the user has requested via the +\fB\-C\fR +option that +\fBsudo\fR +close all files descriptors with a value of +\fInumber\fR +or higher. +The plugin may optionally pass this, or another value, back in the +\fIcommand_info\fR +list. +.TP 6n +cmnd_chroot=string +The root directory (see +chroot(2)) +to run the command in, as specified by the user via the +\fB\-R\fR +option. +The plugin may ignore or restrict the user's ability to specify a new +root directory. +Only available starting with API version 1.16. +.TP 6n +cmnd_cwd=string +The working directory to run the command in, as specified by the user via the +\fB\-D\fR +option. +The plugin may ignore or restrict the user's ability to specify a new +working directory. +Only available starting with API version 1.16. +.TP 6n +debug_flags=string +A debug file path name followed by a space and a comma-separated +list of debug flags that correspond to the plugin's +\fRDebug\fR +entry in +sudo.conf(@mansectform@), +if there is one. +The flags are passed to the plugin exactly as they appear in +sudo.conf(@mansectform@). +The syntax used by +\fBsudo\fR +and the +\fBsudoers\fR +plugin is +\fIsubsystem\fR@\fIpriority\fR +but a plugin is free to use a different +format so long as it does not include a comma +(\(oq,\&\(cq). +Prior to +\fBsudo\fR +1.8.12, there was no way to specify plugin-specific +\fIdebug_flags\fR +so the value was always the same as that used by the +\fBsudo\fR +front end and did not include a path name, only the flags themselves. +As of version 1.7 of the plugin interface, +\fBsudo\fR +will only pass +\fIdebug_flags\fR +if +sudo.conf(@mansectform@) +contains a plugin-specific +\fRDebug\fR +entry. +.TP 6n +ignore_ticket=bool +Set to true if the user specified the +\fB\-k\fR +option along with a +command, indicating that the user wishes to ignore any cached +authentication credentials. +\fIimplied_shell\fR +to true. +This allows +\fBsudo\fR +with no arguments +to be used similarly to +su(1). +If the plugin does not to support this usage, it may return a value of \-2 +from the +\fBcheck_policy\fR() +function, which will cause +\fBsudo\fR +to print a usage message and +exit. +.TP 6n +implied_shell=bool +If the user does not specify a program on the command line, +\fBsudo\fR +will pass the plugin the path to the user's shell and set +.TP 6n +login_class=string +BSD +login class to use when setting resource limits and nice value, +if specified by the +\fB\-c\fR +option. +.TP 6n +login_shell=bool +Set to true if the user specified the +\fB\-i\fR +option, indicating that +the user wishes to run a login shell. +.TP 6n +max_groups=int +The maximum number of groups a user may belong to. +This will only be present if there is a corresponding setting in +sudo.conf(@mansectform@). +.TP 6n +network_addrs=list +A space-separated list of IP network addresses and netmasks in the +form +\(lqaddr/netmask\(rq, +e.g., +\(lq192.168.1.2/255.255.255.0\(rq. +The address and netmask pairs may be either IPv4 or IPv6, depending on +what the operating system supports. +If the address contains a colon +(\(oq:\&\(cq), +it is an IPv6 address, else it is IPv4. +.TP 6n +noninteractive=bool +Set to true if the user specified the +\fB\-n\fR +option, indicating that +\fBsudo\fR +should operate in non-interactive mode. +The plugin may reject a command run in non-interactive mode if user +interaction is required. +.TP 6n +plugin_dir=string +The default plugin directory used by the +\fBsudo\fR +front end. +This is the default directory set at compile time and may not +correspond to the directory the running plugin was loaded from. +It may be used by a plugin to locate support files. +.TP 6n +plugin_path=string +The path name of plugin loaded by the +\fBsudo\fR +front end. +The path name will be a fully-qualified unless the plugin was +statically compiled into +\fBsudo\fR. +.TP 6n +preserve_environment=bool +Set to true if the user specified the +\fB\-E\fR +option, indicating that +the user wishes to preserve the environment. +.TP 6n +preserve_groups=bool +Set to true if the user specified the +\fB\-P\fR +option, indicating that +the user wishes to preserve the group vector instead of setting it +based on the runas user. +.TP 6n +progname=string +The command name that sudo was run as, typically +\(lqsudo\(rq +or +\(lqsudoedit\(rq. +.TP 6n +prompt=string +The prompt to use when requesting a password, if specified via +the +\fB\-p\fR +option. +.TP 6n +remote_host=string +The name of the remote host to run the command on, if specified via +the +\fB\-h\fR +option. +Support for running the command on a remote host is meant to be implemented +via a helper program that is executed in place of the user-specified command. +The +\fBsudo\fR +front end is only capable of executing commands on the local host. +Only available starting with API version 1.4. +.TP 6n +run_shell=bool +Set to true if the user specified the +\fB\-s\fR +option, indicating that the user wishes to run a shell. +.TP 6n +runas_group=string +The group name or gid to run the command as, if specified via +the +\fB\-g\fR +option. +.TP 6n +runas_user=string +The user name or uid to run the command as, if specified via the +\fB\-u\fR +option. +.TP 6n +selinux_role=string +SELinux role to use when executing the command, if specified by +the +\fB\-r\fR +option. +.TP 6n +selinux_type=string +SELinux type to use when executing the command, if specified by +the +\fB\-t\fR +option. +.TP 6n +set_home=bool +Set to true if the user specified the +\fB\-H\fR +option. +If true, set the +\fRHOME\fR +environment variable to the target user's home directory. +.TP 6n +sudoedit=bool +Set to true when the +\fB\-e\fR +option is specified or if invoked as +\fBsudoedit\fR. +The plugin shall substitute an editor into +\fIargv\fR +in the +\fBcheck_policy\fR() +function or return \-2 with a usage error +if the plugin does not support +\fIsudoedit\fR. +For more information, see the +\fIcheck_policy\fR +section. +.TP 6n +timeout=string +Command timeout specified by the user via the +\fB\-T\fR +option. +Not all plugins support command timeouts and the ability of the +user to set a timeout may be restricted by policy. +The format of the timeout string is plugin-specific. +.PP +Additional settings may be added in the future so the plugin should +silently ignore settings that it does not recognize. +.RE +.TP 6n +user_info +A vector of information about the user running the command in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIuser_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +The following values may be set by +\fBsudo\fR: +.PP +.RS 6n +.PD 0 +.TP 6n +cols=int +The number of columns the user's terminal supports. +If there is no terminal device available, a default value of 80 is used. +.PD +.TP 6n +cwd=string +The user's current working directory. +.TP 6n +egid=gid_t +The effective group-ID of the user invoking +\fBsudo\fR. +.TP 6n +euid=uid_t +The effective user-ID of the user invoking +\fBsudo\fR. +.TP 6n +gid=gid_t +The real group-ID of the user invoking +\fBsudo\fR. +.TP 6n +groups=list +The user's supplementary group list formatted as a string of +comma-separated group-IDs. +.TP 6n +host=string +The local machine's hostname as returned by the +gethostname(2) +system call. +.TP 6n +lines=int +The number of lines the user's terminal supports. +If there is +no terminal device available, a default value of 24 is used. +.TP 6n +pgid=int +The ID of the process group that the running +\fBsudo\fR +process is a member of. +Only available starting with API version 1.2. +.TP 6n +pid=int +The process ID of the running +\fBsudo\fR +process. +Only available starting with API version 1.2. +.TP 6n +ppid=int +The parent process ID of the running +\fBsudo\fR +process. +Only available starting with API version 1.2. +.TP 6n +rlimit_as=soft,hard +The maximum size to which the process's address space may grow (in bytes), +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_core=soft,hard +The largest size core dump file that may be created (in bytes). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_cpu=soft,hard +The maximum amount of CPU time that the process may use (in seconds). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_data=soft,hard +The maximum size of the data segment for the process (in bytes). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_fsize=soft,hard +The largest size file that the process may create (in bytes). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_locks=soft,hard +The maximum number of locks that the process may establish, +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_memlock=soft,hard +The maximum size that the process may lock in memory (in bytes), +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_nofile=soft,hard +The maximum number of files that the process may have open. +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_nproc=soft,hard +The maximum number of processes that the user may run simultaneously. +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_rss=soft,hard +The maximum size to which the process's resident set size may grow (in bytes). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +rlimit_stack=soft,hard +The maximum size to which the process's stack may grow (in bytes). +The soft and hard limits are separated by a comma. +A value of +\(lqinfinity\(rq +indicates that there is no limit. +Only available starting with API version 1.16. +.TP 6n +sid=int +The session ID of the running +\fBsudo\fR +process or 0 if +\fBsudo\fR +is not part of a POSIX job control session. +Only available starting with API version 1.2. +.TP 6n +tcpgid=int +The ID of the foreground process group associated with the terminal +device associated with the +\fBsudo\fR +process or 0 if there is no terminal present. +Only available starting with API version 1.2. +.TP 6n +tty=string +The path to the user's terminal device. +If the user has no terminal device associated with the session, +the value will be empty, as in +\(lq\fRtty=\fR\(rq. +.TP 6n +uid=uid_t +The real user-ID of the user invoking +\fBsudo\fR. +.TP 6n +umask=octal +The invoking user's file creation mask. +Only available starting with API version 1.10. +.TP 6n +user=string +The name of the user invoking +\fBsudo\fR. +.PD 0 +.PP +.RE +.PD +.TP 6n +user_env +The user's environment in the form of a +\fRNULL\fR-terminated vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIuser_env\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +plugin_options +Any (non-comment) strings immediately after the plugin path are +passed as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +\fRNULL\fR-terminated +array of strings. +If no arguments were +specified, +\fIplugin_options\fR +will be the +\fRNULL\fR +pointer. +.sp +NOTE: the +\fIplugin_options\fR +parameter is only available starting with +API version 1.2. +A plugin +\fBmust\fR +check the API version specified +by the +\fBsudo\fR +front end before using +\fIplugin_options\fR. +Failure to do so may result in a crash. +.TP 6n +errstr +If the +\fBopen\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +close +.br +.nf +.RS 6n +void (*close)(int exit_status, int error); +.RE +.fi +.RS 6n +.sp +The +\fBclose\fR() +function is called when +\fBsudo\fR +is finished, shortly before it exits. +Starting with API version 1.15, +\fBclose\fR() +is called regardless of whether or not a command was actually executed. +This makes it possible for plugins to perform cleanup even when a +command was not run. +It is not possible to tell whether a command was run based solely +on the arguments passed to the +\fBclose\fR() +function. +To determine if a command was actually run, +the plugin must keep track of whether or not the +\fBcheck_policy\fR() +function returned successfully. +.sp +The function arguments are as follows: +.TP 6n +exit_status +The command's exit status, as returned by the +wait(2) +system call, or zero if no command was run. +The value of +\fRexit_status\fR +is undefined if +\fRerror\fR +is non-zero. +.TP 6n +error +.br +If the command could not be executed, this is set to the value of +\fRerrno\fR +set by the +execve(2) +system call. +The plugin is responsible for displaying error information via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function. +If the command was successfully executed, the value of +\fRerror\fR +is zero. +.PP +If no +\fBclose\fR() +function is defined, no I/O logging plugins are loaded, +and neither the +\fItimeout\fR +not +\fIuse_pty\fR +options are set in the +\fRcommand_info\fR +list, the +\fBsudo\fR +front end may execute the command directly instead of running +it as a child process. +.RE +.TP 6n +show_version +.nf +.RS 6n +int (*show_version)(int verbose); +.RE +.fi +.RS 6n +.sp +The +\fBshow_version\fR() +function is called by +\fBsudo\fR +when the user specifies +the +\fB\-V\fR +option. +The plugin may display its version information to the user via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function using +\fRSUDO_CONV_INFO_MSG\fR. +If the user requests detailed version information, the verbose flag will be set. +.sp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.RE +.TP 6n +check_policy +.nf +.RS 6n +int (*check_policy)(int argc, char * const argv[], char *env_add[], + char **command_info[], char **argv_out[], char **user_env_out[], + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBcheck_policy\fR() +function is called by +\fBsudo\fR +to determine +whether the user is allowed to run the specified commands. +.sp +If the +\fIsudoedit\fR +option was enabled in the +\fIsettings\fR +array +passed to the +\fBopen\fR() +function, the user has requested +\fIsudoedit\fR +mode. +\fIsudoedit\fR +is a mechanism for editing one or more files +where an editor is run with the user's credentials instead of with +elevated privileges. +\fBsudo\fR +achieves this by creating user-writable +temporary copies of the files to be edited and then overwriting the +originals with the temporary copies after editing is complete. +If the plugin supports +\fIsudoedit\fR, +it should choose the editor to be used, potentially from a variable +in the user's environment, such as +\fREDITOR\fR, +and include it in +\fIargv_out\fR +(note that environment +variables may include command line options). +The files to be edited should be copied from +\fIargv\fR +into +\fIargv_out\fR, +separated from the +editor and its arguments by a +\(lq\fR--\fR\(rq +element. +The +\(lq\fR--\fR\(rq +will +be removed by +\fBsudo\fR +before the editor is executed. +The plugin should also set +\fIsudoedit=true\fR +in the +\fIcommand_info\fR +list. +.sp +The +\fBcheck_policy\fR() +function returns 1 if the command is allowed, +0 if not allowed, \-1 for a general error, or \-2 for a usage error +or if +\fIsudoedit\fR +was specified but is unsupported by the plugin. +In the latter case, +\fBsudo\fR +will print a usage message before it +exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +argc +The number of elements in +\fIargv\fR, +not counting the final +\fRNULL\fR +pointer. +.TP 6n +argv +The argument vector describing the command the user wishes to run, +in the same form as what would be passed to the +execve(2) +system call. +The vector is terminated by a +\fRNULL\fR +pointer. +.TP 6n +env_add +Additional environment variables specified by the user on the command +line in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +The plugin may reject the command if one or more variables +are not allowed to be set, or it may silently ignore such variables. +.sp +When parsing +\fIenv_add\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +command_info +Information about the command being run in the form of +\(lqname=value\(rq +strings. +These values are used by +\fBsudo\fR +to set the execution +environment when running a command. +The plugin is responsible for creating and populating the vector, +which must be terminated with a +\fRNULL\fR +pointer. +The following values are recognized by +\fBsudo\fR: +.PP +.RS 6n +.PD 0 +.TP 6n +chroot=string +The root directory to use when running the command. +.PD +.TP 6n +closefrom=number +If specified, +\fBsudo\fR +will close all files descriptors with a value +of +\fInumber\fR +or higher. +.TP 6n +command=string +Fully qualified path to the command to be executed. +.TP 6n +cwd=string +The current working directory to change to when executing the command. +If +\fBsudo\fR +is unable to change to the new working directory, the command will +not be run unless +\fIcwd_optional\fR +is also set (see below). +.TP 6n +cwd_optional=bool +If enabled, +\fBsudo\fR +will treat an inability to change to the new working directory as a +non-fatal error. +This setting has no effect unless +\fIcwd\fR +is also set. +.TP 6n +exec_background=bool +By default, +\fBsudo\fR +runs a command as the foreground process as long as +\fBsudo\fR +itself is running in the foreground. +When +\fIexec_background\fR +is enabled and the command is being run in a pseudo-terminal +(due to I/O logging or the +\fIuse_pty\fR +setting), the command will be run as a background process. +Attempts to read from the controlling terminal (or to change terminal +settings) will result in the command being suspended with the +\fRSIGTTIN\fR +signal (or +\fRSIGTTOU\fR +in the case of terminal settings). +If this happens when +\fBsudo\fR +is a foreground process, the command will be granted the controlling terminal +and resumed in the foreground with no user intervention required. +The advantage of initially running the command in the background is that +\fBsudo\fR +need not read from the terminal unless the command explicitly requests it. +Otherwise, any terminal input must be passed to the command, whether it +has required it or not (the kernel buffers terminals so it is not possible +to tell whether the command really wants the input). +This is different from historic +\fIsudo\fR +behavior or when the command is not being run in a pseudo-terminal. +.sp +For this to work seamlessly, the operating system must support the +automatic restarting of system calls. +Unfortunately, not all operating systems do this by default, +and even those that do may have bugs. +For example, macOS fails to restart the +\fBtcgetattr\fR() +and +\fBtcsetattr\fR() +system calls (this is a bug in macOS). +Furthermore, because this behavior depends on the command stopping with the +\fRSIGTTIN\fR +or +\fRSIGTTOU\fR +signals, programs that catch these signals and suspend themselves +with a different signal (usually +\fRSIGTOP\fR) +will not be automatically foregrounded. +Some versions of the linux +su(1) +command behave this way. +Because of this, a plugin should not set +\fIexec_background\fR +unless it is explicitly enabled by the administrator and there should +be a way to enabled or disable it on a per-command basis. +.sp +This setting has no effect unless I/O logging is enabled or +\fIuse_pty\fR +is enabled. +.TP 6n +execfd=number +If specified, +\fBsudo\fR +will use the +fexecve(2) +system call to execute the command instead of +execve(2). +The specified +\fInumber\fR +must refer to an open file descriptor. +.TP 6n +iolog_compress=bool +Set to true if the I/O logging plugins, if any, should compress the +log data. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_group=string +The group that will own newly created I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_mode=octal +The file permission mode to use when creating I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_user=string +The user that will own newly created I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_path=string +Fully qualified path to the file or directory in which I/O log is +to be stored. +This is a hint to the I/O logging plugin which may choose to ignore it. +If no I/O logging plugin is loaded, this setting has no effect. +.TP 6n +iolog_stdin=bool +Set to true if the I/O logging plugins, if any, should log the +standard input if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_stdout=bool +Set to true if the I/O logging plugins, if any, should log the +standard output if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_stderr=bool +Set to true if the I/O logging plugins, if any, should log the +standard error if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_ttyin=bool +Set to true if the I/O logging plugins, if any, should log all +terminal input. +This only includes input typed by the user and not from a pipe or +redirected from a file. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +iolog_ttyout=bool +Set to true if the I/O logging plugins, if any, should log all +terminal output. +This only includes output to the screen, not output to a pipe or file. +This is a hint to the I/O logging plugin which may choose to ignore it. +.TP 6n +login_class=string +BSD +login class to use when setting resource limits and nice value (optional). +This option is only set on systems that support login classes. +.TP 6n +nice=int +Nice value (priority) to use when executing the command. +The nice value, if specified, overrides the priority associated with the +\fIlogin_class\fR +on +BSD +systems. +.TP 6n +noexec=bool +If set, prevent the command from executing other programs. +.TP 6n +preserve_fds=list +A comma-separated list of file descriptors that should be +preserved, regardless of the value of the +\fIclosefrom\fR +setting. +Only available starting with API version 1.5. +.TP 6n +preserve_groups=bool +If set, +\fBsudo\fR +will preserve the user's group vector instead of +initializing the group vector based on +\fRrunas_user\fR. +.TP 6n +runas_egid=gid +Effective group-ID to run the command as. +If not specified, the value of +\fIrunas_gid\fR +is used. +.TP 6n +runas_euid=uid +Effective user-ID to run the command as. +If not specified, the value of +\fIrunas_uid\fR +is used. +.TP 6n +runas_gid=gid +Group-ID to run the command as. +.TP 6n +runas_group=string +The name of the group the command will run as, if it is different +from the +\fIrunas_user\fR's +default group. +This value is provided for auditing purposes only, the +\fBsudo\fR +front-end uses +\fIrunas_egid\fR +and +\fIrunas_gid\fR +when executing the command. +.TP 6n +runas_groups=list +The supplementary group vector to use for the command in the form +of a comma-separated list of group-IDs. +If +\fIpreserve_groups\fR +is set, this option is ignored. +.TP 6n +runas_uid=uid +User-ID to run the command as. +.TP 6n +runas_user=string +The name of the user the command will run as, which should correspond to +\fIrunas_euid\fR +(or +\fIrunas_uid\fR +if +\fIrunas_euid\fR +is not set). +This value is provided for auditing purposes only, the +\fBsudo\fR +front-end uses +\fIrunas_euid\fR +and +\fIrunas_uid\fR +when executing the command. +.TP 6n +selinux_role=string +SELinux role to use when executing the command. +.TP 6n +selinux_type=string +SELinux type to use when executing the command. +.TP 6n +set_utmp=bool +Create a utmp (or utmpx) entry when a pseudo-terminal is allocated. +By default, the new entry will be a copy of the user's existing utmp +entry (if any), with the tty, time, type and pid fields updated. +.TP 6n +sudoedit=bool +Set to true when in +\fIsudoedit\fR +mode. +The plugin may enable +\fIsudoedit\fR +mode even if +\fBsudo\fR +was not invoked as +\fBsudoedit\fR. +This allows the plugin to perform command substitution and transparently +enable +\fIsudoedit\fR +when the user attempts to run an editor. +.TP 6n +sudoedit_checkdir=bool +Set to false to disable directory writability checks in +\fBsudoedit\fR. +By default, +\fBsudoedit\fR +1.8.16 and higher will check all directory components of the path to be +edited for writability by the invoking user. +Symbolic links will not be followed in writable directories and +\fBsudoedit\fR +will refuse to edit a file located in a writable directory. +These restrictions are not enforced when +\fBsudoedit\fR +is run by root. +The +\fIsudoedit_follow\fR +option can be set to false to disable this check. +Only available starting with API version 1.8. +.TP 6n +sudoedit_follow=bool +Set to true to allow +\fBsudoedit\fR +to edit files that are symbolic links. +By default, +\fBsudoedit\fR +1.8.15 and higher will refuse to open a symbolic link. +The +\fIsudoedit_follow\fR +option can be used to restore the older behavior and allow +\fBsudoedit\fR +to open symbolic links. +Only available starting with API version 1.8. +.TP 6n +timeout=int +Command timeout. +If non-zero then when the timeout expires the command will be killed. +.TP 6n +umask=octal +The file creation mask to use when executing the command. +This value may be overridden by PAM or login.conf on some systems +unless the +\fIumask_override\fR +option is also set. +.TP 6n +umask_override=bool +Force the value specified by the +\fIumask\fR +option to override any umask set by PAM or login.conf. +.TP 6n +use_pty=bool +Allocate a pseudo-terminal to run the command in, regardless of whether +or not I/O logging is in use. +By default, +\fBsudo\fR +will only run +the command in a pseudo-terminal when an I/O log plugin is loaded. +.TP 6n +utmp_user=string +User name to use when constructing a new utmp (or utmpx) entry when +\fIset_utmp\fR +is enabled. +This option can be used to set the user field in the utmp entry to +the user the command runs as rather than the invoking user. +If not set, +\fBsudo\fR +will base the new entry on +the invoking user's existing entry. +.PP +Unsupported values will be ignored. +.RE +.TP 6n +argv_out +The +\fRNULL\fR-terminated +argument vector to pass to the +execve(2) +system call when executing the command. +The plugin is responsible for allocating and populating the vector. +.TP 6n +user_env_out +The +\fRNULL\fR-terminated +environment vector to use when executing the command. +The plugin is responsible for allocating and populating the vector. +.TP 6n +errstr +If the +\fBcheck_policy\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +list +.nf +.RS 6n +int (*list)(int argc, char * const argv[], int verbose, + const char *list_user, const char **errstr); +.RE +.fi +.RS 6n +.sp +List available privileges for the invoking user. +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to +the user. +.sp +Privileges should be output via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function using +\fRSUDO_CONV_INFO_MSG\fR. +.sp +The function arguments are as follows: +.TP 6n +argc +The number of elements in +\fIargv\fR, +not counting the final +\fRNULL\fR +pointer. +.TP 6n +argv +If +non-\fRNULL\fR, +an argument vector describing a command the user +wishes to check against the policy in the same form as what would +be passed to the +execve(2) +system call. +If the command is permitted by the policy, the fully-qualified path +to the command should be displayed along with any command line arguments. +.TP 6n +verbose +Flag indicating whether to list in verbose mode or not. +.TP 6n +list_user +The name of a different user to list privileges for if the policy +allows it. +If +\fRNULL\fR, +the plugin should list the privileges of the invoking user. +.TP 6n +errstr +If the +\fBlist\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +validate +.nf +.RS 6n +int (*validate)(const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBvalidate\fR() +function is called when +\fBsudo\fR +is run with the +\fB\-v\fR +option. +For policy plugins such as +\fBsudoers\fR +that cache +authentication credentials, this function will validate and cache +the credentials. +.sp +The +\fBvalidate\fR() +function should be +\fRNULL\fR +if the plugin does not support credential caching. +.sp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional +error information to the user. +.sp +The function arguments are as follows: +.TP 6n +errstr +If the +\fBvalidate\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +invalidate +.nf +.RS 6n +void (*invalidate)(int remove); +.RE +.fi +.RS 6n +.sp +The +\fBinvalidate\fR() +function is called when +\fBsudo\fR +is run with the +\fB\-k\fR +or +\fB\-K\fR +option. +For policy plugins such as +\fBsudoers\fR +that +cache authentication credentials, this function will invalidate the +credentials. +If the +\fIremove\fR +flag is set, the plugin may remove +the credentials instead of simply invalidating them. +.sp +The +\fBinvalidate\fR() +function should be +\fRNULL\fR +if the plugin does not support credential caching. +.RE +.TP 6n +init_session +.nf +.RS 6n +int (*init_session)(struct passwd *pwd, char **user_env_out[]); +.RE +.fi +.RS 6n +.sp +The +\fBinit_session\fR() +function is called before +\fBsudo\fR +sets up the +execution environment for the command. +It is run in the parent +\fBsudo\fR +process and before any uid or gid changes. +This can be used to perform session setup that is not supported by +\fIcommand_info\fR, +such as opening the PAM session. +The +\fBclose\fR() +function can be +used to tear down the session that was opened by +\fRinit_session\fR. +.sp +The +\fIpwd\fR +argument points to a passwd struct for the user the +command will be run as if the uid the command will run as was found +in the password database, otherwise it will be +\fRNULL\fR. +.sp +The +\fIuser_env_out\fR +argument points to the environment the command will +run in, in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +This is the same string passed back to the front end via +the Policy Plugin's +\fIuser_env_out\fR +parameter. +If the +\fBinit_session\fR() +function needs to modify the user environment, it should update the +pointer stored in +\fIuser_env_out\fR. +The expected use case is to merge the contents of the PAM environment +(if any) with the contents of +\fIuser_env_out\fR. +NOTE: the +\fIuser_env_out\fR +parameter is only available +starting with API version 1.2. +A plugin +\fBmust\fR +check the API +version specified by the +\fBsudo\fR +front end before using +\fIuser_env_out\fR. +Failure to do so may result in a crash. +.sp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional +error information to the user. +.RE +.TP 6n +register_hooks +.nf +.RS 6n +void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); +.RE +.fi +.RS 6n +.sp +The +\fBregister_hooks\fR() +function is called by the sudo front end to +register any hooks the plugin needs. +If the plugin does not support hooks, +\fRregister_hooks\fR +should be set to the +\fRNULL\fR +pointer. +.sp +The +\fIversion\fR +argument describes the version of the hooks API +supported by the +\fBsudo\fR +front end. +.sp +The +\fBregister_hook\fR() +function should be used to register any supported +hooks the plugin needs. +It returns 0 on success, 1 if the hook type is not supported and \-1 +if the major version in +\fRstruct hook\fR +does not match the front end's major hook API version. +.sp +See the +\fIHook function API\fR +section below for more information +about hooks. +.sp +NOTE: the +\fBregister_hooks\fR() +function is only available starting +with API version 1.2. +If the +\fBsudo\fR +front end doesn't support API +version 1.2 or higher, +\fRregister_hooks\fR +will not be called. +.RE +.TP 6n +deregister_hooks +.nf +.RS 6n +void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); +.RE +.fi +.RS 6n +.sp +The +\fBderegister_hooks\fR() +function is called by the sudo front end +to deregister any hooks the plugin has registered. +If the plugin does not support hooks, +\fRderegister_hooks\fR +should be set to the +\fRNULL\fR +pointer. +.sp +The +\fIversion\fR +argument describes the version of the hooks API +supported by the +\fBsudo\fR +front end. +.sp +The +\fBderegister_hook\fR() +function should be used to deregister any +hooks that were put in place by the +\fBregister_hook\fR() +function. +If the plugin tries to deregister a hook that the front end does not support, +\fRderegister_hook\fR +will return an error. +.sp +See the +\fIHook function API\fR +section below for more information +about hooks. +.sp +NOTE: the +\fBderegister_hooks\fR() +function is only available starting +with API version 1.2. +If the +\fBsudo\fR +front end doesn't support API +version 1.2 or higher, +\fRderegister_hooks\fR +will not be called. +.RE +.TP 6n +event_alloc +.nf +.RS 6n +struct sudo_plugin_event * (*event_alloc)(void); +.RE +.fi +.RS 6n +.sp +The +\fBevent_alloc\fR() +function is used to allocate a +\fRstruct sudo_plugin_event\fR +which provides access to the main +\fBsudo\fR +event loop. +Unlike the other fields, the +\fBevent_alloc\fR() +pointer is filled in by the +\fBsudo\fR +front end, not by the plugin. +.sp +See the +\fIEvent API\fR +section below for more information +about events. +.sp +NOTE: the +\fBevent_alloc\fR() +function is only available starting +with API version 1.15. +If the +\fBsudo\fR +front end doesn't support API +version 1.15 or higher, +\fBevent_alloc\fR() +will not be set. +.RE +.TP 6n +errstr +If the +\fBinit_session\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PP +\fIPolicy Plugin Version Macros\fR +.nf +.sp +.RS 0n +/* Plugin API version major/minor. */ +#define SUDO_API_VERSION_MAJOR 1 +#define SUDO_API_VERSION_MINOR 13 +#define SUDO_API_MKVERSION(x, y) ((x << 16) | y) +#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e + SUDO_API_VERSION_MINOR) + +/* Getters and setters for API version */ +#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) +#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) +#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e + *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e +} while(0) +#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e + *(vp) = (*(vp) & 0xffff0000) | (n); \e +} while(0) +.RE +.fi +.SS "I/O plugin API" +.nf +.RS 0n +struct io_plugin { +#define SUDO_IO_PLUGIN 2 + 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 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); + void (*close)(int exit_status, int error); /* wait status or error */ + int (*show_version)(int verbose); + int (*log_ttyin)(const char *buf, unsigned int len, + const char **errstr); + int (*log_ttyout)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stdin)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stdout)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stderr)(const char *buf, unsigned int len, + const char **errstr); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + int (*change_winsize)(unsigned int lines, unsigned int cols, + const char **errstr); + int (*log_suspend)(int signo, const char **errstr); + struct sudo_plugin_event * (*event_alloc)(void); +}; +.RE +.fi +.PP +When an I/O plugin is loaded, +\fBsudo\fR +runs the command in a pseudo-terminal. +This makes it possible to log the input and output from the user's +session. +If any of the standard input, standard output or standard error do not +correspond to a tty, +\fBsudo\fR +will open a pipe to capture +the I/O for logging before passing it on. +.PP +The log_ttyin function receives the raw user input from the terminal +device (note that this will include input even when echo is disabled, +such as when a password is read). +The log_ttyout function receives output from the pseudo-terminal that is +suitable for replaying the user's session at a later time. +The +\fBlog_stdin\fR(), +\fBlog_stdout\fR() +and +\fBlog_stderr\fR() +functions are only called if the standard input, standard output +or standard error respectively correspond to something other than +a tty. +.PP +Any of the logging functions may be set to the +\fRNULL\fR +pointer if no logging is to be performed. +If the open function returns 0, no I/O will be sent to the plugin. +.PP +If a logging function returns an error +(\-1), +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 +If an input logging function rejects the data by returning 0, the +command will be terminated and the data will not be passed to the +command, though it will still be sent to any other I/O logging plugins. +If an output logging function rejects the data by returning 0, 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. +.PP +The audit_plugin struct has the following fields: +.TP 6n +type +The +\fRtype\fR +field should always be set to +\fRSUDO_IO_PLUGIN\fR. +.TP 6n +version +The +\fRversion\fR +field should be set to +\fRSUDO_API_VERSION\fR. +.sp +This allows +\fBsudo\fR +to determine the API version the plugin was +built against. +.TP 6n +open +.nf +.RS 6n +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t 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[]); +.RE +.fi +.RS 6n +.sp +The +\fBopen\fR() +function is run before the +\fBlog_ttyin\fR(), +\fBlog_ttyout\fR(), +\fBlog_stdin\fR(), +\fBlog_stdout\fR(), +\fBlog_stderr\fR(), +\fBlog_suspend\fR(), +\fBchange_winsize\fR(), +or +\fBshow_version\fR() +functions are called. +It is only called if the version is being requested or if the +policy plugin's +\fBcheck_policy\fR() +function has returned successfully. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +\fBsudo\fR +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +version +The version passed in by +\fBsudo\fR +allows the plugin to determine the +major and minor version number of the plugin API supported by +\fBsudo\fR. +.TP 6n +conversation +A pointer to the +\fBconversation\fR() +function that may be used by the +\fBshow_version\fR() +function to display version information (see +\fBshow_version\fR() +below). +The +\fBconversation\fR() +function may also be used to display additional error message to the user. +The +\fBconversation\fR() +function returns 0 on success and \-1 on failure. +.TP 6n +plugin_printf +A pointer to a +\fBprintf\fR()-style +function that may be used by the +\fBshow_version\fR() +function to display version information (see +show_version below). +The +\fBplugin_printf\fR() +function may also be used to display additional error message to the user. +The +\fBplugin_printf\fR() +function returns number of characters printed on success and \-1 on failure. +.TP 6n +settings +A vector of user-supplied +\fBsudo\fR +settings in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +These settings correspond to options the user specified when running +\fBsudo\fR. +As such, they will only be present when the corresponding option has +been specified on the command line. +.sp +When parsing +\fIsettings\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible settings. +.TP 6n +user_info +A vector of information about the user running the command in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIuser_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +command_info +A vector of information describing the command being run in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIcommand_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +argc +The number of elements in +\fIargv\fR, +not counting the final +\fRNULL\fR +pointer. +It can be zero, when +\fBsudo\fR +is called with +\fB\-V\fR. +.TP 6n +argv +If +non-\fRNULL\fR, +an argument vector describing a command the user +wishes to run in the same form as what would be passed to the +execve(2) +system call. +.TP 6n +user_env +The user's environment in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIuser_env\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +\fRNULL\fR-terminated +array of strings. +If no arguments were specified, +\fIplugin_options\fR +will be the +\fRNULL\fR +pointer. +.sp +NOTE: the +\fIplugin_options\fR +parameter is only available starting with +API version 1.2. +A plugin +\fBmust\fR +check the API version specified +by the +\fBsudo\fR +front end before using +\fIplugin_options\fR. +Failure to do so may result in a crash. +.TP 6n +errstr +If the +\fBopen\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +close +.br +.nf +.RS 6n +void (*close)(int exit_status, int error); +.RE +.fi +.RS 6n +.sp +The +\fBclose\fR() +function is called when +\fBsudo\fR +is finished, shortly before it exits. +.sp +The function arguments are as follows: +.TP 6n +exit_status +The command's exit status, as returned by the +wait(2) +system call, or zero if no command was run. +The value of +\fRexit_status\fR +is undefined if +\fRerror\fR +is non-zero. +.TP 6n +error +.br +If the command could not be executed, this is set to the value of +\fRerrno\fR +set by the +execve(2) +system call. +If the command was successfully executed, the value of +\fRerror\fR +is zero. +.PD 0 +.PP +.RE +.PD +.TP 6n +show_version +.nf +.RS 6n +int (*show_version)(int verbose); +.RE +.fi +.RS 6n +.sp +The +\fBshow_version\fR() +function is called by +\fBsudo\fR +when the user specifies +the +\fB\-V\fR +option. +The plugin may display its version information to the user via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function using +\fRSUDO_CONV_INFO_MSG\fR. +.sp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.RE +.TP 6n +log_ttyin +.nf +.RS 6n +int (*log_ttyin)(const char *buf, unsigned int len, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_ttyin\fR() +function is called whenever data can be read from +the user but before it is passed to the running command. +This allows the plugin to reject data if it chooses to (for instance +if the input contains banned content). +Returns 1 if the data should be passed to the command, 0 if the data +is rejected (which will terminate the running command) or \-1 if an +error occurred. +.sp +The function arguments are as follows: +.TP 6n +buf +The buffer containing user input. +.TP 6n +len +The length of +\fIbuf\fR +in bytes. +.TP 6n +errstr +If the +\fBlog_ttyin\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +log_ttyout +.nf +.RS 6n +int (*log_ttyout)(const char *buf, unsigned int len, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_ttyout\fR() +function is called whenever data can be read from +the command but before it is written to the user's terminal. +This allows the plugin to reject data if it chooses to (for instance +if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is rejected +(which will terminate the running command) or \-1 if an error occurred. +.sp +The function arguments are as follows: +.TP 6n +buf +The buffer containing command output. +.TP 6n +len +The length of +\fIbuf\fR +in bytes. +.TP 6n +errstr +If the +\fBlog_ttyout\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +log_stdin +.nf +.RS 6n +int (*log_stdin)(const char *buf, unsigned int len, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_stdin\fR() +function is only used if the standard input does +not correspond to a tty device. +It is called whenever data can be read from the standard input but +before it is passed to the running command. +This allows the plugin to reject data if it chooses to +(for instance if the input contains banned content). +Returns 1 if the data should be passed to the command, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.sp +The function arguments are as follows: +.TP 6n +buf +The buffer containing user input. +.TP 6n +len +The length of +\fIbuf\fR +in bytes. +.TP 6n +errstr +If the +\fBlog_stdin\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +log_stdout +.nf +.RS 6n +int (*log_stdout)(const char *buf, unsigned int len, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_stdout\fR() +function is only used if the standard output does not correspond +to a tty device. +It is called whenever data can be read from the command but before +it is written to the standard output. +This allows the plugin to reject data if it chooses to +(for instance if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.sp +The function arguments are as follows: +.TP 6n +buf +The buffer containing command output. +.TP 6n +len +The length of +\fIbuf\fR +in bytes. +.TP 6n +errstr +If the +\fBlog_stdout\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +log_stderr +.nf +.RS 6n +int (*log_stderr)(const char *buf, unsigned int len, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_stderr\fR() +function is only used if the standard error does +not correspond to a tty device. +It is called whenever data can be read from the command but before it +is written to the standard error. +This allows the plugin to reject data if it chooses to +(for instance if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.sp +The function arguments are as follows: +.TP 6n +buf +The buffer containing command output. +.TP 6n +len +The length of +\fIbuf\fR +in bytes. +.TP 6n +errstr +If the +\fBlog_stderr\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +register_hooks +See the +\fIPolicy plugin API\fR +section for a description of +\fRregister_hooks\fR. +.TP 6n +deregister_hooks +See the +\fIPolicy plugin API\fR +section for a description of +\fRderegister_hooks\fR. +.TP 6n +change_winsize +.nf +.RS 6n +int (*change_winsize)(unsigned int lines, unsigned int cols, + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBchange_winsize\fR() +function is called whenever the window size of the terminal changes from +the initial values specified in the +\fRuser_info\fR +list. +Returns \-1 if an error occurred, in which case no further calls to +\fBchange_winsize\fR() +will be made, +.sp +The function arguments are as follows: +.TP 6n +lines +.br +The number of lines (rows) in the re-sized terminal. +.TP 6n +cols +The number of columns in the re-sized terminal. +.TP 6n +errstr +If the +\fBchange_winsize\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.PD 0 +.PP +.RE +.PD +.TP 6n +log_suspend +.nf +.RS 6n +int (*log_suspend)(int signo, const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBlog_suspend\fR() +function is called whenever a command is suspended or resumed. +Logging this information makes it possible to skip the period of time when +the command was suspended during playback of a session. +Returns \-1 if an error occurred, in which case no further calls to +\fBlog_suspend\fR() +will be made, +.sp +The function arguments are as follows: +.TP 6n +signo +.br +The signal that caused the command to be suspended, or +\fRSIGCONT\fR +if the command was resumed. +.TP 6n +errstr +If the +\fBlog_suspend\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.sp +NOTE: the +\fIerrstr\fR +parameter is only available starting with +API version 1.15. +A plugin +\fBmust\fR +check the API version specified by the +\fBsudo\fR +front end before using +\fIerrstr\fR. +Failure to do so may result in a crash. +.TP 6n +event_alloc +.nf +.RS 6n +struct sudo_plugin_event * (*event_alloc)(void); +.RE +.fi +.RS 6n +.sp +The +\fBevent_alloc\fR() +function is used to allocate a +\fRstruct sudo_plugin_event\fR +which provides access to the main +\fBsudo\fR +event loop. +Unlike the other fields, the +\fBevent_alloc\fR() +pointer is filled in by the +\fBsudo\fR +front end, not by the plugin. +.sp +See the +\fIEvent API\fR +section below for more information +about events. +.sp +NOTE: the +\fBevent_alloc\fR() +function is only available starting +with API version 1.15. +If the +\fBsudo\fR +front end doesn't support API +version 1.15 or higher, +\fBevent_alloc\fR() +will not be set. +.RE +.PP +\fII/O Plugin Version Macros\fR +.sp +Same as for the +\fIPolicy plugin API\fR. +.RE +.SS "Audit plugin API" +.nf +.RS 0n +/* Audit plugin close function status types. */ +#define SUDO_PLUGIN_NO_STATUS 0 +#define SUDO_PLUGIN_WAIT_STATUS 1 +#define SUDO_PLUGIN_EXEC_ERROR 2 +#define SUDO_PLUGIN_SUDO_ERROR 3 + +#define SUDO_AUDIT_PLUGIN 3 +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[], + char * const user_info[], int submit_optind, + char * const submit_argv[], char * const submit_envp[], + char * const plugin_options[], const char **errstr); + void (*close)(int status_type, int status); + int (*accept)(const char *plugin_name, + unsigned int plugin_type, char * const command_info[], + char * const run_argv[], char * const run_envp[], + const char **errstr); + int (*reject)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); + int (*error)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); + int (*show_version)(int verbose); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + struct sudo_plugin_event * (*event_alloc)(void); +} +.RE +.fi +.PP +An audit plugin can be used to log successful and unsuccessful attempts +to run +\fBsudo\fR +independent of the policy or any I/O plugins. +Multiple audit plugins may be specified in +sudo.conf(@mansectform@). +.PP +The audit_plugin struct has the following fields: +.TP 6n +type +The +\fRtype\fR +field should always be set to +\fRSUDO_AUDIT_PLUGIN\fR. +.TP 6n +version +The +\fRversion\fR +field should be set to +\fRSUDO_API_VERSION\fR. +.sp +This allows +\fBsudo\fR +to determine the API version the plugin was +built against. +.TP 6n +open +.nf +.RS 6n +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t sudo_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); +.RE +.fi +.RS 6n +.sp +The audit +\fBopen\fR() +function is run before any other +\fBsudo\fR +plugin API functions. +This makes it possible to audit failures in the other plugins. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +\fBsudo\fR +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +version +The version passed in by +\fBsudo\fR +allows the plugin to determine the +major and minor version number of the plugin API supported by +\fBsudo\fR. +.TP 6n +conversation +A pointer to the +\fBconversation\fR() +function that may be used by the +\fBshow_version\fR() +function to display version information (see +\fBshow_version\fR() +below). +The +\fBconversation\fR() +function may also be used to display additional error message to the user. +The +\fBconversation\fR() +function returns 0 on success and \-1 on failure. +.TP 6n +plugin_printf +A pointer to a +\fBprintf\fR()-style +function that may be used by the +\fBshow_version\fR() +function to display version information (see +show_version below). +The +\fBplugin_printf\fR() +function may also be used to display additional error message to the user. +The +\fBplugin_printf\fR() +function returns number of characters printed on success and \-1 on failure. +.TP 6n +settings +A vector of user-supplied +\fBsudo\fR +settings in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +These settings correspond to options the user specified when running +\fBsudo\fR. +As such, they will only be present when the corresponding option has +been specified on the command line. +.sp +When parsing +\fIsettings\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible settings. +.TP 6n +user_info +A vector of information about the user running the command in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIuser_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +submit_optind +The index into +\fIsubmit_argv\fR +that corresponds to the first entry that is not a command line option. +If +\fIsubmit_argv\fR +only consists of options, which may be the case with the +\fB\-l\fR +or +\fB\-v\fR +options, +\fRsubmit_argv[submit_optind]\fR +will evaluate to the NULL pointer. +.TP 6n +submit_argv +The argument vector +\fBsudo\fR +was invoked with, including all command line options. +The +\fIsubmit_optind\fR +argument can be used to determine the end of the command line options. +.TP 6n +submit_envp +The invoking user's environment in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIsubmit_envp\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +\fRNULL\fR-terminated +array of strings. +If no arguments were specified, +\fIplugin_options\fR +will be the +\fRNULL\fR +pointer. +.TP 6n +errstr +If the +\fBopen\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +close +.br +.nf +.RS 6n +void (*close)(int status_type, int status); +.RE +.fi +.RS 6n +.sp +The +\fBclose\fR() +function is called when +\fBsudo\fR +is finished, shortly before it exits. +.sp +The function arguments are as follows: +.TP 6n +status_type +The type of status being passed. +One of +\fRSUDO_PLUGIN_NO_STATUS\fR, +\fRSUDO_PLUGIN_WAIT_STATUS\fR, +\fRSUDO_PLUGIN_EXEC_ERROR\fR +or +\fRSUDO_PLUGIN_SUDO_ERROR\fR. +.TP 6n +status +Depending on the value of +\fIstatus_type\fR, +this value is either +ignored, the command's exit status as returned by the +wait(2) +system call, the value of +\fRerrno\fR +set by the +execve(2) +system call, or the value of +\fRerrno\fR +resulting from an error in the +\fBsudo\fR +front end. +.PD 0 +.PP +.RE +.PD +.TP 6n +accept +.nf +.RS 6n +int (*accept)(const char *plugin_name, unsigned int plugin_type, + char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBaccept\fR() +function is called when a command or action is accepted by a policy +or approval plugin. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that accepted the command or +\(lqsudo\(rq +for the +\fBsudo\fR +front-end. +.TP 6n +plugin_type +The type of plugin that accepted the command, currently either +\fRSUDO_POLICY_PLUGIN\fR, +\fRSUDO_POLICY_APPROVAL\fR +or +\fRSUDO_FRONT_END\fR. +The +\fBaccept\fR() +function is called multiple times--once for each policy or approval +plugin that succeeds and once for the sudo front-end. +When called on behalf of the sudo front-end, +\fIcommand_info\fR +may include information from an I/O logging plugin as well. +.sp +Typically, an audit plugin is interested in either the accept status from +the +\fBsudo\fR +front-end or from the various policy and approval plugins, but not both. +It is possible for the policy plugin to accept a command that is +later rejected by an approval plugin, in which case the audit +plugin's +\fBaccept\fR() +and +\fBreject\fR() +functions will +\fIboth\fR +be called. +.TP 6n +command_info +An optional +vector of information describing the command being run in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIcommand_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +run_argv +A +\fRNULL\fR-terminated +argument vector describing a command that will be run in the +same form as what would be passed to the +execve(2) +system call. +.TP 6n +run_envp +The environment the command will be run with in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIrun_envp\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +errstr +If the +\fBaccept\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +reject +.nf +.RS 6n +int (*reject)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBreject\fR() +function is called when a command or action is rejected by a plugin. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that rejected the command. +.TP 6n +plugin_type +The type of plugin that rejected the command, currently either +\fRSUDO_POLICY_PLUGIN\fR, +\fRSUDO_APPROVAL_PLUGIN\fR +or +\fRSUDO_IO_PLUGIN\fR. +.sp +Unlike the +\fBaccept\fR() +function, the +\fBreject\fR() +function is not called on behalf of the +\fBsudo\fR +front-end. +.TP 6n +audit_msg +An optional string describing the reason the command was rejected +by the plugin. +If the plugin did not provide a reason, +\fIaudit_msg\fR +will be the +\fRNULL\fR +pointer. +.TP 6n +command_info +An optional +vector of information describing the command being run in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIcommand_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +errstr +If the +\fBreject\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +error +.br +.nf +.RS 6n +int (*error)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); +.RE +.fi +.RS 6n +.sp +The +\fBerror\fR() +function is called when a plugin or the +\fBsudo\fR +front-end returns an error. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that generated the error or +\(lqsudo\(rq +for the +\fBsudo\fR +front-end. +.TP 6n +plugin_type +The type of plugin that generated the error, or +\fRSUDO_FRONT_END\fR +for the +\fBsudo\fR +front-end. +.TP 6n +audit_msg +An optional string describing the plugin error. +If the plugin did not provide a description, +\fIaudit_msg\fR +will be the +\fRNULL\fR +pointer. +.TP 6n +command_info +An optional +vector of information describing the command being run in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIcommand_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +errstr +If the +\fBerror\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +show_version +.nf +.RS 6n +int (*show_version)(int verbose); +.RE +.fi +.RS 6n +.sp +The +\fBshow_version\fR() +function is called by +\fBsudo\fR +when the user specifies +the +\fB\-V\fR +option. +The plugin may display its version information to the user via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function using +\fRSUDO_CONV_INFO_MSG\fR. +If the user requests detailed version information, the verbose flag will be set. +.sp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.RE +.TP 6n +register_hooks +See the +\fIPolicy plugin API\fR +section for a description of +\fRregister_hooks\fR. +.TP 6n +deregister_hooks +See the +\fIPolicy plugin API\fR +section for a description of +\fRderegister_hooks\fR. +.TP 6n +event_alloc +.nf +.RS 6n +struct sudo_plugin_event * (*event_alloc)(void); +.RE +.fi +.RS 6n +.sp +The +\fBevent_alloc\fR() +function is used to allocate a +\fRstruct sudo_plugin_event\fR +which provides access to the main +\fBsudo\fR +event loop. +Unlike the other fields, the +\fBevent_alloc\fR() +pointer is filled in by the +\fBsudo\fR +front end, not by the plugin. +.sp +See the +\fIEvent API\fR +section below for more information +about events. +.sp +NOTE: the +\fBevent_alloc\fR() +function is only available starting +with API version 1.17. +If the +\fBsudo\fR +front end doesn't support API +version 1.17 or higher, +\fBevent_alloc\fR() +will not be set. +.RE +.SS "Approval plugin API" +.nf +.RS 0n +struct approval_plugin { +#define SUDO_APPROVAL_PLUGIN 4 + 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[], + char * const user_info[], int submit_optind, + char * const submit_argv[], char * const submit_envp[], + char * const plugin_options[], const char **errstr); + void (*close)(void); + int (*check)(char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); + int (*show_version)(int verbose); +}; +.RE +.fi +.PP +An approval plugin can be used to apply extra constraints after a +command has been accepted by the policy plugin. +Unlike the other plugin types, it does not remain open until the command +completes. +The plugin is opened before a call to +\fBcheck\fR() +or +\fBshow_version\fR() +and closed shortly thereafter (audit plugin functions must be called +before the plugin is closed). +Multiple approval plugins may be specified in +sudo.conf(@mansectform@). +.PP +The approval_plugin struct has the following fields: +.TP 6n +type +The +\fRtype\fR +field should always be set to +\fRSUDO_APPROVAL_PLUGIN\fR. +.TP 6n +version +The +\fRversion\fR +field should be set to +\fRSUDO_API_VERSION\fR. +.sp +This allows +\fBsudo\fR +to determine the API version the plugin was +built against. +.TP 6n +open +.nf +.RS 6n +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t sudo_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); +.RE +.fi +.RS 6n +.sp +The approval +\fBopen\fR() +function is run immediately before a call to the plugin's +\fBcheck\fR() +or +\fBshow_version\fR() +functions. +It is only called if the version is being requested or if the +policy plugin's +\fBcheck_policy\fR() +function has returned successfully. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +\fBsudo\fR +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +version +The version passed in by +\fBsudo\fR +allows the plugin to determine the +major and minor version number of the plugin API supported by +\fBsudo\fR. +.TP 6n +conversation +A pointer to the +\fBconversation\fR() +function that can be used by the plugin to interact with the user (see +\fIConversation API\fR +for details). +Returns 0 on success and \-1 on failure. +.TP 6n +plugin_printf +A pointer to a +\fBprintf\fR()-style +function that may be used to display informational or error messages (see +\fIConversation API\fR +for details). +Returns the number of characters printed on success and \-1 on failure. +.TP 6n +settings +A vector of user-supplied +\fBsudo\fR +settings in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +These settings correspond to options the user specified when running +\fBsudo\fR. +As such, they will only be present when the corresponding option has +been specified on the command line. +.sp +When parsing +\fIsettings\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible settings. +.TP 6n +user_info +A vector of information about the user running the command in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIuser_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +submit_optind +The index into +\fIsubmit_argv\fR +that corresponds to the first entry that is not a command line option. +If +\fIsubmit_argv\fR +only consists of options, which may be the case with the +\fB\-l\fR +or +\fB\-v\fR +options, +\fRsubmit_argv[submit_optind]\fR +will evaluate to the NULL pointer. +.TP 6n +submit_argv +The argument vector +\fBsudo\fR +was invoked with, including all command line options. +The +\fIsubmit_optind\fR +argument can be used to determine the end of the command line options. +.TP 6n +submit_envp +The invoking user's environment in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIsubmit_envp\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +\fRNULL\fR-terminated +array of strings. +If no arguments were specified, +\fIplugin_options\fR +will be the +\fRNULL\fR +pointer. +.TP 6n +errstr +If the +\fBopen\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +close +.br +.nf +.RS 6n +void (*close)(void); +.RE +.fi +.RS 6n +.sp +The +\fBclose\fR() +function is called after the approval plugin's +\fBcheck\fR() +or +\fBshow_version\fR() +functions have been called. +It takes no arguments. +The +\fBclose\fR() +function is typically used to perform plugin-specific cleanup, +such as the freeing of memory objects allocated by the plugin. +If the plugin does not need to perform any cleanup, +\fBclose\fR() +may be set to the +\fRNULL\fR +pointer. +.RE +.TP 6n +check +.br +.nf +.RS 6n +int (*check)(char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); +.RE +.fi +.RS 6n +.sp +The approval +\fBcheck\fR() +function is run after the policy plugin +\fBcheck_policy\fR() +function and before any I/O logging plugins. +If multiple approval plugins are loaded, they must all succeed for +the command to be allowed. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +\fBsudo\fR +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +command_info +A vector of information describing the command being run in the form of +\(lqname=value\(rq +strings. +The vector is terminated by a +\fRNULL\fR +pointer. +.sp +When parsing +\fIcommand_info\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.sp +See the +\fIPolicy plugin API\fR +section for a list of all possible strings. +.TP 6n +run_argv +A +\fRNULL\fR-terminated +argument vector describing a command that will be run in the +same form as what would be passed to the +execve(2) +system call. +.TP 6n +run_envp +The environment the command will be run with in the form of a +\fRNULL\fR-terminated +vector of +\(lqname=value\(rq +strings. +.sp +When parsing +\fIrun_envp\fR, +the plugin should split on the +\fBfirst\fR +equal sign +(\(oq=\(cq) +since the +\fIname\fR +field will never include one +itself but the +\fIvalue\fR +might. +.TP 6n +errstr +If the +\fBopen\fR() +function returns a value other than 1, the plugin may +store a message describing the failure or error in +\fIerrstr\fR. +The +\fBsudo\fR +front end will then pass this value to any registered audit plugins. +The string stored in +\fIerrstr\fR +must remain valid until the plugin's +\fBclose\fR() +function is called. +.PD 0 +.PP +.RE +.PD +.TP 6n +show_version +.nf +.RS 6n +int (*show_version)(int verbose); +.RE +.fi +.RS 6n +.sp +The +\fBshow_version\fR() +function is called by +\fBsudo\fR +when the user specifies +the +\fB\-V\fR +option. +The plugin may display its version information to the user via the +\fBconversation\fR() +or +\fBplugin_printf\fR() +function using +\fRSUDO_CONV_INFO_MSG\fR. +If the user requests detailed version information, the verbose flag will be set. +.sp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.RE +.SS "Signal handlers" +The +\fBsudo\fR +front end installs default signal handlers to trap common signals +while the plugin functions are run. +The following signals are trapped by default before the command is +executed: +.TP 3n +\fB\(bu\fR +\fRSIGALRM\fR +.PD 0 +.TP 3n +\fB\(bu\fR +\fRSIGHUP\fR +.TP 3n +\fB\(bu\fR +\fRSIGINT\fR +.TP 3n +\fB\(bu\fR +\fRSIGPIPE\fR +.TP 3n +\fB\(bu\fR +\fRSIGQUIT\fR +.TP 3n +\fB\(bu\fR +\fRSIGTERM\fR +.TP 3n +\fB\(bu\fR +\fRSIGTSTP\fR +.TP 3n +\fB\(bu\fR +\fRSIGUSR1\fR +.TP 3n +\fB\(bu\fR +\fRSIGUSR2\fR +.PD +.PP +If a fatal signal is received before the command is executed, +\fBsudo\fR +will call the plugin's +\fBclose\fR() +function with an exit status of 128 plus the value of the signal +that was received. +This allows for consistent logging of commands killed by a signal +for plugins that log such information in their +\fBclose\fR() +function. +An exception to this is +\fRSIGPIPE\fR, +which is ignored until the command is executed. +.PP +A plugin may temporarily install its own signal handlers but must +restore the original handler before the plugin function returns. +.SS "Hook function API" +Beginning with plugin API version 1.2, it is possible to install +hooks for certain functions called by the +\fBsudo\fR +front end. +.PP +Currently, the only supported hooks relate to the handling of +environment variables. +Hooks can be used to intercept attempts to get, set, or remove +environment variables so that these changes can be reflected in +the version of the environment that is used to execute a command. +A future version of the API will support hooking internal +\fBsudo\fR +front end functions as well. +.PP +\fIHook structure\fR +.PP +Hooks in +\fBsudo\fR +are described by the following structure: +.nf +.sp +.RS 0n +typedef int (*sudo_hook_fn_t)(); + +struct sudo_hook { + unsigned int hook_version; + unsigned int hook_type; + sudo_hook_fn_t hook_fn; + void *closure; +}; +.RE +.fi +.PP +The +\fRsudo_hook\fR +structure has the following fields: +.TP 6n +hook_version +The +\fRhook_version\fR +field should be set to +\fRSUDO_HOOK_VERSION\fR. +.TP 6n +hook_type +The +\fRhook_type\fR +field may be one of the following supported hook types: +.PP +.RS 6n +.PD 0 +.TP 6n +\fRSUDO_HOOK_SETENV\fR +The C library +setenv(3) +function. +Any registered hooks will run before the C library implementation. +The +\fRhook_fn\fR +field should +be a function that matches the following typedef: +.nf +.sp +.RS 6n +typedef int (*sudo_hook_fn_setenv_t)(const char *name, + const char *value, int overwrite, void *closure); +.RE +.fi +.RS 6n +.sp +If the registered hook does not match the typedef the results are +unspecified. +.RE +.PD +.TP 6n +\fRSUDO_HOOK_UNSETENV\fR +The C library +unsetenv(3) +function. +Any registered hooks will run before the C library implementation. +The +\fRhook_fn\fR +field should +be a function that matches the following typedef: +.nf +.sp +.RS 6n +typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, + void *closure); +.RE +.fi +.TP 6n +\fRSUDO_HOOK_GETENV\fR +The C library +getenv(3) +function. +Any registered hooks will run before the C library implementation. +The +\fRhook_fn\fR +field should +be a function that matches the following typedef: +.nf +.sp +.RS 6n +typedef int (*sudo_hook_fn_getenv_t)(const char *name, + char **value, void *closure); +.RE +.fi +.RS 6n +.sp +If the registered hook does not match the typedef the results are +unspecified. +.RE +.TP 6n +\fRSUDO_HOOK_PUTENV\fR +The C library +putenv(3) +function. +Any registered hooks will run before the C library implementation. +The +\fRhook_fn\fR +field should +be a function that matches the following typedef: +.nf +.sp +.RS 6n +typedef int (*sudo_hook_fn_putenv_t)(char *string, + void *closure); +.RE +.fi +.RS 6n +.sp +If the registered hook does not match the typedef the results are +unspecified. +.RE +.PD 0 +.PP +.RE +.PD +.TP 6n +hook_fn +sudo_hook_fn_t hook_fn; +.sp +The +\fRhook_fn\fR +field should be set to the plugin's hook implementation. +The actual function arguments will vary depending on the +\fRhook_type\fR +(see +\fRhook_type\fR +above). +In all cases, the +\fRclosure\fR +field of +\fRstruct sudo_hook\fR +is passed as the last function parameter. +This can be used to pass arbitrary data to the plugin's hook implementation. +.sp +The function return value may be one of the following: +.PP +.RS 6n +.PD 0 +.TP 6n +\fRSUDO_HOOK_RET_ERROR\fR +The hook function encountered an error. +.PD +.TP 6n +\fRSUDO_HOOK_RET_NEXT\fR +The hook completed without error, go on to the next hook (including +the system implementation if applicable). +For example, a +getenv(3) +hook might return +\fRSUDO_HOOK_RET_NEXT\fR +if the specified variable was not found in the private copy of the environment. +.TP 6n +\fRSUDO_HOOK_RET_STOP\fR +The hook completed without error, stop processing hooks for this invocation. +This can be used to replace the system implementation. +For example, a +\fRsetenv\fR +hook that operates on a private copy of +the environment but leaves +\fRenviron\fR +unchanged. +.PD 0 +.PP +.RE +.PD +.PP +Note that it is very easy to create an infinite loop when hooking +C library functions. +For example, a +getenv(3) +hook that calls the +snprintf(3) +function may create a loop if the +snprintf(3) +implementation calls +getenv(3) +to check the locale. +To prevent this, you may wish to use a static variable in the hook +function to guard against nested calls. +For example: +.nf +.sp +.RS 0n +static int in_progress = 0; /* avoid recursion */ +if (in_progress) + return SUDO_HOOK_RET_NEXT; +in_progress = 1; +\&... +in_progress = 0; +return SUDO_HOOK_RET_STOP; +.RE +.fi +.PP +\fIHook API Version Macros\fR +.nf +.sp +.RS 0n +/* Hook API version major/minor */ +#define SUDO_HOOK_VERSION_MAJOR 1 +#define SUDO_HOOK_VERSION_MINOR 0 +#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e + SUDO_HOOK_VERSION_MINOR) +.RE +.fi +.PP +For getters and setters see the +\fIPolicy plugin API\fR. +.SS "Event API" +When +\fBsudo\fR +runs a command, it uses an event loop to service signals and I/O. +Events may be triggered based on time, a file or socket descriptor +becoming ready, or due to receipt of a signal. +Starting with API version 1.15, it is possible for a plugin to +participate in this event loop by calling the +\fBevent_alloc\fR() +function. +.PP +\fIEvent structure\fR +.PP +Events are described by the following structure: +.nf +.RS 0n +typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, void *closure); + +struct sudo_plugin_event { + int (*set)(struct sudo_plugin_event *pev, int fd, int events, + sudo_plugin_ev_callback_t callback, void *closure); + int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout); + int (*del)(struct sudo_plugin_event *pev); + int (*pending)(struct sudo_plugin_event *pev, int events, + struct timespec *ts); + int (*fd)(struct sudo_plugin_event *pev); + void (*setbase)(struct sudo_plugin_event *pev, void *base); + void (*loopbreak)(struct sudo_plugin_event *pev); + void (*free)(struct sudo_plugin_event *pev); +}; +.RE +.fi +.PP +The sudo_plugin_event struct contains the following function pointers: +.TP 6n +\fBset\fR() +.br +.nf +.RS 6n +int (*set)(struct sudo_plugin_event *pev, int fd, int events, + sudo_plugin_ev_callback_t callback, void *closure); +.RE +.fi +.RS 6n +.sp +The +\fBset\fR() +function takes the following arguments: +.TP 6n +struct sudo_plugin_event *\fIpev\fR +A pointer to the struct sudo_plugin_event itself. +.TP 6n +\fIfd\fR +The file or socket descriptor for I/O-based events or the signal +number for signal events. +For time-based events, +\fIfd\fR +must be -1. +.TP 6n +\fIevents\fR +The following values determine what will trigger the event callback: +.PP +.RS 6n +.PD 0 +.TP 6n +SUDO_PLUGIN_EV_TIMEOUT +callback is run after the specified timeout expires +.PD +.TP 6n +SUDO_PLUGIN_EV_READ +callback is run when the file descriptor is readable +.TP 6n +SUDO_PLUGIN_EV_WRITE +callback is run when the file descriptor is writable +.TP 6n +SUDO_PLUGIN_EV_PERSIST +event is persistent and remains enabled until explicitly deleted +.TP 6n +SUDO_PLUGIN_EV_SIGNAL +callback is run when the specified signal is received +.PP +The +\fRSUDO_PLUGIN_EV_PERSIST\fR +flag may be ORed with any of the event types. +It is also possible to OR +\fRSUDO_PLUGIN_EV_READ\fR +and +\fRSUDO_PLUGIN_EV_WRITE\fR +together to run the callback when a descriptor is ready to be +either read from or written to. +All other event values are mutually exclusive. +.RE +.TP 6n +sudo_plugin_ev_callback_t \fIcallback\fR +.nf +.RS 6n +typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, + void *closure); +.RE +.fi +.RS 6n +.sp +The function to call when an event is triggered. +The +\fBcallback\fR() +function is run with the following arguments: +.TP 6n +\fIfd\fR +The file or socket descriptor for I/O-based events or the signal +number for signal events. +.TP 6n +\fIwhat\fR +The event type that triggered that callback. +For events that have multiple event types (for example +\fRSUDO_PLUGIN_EV_READ\fR +and +\fRSUDO_PLUGIN_EV_WRITE\fR) +or have an associated timeout, +\fIwhat\fR +can be used to determine why the callback was run. +.TP 6n +\fIclosure\fR +The generic pointer that was specified in the +\fBset\fR() +function. +.PD 0 +.PP +.RE +.PD +.TP 6n +closure +A generic pointer that will be passed to the callback function. +.PP +The +\fBset\fR() +function returns 1 on success, and \-1 if a error occurred. +.RE +.TP 6n +\fBadd\fR() +.br +.nf +.RS 6n +int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout); +.RE +.fi +.RS 6n +.sp +The +\fBadd\fR() +function adds the event +\fIpev\fR +to +\fBsudo\fR's +event loop. +The event must have previously been initialized via the +\fBset\fR() +function. +If the +\fItimeout\fR +argument is not NULL, it should specify a (relative) timeout after +which the event will be triggered if the main event criteria has +not been met. +This is often used to implement an I/O timeout where the event +will fire if a descriptor is not ready within a certain time +period. +If the event is already present in the event loop, its +\fItimeout\fR +will be adjusted to match the new value, if any. +.sp +The +\fBadd\fR() +function returns 1 on success, and \-1 if a error occurred. +.RE +.TP 6n +\fBdel\fR() +.br +.nf +.RS 6n +int (*del)(struct sudo_plugin_event *pev); +.RE +.fi +.RS 6n +.sp +The +\fBdel\fR() +function deletes the event +\fIpev\fR +from +\fBsudo\fR's +event loop. +Deleted events can be added back via the +\fBadd\fR() +function. +.sp +The +\fBdel\fR() +function returns 1 on success, and \-1 if a error occurred. +.RE +.TP 6n +\fBpending\fR() +.nf +.RS 6n +int (*pending)(struct sudo_plugin_event *pev, int events, + struct timespec *ts); +.RE +.fi +.RS 6n +.sp +The +\fBpending\fR() +function can be used to determine whether one or more events is pending. +The +\fIevents\fR +argument specifies which events to check for. +See the +\fBset\fR() +function for a list of valid event types. +If +\fRSUDO_PLUGIN_EV_TIMEOUT\fR +is specified in +\fRevents\fR, +the event has an associated timeout and the +\fIts\fR +pointer is non-NULL, it will be filled in with the remaining time. +.RE +.TP 6n +\fBfd\fR() +.nf +.RS 6n +int (*fd)(struct sudo_plugin_event *pev); +.RE +.fi +.RS 6n +.sp +The +\fBfd\fR() +function returns the descriptor or signal number associated with +the event +\fIpev\fR. +.RE +.TP 6n +\fBsetbase\fR() +.nf +.RS 6n +void (*setbase)(struct sudo_plugin_event *pev, void *base); +.RE +.fi +.RS 6n +.sp +The +\fBsetbase\fR() +function sets the underlying event +\fIbase\fR +for +\fIpev\fR +to the specified value. +This can be used to move an event created via +\fBevent_alloc\fR() +to a new event loop allocated by sudo's event subsystem. +If +\fIbase\fR +is +\fRNULL\fR, +\fIpev\fR's +event base is reset to the default value, which corresponds to +\fBsudo\fR's +main event loop. +Using this function requires linking the plugin with the sudo_util +library. +It is unlikely to be used outside of the +\fBsudoers\fR +plugin. +.RE +.TP 6n +\fBloopbreak\fR() +.nf +.RS 6n +void (*loopbreak)(struct sudo_plugin_event *pev); +.RE +.fi +.RS 6n +.sp +The +\fBloopbreak\fR() +function causes +\fBsudo\fR's +event loop to exit immediately and the running command to be terminated. +.RE +.TP 6n +\fBfree\fR() +.nf +.RS 6n +void (*free)(struct sudo_plugin_event *pev); +.RE +.fi +.RS 6n +.sp +The +\fBfree\fR() +function deletes the event +\fIpev\fR +from the event loop and frees the memory associated with it. +.RE +.SS "Remote command execution" +The +\fBsudo\fR +front end does not support running remote commands. +However, starting with +\fBsudo\fR +1.8.8, the +\fB\-h\fR +option may be used to specify a remote host that is passed +to the policy plugin. +A plugin may also accept a +\fIrunas_user\fR +in the form of +\(lquser@hostname\(rq +which will work with older versions of +\fBsudo\fR. +It is anticipated that remote commands will be supported by executing a +\(lqhelper\(rq +program. +The policy plugin should setup the execution environment such that the +\fBsudo\fR +front end will run the helper which, in turn, will connect to the +remote host and run the command. +.PP +For example, the policy plugin could utilize +\fBssh\fR +to perform remote command execution. +The helper program would be responsible for running +\fBssh\fR +with the proper options to use a private key or certificate +that the remote host will accept and run a program +on the remote host that would setup the execution environment +accordingly. +.PP +Note that remote +\fBsudoedit\fR +functionality must be handled by the policy plugin, not +\fBsudo\fR +itself as the front end has no knowledge that a remote command is +being executed. +This may be addressed in a future revision of the plugin API. +.SS "Conversation API" +If the plugin needs to interact with the user, it may do so via the +\fBconversation\fR() +function. +A plugin should not attempt to read directly from the standard input +or the user's tty (neither of which are guaranteed to exist). +The caller must include a trailing newline in +\fRmsg\fR +if one is to be printed. +.PP +A +\fBprintf\fR()-style +function is also available that can be used to display informational +or error messages to the user, which is usually more convenient for +simple messages where no use input is required. +.PP +\fIConversation function structures\fR +.PP +The conversation function takes as arguments pointers to the following +structures: +.nf +.sp +.RS 0n +struct sudo_conv_message { +#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */ +#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */ +#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ +#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ +#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ +#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ +#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */ + int msg_type; + int timeout; + const char *msg; +}; + +#define SUDO_CONV_REPL_MAX 1023 + +struct sudo_conv_reply { + char *reply; +}; + +typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure); +struct sudo_conv_callback { + unsigned int version; + void *closure; + sudo_conv_callback_fn_t on_suspend; + sudo_conv_callback_fn_t on_resume; +}; +.RE +.fi +.PP +Pointers to the +\fBconversation\fR() +and +\fBprintf\fR()-style +functions are passed +in to the plugin's +\fBopen\fR() +function when the plugin is initialized. +The following type definitions can be used in the declaration of the +\fBopen\fR() +function: +.nf +.sp +.RS 0n +typedef int (*sudo_conv_t)(int num_msgs, + const struct sudo_conv_message msgs[], + struct sudo_conv_reply replies[], struct sudo_conv_callback *callback); + +typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); +.RE +.fi +.PP +To use the +\fBconversation\fR() +function, the plugin must pass an array of +\fRsudo_conv_message\fR +and +\fRsudo_conv_reply\fR +structures. +There must be a +\fRstruct sudo_conv_message\fR +and +\fRstruct sudo_conv_reply\fR +for +each message in the conversation, that is, both arrays must have the same +number of elements. +Each +\fRstruct sudo_conv_reply\fR +must have its +\fIreply\fR +member initialized to +\fRNULL\fR. +The +\fRstruct sudo_conv_callback\fR +pointer, if not +\fRNULL\fR, +should contain function pointers to be called when the +\fBsudo\fR +process is suspended and/or resumed during conversation input. +The +\fIon_suspend\fR +and +\fIon_resume\fR +functions are called with the signal that caused +\fBsudo\fR +to be suspended and the +\fIclosure\fR +pointer from the +\fRstruct sudo_conv_callback\fR. +These functions should return 0 on success and \-1 on error. +On error, the conversation will end and the conversation function +will return a value of \-1. +The intended use is to allow the plugin to release resources, such as locks, +that should not be held indefinitely while suspended and then reacquire them +when the process is resumed. +Note that the functions are not actually invoked from within a signal handler. +.PP +The +\fImsg_type\fR +must be set to one of the following values: +.TP 6n +SUDO_CONV_PROMPT_ECHO_OFF +Prompt the user for input with echo disabled; +this is generally used for passwords. +The reply will be stored in the +\fIreplies\fR +array, and it will never be +\fRNULL\fR. +.TP 6n +SUDO_CONV_PROMPT_ECHO_ON +Prompt the user for input with echo enabled. +The reply will be stored in the +\fIreplies\fR +array, and it will never be +\fRNULL\fR. +.TP 6n +SUDO_CONV_ERROR_MSG +Display an error message. +The message is written to the standard error unless the +\fRSUDO_CONV_PREFER_TTY\fR +flag is set, in which case it is written to the user's terminal if possible. +.TP 6n +SUDO_CONV_INFO_MSG +Display a message. +The message is written to the standard output unless the +\fRSUDO_CONV_PREFER_TTY\fR +flag is set, in which case it is written to the user's terminal if possible. +.TP 6n +SUDO_CONV_PROMPT_MASK +Prompt the user for input but echo an asterisk character for each +character read. +The reply will be stored in the +\fIreplies\fR +array, and it will never be +\fRNULL\fR. +This can be used to provide visual feedback to the user while reading +sensitive information that should not be displayed. +.PP +In addition to the above values, the following flag bits may also be set: +.TP 6n +SUDO_CONV_PROMPT_ECHO_OK +Allow input to be read when echo cannot be disabled +when the message type is +\fRSUDO_CONV_PROMPT_ECHO_OFF\fR +or +\fRSUDO_CONV_PROMPT_MASK\fR. +By default, +\fBsudo\fR +will refuse to read input if the echo cannot be disabled for those +message types. +.TP 6n +SUDO_CONV_PREFER_TTY +When displaying a message via +\fRSUDO_CONV_ERROR_MSG\fR +or +\fRSUDO_CONV_INFO_MSG\fR, +try to write the message to the user's terminal. +If the terminal is unavailable, the standard error or standard output +will be used, depending upon whether +The user's terminal is always used when possible for input, +this flag is only used for output. +\fRSUDO_CONV_ERROR_MSG\fR +or +\fRSUDO_CONV_INFO_MSG\fR +was used. +.PP +The +\fItimeout\fR +in seconds until the prompt will wait for no more input. +A zero value implies an infinite timeout. +.PP +The plugin is responsible for freeing the reply buffer located in each +\fRstruct sudo_conv_reply\fR, +if it is not +\fRNULL\fR. +\fRSUDO_CONV_REPL_MAX\fR +represents the maximum length of the reply buffer (not including +the trailing NUL character). +In practical terms, this is the longest password +\fBsudo\fR +will support. +.PP +The +\fBprintf\fR()-style +function uses the same underlying mechanism as the +\fBconversation\fR() +function but only supports +\fRSUDO_CONV_INFO_MSG\fR +and +\fRSUDO_CONV_ERROR_MSG\fR +for the +\fImsg_type\fR +parameter. +It can be more convenient than using the +\fBconversation\fR() +function if no user reply is needed and supports standard +\fBprintf\fR() +escape sequences. +.PP +See the sample plugin for an example of the +\fBconversation\fR() +function usage. +.SS "Plugin invocation order" +As of +\fBsudo\fR +1.9.0, the plugin +\fBopen\fR() +and +\fBclose\fR() +functions are called in the +following order: +.TP 5n +1.\& +audit open +.TP 5n +2.\& +policy open +.TP 5n +3.\& +approval open +.TP 5n +4.\& +approval close +.TP 5n +5.\& +I/O log open +.TP 5n +6.\& +command runs +.TP 5n +7.\& +command exits +.TP 5n +8.\& +I/O log close +.TP 5n +9.\& +policy close +.TP 5n +10.\& +audit close +.TP 5n +11.\& +sudo exits +.PP +Prior to +\fBsudo\fR +1.9.0, the I/O log +\fBclose\fR() +function was called +\fIafter\fR +the policy +\fBclose\fR() +function. +.SS "Sudoers group plugin API" +The +\fBsudoers\fR +plugin supports its own plugin interface to allow non-Unix +group lookups. +This can be used to query a group source other than the standard Unix +group database. +Two sample group plugins are bundled with +\fBsudo\fR, +\fIgroup_file\fR +and +\fIsystem_group\fR, +are detailed in +sudoers(@mansectform@). +Third party group plugins include a QAS AD plugin available from Quest Software. +.PP +A group plugin must declare and populate a +\fRsudoers_group_plugin\fR +struct in the global scope. +This structure contains pointers to the functions that implement plugin +initialization, cleanup and group lookup. +.nf +.sp +.RS 0n +struct sudoers_group_plugin { + unsigned int version; + int (*init)(int version, sudo_printf_t sudo_printf, + char *const argv[]); + void (*cleanup)(void); + int (*query)(const char *user, const char *group, + const struct passwd *pwd); +}; +.RE +.fi +.PP +The +\fRsudoers_group_plugin\fR +struct has the following fields: +.TP 6n +version +The +\fRversion\fR +field should be set to GROUP_API_VERSION. +.sp +This allows +\fBsudoers\fR +to determine the API version the group plugin +was built against. +.TP 6n +init +.nf +.RS 6n +int (*init)(int version, sudo_printf_t plugin_printf, + char *const argv[]); +.RE +.fi +.RS 6n +.sp +The +\fBinit\fR() +function is called after +\fIsudoers\fR +has been parsed but +before any policy checks. +It returns 1 on success, 0 on failure (or if the plugin is not configured), +and \-1 if a error occurred. +If an error occurs, the plugin may call the +\fBplugin_printf\fR() +function with +\fRSUDO_CONF_ERROR_MSG\fR +to present additional error information to the user. +.sp +The function arguments are as follows: +.TP 6n +version +The version passed in by +\fBsudoers\fR +allows the plugin to determine the +major and minor version number of the group plugin API supported by +\fBsudoers\fR. +.TP 6n +plugin_printf +A pointer to a +\fBprintf\fR()-style +function that may be used to display informational or error message to the user. +Returns the number of characters printed on success and \-1 on failure. +.TP 6n +argv +A +\fRNULL\fR-terminated +array of arguments generated from the +\fIgroup_plugin\fR +option in +\fIsudoers\fR. +If no arguments were given, +\fIargv\fR +will be +\fRNULL\fR. +.PD 0 +.PP +.RE +.PD +.TP 6n +cleanup +.nf +.RS 6n +void (*cleanup)(); +.RE +.fi +.RS 6n +.sp +The +\fBcleanup\fR() +function is called when +\fBsudoers\fR +has finished its +group checks. +The plugin should free any memory it has allocated and close open file handles. +.RE +.TP 6n +query +.br +.nf +.RS 6n +int (*query)(const char *user, const char *group, + const struct passwd *pwd); +.RE +.fi +.RS 6n +.sp +The +\fBquery\fR() +function is used to ask the group plugin whether +\fIuser\fR +is a member of +\fIgroup\fR. +.sp +The function arguments are as follows: +.TP 6n +user +The name of the user being looked up in the external group database. +.TP 6n +group +.br +The name of the group being queried. +.TP 6n +pwd +The password database entry for +\fIuser\fR, +if any. +If +\fIuser\fR +is not +present in the password database, +\fIpwd\fR +will be +\fRNULL\fR. +.PD 0 +.PP +.RE +.PD +.PP +\fIGroup API Version Macros\fR +.nf +.sp +.RS 0n +/* Sudoers group plugin version major/minor */ +#define GROUP_API_VERSION_MAJOR 1 +#define GROUP_API_VERSION_MINOR 0 +#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e + GROUP_API_VERSION_MINOR) +.RE +.fi +For getters and setters see the +\fIPolicy plugin API\fR. +.SH "PLUGIN API CHANGELOG" +The following revisions have been made to the Sudo Plugin API. +.TP 6n +Version 1.0 +Initial API version. +.TP 6n +Version 1.1 (sudo 1.8.0) +The I/O logging plugin's +\fBopen\fR() +function was modified to take the +\fRcommand_info\fR +list as an argument. +.TP 6n +Version 1.2 (sudo 1.8.5) +The Policy and I/O logging plugins' +\fBopen\fR() +functions are now passed +a list of plugin parameters if any are specified in +sudo.conf(@mansectform@). +.sp +A simple hooks API has been introduced to allow plugins to hook in to the +system's environment handling functions. +.sp +The +\fRinit_session\fR +Policy plugin function is now passed a pointer +to the user environment which can be updated as needed. +This can be used to merge in environment variables stored in the PAM +handle before a command is run. +.TP 6n +Version 1.3 (sudo 1.8.7) +Support for the +\fIexec_background\fR +entry has been added to the +\fRcommand_info\fR +list. +.sp +The +\fImax_groups\fR +and +\fIplugin_dir\fR +entries were added to the +\fRsettings\fR +list. +.sp +The +\fBversion\fR() +and +\fBclose\fR() +functions are now optional. +Previously, a missing +\fBversion\fR() +or +\fBclose\fR() +function would result in a crash. +If no policy plugin +\fBclose\fR() +function is defined, a default +\fBclose\fR() +function will be provided by the +\fBsudo\fR +front end that displays a warning if the command could not be +executed. +.sp +The +\fBsudo\fR +front end now installs default signal handlers to trap common signals +while the plugin functions are run. +.TP 6n +Version 1.4 (sudo 1.8.8) +The +\fIremote_host\fR +entry was added to the +\fRsettings\fR +list. +.TP 6n +Version 1.5 (sudo 1.8.9) +The +\fIpreserve_fds\fR +entry was added to the +\fRcommand_info\fR +list. +.TP 6n +Version 1.6 (sudo 1.8.11) +The behavior when an I/O logging plugin returns an error +(\-1) +has changed. +Previously, the +\fBsudo\fR +front end took no action when the +\fBlog_ttyin\fR(), +\fBlog_ttyout\fR(), +\fBlog_stdin\fR(), +\fBlog_stdout\fR(), +or +\fBlog_stderr\fR() +function returned an error. +.sp +The behavior when an I/O logging plugin returns 0 has changed. +Previously, output from the command would be displayed to the +terminal even if an output logging function returned 0. +.TP 6n +Version 1.7 (sudo 1.8.12) +The +\fIplugin_path\fR +entry was added to the +\fRsettings\fR +list. +.sp +The +\fIdebug_flags\fR +entry now starts with a debug file path name and may occur multiple +times if there are multiple plugin-specific Debug lines in the +sudo.conf(@mansectform@) file. +.TP 6n +Version 1.8 (sudo 1.8.15) +The +\fIsudoedit_checkdir\fR +and +\fIsudoedit_follow\fR +entries were added to the +\fRcommand_info\fR +list. +The default value of +\fIsudoedit_checkdir\fR +was changed to true in sudo 1.8.16. +.sp +The sudo +\fIconversation\fR +function now takes a pointer to a +\fRstruct sudo_conv_callback\fR +as its fourth argument. +The +\fRsudo_conv_t\fR +definition has been updated to match. +The plugin must specify that it supports plugin API version 1.8 or higher +to receive a conversation function pointer that supports this argument. +.TP 6n +Version 1.9 (sudo 1.8.16) +The +\fIexecfd\fR +entry was added to the +\fRcommand_info\fR +list. +.TP 6n +Version 1.10 (sudo 1.8.19) +The +\fIumask\fR +entry was added to the +\fRuser_info\fR +list. +The +\fIiolog_group\fR, +\fIiolog_mode\fR, +and +\fIiolog_user\fR +entries were added to the +\fRcommand_info\fR +list. +.TP 6n +Version 1.11 (sudo 1.8.20) +The +\fItimeout\fR +entry was added to the +\fRsettings\fR +list. +.TP 6n +Version 1.12 (sudo 1.8.21) +The +\fRchange_winsize\fR +field was added to the io_plugin struct. +.TP 6n +Version 1.13 (sudo 1.8.26) +The +\fRlog_suspend\fR +field was added to the io_plugin struct. +.TP 6n +Version 1.14 (sudo 1.8.29) +The +\fIumask_override\fR +entry was added to the +\fRcommand_info\fR +list. +.TP 6n +Version 1.15 (sudo 1.9.0) +The +\fIcwd_optional\fR +entry was added to the +\fRcommand_info\fR +list. +.sp +The +\fIevent_alloc\fR +field was added to the policy_plugin and io_plugin structs. +.sp +The +\fIerrstr\fR +argument was added to the policy and I/O plugin functions +which the plugin function can use to return an error string. +This string may be used by the audit plugin to report failure or +error conditions set by the other plugins. +.sp +The +\fBclose\fR() +function is now is called regardless of whether or not a command +was actually executed. +This makes it possible for plugins to perform cleanup even when a +command was not run. +.sp +\fRSUDO_CONV_REPL_MAX\fR +has increased from 255 to 1023 bytes. +.sp +Support for audit and approval plugins was added. +.TP 6n +Version 1.16 (sudo 1.9.3) +Initial resource limit values were added to the +\fRuser_info\fR +list. +.sp +The +\fIcmnd_chroot\fR +and +\fIcmnd_cwd\fR +enties were added to the +\fRsettings\fR +list. +.TP 6n +Version 1.17 (sudo 1.9.4) +The +\fIevent_alloc\fR +field was added to the audit_plugin and approval_plugin structs. +.SH "SEE ALSO" +sudo.conf(@mansectform@), +sudoers(@mansectform@), +sudo(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_plugin.mdoc.in b/doc/sudo_plugin.mdoc.in new file mode 100644 index 0000000..feb265c --- /dev/null +++ b/doc/sudo_plugin.mdoc.in @@ -0,0 +1,4553 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2009-2020 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. +.\" +.Dd November 17, 2020 +.Dt SUDO_PLUGIN @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_plugin +.Nd Sudo Plugin API +.Sh DESCRIPTION +Starting with version 1.8, +.Nm sudo +supports a plugin API +for policy and session logging. +Plugins may be compiled as dynamic shared objects (the default on +systems that support them) or compiled statically into the +.Nm sudo +binary itself. +By default, the +.Nm sudoers +policy plugin and an associated I/O logging plugin are used. +Via the plugin API, +.Nm sudo +can be configured to use alternate policy and/or I/O logging plugins +provided by third parties. +The plugins to be used are specified in the +.Xr sudo.conf @mansectform@ +file. +.Pp +The API is versioned with a major and minor number. +The minor version number is incremented when additions are made. +The major number is incremented when incompatible changes are made. +A plugin should be check the version passed to it and make sure that the +major version matches. +.Pp +The plugin API is defined by the +.Li sudo_plugin.h +header file. +.Ss Policy plugin API +A policy plugin must declare and populate a +.Li policy_plugin +struct in the global scope. +This structure contains pointers to the functions that implement the +.Nm sudo +policy checks. +The name of the symbol should be specified in +.Xr sudo.conf @mansectform@ +along with a path to the plugin so that +.Nm sudo +can load it. +.Bd -literal +struct policy_plugin { +#define SUDO_POLICY_PLUGIN 1 + 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 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); + int (*show_version)(int verbose); + int (*check_policy)(int argc, char * const argv[], + 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); + int (*validate)(const char **errstr); + void (*invalidate)(int remove); + int (*init_session)(struct passwd *pwd, char **user_env[], + const char **errstr); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + struct sudo_plugin_event * (*event_alloc)(void); +}; +.Ed +.Pp +The policy_plugin struct has the following fields: +.Bl -tag -width 4n +.It type +The +.Li type +field should always be set to SUDO_POLICY_PLUGIN. +.It version +The +.Li version +field should be set to +.Dv SUDO_API_VERSION . +.Pp +This allows +.Nm sudo +to determine the API version the plugin was +built against. +.It open +.Bd -literal -compact +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t plugin_printf, char * const settings[], + char * const user_info[], char * const user_env[], + char * const plugin_options[], const char **errstr); +.Ed +.Pp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +.Nm sudo +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It version +The version passed in by +.Nm sudo +allows the plugin to determine the +major and minor version number of the plugin API supported by +.Nm sudo . +.It conversation +A pointer to the +.Fn conversation +function that can be used by the plugin to interact with the user (see +.Sx Conversation API +for details). +Returns 0 on success and \-1 on failure. +.It plugin_printf +A pointer to a +.Fn printf Ns -style +function that may be used to display informational or error messages (see +.Sx Conversation API +for details). +Returns the number of characters printed on success and \-1 on failure. +.It settings +A vector of user-supplied +.Nm sudo +settings in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +These settings correspond to options the user specified when running +.Nm sudo . +As such, they will only be present when the corresponding option has +been specified on the command line. +.Pp +When parsing +.Em settings , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +The following values may be set by +.Nm sudo : +.Bl -tag -width 4n +.It bsdauth_type=string +Authentication type, if specified by the +.Fl a +option, to use on +systems where +.Bx +authentication is supported. +.It closefrom=number +If specified, the user has requested via the +.Fl C +option that +.Nm sudo +close all files descriptors with a value of +.Em number +or higher. +The plugin may optionally pass this, or another value, back in the +.Em command_info +list. +.It cmnd_chroot=string +The root directory (see +.Xr chroot 2 ) +to run the command in, as specified by the user via the +.Fl R +option. +The plugin may ignore or restrict the user's ability to specify a new +root directory. +Only available starting with API version 1.16. +.It cmnd_cwd=string +The working directory to run the command in, as specified by the user via the +.Fl D +option. +The plugin may ignore or restrict the user's ability to specify a new +working directory. +Only available starting with API version 1.16. +.It debug_flags=string +A debug file path name followed by a space and a comma-separated +list of debug flags that correspond to the plugin's +.Li Debug +entry in +.Xr sudo.conf @mansectform@ , +if there is one. +The flags are passed to the plugin exactly as they appear in +.Xr sudo.conf @mansectform@ . +The syntax used by +.Nm sudo +and the +.Nm sudoers +plugin is +.Em subsystem Ns @ Ns Em priority +but a plugin is free to use a different +format so long as it does not include a comma +.Pq Ql ,\& . +Prior to +.Nm sudo +1.8.12, there was no way to specify plugin-specific +.Em debug_flags +so the value was always the same as that used by the +.Nm sudo +front end and did not include a path name, only the flags themselves. +As of version 1.7 of the plugin interface, +.Nm sudo +will only pass +.Em debug_flags +if +.Xr sudo.conf @mansectform@ +contains a plugin-specific +.Li Debug +entry. +.It ignore_ticket=bool +Set to true if the user specified the +.Fl k +option along with a +command, indicating that the user wishes to ignore any cached +authentication credentials. +.Em implied_shell +to true. +This allows +.Nm sudo +with no arguments +to be used similarly to +.Xr su 1 . +If the plugin does not to support this usage, it may return a value of \-2 +from the +.Fn check_policy +function, which will cause +.Nm sudo +to print a usage message and +exit. +.It implied_shell=bool +If the user does not specify a program on the command line, +.Nm sudo +will pass the plugin the path to the user's shell and set +.It login_class=string +.Bx +login class to use when setting resource limits and nice value, +if specified by the +.Fl c +option. +.It login_shell=bool +Set to true if the user specified the +.Fl i +option, indicating that +the user wishes to run a login shell. +.It max_groups=int +The maximum number of groups a user may belong to. +This will only be present if there is a corresponding setting in +.Xr sudo.conf @mansectform@ . +.It network_addrs=list +A space-separated list of IP network addresses and netmasks in the +form +.Dq addr/netmask , +e.g., +.Dq 192.168.1.2/255.255.255.0 . +The address and netmask pairs may be either IPv4 or IPv6, depending on +what the operating system supports. +If the address contains a colon +.Pq Ql :\& , +it is an IPv6 address, else it is IPv4. +.It noninteractive=bool +Set to true if the user specified the +.Fl n +option, indicating that +.Nm sudo +should operate in non-interactive mode. +The plugin may reject a command run in non-interactive mode if user +interaction is required. +.It plugin_dir=string +The default plugin directory used by the +.Nm sudo +front end. +This is the default directory set at compile time and may not +correspond to the directory the running plugin was loaded from. +It may be used by a plugin to locate support files. +.It plugin_path=string +The path name of plugin loaded by the +.Nm sudo +front end. +The path name will be a fully-qualified unless the plugin was +statically compiled into +.Nm sudo . +.It preserve_environment=bool +Set to true if the user specified the +.Fl E +option, indicating that +the user wishes to preserve the environment. +.It preserve_groups=bool +Set to true if the user specified the +.Fl P +option, indicating that +the user wishes to preserve the group vector instead of setting it +based on the runas user. +.It progname=string +The command name that sudo was run as, typically +.Dq sudo +or +.Dq sudoedit . +.It prompt=string +The prompt to use when requesting a password, if specified via +the +.Fl p +option. +.It remote_host=string +The name of the remote host to run the command on, if specified via +the +.Fl h +option. +Support for running the command on a remote host is meant to be implemented +via a helper program that is executed in place of the user-specified command. +The +.Nm sudo +front end is only capable of executing commands on the local host. +Only available starting with API version 1.4. +.It run_shell=bool +Set to true if the user specified the +.Fl s +option, indicating that the user wishes to run a shell. +.It runas_group=string +The group name or gid to run the command as, if specified via +the +.Fl g +option. +.It runas_user=string +The user name or uid to run the command as, if specified via the +.Fl u +option. +.It selinux_role=string +SELinux role to use when executing the command, if specified by +the +.Fl r +option. +.It selinux_type=string +SELinux type to use when executing the command, if specified by +the +.Fl t +option. +.It set_home=bool +Set to true if the user specified the +.Fl H +option. +If true, set the +.Li HOME +environment variable to the target user's home directory. +.It sudoedit=bool +Set to true when the +.Fl e +option is specified or if invoked as +.Nm sudoedit . +The plugin shall substitute an editor into +.Em argv +in the +.Fn check_policy +function or return \-2 with a usage error +if the plugin does not support +.Em sudoedit . +For more information, see the +.Em check_policy +section. +.It timeout=string +Command timeout specified by the user via the +.Fl T +option. +Not all plugins support command timeouts and the ability of the +user to set a timeout may be restricted by policy. +The format of the timeout string is plugin-specific. +.El +.Pp +Additional settings may be added in the future so the plugin should +silently ignore settings that it does not recognize. +.It user_info +A vector of information about the user running the command in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em user_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +The following values may be set by +.Nm sudo : +.Bl -tag -width 4n +.It cols=int +The number of columns the user's terminal supports. +If there is no terminal device available, a default value of 80 is used. +.It cwd=string +The user's current working directory. +.It egid=gid_t +The effective group-ID of the user invoking +.Nm sudo . +.It euid=uid_t +The effective user-ID of the user invoking +.Nm sudo . +.It gid=gid_t +The real group-ID of the user invoking +.Nm sudo . +.It groups=list +The user's supplementary group list formatted as a string of +comma-separated group-IDs. +.It host=string +The local machine's hostname as returned by the +.Xr gethostname 2 +system call. +.It lines=int +The number of lines the user's terminal supports. +If there is +no terminal device available, a default value of 24 is used. +.It pgid=int +The ID of the process group that the running +.Nm sudo +process is a member of. +Only available starting with API version 1.2. +.It pid=int +The process ID of the running +.Nm sudo +process. +Only available starting with API version 1.2. +.It ppid=int +The parent process ID of the running +.Nm sudo +process. +Only available starting with API version 1.2. +.It rlimit_as=soft,hard +The maximum size to which the process's address space may grow (in bytes), +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_core=soft,hard +The largest size core dump file that may be created (in bytes). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_cpu=soft,hard +The maximum amount of CPU time that the process may use (in seconds). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_data=soft,hard +The maximum size of the data segment for the process (in bytes). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_fsize=soft,hard +The largest size file that the process may create (in bytes). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_locks=soft,hard +The maximum number of locks that the process may establish, +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_memlock=soft,hard +The maximum size that the process may lock in memory (in bytes), +if supported by the operating system. +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_nofile=soft,hard +The maximum number of files that the process may have open. +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_nproc=soft,hard +The maximum number of processes that the user may run simultaneously. +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_rss=soft,hard +The maximum size to which the process's resident set size may grow (in bytes). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It rlimit_stack=soft,hard +The maximum size to which the process's stack may grow (in bytes). +The soft and hard limits are separated by a comma. +A value of +.Dq infinity +indicates that there is no limit. +Only available starting with API version 1.16. +.It sid=int +The session ID of the running +.Nm sudo +process or 0 if +.Nm sudo +is not part of a POSIX job control session. +Only available starting with API version 1.2. +.It tcpgid=int +The ID of the foreground process group associated with the terminal +device associated with the +.Nm sudo +process or 0 if there is no terminal present. +Only available starting with API version 1.2. +.It tty=string +The path to the user's terminal device. +If the user has no terminal device associated with the session, +the value will be empty, as in +.Dq Li tty= . +.It uid=uid_t +The real user-ID of the user invoking +.Nm sudo . +.It umask=octal +The invoking user's file creation mask. +Only available starting with API version 1.10. +.It user=string +The name of the user invoking +.Nm sudo . +.El +.It user_env +The user's environment in the form of a +.Dv NULL Ns -terminated vector of +.Dq name=value +strings. +.Pp +When parsing +.Em user_env , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It plugin_options +Any (non-comment) strings immediately after the plugin path are +passed as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +.Dv NULL Ns -terminated +array of strings. +If no arguments were +specified, +.Em plugin_options +will be the +.Dv NULL +pointer. +.Pp +NOTE: the +.Em plugin_options +parameter is only available starting with +API version 1.2. +A plugin +.Sy must +check the API version specified +by the +.Nm sudo +front end before using +.Em plugin_options . +Failure to do so may result in a crash. +.It errstr +If the +.Fn open +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It close +.Bd -literal -compact +void (*close)(int exit_status, int error); +.Ed +.Pp +The +.Fn close +function is called when +.Nm sudo +is finished, shortly before it exits. +Starting with API version 1.15, +.Fn close +is called regardless of whether or not a command was actually executed. +This makes it possible for plugins to perform cleanup even when a +command was not run. +It is not possible to tell whether a command was run based solely +on the arguments passed to the +.Fn close +function. +To determine if a command was actually run, +the plugin must keep track of whether or not the +.Fn check_policy +function returned successfully. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It exit_status +The command's exit status, as returned by the +.Xr wait 2 +system call, or zero if no command was run. +The value of +.Li exit_status +is undefined if +.Li error +is non-zero. +.It error +If the command could not be executed, this is set to the value of +.Li errno +set by the +.Xr execve 2 +system call. +The plugin is responsible for displaying error information via the +.Fn conversation +or +.Fn plugin_printf +function. +If the command was successfully executed, the value of +.Li error +is zero. +.El +.Pp +If no +.Fn close +function is defined, no I/O logging plugins are loaded, +and neither the +.Em timeout +not +.Em use_pty +options are set in the +.Li command_info +list, the +.Nm sudo +front end may execute the command directly instead of running +it as a child process. +.It show_version +.Bd -literal -compact +int (*show_version)(int verbose); +.Ed +.Pp +The +.Fn show_version +function is called by +.Nm sudo +when the user specifies +the +.Fl V +option. +The plugin may display its version information to the user via the +.Fn conversation +or +.Fn plugin_printf +function using +.Dv SUDO_CONV_INFO_MSG . +If the user requests detailed version information, the verbose flag will be set. +.Pp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.It check_policy +.Bd -literal -compact +int (*check_policy)(int argc, char * const argv[], char *env_add[], + char **command_info[], char **argv_out[], char **user_env_out[], + const char **errstr); +.Ed +.Pp +The +.Fn check_policy +function is called by +.Nm sudo +to determine +whether the user is allowed to run the specified commands. +.Pp +If the +.Em sudoedit +option was enabled in the +.Em settings +array +passed to the +.Fn open +function, the user has requested +.Em sudoedit +mode. +.Em sudoedit +is a mechanism for editing one or more files +where an editor is run with the user's credentials instead of with +elevated privileges. +.Nm sudo +achieves this by creating user-writable +temporary copies of the files to be edited and then overwriting the +originals with the temporary copies after editing is complete. +If the plugin supports +.Em sudoedit , +it should choose the editor to be used, potentially from a variable +in the user's environment, such as +.Li EDITOR , +and include it in +.Em argv_out +(note that environment +variables may include command line options). +The files to be edited should be copied from +.Em argv +into +.Em argv_out , +separated from the +editor and its arguments by a +.Dq Li -- +element. +The +.Dq Li -- +will +be removed by +.Nm sudo +before the editor is executed. +The plugin should also set +.Em sudoedit=true +in the +.Em command_info +list. +.Pp +The +.Fn check_policy +function returns 1 if the command is allowed, +0 if not allowed, \-1 for a general error, or \-2 for a usage error +or if +.Em sudoedit +was specified but is unsupported by the plugin. +In the latter case, +.Nm sudo +will print a usage message before it +exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It argc +The number of elements in +.Em argv , +not counting the final +.Dv NULL +pointer. +.It argv +The argument vector describing the command the user wishes to run, +in the same form as what would be passed to the +.Xr execve 2 +system call. +The vector is terminated by a +.Dv NULL +pointer. +.It env_add +Additional environment variables specified by the user on the command +line in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +The plugin may reject the command if one or more variables +are not allowed to be set, or it may silently ignore such variables. +.Pp +When parsing +.Em env_add , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It command_info +Information about the command being run in the form of +.Dq name=value +strings. +These values are used by +.Nm sudo +to set the execution +environment when running a command. +The plugin is responsible for creating and populating the vector, +which must be terminated with a +.Dv NULL +pointer. +The following values are recognized by +.Nm sudo : +.Bl -tag -width 4n +.It chroot=string +The root directory to use when running the command. +.It closefrom=number +If specified, +.Nm sudo +will close all files descriptors with a value +of +.Em number +or higher. +.It command=string +Fully qualified path to the command to be executed. +.It cwd=string +The current working directory to change to when executing the command. +If +.Nm sudo +is unable to change to the new working directory, the command will +not be run unless +.Em cwd_optional +is also set (see below). +.It cwd_optional=bool +If enabled, +.Nm sudo +will treat an inability to change to the new working directory as a +non-fatal error. +This setting has no effect unless +.Em cwd +is also set. +.It exec_background=bool +By default, +.Nm sudo +runs a command as the foreground process as long as +.Nm sudo +itself is running in the foreground. +When +.Em exec_background +is enabled and the command is being run in a pseudo-terminal +(due to I/O logging or the +.Em use_pty +setting), the command will be run as a background process. +Attempts to read from the controlling terminal (or to change terminal +settings) will result in the command being suspended with the +.Dv SIGTTIN +signal (or +.Dv SIGTTOU +in the case of terminal settings). +If this happens when +.Nm sudo +is a foreground process, the command will be granted the controlling terminal +and resumed in the foreground with no user intervention required. +The advantage of initially running the command in the background is that +.Nm sudo +need not read from the terminal unless the command explicitly requests it. +Otherwise, any terminal input must be passed to the command, whether it +has required it or not (the kernel buffers terminals so it is not possible +to tell whether the command really wants the input). +This is different from historic +.Em sudo +behavior or when the command is not being run in a pseudo-terminal. +.Pp +For this to work seamlessly, the operating system must support the +automatic restarting of system calls. +Unfortunately, not all operating systems do this by default, +and even those that do may have bugs. +For example, macOS fails to restart the +.Fn tcgetattr +and +.Fn tcsetattr +system calls (this is a bug in macOS). +Furthermore, because this behavior depends on the command stopping with the +.Dv SIGTTIN +or +.Dv SIGTTOU +signals, programs that catch these signals and suspend themselves +with a different signal (usually +.Dv SIGTOP ) +will not be automatically foregrounded. +Some versions of the linux +.Xr su 1 +command behave this way. +Because of this, a plugin should not set +.Em exec_background +unless it is explicitly enabled by the administrator and there should +be a way to enabled or disable it on a per-command basis. +.Pp +This setting has no effect unless I/O logging is enabled or +.Em use_pty +is enabled. +.It execfd=number +If specified, +.Nm sudo +will use the +.Xr fexecve 2 +system call to execute the command instead of +.Xr execve 2 . +The specified +.Em number +must refer to an open file descriptor. +.It iolog_compress=bool +Set to true if the I/O logging plugins, if any, should compress the +log data. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_group=string +The group that will own newly created I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_mode=octal +The file permission mode to use when creating I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_user=string +The user that will own newly created I/O log files and directories. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_path=string +Fully qualified path to the file or directory in which I/O log is +to be stored. +This is a hint to the I/O logging plugin which may choose to ignore it. +If no I/O logging plugin is loaded, this setting has no effect. +.It iolog_stdin=bool +Set to true if the I/O logging plugins, if any, should log the +standard input if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_stdout=bool +Set to true if the I/O logging plugins, if any, should log the +standard output if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_stderr=bool +Set to true if the I/O logging plugins, if any, should log the +standard error if it is not connected to a terminal device. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_ttyin=bool +Set to true if the I/O logging plugins, if any, should log all +terminal input. +This only includes input typed by the user and not from a pipe or +redirected from a file. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It iolog_ttyout=bool +Set to true if the I/O logging plugins, if any, should log all +terminal output. +This only includes output to the screen, not output to a pipe or file. +This is a hint to the I/O logging plugin which may choose to ignore it. +.It login_class=string +.Bx +login class to use when setting resource limits and nice value (optional). +This option is only set on systems that support login classes. +.It nice=int +Nice value (priority) to use when executing the command. +The nice value, if specified, overrides the priority associated with the +.Em login_class +on +.Bx +systems. +.It noexec=bool +If set, prevent the command from executing other programs. +.It preserve_fds=list +A comma-separated list of file descriptors that should be +preserved, regardless of the value of the +.Em closefrom +setting. +Only available starting with API version 1.5. +.It preserve_groups=bool +If set, +.Nm sudo +will preserve the user's group vector instead of +initializing the group vector based on +.Li runas_user . +.It runas_egid=gid +Effective group-ID to run the command as. +If not specified, the value of +.Em runas_gid +is used. +.It runas_euid=uid +Effective user-ID to run the command as. +If not specified, the value of +.Em runas_uid +is used. +.It runas_gid=gid +Group-ID to run the command as. +.It runas_group=string +The name of the group the command will run as, if it is different +from the +.Em runas_user Ns 's +default group. +This value is provided for auditing purposes only, the +.Nm sudo +front-end uses +.Em runas_egid +and +.Em runas_gid +when executing the command. +.It runas_groups=list +The supplementary group vector to use for the command in the form +of a comma-separated list of group-IDs. +If +.Em preserve_groups +is set, this option is ignored. +.It runas_uid=uid +User-ID to run the command as. +.It runas_user=string +The name of the user the command will run as, which should correspond to +.Em runas_euid +(or +.Em runas_uid +if +.Em runas_euid +is not set). +This value is provided for auditing purposes only, the +.Nm sudo +front-end uses +.Em runas_euid +and +.Em runas_uid +when executing the command. +.It selinux_role=string +SELinux role to use when executing the command. +.It selinux_type=string +SELinux type to use when executing the command. +.It set_utmp=bool +Create a utmp (or utmpx) entry when a pseudo-terminal is allocated. +By default, the new entry will be a copy of the user's existing utmp +entry (if any), with the tty, time, type and pid fields updated. +.It sudoedit=bool +Set to true when in +.Em sudoedit +mode. +The plugin may enable +.Em sudoedit +mode even if +.Nm sudo +was not invoked as +.Nm sudoedit . +This allows the plugin to perform command substitution and transparently +enable +.Em sudoedit +when the user attempts to run an editor. +.It sudoedit_checkdir=bool +Set to false to disable directory writability checks in +.Nm sudoedit . +By default, +.Nm sudoedit +1.8.16 and higher will check all directory components of the path to be +edited for writability by the invoking user. +Symbolic links will not be followed in writable directories and +.Nm sudoedit +will refuse to edit a file located in a writable directory. +These restrictions are not enforced when +.Nm sudoedit +is run by root. +The +.Em sudoedit_follow +option can be set to false to disable this check. +Only available starting with API version 1.8. +.It sudoedit_follow=bool +Set to true to allow +.Nm sudoedit +to edit files that are symbolic links. +By default, +.Nm sudoedit +1.8.15 and higher will refuse to open a symbolic link. +The +.Em sudoedit_follow +option can be used to restore the older behavior and allow +.Nm sudoedit +to open symbolic links. +Only available starting with API version 1.8. +.It timeout=int +Command timeout. +If non-zero then when the timeout expires the command will be killed. +.It umask=octal +The file creation mask to use when executing the command. +This value may be overridden by PAM or login.conf on some systems +unless the +.Em umask_override +option is also set. +.It umask_override=bool +Force the value specified by the +.Em umask +option to override any umask set by PAM or login.conf. +.It use_pty=bool +Allocate a pseudo-terminal to run the command in, regardless of whether +or not I/O logging is in use. +By default, +.Nm sudo +will only run +the command in a pseudo-terminal when an I/O log plugin is loaded. +.It utmp_user=string +User name to use when constructing a new utmp (or utmpx) entry when +.Em set_utmp +is enabled. +This option can be used to set the user field in the utmp entry to +the user the command runs as rather than the invoking user. +If not set, +.Nm sudo +will base the new entry on +the invoking user's existing entry. +.El +.Pp +Unsupported values will be ignored. +.It argv_out +The +.Dv NULL Ns -terminated +argument vector to pass to the +.Xr execve 2 +system call when executing the command. +The plugin is responsible for allocating and populating the vector. +.It user_env_out +The +.Dv NULL Ns -terminated +environment vector to use when executing the command. +The plugin is responsible for allocating and populating the vector. +.It errstr +If the +.Fn check_policy +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It list +.Bd -literal -compact +int (*list)(int argc, char * const argv[], int verbose, + const char *list_user, const char **errstr); +.Ed +.Pp +List available privileges for the invoking user. +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to +the user. +.Pp +Privileges should be output via the +.Fn conversation +or +.Fn plugin_printf +function using +.Dv SUDO_CONV_INFO_MSG . +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It argc +The number of elements in +.Em argv , +not counting the final +.Dv NULL +pointer. +.It argv +If +.No non- Ns Dv NULL , +an argument vector describing a command the user +wishes to check against the policy in the same form as what would +be passed to the +.Xr execve 2 +system call. +If the command is permitted by the policy, the fully-qualified path +to the command should be displayed along with any command line arguments. +.It verbose +Flag indicating whether to list in verbose mode or not. +.It list_user +The name of a different user to list privileges for if the policy +allows it. +If +.Dv NULL , +the plugin should list the privileges of the invoking user. +.It errstr +If the +.Fn list +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It validate +.Bd -literal -compact +int (*validate)(const char **errstr); +.Ed +.Pp +The +.Fn validate +function is called when +.Nm sudo +is run with the +.Fl v +option. +For policy plugins such as +.Nm sudoers +that cache +authentication credentials, this function will validate and cache +the credentials. +.Pp +The +.Fn validate +function should be +.Dv NULL +if the plugin does not support credential caching. +.Pp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional +error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It errstr +If the +.Fn validate +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It invalidate +.Bd -literal -compact +void (*invalidate)(int remove); +.Ed +.Pp +The +.Fn invalidate +function is called when +.Nm sudo +is run with the +.Fl k +or +.Fl K +option. +For policy plugins such as +.Nm sudoers +that +cache authentication credentials, this function will invalidate the +credentials. +If the +.Em remove +flag is set, the plugin may remove +the credentials instead of simply invalidating them. +.Pp +The +.Fn invalidate +function should be +.Dv NULL +if the plugin does not support credential caching. +.It init_session +.Bd -literal -compact +int (*init_session)(struct passwd *pwd, char **user_env_out[]); +.Ed +.Pp +The +.Fn init_session +function is called before +.Nm sudo +sets up the +execution environment for the command. +It is run in the parent +.Nm sudo +process and before any uid or gid changes. +This can be used to perform session setup that is not supported by +.Em command_info , +such as opening the PAM session. +The +.Fn close +function can be +used to tear down the session that was opened by +.Li init_session . +.Pp +The +.Em pwd +argument points to a passwd struct for the user the +command will be run as if the uid the command will run as was found +in the password database, otherwise it will be +.Dv NULL . +.Pp +The +.Em user_env_out +argument points to the environment the command will +run in, in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +This is the same string passed back to the front end via +the Policy Plugin's +.Em user_env_out +parameter. +If the +.Fn init_session +function needs to modify the user environment, it should update the +pointer stored in +.Em user_env_out . +The expected use case is to merge the contents of the PAM environment +(if any) with the contents of +.Em user_env_out . +NOTE: the +.Em user_env_out +parameter is only available +starting with API version 1.2. +A plugin +.Sy must +check the API +version specified by the +.Nm sudo +front end before using +.Em user_env_out . +Failure to do so may result in a crash. +.Pp +Returns 1 on success, 0 on failure and \-1 on error. +On error, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional +error information to the user. +.It register_hooks +.Bd -literal -compact +void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); +.Ed +.Pp +The +.Fn register_hooks +function is called by the sudo front end to +register any hooks the plugin needs. +If the plugin does not support hooks, +.Li register_hooks +should be set to the +.Dv NULL +pointer. +.Pp +The +.Em version +argument describes the version of the hooks API +supported by the +.Nm sudo +front end. +.Pp +The +.Fn register_hook +function should be used to register any supported +hooks the plugin needs. +It returns 0 on success, 1 if the hook type is not supported and \-1 +if the major version in +.Li struct hook +does not match the front end's major hook API version. +.Pp +See the +.Sx Hook function API +section below for more information +about hooks. +.Pp +NOTE: the +.Fn register_hooks +function is only available starting +with API version 1.2. +If the +.Nm sudo +front end doesn't support API +version 1.2 or higher, +.Li register_hooks +will not be called. +.It deregister_hooks +.Bd -literal -compact +void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); +.Ed +.Pp +The +.Fn deregister_hooks +function is called by the sudo front end +to deregister any hooks the plugin has registered. +If the plugin does not support hooks, +.Li deregister_hooks +should be set to the +.Dv NULL +pointer. +.Pp +The +.Em version +argument describes the version of the hooks API +supported by the +.Nm sudo +front end. +.Pp +The +.Fn deregister_hook +function should be used to deregister any +hooks that were put in place by the +.Fn register_hook +function. +If the plugin tries to deregister a hook that the front end does not support, +.Li deregister_hook +will return an error. +.Pp +See the +.Sx Hook function API +section below for more information +about hooks. +.Pp +NOTE: the +.Fn deregister_hooks +function is only available starting +with API version 1.2. +If the +.Nm sudo +front end doesn't support API +version 1.2 or higher, +.Li deregister_hooks +will not be called. +.It event_alloc +.Bd -literal -compact +struct sudo_plugin_event * (*event_alloc)(void); +.Ed +.Pp +The +.Fn event_alloc +function is used to allocate a +.Li struct sudo_plugin_event +which provides access to the main +.Nm sudo +event loop. +Unlike the other fields, the +.Fn event_alloc +pointer is filled in by the +.Nm sudo +front end, not by the plugin. +.Pp +See the +.Sx Event API +section below for more information +about events. +.Pp +NOTE: the +.Fn event_alloc +function is only available starting +with API version 1.15. +If the +.Nm sudo +front end doesn't support API +version 1.15 or higher, +.Fn event_alloc +will not be set. +.It errstr +If the +.Fn init_session +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.Pp +.Em Policy Plugin Version Macros +.Bd -literal +/* Plugin API version major/minor. */ +#define SUDO_API_VERSION_MAJOR 1 +#define SUDO_API_VERSION_MINOR 13 +#define SUDO_API_MKVERSION(x, y) ((x << 16) | y) +#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e + SUDO_API_VERSION_MINOR) + +/* Getters and setters for API version */ +#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16) +#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff) +#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e + *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e +} while(0) +#define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e + *(vp) = (*(vp) & 0xffff0000) | (n); \e +} while(0) +.Ed +.Ss I/O plugin API +.Bd -literal +struct io_plugin { +#define SUDO_IO_PLUGIN 2 + 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 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); + void (*close)(int exit_status, int error); /* wait status or error */ + int (*show_version)(int verbose); + int (*log_ttyin)(const char *buf, unsigned int len, + const char **errstr); + int (*log_ttyout)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stdin)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stdout)(const char *buf, unsigned int len, + const char **errstr); + int (*log_stderr)(const char *buf, unsigned int len, + const char **errstr); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + int (*change_winsize)(unsigned int lines, unsigned int cols, + const char **errstr); + int (*log_suspend)(int signo, const char **errstr); + struct sudo_plugin_event * (*event_alloc)(void); +}; +.Ed +.Pp +When an I/O plugin is loaded, +.Nm sudo +runs the command in a pseudo-terminal. +This makes it possible to log the input and output from the user's +session. +If any of the standard input, standard output or standard error do not +correspond to a tty, +.Nm sudo +will open a pipe to capture +the I/O for logging before passing it on. +.Pp +The log_ttyin function receives the raw user input from the terminal +device (note that this will include input even when echo is disabled, +such as when a password is read). +The log_ttyout function receives output from the pseudo-terminal that is +suitable for replaying the user's session at a later time. +The +.Fn log_stdin , +.Fn log_stdout +and +.Fn log_stderr +functions are only called if the standard input, standard output +or standard error respectively correspond to something other than +a tty. +.Pp +Any of the logging functions may be set to the +.Dv NULL +pointer if no logging is to be performed. +If the open function returns 0, no I/O will be sent to the plugin. +.Pp +If a logging function returns an error +.Pq \-1 , +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 +If an input logging function rejects the data by returning 0, the +command will be terminated and the data will not be passed to the +command, though it will still be sent to any other I/O logging plugins. +If an output logging function rejects the data by returning 0, 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. +.Pp +The audit_plugin struct has the following fields: +.Bl -tag -width 4n +.It type +The +.Li type +field should always be set to +.Dv SUDO_IO_PLUGIN . +.It version +The +.Li version +field should be set to +.Dv SUDO_API_VERSION . +.Pp +This allows +.Nm sudo +to determine the API version the plugin was +built against. +.It open +.Bd -literal -compact +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t 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[]); +.Ed +.Pp +The +.Fn open +function is run before the +.Fn log_ttyin , +.Fn log_ttyout , +.Fn log_stdin , +.Fn log_stdout , +.Fn log_stderr , +.Fn log_suspend , +.Fn change_winsize , +or +.Fn show_version +functions are called. +It is only called if the version is being requested or if the +policy plugin's +.Fn check_policy +function has returned successfully. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +.Nm sudo +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It version +The version passed in by +.Nm sudo +allows the plugin to determine the +major and minor version number of the plugin API supported by +.Nm sudo . +.It conversation +A pointer to the +.Fn conversation +function that may be used by the +.Fn show_version +function to display version information (see +.Fn show_version +below). +The +.Fn conversation +function may also be used to display additional error message to the user. +The +.Fn conversation +function returns 0 on success and \-1 on failure. +.It plugin_printf +A pointer to a +.Fn printf Ns -style +function that may be used by the +.Fn show_version +function to display version information (see +show_version below). +The +.Fn plugin_printf +function may also be used to display additional error message to the user. +The +.Fn plugin_printf +function returns number of characters printed on success and \-1 on failure. +.It settings +A vector of user-supplied +.Nm sudo +settings in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +These settings correspond to options the user specified when running +.Nm sudo . +As such, they will only be present when the corresponding option has +been specified on the command line. +.Pp +When parsing +.Em settings , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible settings. +.It user_info +A vector of information about the user running the command in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em user_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It command_info +A vector of information describing the command being run in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em command_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It argc +The number of elements in +.Em argv , +not counting the final +.Dv NULL +pointer. +It can be zero, when +.Nm sudo +is called with +.Fl V . +.It argv +If +.No non- Ns Dv NULL , +an argument vector describing a command the user +wishes to run in the same form as what would be passed to the +.Xr execve 2 +system call. +.It user_env +The user's environment in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +.Pp +When parsing +.Em user_env , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +.Dv NULL Ns -terminated +array of strings. +If no arguments were specified, +.Em plugin_options +will be the +.Dv NULL +pointer. +.Pp +NOTE: the +.Em plugin_options +parameter is only available starting with +API version 1.2. +A plugin +.Sy must +check the API version specified +by the +.Nm sudo +front end before using +.Em plugin_options . +Failure to do so may result in a crash. +.It errstr +If the +.Fn open +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It close +.Bd -literal -compact +void (*close)(int exit_status, int error); +.Ed +.Pp +The +.Fn close +function is called when +.Nm sudo +is finished, shortly before it exits. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It exit_status +The command's exit status, as returned by the +.Xr wait 2 +system call, or zero if no command was run. +The value of +.Li exit_status +is undefined if +.Li error +is non-zero. +.It error +If the command could not be executed, this is set to the value of +.Li errno +set by the +.Xr execve 2 +system call. +If the command was successfully executed, the value of +.Li error +is zero. +.El +.It show_version +.Bd -literal -compact +int (*show_version)(int verbose); +.Ed +.Pp +The +.Fn show_version +function is called by +.Nm sudo +when the user specifies +the +.Fl V +option. +The plugin may display its version information to the user via the +.Fn conversation +or +.Fn plugin_printf +function using +.Dv SUDO_CONV_INFO_MSG . +.Pp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.It log_ttyin +.Bd -literal -compact +int (*log_ttyin)(const char *buf, unsigned int len, + const char **errstr); +.Ed +.Pp +The +.Fn log_ttyin +function is called whenever data can be read from +the user but before it is passed to the running command. +This allows the plugin to reject data if it chooses to (for instance +if the input contains banned content). +Returns 1 if the data should be passed to the command, 0 if the data +is rejected (which will terminate the running command) or \-1 if an +error occurred. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It buf +The buffer containing user input. +.It len +The length of +.Em buf +in bytes. +.It errstr +If the +.Fn log_ttyin +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It log_ttyout +.Bd -literal -compact +int (*log_ttyout)(const char *buf, unsigned int len, + const char **errstr); +.Ed +.Pp +The +.Fn log_ttyout +function is called whenever data can be read from +the command but before it is written to the user's terminal. +This allows the plugin to reject data if it chooses to (for instance +if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is rejected +(which will terminate the running command) or \-1 if an error occurred. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It buf +The buffer containing command output. +.It len +The length of +.Em buf +in bytes. +.It errstr +If the +.Fn log_ttyout +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It log_stdin +.Bd -literal -compact +int (*log_stdin)(const char *buf, unsigned int len, + const char **errstr); +.Ed +.Pp +The +.Fn log_stdin +function is only used if the standard input does +not correspond to a tty device. +It is called whenever data can be read from the standard input but +before it is passed to the running command. +This allows the plugin to reject data if it chooses to +(for instance if the input contains banned content). +Returns 1 if the data should be passed to the command, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It buf +The buffer containing user input. +.It len +The length of +.Em buf +in bytes. +.It errstr +If the +.Fn log_stdin +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It log_stdout +.Bd -literal -compact +int (*log_stdout)(const char *buf, unsigned int len, + const char **errstr); +.Ed +.Pp +The +.Fn log_stdout +function is only used if the standard output does not correspond +to a tty device. +It is called whenever data can be read from the command but before +it is written to the standard output. +This allows the plugin to reject data if it chooses to +(for instance if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It buf +The buffer containing command output. +.It len +The length of +.Em buf +in bytes. +.It errstr +If the +.Fn log_stdout +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It log_stderr +.Bd -literal -compact +int (*log_stderr)(const char *buf, unsigned int len, + const char **errstr); +.Ed +.Pp +The +.Fn log_stderr +function is only used if the standard error does +not correspond to a tty device. +It is called whenever data can be read from the command but before it +is written to the standard error. +This allows the plugin to reject data if it chooses to +(for instance if the output contains banned content). +Returns 1 if the data should be passed to the user, 0 if the data is +rejected (which will terminate the running command) or \-1 if an error occurred. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It buf +The buffer containing command output. +.It len +The length of +.Em buf +in bytes. +.It errstr +If the +.Fn log_stderr +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It register_hooks +See the +.Sx Policy plugin API +section for a description of +.Li register_hooks . +.It deregister_hooks +See the +.Sx Policy plugin API +section for a description of +.Li deregister_hooks . +.It change_winsize +.Bd -literal -compact +int (*change_winsize)(unsigned int lines, unsigned int cols, + const char **errstr); +.Ed +.Pp +The +.Fn change_winsize +function is called whenever the window size of the terminal changes from +the initial values specified in the +.Li user_info +list. +Returns \-1 if an error occurred, in which case no further calls to +.Fn change_winsize +will be made, +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It lines +The number of lines (rows) in the re-sized terminal. +.It cols +The number of columns in the re-sized terminal. +.It errstr +If the +.Fn change_winsize +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.El +.It log_suspend +.Bd -literal -compact +int (*log_suspend)(int signo, const char **errstr); +.Ed +.Pp +The +.Fn log_suspend +function is called whenever a command is suspended or resumed. +Logging this information makes it possible to skip the period of time when +the command was suspended during playback of a session. +Returns \-1 if an error occurred, in which case no further calls to +.Fn log_suspend +will be made, +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It signo +The signal that caused the command to be suspended, or +.Dv SIGCONT +if the command was resumed. +.It errstr +If the +.Fn log_suspend +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.Pp +NOTE: the +.Fa errstr +parameter is only available starting with +API version 1.15. +A plugin +.Sy must +check the API version specified by the +.Nm sudo +front end before using +.Fa errstr . +Failure to do so may result in a crash. +.It event_alloc +.Bd -literal -compact +struct sudo_plugin_event * (*event_alloc)(void); +.Ed +.Pp +The +.Fn event_alloc +function is used to allocate a +.Li struct sudo_plugin_event +which provides access to the main +.Nm sudo +event loop. +Unlike the other fields, the +.Fn event_alloc +pointer is filled in by the +.Nm sudo +front end, not by the plugin. +.Pp +See the +.Sx Event API +section below for more information +about events. +.Pp +NOTE: the +.Fn event_alloc +function is only available starting +with API version 1.15. +If the +.Nm sudo +front end doesn't support API +version 1.15 or higher, +.Fn event_alloc +will not be set. +.El +.Pp +.Em I/O Plugin Version Macros +.Pp +Same as for the +.Sx Policy plugin API . +.El +.Ss Audit plugin API +.Bd -literal +/* Audit plugin close function status types. */ +#define SUDO_PLUGIN_NO_STATUS 0 +#define SUDO_PLUGIN_WAIT_STATUS 1 +#define SUDO_PLUGIN_EXEC_ERROR 2 +#define SUDO_PLUGIN_SUDO_ERROR 3 + +#define SUDO_AUDIT_PLUGIN 3 +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[], + char * const user_info[], int submit_optind, + char * const submit_argv[], char * const submit_envp[], + char * const plugin_options[], const char **errstr); + void (*close)(int status_type, int status); + int (*accept)(const char *plugin_name, + unsigned int plugin_type, char * const command_info[], + char * const run_argv[], char * const run_envp[], + const char **errstr); + int (*reject)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); + int (*error)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); + int (*show_version)(int verbose); + void (*register_hooks)(int version, + int (*register_hook)(struct sudo_hook *hook)); + void (*deregister_hooks)(int version, + int (*deregister_hook)(struct sudo_hook *hook)); + struct sudo_plugin_event * (*event_alloc)(void); +} +.Ed +.Pp +An audit plugin can be used to log successful and unsuccessful attempts +to run +.Nm sudo +independent of the policy or any I/O plugins. +Multiple audit plugins may be specified in +.Xr sudo.conf @mansectform@ . +.Pp +The audit_plugin struct has the following fields: +.Bl -tag -width 4n +.It type +The +.Li type +field should always be set to +.Dv SUDO_AUDIT_PLUGIN . +.It version +The +.Li version +field should be set to +.Dv SUDO_API_VERSION . +.Pp +This allows +.Nm sudo +to determine the API version the plugin was +built against. +.It open +.Bd -literal -compact +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t sudo_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); +.Ed +.Pp +The audit +.Fn open +function is run before any other +.Nm sudo +plugin API functions. +This makes it possible to audit failures in the other plugins. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +.Nm sudo +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It version +The version passed in by +.Nm sudo +allows the plugin to determine the +major and minor version number of the plugin API supported by +.Nm sudo . +.It conversation +A pointer to the +.Fn conversation +function that may be used by the +.Fn show_version +function to display version information (see +.Fn show_version +below). +The +.Fn conversation +function may also be used to display additional error message to the user. +The +.Fn conversation +function returns 0 on success and \-1 on failure. +.It plugin_printf +A pointer to a +.Fn printf Ns -style +function that may be used by the +.Fn show_version +function to display version information (see +show_version below). +The +.Fn plugin_printf +function may also be used to display additional error message to the user. +The +.Fn plugin_printf +function returns number of characters printed on success and \-1 on failure. +.It settings +A vector of user-supplied +.Nm sudo +settings in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +These settings correspond to options the user specified when running +.Nm sudo . +As such, they will only be present when the corresponding option has +been specified on the command line. +.Pp +When parsing +.Em settings , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible settings. +.It user_info +A vector of information about the user running the command in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em user_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It submit_optind +The index into +.Fa submit_argv +that corresponds to the first entry that is not a command line option. +If +.Fa submit_argv +only consists of options, which may be the case with the +.Fl l +or +.Fl v +options, +.Li submit_argv[submit_optind] +will evaluate to the NULL pointer. +.It submit_argv +The argument vector +.Nm sudo +was invoked with, including all command line options. +The +.Fa submit_optind +argument can be used to determine the end of the command line options. +.It submit_envp +The invoking user's environment in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +.Pp +When parsing +.Em submit_envp , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +.Dv NULL Ns -terminated +array of strings. +If no arguments were specified, +.Em plugin_options +will be the +.Dv NULL +pointer. +.It errstr +If the +.Fn open +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It close +.Bd -literal -compact +void (*close)(int status_type, int status); +.Ed +.Pp +The +.Fn close +function is called when +.Nm sudo +is finished, shortly before it exits. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It status_type +The type of status being passed. +One of +.Dv SUDO_PLUGIN_NO_STATUS , +.Dv SUDO_PLUGIN_WAIT_STATUS , +.Dv SUDO_PLUGIN_EXEC_ERROR +or +.Dv SUDO_PLUGIN_SUDO_ERROR . +.It status +Depending on the value of +.Fa status_type , +this value is either +ignored, the command's exit status as returned by the +.Xr wait 2 +system call, the value of +.Li errno +set by the +.Xr execve 2 +system call, or the value of +.Li errno +resulting from an error in the +.Nm sudo +front end. +.El +.It accept +.Bd -literal -compact +int (*accept)(const char *plugin_name, unsigned int plugin_type, + char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); +.Ed +.Pp +The +.Fn accept +function is called when a command or action is accepted by a policy +or approval plugin. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that accepted the command or +.Dq sudo +for the +.Nm sudo +front-end. +.It plugin_type +The type of plugin that accepted the command, currently either +.Dv SUDO_POLICY_PLUGIN , +.Dv SUDO_POLICY_APPROVAL +or +.Dv SUDO_FRONT_END . +The +.Fn accept +function is called multiple times--once for each policy or approval +plugin that succeeds and once for the sudo front-end. +When called on behalf of the sudo front-end, +.Fa command_info +may include information from an I/O logging plugin as well. +.Pp +Typically, an audit plugin is interested in either the accept status from +the +.Nm sudo +front-end or from the various policy and approval plugins, but not both. +It is possible for the policy plugin to accept a command that is +later rejected by an approval plugin, in which case the audit +plugin's +.Fn accept +and +.Fn reject +functions will +.Em both +be called. +.It command_info +An optional +vector of information describing the command being run in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em command_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It run_argv +A +.Dv NULL Ns -terminated +argument vector describing a command that will be run in the +same form as what would be passed to the +.Xr execve 2 +system call. +.It run_envp +The environment the command will be run with in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +.Pp +When parsing +.Em run_envp , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It errstr +If the +.Fn accept +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It reject +.Bd -literal -compact +int (*reject)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); +.Ed +.Pp +The +.Fn reject +function is called when a command or action is rejected by a plugin. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that rejected the command. +.It plugin_type +The type of plugin that rejected the command, currently either +.Dv SUDO_POLICY_PLUGIN , +.Dv SUDO_APPROVAL_PLUGIN +or +.Dv SUDO_IO_PLUGIN . +.Pp +Unlike the +.Fn accept +function, the +.Fn reject +function is not called on behalf of the +.Nm sudo +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, +.Fa audit_msg +will be the +.Dv NULL +pointer. +.It command_info +An optional +vector of information describing the command being run in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em command_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It errstr +If the +.Fn reject +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It error +.Bd -literal -compact +int (*error)(const char *plugin_name, unsigned int plugin_type, + const char *audit_msg, char * const command_info[], + const char **errstr); +.Ed +.Pp +The +.Fn error +function is called when a plugin or the +.Nm sudo +front-end returns an error. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that generated the error or +.Dq sudo +for the +.Nm sudo +front-end. +.It plugin_type +The type of plugin that generated the error, or +.Dv SUDO_FRONT_END +for the +.Nm sudo +front-end. +.It audit_msg +An optional string describing the plugin error. +If the plugin did not provide a description, +.Fa audit_msg +will be the +.Dv NULL +pointer. +.It command_info +An optional +vector of information describing the command being run in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em command_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It errstr +If the +.Fn error +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It show_version +.Bd -literal -compact +int (*show_version)(int verbose); +.Ed +.Pp +The +.Fn show_version +function is called by +.Nm sudo +when the user specifies +the +.Fl V +option. +The plugin may display its version information to the user via the +.Fn conversation +or +.Fn plugin_printf +function using +.Dv SUDO_CONV_INFO_MSG . +If the user requests detailed version information, the verbose flag will be set. +.Pp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.It register_hooks +See the +.Sx Policy plugin API +section for a description of +.Li register_hooks . +.It deregister_hooks +See the +.Sx Policy plugin API +section for a description of +.Li deregister_hooks . +.It event_alloc +.Bd -literal -compact +struct sudo_plugin_event * (*event_alloc)(void); +.Ed +.Pp +The +.Fn event_alloc +function is used to allocate a +.Li struct sudo_plugin_event +which provides access to the main +.Nm sudo +event loop. +Unlike the other fields, the +.Fn event_alloc +pointer is filled in by the +.Nm sudo +front end, not by the plugin. +.Pp +See the +.Sx Event API +section below for more information +about events. +.Pp +NOTE: the +.Fn event_alloc +function is only available starting +with API version 1.17. +If the +.Nm sudo +front end doesn't support API +version 1.17 or higher, +.Fn event_alloc +will not be set. +.El +.Ss Approval plugin API +.Bd -literal +struct approval_plugin { +#define SUDO_APPROVAL_PLUGIN 4 + 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[], + char * const user_info[], int submit_optind, + char * const submit_argv[], char * const submit_envp[], + char * const plugin_options[], const char **errstr); + void (*close)(void); + int (*check)(char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); + int (*show_version)(int verbose); +}; +.Ed +.Pp +An approval plugin can be used to apply extra constraints after a +command has been accepted by the policy plugin. +Unlike the other plugin types, it does not remain open until the command +completes. +The plugin is opened before a call to +.Fn check +or +.Fn show_version +and closed shortly thereafter (audit plugin functions must be called +before the plugin is closed). +Multiple approval plugins may be specified in +.Xr sudo.conf @mansectform@ . +.Pp +The approval_plugin struct has the following fields: +.Bl -tag -width 4n +.It type +The +.Li type +field should always be set to +.Dv SUDO_APPROVAL_PLUGIN . +.It version +The +.Li version +field should be set to +.Dv SUDO_API_VERSION . +.Pp +This allows +.Nm sudo +to determine the API version the plugin was +built against. +.It open +.Bd -literal -compact +int (*open)(unsigned int version, sudo_conv_t conversation, + sudo_printf_t sudo_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); +.Ed +.Pp +The approval +.Fn open +function is run immediately before a call to the plugin's +.Fn check +or +.Fn show_version +functions. +It is only called if the version is being requested or if the +policy plugin's +.Fn check_policy +function has returned successfully. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +.Nm sudo +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It version +The version passed in by +.Nm sudo +allows the plugin to determine the +major and minor version number of the plugin API supported by +.Nm sudo . +.It conversation +A pointer to the +.Fn conversation +function that can be used by the plugin to interact with the user (see +.Sx Conversation API +for details). +Returns 0 on success and \-1 on failure. +.It plugin_printf +A pointer to a +.Fn printf Ns -style +function that may be used to display informational or error messages (see +.Sx Conversation API +for details). +Returns the number of characters printed on success and \-1 on failure. +.It settings +A vector of user-supplied +.Nm sudo +settings in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +These settings correspond to options the user specified when running +.Nm sudo . +As such, they will only be present when the corresponding option has +been specified on the command line. +.Pp +When parsing +.Em settings , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible settings. +.It user_info +A vector of information about the user running the command in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em user_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It submit_optind +The index into +.Fa submit_argv +that corresponds to the first entry that is not a command line option. +If +.Fa submit_argv +only consists of options, which may be the case with the +.Fl l +or +.Fl v +options, +.Li submit_argv[submit_optind] +will evaluate to the NULL pointer. +.It submit_argv +The argument vector +.Nm sudo +was invoked with, including all command line options. +The +.Fa submit_optind +argument can be used to determine the end of the command line options. +.It submit_envp +The invoking user's environment in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +.Pp +When parsing +.Em submit_envp , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It plugin_options +Any (non-comment) strings immediately after the plugin path are +treated as arguments to the plugin. +These arguments are split on a white space boundary and are passed to +the plugin in the form of a +.Dv NULL Ns -terminated +array of strings. +If no arguments were specified, +.Em plugin_options +will be the +.Dv NULL +pointer. +.It errstr +If the +.Fn open +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It close +.Bd -literal -compact +void (*close)(void); +.Ed +.Pp +The +.Fn close +function is called after the approval plugin's +.Fn check +or +.Fn show_version +functions have been called. +It takes no arguments. +The +.Fn close +function is typically used to perform plugin-specific cleanup, +such as the freeing of memory objects allocated by the plugin. +If the plugin does not need to perform any cleanup, +.Fn close +may be set to the +.Dv NULL +pointer. +.It check +.Bd -literal -compact +int (*check)(char * const command_info[], char * const run_argv[], + char * const run_envp[], const char **errstr); +.Ed +.Pp +The approval +.Fn check +function is run after the policy plugin +.Fn check_policy +function and before any I/O logging plugins. +If multiple approval plugins are loaded, they must all succeed for +the command to be allowed. +It returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error. +In the latter case, +.Nm sudo +will print a usage message before it exits. +If an error occurs, the plugin may optionally call the +.Fn conversation +or +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It command_info +A vector of information describing the command being run in the form of +.Dq name=value +strings. +The vector is terminated by a +.Dv NULL +pointer. +.Pp +When parsing +.Em command_info , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.Pp +See the +.Sx Policy plugin API +section for a list of all possible strings. +.It run_argv +A +.Dv NULL Ns -terminated +argument vector describing a command that will be run in the +same form as what would be passed to the +.Xr execve 2 +system call. +.It run_envp +The environment the command will be run with in the form of a +.Dv NULL Ns -terminated +vector of +.Dq name=value +strings. +.Pp +When parsing +.Em run_envp , +the plugin should split on the +.Sy first +equal sign +.Pq Ql = +since the +.Em name +field will never include one +itself but the +.Em value +might. +.It errstr +If the +.Fn open +function returns a value other than 1, the plugin may +store a message describing the failure or error in +.Fa errstr . +The +.Nm sudo +front end will then pass this value to any registered audit plugins. +The string stored in +.Fa errstr +must remain valid until the plugin's +.Fn close +function is called. +.El +.It show_version +.Bd -literal -compact +int (*show_version)(int verbose); +.Ed +.Pp +The +.Fn show_version +function is called by +.Nm sudo +when the user specifies +the +.Fl V +option. +The plugin may display its version information to the user via the +.Fn conversation +or +.Fn plugin_printf +function using +.Dv SUDO_CONV_INFO_MSG . +If the user requests detailed version information, the verbose flag will be set. +.Pp +Returns 1 on success, 0 on failure, \-1 if a general error occurred, +or \-2 if there was a usage error, although the return value is currently +ignored. +.El +.Ss Signal handlers +The +.Nm sudo +front end installs default signal handlers to trap common signals +while the plugin functions are run. +The following signals are trapped by default before the command is +executed: +.Pp +.Bl -bullet -compact -width 1n +.It +.Dv SIGALRM +.It +.Dv SIGHUP +.It +.Dv SIGINT +.It +.Dv SIGPIPE +.It +.Dv SIGQUIT +.It +.Dv SIGTERM +.It +.Dv SIGTSTP +.It +.Dv SIGUSR1 +.It +.Dv SIGUSR2 +.El +.Pp +If a fatal signal is received before the command is executed, +.Nm sudo +will call the plugin's +.Fn close +function with an exit status of 128 plus the value of the signal +that was received. +This allows for consistent logging of commands killed by a signal +for plugins that log such information in their +.Fn close +function. +An exception to this is +.Ev SIGPIPE , +which is ignored until the command is executed. +.Pp +A plugin may temporarily install its own signal handlers but must +restore the original handler before the plugin function returns. +.Ss Hook function API +Beginning with plugin API version 1.2, it is possible to install +hooks for certain functions called by the +.Nm sudo +front end. +.Pp +Currently, the only supported hooks relate to the handling of +environment variables. +Hooks can be used to intercept attempts to get, set, or remove +environment variables so that these changes can be reflected in +the version of the environment that is used to execute a command. +A future version of the API will support hooking internal +.Nm sudo +front end functions as well. +.Pp +.Em Hook structure +.Pp +Hooks in +.Nm sudo +are described by the following structure: +.Bd -literal +typedef int (*sudo_hook_fn_t)(); + +struct sudo_hook { + unsigned int hook_version; + unsigned int hook_type; + sudo_hook_fn_t hook_fn; + void *closure; +}; +.Ed +.Pp +The +.Li sudo_hook +structure has the following fields: +.Bl -tag -width 4n +.It hook_version +The +.Li hook_version +field should be set to +.Dv SUDO_HOOK_VERSION . +.It hook_type +The +.Li hook_type +field may be one of the following supported hook types: +.Bl -tag -width 4n +.It Dv SUDO_HOOK_SETENV +The C library +.Xr setenv 3 +function. +Any registered hooks will run before the C library implementation. +The +.Li hook_fn +field should +be a function that matches the following typedef: +.Bd -literal +typedef int (*sudo_hook_fn_setenv_t)(const char *name, + const char *value, int overwrite, void *closure); +.Ed +.Pp +If the registered hook does not match the typedef the results are +unspecified. +.It Dv SUDO_HOOK_UNSETENV +The C library +.Xr unsetenv 3 +function. +Any registered hooks will run before the C library implementation. +The +.Li hook_fn +field should +be a function that matches the following typedef: +.Bd -literal +typedef int (*sudo_hook_fn_unsetenv_t)(const char *name, + void *closure); +.Ed +.It Dv SUDO_HOOK_GETENV +The C library +.Xr getenv 3 +function. +Any registered hooks will run before the C library implementation. +The +.Li hook_fn +field should +be a function that matches the following typedef: +.Bd -literal +typedef int (*sudo_hook_fn_getenv_t)(const char *name, + char **value, void *closure); +.Ed +.Pp +If the registered hook does not match the typedef the results are +unspecified. +.It Dv SUDO_HOOK_PUTENV +The C library +.Xr putenv 3 +function. +Any registered hooks will run before the C library implementation. +The +.Li hook_fn +field should +be a function that matches the following typedef: +.Bd -literal +typedef int (*sudo_hook_fn_putenv_t)(char *string, + void *closure); +.Ed +.Pp +If the registered hook does not match the typedef the results are +unspecified. +.El +.It hook_fn +sudo_hook_fn_t hook_fn; +.Pp +The +.Li hook_fn +field should be set to the plugin's hook implementation. +The actual function arguments will vary depending on the +.Li hook_type +(see +.Li hook_type +above). +In all cases, the +.Li closure +field of +.Li struct sudo_hook +is passed as the last function parameter. +This can be used to pass arbitrary data to the plugin's hook implementation. +.Pp +The function return value may be one of the following: +.Bl -tag -width 4n +.It Dv SUDO_HOOK_RET_ERROR +The hook function encountered an error. +.It Dv SUDO_HOOK_RET_NEXT +The hook completed without error, go on to the next hook (including +the system implementation if applicable). +For example, a +.Xr getenv 3 +hook might return +.Dv SUDO_HOOK_RET_NEXT +if the specified variable was not found in the private copy of the environment. +.It Dv SUDO_HOOK_RET_STOP +The hook completed without error, stop processing hooks for this invocation. +This can be used to replace the system implementation. +For example, a +.Li setenv +hook that operates on a private copy of +the environment but leaves +.Li environ +unchanged. +.El +.El +.Pp +Note that it is very easy to create an infinite loop when hooking +C library functions. +For example, a +.Xr getenv 3 +hook that calls the +.Xr snprintf 3 +function may create a loop if the +.Xr snprintf 3 +implementation calls +.Xr getenv 3 +to check the locale. +To prevent this, you may wish to use a static variable in the hook +function to guard against nested calls. +For example: +.Bd -literal +static int in_progress = 0; /* avoid recursion */ +if (in_progress) + return SUDO_HOOK_RET_NEXT; +in_progress = 1; +\&... +in_progress = 0; +return SUDO_HOOK_RET_STOP; +.Ed +.Pp +.Em Hook API Version Macros +.Bd -literal +/* Hook API version major/minor */ +#define SUDO_HOOK_VERSION_MAJOR 1 +#define SUDO_HOOK_VERSION_MINOR 0 +#define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e + SUDO_HOOK_VERSION_MINOR) +.Ed +.Pp +For getters and setters see the +.Sx Policy plugin API . +.Ss Event API +When +.Nm sudo +runs a command, it uses an event loop to service signals and I/O. +Events may be triggered based on time, a file or socket descriptor +becoming ready, or due to receipt of a signal. +Starting with API version 1.15, it is possible for a plugin to +participate in this event loop by calling the +.Fn event_alloc +function. +.Pp +.Em Event structure +.Pp +Events are described by the following structure: +.Pp +.Bd -literal -compact +typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, void *closure); + +struct sudo_plugin_event { + int (*set)(struct sudo_plugin_event *pev, int fd, int events, + sudo_plugin_ev_callback_t callback, void *closure); + int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout); + int (*del)(struct sudo_plugin_event *pev); + int (*pending)(struct sudo_plugin_event *pev, int events, + struct timespec *ts); + int (*fd)(struct sudo_plugin_event *pev); + void (*setbase)(struct sudo_plugin_event *pev, void *base); + void (*loopbreak)(struct sudo_plugin_event *pev); + void (*free)(struct sudo_plugin_event *pev); +}; +.Ed +.Pp +The sudo_plugin_event struct contains the following function pointers: +.Bl -tag -width 4n +.It Fn set +.Bd -literal -compact +int (*set)(struct sudo_plugin_event *pev, int fd, int events, + sudo_plugin_ev_callback_t callback, void *closure); +.Ed +.Pp +The +.Fn set +function takes the following arguments: +.Bl -tag -width 4n +.It struct sudo_plugin_event * Ns Fa pev +A pointer to the struct sudo_plugin_event itself. +.It Fa fd +The file or socket descriptor for I/O-based events or the signal +number for signal events. +For time-based events, +.Fa fd +must be -1. +.It Fa events +The following values determine what will trigger the event callback: +.Bl -tag -width 4n +.It SUDO_PLUGIN_EV_TIMEOUT +callback is run after the specified timeout expires +.It SUDO_PLUGIN_EV_READ +callback is run when the file descriptor is readable +.It SUDO_PLUGIN_EV_WRITE +callback is run when the file descriptor is writable +.It SUDO_PLUGIN_EV_PERSIST +event is persistent and remains enabled until explicitly deleted +.It SUDO_PLUGIN_EV_SIGNAL +callback is run when the specified signal is received +.El +.Pp +The +.Ev SUDO_PLUGIN_EV_PERSIST +flag may be ORed with any of the event types. +It is also possible to OR +.Ev SUDO_PLUGIN_EV_READ +and +.Ev SUDO_PLUGIN_EV_WRITE +together to run the callback when a descriptor is ready to be +either read from or written to. +All other event values are mutually exclusive. +.It sudo_plugin_ev_callback_t Fa callback +.Bd -literal -compact +typedef void (*sudo_plugin_ev_callback_t)(int fd, int what, + void *closure); +.Ed +.Pp +The function to call when an event is triggered. +The +.Fn callback +function is run with the following arguments: +.Bl -tag -width 4n +.It Fa fd +The file or socket descriptor for I/O-based events or the signal +number for signal events. +.It Fa what +The event type that triggered that callback. +For events that have multiple event types (for example +.Ev SUDO_PLUGIN_EV_READ +and +.Ev SUDO_PLUGIN_EV_WRITE ) +or have an associated timeout, +.Fa what +can be used to determine why the callback was run. +.It Fa closure +The generic pointer that was specified in the +.Fn set +function. +.El +.It closure +A generic pointer that will be passed to the callback function. +.El +.Pp +The +.Fn set +function returns 1 on success, and \-1 if a error occurred. +.It Fn add +.Bd -literal -compact +int (*add)(struct sudo_plugin_event *pev, struct timespec *timeout); +.Ed +.Pp +The +.Fn add +function adds the event +.Fa pev +to +.Nm sudo Ns No 's +event loop. +The event must have previously been initialized via the +.Fn set +function. +If the +.Fa timeout +argument is not NULL, it should specify a (relative) timeout after +which the event will be triggered if the main event criteria has +not been met. +This is often used to implement an I/O timeout where the event +will fire if a descriptor is not ready within a certain time +period. +If the event is already present in the event loop, its +.Fa timeout +will be adjusted to match the new value, if any. +.Pp +The +.Fn add +function returns 1 on success, and \-1 if a error occurred. +.It Fn del +.Bd -literal -compact +int (*del)(struct sudo_plugin_event *pev); +.Ed +.Pp +The +.Fn del +function deletes the event +.Fa pev +from +.Nm sudo Ns No 's +event loop. +Deleted events can be added back via the +.Fn add +function. +.Pp +The +.Fn del +function returns 1 on success, and \-1 if a error occurred. +.It Fn pending +.Bd -literal -compact +int (*pending)(struct sudo_plugin_event *pev, int events, + struct timespec *ts); +.Ed +.Pp +The +.Fn pending +function can be used to determine whether one or more events is pending. +The +.Fa events +argument specifies which events to check for. +See the +.Fn set +function for a list of valid event types. +If +.Dv SUDO_PLUGIN_EV_TIMEOUT +is specified in +.Dv events , +the event has an associated timeout and the +.Fa ts +pointer is non-NULL, it will be filled in with the remaining time. +.It Fn fd +.Bd -literal -compact +int (*fd)(struct sudo_plugin_event *pev); +.Ed +.Pp +The +.Fn fd +function returns the descriptor or signal number associated with +the event +.Fa pev . +.It Fn setbase +.Bd -literal -compact +void (*setbase)(struct sudo_plugin_event *pev, void *base); +.Ed +.Pp +The +.Fn setbase +function sets the underlying event +.Fa base +for +.Fa pev +to the specified value. +This can be used to move an event created via +.Fn event_alloc +to a new event loop allocated by sudo's event subsystem. +If +.Fa base +is +.Dv NULL , +.Fa pev Ns 's +event base is reset to the default value, which corresponds to +.Nm sudo Ns 's +main event loop. +Using this function requires linking the plugin with the sudo_util +library. +It is unlikely to be used outside of the +.Nm sudoers +plugin. +.It Fn loopbreak +.Bd -literal -compact +void (*loopbreak)(struct sudo_plugin_event *pev); +.Ed +.Pp +The +.Fn loopbreak +function causes +.Nm sudo Ns No 's +event loop to exit immediately and the running command to be terminated. +.It Fn free +.Bd -literal -compact +void (*free)(struct sudo_plugin_event *pev); +.Ed +.Pp +The +.Fn free +function deletes the event +.Fa pev +from the event loop and frees the memory associated with it. +.El +.Ss Remote command execution +The +.Nm sudo +front end does not support running remote commands. +However, starting with +.Nm sudo +1.8.8, the +.Fl h +option may be used to specify a remote host that is passed +to the policy plugin. +A plugin may also accept a +.Em runas_user +in the form of +.Dq user@hostname +which will work with older versions of +.Nm sudo . +It is anticipated that remote commands will be supported by executing a +.Dq helper +program. +The policy plugin should setup the execution environment such that the +.Nm sudo +front end will run the helper which, in turn, will connect to the +remote host and run the command. +.Pp +For example, the policy plugin could utilize +.Nm ssh +to perform remote command execution. +The helper program would be responsible for running +.Nm ssh +with the proper options to use a private key or certificate +that the remote host will accept and run a program +on the remote host that would setup the execution environment +accordingly. +.Pp +Note that remote +.Nm sudoedit +functionality must be handled by the policy plugin, not +.Nm sudo +itself as the front end has no knowledge that a remote command is +being executed. +This may be addressed in a future revision of the plugin API. +.Ss Conversation API +If the plugin needs to interact with the user, it may do so via the +.Fn conversation +function. +A plugin should not attempt to read directly from the standard input +or the user's tty (neither of which are guaranteed to exist). +The caller must include a trailing newline in +.Li msg +if one is to be printed. +.Pp +A +.Fn printf Ns -style +function is also available that can be used to display informational +or error messages to the user, which is usually more convenient for +simple messages where no use input is required. +.Pp +.Em Conversation function structures +.Pp +The conversation function takes as arguments pointers to the following +structures: +.Bd -literal +struct sudo_conv_message { +#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */ +#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */ +#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */ +#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */ +#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */ +#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */ +#define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */ + int msg_type; + int timeout; + const char *msg; +}; + +#define SUDO_CONV_REPL_MAX 1023 + +struct sudo_conv_reply { + char *reply; +}; + +typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure); +struct sudo_conv_callback { + unsigned int version; + void *closure; + sudo_conv_callback_fn_t on_suspend; + sudo_conv_callback_fn_t on_resume; +}; +.Ed +.Pp +Pointers to the +.Fn conversation +and +.Fn printf Ns -style +functions are passed +in to the plugin's +.Fn open +function when the plugin is initialized. +The following type definitions can be used in the declaration of the +.Fn open +function: +.Bd -literal +typedef int (*sudo_conv_t)(int num_msgs, + const struct sudo_conv_message msgs[], + struct sudo_conv_reply replies[], struct sudo_conv_callback *callback); + +typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); +.Ed +.Pp +To use the +.Fn conversation +function, the plugin must pass an array of +.Li sudo_conv_message +and +.Li sudo_conv_reply +structures. +There must be a +.Li struct sudo_conv_message +and +.Li struct sudo_conv_reply +for +each message in the conversation, that is, both arrays must have the same +number of elements. +Each +.Li struct sudo_conv_reply +must have its +.Em reply +member initialized to +.Dv NULL . +The +.Li struct sudo_conv_callback +pointer, if not +.Dv NULL , +should contain function pointers to be called when the +.Nm sudo +process is suspended and/or resumed during conversation input. +The +.Fa on_suspend +and +.Fa on_resume +functions are called with the signal that caused +.Nm sudo +to be suspended and the +.Fa closure +pointer from the +.Li struct sudo_conv_callback . +These functions should return 0 on success and \-1 on error. +On error, the conversation will end and the conversation function +will return a value of \-1. +The intended use is to allow the plugin to release resources, such as locks, +that should not be held indefinitely while suspended and then reacquire them +when the process is resumed. +Note that the functions are not actually invoked from within a signal handler. +.Pp +The +.Em msg_type +must be set to one of the following values: +.Bl -tag -width 4n +.It SUDO_CONV_PROMPT_ECHO_OFF +Prompt the user for input with echo disabled; +this is generally used for passwords. +The reply will be stored in the +.Em replies +array, and it will never be +.Dv NULL . +.It SUDO_CONV_PROMPT_ECHO_ON +Prompt the user for input with echo enabled. +The reply will be stored in the +.Em replies +array, and it will never be +.Dv NULL . +.It SUDO_CONV_ERROR_MSG +Display an error message. +The message is written to the standard error unless the +.Dv SUDO_CONV_PREFER_TTY +flag is set, in which case it is written to the user's terminal if possible. +.It SUDO_CONV_INFO_MSG +Display a message. +The message is written to the standard output unless the +.Dv SUDO_CONV_PREFER_TTY +flag is set, in which case it is written to the user's terminal if possible. +.It SUDO_CONV_PROMPT_MASK +Prompt the user for input but echo an asterisk character for each +character read. +The reply will be stored in the +.Em replies +array, and it will never be +.Dv NULL . +This can be used to provide visual feedback to the user while reading +sensitive information that should not be displayed. +.El +.Pp +In addition to the above values, the following flag bits may also be set: +.Bl -tag -width 4n +.It SUDO_CONV_PROMPT_ECHO_OK +Allow input to be read when echo cannot be disabled +when the message type is +.Dv SUDO_CONV_PROMPT_ECHO_OFF +or +.Dv SUDO_CONV_PROMPT_MASK . +By default, +.Nm sudo +will refuse to read input if the echo cannot be disabled for those +message types. +.It SUDO_CONV_PREFER_TTY +When displaying a message via +.Dv SUDO_CONV_ERROR_MSG +or +.Dv SUDO_CONV_INFO_MSG , +try to write the message to the user's terminal. +If the terminal is unavailable, the standard error or standard output +will be used, depending upon whether +The user's terminal is always used when possible for input, +this flag is only used for output. +.Dv SUDO_CONV_ERROR_MSG +or +.Dv SUDO_CONV_INFO_MSG +was used. +.El +.Pp +The +.Em timeout +in seconds until the prompt will wait for no more input. +A zero value implies an infinite timeout. +.Pp +The plugin is responsible for freeing the reply buffer located in each +.Li struct sudo_conv_reply , +if it is not +.Dv NULL . +.Dv SUDO_CONV_REPL_MAX +represents the maximum length of the reply buffer (not including +the trailing NUL character). +In practical terms, this is the longest password +.Nm sudo +will support. +.Pp +The +.Fn printf Ns -style +function uses the same underlying mechanism as the +.Fn conversation +function but only supports +.Dv SUDO_CONV_INFO_MSG +and +.Dv SUDO_CONV_ERROR_MSG +for the +.Em msg_type +parameter. +It can be more convenient than using the +.Fn conversation +function if no user reply is needed and supports standard +.Fn printf +escape sequences. +.Pp +See the sample plugin for an example of the +.Fn conversation +function usage. +.Ss Plugin invocation order +As of +.Nm sudo +1.9.0, the plugin +.Fn open +and +.Fn close +functions are called in the +following order: +.Bl -enum +.It +audit open +.It +policy open +.It +approval open +.It +approval close +.It +I/O log open +.It +command runs +.It +command exits +.It +I/O log close +.It +policy close +.It +audit close +.It +sudo exits +.El +.Pp +Prior to +.Nm sudo +1.9.0, the I/O log +.Fn close +function was called +.Em after +the policy +.Fn close +function. +.Ss Sudoers group plugin API +The +.Nm sudoers +plugin supports its own plugin interface to allow non-Unix +group lookups. +This can be used to query a group source other than the standard Unix +group database. +Two sample group plugins are bundled with +.Nm sudo , +.Em group_file +and +.Em system_group , +are detailed in +.Xr sudoers @mansectform@ . +Third party group plugins include a QAS AD plugin available from Quest Software. +.Pp +A group plugin must declare and populate a +.Li sudoers_group_plugin +struct in the global scope. +This structure contains pointers to the functions that implement plugin +initialization, cleanup and group lookup. +.Bd -literal +struct sudoers_group_plugin { + unsigned int version; + int (*init)(int version, sudo_printf_t sudo_printf, + char *const argv[]); + void (*cleanup)(void); + int (*query)(const char *user, const char *group, + const struct passwd *pwd); +}; +.Ed +.Pp +The +.Li sudoers_group_plugin +struct has the following fields: +.Bl -tag -width 4n +.It version +The +.Li version +field should be set to GROUP_API_VERSION. +.Pp +This allows +.Nm sudoers +to determine the API version the group plugin +was built against. +.It init +.Bd -literal -compact +int (*init)(int version, sudo_printf_t plugin_printf, + char *const argv[]); +.Ed +.Pp +The +.Fn init +function is called after +.Em sudoers +has been parsed but +before any policy checks. +It returns 1 on success, 0 on failure (or if the plugin is not configured), +and \-1 if a error occurred. +If an error occurs, the plugin may call the +.Fn plugin_printf +function with +.Dv SUDO_CONF_ERROR_MSG +to present additional error information to the user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It version +The version passed in by +.Nm sudoers +allows the plugin to determine the +major and minor version number of the group plugin API supported by +.Nm sudoers . +.It plugin_printf +A pointer to a +.Fn printf Ns -style +function that may be used to display informational or error message to the user. +Returns the number of characters printed on success and \-1 on failure. +.It argv +A +.Dv NULL Ns -terminated +array of arguments generated from the +.Em group_plugin +option in +.Em sudoers . +If no arguments were given, +.Em argv +will be +.Dv NULL . +.El +.It cleanup +.Bd -literal -compact +void (*cleanup)(); +.Ed +.Pp +The +.Fn cleanup +function is called when +.Nm sudoers +has finished its +group checks. +The plugin should free any memory it has allocated and close open file handles. +.It query +.Bd -literal -compact +int (*query)(const char *user, const char *group, + const struct passwd *pwd); +.Ed +.Pp +The +.Fn query +function is used to ask the group plugin whether +.Em user +is a member of +.Em group . +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It user +The name of the user being looked up in the external group database. +.It group +The name of the group being queried. +.It pwd +The password database entry for +.Em user , +if any. +If +.Em user +is not +present in the password database, +.Em pwd +will be +.Dv NULL . +.El +.El +.Pp +.Em Group API Version Macros +.Bd -literal +/* Sudoers group plugin version major/minor */ +#define GROUP_API_VERSION_MAJOR 1 +#define GROUP_API_VERSION_MINOR 0 +#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e + GROUP_API_VERSION_MINOR) +.Ed +For getters and setters see the +.Sx Policy plugin API . +.Sh PLUGIN API CHANGELOG +The following revisions have been made to the Sudo Plugin API. +.Bl -tag -width 4n +.It Version 1.0 +Initial API version. +.It Version 1.1 (sudo 1.8.0) +The I/O logging plugin's +.Fn open +function was modified to take the +.Li command_info +list as an argument. +.It Version 1.2 (sudo 1.8.5) +The Policy and I/O logging plugins' +.Fn open +functions are now passed +a list of plugin parameters if any are specified in +.Xr sudo.conf @mansectform@ . +.Pp +A simple hooks API has been introduced to allow plugins to hook in to the +system's environment handling functions. +.Pp +The +.Li init_session +Policy plugin function is now passed a pointer +to the user environment which can be updated as needed. +This can be used to merge in environment variables stored in the PAM +handle before a command is run. +.It Version 1.3 (sudo 1.8.7) +Support for the +.Em exec_background +entry has been added to the +.Li command_info +list. +.Pp +The +.Em max_groups +and +.Em plugin_dir +entries were added to the +.Li settings +list. +.Pp +The +.Fn version +and +.Fn close +functions are now optional. +Previously, a missing +.Fn version +or +.Fn close +function would result in a crash. +If no policy plugin +.Fn close +function is defined, a default +.Fn close +function will be provided by the +.Nm sudo +front end that displays a warning if the command could not be +executed. +.Pp +The +.Nm sudo +front end now installs default signal handlers to trap common signals +while the plugin functions are run. +.It Version 1.4 (sudo 1.8.8) +The +.Em remote_host +entry was added to the +.Li settings +list. +.It Version 1.5 (sudo 1.8.9) +The +.Em preserve_fds +entry was added to the +.Li command_info +list. +.It Version 1.6 (sudo 1.8.11) +The behavior when an I/O logging plugin returns an error +.Pq \-1 +has changed. +Previously, the +.Nm sudo +front end took no action when the +.Fn log_ttyin , +.Fn log_ttyout , +.Fn log_stdin , +.Fn log_stdout , +or +.Fn log_stderr +function returned an error. +.Pp +The behavior when an I/O logging plugin returns 0 has changed. +Previously, output from the command would be displayed to the +terminal even if an output logging function returned 0. +.It Version 1.7 (sudo 1.8.12) +The +.Em plugin_path +entry was added to the +.Li settings +list. +.Pp +The +.Em debug_flags +entry now starts with a debug file path name and may occur multiple +times if there are multiple plugin-specific Debug lines in the +.Xr sudo.conf @mansectform@ file. +.It Version 1.8 (sudo 1.8.15) +The +.Em sudoedit_checkdir +and +.Em sudoedit_follow +entries were added to the +.Li command_info +list. +The default value of +.Em sudoedit_checkdir +was changed to true in sudo 1.8.16. +.Pp +The sudo +.Em conversation +function now takes a pointer to a +.Li struct sudo_conv_callback +as its fourth argument. +The +.Li sudo_conv_t +definition has been updated to match. +The plugin must specify that it supports plugin API version 1.8 or higher +to receive a conversation function pointer that supports this argument. +.It Version 1.9 (sudo 1.8.16) +The +.Em execfd +entry was added to the +.Li command_info +list. +.It Version 1.10 (sudo 1.8.19) +The +.Em umask +entry was added to the +.Li user_info +list. +The +.Em iolog_group , +.Em iolog_mode , +and +.Em iolog_user +entries were added to the +.Li command_info +list. +.It Version 1.11 (sudo 1.8.20) +The +.Em timeout +entry was added to the +.Li settings +list. +.It Version 1.12 (sudo 1.8.21) +The +.Li change_winsize +field was added to the io_plugin struct. +.It Version 1.13 (sudo 1.8.26) +The +.Li log_suspend +field was added to the io_plugin struct. +.It Version 1.14 (sudo 1.8.29) +The +.Em umask_override +entry was added to the +.Li command_info +list. +.It Version 1.15 (sudo 1.9.0) +The +.Em cwd_optional +entry was added to the +.Li command_info +list. +.Pp +The +.Em event_alloc +field was added to the policy_plugin and io_plugin structs. +.Pp +The +.Fa errstr +argument was added to the policy and I/O plugin functions +which the plugin function can use to return an error string. +This string may be used by the audit plugin to report failure or +error conditions set by the other plugins. +.Pp +The +.Fn close +function is now is called regardless of whether or not a command +was actually executed. +This makes it possible for plugins to perform cleanup even when a +command was not run. +.Pp +.Dv SUDO_CONV_REPL_MAX +has increased from 255 to 1023 bytes. +.Pp +Support for audit and approval plugins was added. +.It Version 1.16 (sudo 1.9.3) +Initial resource limit values were added to the +.Li user_info +list. +.Pp +The +.Em cmnd_chroot +and +.Em cmnd_cwd +enties were added to the +.Li settings +list. +.It Version 1.17 (sudo 1.9.4) +The +.Em event_alloc +field was added to the audit_plugin and approval_plugin structs. +.El +.Sh SEE ALSO +.Xr sudo.conf @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_plugin_python.man.in b/doc/sudo_plugin_python.man.in new file mode 100644 index 0000000..919ecd9 --- /dev/null +++ b/doc/sudo_plugin_python.man.in @@ -0,0 +1,1890 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 Robert Manner <robert.manner@oneidentity.com> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.TH "SUDO_PLUGIN_PYTHON" "5" "February 19, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_plugin_python\fR +\- Sudo Plugin API (Python) +.SH "DESCRIPTION" +Starting with version 1.9, +\fBsudo\fR +plugins can be written in python. +The API closely follows the C +\fBsudo\fR +plugin API described by +sudo_plugin(@mansectform@). +.PP +The supported plugins types are: +.PP +.RS 4n +.PD 0 +.TP 3n +\fB\(bu\fR +Policy plugin +.TP 3n +\fB\(bu\fR +I/O plugin +.TP 3n +\fB\(bu\fR +Audit plugin +.TP 3n +\fB\(bu\fR +Approval plugin +.TP 3n +\fB\(bu\fR +Group provider plugin +.RE +.PD +.PP +Python plugin support needs to be explicitly enabled at build time +with the configure option +\(lq--enable-python\(rq. +Python version 3.0 or higher is required. +.SS "Sudo Python Plugin Base" +A plugin written in Python should be a class in a python file that +inherits from +\fIsudo.Plugin\fR. +The +\fIsudo.Plugin\fR +base class has no real purpose other than to identify this class as a plugin. +.PP +The only implemented method is a constructor, which stores the +keyword arguments it receives as fields (member variables) in the object. +This is intended as a convenience to allow you to avoid writing the +constructor yourself. +.PP +For example: +.nf +.sp +.RS 6n +import sudo + +class MySudoPlugin(sudo.Plugin): + # example constructor (optional) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # example destructor (optional) + def __del__(self): + pass +.RE +.fi +.PP +Both the constructor and destructor are optional and can be omitted. +.PP +The customized Plugin class should define a few plugin-specific methods. +When the plugin loads, +\fBsudo\fR +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 +result code, as documented in +sudo_plugin(@mansctsu@), +that indicates whether or not the method was successful. +The Python sudo module defines the following constants to improve readability: +.RS 4n +.TS +l l. +.PP +\fBDefine\fR \fBValue\fR +.PP +\fRsudo.RC.OK\fR 1 +.PP +\fRsudo.RC.ACCEPT\fR 1 +.PP +\fRsudo.RC.REJECT\fR 0 +.PP +\fRsudo.RC.ERROR\fR -1 +.PP +\fRsudo.RC.USAGE_ERROR\fR -2 +.TE +.RE +.PP +If a function returns +\fINone\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 +\fRsudo.RC.ERROR\fR. +If that is not acceptable, you must catch the exception and handle it yourself. +.PP +Instead of just returning +\fRsudo.RC.ERROR\fR +or +\fRsudo.RC.REJECT\fR +result code the plugin can also provide a message describing the problem. +This can be done by raising one of the special exceptions: +.nf +.sp +.RS 6n +raise sudo.PluginError("Message") +raise sudo.PluginReject("Message") +.RE +.fi +.PP +This added message will be used by the audit plugins. +Both exceptions inherit from +\fRsudo.PluginException\fR +.SS "Python Plugin Loader" +Running the Python interpreter and bridging between C and Python is +handled by the +\fBsudo\fR +plugin +\fRpython_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 +plugin it is loading as arguments. +.PP +Example usage in +sudo.conf(@mansectform@): +.nf +.sp +.RS 6n +Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class> +.RE +.fi +.PP +Example group provider plugin usage in the +\fIsudoers\fR +file: +.nf +.sp +.RS 6n +Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>" +.RE +.fi +.PP +The plugin arguments are as follows: +.TP 6n +ModulePath +The path of a python file which contains the class of the sudo Python plugin. +It must be either an absolute path or a path relative to the sudo Python plugin +directory: "@plugindir@/python". +.TP 6n +ClassName +(Optional.) The name of the class implementing the sudo Python plugin. +If not supplied, the one and only sudo.Plugin that is present in the module +will be used. +If there are multiple such plugins in the module (or none), it +will result in an error. +.SS "Policy plugin API" +Policy plugins must be registered in +sudo.conf(@mansectform@). +For example: +.nf +.sp +.RS 6n +Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class> +.RE +.fi +.PP +Currently, only a single policy plugin may be specified in +sudo.conf(@mansectform@). +.PP +A policy plugin may have the following member functions: +.TP 6n +\fBconstructor\fR +.nf +.RS 6n +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], + plugin_options: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.sp +The constructor matches the +\fBopen\fR() +function in the C sudo plugin API. +.sp +The function arguments are as follows: +.TP 6n +\fIuser_env\fR +The user's environment as a tuple of strings in +\(lqkey=value\(rq +format. +.TP 6n +\fIsettings\fR +A tuple of user-supplied +\fIsudo\fR +settings in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIversion\fR +The version of the Python Policy Plugin API. +.TP 6n +\fIuser_info\fR +A tuple of information about the user running the command in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIplugin_options\fR +The plugin options passed as arguments in the +sudo.conf(@mansectform@) +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +\(lqkey=value\(rq +format. +.PP +The +\fBsudo.options_as_dict\fR() +convenience function can be used to convert +\(lqkey=value\(rq +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the policy plugin +\fBopen\fR() +documentation in +sudo_plugin(@mansectform@). +.RE +.TP 6n +\fBcheck_policy\fR +.nf +.RS 6n +check_policy(self, argv: Tuple[str, ...], env_add: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +The +\fBcheck_policy\fR() +function is called by +\fBsudo\fR +to determine whether the user is allowed to run the specified command. +Implementing this function is mandatory for a policy plugin. +.sp +The function arguments are as follows: +.TP 6n +\fIargv\fR +A tuple describing the command the user wishes to run. +.TP 6n +\fIenv_add\fR +Additional environment variables specified by the user on the command line in +the form of a tuple of +\(lqkey=value\(rq +pairs. +The +\fBsudo.options_as_dict\fR() +convenience function can be used to convert them to a dictionary. +.PP +This function should return a result code or a tuple in the following format: +.nf +.sp +.RS 12n +return (rc, command_info_out, argv_out, user_env_out) +.RE +.fi +.sp +The tuple values are as follows: +.TP 6n +\fIrc\fR +The result of the policy check, one of the +\fRsudo.RC.*\fR +constants. +\fRsudo.RC.ACCEPT\fR +if the command is allowed, +\fRsudo.RC.REJECT\fR +if not allowed, +\fRsudo.RC.ERROR\fR +for a general error, or +\fRsudo.RC.USAGE_ERROR\fR +for a usage error. +.TP 6n +\fIcommand_info_out\fR +Optional (only required when the command is accepted). +Information about the command being run in the form of +\(lqkey=value\(rq +strings. +.sp +To accept a command, at the very minimum the plugin must set in the +\fIcommand\fR, +\fIrunas_uid\fR +and +\fIrunas_gid\fR +keys. +.sp +For a list of recognized keys and supported values, +see the +\fBcheck_policy\fR() +documentation in +sudo_plugin(@mansectform@). +.TP 6n +\fIargv_out\fR +Optional (only required when the command is accepted). +The arguments to pass to the +execve(2) +system call when executing the command. +.TP 6n +\fIuser_env_out\fR +Optional (only required when the command is accepted). +The environment to use when executing the command in the form of a +tuple of strings in +\(lqkey=value\(rq +format. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBinit_session\fR +.nf +.RS 6n +init_session(self, user_pwd: Tuple, user_env: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +Perform session setup (optional). +The +\fBinit_session\fR() +function is called before +\fBsudo\fR +sets up the +execution environment for the command before any uid or gid changes. +.sp +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 +if the user is not present in the password database. +.sp +Example conversion: +.nf +.RS 12n +user_pwd = pwd.struct_passwd(user_pwd) if user_pwd else None +.RE +.fi +.TP 6n +\fIuser_env\fR +The environment the command will run in. +This is a tuple of strings in +\(lqkey=value\(rq +format. +.PP +This function should return a result code or a tuple in the following format: +.nf +.sp +.RS 10n +return (rc, user_env_out) +.RE +.fi +.sp +The tuple values are as follows: +.TP 6n +\fIrc\fR +The result of the session init, one of the +\fRsudo.RC.*\fR +constants. +\fRsudo.RC.OK\fR +on success, 0 on failure, or +\fRsudo.RC.ERROR\fR +if an error occurred. +.TP 6n +\fIuser_env_out\fR +Optional. +If the +\fBinit_session\fR() +function needs to modify the user environment, it can return the new +environment in +\fIuser_env_out\fR. +If this is omitted, no changes will be made to +\fIuser_env\fR. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBlist\fR +.nf +.RS 6n +list(self, argv: Tuple[str, ...], is_verbose: int, user: str) +.RE +.fi +.RS 6n +.sp +List available privileges for the invoking user. +.sp +The function arguments are as follows: +.TP 6n +\fIargv\fR +If not set to +\fINone\fR, +an argument vector describing a command the user wishes to check +against the policy. +.TP 6n +\fIis_verbose\fR +Flag indicating whether to list in verbose mode or not. +.TP 6n +\fIuser\fR +The name of a different user to list privileges for if the policy allows it. +If +\fINone\fR, +the plugin should list the privileges of the invoking user. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBvalidate\fR +.nf +.RS 6n +validate(self) +.RE +.fi +.RS 6n +.sp +For policy plugins that cache authentication credentials, this function is used to validate and cache the credentials (optional). +.RE +.TP 6n +\fBinvalidate\fR +.nf +.RS 6n +invalidate(self, remove: int) +.RE +.fi +.RS 6n +.sp +For policy plugins that cache authentication credentials, this function is used to invalidate the credentials (optional). +.sp +The function arguments are as follows: +.TP 6n +\fIremove\fR +If this flag is set, the plugin may remove the credentials instead of simply +invalidating them. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBshow_version\fR +.nf +.RS 6n +show_version(self, is_verbose: int) +.RE +.fi +.RS 6n +.sp +Display the plugin version information to the user. +The +\fBsudo.log_info\fR() +function should be used. +.sp +The function arguments are as follows: +.TP 6n +\fIis_verbose\fR +A flag to indicate displaying more verbose information. +Currently this is 1 if +\(oqsudo -V\(cq +is run as the root user. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBclose\fR +.br +.nf +.RS 6n +close(self, exit_status: int, error: int) +.RE +.fi +.RS 6n +.sp +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 +\fBsudo\fR +attempts to execute the command. +.sp +The function arguments are as follows: +.TP 6n +\fIexit_status\fR +The exit status of the command if was executed, otherwise -1. +.TP 6n +\fIerror\fR +.br +If the command could not be executed, this is set to the value of +errno set by the +execve(2) +system call, otherwise 0. +.PD 0 +.PP +.RE +.PD +.SS "Policy plugin example" +Sudo ships with an example Python policy plugin. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 0n +Plugin python_policy python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_policy_plugin.py \e + ClassName=SudoPolicyPlugin +.RE +.fi +.PP +Be aware, however, that you cannot enable the Python policy plugin +in addition to another policy plugin, such as +sudoers(@mansectform@). +.SS "I/O plugin API" +I/O plugins must be registered in +sudo.conf(@mansectform@). +For example: +.nf +.sp +.RS 6n +Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class> +.RE +.fi +.PP +Sudo supports loading multiple I/O plugins. +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 +.nf +.RS 6n +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], + plugin_options: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.sp +The constructor matches the +\fBopen\fR() +function in the C sudo plugin API. +.sp +The function arguments are as follows: +.TP 6n +\fIuser_env\fR +The user's environment as a tuple of strings in +\(lqkey=value\(rq +format. +.TP 6n +\fIsettings\fR +A tuple of user-supplied +\fIsudo\fR +settings in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIversion\fR +The version of the Python I/O Plugin API. +.TP 6n +\fIuser_info\fR +A tuple of information about the user running the command in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIplugin_options\fR +The plugin options passed as arguments in the +sudo.conf(@mansectform@) +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +\(lqkey=value\(rq +format. +.PP +The +\fBsudo.options_as_dict\fR() +convenience function can be used to convert +\(lqkey=value\(rq +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the I/O plugin +\fBopen\fR() +documentation in +sudo_plugin(@mansectform@). +.RE +.TP 6n +\fBopen\fR +.nf +.RS 6n +open(self, argv: Tuple[str, ...], + command_info: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +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: +.sp +.RS 10n +.PD 0 +.TP 3n +\fB\(bu\fR +It only gets called before the user would execute some command +(and not for a version query for example). +.TP 3n +\fB\(bu\fR +Other arguments of the C API +\fBopen\fR() +function are received through the constructor. +.RE +.sp +The function arguments are as follows: +.PD +.TP 6n +\fIargv\fR +A tuple of the arguments describing the command the user wishes to run. +.TP 6n +\fIcommand_info\fR +Information about the command being run in the form of +\(lqkey=value\(rq +strings. +.PP +The +\fBsudo.options_as_dict\fR() +convenience function can be used to convert +\(lqkey=value\(rq +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the I/O plugin +\fBopen\fR() +documentation in +sudo_plugin(@mansectform@). +.sp +The +\fBopen\fR() +function should return a result code, one of the +\fRsudo.RC.*\fR +constants. +If the function returns +\fRsudo.RC.REJECT\fR, +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 +.nf +.RS 6n +log_ttyin(self, buf: str) -> int +log_ttyout(self, buf: str) -> int +log_stdin(self, buf: str) -> int +log_stdout(self, buf: str) -> int +log_stderr(self, buf: str) -> int +.RE +.fi +.RS 6n +.sp +Receive the user input or output of the terminal device and +application standard input / output / error. +See the matching calls in +sudo_plugin(@mansectform@). +.sp +The function arguments are as follows: +.TP 6n +\fIbuf\fR +The input (or output) buffer in the form of a string. +.PP +The function should return a result code, one of the +\fRsudo.RC.*\fR +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. +Other I/O logging plugins will still receive any remaining +input or output that has not yet been processed. +.sp +If an input logging function rejects the data by returning +\fRsudo.RC.REJECT\fR, +the command will be terminated and the data will not be passed to the +command, though it will still be sent to any other I/O logging plugins. +If an output logging function rejects the data by returning +\fRsudo.RC.REJECT\fR, +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 +.nf +.RS 6n +change_winsize(self, line: int, cols: int) -> int +.RE +.fi +.RS 6n +.sp +Called whenever the window size of the terminal changes. +The function arguments are as follows: +.TP 6n +\fIline\fR +The number of lines of the terminal. +.TP 6n +\fIcols\fR +The number of columns of the terminal. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBlog_suspend\fR +.nf +.RS 6n +log_suspend(self, signo: int) -> int +.RE +.fi +.RS 6n +Called whenever a command is suspended or resumed. +.sp +The function arguments are as follows: +.TP 6n +\fIsigno\fR +.br +The number of the signal that caused the command to be suspended or +\fRSIGCONT\fR +if the command was resumed. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBshow_version\fR +.nf +.RS 6n +show_version(self, is_verbose: int) +.RE +.fi +.RS 6n +Display the plugin version information to the user. +The +\fBsudo.log_info\fR() +function should be used. +.sp +The function arguments are as follows: +.TP 6n +\fIis_verbose\fR +A flag to indicate displaying more verbose information. +Currently this is 1 if +\(oqsudo -V\(cq +is run as the root user. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBclose\fR +.br +.nf +.RS 6n +close(self, exit_status: int, error: int) -> None +.RE +.fi +.RS 6n +Called when a command execution finished. +.sp +Works the same as the +\fBclose\fR() +function in the C sudo plugin API, except that it only gets called if +\fBsudo\fR +attempts to execute the command. +.sp +The function arguments are as follows: +.TP 6n +\fIexit_status\fR +The exit status of the command if was executed, otherwise -1. +.TP 6n +\fIerror\fR +.br +If the command could not be executed, this is set to the value of +errno set by the +execve(2) +system call, otherwise 0. +.PD 0 +.PP +.RE +.PD +.SS "I/O plugin example" +Sudo ships a Python I/O plugin example. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 6n +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_io_plugin.py \e + ClassName=SudoIOPlugin +.RE +.fi +.SS "Audit plugin API" +Audit plugins must be registered in +sudo.conf(@mansectform@). +For example: +.nf +.sp +.RS 6n +Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class> +.RE +.fi +.PP +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): +.TP 6n +\fBconstructor\fR +.nf +.RS 6n +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +The default constructor will set the keyword arguments it receives +as member variables in the object. +.sp +The constructor matches the +\fBopen\fR() +function in the C sudo plugin API. +.sp +The function arguments are as follows: +.TP 6n +\fIuser_env\fR +The user's environment as a tuple of strings in +\(lqkey=value\(rq +format. +.TP 6n +\fIsettings\fR +A tuple of user-supplied +\fIsudo\fR +settings in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIversion\fR +The version of the Python Audit Plugin API. +.TP 6n +\fIuser_info\fR +A tuple of information about the user running the command in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIplugin_options\fR +The plugin options passed as arguments in the +sudo.conf(@mansectform@) +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +\(lqkey=value\(rq +format. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBopen\fR +.nf +.RS 6n +open(self, submit_optind: int, + submit_argv: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +The function arguments are as follows: +.TP 6n +\fIsubmit_optind\fR +The index into +\fIsubmit_argv\fR +that corresponds to the first entry that is not a command line option. +.TP 6n +\fIsubmit_argv\fR +The argument vector sudo was invoked with, including all command line options. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBclose\fR +.br +.nf +.RS 6n +close(self, status_type: int, status: int) -> None +.RE +.fi +.RS 6n +.sp +Called when sudo is finished, shortly before it exits. +.sp +The function arguments are as follows: +.TP 6n +\fIstatus_type\fR +The type of status being passed. +One of the sudo.EXIT_REASON.* constants. +.TP 6n +\fIstatus\fR +Depending on the value of +\fIstatus_type\fR, +this value is either +ignored, the command's exit status as returned by the +wait(2) +system call, the value of +\fRerrno\fR +set by the +execve(2) +system call, or the value of +\fRerrno\fR +resulting from an error in the +\fBsudo\fR +front end. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBshow_version\fR +.nf +.RS 6n +show_version(self, is_verbose: int) -> int +.RE +.fi +.RS 6n +.sp +Display the plugin version information to the user. +The +\fBsudo.log_info\fR() +function should be used. +.sp +The function arguments are as follows: +.TP 6n +\fIis_verbose\fR +A flag to indicate displaying more verbose information. +Currently this is 1 if +\(oqsudo -V\(cq +is run as the root user. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBaccept\fR +.nf +.RS 6n +accept(self, plugin_name: str, plugin_type: int, command_info: Tuple[str, ...], + run_argv: Tuple[str, ...], run_envp: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +This function is called when a command or action is accepted by a policy +or approval plugin. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that accepted the command or +\(lqsudo\(rq +for the +\fBsudo\fR +front-end. +.TP 6n +plugin_type +The type of plugin that accepted the command, currently either +\fRsudo.PLUGIN_TYPE.POLICY\fR, +\fRsudo.PLUGIN_TYPE.APPROVAL\fR +or +\fRsudo.PLUGIN_TYPE.SUDO\fR. +The +\fBaccept\fR() +function is called multiple times--once for each policy or approval +plugin that succeeds and once for the sudo front-end. +When called on behalf of the sudo front-end, +\fIcommand_info\fR +may include information from an I/O logging plugin as well. +.sp +Typically, an audit plugin is interested in either the accept status from +the +\fBsudo\fR +front-end or from the various policy and approval plugins, but not both. +It is possible for the policy plugin to accept a command that is +later rejected by an approval plugin, in which case the audit +plugin's +\fBaccept\fR() +and +\fBreject\fR() +functions will +\fIboth\fR +be called. +.TP 6n +command_info +A vector of information describing the command being run. +See the +sudo_plugin(@mansectform@) +manual for possible values. +.TP 6n +run_argv +Argument vector describing a command that will be run. +.TP 6n +run_envp +The environment the command will be run with. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBreject\fR +.nf +.RS 6n +reject(self, plugin_name: str, plugin_type: int, audit_msg: str, + command_info: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +This function is called when a command or action is rejected by the policy +plugin. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that rejected the command. +.TP 6n +plugin_type +The type of plugin that rejected the command, currently either +\fRsudo.PLUGIN_TYPE.POLICY\fR, +\fRsudo.PLUGIN_TYPE.APPROVAL\fR +or +\fRsudo.PLUGIN_TYPE.IO\fR. +.sp +Unlike the +\fBaccept\fR() +function, the +\fBreject\fR() +function is not called on behalf of the +\fBsudo\fR +front-end. +.TP 6n +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 +.TP 6n +command_info +A vector of information describing the rejected command. +See the +sudo_plugin(@mansectform@) +manual for possible values. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBerror\fR +.br +.nf +.RS 6n +error(self, plugin_name: str, plugin_type: int, audit_msg: str, + command_info: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +This function is called when a plugin or the +\fBsudo\fR +front-end returns an error. +The function arguments are as follows: +.TP 6n +plugin_name +The name of the plugin that generated the error or +\(lqsudo\(rq +for the +\fBsudo\fR +front-end. +.TP 6n +plugin_type +The type of plugin that generated the error, or +\fRSUDO_FRONT_END\fR +for the +\fBsudo\fR +front-end. +.TP 6n +audit_msg +An optional string describing the plugin error. +If the plugin did not provide a description, it will be +\fINone\fR +.TP 6n +command_info +A vector of information describing the command. +See the +sudo_plugin(@mansectform@) +manual for possible values. +.PD 0 +.PP +.RE +.PD +.SS "Audit plugin example" +Sudo ships a Python Audit plugin example. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 6n +Plugin python_audit python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_audit_plugin.py \e + ClassName=SudoAuditPlugin +.RE +.fi +.PP +It will log the plugin accept / reject / error results to the output. +.SS "Approval plugin API" +Approval plugins must be registered in +sudo.conf(@mansectform@). +For example: +.nf +.sp +.RS 6n +Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class> +.RE +.fi +.PP +Sudo supports loading multiple approval plugins. +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 +.nf +.RS 6n +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...], + submit_optind: int, submit_argv: Tuple[str, ...]) +.RE +.fi +.RS 6n +.sp +Optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.sp +The constructor matches the +\fBopen\fR() +function in the C sudo plugin API. +.sp +The function arguments are as follows: +.TP 6n +\fIuser_env\fR +The user's environment as a tuple of strings in +\(lqkey=value\(rq +format. +.TP 6n +\fIsettings\fR +A tuple of user-supplied +\fIsudo\fR +settings in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIversion\fR +The version of the Python Approval Plugin API. +.TP 6n +\fIuser_info\fR +A tuple of information about the user running the command in the form of +\(lqkey=value\(rq +strings. +.TP 6n +\fIplugin_options\fR +The plugin options passed as arguments in the +sudo.conf(@mansectform@) +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +\(lqkey=value\(rq +format. +.TP 6n +\fIsubmit_optind\fR +The index into +\fIsubmit_argv\fR +that corresponds to the first entry that is not a command line option. +.TP 6n +\fIsubmit_argv\fR +The argument vector sudo was invoked with, including all command line options. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBshow_version\fR +.nf +.RS 6n +show_version(self, is_verbose: int) -> int +.RE +.fi +.RS 6n +.sp +Display the version. (Same as for all the other plugins.) +.RE +.TP 6n +\fBcheck\fR +.br +.nf +.RS 6n +check(self, command_info: Tuple[str, ...], run_argv: Tuple[str, ...], + run_env: Tuple[str, ...]) -> int +.RE +.fi +.RS 6n +.sp +This function is called after policy plugin's check_policy has succeeded. +It can reject execution of the command by returning sudo.RC.REJECT or +raising the special exception: +.nf +.sp +.RS 12n +raise sudo.PluginReject("some message") +.RE +.fi +.sp +with the message describing the problem. +In the latter case, the audit plugins will get the description. +.sp +The function arguments are as follows: +.TP 6n +command_info +A vector of information describing the command that will run. +See the +sudo_plugin(@mansectform@) +manual for possible values. +.TP 6n +run_argv +Argument vector describing a command that will be run. +.TP 6n +run_env +The environment the command will be run with. +.PD 0 +.PP +.RE +.PD +.SS "Approval plugin example" +Sudo ships a Python Approval plugin example. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 6n +Plugin python_approval python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_approval_plugin.py \e + ClassName=BusinessHoursApprovalPlugin +.RE +.fi +.PP +It will only allow execution of commands in the "business hours" (from Monday +to Friday between 8:00 and 17:59:59). +.SS "Sudoers group provider plugin API" +A group provider plugin is registered in the +sudoers(@mansectform@) +file. +For example: +.nf +.sp +.RS 6n +Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>" +.RE +.fi +.PP +Currently, only a single group plugin can be registered in +\fIsudoers\fR. +.PP +A group provider plugin may have the following member functions: +.TP 6n +\fBconstructor\fR +.nf +.RS 6n +__init__(self, args: Tuple[str, ...], version: str) +.RE +.fi +.RS 6n +.sp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.sp +The function arguments are as follows: +.TP 6n +\fIargs\fR +The plugin options passed as arguments in the +\fIsudoers\fR +file plugin registration. +All the arguments are free form strings (not necessarily in +\(lqkey=value\(rq +format). +.TP 6n +\fIversion\fR +The version of the Python Group Plugin API. +.PD 0 +.PP +.RE +.PD +.TP 6n +\fBquery\fR +.br +.nf +.RS 6n +query(self, user: str, group: str, user_pwd: Tuple) +.RE +.fi +.RS 6n +.sp +The +\fBquery\fR() +function is used to ask the group plugin whether +\fIuser\fR +is a member of +\fIgroup\fR. +This method is required. +.RE +.PP +The function arguments are as follows: +.TP 6n +\fIuser\fR +The name of the user being looked up in the external group database. +.TP 6n +\fIgroup\fR +.br +The name of the group being queried. +.TP 6n +\fIuser_pwd\fR +The password database entry for the user, if any. +If +\fIuser\fR +is not present in the password database, +\fIuser_pwd\fR +will be +\fRNULL\fR. +.SS "Group plugin example" +Sudo ships a Python group plugin example. +To try it, register it in the +\fIsudoers\fR +file by adding the following lines: +.nf +.sp +.RS 6n +Defaults group_plugin="python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_group_plugin.py \e + ClassName=SudoGroupPlugin" +.RE +.fi +.PP +The example plugin will tell +\fBsudo\fR +that the user +\fItest\fR +is part of the non-unix group +\fImygroup\fR. +If you add a rule that uses this group, it will affect the +\fItest\fR +user. +For example: +.nf +.sp +.RS 6n +%:mygroup ALL=(ALL) NOPASSWD: ALL +.RE +.fi +.PP +Will allow user +\fItest\fR +to run +\fBsudo\fR +without a password. +.SS "Hook function API" +The hook function API is currently not supported for plugins +written in Python. +.SS "Conversation API" +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 +class. +This is the Python equivalent of the +\fBconversation\fR() +function in the C 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 +\fBsudo.ConvMessage\fR +class specifies how the user interaction should occur: +.nf +.sp +.RS 4n +sudo.ConvMessage(msg_type: int, msg: str, timeout: int) +.RE +.fi +.PP +\fBsudo.ConvMessage\fR +member variables: +.TP 6n +\fImsg_type\fR +Specifies the type of the conversation. +See the +\fRsudo.CONV.*\fR +constants below. +.TP 6n +\fImsg\fR +The message to display to the user. +The caller must include a trailing newline in +\fRmsg\fR +if one is to be displayed. +.TP 6n +\fItimeout\fR +Optional. +The maximum amount of time for the conversation in seconds. +If the timeout is exceeded, the +\fBsudo.conv\fR() +function will raise a +\fRsudo.ConversationInterrupted\fR +exception. +The default is to wait forever (no timeout). +.PP +To specify the message type, the following constants are available: +.PP +.RS 4n +.PD 0 +.TP 3n +\fB\(bu\fR +sudo.CONV.PROMPT_ECHO_OFF +.TP 3n +\fB\(bu\fR +sudo.CONV.PROMPT_ECHO_ON +.TP 3n +\fB\(bu\fR +sudo.CONV.ERROR_MSG +.TP 3n +\fB\(bu\fR +sudo.CONV.INFO_MSG +.TP 3n +\fB\(bu\fR +sudo.CONV.PROMPT_MASK +.TP 3n +\fB\(bu\fR +sudo.CONV.PROMPT_ECHO_OK +.TP 3n +\fB\(bu\fR +sudo.CONV.PREFER_TTY +.RE +.PD +.PP +See the +sudo_plugin(@mansectform@) +manual for a description of the message types. +.PP +The +\fBsudo.conv\fR() +function performs the actual user interaction: +.nf +.sp +.RS 4n +sudo.conv(message(s), on_suspend=suspend_function, + on_resume=resume_function) +.RE +.fi +.PP +The function arguments are as follows: +.TP 6n +\fImessage(s)\fR +One of more messages (of type +\fBsudo.ConvMessage\fR), +each describing a conversation. +At least one message is required. +.TP 6n +\fIon_suspend\fR +An optional callback function which gets called if the conversation +is suspended, for example by the user pressing control-Z. +The specified function must take a single argument which will be filled +with the number of the signal that caused the process to be suspended. +.TP 6n +\fIon_resume\fR +An optional callback function which gets called when the previously +suspended conversation is resumed. +The specified function must take a single argument which will be filled +with the number of the signal that caused the process to be suspended. +.PP +The +\fBsudo.conv\fR() +function can raise the following exceptions: +.TP 6n +\fBsudo.SudoException\fR +If the conversation fails, for example when the conversation function is not +available. +.TP 6n +\fBsudo.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" +Sudo ships with an example plugin demonstrating the Python conversation API. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 6n +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_conversation.py \e + ClassName=ReasonLoggerIOPlugin +.RE +.fi +.SS "Information / error display API" +.nf +.RS 0n +sudo.log_info(string(s), sep=" ", end="\en") +sudo.log_error(string(s), sep=" ", end="\en") +.RE +.fi +.PP +To display information to the user, the +\fBsudo.log_info\fR() +function can be used. +To display error messages, use +\fBsudo.log_error\fR(). +The syntax is similar to the Python +\fBprint\fR() +function. +.PP +The function arguments are as follows: +.TP 6n +\fIstring(s)\fR +One or more strings to display. +.TP 6n +\fIsep\fR +An optional string which will be used as the separator between the +specified strings. +The default is a space character, +(\(oq\ \(cq). +.TP 6n +\fIend\fR +An optional string which will be displayed at the end of the message. +The default is a new line character +(\(oq\en\(cq). +.SS "Debug API" +Debug messages are not visible to the user and are only logged debugging +is explicitly enabled in +sudo.conf(@mansectform@). +Python plugins can use the +\fBsudo.debug\fR() +function to make use of +\fBsudo\fR's +debug system. +.PP +\fIEnabling debugging in sudo.conf\fR +.PP +To enable debug messages, add a +\fRDebug\fR +line to +sudo.conf(@mansectform@) +with the program set to +\fIpython_plugin.so\fR. +For example, to store debug output in +\fI/var/log/sudo_python_debug\fR, +use a line like the following: +.nf +.sp +.RS 6n +Debug python_plugin.so /var/log/sudo_python_debug \e + plugin@trace,c_calls@trace +.RE +.fi +.PP +The debug options are in the form of multiple +\(lqsubsystem@level\(rq +strings, separated by commas +(\(oq\&,\(cq). +For example to just see the debug output of +\fBsudo.debug\fR() +calls, use: +.nf +.sp +.RS 6n +Debug python_plugin.so /var/log/sudo_python_debug plugin@trace +.RE +.fi +.PP +See +sudo_conf(@mansectform@) +for more details. +.PP +The most interesting subsystems for Python plugin development are: +.TP 6n +\fIplugin\fR +Logs each +\fBsudo.debug\fR() +API call. +.TP 6n +\fIpy_calls\fR +Logs whenever a C function calls into the python module. +For example, calling the +\fB__init__\fR() +function. +.TP 6n +\fIc_calls\fR +Logs whenever python calls into a C +\fBsudo\fR +API function. +.TP 6n +\fIinternal\fR +Logs internal functions of the python language wrapper plugin. +.TP 6n +\fIsudo_cb\fR +Logs when +\fBsudo\fR +calls into the python plugin API. +.TP 6n +\fIload\fR +Logs python plugin loading / unloading events. +.PP +You can also specify +\(lqall\(rq +as the subsystem name to log debug messages for all subsystems. +.PP +The +\fBsudo.debug\fR() +function is defined as: +.nf +.sp +.RS 4n +sudo.debug(level, message(s)) +.RE +.fi +.PP +The function arguments are as follows: +.TP 6n +\fIlevel\fR +.br +an integer, use one of the log level constants below +.TP 6n +\fImessage(s)\fR +one or more messages to log +.PP +\fIAvailable log levels:\fR +.TS +l l l. +.PP +\fBsudo.conf name\fR \fBPython constant\fR \fBdescription\fR +.PP +crit sudo.DEBUG.CRIT only critical messages +.PP +err sudo.DEBUG.ERROR +.PP +warn sudo.DEBUG.WARN +.PP +notice sudo.DEBUG.NOTICE +.PP +diag sudo.DEBUG.DIAG +.PP +info sudo.DEBUG.INFO +.PP +trace sudo.DEBUG.TRACE +.PP +debug sudo.DEBUG.DEBUG very extreme verbose debugging +.TE +.PP +\fIUsing the logging module\fR +.PP +Alternatively, a plugin can use the built in logging module of Python as well. +Sudo adds its log handler to the root logger, so by default all output of a +logger will get forwarded to sudo log system, as it would call sudo.debug. +.PP +The log handler of sudo will map each Python log level of a message to +the appropriate sudo debug level. +Note however, that sudo debug system will only get the messages 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. +.SS "Debug example" +Sudo ships an example debug plugin by default. +To try it, register it by adding the following lines to +\fI@sysconfdir@/sudo.conf\fR: +.nf +.sp +.RS 6n +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_debugging.py \e + ClassName=DebugDemoPlugin + +Debug python_plugin.so \e + /var/log/sudo_python_debug plugin@trace,c_calls@trace +.RE +.fi +.SS "Option conversion API" +The Python plugin API includes two convenience functions to +convert options in +\(lqkey=value\(rq +format to a dictionary and vice versa. +.TP 6n +options_as_dict +.nf +.RS 6n +options_as_dict(options) +.RE +.fi +.RS 6n +.sp +The function arguments are as follows: +.TP 6n +\fIoptions\fR +An iterable (tuple, list, etc.) of strings, each in +\(lqkey=value\(rq +format. +This is how the plugin API passes options and settings to a Python plugin. +.PP +The function returns the resulting dictionary. +Each string of the passed in +\fIoptions\fR +will be split at the first equal sign +(\(oq\&=\(cq) +into a +\fIkey\fR +and +\fIvalue\fR. +Dictionary keys will never contain this symbol (but values may). +.RE +.TP 6n +options_from_dict +.nf +.RS 6n +options_from_dict(options_dict) +.RE +.fi +.RS 6n +.sp +The function arguments are as follows: +.TP 6n +\fIoptions_dict\fR +A dictionary where both the key and the value are strings. +Note that the key should not contain an equal sign +(\(oq\&=\(cq), +otherwise the resulting string will have a different meaning. +However, this is not currently enforced. +.PP +The function returns a tuple containing the strings in +\(lqkey=value\(rq +form for each key and value in the +\fIoptions_dict\fR +dictionary passed in. +This is how the plugin API accepts options and settings. +.RE +.SH "PLUGIN API CHANGELOG (Python)" +None yet +.SH "LIMITATIONS" +Only a maximum number 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. +.SH "SEE ALSO" +sudo.conf(@mansectform@), +sudo_plugin(@mansectform@), +sudoers(@mansectform@), +sudo(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +Python plugin support is currently considered experimental. +.PP +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SECURITY CONSIDERATIONS" +All Python plugin handling is implemented inside the +\fRpython_plugin.so\fR +dynamic plugin. +Therefore, if no Python plugin is registered in +sudo.conf(@mansectform@) +or the +\fIsudoers\fR +file, +\fBsudo\fR +will not load the Python interpreter or the Python libraries. +.PP +By default, a Python plugin can only import Python modules which are +owned by +\fIroot\fR +and are only writable by the owner. +The reason for this is to prevent a file getting imported accidentally +which is modifiable by a non-root user. +As +\fBsudo\fR +plugins run as +\fIroot\fR, +accidentally importing such file would make it possible for any user +(having write access) to execute any code with administrative rights. +.PP +However, during development of a plugin this might not be very convenient. +The +sudo.conf(@mansectform@) +\fRdeveloper_mode\fR +option can be used to disable it. +For example: +.RS 6n +Set developer_mode true +.RE +.PP +Please note that this creates a security risk, so it is not recommended +on critical systems such as a desktop machine for daily use, but is intended +to be used in development environments (VM, container, etc). +Before enabling developer mode, ensure you understand the implications. +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_plugin_python.mdoc.in b/doc/sudo_plugin_python.mdoc.in new file mode 100644 index 0000000..ba87971 --- /dev/null +++ b/doc/sudo_plugin_python.mdoc.in @@ -0,0 +1,1541 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 Robert Manner <robert.manner@oneidentity.com> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd February 19, 2020 +.Dt SUDO_PLUGIN_PYTHON @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_plugin_python +.Nd Sudo Plugin API (Python) +.Sh DESCRIPTION +Starting with version 1.9, +.Nm sudo +plugins can be written in python. +The API closely follows the C +.Nm sudo +plugin API described by +.Xr sudo_plugin @mansectform@ . +.Pp +The supported plugins types are: +.Pp +.Bl -bullet -compact -offset 4n -width 1n +.It +Policy plugin +.It +I/O plugin +.It +Audit plugin +.It +Approval plugin +.It +Group provider plugin +.El +.Pp +Python plugin support needs to be explicitly enabled at build time +with the configure option +.Dq --enable-python . +Python version 3.0 or higher is required. +.Ss Sudo Python Plugin Base +A plugin written in Python should be a class in a python file that +inherits from +.Em sudo.Plugin . +The +.Em sudo.Plugin +base class has no real purpose other than to identify this class as a plugin. +.Pp +The only implemented method is a constructor, which stores the +keyword arguments it receives as fields (member variables) in the object. +This is intended as a convenience to allow you to avoid writing the +constructor yourself. +.Pp +For example: +.Bd -literal -offset indent +import sudo + +class MySudoPlugin(sudo.Plugin): + # example constructor (optional) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # example destructor (optional) + def __del__(self): + pass +.Ed +.Pp +Both the constructor and destructor are optional and can be omitted. +.Pp +The customized Plugin class should define a few plugin-specific methods. +When the plugin loads, +.Nm sudo +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 +result code, as documented in +.Xr sudo_plugin @mansctsu@ , +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 +.It Sy Define Ta Sy Value +.It Dv sudo.RC.OK Ta 1 +.It Dv sudo.RC.ACCEPT Ta 1 +.It Dv sudo.RC.REJECT Ta 0 +.It Dv sudo.RC.ERROR Ta -1 +.It Dv sudo.RC.USAGE_ERROR Ta -2 +.El +.Pp +If a function returns +.Em 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 +.Dv sudo.RC.ERROR . +If that is not acceptable, you must catch the exception and handle it yourself. +.Pp +Instead of just returning +.Dv sudo.RC.ERROR +or +.Dv sudo.RC.REJECT +result code the plugin can also provide a message describing the problem. +This can be done by raising one of the special exceptions: +.Bd -literal -offset indent +raise sudo.PluginError("Message") +raise sudo.PluginReject("Message") +.Ed +.Pp +This added message will be used by the audit plugins. +Both exceptions inherit from +.Dv sudo.PluginException +.Ss Python Plugin Loader +Running the Python interpreter and bridging between C and Python is +handled by the +.Nm sudo +plugin +.Li 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 +plugin it is loading as arguments. +.Pp +Example usage in +.Xr sudo.conf @mansectform@ : +.Bd -literal -offset indent +Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class> +Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class> +.Ed +.Pp +Example group provider plugin usage in the +.Em sudoers +file: +.Bd -literal -offset indent +Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>" +.Ed +.Pp +The plugin arguments are as follows: +.Bl -tag -width 4n +.It ModulePath +The path of a python file which contains the class of the sudo Python plugin. +It must be either an absolute path or a path relative to the sudo Python plugin +directory: "@plugindir@/python". +.It ClassName +(Optional.) The name of the class implementing the sudo Python plugin. +If not supplied, the one and only sudo.Plugin that is present in the module +will be used. +If there are multiple such plugins in the module (or none), it +will result in an error. +.El +.Ss Policy plugin API +Policy plugins must be registered in +.Xr sudo.conf @mansectform@ . +For example: +.Bd -literal -offset indent +Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class> +.Ed +.Pp +Currently, only a single policy plugin may be specified in +.Xr sudo.conf @mansectform@ . +.Pp +A policy plugin may have the following member functions: +.Bl -tag -width 4n +.It Sy constructor +.Bd -literal +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], + plugin_options: Tuple[str, ...]) +.Ed +.Pp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.Pp +The constructor matches the +.Fn open +function in the C sudo plugin API. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa user_env +The user's environment as a tuple of strings in +.Dq key=value +format. +.It Fa settings +A tuple of user-supplied +.Em sudo +settings in the form of +.Dq key=value +strings. +.It Fa version +The version of the Python Policy Plugin API. +.It Fa user_info +A tuple of information about the user running the command in the form of +.Dq key=value +strings. +.It Fa plugin_options +The plugin options passed as arguments in the +.Xr sudo.conf @mansectform@ +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +.Dq key=value +format. +.El +.Pp +The +.Fn sudo.options_as_dict +convenience function can be used to convert +.Dq key=value +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the policy plugin +.Fn open +documentation in +.Xr sudo_plugin @mansectform@ . +.It Sy check_policy +.Bd -literal -compact +check_policy(self, argv: Tuple[str, ...], env_add: Tuple[str, ...]) +.Ed +.Pp +The +.Fn check_policy +function is called by +.Nm sudo +to determine whether the user is allowed to run the specified command. +Implementing this function is mandatory for a policy plugin. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa argv +A tuple describing the command the user wishes to run. +.It Fa env_add +Additional environment variables specified by the user on the command line in +the form of a tuple of +.Dq key=value +pairs. +The +.Fn sudo.options_as_dict +convenience function can be used to convert them to a dictionary. +.El +.Pp +This function should return a result code or a tuple in the following format: +.Bd -literal -offset indent +return (rc, command_info_out, argv_out, user_env_out) +.Ed +.Pp +The tuple values are as follows: +.Bl -tag -width 4n +.It Fa rc +The result of the policy check, one of the +.Dv sudo.RC.* +constants. +.Dv sudo.RC.ACCEPT +if the command is allowed, +.Dv sudo.RC.REJECT +if not allowed, +.Dv sudo.RC.ERROR +for a general error, or +.Dv sudo.RC.USAGE_ERROR +for a usage error. +.It Fa command_info_out +Optional (only required when the command is accepted). +Information about the command being run in the form of +.Dq key=value +strings. +.Pp +To accept a command, at the very minimum the plugin must set in the +.Em command , +.Em runas_uid +and +.Em runas_gid +keys. +.Pp +For a list of recognized keys and supported values, +see the +.Fn check_policy +documentation in +.Xr sudo_plugin @mansectform@ . +.It Fa argv_out +Optional (only required when the command is accepted). +The arguments to pass to the +.Xr execve 2 +system call when executing the command. +.It Fa user_env_out +Optional (only required when the command is accepted). +The environment to use when executing the command in the form of a +tuple of strings in +.Dq key=value +format. +.El +.It Sy init_session +.Bd -literal -compact +init_session(self, user_pwd: Tuple, user_env: Tuple[str, ...]) +.Ed +.Pp +Perform session setup (optional). +The +.Fn init_session +function is called before +.Nm sudo +sets up the +execution environment for the command before any uid or gid changes. +.Pp +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 +if the user is not present in the password database. +.Pp +Example conversion: +.Bd -literal -compact -offset indent +user_pwd = pwd.struct_passwd(user_pwd) if user_pwd else None +.Ed +.It Fa user_env +The environment the command will run in. +This is a tuple of strings in +.Dq key=value +format. +.El +.Pp +This function should return a result code or a tuple in the following format: +.Bd -literal -offset 4n +return (rc, user_env_out) +.Ed +.Pp +The tuple values are as follows: +.Bl -tag -width 4n +.It Fa rc +The result of the session init, one of the +.Dv sudo.RC.* +constants. +.Dv sudo.RC.OK +on success, 0 on failure, or +.Dv sudo.RC.ERROR +if an error occurred. +.It Fa user_env_out +Optional. +If the +.Fn init_session +function needs to modify the user environment, it can return the new +environment in +.Fa user_env_out . +If this is omitted, no changes will be made to +.Fa user_env . +.El +.It Sy list +.Bd -literal -compact +list(self, argv: Tuple[str, ...], is_verbose: int, user: str) +.Ed +.Pp +List available privileges for the invoking user. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa argv +If not set to +.Em None , +an argument vector describing a command the user wishes to check +against the policy. +.It Fa is_verbose +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 , +the plugin should list the privileges of the invoking user. +.El +.It Sy 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 +.Bd -literal -compact +invalidate(self, remove: int) +.Ed +.Pp +For policy plugins that cache authentication credentials, this function is used to invalidate the credentials (optional). +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa remove +If this flag is set, the plugin may remove the credentials instead of simply +invalidating them. +.El +.It Sy show_version +.Bd -literal -compact +show_version(self, is_verbose: int) +.Ed +.Pp +Display the plugin version information to the user. +The +.Fn sudo.log_info +function should be used. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa is_verbose +A flag to indicate displaying more verbose information. +Currently this is 1 if +.Ql sudo -V +is run as the root user. +.El +.It Sy close +.Bd -literal -compact +close(self, exit_status: int, error: int) +.Ed +.Pp +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 +.Nm sudo +attempts to execute the command. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa exit_status +The exit status of the command if was executed, otherwise -1. +.It Fa error +If the command could not be executed, this is set to the value of +errno set by the +.Xr execve 2 +system call, otherwise 0. +.El +.El +.Ss Policy plugin example +Sudo ships with an example Python policy plugin. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal +Plugin python_policy python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_policy_plugin.py \e + ClassName=SudoPolicyPlugin +.Ed +.Pp +Be aware, however, that you cannot enable the Python policy plugin +in addition to another policy plugin, such as +.Xr sudoers @mansectform@ . +.Ss I/O plugin API +I/O plugins must be registered in +.Xr sudo.conf @mansectform@ . +For example: +.Bd -literal -offset indent +Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class> +.Ed +.Pp +Sudo supports loading multiple I/O plugins. +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 +.Bd -literal -compact +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], + plugin_options: Tuple[str, ...]) +.Ed +.Pp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.Pp +The constructor matches the +.Fn open +function in the C sudo plugin API. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa user_env +The user's environment as a tuple of strings in +.Dq key=value +format. +.It Fa settings +A tuple of user-supplied +.Em sudo +settings in the form of +.Dq key=value +strings. +.It Fa version +The version of the Python I/O Plugin API. +.It Fa user_info +A tuple of information about the user running the command in the form of +.Dq key=value +strings. +.It Fa plugin_options +The plugin options passed as arguments in the +.Xr sudo.conf @mansectform@ +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +.Dq key=value +format. +.El +.Pp +The +.Fn sudo.options_as_dict +convenience function can be used to convert +.Dq key=value +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the I/O plugin +.Fn open +documentation in +.Xr sudo_plugin @mansectform@ . +.It Sy open +.Bd -literal -compact +open(self, argv: Tuple[str, ...], + command_info: Tuple[str, ...]) -> int +.Ed +.Pp +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: +.Pp +.Bl -bullet -compact -offset 4n -width 1n +.It +It only gets called before the user would execute some command +(and not for a version query for example). +.It +Other arguments of the C API +.Fn open +function are received through the constructor. +.El +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa argv +A tuple of the arguments describing the command the user wishes to run. +.It Fa command_info +Information about the command being run in the form of +.Dq key=value +strings. +.El +.Pp +The +.Fn sudo.options_as_dict +convenience function can be used to convert +.Dq key=value +pairs to a dictionary. +For a list of recognized keys and their supported values, +see the I/O plugin +.Fn open +documentation in +.Xr sudo_plugin @mansectform@ . +.Pp +The +.Fn open +function should return a result code, one of the +.Dv sudo.RC.* +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 +.Bd -literal -compact +log_ttyin(self, buf: str) -> int +log_ttyout(self, buf: str) -> int +log_stdin(self, buf: str) -> int +log_stdout(self, buf: str) -> int +log_stderr(self, buf: str) -> int +.Ed +.Pp +Receive the user input or output of the terminal device and +application standard input / output / error. +See the matching calls in +.Xr sudo_plugin @mansectform@ . +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa buf +The input (or output) buffer in the form of a string. +.El +.Pp +The function should return a result code, one of the +.Dv sudo.RC.* +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. +Other I/O logging plugins will still receive any remaining +input or output that has not yet been processed. +.Pp +If an input logging function rejects the data by returning +.Dv sudo.RC.REJECT , +the command will be terminated and the data will not be passed to the +command, though it will still be sent to any other I/O logging plugins. +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 +.Bd -literal -compact +change_winsize(self, line: int, cols: int) -> int +.Ed +.Pp +Called whenever the window size of the terminal changes. +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa line +The number of lines of the terminal. +.It Fa cols +The number of columns of the terminal. +.El +.It Sy log_suspend +.Bd -literal -compact +log_suspend(self, signo: int) -> int +.Ed +Called whenever a command is suspended or resumed. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa signo +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 +.Bd -literal -compact +show_version(self, is_verbose: int) +.Ed +Display the plugin version information to the user. +The +.Fn sudo.log_info +function should be used. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa is_verbose +A flag to indicate displaying more verbose information. +Currently this is 1 if +.Ql sudo -V +is run as the root user. +.El +.It Sy close +.Bd -literal -compact +close(self, exit_status: int, error: int) -> None +.Ed +Called when a command execution finished. +.Pp +Works the same as the +.Fn close +function in the C sudo plugin API, except that it only gets called if +.Nm sudo +attempts to execute the command. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa exit_status +The exit status of the command if was executed, otherwise -1. +.It Fa error +If the command could not be executed, this is set to the value of +errno set by the +.Xr execve 2 +system call, otherwise 0. +.El +.El +.Ss I/O plugin example +Sudo ships a Python I/O plugin example. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal -offset indent +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_io_plugin.py \e + ClassName=SudoIOPlugin +.Ed +.Ss Audit plugin API +Audit plugins must be registered in +.Xr sudo.conf @mansectform@ . +For example: +.Bd -literal -offset indent +Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class> +.Ed +.Pp +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): +.Bl -tag -width 4n +.It Sy constructor +.Bd -literal -compact +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...]) +.Ed +.Pp +The default constructor will set the keyword arguments it receives +as member variables in the object. +.Pp +The constructor matches the +.Fn open +function in the C sudo plugin API. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa user_env +The user's environment as a tuple of strings in +.Dq key=value +format. +.It Fa settings +A tuple of user-supplied +.Em sudo +settings in the form of +.Dq key=value +strings. +.It Fa version +The version of the Python Audit Plugin API. +.It Fa user_info +A tuple of information about the user running the command in the form of +.Dq key=value +strings. +.It Fa plugin_options +The plugin options passed as arguments in the +.Xr sudo.conf @mansectform@ +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +.Dq key=value +format. +.El +.It Sy open +.Bd -literal -compact +open(self, submit_optind: int, + submit_argv: Tuple[str, ...]) -> int +.Ed +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa submit_optind +The index into +.Fa submit_argv +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 +.Bd -literal -compact +close(self, status_type: int, status: int) -> None +.Ed +.Pp +Called when sudo is finished, shortly before it exits. +.Pp +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. +.It Fa status +Depending on the value of +.Fa status_type , +this value is either +ignored, the command's exit status as returned by the +.Xr wait 2 +system call, the value of +.Li errno +set by the +.Xr execve 2 +system call, or the value of +.Li errno +resulting from an error in the +.Nm sudo +front end. +.El +.It Sy show_version +.Bd -literal -compact +show_version(self, is_verbose: int) -> int +.Ed +.Pp +Display the plugin version information to the user. +The +.Fn sudo.log_info +function should be used. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa is_verbose +A flag to indicate displaying more verbose information. +Currently this is 1 if +.Ql sudo -V +is run as the root user. +.El +.It Sy 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 +.Ed +.Pp +This function is called when a command or action is accepted by a policy +or approval plugin. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that accepted the command or +.Dq sudo +for the +.Nm sudo +front-end. +.It plugin_type +The type of plugin that accepted the command, currently either +.Dv sudo.PLUGIN_TYPE.POLICY , +.Dv sudo.PLUGIN_TYPE.APPROVAL +or +.Dv sudo.PLUGIN_TYPE.SUDO . +The +.Fn accept +function is called multiple times--once for each policy or approval +plugin that succeeds and once for the sudo front-end. +When called on behalf of the sudo front-end, +.Fa command_info +may include information from an I/O logging plugin as well. +.Pp +Typically, an audit plugin is interested in either the accept status from +the +.Nm sudo +front-end or from the various policy and approval plugins, but not both. +It is possible for the policy plugin to accept a command that is +later rejected by an approval plugin, in which case the audit +plugin's +.Fn accept +and +.Fn reject +functions will +.Em both +be called. +.It command_info +A vector of information describing the command being run. +See the +.Xr sudo_plugin @mansectform@ +manual for possible values. +.It run_argv +Argument vector describing a command that will be run. +.It run_envp +The environment the command will be run with. +.El +.It Sy reject +.Bd -literal -compact +reject(self, plugin_name: str, plugin_type: int, audit_msg: str, + command_info: Tuple[str, ...]) -> int +.Ed +.Pp +This function is called when a command or action is rejected by the policy +plugin. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that rejected the command. +.It plugin_type +The type of plugin that rejected the command, currently either +.Dv sudo.PLUGIN_TYPE.POLICY , +.Dv sudo.PLUGIN_TYPE.APPROVAL +or +.Dv sudo.PLUGIN_TYPE.IO . +.Pp +Unlike the +.Fn accept +function, the +.Fn reject +function is not called on behalf of the +.Nm sudo +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 +. +.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 +.Bd -literal -compact +error(self, plugin_name: str, plugin_type: int, audit_msg: str, + command_info: Tuple[str, ...]) -> int +.Ed +.Pp +This function is called when a plugin or the +.Nm sudo +front-end returns an error. +The function arguments are as follows: +.Bl -tag -width 4n +.It plugin_name +The name of the plugin that generated the error or +.Dq sudo +for the +.Nm sudo +front-end. +.It plugin_type +The type of plugin that generated the error, or +.Dv SUDO_FRONT_END +for the +.Nm sudo +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 +. +.It command_info +A vector of information describing the command. +See the +.Xr sudo_plugin @mansectform@ +manual for possible values. +.El +.El +.Ss Audit plugin example +Sudo ships a Python Audit plugin example. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal -offset indent +Plugin python_audit python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_audit_plugin.py \e + ClassName=SudoAuditPlugin +.Ed +.Pp +It will log the plugin accept / reject / error results to the output. +.Ss Approval plugin API +Approval plugins must be registered in +.Xr sudo.conf @mansectform@ . +For example: +.Bd -literal -offset indent +Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class> +.Ed +.Pp +Sudo supports loading multiple approval plugins. +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 +.Bd -literal -compact +__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...], + version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...], + submit_optind: int, submit_argv: Tuple[str, ...]) +.Ed +.Pp +Optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.Pp +The constructor matches the +.Fn open +function in the C sudo plugin API. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa user_env +The user's environment as a tuple of strings in +.Dq key=value +format. +.It Fa settings +A tuple of user-supplied +.Em sudo +settings in the form of +.Dq key=value +strings. +.It Fa version +The version of the Python Approval Plugin API. +.It Fa user_info +A tuple of information about the user running the command in the form of +.Dq key=value +strings. +.It Fa plugin_options +The plugin options passed as arguments in the +.Xr sudo.conf @mansectform@ +plugin registration. +This is a tuple of strings, usually (but not necessarily) in +.Dq key=value +format. +.It Fa submit_optind +The index into +.Fa submit_argv +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 +.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 +.Bd -literal -compact +check(self, command_info: Tuple[str, ...], run_argv: Tuple[str, ...], + run_env: Tuple[str, ...]) -> int +.Ed +.Pp +This function is called after policy plugin's check_policy has succeeded. +It can reject execution of the command by returning sudo.RC.REJECT or +raising the special exception: +.Bd -literal -offset indent +raise sudo.PluginReject("some message") +.Ed +.Pp +with the message describing the problem. +In the latter case, the audit plugins will get the description. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It command_info +A vector of information describing the command that will run. +See the +.Xr sudo_plugin @mansectform@ +manual for possible values. +.It run_argv +Argument vector describing a command that will be run. +.It run_env +The environment the command will be run with. +.El +.El +.Ss Approval plugin example +Sudo ships a Python Approval plugin example. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal -offset indent +Plugin python_approval python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_approval_plugin.py \e + ClassName=BusinessHoursApprovalPlugin +.Ed +.Pp +It will only allow execution of commands in the "business hours" (from Monday +to Friday between 8:00 and 17:59:59). +.Ss Sudoers group provider plugin API +A group provider plugin is registered in the +.Xr sudoers @mansectform@ +file. +For example: +.Bd -literal -offset indent +Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>" +.Ed +.Pp +Currently, only a single group plugin can be registered in +.Em sudoers . +.Pp +A group provider plugin may have the following member functions: +.Bl -tag -width 4n +.It Sy constructor +.Bd -literal -compact +__init__(self, args: Tuple[str, ...], version: str) +.Ed +.Pp +Implementing this function is optional. +The default constructor will set the keyword arguments it receives +as member variables in the object. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa args +The plugin options passed as arguments in the +.Em sudoers +file plugin registration. +All the arguments are free form strings (not necessarily in +.Dq key=value +format). +.It Fa version +The version of the Python Group Plugin API. +.El +.It Sy query +.Bd -literal -compact +query(self, user: str, group: str, user_pwd: Tuple) +.Ed +.Pp +The +.Fn query +function is used to ask the group plugin whether +.Fa user +is a member of +.Fa group . +This method is required. +.El +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa user +The name of the user being looked up in the external group database. +.It Fa group +The name of the group being queried. +.It Fa user_pwd +The password database entry for the user, if any. +If +.Fa user +is not present in the password database, +.Fa user_pwd +will be +.Dv NULL . +.El +.Ss Group plugin example +Sudo ships a Python group plugin example. +To try it, register it in the +.Em sudoers +file by adding the following lines: +.Bd -literal -offset indent +Defaults group_plugin="python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_group_plugin.py \e + ClassName=SudoGroupPlugin" +.Ed +.Pp +The example plugin will tell +.Nm sudo +that the user +.Em test +is part of the non-unix group +.Em mygroup . +If you add a rule that uses this group, it will affect the +.Em test +user. +For example: +.Bd -literal -offset indent +%:mygroup ALL=(ALL) NOPASSWD: ALL +.Ed +.Pp +Will allow user +.Em test +to run +.Nm sudo +without a password. +.Ss Hook function API +The hook function API is currently not supported for plugins +written in Python. +.Ss Conversation API +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 +class. +This is the Python equivalent of the +.Fn conversation +function in the C 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 +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 +member variables: +.Bl -tag -width 4n +.It Fa msg_type +Specifies the type of the conversation. +See the +.Dv sudo.CONV.* +constants below. +.It Fa msg +The message to display to the user. +The caller must include a trailing newline in +.Li msg +if one is to be displayed. +.It Fa timeout +Optional. +The maximum amount of time for the conversation in seconds. +If the timeout is exceeded, the +.Fn sudo.conv +function will raise a +.Dv sudo.ConversationInterrupted +exception. +The default is to wait forever (no timeout). +.El +.Pp +To specify the message type, the following constants are available: +.Pp +.Bl -bullet -compact -offset 4n -width 1n +.It +sudo.CONV.PROMPT_ECHO_OFF +.It +sudo.CONV.PROMPT_ECHO_ON +.It +sudo.CONV.ERROR_MSG +.It +sudo.CONV.INFO_MSG +.It +sudo.CONV.PROMPT_MASK +.It +sudo.CONV.PROMPT_ECHO_OK +.It +sudo.CONV.PREFER_TTY +.El +.Pp +See the +.Xr sudo_plugin @mansectform@ +manual for a description of the message types. +.Pp +The +.Fn sudo.conv +function performs the actual user interaction: +.Bd -literal -offset 4n +sudo.conv(message(s), on_suspend=suspend_function, + on_resume=resume_function) +.Ed +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa message(s) +One of more messages (of type +.Sy sudo.ConvMessage ) , +each describing a conversation. +At least one message is required. +.It Fa on_suspend +An optional callback function which gets called if the conversation +is suspended, for example by the user pressing control-Z. +The specified function must take a single argument which will be filled +with the number of the signal that caused the process to be suspended. +.It Fa on_resume +An optional callback function which gets called when the previously +suspended conversation is resumed. +The specified function must take a single argument which will be filled +with the number of the signal that caused the process to be suspended. +.El +.Pp +The +.Fn sudo.conv +function can raise the following exceptions: +.Bl -tag -width 4n +.It Sy sudo.SudoException +If the conversation fails, for example when the conversation function is not +available. +.It Sy 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 +.Ss Conversation example +Sudo ships with an example plugin demonstrating the Python conversation API. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal -offset indent +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_conversation.py \e + ClassName=ReasonLoggerIOPlugin +.Ed +.Ss Information / error display API +.Bd -literal +sudo.log_info(string(s), sep=" ", end="\en") +sudo.log_error(string(s), sep=" ", end="\en") +.Ed +.Pp +To display information to the user, the +.Fn sudo.log_info +function can be used. +To display error messages, use +.Fn sudo.log_error . +The syntax is similar to the Python +.Fn print +function. +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa string(s) +One or more strings to display. +.It Fa sep +An optional string which will be used as the separator between the +specified strings. +The default is a space character, +.Pq Sq \ . +.It Fa end +An optional string which will be displayed at the end of the message. +The default is a new line character +.Pq Sq \en . +.El +.Ss Debug API +Debug messages are not visible to the user and are only logged debugging +is explicitly enabled in +.Xr sudo.conf @mansectform@ . +Python plugins can use the +.Fn sudo.debug +function to make use of +.Nm sudo Ns No 's +debug system. +.Pp +.Em Enabling debugging in sudo.conf +.Pp +To enable debug messages, add a +.Li Debug +line to +.Xr sudo.conf @mansectform@ +with the program set to +.Pa python_plugin.so . +For example, to store debug output in +.Pa /var/log/sudo_python_debug , +use a line like the following: +.Bd -literal -offset indent +Debug python_plugin.so /var/log/sudo_python_debug \e + plugin@trace,c_calls@trace +.Ed +.Pp +The debug options are in the form of multiple +.Dq subsystem@level +strings, separated by commas +.Pq Sq \&, . +For example to just see the debug output of +.Fn sudo.debug +calls, use: +.Bd -literal -offset indent +Debug python_plugin.so /var/log/sudo_python_debug plugin@trace +.Ed +.Pp +See +.Xr sudo_conf @mansectform@ +for more details. +.Pp +The most interesting subsystems for Python plugin development are: +.Bl -tag -width 4n +.It Em plugin +Logs each +.Fn sudo.debug +API call. +.It Em py_calls +Logs whenever a C function calls into the python module. +For example, calling the +.Fn __init__ +function. +.It Em c_calls +Logs whenever python calls into a C +.Nm sudo +API function. +.It Em internal +Logs internal functions of the python language wrapper plugin. +.It Em sudo_cb +Logs when +.Nm sudo +calls into the python plugin API. +.It Em load +Logs python plugin loading / unloading events. +.El +.Pp +You can also specify +.Dq all +as the subsystem name to log debug messages for all subsystems. +.Pp +The +.Fn sudo.debug +function is defined as: +.Bd -literal -offset 4n +sudo.debug(level, message(s)) +.Ed +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa level +an integer, use one of the log level constants below +.It Fa message(s) +one or more messages to log +.El +.Pp +.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 +.El +.Pp +.Em Using the logging module +.Pp +Alternatively, a plugin can use the built in logging module of Python as well. +Sudo adds its log handler to the root logger, so by default all output of a +logger will get forwarded to sudo log system, as it would call sudo.debug. +.Pp +The log handler of sudo will map each Python log level of a message to +the appropriate sudo debug level. +Note however, that sudo debug system will only get the messages 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. +.Ss Debug example +Sudo ships an example debug plugin by default. +To try it, register it by adding the following lines to +.Pa @sysconfdir@/sudo.conf : +.Bd -literal -offset indent +Plugin python_io python_plugin.so \e + ModulePath=@prefix@/share/doc/sudo/examples/example_debugging.py \e + ClassName=DebugDemoPlugin + +Debug python_plugin.so \e + /var/log/sudo_python_debug plugin@trace,c_calls@trace +.Ed +.Ss Option conversion API +The Python plugin API includes two convenience functions to +convert options in +.Dq key=value +format to a dictionary and vice versa. +.Bl -tag -width 4n +.It options_as_dict +.Bd -literal -compact +options_as_dict(options) +.Ed +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa options +An iterable (tuple, list, etc.) of strings, each in +.Dq key=value +format. +This is how the plugin API passes options and settings to a Python plugin. +.El +.Pp +The function returns the resulting dictionary. +Each string of the passed in +.Fa options +will be split at the first equal sign +.Pq Sq \&= +into a +.Em key +and +.Em value . +Dictionary keys will never contain this symbol (but values may). +.It options_from_dict +.Bd -literal -compact +options_from_dict(options_dict) +.Ed +.Pp +The function arguments are as follows: +.Bl -tag -width 4n +.It Fa options_dict +A dictionary where both the key and the value are strings. +Note that the key should not contain an equal sign +.Pq Sq \&= , +otherwise the resulting string will have a different meaning. +However, this is not currently enforced. +.El +.Pp +The function returns a tuple containing the strings in +.Dq key=value +form for each key and value in the +.Fa options_dict +dictionary passed in. +This is how the plugin API accepts options and settings. +.El +.Sh PLUGIN API CHANGELOG (Python) +None yet +.Sh LIMITATIONS +Only a maximum number 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. +.Sh SEE ALSO +.Xr sudo.conf @mansectform@ , +.Xr sudo_plugin @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +Python plugin support is currently considered experimental. +.Pp +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SECURITY CONSIDERATIONS +All Python plugin handling is implemented inside the +.Li python_plugin.so +dynamic plugin. +Therefore, if no Python plugin is registered in +.Xr sudo.conf @mansectform@ +or the +.Em sudoers +file, +.Nm sudo +will not load the Python interpreter or the Python libraries. +.Pp +By default, a Python plugin can only import Python modules which are +owned by +.Em root +and are only writable by the owner. +The reason for this is to prevent a file getting imported accidentally +which is modifiable by a non-root user. +As +.Nm sudo +plugins run as +.Em root , +accidentally importing such file would make it possible for any user +(having write access) to execute any code with administrative rights. +.Pp +However, during development of a plugin this might not be very convenient. +The +.Xr sudo.conf @mansectform@ +.Li developer_mode +option can be used to disable it. +For example: +.Dl Set developer_mode true +.Pp +Please note that this creates a security risk, so it is not recommended +on critical systems such as a desktop machine for daily use, but is intended +to be used in development environments (VM, container, etc). +Before enabling developer mode, ensure you understand the implications. +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_sendlog.man.in b/doc/sudo_sendlog.man.in new file mode 100644 index 0000000..4d72d75 --- /dev/null +++ b/doc/sudo_sendlog.man.in @@ -0,0 +1,190 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.TH "SUDO_SENDLOG" "@mansectsu@" "May 12, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudo_sendlog\fR +\- send sudo I/O log to log server +.SH "SYNOPSIS" +.HP 13n +\fBsudo_sendlog\fR +[\fB\-AnV\fR] +[\fB\-b\fR\ \fIca_bundle\fR] +[\fB\-c\fR\ \fIcert_file\fR] +[\fB\-h\fR\ \fIhost\fR] +[\fB\-i\fR\ \fIiolog-id\fR] +[\fB\-k\fR\ \fIkey_file\fR] +[\fB\-p\fR\ \fIport\fR] +[\fB\-r\fR\ \fIrestart-point\fR] +[\fB\-R\fR\ \fIreject-reason\fR] +[\fB\-t\fR\ \fInumber\fR] +\fIpath\fR +.SH "DESCRIPTION" +\fBsudo_sendlog\fR +can be used to send the existing +\fBsudoers\fR +I/O log +\fIpath\fR +to a remote log server such as +sudo_logsrvd(@mansectsu@) +for central storage. +.PP +The options are as follows: +.TP 12n +\fB\-A\fR, \fB\--accept-only\fR +Only send the accept event, not the I/O associated with the log. +This can be used to test the logging of accept events without +any associated I/O. +.TP 12n +\fB\-b\fR, \fB\--ca-bundle\fR +The path to a certificate authority bundle file, in PEM format, +to use instead of the system's default certificate authority database +when authenticating the log server. +The default is to use the system's default certificate authority database. +.TP 12n +\fB\-c\fR, \fB\--cert\fR +The path to the client's certificate file in PEM format. +This setting is required when the connection to the remote log server +is secured with TLS. +.TP 12n +\fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-h\fR, \fB\--host\fR +Connect to the specified +\fIhost\fR +instead of localhost. +.TP 12n +\fB\-i\fR, \fB\--iolog-id\fR +Use the specified +\fIiolog-id\fR +when restarting a log transfer. +The +\fIiolog-id\fR +is reported by the server when it creates the remote I/O log. +This option may only be used in conjunction with the +\fB\-r\fR +option. +.TP 12n +\fB\-k\fR, \fB\--key\fR +.br +The path to the client's private key file in PEM format. +This setting is required when the connection to the remote log server +is secured with TLS. +.TP 12n +\fB\-n\fR, \fB\--no-verify\fR +If specified, the server's certificate will not be verified during +the TLS handshake. +By default, +\fBsudo_sendlog\fR +verifies that the server's certificate is valid and that it contains either +the server's host name or its IP address. +This setting is only supported when the connection to the remote log server +is secured with TLS. +.TP 12n +\fB\-p\fR, \fB\--port\fR +Use the specified network +\fIport\fR +when connecting to the log server instead of the +default, port 30344. +.TP 12n +\fB\-r\fR, \fB\--restart\fR +Restart an interrupted connection to the log server. +The specified +\fIrestart-point\fR +is used to tell the server the point in time at which to continue the log. +The +\fIrestart-point\fR +is specified in the form +\(lqseconds,nanoseconds\(rq +and is usually the last commit point received from the server. +The +\fB\-i\fR +option must also be specified when restarting a transfer. +.TP 12n +\fB\-R\fR, \fB\--reject\fR +Send a reject event for the command using the specified +\fIreject-reason\fR, +even though it was actually accepted locally. +This can be used to test the logging of reject events; no I/O +will be sent. +.TP 12n +\fB\-t\fR, \fB\--test\fR +Open +\fInumber\fR +simultaneous connections to the log server and send the specified +I/O log file on each one. +This option is useful for performance testing. +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBsudo_sendlog\fR +version and exit. +.SS "Debugging sendlog" +\fBsudo_sendlog\fR +supports a flexible debugging framework that is configured via +\fRDebug\fR +lines in the +sudo.conf(@mansectform@) +file. +.PP +For more information on configuring +sudo.conf(@mansectform@), +please refer to its manual. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +Sudo front end configuration +.SH "SEE ALSO" +sudo.conf(@mansectform@), +sudo(@mansectsu@), +sudo_logsrvd(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo_sendlog\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo_sendlog\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudo_sendlog.mdoc.in b/doc/sudo_sendlog.mdoc.in new file mode 100644 index 0000000..8ec887d --- /dev/null +++ b/doc/sudo_sendlog.mdoc.in @@ -0,0 +1,176 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2019-2020 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. +.\" +.Dd May 12, 2020 +.Dt SUDO_SENDLOG @mansectsu@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudo_sendlog +.Nd send sudo I/O log to log server +.Sh SYNOPSIS +.Nm sudo_sendlog +.Op Fl AnV +.Op Fl b Ar ca_bundle +.Op Fl c Ar cert_file +.Op Fl h Ar host +.Op Fl i Ar iolog-id +.Op Fl k Ar key_file +.Op Fl p Ar port +.Op Fl r Ar restart-point +.Op Fl R Ar reject-reason +.Op Fl t Ar number +.Ar path +.Sh DESCRIPTION +.Nm +can be used to send the existing +.Nm sudoers +I/O log +.Ar path +to a remote log server such as +.Xr sudo_logsrvd @mansectsu@ +for central storage. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl A , -accept-only +Only send the accept event, not the I/O associated with the log. +This can be used to test the logging of accept events without +any associated I/O. +.It Fl b , -ca-bundle +The path to a certificate authority bundle file, in PEM format, +to use instead of the system's default certificate authority database +when authenticating the log server. +The default is to use the system's default certificate authority database. +.It Fl c , -cert +The path to the client's certificate file in PEM format. +This setting is required when the connection to the remote log server +is secured with TLS. +.It Fl -help +Display a short help message to the standard output and exit. +.It Fl h , -host +Connect to the specified +.Ar host +instead of localhost. +.It Fl i , -iolog-id +Use the specified +.Ar iolog-id +when restarting a log transfer. +The +.Ar iolog-id +is reported by the server when it creates the remote I/O log. +This option may only be used in conjunction with the +.Fl r +option. +.It Fl k , -key +The path to the client's private key file in PEM format. +This setting is required when the connection to the remote log server +is secured with TLS. +.It Fl n , -no-verify +If specified, the server's certificate will not be verified during +the TLS handshake. +By default, +.Nm +verifies that the server's certificate is valid and that it contains either +the server's host name or its IP address. +This setting is only supported when the connection to the remote log server +is secured with TLS. +.It Fl p , -port +Use the specified network +.Ar port +when connecting to the log server instead of the +default, port 30344. +.It Fl r , -restart +Restart an interrupted connection to the log server. +The specified +.Ar restart-point +is used to tell the server the point in time at which to continue the log. +The +.Ar restart-point +is specified in the form +.Dq seconds,nanoseconds +and is usually the last commit point received from the server. +The +.Fl i +option must also be specified when restarting a transfer. +.It Fl R , -reject +Send a reject event for the command using the specified +.Ar reject-reason , +even though it was actually accepted locally. +This can be used to test the logging of reject events; no I/O +will be sent. +.It Fl t , -test +Open +.Ar number +simultaneous connections to the log server and send the specified +I/O log file on each one. +This option is useful for performance testing. +.It Fl V , -version +Print the +.Nm +version and exit. +.El +.Ss Debugging sendlog +.Nm +supports a flexible debugging framework that is configured via +.Li Debug +lines in the +.Xr sudo.conf @mansectform@ +file. +.Pp +For more information on configuring +.Xr sudo.conf @mansectform@ , +please refer to its manual. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +Sudo front end configuration +.El +.Sh SEE ALSO +.Xr sudo.conf @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr sudo_logsrvd @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers.ldap.man.in b/doc/sudoers.ldap.man.in new file mode 100644 index 0000000..dc81ddb --- /dev/null +++ b/doc/sudoers.ldap.man.in @@ -0,0 +1,1727 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2003-2020 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. +.\" +.TH "SUDOERS.LDAP" "@mansectform@" "October 29, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudoers.ldap\fR +\- sudo LDAP configuration +.SH "DESCRIPTION" +In addition to the standard +\fIsudoers\fR +file, +\fBsudo\fR +may be configured +via LDAP. +This can be especially useful for synchronizing +\fIsudoers\fR +in a large, distributed environment. +.PP +Using LDAP for +\fIsudoers\fR +has several benefits: +.TP 3n +\fB\(bu\fR +\fBsudo\fR +no longer needs to read +\fIsudoers\fR +in its entirety. +When LDAP is used, there are only two or three LDAP queries per invocation. +This makes it especially fast and particularly usable in LDAP environments. +.TP 3n +\fB\(bu\fR +\fBsudo\fR +no longer exits if there is a typo in +\fIsudoers\fR. +It is not possible to load LDAP data into the server that does +not conform to the sudoers schema, so proper syntax is guaranteed. +It is still possible to have typos in a user or host name, but +this will not prevent +\fBsudo\fR +from running. +.TP 3n +\fB\(bu\fR +It is possible to specify per-entry options that override the global +default options. +\fI@sysconfdir@/sudoers\fR +only supports default options and limited options associated with +user/host/commands/aliases. +The syntax is complicated and can be difficult for users to understand. +Placing the options directly in the entry is more natural. +.TP 3n +\fB\(bu\fR +The +\fBvisudo\fR +program is no longer needed. +\fBvisudo\fR +provides locking and syntax checking of the +\fI@sysconfdir@/sudoers\fR +file. +Since LDAP updates are atomic, locking is no longer necessary. +Because syntax is checked when the data is inserted into LDAP, there +is no need for a specialized tool to check syntax. +.SS "SUDOers LDAP container" +The +\fIsudoers\fR +configuration is contained in the +\fRou=SUDOers\fR +LDAP container. +.PP +Sudo first looks for the +\fRcn=defaults\fR +entry in the SUDOers container. +If found, the multi-valued +\fRsudoOption\fR +attribute is parsed in the same manner as a global +\fRDefaults\fR +line in +\fI@sysconfdir@/sudoers\fR. +In the following example, the +\fRSSH_AUTH_SOCK\fR +variable will be preserved in the environment for all users. +.nf +.sp +.RS 4n +dn: cn=defaults,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: defaults +description: Default sudoOption's go here +sudoOption: env_keep+=SSH_AUTH_SOCK +.RE +.fi +.PP +The equivalent of a sudoer in LDAP is a +\fRsudoRole\fR. +It consists of the following attributes: +.TP 6n +\fBsudoUser\fR +A user name, user-ID (prefixed with +\(oq#\(cq), +Unix group name or ID (prefixed with +\(oq%\(cq +or +\(oq%#\(cq +respectively), user netgroup (prefixed with +\(oq+\(cq), +or non-Unix group name or ID (prefixed with +\(oq%:\(cq +or +\(oq%:#\(cq +respectively). +User netgroups are matched using the user and domain members only; +the host member is not used when matching. +Non-Unix group support is only available when an appropriate +\fIgroup_plugin\fR +is defined in the global +\fIdefaults\fR +\fRsudoRole\fR +object. +.TP 6n +\fBsudoHost\fR +A host name, IP address, IP network, or host netgroup (prefixed with a +\(oq+\(cq). +The special value +\fRALL\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 +entry is preceded by an exclamation point, +\(oq\&!\(cq, +and the entry matches, the +\fRsudoRole\fR +in which it resides will be ignored. +Negated +\fRsudoHost\fR +entries are only supported by version 1.8.18 or higher. +.TP 6n +\fBsudoCommand\fR +A fully-qualified Unix command name with optional command line arguments, +potentially including globbing characters (aka wild cards). +If a command name is preceded by an exclamation point, +\(oq\&!\(cq, +the user will be prohibited from running that command. +.sp +The built-in command +\(lq\fRsudoedit\fR\(rq +is used to permit a user to run +\fBsudo\fR +with the +\fB\-e\fR +option (or as +\fBsudoedit\fR). +It may take command line arguments just as a normal command does. +Note that +\(lq\fRsudoedit\fR\(rq +is a command built into +\fBsudo\fR +itself and must be specified in without a leading path. +.sp +The special value +\fRALL\fR +will match any command. +.sp +If a command name is prefixed with a SHA-2 digest, it will +only be allowed if the digest matches. +This may be useful in situations where the user invoking +\fBsudo\fR +has write access to the command or its parent directory. +The following digest formats are supported: sha224, sha256, sha384 and sha512. +The digest name must be followed by a colon +(\(oq:\&\(cq) +and then the actual digest, in either hex or base64 format. +For example, given the following value for sudoCommand: +.nf +.sp +.RS 10n +sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ /bin/ls +.RE +.fi +.RS 6n +.sp +The user may only run +\fI/bin/ls\fR +if its sha224 digest matches the specified value. +Command digests are only supported by version 1.8.7 or higher. +.RE +.TP 6n +\fBsudoOption\fR +Identical in function to the global options described above, but +specific to the +\fRsudoRole\fR +in which it resides. +.TP 6n +\fBsudoRunAsUser\fR +A user name or uid (prefixed with +\(oq#\(cq) +that commands may be run as or a Unix group (prefixed with a +\(oq%\(cq) +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 +will match any user. +If a +\fRsudoRunAsUser\fR +entry is preceded by an exclamation point, +\(oq\&!\(cq, +and the entry matches, the +\fRsudoRole\fR +in which it resides will be ignored. +If +\fRsudoRunAsUser\fR +is specified but empty, it will match the invoking user. +If neither +\fRsudoRunAsUser\fR +nor +\fRsudoRunAsGroup\fR +are present, the value of the +\fIrunas_default\fR +\fRsudoOption\fR +is used (defaults to +\fR@runas_default@\fR). +.sp +The +\fRsudoRunAsUser\fR +attribute is only available in +\fBsudo\fR +versions +1.7.0 and higher. +Older versions of +\fBsudo\fR +use the +\fRsudoRunAs\fR +attribute instead. +Negated +\fRsudoRunAsUser\fR +entries are only supported by version 1.8.26 or higher. +.TP 6n +\fBsudoRunAsGroup\fR +A Unix group or gid (prefixed with +\(oq#\(cq) +that commands may be run as. +The special value +\fRALL\fR +will match any group. +If a +\fRsudoRunAsGroup\fR +entry is preceded by an exclamation point, +\(oq\&!\(cq, +and the entry matches, the +\fRsudoRole\fR +in which it resides will be ignored. +.sp +The +\fRsudoRunAsGroup\fR +attribute is only available in +\fBsudo\fR +versions +1.7.0 and higher. +Negated +\fRsudoRunAsGroup\fR +entries are only supported by version 1.8.26 or higher. +.TP 6n +\fBsudoNotBefore\fR +A timestamp in the form +\fRyyyymmddHHMMSSZ\fR +that can be used to provide a start date/time for when the +\fRsudoRole\fR +will be valid. +If multiple +\fRsudoNotBefore\fR +entries are present, the earliest is used. +Note that timestamps must be in Coordinated Universal Time (UTC), +not the local timezone. +The minute and seconds portions are optional, but some LDAP servers +require that they be present (contrary to the RFC). +.sp +The +\fRsudoNotBefore\fR +attribute is only available in +\fBsudo\fR +versions 1.7.5 and higher and must be explicitly enabled via the +\fBSUDOERS_TIMED\fR +option in +\fI@ldap_conf@\fR. +.TP 6n +\fBsudoNotAfter\fR +A timestamp in the form +\fRyyyymmddHHMMSSZ\fR +that indicates an expiration date/time, after which the +\fRsudoRole\fR +will no longer be valid. +If multiple +\fRsudoNotAfter\fR +entries are present, the last one is used. +Note that timestamps must be in Coordinated Universal Time (UTC), +not the local timezone. +The minute and seconds portions are optional, but some LDAP servers +require that they be present (contrary to the RFC). +.sp +The +\fRsudoNotAfter\fR +attribute is only available in +\fBsudo\fR +versions +1.7.5 and higher and must be explicitly enabled via the +\fBSUDOERS_TIMED\fR +option in +\fI@ldap_conf@\fR. +.TP 6n +\fBsudoOrder\fR +The +\fRsudoRole\fR +entries retrieved from the LDAP directory have no inherent order. +The +\fRsudoOrder\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 +attribute is chosen. +This corresponds to the +\(lqlast match\(rq +behavior of the sudoers file. +If the +\fRsudoOrder\fR +attribute is not present, a value of 0 is assumed. +.sp +The +\fRsudoOrder\fR +attribute is only available in +\fBsudo\fR +versions 1.7.5 and higher. +.PP +Each attribute listed above should contain a single value, but there +may be multiple instances of each attribute type. +A +\fRsudoRole\fR +must contain at least one +\fRsudoUser\fR, +\fRsudoHost\fR +and +\fRsudoCommand\fR. +.PP +The following example allows users in group wheel to run any command +on any host via +\fBsudo\fR: +.nf +.sp +.RS 4n +dn: cn=%wheel,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: %wheel +sudoUser: %wheel +sudoHost: ALL +sudoCommand: ALL +.RE +.fi +.SS "Anatomy of LDAP sudoers lookup" +When looking up a sudoer using LDAP there are only two or three +LDAP queries per invocation. +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 +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 +non-Unix groups and checks to see if the user belongs to any of them. +.PP +If timed entries are enabled with the +\fBSUDOERS_TIMED\fR +configuration directive, the LDAP queries include a sub-filter that +limits retrieval to entries that satisfy the time constraints, if any. +.PP +If the +\fBNETGROUP_BASE\fR +configuration directive is present (see +\fIConfiguring ldap.conf\fR +below), queries are performed to determine +the list of netgroups the user belongs to before the sudoers query. +This makes it possible to include netgroups in the sudoers query +string in the same manner as Unix groups. +The third query mentioned above is not performed unless a group provider +plugin is also configured. +The actual LDAP queries performed by +\fBsudo\fR +are as follows: +.TP 5n +1.\& +Match all +\fRnisNetgroup\fR +records with a +\fRnisNetgroupTriple\fR +containing the user, host and NIS domain. +The query will match +\fRnisNetgroupTriple\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 +that include the domain or for which there is no domain present. +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. +.TP 5n +2.\& +Repeated queries are performed to find any nested +\fRnisNetgroup\fR +records with a +\fRmemberNisNetgroup\fR +entry that refers to an already-matched record. +.PP +For sites with a large number of netgroups, using +\fBNETGROUP_BASE\fR +can significantly speed up +\fBsudo\fR's +execution time. +.SS "Differences between LDAP and non-LDAP sudoers" +One of the major differences between LDAP and file-based +\fIsudoers\fR +is that in LDAP, +\fBsudo\fR-specific +Aliases are not supported. +.PP +For the most part, there is little need for +\fBsudo\fR-specific +Aliases. +Unix groups, non-Unix groups (via the +\fIgroup_plugin\fR) +or user netgroups can be used in place of User_Aliases and Runas_Aliases. +Host netgroups can be used in place of Host_Aliases. +Since groups and netgroups can also be stored in LDAP there is no real need for +\fBsudo\fR-specific +aliases. +.PP +There are also some subtle differences in the way sudoers is handled +once in LDAP. +Probably the biggest is that according to the RFC, LDAP ordering +is arbitrary and you cannot expect that Attributes and Entries are +returned in any specific order. +.PP +The order in which different entries are applied can be controlled +using the +\fRsudoOrder\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 +takes precedence. +This is called paranoid behavior (not necessarily the most specific +match). +.PP +Here is an example: +.nf +.sp +.RS 4n +# /etc/sudoers: +# Allow all commands except shell +johnny ALL=(root) ALL,!/bin/sh +# Always allows all commands because ALL is matched last +puddles ALL=(root) !/bin/sh,ALL + +# LDAP equivalent of johnny +# Allows all commands except shell +dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com +objectClass: sudoRole +objectClass: top +cn: role1 +sudoUser: johnny +sudoHost: ALL +sudoCommand: ALL +sudoCommand: !/bin/sh + +# LDAP equivalent of puddles +# Notice that even though ALL comes last, it still behaves like +# role1 since the LDAP code assumes the more paranoid configuration +dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com +objectClass: sudoRole +objectClass: top +cn: role2 +sudoUser: puddles +sudoHost: ALL +sudoCommand: !/bin/sh +sudoCommand: ALL +.RE +.fi +.PP +Another difference is that it is not possible to use negation in a +sudoUser, sudoRunAsUser or sudoRunAsGroup attribute. +For example, the following attributes do not behave the way one might expect. +.nf +.sp +.RS 4n +# does not match all but joe +# rather, does not match anyone +sudoUser: !joe + +# does not match all but joe +# rather, matches everyone including Joe +sudoUser: ALL +sudoUser: !joe +.RE +.fi +.SS "Converting between file-based and LDAP sudoers" +The +cvtsudoers(1) +utility can be used to convert between file-based and LDAP +\fIsudoers\fR. +However, there are features in the file-based sudoers that have +no equivalent in LDAP-based sudoers (and vice versa). +These cannot be converted automatically. +.PP +For example, a Cmnd_Alias in a +\fIsudoers\fR +file may be converted to a +\fRsudoRole\fR +that contains multiple commands. +Multiple users and/or groups may be assigned to the +\fRsudoRole\fR. +.PP +Also, host, user, runas and command-based +\fRDefaults\fR +entries are not supported. +However, a +\fRsudoRole\fR +may contain one or more +\fRsudoOption\fR +attributes which can often serve the same purpose. +.PP +Consider the following +\fIsudoers\fR +lines: +.nf +.sp +.RS 4n +Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less +Defaults!PAGERS noexec +alice, bob ALL = ALL +.RE +.fi +.PP +In this example, alice and bob are allowed to run all commands, but +the commands listed in PAGERS will have the noexec flag set, +preventing shell escapes. +.PP +When converting this to LDAP, two sudoRole objects can be used: +.nf +.sp +.RS 4n +dn: cn=PAGERS,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: PAGERS +sudoUser: alice +sudoUser: bob +sudoHost: ALL +sudoCommand: /usr/bin/more +sudoCommand: /usr/bin/pg +sudoCommand: /usr/bin/less +sudoOption: noexec +sudoOrder: 900 + +dn: cn=ADMINS,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: ADMINS +sudoUser: alice +sudoUser: bob +sudoHost: ALL +sudoCommand: ALL +sudoOrder: 100 +.RE +.fi +.PP +In the LDAP version, the sudoOrder attribute is used to guarantee +that the PAGERS sudoRole with +\fInoexec\fR +has precedence. +Unlike the +\fIsudoers\fR +version, the LDAP version requires that all users for whom the restriction +should apply be assigned to the PAGERS sudoRole. +Using a Unix group or netgroup in PAGERS rather than listing each +user would make this easier to maintain. +.PP +Per-user +\fRDefaults\fR +entries can be emulated by using one or more sudoOption attributes +in a sudoRole. +Consider the following +\fIsudoers\fR +lines: +.nf +.sp +.RS 4n +User_Alias ADMINS = john, sally +Defaults:ADMINS !authenticate +ADMINS ALL = (ALL:ALL) ALL +.RE +.fi +.PP +In this example, john and sally are allowed to run any command +as any user or group. +.PP +When converting this to LDAP, we can use a Unix group instead +of the User_Alias. +.nf +.sp +.RS 4n +dn: cn=admins,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: admins +sudoUser: %admin +sudoHost: ALL +sudoRunAsUser: ALL +sudoRunAsGroup: ALL +sudoCommand: ALL +sudoOption: !authenticate +.RE +.fi +.PP +This assumes that users john and sally are members of the +\(lqadmins\(rq +Unix group. +.SS "Sudoers schema" +In order to use +\fBsudo\fR's +LDAP support, the +\fBsudo\fR +schema must be +installed on your LDAP server. +In addition, be sure to index the +\fRsudoUser\fR +attribute. +.PP +The +\fBsudo\fR +distribution includes versions of the +\fBsudoers\fR +schema for multiple LDAP servers: +.TP 6n +\fIschema.OpenLDAP\fR +OpenLDAP slapd and +OpenBSD +ldapd +.TP 6n +\fIschema.olcSudo\fR +OpenLDAP slapd 2.3 and higher when on-line configuration is enabled +.TP 6n +\fIschema.iPlanet\fR +Netscape-derived servers such as the iPlanet, Oracle, +and 389 Directory Servers +.TP 6n +\fIschema.ActiveDirectory\fR +Microsoft Active Directory +.PP +The schema in OpenLDAP format is also included in the +\fIEXAMPLES\fR +section. +.SS "Configuring ldap.conf" +Sudo reads the +\fI@ldap_conf@\fR +file for LDAP-specific configuration. +Typically, this file is shared between different LDAP-aware clients. +As such, most of the settings are not +\fBsudo\fR-specific. +Note that +\fBsudo\fR +parses +\fI@ldap_conf@\fR +itself and may support options that differ from those described in the +system's +ldap.conf(@mansectform@) +manual. +The path to +\fIldap.conf\fR +may be overridden via the +\fIldap_conf\fR +plugin argument in +sudo.conf(@mansectform@). +.PP +Also note that on systems using the OpenLDAP libraries, default +values specified in +\fI/etc/openldap/ldap.conf\fR +or the user's +\fI.ldaprc\fR +files are not used. +.PP +\fBsudo\fR +supports a variety of LDAP library implementations, including +OpenLDAP, Netscape-derived (also used by Solaris and HP-UX), and +IBM LDAP (aka Tivoli). +Some options are specific to certain LDAP implementations or have +implementation-specific behavior. +These differences are noted below where applicable. +.PP +Only those options explicitly listed in +\fI@ldap_conf@\fR +as being supported by +\fBsudo\fR +are honored. +Configuration options are listed below in upper case but are parsed +in a case-independent manner. +.PP +Lines beginning with a pound sign +(\(oq#\(cq) +are ignored. +Leading white space is removed from the beginning of lines. +.TP 6n +\fBBIND_TIMELIMIT\fR \fIseconds\fR +The +\fBBIND_TIMELIMIT\fR +parameter specifies the amount of time, in seconds, to wait while trying +to connect to an LDAP server. +If multiple +\fBURI\fRs +or +\fBHOST\fRs +are specified, this is the amount of time to wait before trying +the next one in the list. +.TP 6n +\fBBINDDN\fR \fIDN\fR +The +\fBBINDDN\fR +parameter specifies the identity, in the form of a Distinguished Name (DN), +to use when performing LDAP operations. +If not specified, LDAP operations are performed with an anonymous identity. +By default, most LDAP servers will allow anonymous access. +.TP 6n +\fBBINDPW\fR \fIsecret\fR +The +\fBBINDPW\fR +parameter specifies the password to use when performing LDAP operations. +This is typically used in conjunction with the +\fBBINDDN\fR +parameter. +The +\fIsecret\fR +may be a plain text password or a base64-encoded string with a +\(lqbase64:\(rq +prefix. +For example: +.nf +.sp +.RS 10n +BINDPW base64:dGVzdA== +.RE +.fi +.RS 6n +.sp +If a plain text password is used, it should be a simple string without quotes. +Plain text passwords may not include the comment character +(\(oq#\(cq) +and the escaping of special characters with a backslash +(\(oq\e\(cq) +is not supported. +.RE +.TP 6n +\fBDEREF\fR \fInever/searching/finding/always\fR +How alias dereferencing is to be performed when searching. +See the +ldap.conf(@mansectform@) +manual for a full description of this option. +.TP 6n +\fBHOST\fR \fIname[:port] ...\fR +If no +\fBURI\fR +is specified (see below), the +\fBHOST\fR +parameter specifies a white space-delimited list of LDAP servers to connect to. +Each host may include an optional +\fIport\fR +separated by a colon +(\(oq:\&\(cq). +The +\fBHOST\fR +parameter is deprecated in favor of the +\fBURI\fR +specification and is included for backward compatibility only. +.TP 6n +\fBKRB5_CCNAME\fR \fIfile name\fR +The path to the Kerberos 5 credential cache to use when authenticating +with the remote server. +.sp +This option is only relevant when using SASL authentication (see below). +.TP 6n +\fBLDAP_VERSION\fR \fInumber\fR +The version of the LDAP protocol to use when connecting to the server. +The default value is protocol version 3. +.TP 6n +\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. +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 +object containing a +\fRsudoUser\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 +object by its +\fRnisNetgroupTriple\fR +member. +OpenLDAP's +\fBslapd\fR +requires the following change to the +\fRnisNetgroupTriple\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 ) +.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 +or +\fR(&(attribute=value)(attribute2=value2))\fR. +The default search filter is: +\fRobjectClass=nisNetgroup\fR. +If +\fIldap_filter\fR +is omitted, no search filter will be used. +.sp +This option is only used when querying netgroups directly via LDAP. +.TP 6n +\fBNETWORK_TIMEOUT\fR \fIseconds\fR +An alias for +\fBBIND_TIMELIMIT\fR +provided for OpenLDAP compatibility. +.TP 6n +\fBPORT\fR \fIport_number\fR +If no +\fBURI\fR +is specified, the +\fBPORT\fR +parameter specifies the default port to connect to on the LDAP server if a +\fBHOST\fR +parameter does not specify the port itself. +If no +\fBPORT\fR +parameter is used, the default is port 389 for LDAP and port 636 for LDAP +over TLS (SSL). +The +\fBPORT\fR +parameter is deprecated in favor of the +\fBURI\fR +specification and is included for backward compatibility only. +.TP 6n +\fBROOTBINDDN\fR \fIDN\fR +The +\fBROOTBINDDN\fR +parameter specifies the identity, in the form of a Distinguished Name (DN), +to use when performing privileged LDAP operations, such as +\fIsudoers\fR +queries. +The password corresponding to the identity should be stored in the +or the path specified by the +\fIldap_secret\fR +plugin argument in +sudo.conf(@mansectform@), +which defaults to +\fI@ldap_secret@\fR. +If no +\fBROOTBINDDN\fR +is specified, the +\fBBINDDN\fR +identity is used (if any). +.TP 6n +\fBROOTUSE_SASL\fR \fIon/true/yes/off/false/no\fR +Enable +\fBROOTUSE_SASL\fR +to enable SASL authentication when connecting +to an LDAP server from a privileged process, such as +\fBsudo\fR. +.TP 6n +\fBSASL_AUTH_ID\fR \fIidentity\fR +The SASL user name to use when connecting to the LDAP server. +By default, +\fBsudo\fR +will use an anonymous connection. +.sp +This option is only relevant when using SASL authentication. +.TP 6n +\fBSASL_MECH\fR \fImechanisms\fR +A white space-delimited list of SASL authentication mechanisms to use. +By default, +\fBsudo\fR +will use +\fRGSSAPI\fR +authentication. +.TP 6n +\fBSASL_SECPROPS\fR \fInone/properties\fR +SASL security properties or +\fInone\fR +for no properties. +See the SASL programmer's manual for details. +.sp +This option is only relevant when using SASL authentication. +.TP 6n +\fBSSL\fR \fIon/true/yes/off/false/no\fR +If the +\fBSSL\fR +parameter is set to +\fRon\fR, +\fRtrue\fR +\fRor\fR +\fRyes\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 +\fBSSL\fR \fIstart_tls\fR +If the +\fBSSL\fR +parameter is set to +\fRstart_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 +communications. +This parameter is only supported by LDAP servers that honor the +\fIstart_tls\fR +extension, such as the OpenLDAP and IBM Tivoli Directory servers. +.TP 6n +\fBSUDOERS_BASE\fR \fIbase\fR +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. +Multiple +\fBSUDOERS_BASE\fR +lines may be specified, in which case they are queried in the order specified. +.TP 6n +\fBSUDOERS_DEBUG\fR \fIdebug_level\fR +This sets the debug level for +\fBsudo\fR +LDAP queries. +Debugging information is printed to the standard error. +A value of 1 results in a moderate amount of debugging information. +A value of 2 shows the results of the matches themselves. +This parameter should not be set in a production environment as the +extra information is likely to confuse users. +.sp +The +\fBSUDOERS_DEBUG\fR +parameter is deprecated and will be removed in a future release. +The same information is now logged via the +\fBsudo\fR +debugging framework using the +\(lqldap\(rq +subsystem at priorities +\fIdiag\fR +and +\fIinfo\fR +for +\fIdebug_level\fR +values 1 and 2 respectively. +See the +sudo.conf(@mansectform@) +manual for details on how to configure +\fBsudo\fR +debugging. +.TP 6n +\fBSUDOERS_SEARCH_FILTER\fR \fIldap_filter\fR +An LDAP filter which is used to restrict the set of records returned +when performing a +\fBsudo\fR +LDAP query. +Typically, this is of the +form +\fRattribute=value\fR +or +\fR(&(attribute=value)(attribute2=value2))\fR. +The default search filter is: +\fRobjectClass=sudoRole\fR. +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 +and +\fRsudoNotAfter\fR +attributes that implement time-dependent sudoers entries. +.TP 6n +\fBTIMELIMIT\fR \fIseconds\fR +The +\fBTIMELIMIT\fR +parameter specifies the amount of time, in seconds, to wait for a +response to an LDAP query. +.TP 6n +\fBTIMEOUT\fR \fIseconds\fR +The +\fBTIMEOUT\fR +parameter specifies the amount of time, in seconds, to wait for a +response from the various LDAP APIs. +.TP 6n +\fBTLS_CACERT\fR \fIfile name\fR +An alias for +\fBTLS_CACERTFILE\fR +for OpenLDAP compatibility. +.TP 6n +\fBTLS_CACERTFILE\fR \fIfile name\fR +The path to a certificate authority bundle which contains the certificates +for all the Certificate Authorities the client knows to be valid, e.g., +\fI/etc/ssl/ca-bundle.pem\fR. +.sp +This option is only supported by the OpenLDAP libraries. +Netscape-derived LDAP libraries use the same certificate +database for CA and client certificates (see +\fBTLS_CERT\fR). +.TP 6n +\fBTLS_CACERTDIR\fR \fIdirectory\fR +Similar to +\fBTLS_CACERTFILE\fR +but instead of a file, it is a directory containing individual +Certificate Authority certificates, e.g., +\fI/etc/ssl/certs\fR. +The directory specified by +\fBTLS_CACERTDIR\fR +is checked after +\fBTLS_CACERTFILE\fR. +.sp +This option is only supported by the OpenLDAP libraries. +.TP 6n +\fBTLS_CERT\fR \fIfile name\fR +The path to a file containing the client certificate which can +be used to authenticate the client to the LDAP server. +The certificate type depends on the LDAP libraries used. +.PP +.RS 6n +.PD 0 +.TP 6n +OpenLDAP: +\fRtls_cert /etc/ssl/client_cert.pem\fR +.PD +.TP 6n +Netscape-derived: +\fRtls_cert /var/ldap/cert7.db\fR +.TP 6n +IBM LDAP: +Unused, the key database specified by +\fBTLS_KEY\fR +contains both keys and certificates. +.PP +When using Netscape-derived libraries, this file may also contain +Certificate Authority certificates. +.RE +.TP 6n +\fBTLS_CHECKPEER\fR \fIon/true/yes/off/false/no\fR +If enabled, +\fBTLS_CHECKPEER\fR +will cause the LDAP server's TLS certificated to be verified. +If the server's TLS certificate cannot be verified (usually because it +is signed by an unknown certificate authority), +\fBsudo\fR +will be unable to connect to it. +If +\fBTLS_CHECKPEER\fR +is disabled, no check is made. +Note that disabling the check creates an opportunity for man-in-the-middle +attacks since the server's identity will not be authenticated. +If possible, the CA's certificate should be installed locally so it can +be verified. +.sp +This option is not supported by the IBM LDAP libraries. +.TP 6n +\fBTLS_KEY\fR \fIfile name\fR +The path to a file containing the private key which matches the +certificate specified by +\fBTLS_CERT\fR. +The private key must not be password-protected. +The key type depends on the LDAP libraries used. +.PP +.RS 6n +.PD 0 +.TP 6n +OpenLDAP: +\fRtls_key /etc/ssl/client_key.pem\fR +.PD +.TP 6n +Netscape-derived: +\fRtls_key /var/ldap/key3.db\fR +.TP 6n +IBM LDAP: +\fRtls_key /usr/ldap/ldapkey.kdb\fR +.PP +When using IBM LDAP libraries, this file may also contain +Certificate Authority and client certificates and may be encrypted. +.RE +.TP 6n +\fBTLS_CIPHERS\fR \fIcipher list\fR +The +\fBTLS_CIPHERS\fR +parameter allows the administer to restrict which encryption algorithms +may be used for TLS (SSL) connections. +See the OpenLDAP or IBM Tivoli Directory Server manual for a list of valid +ciphers. +.sp +This option is not supported by Netscape-derived libraries. +.TP 6n +\fBTLS_KEYPW\fR \fIsecret\fR +The +\fBTLS_KEYPW\fR +contains the password used to decrypt the key database on clients +using the IBM LDAP library. +The +\fIsecret\fR +may be a plain text password or a base64-encoded string with a +\(lqbase64:\(rq +prefix. +For example: +.nf +.sp +.RS 10n +TLS_KEYPW base64:dGVzdA== +.RE +.fi +.RS 6n +.sp +If a plain text password is used, it should be a simple string without quotes. +Plain text passwords may not include the comment character +(\(oq#\(cq) +and the escaping of special characters with a backslash +(\(oq\e\(cq) +is not supported. +If this option is used, +\fI@ldap_conf@\fR +must not be world-readable to avoid exposing the password. +Alternately, a +\fIstash file\fR +can be used to store the password in encrypted form (see below). +.sp +If no +\fBTLS_KEYPW\fR +is specified, a +\fIstash file\fR +will be used if it exists. +The +\fIstash file\fR +must have the same path as the file specified by +\fBTLS_KEY\fR, +but use a +\fR.sth\fR +file extension instead of +\fR.kdb\fR, +e.g., +\fRldapkey.sth\fR. +The default +\fRldapkey.kdb\fR +that ships with the IBM Tivoli Directory Server is encrypted with the password +\fRssl_password\fR. +The +\fIgsk8capicmd\fR +utility can be used to manage the key database and create a +\fIstash file\fR. +.sp +This option is only supported by the IBM LDAP libraries. +.RE +.TP 6n +\fBTLS_REQCERT\fR \fIlevel\fR +The +\fBTLS_REQCERT\fR +parameter controls how the LDAP server's TLS certificated will be +verified (if at all). +If the server's TLS certificate cannot be verified (usually because it +is signed by an unknown certificate authority), +\fBsudo\fR +will be unable to connect to it. +The following +\fIlevel\fR +values are supported: +.RS 10n +.TP 10n +never +The server certificate will not be requested or checked. +.TP 10n +allow +The server certificate will be requested. +A missing or invalid certificate is ignored and not considered an error. +.TP 10n +try +The server certificate will be requested. +A missing certificate is ignored but an invalid certificate will +result in a connection error. +.TP 10n +demand | \fIhard\fR +The server certificate will be requested. +A missing or invalid certificate will result in a connection error. +This is the default behavior. +.RE +.RS 6n +.sp +This option is only supported by the OpenLDAP libraries. +Other LDAP libraries only support the +\fBTLS_CHECKPEER\fR +parameter. +.RE +.TP 6n +\fBTLS_RANDFILE\fR \fIfile name\fR +The +\fBTLS_RANDFILE\fR +parameter specifies the path to an entropy source for systems that lack +a random device. +It is generally used in conjunction with +\fIprngd\fR +or +\fIegd\fR. +.sp +This option is only supported by the OpenLDAP libraries. +.TP 6n +\fBURI\fR \fIldap[s]://[hostname[:port]] ...\fR +Specifies a white space-delimited list of one or more URIs describing +the LDAP server(s) to connect to. +The +\fIprotocol\fR +may be either +\fIldap\fR +\fIldaps\fR, +the latter being for servers that support TLS (SSL) encryption. +If no +\fIport\fR +is specified, the default is port 389 for +\fRldap://\fR +or port 636 for +\fRldaps://\fR. +If no +\fIhostname\fR +is specified, +\fBsudo\fR +will connect to +\fIlocalhost\fR. +Multiple +\fBURI\fR +lines are treated identically to a +\fBURI\fR +line containing multiple entries. +Only systems using the OpenSSL libraries support the mixing of +\fRldap://\fR +and +\fRldaps://\fR +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. +.TP 6n +\fBUSE_SASL\fR \fIon/true/yes/off/false/no\fR +Enable +\fBUSE_SASL\fR +for LDAP servers that support SASL authentication. +.TP 6n +\fBROOTSASL_AUTH_ID\fR \fIidentity\fR +The SASL user name to use when +\fBROOTUSE_SASL\fR +is enabled. +.PP +See the +\fIldap.conf\fR +entry in the +\fIEXAMPLES\fR +section. +.SS "Configuring nsswitch.conf" +Unless it is disabled at build time, +\fBsudo\fR +consults the Name Service Switch file, +\fI@nsswitch_conf@\fR, +to specify the +\fIsudoers\fR +search order. +Sudo looks for a line beginning with +\fRsudoers\fR: +and uses this to determine the search order. +Note that +\fBsudo\fR +does +not stop searching after the first match and later matches take +precedence over earlier ones. +The following sources are recognized: +.PP +.RS 4n +.PD 0 +.TP 10n +files +read sudoers from +\fI@sysconfdir@/sudoers\fR +.TP 10n +ldap +read sudoers from LDAP +.RE +.PD +.PP +In addition, the entry +\fR[NOTFOUND=return]\fR +will short-circuit the search if the user was not found in the +preceding source. +.PP +To consult LDAP first followed by the local sudoers file (if it +exists), use: +.nf +.sp +.RS 4n +sudoers: ldap files +.RE +.fi +.PP +The local +\fIsudoers\fR +file can be ignored completely by using: +.nf +.sp +.RS 4n +sudoers: ldap +.RE +.fi +.PP +If the +\fI@nsswitch_conf@\fR +file is not present or there is no sudoers line, the following +default is assumed: +.nf +.sp +.RS 4n +sudoers: files +.RE +.fi +.PP +Note that +\fI@nsswitch_conf@\fR +is supported even when the underlying operating system does not use +an nsswitch.conf file, except on AIX (see below). +.SS "Configuring netsvc.conf" +On AIX systems, the +\fI@netsvc_conf@\fR +file is consulted instead of +\fI@nsswitch_conf@\fR. +\fBsudo\fR +simply treats +\fInetsvc.conf\fR +as a variant of +\fInsswitch.conf\fR; +information in the previous section unrelated to the file format +itself still applies. +.PP +To consult LDAP first followed by the local sudoers file (if it +exists), use: +.nf +.sp +.RS 4n +sudoers = ldap, files +.RE +.fi +.PP +The local +\fIsudoers\fR +file can be ignored completely by using: +.nf +.sp +.RS 4n +sudoers = ldap +.RE +.fi +.PP +To treat LDAP as authoritative and only use the local sudoers file +if the user is not present in LDAP, use: +.nf +.sp +.RS 4n +sudoers = ldap = auth, files +.RE +.fi +.PP +Note that in the above example, the +\fRauth\fR +qualifier only affects user lookups; both LDAP and +\fIsudoers\fR +will be queried for +\fRDefaults\fR +entries. +.PP +If the +\fI@netsvc_conf@\fR +file is not present or there is no sudoers line, the following +default is assumed: +.nf +.sp +.RS 4n +sudoers = files +.RE +.fi +.SS "Integration with sssd" +On systems with the +\fISystem Security Services Daemon\fR +(SSSD) and where +\fBsudo\fR +has been built with SSSD support, +it is possible to use SSSD to cache LDAP +\fIsudoers\fR +rules. +To use SSSD as the +\fIsudoers\fR +source, you should use +\fRsss\fR +instead of +\fRldap\fR +for the sudoers entry in +\fI@nsswitch_conf@\fR. +Note that the +\fI@ldap_conf@\fR +file is not used by the SSSD +\fBsudo\fR +back end. +Please see +sssd-sudo(@mansectform@) +for more information on configuring +\fBsudo\fR +to work with SSSD. +.SH "FILES" +.TP 26n +\fI@ldap_conf@\fR +LDAP configuration file +.TP 26n +\fI@nsswitch_conf@\fR +determines sudoers source order +.TP 26n +\fI@netsvc_conf@\fR +determines sudoers source order on AIX +.SH "EXAMPLES" +.SS "Example ldap.conf" +.nf +.RS 2n +# Either specify one or more URIs or one or more host:port pairs. +# If neither is specified sudo will default to localhost, port 389. +# +#host ldapserver +#host ldapserver1 ldapserver2:390 +# +# Default port if host is specified without one, defaults to 389. +#port 389 +# +# URI will override the host and port settings. +uri ldap://ldapserver +#uri ldaps://secureldapserver +#uri ldaps://secureldapserver ldap://ldapserver +# +# The amount of time, in seconds, to wait while trying to connect to +# an LDAP server. +bind_timelimit 30 +# +# The amount of time, in seconds, to wait while performing an LDAP query. +timelimit 30 +# +# Must be set or sudo will ignore LDAP; may be specified multiple times. +sudoers_base ou=SUDOers,dc=my-domain,dc=com +# +# verbose sudoers matching from ldap +#sudoers_debug 2 +# +# Enable support for time-based entries in sudoers. +#sudoers_timed yes +# +# optional proxy credentials +#binddn <who to search as> +#bindpw <password> +#rootbinddn <who to search as, uses /etc/ldap.secret for bindpw> +# +# LDAP protocol version, defaults to 3 +#ldap_version 3 +# +# Define if you want to use an encrypted LDAP connection. +# Typically, you must also set the port to 636 (ldaps). +#ssl on +# +# Define if you want to use port 389 and switch to +# encryption before the bind credentials are sent. +# Only supported by LDAP servers that support the start_tls +# extension such as OpenLDAP. +#ssl start_tls +# +# Additional TLS options follow that allow tweaking of the +# SSL/TLS connection. +# +#tls_checkpeer yes # verify server SSL certificate +#tls_checkpeer no # ignore server SSL certificate +# +# If you enable tls_checkpeer, specify either tls_cacertfile +# or tls_cacertdir. Only supported when using OpenLDAP. +# +#tls_cacertfile /etc/certs/trusted_signers.pem +#tls_cacertdir /etc/certs +# +# For systems that don't have /dev/random +# use this along with PRNGD or EGD.pl to seed the +# random number pool to generate cryptographic session keys. +# Only supported when using OpenLDAP. +# +#tls_randfile /etc/egd-pool +# +# You may restrict which ciphers are used. Consult your SSL +# documentation for which options go here. +# Only supported when using OpenLDAP. +# +#tls_ciphers <cipher-list> +# +# Sudo can provide a client certificate when communicating to +# the LDAP server. +# Tips: +# * Enable both lines at the same time. +# * Do not password protect the key file. +# * Ensure the keyfile is only readable by root. +# +# For OpenLDAP: +#tls_cert /etc/certs/client_cert.pem +#tls_key /etc/certs/client_key.pem +# +# For Netscape-derived LDAP, tls_cert and tls_key may specify either +# a directory, in which case the files in the directory must have the +# default names (e.g., cert8.db and key4.db), or the path to the cert +# and key files themselves. However, a bug in version 5.0 of the LDAP +# SDK will prevent specific file names from working. For this reason +# it is suggested that tls_cert and tls_key be set to a directory, +# not a file name. +# +# The certificate database specified by tls_cert may contain CA certs +# and/or the client's cert. If the client's cert is included, tls_key +# should be specified as well. +# For backward compatibility, "sslpath" may be used in place of tls_cert. +#tls_cert /var/ldap +#tls_key /var/ldap +# +# If using SASL authentication for LDAP (OpenSSL) +# use_sasl yes +# sasl_auth_id <SASL user name> +# rootuse_sasl yes +# rootsasl_auth_id <SASL user name for root access> +# sasl_secprops none +# krb5_ccname /etc/.ldapcache +.RE +.fi +.SS "Sudoers schema for OpenLDAP" +The following schema, in OpenLDAP format, is included with +\fBsudo\fR +source and binary distributions as +\fIschema.OpenLDAP\fR. +Simply copy +it to the schema directory (e.g., +\fI/etc/openldap/schema\fR), +add the proper +\fRinclude\fR +line in +\fIslapd.conf\fR +and restart +\fBslapd\fR. +Sites using the optional on-line configuration supported by OpenLDAP 2.3 +and higher should apply the +\fIschema.olcSudo\fR +file instead. +.nf +.sp +.RS 2n +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +attributetype ( 1.3.6.1.4.1.15953.9.1.4 + NAME 'sudoRunAs' + DESC 'User(s) impersonated by sudo' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 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 ) + +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 ) + +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +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 ) + +objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL + DESC 'Sudoer Entries' + MUST ( cn ) + MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ + sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $ + sudoOrder $ description ) + ) +.RE +.fi +.SH "SEE ALSO" +cvtsudoers(1), +ldap.conf(@mansectform@), +sssd-sudo(@mansectform@), +sudo.conf(@mansectform@), +sudoers(@mansectform@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "CAVEATS" +Note that there are differences in the way that LDAP-based +\fIsudoers\fR +is parsed compared to file-based +\fIsudoers\fR. +See the +\fIDifferences between LDAP and non-LDAP sudoers\fR +section for more information. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers.ldap.mdoc.in b/doc/sudoers.ldap.mdoc.in new file mode 100644 index 0000000..ac32bfa --- /dev/null +++ b/doc/sudoers.ldap.mdoc.in @@ -0,0 +1,1588 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2003-2020 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. +.\" +.Dd October 29, 2020 +.Dt SUDOERS.LDAP @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudoers.ldap +.Nd sudo LDAP configuration +.Sh DESCRIPTION +In addition to the standard +.Em sudoers +file, +.Nm sudo +may be configured +via LDAP. +This can be especially useful for synchronizing +.Em sudoers +in a large, distributed environment. +.Pp +Using LDAP for +.Em sudoers +has several benefits: +.Bl -bullet -width 1n +.It +.Nm sudo +no longer needs to read +.Em sudoers +in its entirety. +When LDAP is used, there are only two or three LDAP queries per invocation. +This makes it especially fast and particularly usable in LDAP environments. +.It +.Nm sudo +no longer exits if there is a typo in +.Em sudoers . +It is not possible to load LDAP data into the server that does +not conform to the sudoers schema, so proper syntax is guaranteed. +It is still possible to have typos in a user or host name, but +this will not prevent +.Nm sudo +from running. +.It +It is possible to specify per-entry options that override the global +default options. +.Pa @sysconfdir@/sudoers +only supports default options and limited options associated with +user/host/commands/aliases. +The syntax is complicated and can be difficult for users to understand. +Placing the options directly in the entry is more natural. +.It +The +.Nm visudo +program is no longer needed. +.Nm visudo +provides locking and syntax checking of the +.Pa @sysconfdir@/sudoers +file. +Since LDAP updates are atomic, locking is no longer necessary. +Because syntax is checked when the data is inserted into LDAP, there +is no need for a specialized tool to check syntax. +.El +.Ss SUDOers LDAP container +The +.Em sudoers +configuration is contained in the +.Li ou=SUDOers +LDAP container. +.Pp +Sudo first looks for the +.Li cn=defaults +entry in the SUDOers container. +If found, the multi-valued +.Li sudoOption +attribute is parsed in the same manner as a global +.Li Defaults +line in +.Pa @sysconfdir@/sudoers . +In the following example, the +.Ev SSH_AUTH_SOCK +variable will be preserved in the environment for all users. +.Bd -literal -offset 4n +dn: cn=defaults,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: defaults +description: Default sudoOption's go here +sudoOption: env_keep+=SSH_AUTH_SOCK +.Ed +.Pp +The equivalent of a sudoer in LDAP is a +.Li sudoRole . +It consists of the following attributes: +.Bl -tag -width 4n +.It Sy sudoUser +A user name, user-ID (prefixed with +.Ql # ) , +Unix group name or ID (prefixed with +.Ql % +or +.Ql %# +respectively), user netgroup (prefixed with +.Ql + ) , +or non-Unix group name or ID (prefixed with +.Ql %: +or +.Ql %:# +respectively). +User netgroups are matched using the user and domain members only; +the host member is not used when matching. +Non-Unix group support is only available when an appropriate +.Em group_plugin +is defined in the global +.Em defaults +.Li sudoRole +object. +.It Sy sudoHost +A host name, IP address, IP network, or host netgroup (prefixed with a +.Ql + ) . +The special value +.Li 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 +entry is preceded by an exclamation point, +.Ql \&! , +and the entry matches, the +.Li sudoRole +in which it resides will be ignored. +Negated +.Li 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, +potentially including globbing characters (aka wild cards). +If a command name is preceded by an exclamation point, +.Ql \&! , +the user will be prohibited from running that command. +.Pp +The built-in command +.Dq Li sudoedit +is used to permit a user to run +.Nm sudo +with the +.Fl e +option (or as +.Nm sudoedit ) . +It may take command line arguments just as a normal command does. +Note that +.Dq Li sudoedit +is a command built into +.Nm sudo +itself and must be specified in without a leading path. +.Pp +The special value +.Li ALL +will match any command. +.Pp +If a command name is prefixed with a SHA-2 digest, it will +only be allowed if the digest matches. +This may be useful in situations where the user invoking +.Nm sudo +has write access to the command or its parent directory. +The following digest formats are supported: sha224, sha256, sha384 and sha512. +The digest name must be followed by a colon +.Pq Ql :\& +and then the actual digest, in either hex or base64 format. +For example, given the following value for sudoCommand: +.Bd -literal -offset 4n +sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ /bin/ls +.Ed +.Pp +The user may only run +.Pa /bin/ls +if its sha224 digest matches the specified value. +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 +in which it resides. +.It Sy sudoRunAsUser +A user name or uid (prefixed with +.Ql # ) +that commands may be run as or a Unix group (prefixed with a +.Ql % ) +or user netgroup (prefixed with a +.Ql + ) +that contains a list of users that commands may be run as. +The special value +.Li ALL +will match any user. +If a +.Li sudoRunAsUser +entry is preceded by an exclamation point, +.Ql \&! , +and the entry matches, the +.Li sudoRole +in which it resides will be ignored. +If +.Li sudoRunAsUser +is specified but empty, it will match the invoking user. +If neither +.Li sudoRunAsUser +nor +.Li sudoRunAsGroup +are present, the value of the +.Em runas_default +.Li sudoOption +is used (defaults to +.Li @runas_default@ ) . +.Pp +The +.Li sudoRunAsUser +attribute is only available in +.Nm sudo +versions +1.7.0 and higher. +Older versions of +.Nm sudo +use the +.Li sudoRunAs +attribute instead. +Negated +.Li sudoRunAsUser +entries are only supported by version 1.8.26 or higher. +.It Sy sudoRunAsGroup +A Unix group or gid (prefixed with +.Ql # ) +that commands may be run as. +The special value +.Li ALL +will match any group. +If a +.Li sudoRunAsGroup +entry is preceded by an exclamation point, +.Ql \&! , +and the entry matches, the +.Li sudoRole +in which it resides will be ignored. +.Pp +The +.Li sudoRunAsGroup +attribute is only available in +.Nm sudo +versions +1.7.0 and higher. +Negated +.Li sudoRunAsGroup +entries are only supported by version 1.8.26 or higher. +.It Sy sudoNotBefore +A timestamp in the form +.Li yyyymmddHHMMSSZ +that can be used to provide a start date/time for when the +.Li sudoRole +will be valid. +If multiple +.Li sudoNotBefore +entries are present, the earliest is used. +Note that timestamps must be in Coordinated Universal Time (UTC), +not the local timezone. +The minute and seconds portions are optional, but some LDAP servers +require that they be present (contrary to the RFC). +.Pp +The +.Li sudoNotBefore +attribute is only available in +.Nm sudo +versions 1.7.5 and higher and must be explicitly enabled via the +.Sy SUDOERS_TIMED +option in +.Pa @ldap_conf@ . +.It Sy sudoNotAfter +A timestamp in the form +.Li yyyymmddHHMMSSZ +that indicates an expiration date/time, after which the +.Li sudoRole +will no longer be valid. +If multiple +.Li sudoNotAfter +entries are present, the last one is used. +Note that timestamps must be in Coordinated Universal Time (UTC), +not the local timezone. +The minute and seconds portions are optional, but some LDAP servers +require that they be present (contrary to the RFC). +.Pp +The +.Li sudoNotAfter +attribute is only available in +.Nm sudo +versions +1.7.5 and higher and must be explicitly enabled via the +.Sy SUDOERS_TIMED +option in +.Pa @ldap_conf@ . +.It Sy sudoOrder +The +.Li sudoRole +entries retrieved from the LDAP directory have no inherent order. +The +.Li 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 +attribute is chosen. +This corresponds to the +.Dq last match +behavior of the sudoers file. +If the +.Li sudoOrder +attribute is not present, a value of 0 is assumed. +.Pp +The +.Li sudoOrder +attribute is only available in +.Nm sudo +versions 1.7.5 and higher. +.El +.Pp +Each attribute listed above should contain a single value, but there +may be multiple instances of each attribute type. +A +.Li sudoRole +must contain at least one +.Li sudoUser , +.Li sudoHost +and +.Li sudoCommand . +.Pp +The following example allows users in group wheel to run any command +on any host via +.Nm sudo : +.Bd -literal -offset 4n +dn: cn=%wheel,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: %wheel +sudoUser: %wheel +sudoHost: ALL +sudoCommand: ALL +.Ed +.Ss Anatomy of LDAP sudoers lookup +When looking up a sudoer using LDAP there are only two or three +LDAP queries per invocation. +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 +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 +non-Unix groups and checks to see if the user belongs to any of them. +.Pp +If timed entries are enabled with the +.Sy SUDOERS_TIMED +configuration directive, the LDAP queries include a sub-filter that +limits retrieval to entries that satisfy the time constraints, if any. +.Pp +If the +.Sy NETGROUP_BASE +configuration directive is present (see +.Sx Configuring ldap.conf +below), queries are performed to determine +the list of netgroups the user belongs to before the sudoers query. +This makes it possible to include netgroups in the sudoers query +string in the same manner as Unix groups. +The third query mentioned above is not performed unless a group provider +plugin is also configured. +The actual LDAP queries performed by +.Nm sudo +are as follows: +.Bl -enum +.It +Match all +.Li nisNetgroup +records with a +.Li nisNetgroupTriple +containing the user, host and NIS domain. +The query will match +.Li 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 +that include the domain or for which there is no domain present. +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 . +.It +Repeated queries are performed to find any nested +.Li nisNetgroup +records with a +.Li memberNisNetgroup +entry that refers to an already-matched record. +.El +.Pp +For sites with a large number of netgroups, using +.Sy NETGROUP_BASE +can significantly speed up +.Nm sudo Ns 's +execution time. +.Ss Differences between LDAP and non-LDAP sudoers +One of the major differences between LDAP and file-based +.Em sudoers +is that in LDAP, +.Nm sudo Ns -specific +Aliases are not supported. +.Pp +For the most part, there is little need for +.Nm sudo Ns -specific +Aliases. +Unix groups, non-Unix groups (via the +.Em group_plugin ) +or user netgroups can be used in place of User_Aliases and Runas_Aliases. +Host netgroups can be used in place of Host_Aliases. +Since groups and netgroups can also be stored in LDAP there is no real need for +.Nm sudo Ns -specific +aliases. +.Pp +There are also some subtle differences in the way sudoers is handled +once in LDAP. +Probably the biggest is that according to the RFC, LDAP ordering +is arbitrary and you cannot expect that Attributes and Entries are +returned in any specific order. +.Pp +The order in which different entries are applied can be controlled +using the +.Li 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 +takes precedence. +This is called paranoid behavior (not necessarily the most specific +match). +.Pp +Here is an example: +.Bd -literal -offset 4n +# /etc/sudoers: +# Allow all commands except shell +johnny ALL=(root) ALL,!/bin/sh +# Always allows all commands because ALL is matched last +puddles ALL=(root) !/bin/sh,ALL + +# LDAP equivalent of johnny +# Allows all commands except shell +dn: cn=role1,ou=Sudoers,dc=my-domain,dc=com +objectClass: sudoRole +objectClass: top +cn: role1 +sudoUser: johnny +sudoHost: ALL +sudoCommand: ALL +sudoCommand: !/bin/sh + +# LDAP equivalent of puddles +# Notice that even though ALL comes last, it still behaves like +# role1 since the LDAP code assumes the more paranoid configuration +dn: cn=role2,ou=Sudoers,dc=my-domain,dc=com +objectClass: sudoRole +objectClass: top +cn: role2 +sudoUser: puddles +sudoHost: ALL +sudoCommand: !/bin/sh +sudoCommand: ALL +.Ed +.Pp +Another difference is that it is not possible to use negation in a +sudoUser, sudoRunAsUser or sudoRunAsGroup attribute. +For example, the following attributes do not behave the way one might expect. +.Bd -literal -offset 4n +# does not match all but joe +# rather, does not match anyone +sudoUser: !joe + +# does not match all but joe +# rather, matches everyone including Joe +sudoUser: ALL +sudoUser: !joe +.Ed +.Ss Converting between file-based and LDAP sudoers +The +.Xr cvtsudoers 1 +utility can be used to convert between file-based and LDAP +.Em sudoers . +However, there are features in the file-based sudoers that have +no equivalent in LDAP-based sudoers (and vice versa). +These cannot be converted automatically. +.Pp +For example, a Cmnd_Alias in a +.Em sudoers +file may be converted to a +.Li sudoRole +that contains multiple commands. +Multiple users and/or groups may be assigned to the +.Li sudoRole . +.Pp +Also, host, user, runas and command-based +.Li Defaults +entries are not supported. +However, a +.Li sudoRole +may contain one or more +.Li sudoOption +attributes which can often serve the same purpose. +.Pp +Consider the following +.Em sudoers +lines: +.Bd -literal -offset 4n +Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less +Defaults!PAGERS noexec +alice, bob ALL = ALL +.Ed +.Pp +In this example, alice and bob are allowed to run all commands, but +the commands listed in PAGERS will have the noexec flag set, +preventing shell escapes. +.Pp +When converting this to LDAP, two sudoRole objects can be used: +.Bd -literal -offset 4n +dn: cn=PAGERS,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: PAGERS +sudoUser: alice +sudoUser: bob +sudoHost: ALL +sudoCommand: /usr/bin/more +sudoCommand: /usr/bin/pg +sudoCommand: /usr/bin/less +sudoOption: noexec +sudoOrder: 900 + +dn: cn=ADMINS,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: ADMINS +sudoUser: alice +sudoUser: bob +sudoHost: ALL +sudoCommand: ALL +sudoOrder: 100 +.Ed +.Pp +In the LDAP version, the sudoOrder attribute is used to guarantee +that the PAGERS sudoRole with +.Em noexec +has precedence. +Unlike the +.Em sudoers +version, the LDAP version requires that all users for whom the restriction +should apply be assigned to the PAGERS sudoRole. +Using a Unix group or netgroup in PAGERS rather than listing each +user would make this easier to maintain. +.Pp +Per-user +.Li Defaults +entries can be emulated by using one or more sudoOption attributes +in a sudoRole. +Consider the following +.Em sudoers +lines: +.Bd -literal -offset 4n +User_Alias ADMINS = john, sally +Defaults:ADMINS !authenticate +ADMINS ALL = (ALL:ALL) ALL +.Ed +.Pp +In this example, john and sally are allowed to run any command +as any user or group. +.Pp +When converting this to LDAP, we can use a Unix group instead +of the User_Alias. +.Bd -literal -offset 4n +dn: cn=admins,ou=SUDOers,dc=my-domain,dc=com +objectClass: top +objectClass: sudoRole +cn: admins +sudoUser: %admin +sudoHost: ALL +sudoRunAsUser: ALL +sudoRunAsGroup: ALL +sudoCommand: ALL +sudoOption: !authenticate +.Ed +.Pp +This assumes that users john and sally are members of the +.Dq admins +Unix group. +.Ss Sudoers schema +In order to use +.Nm sudo Ns 's +LDAP support, the +.Nm sudo +schema must be +installed on your LDAP server. +In addition, be sure to index the +.Li sudoUser +attribute. +.Pp +The +.Nm sudo +distribution includes versions of the +.Nm sudoers +schema for multiple LDAP servers: +.Bl -tag -width 4n +.It Pa schema.OpenLDAP +OpenLDAP slapd and +.Ox +ldapd +.It Pa schema.olcSudo +OpenLDAP slapd 2.3 and higher when on-line configuration is enabled +.It Pa schema.iPlanet +Netscape-derived servers such as the iPlanet, Oracle, +and 389 Directory Servers +.It Pa schema.ActiveDirectory +Microsoft Active Directory +.El +.Pp +The schema in OpenLDAP format is also included in the +.Sx EXAMPLES +section. +.Ss Configuring ldap.conf +Sudo reads the +.Pa @ldap_conf@ +file for LDAP-specific configuration. +Typically, this file is shared between different LDAP-aware clients. +As such, most of the settings are not +.Nm sudo Ns -specific. +Note that +.Nm sudo +parses +.Pa @ldap_conf@ +itself and may support options that differ from those described in the +system's +.Xr ldap.conf @mansectform@ +manual. +The path to +.Pa ldap.conf +may be overridden via the +.Em ldap_conf +plugin argument in +.Xr sudo.conf @mansectform@ . +.Pp +Also note that on systems using the OpenLDAP libraries, default +values specified in +.Pa /etc/openldap/ldap.conf +or the user's +.Pa .ldaprc +files are not used. +.Pp +.Nm sudo +supports a variety of LDAP library implementations, including +OpenLDAP, Netscape-derived (also used by Solaris and HP-UX), and +IBM LDAP (aka Tivoli). +Some options are specific to certain LDAP implementations or have +implementation-specific behavior. +These differences are noted below where applicable. +.Pp +Only those options explicitly listed in +.Pa @ldap_conf@ +as being supported by +.Nm sudo +are honored. +Configuration options are listed below in upper case but are parsed +in a case-independent manner. +.Pp +Lines beginning with a pound sign +.Pq Ql # +are ignored. +Leading white space is removed from the beginning of lines. +.Bl -tag -width 4n +.It Sy BIND_TIMELIMIT Ar seconds +The +.Sy BIND_TIMELIMIT +parameter specifies the amount of time, in seconds, to wait while trying +to connect to an LDAP server. +If multiple +.Sy URI Ns s +or +.Sy HOST Ns s +are specified, this is the amount of time to wait before trying +the next one in the list. +.It Sy BINDDN Ar DN +The +.Sy BINDDN +parameter specifies the identity, in the form of a Distinguished Name (DN), +to use when performing LDAP operations. +If not specified, LDAP operations are performed with an anonymous identity. +By default, most LDAP servers will allow anonymous access. +.It Sy BINDPW Ar secret +The +.Sy BINDPW +parameter specifies the password to use when performing LDAP operations. +This is typically used in conjunction with the +.Sy BINDDN +parameter. +The +.Ar secret +may be a plain text password or a base64-encoded string with a +.Dq base64: +prefix. +For example: +.Bd -literal -offset 4n +BINDPW base64:dGVzdA== +.Ed +.Pp +If a plain text password is used, it should be a simple string without quotes. +Plain text passwords may not include the comment character +.Pq Ql # +and the escaping of special characters with a backslash +.Pq Ql \e +is not supported. +.It Sy DEREF Ar never/searching/finding/always +How alias dereferencing is to be performed when searching. +See the +.Xr ldap.conf @mansectform@ +manual for a full description of this option. +.It Sy HOST Ar name[:port] ... +If no +.Sy URI +is specified (see below), the +.Sy HOST +parameter specifies a white space-delimited list of LDAP servers to connect to. +Each host may include an optional +.Em port +separated by a colon +.Pq Ql :\& . +The +.Sy HOST +parameter is deprecated in favor of the +.Sy URI +specification and is included for backward compatibility only. +.It Sy KRB5_CCNAME Ar file name +The path to the Kerberos 5 credential cache to use when authenticating +with the remote server. +.Pp +This option is only relevant when using SASL authentication (see below). +.It Sy LDAP_VERSION Ar number +The version of the LDAP protocol to use when connecting to the server. +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 . +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 +object containing a +.Li sudoUser +that begins with a +.Ql + +prefix. +The NIS schema used by some LDAP servers need a modification to +support querying the +.Li nisNetgroup +object by its +.Li nisNetgroupTriple +member. +OpenLDAP's +.Sy slapd +requires the following change to the +.Li 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 ) +.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 +or +.Li (&(attribute=value)(attribute2=value2)) . +The default search filter is: +.Li objectClass=nisNetgroup . +If +.Ar ldap_filter +is omitted, no search filter will be used. +.Pp +This option is only used when querying netgroups directly via LDAP. +.It Sy NETWORK_TIMEOUT Ar seconds +An alias for +.Sy BIND_TIMELIMIT +provided for OpenLDAP compatibility. +.It Sy PORT Ar port_number +If no +.Sy URI +is specified, the +.Sy PORT +parameter specifies the default port to connect to on the LDAP server if a +.Sy HOST +parameter does not specify the port itself. +If no +.Sy PORT +parameter is used, the default is port 389 for LDAP and port 636 for LDAP +over TLS (SSL). +The +.Sy PORT +parameter is deprecated in favor of the +.Sy URI +specification and is included for backward compatibility only. +.It Sy ROOTBINDDN Ar DN +The +.Sy ROOTBINDDN +parameter specifies the identity, in the form of a Distinguished Name (DN), +to use when performing privileged LDAP operations, such as +.Em sudoers +queries. +The password corresponding to the identity should be stored in the +or the path specified by the +.Em ldap_secret +plugin argument in +.Xr sudo.conf @mansectform@ , +which defaults to +.Pa @ldap_secret@ . +If no +.Sy ROOTBINDDN +is specified, the +.Sy BINDDN +identity is used (if any). +.It Sy ROOTUSE_SASL Ar on/true/yes/off/false/no +Enable +.Sy ROOTUSE_SASL +to enable SASL authentication when connecting +to an LDAP server from a privileged process, such as +.Nm sudo . +.It Sy SASL_AUTH_ID Ar identity +The SASL user name to use when connecting to the LDAP server. +By default, +.Nm sudo +will use an anonymous connection. +.Pp +This option is only relevant when using SASL authentication. +.It Sy SASL_MECH Ar mechanisms +A white space-delimited list of SASL authentication mechanisms to use. +By default, +.Nm sudo +will use +.Dv GSSAPI +authentication. +.It Sy SASL_SECPROPS Ar none/properties +SASL security properties or +.Em none +for no properties. +See the SASL programmer's manual for details. +.Pp +This option is only relevant when using SASL authentication. +.It Sy SSL Ar on/true/yes/off/false/no +If the +.Sy SSL +parameter is set to +.Li on , +.Li true +.Li or +.Li 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 , +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 +communications. +This parameter is only supported by LDAP servers that honor the +.Em start_tls +extension, such as the OpenLDAP and IBM Tivoli Directory servers. +.It Sy SUDOERS_BASE Ar base +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 . +Multiple +.Sy SUDOERS_BASE +lines may be specified, in which case they are queried in the order specified. +.It Sy SUDOERS_DEBUG Ar debug_level +This sets the debug level for +.Nm sudo +LDAP queries. +Debugging information is printed to the standard error. +A value of 1 results in a moderate amount of debugging information. +A value of 2 shows the results of the matches themselves. +This parameter should not be set in a production environment as the +extra information is likely to confuse users. +.Pp +The +.Sy SUDOERS_DEBUG +parameter is deprecated and will be removed in a future release. +The same information is now logged via the +.Nm sudo +debugging framework using the +.Dq ldap +subsystem at priorities +.Em diag +and +.Em info +for +.Em debug_level +values 1 and 2 respectively. +See the +.Xr sudo.conf @mansectform@ +manual for details on how to configure +.Nm sudo +debugging. +.It Sy SUDOERS_SEARCH_FILTER Ar ldap_filter +An LDAP filter which is used to restrict the set of records returned +when performing a +.Nm sudo +LDAP query. +Typically, this is of the +form +.Li attribute=value +or +.Li (&(attribute=value)(attribute2=value2)) . +The default search filter is: +.Li 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 +and +.Li sudoNotAfter +attributes that implement time-dependent sudoers entries. +.It Sy TIMELIMIT Ar seconds +The +.Sy TIMELIMIT +parameter specifies the amount of time, in seconds, to wait for a +response to an LDAP query. +.It Sy TIMEOUT Ar seconds +The +.Sy TIMEOUT +parameter specifies the amount of time, in seconds, to wait for a +response from the various LDAP APIs. +.It Sy TLS_CACERT Ar file name +An alias for +.Sy TLS_CACERTFILE +for OpenLDAP compatibility. +.It Sy TLS_CACERTFILE Ar file name +The path to a certificate authority bundle which contains the certificates +for all the Certificate Authorities the client knows to be valid, e.g., +.Pa /etc/ssl/ca-bundle.pem . +.Pp +This option is only supported by the OpenLDAP libraries. +Netscape-derived LDAP libraries use the same certificate +database for CA and client certificates (see +.Sy TLS_CERT ) . +.It Sy TLS_CACERTDIR Ar directory +Similar to +.Sy TLS_CACERTFILE +but instead of a file, it is a directory containing individual +Certificate Authority certificates, e.g., +.Pa /etc/ssl/certs . +The directory specified by +.Sy TLS_CACERTDIR +is checked after +.Sy TLS_CACERTFILE . +.Pp +This option is only supported by the OpenLDAP libraries. +.It Sy TLS_CERT Ar file name +The path to a file containing the client certificate which can +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 +.It Netscape-derived: +.Li tls_cert /var/ldap/cert7.db +.It IBM LDAP: +Unused, the key database specified by +.Sy TLS_KEY +contains both keys and certificates. +.El +.Pp +When using Netscape-derived libraries, this file may also contain +Certificate Authority certificates. +.It Sy TLS_CHECKPEER Ar on/true/yes/off/false/no +If enabled, +.Sy TLS_CHECKPEER +will cause the LDAP server's TLS certificated to be verified. +If the server's TLS certificate cannot be verified (usually because it +is signed by an unknown certificate authority), +.Nm sudo +will be unable to connect to it. +If +.Sy TLS_CHECKPEER +is disabled, no check is made. +Note that disabling the check creates an opportunity for man-in-the-middle +attacks since the server's identity will not be authenticated. +If possible, the CA's certificate should be installed locally so it can +be verified. +.Pp +This option is not supported by the IBM LDAP libraries. +.It Sy TLS_KEY Ar file name +The path to a file containing the private key which matches the +certificate specified by +.Sy TLS_CERT . +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 +.It Netscape-derived: +.Li tls_key /var/ldap/key3.db +.It IBM LDAP: +.Li tls_key /usr/ldap/ldapkey.kdb +.El +.Pp +When using IBM LDAP libraries, this file may also contain +Certificate Authority and client certificates and may be encrypted. +.It Sy TLS_CIPHERS Ar cipher list +The +.Sy TLS_CIPHERS +parameter allows the administer to restrict which encryption algorithms +may be used for TLS (SSL) connections. +See the OpenLDAP or IBM Tivoli Directory Server manual for a list of valid +ciphers. +.Pp +This option is not supported by Netscape-derived libraries. +.It Sy TLS_KEYPW Ar secret +The +.Sy TLS_KEYPW +contains the password used to decrypt the key database on clients +using the IBM LDAP library. +The +.Ar secret +may be a plain text password or a base64-encoded string with a +.Dq base64: +prefix. +For example: +.Bd -literal -offset 4n +TLS_KEYPW base64:dGVzdA== +.Ed +.Pp +If a plain text password is used, it should be a simple string without quotes. +Plain text passwords may not include the comment character +.Pq Ql # +and the escaping of special characters with a backslash +.Pq Ql \e +is not supported. +If this option is used, +.Pa @ldap_conf@ +must not be world-readable to avoid exposing the password. +Alternately, a +.Em stash file +can be used to store the password in encrypted form (see below). +.Pp +If no +.Sy TLS_KEYPW +is specified, a +.Em stash file +will be used if it exists. +The +.Em stash file +must have the same path as the file specified by +.Sy TLS_KEY , +but use a +.Li .sth +file extension instead of +.Li .kdb , +e.g., +.Li ldapkey.sth . +The default +.Li ldapkey.kdb +that ships with the IBM Tivoli Directory Server is encrypted with the password +.Li ssl_password . +The +.Em gsk8capicmd +utility can be used to manage the key database and create a +.Em stash file . +.Pp +This option is only supported by the IBM LDAP libraries. +.It Sy TLS_REQCERT Ar level +The +.Sy TLS_REQCERT +parameter controls how the LDAP server's TLS certificated will be +verified (if at all). +If the server's TLS certificate cannot be verified (usually because it +is signed by an unknown certificate authority), +.Nm sudo +will be unable to connect to it. +The following +.Ar level +values are supported: +.Bl -tag -width 8n -offset 4n +.It never +The server certificate will not be requested or checked. +.It allow +The server certificate will be requested. +A missing or invalid certificate is ignored and not considered an error. +.It try +The server certificate will be requested. +A missing certificate is ignored but an invalid certificate will +result in a connection error. +.It demand | Ar hard +The server certificate will be requested. +A missing or invalid certificate will result in a connection error. +This is the default behavior. +.El +.Pp +This option is only supported by the OpenLDAP libraries. +Other LDAP libraries only support the +.Sy TLS_CHECKPEER +parameter. +.It Sy TLS_RANDFILE Ar file name +The +.Sy TLS_RANDFILE +parameter specifies the path to an entropy source for systems that lack +a random device. +It is generally used in conjunction with +.Em prngd +or +.Em egd . +.Pp +This option is only supported by the OpenLDAP libraries. +.It Sy URI Ar ldap[s]://[hostname[:port]] ... +Specifies a white space-delimited list of one or more URIs describing +the LDAP server(s) to connect to. +The +.Em protocol +may be either +.Em ldap +.Em ldaps , +the latter being for servers that support TLS (SSL) encryption. +If no +.Em port +is specified, the default is port 389 for +.Li ldap:// +or port 636 for +.Li ldaps:// . +If no +.Em hostname +is specified, +.Nm sudo +will connect to +.Em localhost . +Multiple +.Sy URI +lines are treated identically to a +.Sy URI +line containing multiple entries. +Only systems using the OpenSSL libraries support the mixing of +.Li ldap:// +and +.Li 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. +.It Sy USE_SASL Ar on/true/yes/off/false/no +Enable +.Sy USE_SASL +for LDAP servers that support SASL authentication. +.It Sy ROOTSASL_AUTH_ID Ar identity +The SASL user name to use when +.Sy ROOTUSE_SASL +is enabled. +.El +.Pp +See the +.Pa ldap.conf +entry in the +.Sx EXAMPLES +section. +.Ss Configuring nsswitch.conf +Unless it is disabled at build time, +.Nm sudo +consults the Name Service Switch file, +.Pa @nsswitch_conf@ , +to specify the +.Em sudoers +search order. +Sudo looks for a line beginning with +.Li sudoers : +and uses this to determine the search order. +Note that +.Nm sudo +does +not stop searching after the first match and later matches take +precedence over earlier ones. +The following sources are recognized: +.Pp +.Bl -tag -width 8n -offset 4n -compact +.It files +read sudoers from +.Pa @sysconfdir@/sudoers +.It ldap +read sudoers from LDAP +.El +.Pp +In addition, the entry +.Li [NOTFOUND=return] +will short-circuit the search if the user was not found in the +preceding source. +.Pp +To consult LDAP first followed by the local sudoers file (if it +exists), use: +.Bd -literal -offset 4n +sudoers: ldap files +.Ed +.Pp +The local +.Em sudoers +file can be ignored completely by using: +.Bd -literal -offset 4n +sudoers: ldap +.Ed +.Pp +If the +.Pa @nsswitch_conf@ +file is not present or there is no sudoers line, the following +default is assumed: +.Bd -literal -offset 4n +sudoers: files +.Ed +.Pp +Note that +.Pa @nsswitch_conf@ +is supported even when the underlying operating system does not use +an nsswitch.conf file, except on AIX (see below). +.Ss Configuring netsvc.conf +On AIX systems, the +.Pa @netsvc_conf@ +file is consulted instead of +.Pa @nsswitch_conf@ . +.Nm sudo +simply treats +.Pa netsvc.conf +as a variant of +.Pa nsswitch.conf ; +information in the previous section unrelated to the file format +itself still applies. +.Pp +To consult LDAP first followed by the local sudoers file (if it +exists), use: +.Bd -literal -offset 4n +sudoers = ldap, files +.Ed +.Pp +The local +.Em sudoers +file can be ignored completely by using: +.Bd -literal -offset 4n +sudoers = ldap +.Ed +.Pp +To treat LDAP as authoritative and only use the local sudoers file +if the user is not present in LDAP, use: +.Bd -literal -offset 4n +sudoers = ldap = auth, files +.Ed +.Pp +Note that in the above example, the +.Li auth +qualifier only affects user lookups; both LDAP and +.Em sudoers +will be queried for +.Li Defaults +entries. +.Pp +If the +.Pa @netsvc_conf@ +file is not present or there is no sudoers line, the following +default is assumed: +.Bd -literal -offset 4n +sudoers = files +.Ed +.Ss Integration with sssd +On systems with the +.Em System Security Services Daemon +(SSSD) and where +.Nm sudo +has been built with SSSD support, +it is possible to use SSSD to cache LDAP +.Em sudoers +rules. +To use SSSD as the +.Em sudoers +source, you should use +.Li sss +instead of +.Li ldap +for the sudoers entry in +.Pa @nsswitch_conf@ . +Note that the +.Pa @ldap_conf@ +file is not used by the SSSD +.Nm sudo +back end. +Please see +.Xr sssd-sudo @mansectform@ +for more information on configuring +.Nm sudo +to work with SSSD. +.Sh FILES +.Bl -tag -width 24n +.It Pa @ldap_conf@ +LDAP configuration file +.It Pa @nsswitch_conf@ +determines sudoers source order +.It Pa @netsvc_conf@ +determines sudoers source order on AIX +.El +.Sh EXAMPLES +.Ss Example ldap.conf +.Bd -literal -offset 2n +# Either specify one or more URIs or one or more host:port pairs. +# If neither is specified sudo will default to localhost, port 389. +# +#host ldapserver +#host ldapserver1 ldapserver2:390 +# +# Default port if host is specified without one, defaults to 389. +#port 389 +# +# URI will override the host and port settings. +uri ldap://ldapserver +#uri ldaps://secureldapserver +#uri ldaps://secureldapserver ldap://ldapserver +# +# The amount of time, in seconds, to wait while trying to connect to +# an LDAP server. +bind_timelimit 30 +# +# The amount of time, in seconds, to wait while performing an LDAP query. +timelimit 30 +# +# Must be set or sudo will ignore LDAP; may be specified multiple times. +sudoers_base ou=SUDOers,dc=my-domain,dc=com +# +# verbose sudoers matching from ldap +#sudoers_debug 2 +# +# Enable support for time-based entries in sudoers. +#sudoers_timed yes +# +# optional proxy credentials +#binddn <who to search as> +#bindpw <password> +#rootbinddn <who to search as, uses /etc/ldap.secret for bindpw> +# +# LDAP protocol version, defaults to 3 +#ldap_version 3 +# +# Define if you want to use an encrypted LDAP connection. +# Typically, you must also set the port to 636 (ldaps). +#ssl on +# +# Define if you want to use port 389 and switch to +# encryption before the bind credentials are sent. +# Only supported by LDAP servers that support the start_tls +# extension such as OpenLDAP. +#ssl start_tls +# +# Additional TLS options follow that allow tweaking of the +# SSL/TLS connection. +# +#tls_checkpeer yes # verify server SSL certificate +#tls_checkpeer no # ignore server SSL certificate +# +# If you enable tls_checkpeer, specify either tls_cacertfile +# or tls_cacertdir. Only supported when using OpenLDAP. +# +#tls_cacertfile /etc/certs/trusted_signers.pem +#tls_cacertdir /etc/certs +# +# For systems that don't have /dev/random +# use this along with PRNGD or EGD.pl to seed the +# random number pool to generate cryptographic session keys. +# Only supported when using OpenLDAP. +# +#tls_randfile /etc/egd-pool +# +# You may restrict which ciphers are used. Consult your SSL +# documentation for which options go here. +# Only supported when using OpenLDAP. +# +#tls_ciphers <cipher-list> +# +# Sudo can provide a client certificate when communicating to +# the LDAP server. +# Tips: +# * Enable both lines at the same time. +# * Do not password protect the key file. +# * Ensure the keyfile is only readable by root. +# +# For OpenLDAP: +#tls_cert /etc/certs/client_cert.pem +#tls_key /etc/certs/client_key.pem +# +# For Netscape-derived LDAP, tls_cert and tls_key may specify either +# a directory, in which case the files in the directory must have the +# default names (e.g., cert8.db and key4.db), or the path to the cert +# and key files themselves. However, a bug in version 5.0 of the LDAP +# SDK will prevent specific file names from working. For this reason +# it is suggested that tls_cert and tls_key be set to a directory, +# not a file name. +# +# The certificate database specified by tls_cert may contain CA certs +# and/or the client's cert. If the client's cert is included, tls_key +# should be specified as well. +# For backward compatibility, "sslpath" may be used in place of tls_cert. +#tls_cert /var/ldap +#tls_key /var/ldap +# +# If using SASL authentication for LDAP (OpenSSL) +# use_sasl yes +# sasl_auth_id <SASL user name> +# rootuse_sasl yes +# rootsasl_auth_id <SASL user name for root access> +# sasl_secprops none +# krb5_ccname /etc/.ldapcache +.Ed +.Ss Sudoers schema for OpenLDAP +The following schema, in OpenLDAP format, is included with +.Nm sudo +source and binary distributions as +.Pa schema.OpenLDAP . +Simply copy +it to the schema directory (e.g., +.Pa /etc/openldap/schema ) , +add the proper +.Li include +line in +.Pa slapd.conf +and restart +.Nm slapd . +Sites using the optional on-line configuration supported by OpenLDAP 2.3 +and higher should apply the +.Pa schema.olcSudo +file instead. +.Bd -literal -offset 2n +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +attributetype ( 1.3.6.1.4.1.15953.9.1.4 + NAME 'sudoRunAs' + DESC 'User(s) impersonated by sudo' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 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 ) + +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 ) + +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 ) + +attributetype ( 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 ) + +attributetype ( 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 ) + +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 ) + +objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL + DESC 'Sudoer Entries' + MUST ( cn ) + MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ + sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $ + sudoOrder $ description ) + ) +.Ed +.Sh SEE ALSO +.Xr cvtsudoers 1 , +.Xr ldap.conf @mansectform@ , +.Xr sssd-sudo @mansectform@ , +.Xr sudo.conf @mansectform@ , +.Xr sudoers @mansectform@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh CAVEATS +Note that there are differences in the way that LDAP-based +.Em sudoers +is parsed compared to file-based +.Em sudoers . +See the +.Sx Differences between LDAP and non-LDAP sudoers +section for more information. +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in new file mode 100644 index 0000000..6bd08d9 --- /dev/null +++ b/doc/sudoers.man.in @@ -0,0 +1,6548 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1994-1996, 1998-2005, 2007-2021 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.nr SL @SEMAN@ +.nr BA @BAMAN@ +.nr LC @LCMAN@ +.nr PS @PSMAN@ +.TH "SUDOERS" "@mansectform@" "January 8, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudoers\fR +\- default sudo security policy plugin +.SH "DESCRIPTION" +The +\fBsudoers\fR +policy plugin determines a user's +\fBsudo\fR +privileges. +It is the default +\fBsudo\fR +policy plugin. +The policy is driven by +the +\fI@sysconfdir@/sudoers\fR +file or, optionally in LDAP. +The policy format is described in detail in the +\fISUDOERS FILE FORMAT\fR +section. +For information on storing +\fBsudoers\fR +policy information +in LDAP, please see +sudoers.ldap(@mansectform@). +.SS "Configuring sudo.conf for sudoers" +\fBsudo\fR +consults the +sudo.conf(@mansectform@) +file to determine which policy and I/O logging plugins to load. +If no +sudo.conf(@mansectform@) +file is present, or if it contains no +\fRPlugin\fR +lines, +\fBsudoers\fR +will be used for policy decisions and I/O logging. +To explicitly configure +sudo.conf(@mansectform@) +to use the +\fBsudoers\fR +plugin, the following configuration can be used. +.nf +.sp +.RS 6n +Plugin sudoers_audit sudoers.so +Plugin sudoers_policy sudoers.so +Plugin sudoers_io sudoers.so +.RE +.fi +.PP +Starting with +\fBsudo\fR +1.8.5, it is possible to specify optional arguments to the +\fBsudoers\fR +plugin in the +sudo.conf(@mansectform@) +file. +Plugin arguments, if any, should be listed after the path to the plugin +(i.e., after +\fIsudoers.so\fR). +The arguments are only effective for the plugin that opens (and parses) the +\fIsudoers\fR +file. +.PP +For +\fBsudo\fR +version 1.9.1 and higher, this is the +\fIsudoers_audit\fR +plugin. +For older versions, it is the +\fIsudoers_policy\fR +plugin. +Multiple arguments may be specified, separated by white space. +For example: +.nf +.sp +.RS 6n +Plugin sudoers_audit sudoers.so sudoers_mode=0400 error_recovery=false +.RE +.fi +.PP +The following plugin arguments are supported: +.TP 10n +error_recovery=bool +The +\fIerror_recovery\fR +argument can be used to control whether +\fBsudoers\fR +should attempt to recover from syntax errors in the +\fIsudoers\fR +file. +If set to +\fItrue\fR +(the default), +\fBsudoers\fR +will try to recover from a syntax error by discarding the portion +of the line that contains the error until the end of the line. +A value of +\fIfalse\fR +will disable error recovery. +Prior to version 1.9.3, no error recovery was performed. +.TP 10n +ldap_conf=pathname +The +\fIldap_conf\fR +argument can be used to override the default path to the +\fIldap.conf\fR +file. +.TP 10n +ldap_secret=pathname +The +\fIldap_secret\fR +argument can be used to override the default path to the +\fIldap.secret\fR +file. +.TP 10n +sudoers_file=pathname +The +\fIsudoers_file\fR +argument can be used to override the default path to the +\fIsudoers\fR +file. +.TP 10n +sudoers_uid=uid +The +\fIsudoers_uid\fR +argument can be used to override the default owner of the sudoers file. +It should be specified as a numeric user-ID. +.TP 10n +sudoers_gid=gid +The +\fIsudoers_gid\fR +argument can be used to override the default group of the sudoers file. +It must be specified as a numeric group-ID (not a group name). +.TP 10n +sudoers_mode=mode +The +\fIsudoers_mode\fR +argument can be used to override the default file mode for the sudoers file. +It should be specified as an octal value. +.PP +For more information on configuring +sudo.conf(@mansectform@), +please refer to its manual. +.SS "User Authentication" +The +\fBsudoers\fR +security policy requires that most users authenticate +themselves before they can use +\fBsudo\fR. +A password is not required +if the invoking user is root, if the target user is the same as the +invoking user, or if the policy has disabled authentication for the +user or command. +Unlike +su(1), +when +\fBsudoers\fR +requires +authentication, it validates the invoking user's credentials, not +the target user's (or root's) credentials. +This can be changed via +the +\fIrootpw\fR, +\fItargetpw\fR +and +\fIrunaspw\fR +flags, described later. +.PP +If a user who is not listed in the policy tries to run a command +via +\fBsudo\fR, +mail is sent to the proper authorities. +The address +used for such mail is configurable via the +\fImailto\fR +Defaults entry +(described later) and defaults to +\fR@mailto@\fR. +.PP +Note that no mail will be sent if an unauthorized user tries to run +\fBsudo\fR +with the +\fB\-l\fR +or +\fB\-v\fR +option unless there is an authentication error and +either the +\fImail_always\fR +or +\fImail_badpass\fR +flags are enabled. +This allows users to +determine for themselves whether or not they are allowed to use +\fBsudo\fR. +By default, all attempts to run +\fBsudo\fR +(successful or not) +are logged, regardless of whether or not mail is sent. +.PP +If +\fBsudo\fR +is run by root and the +\fRSUDO_USER\fR +environment variable +is set, the +\fBsudoers\fR +policy will use this value to determine who +the actual user is. +This can be used by a user to log commands +through sudo even when a root shell has been invoked. +It also +allows the +\fB\-e\fR +option to remain useful even when invoked via a +sudo-run script or program. +Note, however, that the +\fIsudoers\fR +file lookup is still done for root, not the user specified by +\fRSUDO_USER\fR. +.PP +\fBsudoers\fR +uses per-user time stamp files for credential caching. +Once a user has been authenticated, a record is written +containing the user-ID that was used to authenticate, the +terminal session ID, the start time of the session leader +(or parent process) and a time stamp +(using a monotonic clock if one is available). +The user may then use +\fBsudo\fR +without a password for a short period of time +(\fR@timeout@\fR +minutes unless overridden by the +\fItimestamp_timeout\fR +option) +\&. +By default, +\fBsudoers\fR +uses a separate record for each terminal, which means that +a user's login sessions are authenticated separately. +The +\fItimestamp_type\fR +option can be used to select the type of time stamp record +\fBsudoers\fR +will use. +.SS "Logging" +By default, +\fBsudoers\fR +logs both successful and unsuccessful attempts (as well +as errors). +The +\fIlog_allowed\fR +and +\fIlog_denied\fR +flags can be used to control this behavior. +Messages can be logged to +syslog(3), +a log file, or both. +The default is to log to +syslog(3) +but this is configurable via the +\fIsyslog\fR +and +\fIlogfile\fR +settings. +See +\fILOG FORMAT\fR +for a description of the log file format. +.PP +\fBsudoers\fR +is also capable of running a command in a pseudo-terminal and logging all +input and/or output. +The standard input, standard output and standard error can be logged +even when not associated with a terminal. +I/O logging is not on by default but can be enabled using +the +\fIlog_input\fR +and +\fIlog_output\fR +options as well as the +\fRLOG_INPUT\fR +and +\fRLOG_OUTPUT\fR +command tags. +See +\fII/O LOG FILES\fR +for details on how I/O log files are stored. +.PP +Starting with version 1.9, the +\fIlog_servers\fR +setting may be used to send event and I/O log data to a remote server running +\fBsudo_logsrvd\fR +or another service that implements the protocol described by +sudo_logsrv.proto(@mansectform@). +.SS "Command environment" +Since environment variables can influence program behavior, +\fBsudoers\fR +provides a means to restrict which variables from the user's +environment are inherited by the command to be run. +There are two +distinct ways +\fBsudoers\fR +can deal with environment variables. +.PP +By default, the +\fIenv_reset\fR +flag is enabled. +This causes commands +to be executed with a new, minimal environment. +On AIX (and Linux +systems without PAM), the environment is initialized with the +contents of the +\fI/etc/environment\fR +file. +.if \n(LC \{\ +On +BSD +systems, if the +\fIuse_loginclass\fR +flag is enabled, the environment is initialized +based on the +\fIpath\fR +and +\fIsetenv\fR +settings in +\fI/etc/login.conf\fR. +.\} +The +\fRHOME\fR, +\fRMAIL\fR, +\fRSHELL\fR, +\fRLOGNAME\fR +and +\fRUSER\fR +environment variables are initialized based on the target user +and the +\fRSUDO_*\fR +variables are set based on the invoking user. +Additional variables, such as +\fRDISPLAY\fR, +\fRPATH\fR +and +\fRTERM\fR, +are preserved from the invoking user's environment if permitted by the +\fIenv_check\fR +or +\fIenv_keep\fR +options. +A few environment variables are treated specially. +If the +\fRPATH\fR +and +\fRTERM\fR +variables are not preserved from the user's environment, they will be set +to default values. +The +\fRLOGNAME\fR +and +\fRUSER\fR +are handled as a single entity. +If one of them is preserved (or removed) from the user's environment, +the other will be as well. +If +\fRLOGNAME\fR +and +\fRUSER\fR +are to be preserved but only one of them is present in the user's environment, +the other will be set to the same value. +This avoids an inconsistent environment where one of the variables +describing the user name is set to the invoking user and one is +set to the target user. +Environment variables with a value beginning with +\fR()\fR +are removed unless both the name and value parts are matched by +\fIenv_keep\fR +or +\fIenv_check\fR, +as they may be interpreted as functions by the +\fBbash\fR +shell. +Prior to version 1.8.11, such variables were always removed. +.PP +If, however, the +\fIenv_reset\fR +flag is disabled, any variables not +explicitly denied by the +\fIenv_check\fR +and +\fIenv_delete\fR +options are allowed and their values are +inherited from the invoking process. +Prior to version 1.8.21, environment variables with a value beginning with +\fR()\fR +were always removed. +Beginning with version 1.8.21, a pattern in +\fIenv_delete\fR +is used to match +\fBbash\fR +shell functions instead. +Since it is not possible +to block all potentially dangerous environment variables, use +of the default +\fIenv_reset\fR +behavior is encouraged. +.PP +Environment variables specified by +\fIenv_check\fR, +\fIenv_delete\fR, +or +\fIenv_keep\fR +may include one or more +\(oq*\(cq +characters which will match zero or more characters. +No other wildcard characters are supported. +.PP +By default, environment variables are matched by name. +However, if the pattern includes an equal sign +(\(oq=\&\(cq), +both the variables name and value must match. +For example, a +\fBbash\fR +shell function could be matched as follows: +.nf +.sp +.RS 4n +env_keep += "BASH_FUNC_my_func%%=()*" +.RE +.fi +.PP +Without the +\(lq\fR=()*\fR\(rq +suffix, this would not match, as +\fBbash\fR +shell functions are not preserved by default. +.PP +The complete list of environment variables that are preserved or removed, +as modified by global Defaults parameters in +\fIsudoers\fR, +is displayed when +\fBsudo\fR +is run by root with the +\fB\-V\fR +option. +Please note that the list of environment variables to remove +varies based on the operating system +\fBsudo\fR +is running on. +.PP +Other +\fBsudoers\fR +options may influence the command environment, such as +\fIalways_set_home\fR, +\fIsecure_path\fR, +\fIset_logname\fR, +and +\fIset_home\fR. +.PP +On systems that support PAM where the +\fBpam_env\fR +module is enabled for +\fBsudo\fR, +variables in the PAM environment may be merged in to the environment. +If a variable in the PAM environment is already present in the +user's environment, the value will only be overridden if the variable +was not preserved by +\fBsudoers\fR. +When +\fIenv_reset\fR +is enabled, variables preserved from the invoking user's environment +by the +\fIenv_keep\fR +list take precedence over those in the PAM environment. +When +\fIenv_reset\fR +is disabled, variables present the invoking user's environment +take precedence over those in the PAM environment unless they +match a pattern in the +\fIenv_delete\fR +list. +.PP +Note that the dynamic linker on most operating systems will remove +variables that can control dynamic linking from the environment of +set-user-ID executables, including +\fBsudo\fR. +Depending on the operating +system this may include +\fR_RLD*\fR, +\fRDYLD_*\fR, +\fRLD_*\fR, +\fRLDR_*\fR, +\fRLIBPATH\fR, +\fRSHLIB_PATH\fR, +and others. +These type of variables are +removed from the environment before +\fBsudo\fR +even begins execution +and, as such, it is not possible for +\fBsudo\fR +to preserve them. +.PP +As a special case, if the +\fB\-i\fR +option (initial login) is +specified, +\fBsudoers\fR +will initialize the environment regardless +of the value of +\fIenv_reset\fR. +The +\fRDISPLAY\fR, +\fRPATH\fR +and +\fRTERM\fR +variables remain unchanged; +\fRHOME\fR, +\fRMAIL\fR, +\fRSHELL\fR, +\fRUSER\fR, +and +\fRLOGNAME\fR +are set based on the target user. +On AIX (and Linux +systems without PAM), the contents of +\fI/etc/environment\fR +are also +included. +.if \n(LC \{\ +On +BSD +systems, if the +\fIuse_loginclass\fR +flag is +enabled, the +\fIpath\fR +and +\fIsetenv\fR +variables in +\fI/etc/login.conf\fR +are also applied. +.\} +All other environment variables are removed unless permitted by +\fIenv_keep\fR +or +\fIenv_check\fR, +described above. +.PP +Finally, the +\fIrestricted_env_file\fR +and +\fIenv_file\fR +files are applied, if present. +The variables in +\fIrestricted_env_file\fR +are applied first and are subject to the same restrictions as the +invoking user's environment, as detailed above. +The variables in +\fIenv_file\fR +are applied last and are not subject to these restrictions. +In both cases, variables present in the files will only be set to +their specified values if they would not conflict with an existing +environment variable. +.SH "SUDOERS FILE FORMAT" +The +\fIsudoers\fR +file is composed of two types of entries: aliases +(basically variables) and user specifications (which specify who +may run what). +.PP +When multiple entries match for a user, they are applied in order. +Where there are multiple matches, the last match is used (which is +not necessarily the most specific match). +.PP +The +\fIsudoers\fR +file grammar will be described below in Extended Backus-Naur +Form (EBNF). +Don't despair if you are unfamiliar with EBNF; it is fairly simple, +and the definitions below are annotated. +.SS "Quick guide to EBNF" +EBNF is a concise and exact way of describing the grammar of a language. +Each EBNF definition is made up of +\fIproduction rules\fR. +E.g., +.PP +\fRsymbol ::= definition\fR | \fRalternate1\fR | \fRalternate2 ...\fR +.PP +Each +\fIproduction rule\fR +references others and thus makes up a +grammar for the language. +EBNF also contains the following +operators, which many readers will recognize from regular +expressions. +Do not, however, confuse them with +\(lqwildcard\(rq +characters, which have different meanings. +.TP 6n +\fR\&?\fR +Means that the preceding symbol (or group of symbols) is optional. +That is, it may appear once or not at all. +.TP 6n +\fR*\fR +Means that the preceding symbol (or group of symbols) may appear +zero or more times. +.TP 6n +\fR+\fR +Means that the preceding symbol (or group of symbols) may appear +one or more times. +.PP +Parentheses may be used to group symbols together. +For clarity, +we will use single quotes +('') +to designate what is a verbatim character string (as opposed to a symbol name). +.SS "Aliases" +There are four kinds of aliases: +\fRUser_Alias\fR, +\fRRunas_Alias\fR, +\fRHost_Alias\fR +and +\fRCmnd_Alias\fR. +Beginning with +\fBsudo\fR +1.9.0, +\fRCmd_Alias\fR +may be used in place of +\fRCmnd_Alias\fR +if desired. +.nf +.sp +.RS 0n +Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* | + 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* | + 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* | + 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)* | + 'Cmd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)* + +User_Alias ::= NAME + +User_Alias_Spec ::= User_Alias '=' User_List + +Runas_Alias ::= NAME + +Runas_Alias_Spec ::= Runas_Alias '=' Runas_List + +Host_Alias ::= NAME + +Host_Alias_Spec ::= Host_Alias '=' Host_List + +Cmnd_Alias ::= NAME + +Cmnd_Alias_Spec ::= Cmnd_Alias '=' Cmnd_List + +NAME ::= [A-Z]([A-Z][0-9]_)* +.RE +.fi +.PP +Each +\fIalias\fR +definition is of the form +.nf +.sp +.RS 0n +Alias_Type NAME = item1, item2, ... +.RE +.fi +.PP +where +\fIAlias_Type\fR +is one of +\fRUser_Alias\fR, +\fRRunas_Alias\fR, +\fRHost_Alias\fR, +or +\fRCmnd_Alias\fR. +A +\fRNAME\fR +is a string of uppercase letters, numbers, +and underscore characters +(\(oq_\(cq). +A +\fRNAME\fR +\fBmust\fR +start with an +uppercase letter. +It is possible to put several alias definitions +of the same type on a single line, joined by a colon +(\(oq:\&\(cq). +E.g., +.nf +.sp +.RS 0n +Alias_Type NAME = item1, item2, item3 : NAME = item4, item5 +.RE +.fi +.PP +It is a syntax error to redefine an existing +\fIalias\fR. +It is possible to use the same name for +\fIaliases\fR +of different types, but this is not recommended. +.PP +The definitions of what constitutes a valid +\fIalias\fR +member follow. +.nf +.sp +.RS 0n +User_List ::= User | + User ',' User_List + +User ::= '!'* user name | + '!'* #uid | + '!'* %group | + '!'* %#gid | + '!'* +netgroup | + '!'* %:nonunix_group | + '!'* %:#nonunix_gid | + '!'* User_Alias +.RE +.fi +.PP +A +\fRUser_List\fR +is made up of one or more user names, user-IDs +(prefixed with +\(oq#\(cq), +system group names and IDs (prefixed with +\(oq%\(cq +and +\(oq%#\(cq +respectively), netgroups (prefixed with +\(oq+\(cq), +non-Unix group names and IDs (prefixed with +\(oq%:\(cq +and +\(oq%:#\(cq +respectively) and +\fRUser_Alias\fRes. +Each list item may be prefixed with zero or more +\(oq\&!\(cq +operators. +An odd number of +\(oq\&!\(cq +operators negate the value of +the item; an even number just cancel each other out. +User netgroups are matched using the user and domain members only; +the host member is not used when matching. +.PP +A +\fRuser name\fR, +\fRuid\fR, +\fRgroup\fR, +\fRgid\fR, +\fRnetgroup\fR, +\fRnonunix_group\fR +or +\fRnonunix_gid\fR +may be enclosed in double quotes to avoid the +need for escaping special characters. +Alternately, special characters +may be specified in escaped hex mode, e.g., \ex20 for space. +When +using double quotes, any prefix characters must be included inside +the quotes. +.PP +The actual +\fRnonunix_group\fR +and +\fRnonunix_gid\fR +syntax depends on +the underlying group provider plugin. +For instance, the QAS AD plugin supports the following formats: +.TP 3n +\fB\(bu\fR +Group in the same domain: "%:Group Name" +.TP 3n +\fB\(bu\fR +Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN" +.TP 3n +\fB\(bu\fR +Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567" +.PP +See +\fIGROUP PROVIDER PLUGINS\fR +for more information. +.PP +Note that quotes around group names are optional. +Unquoted strings must use a backslash +(\(oq\e\(cq) +to escape spaces and special characters. +See +\fIOther special characters and reserved words\fR +for a list of +characters that need to be escaped. +.nf +.sp +.RS 0n +Runas_List ::= Runas_Member | + Runas_Member ',' Runas_List + +Runas_Member ::= '!'* user name | + '!'* #uid | + '!'* %group | + '!'* %#gid | + '!'* %:nonunix_group | + '!'* %:#nonunix_gid | + '!'* +netgroup | + '!'* Runas_Alias +.RE +.fi +.PP +A +\fRRunas_List\fR +is similar to a +\fRUser_List\fR +except that instead +of +\fRUser_Alias\fRes +it can contain +\fRRunas_Alias\fRes. +Note that +user names and groups are matched as strings. +In other words, two users (groups) with the same user (group) ID +are considered to be distinct. +If you wish to match all user names with the same user-ID (e.g., root and +toor), you can use a user-ID instead of a name (#0 in the example given). +Note that the user-ID or group-ID specified in a +\fRRunas_Member\fR +need not be listed in the password or group database. +.nf +.sp +.RS 0n +Host_List ::= Host | + Host ',' Host_List + +Host ::= '!'* host name | + '!'* ip_addr | + '!'* network(/netmask)? | + '!'* +netgroup | + '!'* Host_Alias +.RE +.fi +.PP +A +\fRHost_List\fR +is made up of one or more host names, IP addresses, +network numbers, netgroups (prefixed with +\(oq+\(cq) +and other aliases. +Again, the value of an item may be negated with the +\(oq\&!\(cq +operator. +Host netgroups are matched using the host (both qualified and unqualified) +and domain members only; the user member is not used when matching. +If you specify a network number without a netmask, +\fBsudo\fR +will query each of the local host's network interfaces and, +if the network number corresponds to one of the hosts's network +interfaces, will use the netmask of that interface. +The netmask may be specified either in standard IP address notation +(e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::), +or CIDR notation (number of bits, e.g., 24 or 64). +A host name may include shell-style wildcards (see the +\fIWildcards\fR +section below), +but unless the +\fRhost name\fR +command on your machine returns the fully +qualified host name, you'll need to use the +\fIfqdn\fR +flag for wildcards to be useful. +Note that +\fBsudo\fR +only inspects actual network interfaces; this means that IP address +127.0.0.1 (localhost) will never match. +Also, the host name +\(lqlocalhost\(rq +will only match if that is the actual host name, which is usually +only the case for non-networked systems. +.nf +.sp +.RS 0n +digest ::= [A-Fa-f0-9]+ | + [A-Za-z0-9\e+/=]+ + +Digest_Spec ::= "sha224" ':' digest | + "sha256" ':' digest | + "sha384" ':' digest | + "sha512" ':' digest + +Digest_List ::= Digest_Spec | + Digest_Spec ',' Digest_List + +Cmnd_List ::= Cmnd | + Cmnd ',' Cmnd_List + +command name ::= file name | + file name args | + file name '""' + +Edit_Spec ::= "sudoedit" file name+ + +Cmnd ::= Digest_List? '!'* command name | + '!'* directory | + '!'* Edit_Spec | + '!'* Cmnd_Alias +.RE +.fi +.PP +A +\fRCmnd_List\fR +is a list of one or more command names, directories, and other aliases. +A command name is a fully qualified file name which may include +shell-style wildcards (see the +\fIWildcards\fR +section below). +A simple file name allows the user to run the command with any +arguments they wish. +However, you may also specify command line arguments (including +wildcards). +Alternately, you can specify +\fR\&""\fR +to indicate that the command +may only be run +\fBwithout\fR +command line arguments. +A directory is a +fully qualified path name ending in a +\(oq/\(cq. +When you specify a directory in a +\fRCmnd_List\fR, +the user will be able to run any file within that directory +(but not in any sub-directories therein). +.PP +If a +\fRCmnd\fR +has associated command line arguments, then the arguments +in the +\fRCmnd\fR +must match exactly those given by the user on the command line +(or match the wildcards if there are any). +Note that the following characters must be escaped with a +\(oq\e\(cq +if they are used in command arguments: +\(oq,\&\(cq, +\(oq:\&\(cq, +\(oq=\&\(cq, +\(oq\e\(cq. +The built-in command +\(lq\fRsudoedit\fR\(rq +is used to permit a user to run +\fBsudo\fR +with the +\fB\-e\fR +option (or as +\fBsudoedit\fR). +It may take command line arguments just as a normal command does. +Note that +\(lq\fRsudoedit\fR\(rq +is a command built into +\fBsudo\fR +itself and must be specified in the +\fIsudoers\fR +file +\fBwithout\fR +a leading path. +If a leading path is present, for example +\fI/usr/bin/sudoedit\fR, +the path name will be silently converted to +\(lq\fRsudoedit\fR\(rq. +A fully-qualified path for +\fBsudoedit\fR +is treated as an error by +\fBvisudo\fR. +.PP +A +\fRcommand name\fR +may be preceded by a +\fRDigest_List\fR, +a comma-separated list of one or more +\fRDigest_Spec\fR +entries. +If a +\fRDigest_List\fR +is present, the command will only match successfully if it can be verified +using one of the SHA-2 digests in the list. +Starting with version 1.9.0, the +\fBALL\fR +reserved word can be used in conjunction with a +\fRDigest_List\fR. +The following digest formats are supported: sha224, sha256, sha384 and sha512. +The string may be specified in either hex or base64 format +(base64 is more compact). +There are several utilities capable of generating SHA-2 digests in hex +format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum. +.PP +For example, using openssl: +.nf +.sp +.RS 0n +$ openssl dgst -sha224 /bin/ls +SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25 +.RE +.fi +.PP +It is also possible to use openssl to generate base64 output: +.nf +.sp +.RS 0n +$ openssl dgst -binary -sha224 /bin/ls | openssl base64 +EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== +.RE +.fi +.PP +Warning, if the user has write access to the command itself (directly or via a +\fBsudo\fR +command), it may be possible for the user to replace the command after the +digest check has been performed but before the command is executed. +A similar race condition exists on systems that lack the +fexecve(2) +system call when the directory in which the command is located +is writable by the user. +See the description of the +\fIfdexec\fR +setting for more information on how +\fBsudo\fR +executes commands that have an associated digest. +.PP +Command digests are only supported by version 1.8.7 or higher. +.SS "Defaults" +Certain configuration options may be changed from their default +values at run-time via one or more +\fRDefault_Entry\fR +lines. +These may affect all users on any host, all users on a specific host, a +specific user, a specific command, or commands being run as a specific user. +Note that per-command entries may not include command line arguments. +If you need to specify arguments, define a +\fRCmnd_Alias\fR +and reference +that instead. +.nf +.sp +.RS 0n +Default_Type ::= 'Defaults' | + 'Defaults' '@' Host_List | + 'Defaults' ':' User_List | + 'Defaults' '!' Cmnd_List | + 'Defaults' '>' Runas_List + +Default_Entry ::= Default_Type Parameter_List + +Parameter_List ::= Parameter | + Parameter ',' Parameter_List + +Parameter ::= Parameter '=' Value | + Parameter '+=' Value | + Parameter '-=' Value | + '!'* Parameter +.RE +.fi +.PP +Parameters may be +\fBflags\fR, +\fBinteger\fR +values, +\fBstrings\fR, +or +\fBlists\fR. +Flags are implicitly boolean and can be turned off via the +\(oq\&!\(cq +operator. +Some integer, string and list parameters may also be +used in a boolean context to disable them. +Values may be enclosed +in double quotes +(\&"") +when they contain multiple words. +Special characters may be escaped with a backslash +(\(oq\e\(cq). +.PP +Lists have two additional assignment operators, +\fR+=\fR +and +\fR-=\fR. +These operators are used to add to and delete from a list respectively. +It is not an error to use the +\fR-=\fR +operator to remove an element +that does not exist in a list. +.PP +Defaults entries are parsed in the following order: generic, host, +user and runas Defaults first, then command defaults. +If there are multiple Defaults settings of the same type, the last +matching setting is used. +The following Defaults settings are parsed before all others since +they may affect subsequent entries: +\fIfqdn\fR, +\fIgroup_plugin\fR, +\fIrunas_default\fR, +\fIsudoers_locale\fR. +.PP +See +\fISUDOERS OPTIONS\fR +for a list of supported Defaults parameters. +.SS "User specification" +.nf +.RS 0n +User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e + (':' Host_List '=' Cmnd_Spec_List)* + +Cmnd_Spec_List ::= Cmnd_Spec | + Cmnd_Spec ',' Cmnd_Spec_List + +Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd + +Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')' + +.ie \n(SL \{\ +.ie \n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec) +.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec) +.\} +.el \{\ +.ie \n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec) +.el Option_Spec ::= (Date_Spec | Timeout_Spec) +.\} + +.if \n(SL \{\ +SELinux_Spec ::= ('ROLE=role' | 'TYPE=type') + +.\} +.if \n(PS \{\ +Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset') + +.\} +Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp') + +Timeout_Spec ::= 'TIMEOUT=timeout' + +Chdir_Spec ::= 'CWD=directory' + +Chroot_Spec ::= 'CHROOT=directory' + +Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' | + 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' | + 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' | + 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:') +.RE +.fi +.PP +A +\fBuser specification\fR +determines which commands a user may run +(and as what user) on specified hosts. +By default, commands are +run as +\fBroot\fR, +but this can be changed on a per-command basis. +.PP +The basic structure of a user specification is +\(lqwho where = (as_whom) what\(rq. +Let's break that down into its constituent parts: +.SS "Runas_Spec" +A +\fRRunas_Spec\fR +determines the user and/or the group that a command +may be run as. +A fully-specified +\fRRunas_Spec\fR +consists of two +\fRRunas_List\fRs +(as defined above) separated by a colon +(\(oq:\&\(cq) +and enclosed in a set of parentheses. +The first +\fRRunas_List\fR +indicates which users the command may be run as via the +\fB\-u\fR +option. +The second defines a list of groups that can be specified via the +\fB\-g\fR +option in addition to any of the target user's groups. +If both +\fRRunas_List\fRs +are specified, the command may be run with any combination of users +and groups listed in their respective +\fRRunas_List\fRs. +If only the first is specified, the command may be run as any user +in the list but no +\fB\-g\fR +option +may be specified. +If the first +\fRRunas_List\fR +is empty but the +second is specified, the command may be run as the invoking user +with the group set to any listed in the +\fRRunas_List\fR. +If both +\fRRunas_List\fRs +are empty, the command may only be run as the invoking user. +If no +\fRRunas_Spec\fR +is specified the command may be run as +\fBroot\fR +and +no group may be specified. +.PP +A +\fRRunas_Spec\fR +sets the default for the commands that follow it. +What this means is that for the entry: +.nf +.sp +.RS 0n +dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm +.RE +.fi +.PP +The user +\fBdgb\fR +may run +\fI/bin/ls\fR, +\fI/bin/kill\fR, +and +\fI/usr/bin/lprm\fR +on the host +boulder\(embut +only as +\fBoperator\fR. +E.g., +.nf +.sp +.RS 0n +$ sudo -u operator /bin/ls +.RE +.fi +.PP +It is also possible to override a +\fRRunas_Spec\fR +later on in an entry. +If we modify the entry like so: +.nf +.sp +.RS 0n +dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm +.RE +.fi +.PP +Then user +\fBdgb\fR +is now allowed to run +\fI/bin/ls\fR +as +\fBoperator\fR, +but +\fI/bin/kill\fR +and +\fI/usr/bin/lprm\fR +as +\fBroot\fR. +.PP +We can extend this to allow +\fBdgb\fR +to run +\fR/bin/ls\fR +with either +the user or group set to +\fBoperator\fR: +.nf +.sp +.RS 0n +dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\e + /usr/bin/lprm +.RE +.fi +.PP +Note that while the group portion of the +\fRRunas_Spec\fR +permits the +user to run as command with that group, it does not force the user +to do so. +If no group is specified on the command line, the command +will run with the group listed in the target user's password database +entry. +The following would all be permitted by the sudoers entry above: +.nf +.sp +.RS 0n +$ sudo -u operator /bin/ls +$ sudo -u operator -g operator /bin/ls +$ sudo -g operator /bin/ls +.RE +.fi +.PP +In the following example, user +\fBtcm\fR +may run commands that access +a modem device file with the dialer group. +.nf +.sp +.RS 0n +tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\e + /usr/local/bin/minicom +.RE +.fi +.PP +Note that in this example only the group will be set, the command +still runs as user +\fBtcm\fR. +E.g.\& +.nf +.sp +.RS 0n +$ sudo -g dialer /usr/bin/cu +.RE +.fi +.PP +Multiple users and groups may be present in a +\fRRunas_Spec\fR, +in which case the user may select any combination of users and groups via the +\fB\-u\fR +and +\fB\-g\fR +options. +In this example: +.nf +.sp +.RS 0n +alan ALL = (root, bin : operator, system) ALL +.RE +.fi +.PP +user +\fBalan\fR +may run any command as either user root or bin, +optionally setting the group to operator or system. +.SS "Option_Spec" +A +\fRCmnd\fR +may have zero or more options associated with it. +Options may consist of +.if \n(SL \{\ +SELinux roles and/or types, +.\} +.if \n(PS \{\ +Solaris privileges sets, +.\} +start and/or end dates and command timeouts. +Once an option is set for a +\fRCmnd\fR, +subsequent +\fRCmnd\fRs +in the +\fRCmnd_Spec_List\fR, +inherit that option unless it is overridden by another option. +Note that the option names are reserved words in +\fIsudoers\fR. +This means that none of the valid option names (see below) can be used +when declaring an alias. +.if \n(SL \{\ +.SS "SELinux_Spec" +On systems with SELinux support, +\fIsudoers\fR +file entries may optionally have an SELinux role and/or type associated +with a command. +If a role or +type is specified with the command it will override any default values +specified in +\fIsudoers\fR. +A role or type specified on the command line, +however, will supersede the values in +\fIsudoers\fR. +.\} +.if \n(PS \{\ +.SS "Solaris_Priv_Spec" +On Solaris systems, +\fIsudoers\fR +file entries may optionally specify Solaris privilege set and/or limit +privilege set associated with a command. +If privileges or limit privileges are specified with the command +it will override any default values specified in +\fIsudoers\fR. +.PP +A privilege set is a comma-separated list of privilege names. +The +ppriv(1) +command can be used to list all privileges known to the system. +For example: +.nf +.sp +.RS 0n +$ ppriv -l +.RE +.fi +.PP +In addition, there are several +\(lqspecial\(rq +privilege strings: +.TP 10n +none +the empty set +.TP 10n +all +the set of all privileges +.TP 10n +zone +the set of all privileges available in the current zone +.TP 10n +basic +the default set of privileges normal users are granted at login time +.PP +Privileges can be excluded from a set by prefixing the privilege +name with either an +\(oq\&!\(cq +or +\(oq\-\(cq +character. +.\} +.SS "Date_Spec" +\fBsudoers\fR +rules can be specified with a start and end date via the +\fRNOTBEFORE\fR +and +\fRNOTAFTER\fR +settings. +The time stamp must be specified in +\fIGeneralized Time\fR +as defined by RFC 4517. +The format is effectively +\fRyyyymmddHHMMSSZ\fR +where the minutes and seconds are optional. +The +\(oqZ\(cq +suffix indicates that the time stamp is in Coordinated Universal Time (UTC). +It is also possible to specify a timezone offset from UTC in hours +and minutes instead of a +\(oqZ\(cq. +For example, +\(oq-0500\(cq +would correspond to Eastern Standard time in the US. +As an extension, if no +\(oqZ\(cq +or timezone offset is specified, local time will be used. +.PP +The following are all valid time stamps: +.nf +.sp +.RS 4n +20170214083000Z +2017021408Z +20160315220000-0500 +20151201235900 +.RE +.fi +.SS "Timeout_Spec" +A command may have a timeout associated with it. +If the timeout expires before the command has exited, the +command will be terminated. +The timeout may be specified in combinations of days, hours, +minutes and seconds with a single-letter case-insensitive suffix +that indicates the unit of time. +For example, a timeout of 7 days, 8 hours, 30 minutes and +10 seconds would be written as +\fR7d8h30m10s\fR. +If a number is specified without a unit, seconds are assumed. +Any of the days, minutes, hours or seconds may be omitted. +The order must be from largest to smallest unit and a unit +may not be specified more than once. +.PP +The following are all +\fIvalid\fR +timeout values: +\fR7d8h30m10s\fR, +\fR14d\fR, +\fR8h30m\fR, +\fR600s\fR, +\fR3600\fR. +The following are +\fIinvalid\fR +timeout values: +\fR12m2w1d\fR, +\fR30s10m4h\fR, +\fR1d2d3h\fR. +.PP +This setting is only supported by version 1.8.20 or higher. +.SS "Chdir_Spec" +The working directory that the command will be run in can be specified +using the +\fRCWD\fR +setting. +The +\fIdirectory\fR +must be a fully-qualified path name beginning with a +\(oq/\(cq +or +\(oq~\(cq +character, or the special value +\(lq*\(rq. +A value of +\(lq*\(rq +indicates that the user may specify the working directory by running +\fBsudo\fR +with the +\fB\-D\fR +option. +By default, commands are run from the invoking user's current working +directory, unless the +\fB\-i\fR +option is given. +Path names of the form +\fR~user/path/name\fR +are interpreted as being relative to the named user's home directory. +If the user name is omitted, the path will be relative to the runas +user's home directory. +.PP +This setting is only supported by version 1.9.3 or higher. +.SS "Chroot_Spec" +The root directory that the command will be run in can be specified +using the +\fRCHROOT\fR +setting. +The +\fIdirectory\fR +must be a fully-qualified path name beginning with a +\(oq/\(cq +or +\(oq~\(cq +character, or the special value +\(lq*\(rq. +A value of +\(lq*\(rq +indicates that the user may specify the root directory by running +\fBsudo\fR +with the +\fB\-R\fR +option. +This setting can be used to run the command in a +chroot(2) +\(lqsandbox\(rq +similar to the +chroot(@mansectsu@) +utility. +Path names of the form +\fR~user/path/name\fR +are interpreted as being relative to the named user's home directory. +If the user name is omitted, the path will be relative to the runas +user's home directory. +.PP +This setting is only supported by version 1.9.3 or higher. +.SS "Tag_Spec" +A command may have zero or more tags associated with it. +The following tag values are supported: +\fREXEC\fR, +\fRNOEXEC\fR, +\fRFOLLOW\fR, +\fRNOFOLLOW\fR, +\fRLOG_INPUT\fR, +\fRNOLOG_INPUT\fR, +\fRLOG_OUTPUT\fR, +\fRNOLOG_OUTPUT\fR, +\fRMAIL\fR, +\fRNOMAIL\fR, +\fRPASSWD\fR, +\fRNOPASSWD\fR, +\fRSETENV\fR, +and +\fRNOSETENV\fR. +Once a tag is set on a +\fRCmnd\fR, +subsequent +\fRCmnd\fRs +in the +\fRCmnd_Spec_List\fR, +inherit the tag unless it is overridden by the opposite tag (in other words, +\fRPASSWD\fR +overrides +\fRNOPASSWD\fR +and +\fRNOEXEC\fR +overrides +\fREXEC\fR). +.TP 2n +\fIEXEC\fR and \fINOEXEC\fR +.sp +If +\fBsudo\fR +has been compiled with +\fInoexec\fR +support and the underlying operating system supports it, the +\fRNOEXEC\fR +tag can be used to prevent a dynamically-linked executable from +running further commands itself. +.sp +In the following example, user +\fBaaron\fR +may run +\fI/usr/bin/more\fR +and +\fI/usr/bin/vi\fR +but shell escapes will be disabled. +.nf +.sp +.RS 2n +aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi +.RE +.fi +.RS 2n +.sp +See the +\fIPreventing shell escapes\fR +section below for more details on how +\fRNOEXEC\fR +works and whether or not it will work on your system. +.RE +.TP 2n +\fIFOLLOW\fR and \fINOFOLLOW\fR +Starting with version 1.8.15, +\fBsudoedit\fR +will not open a file that is a symbolic link unless the +\fIsudoedit_follow\fR +flag is enabled. +The +\fIFOLLOW\fR +and +\fINOFOLLOW\fR +tags override the value of +\fIsudoedit_follow\fR +and can be used to permit (or deny) the editing of symbolic links +on a per-command basis. +These tags are only effective for the +\fIsudoedit\fR +command and are ignored for all other commands. +.TP 2n +\fILOG_INPUT\fR and \fINOLOG_INPUT\fR +.sp +These tags override the value of the +\fIlog_input\fR +flag on a per-command basis. +For more information, see the description of +\fIlog_input\fR +in the +\fISUDOERS OPTIONS\fR +section below. +.TP 2n +\fILOG_OUTPUT\fR and \fINOLOG_OUTPUT\fR +.sp +These tags override the value of the +\fIlog_output\fR +flag on a per-command basis. +For more information, see the description of +\fIlog_output\fR +in the +\fISUDOERS OPTIONS\fR +section below. +.TP 2n +\fIMAIL\fR and \fINOMAIL\fR +.sp +These tags provide fine-grained control over whether +mail will be sent when a user runs a command by +overriding the value of the +\fImail_all_cmnds\fR +flag on a per-command basis. +They have no effect when +\fBsudo\fR +is run with the +\fB\-l\fR +or +\fB\-v\fR +options. +A +\fINOMAIL\fR +tag will also override the +\fImail_always\fR +and +\fImail_no_perms\fR +options. +For more information, see the descriptions of +\fImail_all_cmnds\fR, +\fImail_always\fR, +and +\fImail_no_perms\fR +in the +\fISUDOERS OPTIONS\fR +section below. +.TP 2n +\fIPASSWD\fR and \fINOPASSWD\fR +.sp +By default, +\fBsudo\fR +requires that a user authenticate him or herself +before running a command. +This behavior can be modified via the +\fRNOPASSWD\fR +tag. +Like a +\fRRunas_Spec\fR, +the +\fRNOPASSWD\fR +tag sets +a default for the commands that follow it in the +\fRCmnd_Spec_List\fR. +Conversely, the +\fRPASSWD\fR +tag can be used to reverse things. +For example: +.nf +.sp +.RS 2n +ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm +.RE +.fi +.RS 2n +.sp +would allow the user +\fBray\fR +to run +\fI/bin/kill\fR, +\fI/bin/ls\fR, +and +\fI/usr/bin/lprm\fR +as +\fBroot\fR +on the machine rushmore without authenticating himself. +If we only want +\fBray\fR +to be able to +run +\fI/bin/kill\fR +without a password the entry would be: +.nf +.sp +.RS 2n +ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm +.RE +.fi +.sp +Note, however, that the +\fRPASSWD\fR +tag has no effect on users who are in the group specified by the +\fIexempt_group\fR +setting. +.sp +By default, if the +\fRNOPASSWD\fR +tag is applied to any of a user's entries for the current host, +the user will be able to run +\(lq\fRsudo -l\fR\(rq +without a password. +Additionally, a user may only run +\(lq\fRsudo -v\fR\(rq +without a password if all of the user's entries for the current +host have the +\fRNOPASSWD\fR +tag. +This behavior may be overridden via the +\fIverifypw\fR +and +\fIlistpw\fR +options. +.RE +.TP 2n +\fISETENV\fR and \fINOSETENV\fR +.sp +These tags override the value of the +\fIsetenv\fR +flag on a per-command basis. +Note that if +\fRSETENV\fR +has been set for a command, the user may disable the +\fIenv_reset\fR +flag from the command line via the +\fB\-E\fR +option. +Additionally, environment variables set on the command +line are not subject to the restrictions imposed by +\fIenv_check\fR, +\fIenv_delete\fR, +or +\fIenv_keep\fR. +As such, only trusted users should be allowed to set variables in this manner. +If the command matched is +\fBALL\fR, +the +\fRSETENV\fR +tag is implied for that command; this default may be overridden by use of the +\fRNOSETENV\fR +tag. +.SS "Wildcards" +\fBsudo\fR +allows shell-style +\fIwildcards\fR +(aka meta or glob characters) +to be used in host names, path names and command line arguments in the +\fIsudoers\fR +file. +Wildcard matching is done via the +glob(3) +and +fnmatch(3) +functions as specified by +IEEE Std 1003.1 (\(lqPOSIX.1\(rq). +.TP 10n +\fR*\fR +Matches any set of zero or more characters (including white space). +.TP 10n +\fR\&?\fR +Matches any single character (including white space). +.TP 10n +\fR[...]\fR +Matches any character in the specified range. +.TP 10n +\fR[!...]\fR +Matches any character +\fInot\fR +in the specified range. +.TP 10n +\fR\ex\fR +For any character +\(oqx\(cq, +evaluates to +\(oqx\(cq. +This is used to escape special characters such as: +\(oq*\(cq, +\(oq\&?\(cq, +\(oq[\&\(cq, +and +\(oq]\&\(cq. +.PP +\fBNote that these are not regular expressions.\fR +Unlike a regular expression there is no way to match one or more +characters within a range. +.PP +Character classes may be used if your system's +glob(3) +and +fnmatch(3) +functions support them. +However, because the +\(oq:\&\(cq +character has special meaning in +\fIsudoers\fR, +it must be +escaped. +For example: +.nf +.sp +.RS 4n +/bin/ls [[\e:\&alpha\e:\&]]* +.RE +.fi +.PP +Would match any file name beginning with a letter. +.PP +Note that a forward slash +(\(oq/\(cq) +will +\fInot\fR +be matched by +wildcards used in the file name portion of the command. +This is to make a path like: +.nf +.sp +.RS 4n +/usr/bin/* +.RE +.fi +.PP +match +\fI/usr/bin/who\fR +but not +\fI/usr/bin/X11/xterm\fR. +.PP +When matching the command line arguments, however, a slash +\fIdoes\fR +get matched by wildcards since command line arguments may contain +arbitrary strings and not just path names. +.PP +\fBWildcards in command line arguments should be used with care.\fR +.br +Command line arguments are matched as a single, concatenated string. +This mean a wildcard character such as +\(oq\&?\(cq +or +\(oq*\(cq +will match across word boundaries, which may be unexpected. +For example, while a sudoers entry like: +.nf +.sp +.RS 4n +%operator ALL = /bin/cat /var/log/messages* +.RE +.fi +.PP +will allow command like: +.nf +.sp +.RS 4n +$ sudo cat /var/log/messages.1 +.RE +.fi +.PP +It will also allow: +.nf +.sp +.RS 4n +$ sudo cat /var/log/messages /etc/shadow +.RE +.fi +.PP +which is probably not what was intended. +In most cases it is better to do command line processing +outside of the +\fIsudoers\fR +file in a scripting language. +.SS "Exceptions to wildcard rules" +The following exceptions apply to the above rules: +.TP 10n +\fR\&""\fR +If the empty string +\fR\&""\fR +is the only command line argument in the +\fIsudoers\fR +file entry it means that command is not allowed to be run with +\fIany\fR +arguments. +.TP 10n +sudoedit +Command line arguments to the +\fIsudoedit\fR +built-in command should always be path names, so a forward slash +(\(oq/\(cq) +will not be matched by a wildcard. +.SS "Including other files from within sudoers" +It is possible to include other +\fIsudoers\fR +files from within the +\fIsudoers\fR +file currently being parsed using the +\fR@include\fR +and +\fR@includedir\fR +directives. +For compatibility with sudo versions prior to 1.9.1, +\fR#include\fR +and +\fR#includedir\fR +are also accepted. +.PP +An include file can be used, for example, to keep a site-wide +\fIsudoers\fR +file in addition to a local, per-machine file. +For the sake of this example the site-wide +\fIsudoers\fR +file will be +\fI/etc/sudoers\fR +and the per-machine one will be +\fI/etc/sudoers.local\fR. +To include +\fI/etc/sudoers.local\fR +from within +\fI/etc/sudoers\fR +one would use the following line in +\fI/etc/sudoers\fR: +.nf +.sp +.RS 4n +@include /etc/sudoers.local +.RE +.fi +.PP +When +\fBsudo\fR +reaches this line it will suspend processing of the current file +(\fI/etc/sudoers\fR) +and switch to +\fI/etc/sudoers.local\fR. +Upon reaching the end of +\fI/etc/sudoers.local\fR, +the rest of +\fI/etc/sudoers\fR +will be processed. +Files that are included may themselves include other files. +A hard limit of 128 nested include files is enforced to prevent include +file loops. +.PP +The path to the include file may contain white space if it is +escaped with a backslash +(\(oq\e\(cq). +Alternately, the entire path may be enclosed in double quotes +(\&""), +in which case no escaping is necessary. +To include a literal backslash in the path, +\(oq\e\e\(cq +should be used. +.PP +If the path to the include file is not fully-qualified (does not +begin with a +\(oq/\(cq), +it must be located in the same directory as the sudoers file it was +included from. +For example, if +\fI/etc/sudoers\fR +contains the line: +.nf +.sp +.RS 4n +\fR@include sudoers.local\fR +.RE +.fi +.PP +the file that will be included is +\fI/etc/sudoers.local\fR. +.PP +The file name may also include the +\fR%h\fR +escape, signifying the short form of the host name. +In other words, if the machine's host name is +\(lqxerxes\(rq, +then +.nf +.sp +.RS 4n +@include /etc/sudoers.%h +.RE +.fi +.PP +will cause +\fBsudo\fR +to include the file +\fI/etc/sudoers.xerxes\fR. +.PP +The +\fR@includedir\fR +directive can be used to create a +\fIsudoers.d\fR +directory that the system package manager can drop +\fIsudoers\fR +file rules into as part of package installation. +For example, given: +.nf +.sp +.RS 4n +@includedir /etc/sudoers.d +.RE +.fi +.PP +\fBsudo\fR +will suspend processing of the current file and read each file in +\fI/etc/sudoers.d\fR, +skipping file names that end in +\(oq~\(cq +or contain a +\(oq.\&\(cq +character to avoid causing problems with package manager or editor +temporary/backup files. +Files are parsed in sorted lexical order. +That is, +\fI/etc/sudoers.d/01_first\fR +will be parsed before +\fI/etc/sudoers.d/10_second\fR. +Be aware that because the sorting is lexical, not numeric, +\fI/etc/sudoers.d/1_whoops\fR +would be loaded +\fIafter\fR +\fI/etc/sudoers.d/10_second\fR. +Using a consistent number of leading zeroes in the file names can be used +to avoid such problems. +After parsing the files in the directory, control returns to the +file that contained the +\fR@includedir\fR +directive. +.PP +Note that unlike files included via +\fR@include\fR, +\fBvisudo\fR +will not edit the files in a +\fR@includedir\fR +directory unless one of them contains a syntax error. +It is still possible to run +\fBvisudo\fR +with the +\fB\-f\fR +flag to edit the files directly, but this will not catch the +redefinition of an +\fIalias\fR +that is also present in a different file. +.SS "Other special characters and reserved words" +The pound sign +(\(oq#\(cq) +is used to indicate a comment (unless it is part of a #include +directive or unless it occurs in the context of a user name and is +followed by one or more digits, in which case it is treated as a +user-ID). +Both the comment character and any text after it, up to the end of +the line, are ignored. +.PP +The reserved word +\fBALL\fR +is a built-in +\fIalias\fR +that always causes a match to succeed. +It can be used wherever one might otherwise use a +\fRCmnd_Alias\fR, +\fRUser_Alias\fR, +\fRRunas_Alias\fR, +or +\fRHost_Alias\fR. +Attempting to define an +\fIalias\fR +named +\fBALL\fR +will result in a syntax error. +Please note that using +\fBALL\fR +can be dangerous since in a command context, it allows the user to run +\fIany\fR +command on the system. +.PP +The following option names permitted in an +\fROption_Spec\fR +are also considered reserved words: +\fRCHROOT\fR, +.if \n(PS \{\ +\fRPRIVS\fR, +.\} +.if \n(PS \{\ +\fRLIMITPRIVS\fR, +.\} +.if \n(SL \{\ +\fRROLE\fR, +.\} +.if \n(SL \{\ +\fRTYPE\fR, +.\} +\fRTIMEOUT\fR, +\fRCWD\fR, +\fRNOTBEFORE\fR +and +\fRNOTAFTER\fR. +Attempting to define an +\fIalias\fR +with the same name as one of the options will result in a syntax error. +.PP +An exclamation point +(\(oq\&!\(cq) +can be used as a logical +\fInot\fR +operator in a list or +\fIalias\fR +as well as in front of a +\fRCmnd\fR. +This allows one to exclude certain values. +For the +\(oq\&!\(cq +operator to be effective, there must be something for it to exclude. +For example, to match all users except for root one would use: +.nf +.sp +.RS 4n +ALL,!root +.RE +.fi +.PP +If the +\fBALL\fR, +is omitted, as in: +.nf +.sp +.RS 4n +!root +.RE +.fi +.PP +it would explicitly deny root but not match any other users. +This is different from a true +\(lqnegation\(rq +operator. +.PP +Note, however, that using a +\(oq\&!\(cq +in conjunction with the built-in +\fBALL\fR +alias to allow a user to run +\(lqall but a few\(rq +commands rarely works as intended (see +\fISECURITY NOTES\fR +below). +.PP +Long lines can be continued with a backslash +(\(oq\e\(cq) +as the last character on the line. +.PP +White space between elements in a list as well as special syntactic +characters in a +\fIUser Specification\fR +(\(oq=\&\(cq, +\(oq:\&\(cq, +\(oq(\&\(cq, +\(oq)\&\(cq) +is optional. +.PP +The following characters must be escaped with a backslash +(\(oq\e\(cq) +when used as part of a word (e.g., a user name or host name): +\(oq\&!\(cq, +\(oq=\&\(cq, +\(oq:\&\(cq, +\(oq,\&\(cq, +\(oq(\&\(cq, +\(oq)\&\(cq, +\(oq\e\(cq. +.SH "SUDOERS OPTIONS" +\fBsudo\fR's +behavior can be modified by +\fRDefault_Entry\fR +lines, as explained earlier. +A list of all supported Defaults parameters, grouped by type, are listed below. +.PP +\fBBoolean Flags\fR: +.TP 18n +always_query_group_plugin +If a +\fIgroup_plugin\fR +is configured, use it to resolve groups of the form %group as long +as there is not also a system group of the same name. +Normally, only groups of the form %:group are passed to the +\fIgroup_plugin\fR. +This flag is +\fIoff\fR +by default. +.TP 18n +always_set_home +If enabled, +\fBsudo\fR +will set the +\fRHOME\fR +environment variable to the home directory of the target user +(which is the root user unless the +\fB\-u\fR +option is used). +This flag is largely obsolete and has no effect unless the +\fIenv_reset\fR +flag has been disabled or +\fRHOME\fR +is present in the +\fIenv_keep\fR +list, both of which are strongly discouraged. +This flag is +\fIoff\fR +by default. +.TP 18n +authenticate +If set, users must authenticate themselves via a password (or other +means of authentication) before they may run commands. +This default may be overridden via the +\fRPASSWD\fR +and +\fRNOPASSWD\fR +tags. +This flag is +\fIon\fR +by default. +.TP 18n +case_insensitive_group +If enabled, group names in +\fIsudoers\fR +will be matched in a case insensitive manner. +This may be necessary when users are stored in LDAP or AD. +This flag is +\fIon\fR +by default. +.TP 18n +case_insensitive_user +If enabled, user names in +\fIsudoers\fR +will be matched in a case insensitive manner. +This may be necessary when groups are stored in LDAP or AD. +This flag is +\fIon\fR +by default. +.TP 18n +closefrom_override +If set, the user may use the +\fB\-C\fR +option which overrides the default starting point at which +\fBsudo\fR +begins closing open file descriptors. +This flag is +\fIoff\fR +by default. +.TP 18n +compress_io +If set, and +\fBsudo\fR +is configured to log a command's input or output, +the I/O logs will be compressed using +\fBzlib\fR. +This flag is +\fIon\fR +by default when +\fBsudo\fR +is compiled with +\fBzlib\fR +support. +.TP 18n +exec_background +By default, +\fBsudo\fR +runs a command as the foreground process as long as +\fBsudo\fR +itself is running in the foreground. +When the +\fIexec_background\fR +flag is enabled and the command is being run in a pseudo-terminal +(due to I/O logging or the +\fIuse_pty\fR +flag), the command will be run as a background process. +Attempts to read from the controlling terminal (or to change terminal +settings) will result in the command being suspended with the +\fRSIGTTIN\fR +signal (or +\fRSIGTTOU\fR +in the case of terminal settings). +If this happens when +\fBsudo\fR +is a foreground process, the command will be granted the controlling terminal +and resumed in the foreground with no user intervention required. +The advantage of initially running the command in the background is that +\fBsudo\fR +need not read from the terminal unless the command explicitly requests it. +Otherwise, any terminal input must be passed to the command, whether it +has required it or not (the kernel buffers terminals so it is not possible +to tell whether the command really wants the input). +This is different from historic +\fIsudo\fR +behavior or when the command is not being run in a pseudo-terminal. +.sp +For this to work seamlessly, the operating system must support the +automatic restarting of system calls. +Unfortunately, not all operating systems do this by default, +and even those that do may have bugs. +For example, macOS fails to restart the +\fBtcgetattr\fR() +and +\fBtcsetattr\fR() +system calls (this is a bug in macOS). +Furthermore, because this behavior depends on the command stopping with the +\fRSIGTTIN\fR +or +\fRSIGTTOU\fR +signals, programs that catch these signals and suspend themselves +with a different signal (usually +\fRSIGTOP\fR) +will not be automatically foregrounded. +Some versions of the linux +su(1) +command behave this way. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.7 or higher. +It has no effect unless I/O logging is enabled or the +\fIuse_pty\fR +flag is enabled. +.TP 18n +env_editor +If set, +\fBvisudo\fR +will use the value of the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variables before falling back on the default editor list. +Note that +\fBvisudo\fR +is typically run as root so this flag may allow a user with +\fBvisudo\fR +privileges to run arbitrary commands as root without logging. +An alternative is to place a colon-separated list of +\(lqsafe\(rq +editors int the +\fIeditor\fR +variable. +\fBvisudo\fR +will then only use +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +if they match a value specified in +\fIeditor\fR. +If the +\fIenv_reset\fR +flag is enabled, the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +and/or +\fREDITOR\fR +environment variables must be present in the +\fIenv_keep\fR +list for the +\fIenv_editor\fR +flag to function when +\fBvisudo\fR +is invoked via +\fBsudo\fR. +This flag is +\fI@env_editor@\fR +by default. +.TP 18n +env_reset +If set, +\fBsudo\fR +will run the command in a minimal environment containing the +\fRTERM\fR, +\fRPATH\fR, +\fRHOME\fR, +\fRMAIL\fR, +\fRSHELL\fR, +\fRLOGNAME\fR, +\fRUSER\fR +and +\fRSUDO_*\fR +variables. +Any variables in the caller's environment or in the file specified +by the +\fIrestricted_env_file\fR +setting that match the +\fRenv_keep\fR +and +\fRenv_check\fR +lists are then added, followed by any variables present in the file +specified by the +\fIenv_file\fR +setting (if any). +The contents of the +\fRenv_keep\fR +and +\fRenv_check\fR +lists, as modified by global Defaults parameters in +\fIsudoers\fR, +are displayed when +\fBsudo\fR +is run by root with the +\fB\-V\fR +option. +If the +\fIsecure_path\fR +setting is enabled, its value will be used for the +\fRPATH\fR +environment variable. +This flag is +\fI@env_reset@\fR +by default. +.TP 18n +fast_glob +Normally, +\fBsudo\fR +uses the +glob(3) +function to do shell-style globbing when matching path names. +However, since it accesses the file system, +glob(3) +can take a long time to complete for some patterns, especially +when the pattern references a network file system that is mounted +on demand (auto mounted). +The +\fIfast_glob\fR +flag causes +\fBsudo\fR +to use the +fnmatch(3) +function, which does not access the file system to do its matching. +The disadvantage of +\fIfast_glob\fR +is that it is unable to match relative path names such as +\fI./ls\fR +or +\fI../bin/ls\fR. +This has security implications when path names that include globbing +characters are used with the negation operator, +\(oq!\&\(cq, +as such rules can be trivially bypassed. +As such, this flag should not be used when the +\fIsudoers\fR +file contains rules that contain negated path names which include globbing +characters. +This flag is +\fIoff\fR +by default. +.TP 18n +fqdn +Set this flag if you want to put fully qualified host names in the +\fIsudoers\fR +file when the local host name (as returned by the +\fRhostname\fR +command) does not contain the domain name. +In other words, instead of myhost you would use myhost.mydomain.edu. +You may still use the short form if you wish (and even mix the two). +This flag is only effective when the +\(lqcanonical\(rq +host name, as returned by the +\fBgetaddrinfo\fR() +or +\fBgethostbyname\fR() +function, is a fully-qualified domain name. +This is usually the case when the system is configured to use DNS +for host name resolution. +.sp +If the system is configured to use the +\fI/etc/hosts\fR +file in preference to DNS, the +\(lqcanonical\(rq +host name may not be fully-qualified. +The order that sources are queried for host name resolution +is usually specified in the +\fI@nsswitch_conf@\fR, +\fI@netsvc_conf@\fR, +\fI/etc/host.conf\fR, +or, in some cases, +\fI/etc/resolv.conf\fR +file. +In the +\fI/etc/hosts\fR +file, the first host name of the entry is considered to be the +\(lqcanonical\(rq +name; subsequent names are aliases that are not used by +\fBsudoers\fR. +For example, the following hosts file line for the machine +\(lqxyzzy\(rq +has the fully-qualified domain name as the +\(lqcanonical\(rq +host name, and the short version as an alias. +.sp +.RS 24n +192.168.1.1 xyzzy.sudo.ws xyzzy +.RE +.RS 18n +.sp +If the machine's hosts file entry is not formatted properly, the +\fIfqdn\fR +flag will not be effective if it is queried before DNS. +.sp +Beware that when using DNS for host name resolution, turning on +\fIfqdn\fR +requires +\fBsudoers\fR +to make DNS lookups which renders +\fBsudo\fR +unusable if DNS stops working (for example if the machine is disconnected +from the network). +Also note that just like with the hosts file, you must use the +\(lqcanonical\(rq +name as DNS knows it. +That is, you may not use a host alias +(\fRCNAME\fR +entry) +due to performance issues and the fact that there is no way to get all +aliases from DNS. +.sp +This flag is +\fI@fqdn@\fR +by default. +.RE +.TP 18n +ignore_audit_errors +Allow commands to be run even if +\fBsudoers\fR +cannot write to the audit log. +If enabled, an audit log write failure is not treated as a fatal error. +If disabled, a command may only be run after the audit event is successfully +written. +This flag is only effective on systems for which +\fBsudoers\fR +supports audit logging, including +FreeBSD, +Linux, macOS and Solaris. +This flag is +\fIon\fR +by default. +.TP 18n +ignore_dot +If set, +\fBsudo\fR +will ignore "." or "" (both denoting current directory) in the +\fRPATH\fR +environment variable; the +\fRPATH\fR +itself is not modified. +This flag is +\fI@ignore_dot@\fR +by default. +.TP 18n +ignore_iolog_errors +Allow commands to be run even if +\fBsudoers\fR +cannot write to the I/O log (local or remote). +If enabled, an I/O log write failure is not treated as a fatal error. +If disabled, the command will be terminated if the I/O log cannot be written to. +This flag is +\fIoff\fR +by default. +.TP 18n +ignore_logfile_errors +Allow commands to be run even if +\fBsudoers\fR +cannot write to the log file. +If enabled, a log file write failure is not treated as a fatal error. +If disabled, a command may only be run after the log file entry is successfully +written. +This flag only has an effect when +\fBsudoers\fR +is configured to use file-based logging via the +\fIlogfile\fR +setting. +This flag is +\fIon\fR +by default. +.TP 18n +ignore_local_sudoers +If set via LDAP, parsing of +\fI@sysconfdir@/sudoers\fR +will be skipped. +This is intended for Enterprises that wish to prevent the usage of local +sudoers files so that only LDAP is used. +This thwarts the efforts of rogue operators who would attempt to add roles to +\fI@sysconfdir@/sudoers\fR. +When this flag is enabled, +\fI@sysconfdir@/sudoers\fR +does not even need to exist. +Since this flag tells +\fBsudo\fR +how to behave when no specific LDAP entries have been matched, this +sudoOption is only meaningful for the +\fRcn=defaults\fR +section. +This flag is +\fIoff\fR +by default. +.TP 18n +ignore_unknown_defaults +If set, +\fBsudo\fR +will not produce a warning if it encounters an unknown Defaults entry +in the +\fIsudoers\fR +file or an unknown sudoOption in LDAP. +This flag is +\fIoff\fR +by default. +.TP 18n +insults +If set, +\fBsudo\fR +will insult users when they enter an incorrect password. +This flag is +\fI@insults@\fR +by default. +.TP 18n +log_allowed +If set, +\fBsudoers\fR +will log commands allowed by the policy to the system audit log +(where supported) as well as to syslog and/or a log file. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.8.29 or higher. +.TP 18n +log_denied +If set, +\fBsudoers\fR +will log commands denied by the policy to the system audit log +(where supported) as well as to syslog and/or a log file. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.8.29 or higher. +.TP 18n +log_host +If set, the host name will be included in log entries written to +the file configured by the +\fIlogfile\fR +setting. +This flag is +\fIoff\fR +by default. +.TP 18n +log_input +If set, +\fBsudo\fR +will run the command in a pseudo-terminal and log all user input. +If the standard input is not connected to the user's tty, due to +I/O redirection or because the command is part of a pipeline, that +input is also captured and stored in a separate log file. +Anything sent to the standard input will be consumed, regardless of +whether or not the command run via +\fBsudo\fR +is actually reading the standard input. +This may have unexpected results when using +\fBsudo\fR +in a shell script that expects to process the standard input. +For more information about I/O logging, see the +\fII/O LOG FILES\fR +section. +This flag is +\fIoff\fR +by default. +.TP 18n +log_output +If set, +\fBsudo\fR +will run the command in a pseudo-terminal and log all output that is sent +to the screen, similar to the +script(1) +command. +For more information about I/O logging, see the +\fII/O LOG FILES\fR +section. +This flag is +\fIoff\fR +by default. +.TP 18n +log_server_keepalive +If set, +\fBsudo\fR +will enable the TCP keepalive socket option on the connection to the log server. +This enables the periodic transmission of keepalive messages to the server. +If the server does not respond to a message, the connection will +be closed and the running command will be terminated unless the +\fIignore_iolog_errors\fR +flag (I/O logging enabled) or the +\fIignore_log_errors\fR +flag (I/O logging disabled) is set. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +log_server_verify +.br +If set, the server certificate received during the TLS handshake +must be valid and it must contain either the server name (from +\fIlog_servers\fR) +or its IP address. +If either of these conditions is not met, the TLS handshake will fail. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +log_year +If set, the four-digit year will be logged in the (non-syslog) +\fBsudo\fR +log file. +This flag is +\fIoff\fR +by default. +.TP 18n +long_otp_prompt +When validating with a One Time Password (OTP) scheme such as +\fBS/Key\fR +or +\fBOPIE\fR, +a two-line prompt is used to make it easier +to cut and paste the challenge to a local window. +It's not as pretty as the default but some people find it more convenient. +This flag is +\fI@long_otp_prompt@\fR +by default. +.TP 18n +mail_all_cmnds +Send mail to the +\fImailto\fR +user every time a user attempts to run a command via +\fBsudo\fR +(this includes +\fBsudoedit\fR). +No mail will be sent if the user runs +\fBsudo\fR +with the +\fB\-l\fR +or +\fB\-v\fR +option unless there is an authentication error and the +\fImail_badpass\fR +flag is also set. +This flag is +\fIoff\fR +by default. +.TP 18n +mail_always +Send mail to the +\fImailto\fR +user every time a user runs +\fBsudo\fR. +This flag is +\fIoff\fR +by default. +.TP 18n +mail_badpass +Send mail to the +\fImailto\fR +user if the user running +\fBsudo\fR +does not enter the correct password. +If the command the user is attempting to run is not permitted by +\fBsudoers\fR +and one of the +\fImail_all_cmnds\fR, +\fImail_always\fR, +\fImail_no_host\fR, +\fImail_no_perms\fR +or +\fImail_no_user\fR +flags are set, this flag will have no effect. +This flag is +\fIoff\fR +by default. +.TP 18n +mail_no_host +If set, mail will be sent to the +\fImailto\fR +user if the invoking user exists in the +\fIsudoers\fR +file, but is not allowed to run commands on the current host. +This flag is +\fI@mail_no_host@\fR +by default. +.TP 18n +mail_no_perms +If set, mail will be sent to the +\fImailto\fR +user if the invoking user is allowed to use +\fBsudo\fR +but the command they are trying is not listed in their +\fIsudoers\fR +file entry or is explicitly denied. +This flag is +\fI@mail_no_perms@\fR +by default. +.TP 18n +mail_no_user +If set, mail will be sent to the +\fImailto\fR +user if the invoking user is not in the +\fIsudoers\fR +file. +This flag is +\fI@mail_no_user@\fR +by default. +.TP 18n +match_group_by_gid +By default, +\fBsudoers\fR +will look up each group the user is a member of by group-ID to +determine the group name (this is only done once). +The resulting list of the user's group names is used when matching +groups listed in the +\fIsudoers\fR +file. +This works well on systems where the number of groups listed in the +\fIsudoers\fR +file is larger than the number of groups a typical user belongs to. +On systems where group lookups are slow, where users may belong +to a large number of groups, and where the number of groups listed +in the +\fIsudoers\fR +file is relatively small, it may be prohibitively expensive and +running commands via +\fBsudo\fR +may take longer than normal. +On such systems it may be faster to use the +\fImatch_group_by_gid\fR +flag to avoid resolving the user's group-IDs to group names. +In this case, +\fBsudoers\fR +must look up any group name listed in the +\fIsudoers\fR +file and use the group-ID instead of the group name when determining +whether the user is a member of the group. +.sp +Note that if +\fImatch_group_by_gid\fR +is enabled, group database lookups performed by +\fBsudoers\fR +will be keyed by group name as opposed to group-ID. +On systems where there are multiple sources for the group database, +it is possible to have conflicting group names or group-IDs in the local +\fI/etc/group\fR +file and the remote group database. +On such systems, enabling or disabling +\fImatch_group_by_gid\fR +can be used to choose whether group database queries are performed +by name (enabled) or ID (disabled), which may aid in working around +group entry conflicts. +.sp +The +\fImatch_group_by_gid\fR +flag has no effect when +\fIsudoers\fR +data is stored in LDAP. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.18 or higher. +.TP 18n +netgroup_tuple +If set, netgroup lookups will be performed using the full netgroup +tuple: host name, user name and domain (if one is set). +Historically, +\fBsudo\fR +only matched the user name and domain for netgroups used in a +\fRUser_List\fR +and only matched the host name and domain for netgroups used in a +\fRHost_List\fR. +This flag is +\fIoff\fR +by default. +.TP 18n +noexec +If set, all commands run via +\fBsudo\fR +will behave as if the +\fRNOEXEC\fR +tag has been set, unless overridden by an +\fREXEC\fR +tag. +See the description of +\fIEXEC and NOEXEC\fR +above as well as the +\fIPreventing shell escapes\fR +section at the end of this manual. +This flag is +\fIoff\fR +by default. +.TP 18n +pam_acct_mgmt +On systems that use PAM for authentication, +\fBsudo\fR +will perform PAM account validation for the invoking user by default. +The actual checks performed depend on which PAM modules are configured. +If enabled, account validation will be performed regardless of whether +or not a password is required. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.8.28 or higher. +.TP 18n +pam_rhost +On systems that use PAM for authentication, +\fBsudo\fR +will set the PAM remote host value to the name of the local host +when the +\fIpam_rhost\fR +flag is enabled. +On Linux systems, enabling +\fIpam_rhost\fR +may result in DNS lookups of the local host name when PAM is initialized. +On Solaris versions prior to Solaris 8, +\fIpam_rhost\fR +must be enabled if +\fIpam_ruser\fR +is also enabled to avoid a crash in the Solaris PAM implementation. +.sp +This flag is +\fIoff\fR +by default on systems other than Solaris. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +pam_ruser +On systems that use PAM for authentication, +\fBsudo\fR +will set the PAM remote user value to the name of the user that invoked sudo +when the +\fIpam_ruser\fR +flag is enabled. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +pam_session +On systems that use PAM for authentication, +\fBsudo\fR +will create a new PAM session for the command to be run in. +Unless +\fBsudo\fR +is given the +\fB\-i\fR +or +\fB\-s\fR +options, PAM session modules are run with the +\(lqsilent\(rq +flag enabled. +This prevents last login information from being displayed for every +command on some systems. +Disabling +\fIpam_session\fR +may be needed on older PAM implementations or on operating systems where +opening a PAM session changes the utmp or wtmp files. +If PAM session support is disabled, resource limits may not be updated +for the command being run. +If +\fIpam_session\fR, +\fIpam_setcred\fR, +and +\fIuse_pty\fR +are disabled, +\fIlog_servers\fR +has not been set and I/O logging has not been configured, +\fBsudo\fR +will execute the command directly instead of running it as a child +process. +This flag is +\fI@pam_session@\fR +by default. +.sp +This setting is only supported by version 1.8.7 or higher. +.TP 18n +pam_setcred +On systems that use PAM for authentication, +\fBsudo\fR +will attempt to establish credentials for the target user by default, +if supported by the underlying authentication system. +One example of a credential is a Kerberos ticket. +If +\fIpam_session\fR, +\fIpam_setcred\fR, +and +\fIuse_pty\fR +are disabled, +\fIlog_servers\fR +has not been set and I/O logging has not been configured, +\fBsudo\fR +will execute the command directly instead of running it as a child +process. +This flag is +\fIon\fR +by default. +.sp +This setting is only supported by version 1.8.8 or higher. +.TP 18n +passprompt_override +If set, the prompt specified by +\fIpassprompt\fR +or the +\fRSUDO_PROMPT\fR +environment variable will always be used and will replace the +prompt provided by a PAM module or other authentication method. +This flag is +\fIoff\fR +by default. +.TP 18n +path_info +Normally, +\fBsudo\fR +will tell the user when a command could not be +found in their +\fRPATH\fR +environment variable. +Some sites may wish to disable this as it could be used to gather +information on the location of executables that the normal user does +not have access to. +The disadvantage is that if the executable is simply not in the user's +\fRPATH\fR, +\fBsudo\fR +will tell the user that they are not allowed to run it, which can be confusing. +This flag is +\fI@path_info@\fR +by default. +.TP 18n +preserve_groups +By default, +\fBsudo\fR +will initialize the group vector to the list of groups the target user is in. +When +\fIpreserve_groups\fR +is set, the user's existing group vector is left unaltered. +The real and effective group-IDs, however, are still set to match the +target user. +This flag is +\fIoff\fR +by default. +.TP 18n +pwfeedback +By default, +\fBsudo\fR +reads the password like most other Unix programs, +by turning off echo until the user hits the return (or enter) key. +Some users become confused by this as it appears to them that +\fBsudo\fR +has hung at this point. +When +\fIpwfeedback\fR +is set, +\fBsudo\fR +will provide visual feedback when the user presses a key. +Note that this does have a security impact as an onlooker may be able to +determine the length of the password being entered. +This flag is +\fIoff\fR +by default. +.TP 18n +requiretty +If set, +\fBsudo\fR +will only run when the user is logged in to a real tty. +When this flag is set, +\fBsudo\fR +can only be run from a login session and not via other means such as +cron(@mansectsu@) +or cgi-bin scripts. +This flag is +\fIoff\fR +by default. +.TP 18n +root_sudo +If set, root is allowed to run +\fBsudo\fR +too. +Disabling this prevents users from +\(lqchaining\(rq +\fBsudo\fR +commands to get a root shell by doing something like +\(lq\fRsudo sudo /bin/sh\fR\(rq. +Note, however, that turning off +\fIroot_sudo\fR +will also prevent root from running +\fBsudoedit\fR. +Disabling +\fIroot_sudo\fR +provides no real additional security; it exists purely for historical reasons. +This flag is +\fI@root_sudo@\fR +by default. +.TP 18n +rootpw +If set, +\fBsudo\fR +will prompt for the root password instead of the password of the invoking user +when running a command or editing a file. +This flag is +\fIoff\fR +by default. +.TP 18n +runas_allow_unknown_id +If enabled, allow matching of runas user and group IDs that are +not present in the password or group databases. +In addition to explicitly matching unknown user or group IDs in a +\fRRunas_List\fR, +this option also allows the +\fBALL\fR +alias to match unknown IDs. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.30 or higher. +Older versions of +\fBsudo\fR +always allowed matching of unknown user and group IDs. +.TP 18n +runas_check_shell +.br +If enabled, +\fBsudo\fR +will only run commands as a user whose shell appears in the +\fI/etc/shells\fR +file, even if the invoking user's +\fRRunas_List\fR +would otherwise permit it. +If no +\fI/etc/shells\fR +file is present, a system-dependent list of built-in default shells is used. +On many operating systems, system users such as +\(lqbin\(rq, +do not have a valid shell and this flag can be used to prevent +commands from being run as those users. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.30 or higher. +.TP 18n +runaspw +If set, +\fBsudo\fR +will prompt for the password of the user defined by the +\fIrunas_default\fR +option (defaults to +\fR@runas_default@\fR) +instead of the password of the invoking user +when running a command or editing a file. +This flag is +\fIoff\fR +by default. +.if \n(SL \{\ +.TP 18n +selinux +If enabled, the user may specify an SELinux role and/or type to use +when running the command, as permitted by the SELinux policy. +If SELinux is disabled on the system, this flag has no effect. +This flag is +\fIon\fR +by default. +.\} +.TP 18n +set_home +If enabled and +\fBsudo\fR +is invoked with the +\fB\-s\fR +option, the +\fRHOME\fR +environment variable will be set to the home directory of the target +user (which is the root user unless the +\fB\-u\fR +option is used). +This flag is largely obsolete and has no effect unless the +\fIenv_reset\fR +flag has been disabled or +\fRHOME\fR +is present in the +\fIenv_keep\fR +list, both of which are strongly discouraged. +This flag is +\fIoff\fR +by default. +.TP 18n +set_logname +Normally, +\fBsudo\fR +will set the +\fRLOGNAME\fR +and +\fRUSER\fR +environment variables to the name of the target user (usually root unless the +\fB\-u\fR +option is given). +However, since some programs (including the RCS revision control system) use +\fRLOGNAME\fR +to determine the real identity of the user, it may be desirable to +change this behavior. +This can be done by negating the set_logname option. +Note that +\fIset_logname\fR +will have no effect +if the +\fIenv_reset\fR +option has not been disabled and the +\fIenv_keep\fR +list contains +\fRLOGNAME\fR +or +\fRUSER\fR. +This flag is +\fIon\fR +by default. +.TP 18n +set_utmp +When enabled, +\fBsudo\fR +will create an entry in the utmp (or utmpx) file when a pseudo-terminal +is allocated. +A pseudo-terminal is allocated by +\fBsudo\fR +when it is running in a terminal and one or more of the +\fIlog_input\fR, +\fIlog_output\fR +or +\fIuse_pty\fR +flags is enabled. +By default, the new entry will be a copy of the user's existing utmp +entry (if any), with the tty, time, type and pid fields updated. +This flag is +\fIon\fR +by default. +.TP 18n +setenv +Allow the user to disable the +\fIenv_reset\fR +option from the command line via the +\fB\-E\fR +option. +Additionally, environment variables set via the command line are +not subject to the restrictions imposed by +\fIenv_check\fR, +\fIenv_delete\fR, +or +\fIenv_keep\fR. +As such, only trusted users should be allowed to set variables in this manner. +This flag is +\fIoff\fR +by default. +.TP 18n +shell_noargs +If set and +\fBsudo\fR +is invoked with no arguments it acts as if the +\fB\-s\fR +option had been given. +That is, it runs a shell as root (the shell is determined by the +\fRSHELL\fR +environment variable if it is set, falling back on the shell listed +in the invoking user's /etc/passwd entry if not). +This flag is +\fIoff\fR +by default. +.TP 18n +stay_setuid +Normally, when +\fBsudo\fR +executes a command the real and effective UIDs are set to the target +user (root by default). +This option changes that behavior such that the real UID is left +as the invoking user's UID. +In other words, this makes +\fBsudo\fR +act as a set-user-ID wrapper. +This can be useful on systems that disable some potentially +dangerous functionality when a program is run set-user-ID. +This option is only effective on systems that support either the +setreuid(2) +or +setresuid(2) +system call. +This flag is +\fIoff\fR +by default. +.TP 18n +sudoedit_checkdir +.br +If set, +\fBsudoedit\fR +will check all directory components of the path to be edited for writability +by the invoking user. +Symbolic links will not be followed in writable directories and +\fBsudoedit\fR +will refuse to edit a file located in a writable directory. +These restrictions are not enforced when +\fBsudoedit\fR +is run by root. +On some systems, if all directory components of the path to be edited +are not readable by the target user, +\fBsudoedit\fR +will be unable to edit the file. +This flag is +\fIon\fR +by default. +.sp +This setting was first introduced in version 1.8.15 but initially +suffered from a race condition. +The check for symbolic links in writable intermediate directories +was added in version 1.8.16. +.TP 18n +sudoedit_follow +By default, +\fBsudoedit\fR +will not follow symbolic links when opening files. +The +\fIsudoedit_follow\fR +option can be enabled to allow +\fBsudoedit\fR +to open symbolic links. +It may be overridden on a per-command basis by the +\fIFOLLOW\fR +and +\fINOFOLLOW\fR +tags. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.15 or higher. +.TP 18n +syslog_pid +When logging via +syslog(3), +include the process ID in the log entry. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.21 or higher. +.TP 18n +targetpw +If set, +\fBsudo\fR +will prompt for the password of the user specified +by the +\fB\-u\fR +option (defaults to +\fRroot\fR) +instead of the password of the invoking user +when running a command or editing a file. +Note that this flag precludes the use of a user-ID not listed in the passwd +database as an argument to the +\fB\-u\fR +option. +This flag is +\fIoff\fR +by default. +.TP 18n +tty_tickets +If set, users must authenticate on a per-tty basis. +With this flag enabled, +\fBsudo\fR +will use a separate record in the time stamp file for each terminal. +If disabled, a single record is used for all login sessions. +.sp +This option has been superseded by the +\fItimestamp_type\fR +option. +.TP 18n +umask_override +If set, +\fBsudo\fR +will set the umask as specified in the +\fIsudoers\fR +file without modification. +This makes it possible to specify a umask in the +\fIsudoers\fR +file that is more permissive than the user's own umask and matches +historical behavior. +If +\fIumask_override\fR +is not set, +\fBsudo\fR +will set the umask to be the union of the user's umask and what is specified in +\fIsudoers\fR. +This flag is +\fI@umask_override@\fR +by default. +.if \n(BA \{\ +.TP 18n +use_loginclass +If set, +\fBsudo\fR +will apply the defaults specified for the target user's login class +if one exists. +Only available if +\fBsudo\fR +is configured with the +\fR--with-logincap\fR +option. +This flag is +\fIoff\fR +by default. +.\} +.TP 18n +use_netgroups +If set, netgroups (prefixed with +\(oq+\(cq), +may be used in place of a user or host. +For LDAP-based sudoers, netgroup support requires an expensive +sub-string match on the server unless the +\fBNETGROUP_BASE\fR +directive is present in the +\fI@ldap_conf@\fR +file. +If netgroups are not needed, this option can be disabled to reduce the +load on the LDAP server. +This flag is +\fIon\fR +by default. +.TP 18n +use_pty +If set, and +\fBsudo\fR +is running in a terminal, the command will be run in a pseudo-terminal +(even if no I/O logging is being done). +If the +\fBsudo\fR +process is not attached to a terminal, +\fIuse_pty\fR +has no effect. +.sp +A malicious program run under +\fBsudo\fR +may be capable of injecting commands into the user's +terminal or running a background process that retains access to the +user's terminal device even after the main program has finished +executing. +By running the command in a separate pseudo-terminal, this attack is +no longer possible. +This flag is +\fIoff\fR +by default. +.TP 18n +user_command_timeouts +If set, the user may specify a timeout on the command line. +If the timeout expires before the command has exited, the +command will be terminated. +If a timeout is specified both in the +\fIsudoers\fR +file and on the command line, the smaller of the two timeouts will be used. +See the +\fRTimeout_Spec\fR +section for a description of the timeout syntax. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.20 or higher. +.TP 18n +utmp_runas +If set, +\fBsudo\fR +will store the name of the runas user when updating the utmp (or utmpx) file. +By default, +\fBsudo\fR +stores the name of the invoking user. +This flag is +\fIoff\fR +by default. +.TP 18n +visiblepw +By default, +\fBsudo\fR +will refuse to run if the user must enter a password but it is not +possible to disable echo on the terminal. +If the +\fIvisiblepw\fR +flag is set, +\fBsudo\fR +will prompt for a password even when it would be visible on the screen. +This makes it possible to run things like +\(lq\fRssh somehost sudo ls\fR\(rq +since by default, +ssh(1) +does +not allocate a tty when running a command. +This flag is +\fIoff\fR +by default. +.PP +\fBIntegers\fR: +.TP 18n +closefrom +Before it executes a command, +\fBsudo\fR +will close all open file descriptors other than standard input, +standard output and standard error (ie: file descriptors 0-2). +The +\fIclosefrom\fR +option can be used to specify a different file descriptor at which +to start closing. +The default is +\fR3\fR. +.TP 18n +command_timeout +The maximum amount of time a command is allowed to run before +it is terminated. +See the +\fRTimeout_Spec\fR +section for a description of the timeout syntax. +.sp +This setting is only supported by version 1.8.20 or higher. +.TP 18n +log_server_timeout +The maximum amount of time to wait when connecting to a log server +or waiting for a server response. +See the +\fRTimeout_Spec\fR +section for a description of the timeout syntax. +The default value is 30 seconds. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +maxseq +The maximum sequence number that will be substituted for the +\(lq\fR%{seq}\fR\(rq +escape in the I/O log file (see the +\fIiolog_dir\fR +description below for more information). +While the value substituted for +\(lq\fR%{seq}\fR\(rq +is in base 36, +\fImaxseq\fR +itself should be expressed in decimal. +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. +.sp +Once the local sequence number reaches the value of +\fImaxseq\fR, +it will +\(lqroll over\(rq +to zero, after which +\fBsudoers\fR +will truncate and re-use any existing I/O log path names. +.sp +This setting is only supported by version 1.8.7 or higher. +.TP 18n +passwd_tries +The number of tries a user gets to enter his/her password before +\fBsudo\fR +logs the failure and exits. +The default is +\fR@passwd_tries@\fR. +.TP 18n +syslog_maxlen +On many systems, +syslog(3) +has a relatively small log buffer. +IETF RFC 5424 states that syslog servers must support messages of +at least 480 bytes and should support messages up to 2048 bytes. +By default, +\fBsudoers\fR +creates log messages up to 980 bytes which corresponds to the +historic +BSD +syslog implementation which used a 1024 byte buffer +to store the message, date, hostname and program name. +To prevent syslog messages from being truncated, +\fBsudoers\fR +will split up log messages that are larger than +\fIsyslog_maxlen\fR +bytes. +When a message is split, additional parts will include the string +\(lq(command continued)\(rq +after the user name and before the continued command line arguments. +.sp +This setting is only supported by version 1.8.19 or higher. +.PP +\fBIntegers that can be used in a boolean context\fR: +.TP 18n +loglinelen +Number of characters per line for the file log. +This value is used to decide when to wrap lines for nicer log files. +This has no effect on the syslog log file, only the file log. +The default is +\fR@loglen@\fR +(use 0 or negate the option to disable word wrap). +.TP 18n +passwd_timeout +Number of minutes before the +\fBsudo\fR +password prompt times out, or +\fR0\fR +for no timeout. +The timeout may include a fractional component +if minute granularity is insufficient, for example +\fR2.5\fR. +The +default is +\fR@password_timeout@\fR. +.TP 18n +timestamp_timeout +.br +Number of minutes that can elapse before +\fBsudo\fR +will ask for a passwd again. +The timeout may include a fractional component if +minute granularity is insufficient, for example +\fR2.5\fR. +The default is +\fR@timeout@\fR. +Set this to +\fR0\fR +to always prompt for a password. +If set to a value less than +\fR0\fR +the user's time stamp will not expire until the system is rebooted. +This can be used to allow users to create or delete their own time stamps via +\(lq\fRsudo -v\fR\(rq +and +\(lq\fRsudo -k\fR\(rq +respectively. +.TP 18n +umask +File mode creation mask to use when running the command. +Negate this option or set it to 0777 to prevent +\fBsudoers\fR +from changing the umask. +Unless the +\fIumask_override\fR +flag is set, the actual umask will be the union of the +user's umask and the value of the +\fIumask\fR +setting, which defaults to +\fR@sudo_umask@\fR. +This guarantees +that +\fBsudo\fR +never lowers the umask when running a command. +.sp +If +\fIumask\fR +is explicitly set in +\fIsudoers\fR, +it will override any umask setting in PAM or login.conf. +If +\fIumask\fR +is not set in +\fIsudoers\fR, +the umask specified by PAM or login.conf will take precedence. +The umask setting in PAM is not used for +\fBsudoedit\fR, +which does not create a new PAM session. +.PP +\fBStrings\fR: +.TP 18n +authfail_message +Message that is displayed after a user fails to authenticate. +The message may include the +\(oq%d\(cq +escape which will expand to the number of failed password attempts. +If set, it overrides the default message, +\fR%d incorrect password attempt(s)\fR. +.TP 18n +badpass_message +Message that is displayed if a user enters an incorrect password. +The default is +\fR@badpass_message@\fR +unless insults are enabled. +.TP 18n +editor +A colon +(\(oq:\&\(cq) +separated list of editors path names used by +\fBsudoedit\fR +and +\fBvisudo\fR. +For +\fBsudoedit\fR, +this list is used to find an editor when none of the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variables are set to an editor that exists and is executable. +For +\fBvisudo\fR, +it is used as a white list of allowed editors; +\fBvisudo\fR +will choose the editor that matches the user's +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variable if possible, or the first editor in the +list that exists and is executable if not. +Unless invoked as +\fBsudoedit\fR, +\fBsudo\fR +does not preserve the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variables unless they are present in the +\fIenv_keep\fR +list or the +\fIenv_reset\fR +option is disabled. +The default is +\fI@editor@\fR. +.TP 18n +iolog_dir +The top-level directory to use when constructing the path name for +the input/output log directory. +Only used if the +\fIlog_input\fR +or +\fIlog_output\fR +options are enabled or when the +\fRLOG_INPUT\fR +or +\fRLOG_OUTPUT\fR +tags are present for a command. +The session sequence number, if any, is stored in the directory. +The default is +\fI@iolog_dir@\fR. +.sp +The following percent +(\(oq%\(cq) +escape sequences are supported: +.PP +.RS 18n +.PD 0 +.TP 6n +\fR%{seq}\fR +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 +expanded to the invoking user's login name +.TP 6n +\fR%{group}\fR +expanded to the name of the invoking user's real group-ID +.TP 6n +\fR%{runas_user}\fR +expanded to the login name of the user the command will +be run as (e.g., root) +.TP 6n +\fR%{runas_group}\fR +expanded to the group name of the user the command will +be run as (e.g., wheel) +.TP 6n +\fR%{hostname}\fR +expanded to the local host name without the domain name +.TP 6n +\fR%{command}\fR +expanded to the base name of the command being run +.PP +In addition, any escape sequences supported by the system's +strftime(3) +function will be expanded. +.sp +To include a literal +\(oq%\(cq +character, the string +\(oq%%\(cq +should be used. +.RE +.TP 18n +iolog_file +The path name, relative to +\fIiolog_dir\fR, +in which to store input/output logs when the +\fIlog_input\fR +or +\fIlog_output\fR +options are enabled or when the +\fRLOG_INPUT\fR +or +\fRLOG_OUTPUT\fR +tags are present for a command. +Note that +\fIiolog_file\fR +may contain directory components. +The default is +\(lq\fR%{seq}\fR\(rq. +.sp +See the +\fIiolog_dir\fR +option above for a list of supported percent +(\(oq%\(cq) +escape sequences. +.sp +In addition to the escape sequences, path names that end in six or +more +\fRX\fRs +will have the +\fRX\fRs +replaced with a unique combination of digits and letters, similar to the +mktemp(3) +function. +.sp +If the path created by concatenating +\fIiolog_dir\fR +and +\fIiolog_file\fR +already exists, the existing I/O log file will be truncated and +overwritten unless +\fIiolog_file\fR +ends in six or +more +\fRX\fRs. +.TP 18n +iolog_flush +If set, +\fBsudo\fR +will flush I/O log data to disk after each write instead of buffering it. +This makes it possible to view the logs in real-time as the program +is executing but may significantly reduce the effectiveness of I/O +log compression. +This flag is +\fIoff\fR +by default. +.sp +This setting is only supported by version 1.8.20 or higher. +.TP 18n +iolog_group +The group name to look up when setting the group-ID on new I/O log +files and directories. +If +\fIiolog_group\fR +is not set, +the primary group-ID of the user specified by +\fIiolog_user\fR +is used. +If neither +\fIiolog_group\fR +nor +\fIiolog_user\fR +are set, I/O log files and directories are created with group-ID 0. +.sp +This setting is only supported by version 1.8.19 or higher. +.TP 18n +iolog_mode +The file mode to use when creating I/O log files. +Mode bits for read and write permissions for owner, group or other +are honored, everything else is ignored. +The file permissions will always include the owner read and +write bits, even if they are not present in the specified mode. +When creating I/O log directories, search (execute) bits are added +to match the read and write bits specified by +\fIiolog_mode\fR. +Defaults to 0600 (read and write by user only). +.sp +This setting is only supported by version 1.8.19 or higher. +.TP 18n +iolog_user +The user name to look up when setting the user and group-IDs on new +I/O log files and directories. +If +\fIiolog_group\fR +is set, it will be used instead of the user's primary group-ID. +By default, I/O log files and directories are created with user and +group-ID 0. +.sp +This setting can be useful when the I/O logs are stored on a Network +File System (NFS) share. +Having a dedicated user own the I/O log files means that +\fBsudoers\fR +does not write to the log files as user-ID 0, which is usually +not permitted by NFS. +.sp +This setting is only supported by version 1.8.19 or higher. +.TP 18n +lecture_status_dir +The directory in which +\fBsudo\fR +stores per-user lecture status files. +Once a user has received the lecture, a zero-length file is +created in this directory so that +\fBsudo\fR +will not lecture the user again. +This directory should +\fInot\fR +be cleared when the system reboots. +The default is +\fI@vardir@/lectured\fR. +.if \n(PS \{\ +.TP 18n +limitprivs +The default Solaris limit privileges to use when constructing a new +privilege set for a command. +This bounds all privileges of the executing process. +The default limit privileges may be overridden on a per-command basis in +\fIsudoers\fR. +This option is only available if +\fBsudoers\fR +is built on Solaris 10 or higher. +.\} +.TP 18n +log_server_cabundle +The path to a certificate authority bundle file, in PEM format, +to use instead of the system's default certificate authority database +when authenticating the log server. +The default is to use the system's default certificate authority database. +This setting has no effect unless +\fIlog_servers\fR +is set and the remote log server is secured with TLS. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +log_server_peer_cert +The path to the client's certificate file, in PEM format. +This setting is required when +\fIlog_servers\fR +is set and the remote log server is secured with TLS. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +log_server_peer_key +The path to the client's private key file, in PEM format. +This setting is required when +\fIlog_servers\fR +is set and the remote log server is secured with TLS. +.sp +This setting is only supported by version 1.9.0 or higher. +.TP 18n +mailsub +Subject of the mail sent to the +\fImailto\fR +user. +The escape +\fR%h\fR +will expand to the host name of the machine. +Default is +\(lq\fR@mailsub@\fR\(rq. +.TP 18n +noexec_file +As of +\fBsudo\fR +version 1.8.1 this option is no longer supported. +The path to the noexec file should now be set in the +sudo.conf(@mansectform@) +file. +.TP 18n +pam_login_service +.br +On systems that use PAM for authentication, this is the service +name used when the +\fB\-i\fR +option is specified. +The default value is +\(lq\fR@pam_login_service@\fR\(rq. +See the description of +\fIpam_service\fR +for more information. +.sp +This setting is only supported by version 1.8.8 or higher. +.TP 18n +pam_service +On systems that use PAM for authentication, the service name +specifies the PAM policy to apply. +This usually corresponds to an entry in the +\fIpam.conf\fR +file or a file in the +\fI/etc/pam.d\fR +directory. +The default value is +\(lq\fRsudo\fR\(rq. +.sp +This setting is only supported by version 1.8.8 or higher. +.TP 18n +passprompt +The default prompt to use when asking for a password; can be overridden via the +\fB\-p\fR +option or the +\fRSUDO_PROMPT\fR +environment variable. +The following percent +(\(oq%\(cq) +escape sequences are supported: +.PP +.RS 18n +.PD 0 +.TP 6n +\fR%H\fR +expanded to the local host name including the domain name +(only if the machine's host name is fully qualified or the +\fIfqdn\fR +option is set) +.PD +.TP 6n +\fR%h\fR +expanded to the local host name without the domain name +.TP 6n +\fR%p\fR +expanded to the user whose password is being asked for (respects the +\fIrootpw\fR, +\fItargetpw\fR +and +\fIrunaspw\fR +flags in +\fIsudoers\fR) +.TP 6n +\fR\&%U\fR +expanded to the login name of the user the command will +be run as (defaults to root) +.TP 6n +\fR%u\fR +expanded to the invoking user's login name +.TP 6n +\fR%%\fR +two consecutive +\fR%\fR +characters are collapsed into a single +\fR%\fR +character +.PP +On systems that use PAM for authentication, +\fIpassprompt\fR +will only be used if the prompt provided by the PAM module matches the string +\(lqPassword: \(rq +or +\(lqusername's Password: \(rq. +This ensures that the +\fIpassprompt\fR +setting does not interfere with challenge-response style authentication. +The +\fIpassprompt_override\fR +flag can be used to change this behavior. +.sp +The default value is +\(lq\fR@passprompt@\fR\(rq. +.RE +.if \n(PS \{\ +.TP 18n +privs +The default Solaris privileges to use when constructing a new +privilege set for a command. +This is passed to the executing process via the inherited privilege set, +but is bounded by the limit privileges. +If the +\fIprivs\fR +option is specified but the +\fIlimitprivs\fR +option is not, the limit privileges of the executing process is set to +\fIprivs\fR. +The default privileges may be overridden on a per-command basis in +\fIsudoers\fR. +This option is only available if +\fBsudoers\fR +is built on Solaris 10 or higher. +.\} +.if \n(SL \{\ +.TP 18n +role +The default SELinux role to use when constructing a new security +context to run the command. +The default role may be overridden on a per-command basis in the +\fIsudoers\fR +file or via command line options. +This option is only available when +\fBsudo\fR +is built with SELinux support. +.\} +.TP 18n +runas_default +The default user to run commands as if the +\fB\-u\fR +option is not specified on the command line. +This defaults to +\fR@runas_default@\fR. +.TP 18n +sudoers_locale +Locale to use when parsing the sudoers file, logging commands, and +sending email. +Note that changing the locale may affect how sudoers is interpreted. +Defaults to +\(lq\fRC\fR\(rq. +.TP 18n +timestamp_type +\fBsudoers\fR +uses per-user time stamp files for credential caching. +The +\fItimestamp_type\fR +option can be used to specify the type of time stamp record used. +It has the following possible values: +.PP +.RS 18n +.PD 0 +.TP 8n +global +A single time stamp record is used for all of a user's login sessions, +regardless of the terminal or parent process ID. +An additional record is used to serialize password prompts when +\fBsudo\fR +is used multiple times in a pipeline, but this does not affect authentication. +.PD +.TP 8n +ppid +A single time stamp record is used for all processes with the same parent +process ID (usually the shell). +Commands run from the same shell (or other common parent process) +will not require a password for +\fItimestamp_timeout\fR +minutes +(\fR@timeout@\fR +by default) +\&. +Commands run via +\fBsudo\fR +with a different parent process ID, for example from a shell script, +will be authenticated separately. +.TP 8n +tty +One time stamp record is used for each terminal, +which means that a user's login sessions are authenticated separately. +If no terminal is present, the behavior is the same as +\fIppid\fR. +Commands run from the same terminal will not require a password for +\fItimestamp_timeout\fR +minutes +(\fR@timeout@\fR +by default) +\&. +.TP 8n +kernel +The time stamp is stored in the kernel as an attribute of the terminal +device. +If no terminal is present, the behavior is the same as +\fIppid\fR. +Negative +\fItimestamp_timeout\fR +values are not supported and positive values are limited to a maximum +of 60 minutes. +This is currently only supported on +OpenBSD. +.PP +The default value is +\fI@timestamp_type@\fR. +.sp +This setting is only supported by version 1.8.21 or higher. +.RE +.TP 18n +timestampdir +The directory in which +\fBsudo\fR +stores its time stamp files. +This directory should be cleared when the system reboots. +The default is +\fI@rundir@/ts\fR. +.TP 18n +timestampowner +The owner of the lecture status directory, time stamp directory and all +files stored therein. +The default is +\fRroot\fR. +.if \n(SL \{\ +.TP 18n +type +The default SELinux type to use when constructing a new security +context to run the command. +The default type may be overridden on a per-command basis in the +\fIsudoers\fR +file or via command line options. +This option is only available when +\fBsudo\fR +is built with SELinux support. +.PP +\fBStrings that can be used in a boolean context\fR: +.TP 14n +env_file +The +\fIenv_file\fR +option specifies the fully qualified path to a file containing variables +to be set in the environment of the program being run. +Entries in this file should either be of the form +\(lq\fRVARIABLE=value\fR\(rq +or +\(lq\fRexport VARIABLE=value\fR\(rq. +The value may optionally be enclosed in single or double quotes. +Variables in this file are only added if the variable does not already +exist in the environment. +This file is considered to be part of the security policy, +its contents are not subject to other +\fBsudo\fR +environment restrictions such as +\fIenv_keep\fR +and +\fIenv_check\fR. +.TP 14n +exempt_group +Users in this group are exempt from password and PATH requirements. +The group name specified should not include a +\fR%\fR +prefix. +This is not set by default. +.TP 14n +fdexec +Determines whether +\fBsudo\fR +will execute a command by its path or by an open file descriptor. +It has the following possible values: +.PP +.RS 14n +.PD 0 +.TP 8n +always +Always execute by file descriptor. +.PD +.TP 8n +never +Never execute by file descriptor. +.TP 8n +digest_only +Only execute by file descriptor if the command has an associated digest +in the +\fIsudoers\fR +file. +.PP +The default value is +\fIdigest_only\fR. +This avoids a time of check versus time of use race condition when +the command is located in a directory writable by the invoking user. +.sp +Note that +\fIfdexec\fR +will change the first element of the argument vector for scripts +($0 in the shell) due to the way the kernel runs script interpreters. +Instead of being a normal path, it will refer to a file descriptor. +For example, +\fI/dev/fd/4\fR +on Solaris and +\fI/proc/self/fd/4\fR +on Linux. +A workaround is to use the +\fRSUDO_COMMAND\fR +environment variable instead. +.sp +The +\fIfdexec\fR +setting is only used when the command is matched by path name. +It has no effect if the command is matched by the built-in +\fBALL\fR +alias. +.sp +This setting is only supported by version 1.8.20 or higher. +If the operating system does not support the +fexecve(2) +system call, this setting has no effect. +.RE +.TP 14n +group_plugin +A string containing a +\fBsudoers\fR +group plugin with optional arguments. +The string should consist of the plugin +path, either fully-qualified or relative to the +\fI@plugindir@\fR +directory, followed by any configuration arguments the plugin requires. +These arguments (if any) will be passed to the plugin's initialization function. +If arguments are present, the string must be enclosed in double quotes +(\&""). +.sp +For more information see +\fIGROUP PROVIDER PLUGINS\fR. +.TP 14n +lecture +This option controls when a short lecture will be printed along with +the password prompt. +It has the following possible values: +.PP +.RS 14n +.PD 0 +.TP 8n +always +Always lecture the user. +.PD +.TP 8n +never +Never lecture the user. +.TP 8n +once +Only lecture the user the first time they run +\fBsudo\fR. +.PP +If no value is specified, a value of +\fIonce\fR +is implied. +Negating the option results in a value of +\fInever\fR +being used. +The default value is +\fI@lecture@\fR. +.RE +.TP 14n +lecture_file +Path to a file containing an alternate +\fBsudo\fR +lecture that will be used in place of the standard lecture if the named +file exists. +By default, +\fBsudo\fR +uses a built-in lecture. +.TP 14n +listpw +This option controls when a password will be required when a user runs +\fBsudo\fR +with the +\fB\-l\fR +option. +It has the following possible values: +.PP +.RS 14n +.PD 0 +.TP 10n +all +All the user's +\fIsudoers\fR +file entries for the current host must have +the +\fRNOPASSWD\fR +flag set to avoid entering a password. +.PD +.TP 10n +always +The user must always enter a password to use the +\fB\-l\fR +option. +.TP 10n +any +At least one of the user's +\fIsudoers\fR +file entries for the current host +must have the +\fRNOPASSWD\fR +flag set to avoid entering a password. +.TP 10n +never +The user need never enter a password to use the +\fB\-l\fR +option. +.PP +If no value is specified, a value of +\fIany\fR +is implied. +Negating the option results in a value of +\fInever\fR +being used. +The default value is +\fIany\fR. +.RE +.TP 14n +log_format +The event log format. +Supported log formats are: +.PP +.RS 14n +.PD 0 +.TP 10n +json +Logs in JSON format. +JSON log entries contain the full user details as well as the execution +environment if the command was allowed. +Due to limitations of the protocol, JSON events sent via +\fIsyslog\fR +may be truncated. +.PD +.TP 10n +sudo +Traditional sudo-style logs, see +\fILOG FORMAT\fR +for a description of the log file format. +.PP +This setting affects logs sent via +syslog(3) +as well as the file specified by the +\fIlogfile\fR +setting, if any. +The default value is +\fIsudo\fR. +.RE +.TP 14n +logfile +Path to the +\fBsudo\fR +log file (not the syslog log file). +Setting a path turns on logging to a file; +negating this option turns it off. +By default, +\fBsudo\fR +logs via syslog. +.TP 14n +mailerflags +Flags to use when invoking mailer. +Defaults to +\fB\-t\fR. +.TP 14n +mailerpath +Path to mail program used to send warning mail. +Defaults to the path to sendmail found at configure time. +.TP 14n +mailfrom +Address to use for the +\(lqfrom\(rq +address when sending warning and error mail. +The address should be enclosed in double quotes +(\&"") +to protect against +\fBsudo\fR +interpreting the +\fR@\fR +sign. +Defaults to the name of the user running +\fBsudo\fR. +.TP 14n +mailto +Address to send warning and error mail to. +The address should be enclosed in double quotes +(\&"") +to protect against +\fBsudo\fR +interpreting the +\fR@\fR +sign. +Defaults to +\fR@mailto@\fR. +.TP 14n +restricted_env_file +The +\fIrestricted_env_file\fR +option specifies the fully qualified path to a file containing variables +to be set in the environment of the program being run. +Entries in this file should either be of the form +\(lq\fRVARIABLE=value\fR\(rq +or +\(lq\fRexport VARIABLE=value\fR\(rq. +The value may optionally be enclosed in single or double quotes. +Variables in this file are only added if the variable does not already +exist in the environment. +Unlike +\fIenv_file\fR, +the file's contents are not trusted and are processed in a manner +similar to that of the invoking user's environment. +If +\fIenv_reset\fR +is enabled, variables in the file will only be added if they are +matched by either the +\fIenv_check\fR +or +\fIenv_keep\fR +list. +If +\fIenv_reset\fR +is disabled, variables in the file are added as long as they +are not matched by the +\fIenv_delete\fR +list. +In either case, the contents of +\fIrestricted_env_file\fR +are processed before the contents of +\fIenv_file\fR. +.TP 14n +runchroot +If set, +\fBsudo\fR +will use this value for the root directory when running a command. +The special value +\(lq*\(rq +will allow the user to specify the root directory via +\fBsudo\fR's +\fB\-R\fR +option. +See the +\fIChroot_Spec\fR +section for more details. +.sp +It is only possible to use +\fIrunchroot\fR +as a command-specific Defaults setting if the command exists with +the same path both inside and outside the chroot jail. +This restriction does not apply to generic, host or user-based +Defaults settings or to a +\fICmnd_Spec\fR +that includes a +\fIChroot_Spec\fR. +.sp +This setting is only supported by version 1.9.3 or higher. +.TP 14n +runcwd +If set, +\fBsudo\fR +will use this value for the working directory when running a command. +The special value +\(lq*\(rq +will allow the user to specify the working directory via +\fBsudo\fR's +\fB\-D\fR +option. +See the +\fIChdir_Spec\fR +section for more details. +.sp +This setting is only supported by version 1.9.3 or higher. +.TP 14n +secure_path +If set, +\fBsudo\fR +will use this value in place of the user's +\fRPATH\fR +environment variable. +This option can be used to reset the +\fRPATH\fR +to a known good value that contains directories for system administrator +commands such as +\fI/usr/sbin\fR. +.sp +Users in the group specified by the +\fIexempt_group\fR +option are not affected by +\fIsecure_path\fR. +This option is @secure_path@ by default. +.TP 14n +syslog +Syslog facility if syslog is being used for logging (negate to +disable syslog logging). +Defaults to +\fR@logfac@\fR. +.sp +The following syslog facilities are supported: +\fBauthpriv\fR +(if your +OS supports it), +\fBauth\fR, +\fBdaemon\fR, +\fBuser\fR, +\fBlocal0\fR, +\fBlocal1\fR, +\fBlocal2\fR, +\fBlocal3\fR, +\fBlocal4\fR, +\fBlocal5\fR, +\fBlocal6\fR, +and +\fBlocal7\fR. +.TP 14n +syslog_badpri +.br +Syslog priority to use when the user is not allowed to run a command or +when authentication is unsuccessful. +Defaults to +\fR@badpri@\fR. +.sp +The following syslog priorities are supported: +\fBalert\fR, +\fBcrit\fR, +\fBdebug\fR, +\fBemerg\fR, +\fBerr\fR, +\fBinfo\fR, +\fBnotice\fR, +\fBwarning\fR, +and +\fBnone\fR. +Negating the option or setting it to a value of +\fBnone\fR +will disable logging of unsuccessful commands. +.TP 14n +syslog_goodpri +Syslog priority to use when the user is allowed to run a command and +authentication is successful. +Defaults to +\fR@goodpri@\fR. +.sp +See +\fIsyslog_badpri\fR +for the list of supported syslog priorities. +Negating the option or setting it to a value of +\fBnone\fR +will disable logging of successful commands. +.TP 14n +verifypw +This option controls when a password will be required when a user runs +\fBsudo\fR +with the +\fB\-v\fR +option. +It has the following possible values: +.PP +.RS 14n +.PD 0 +.TP 8n +all +All the user's +\fIsudoers\fR +file entries for the current host must have the +\fRNOPASSWD\fR +flag set to avoid entering a password. +.PD +.TP 8n +always +The user must always enter a password to use the +\fB\-v\fR +option. +.TP 8n +any +At least one of the user's +\fIsudoers\fR +file entries for the current host must have the +\fRNOPASSWD\fR +flag set to avoid entering a password. +.TP 8n +never +The user need never enter a password to use the +\fB\-v\fR +option. +.PP +If no value is specified, a value of +\fIall\fR +is implied. +Negating the option results in a value of +\fInever\fR +being used. +The default value is +\fIall\fR. +.RE +.PP +\fBLists that can be used in a boolean context\fR: +.\} +.TP 18n +env_check +Environment variables to be removed from the user's environment +unless they are considered +\(lqsafe\(rq. +For all variables except +\fRTZ\fR, +\(lqsafe\(rq +means that the variable's value does not contain any +\(oq%\(cq +or +\(oq/\(cq +characters. +This can be used to guard against printf-style format vulnerabilities +in poorly-written programs. +The +\fRTZ\fR +variable is considered unsafe if any of the following are true: +.PP +.RS 18n +.PD 0 +.TP 3n +\fB\(bu\fR +It consists of a fully-qualified path name, +optionally prefixed with a colon +(\(oq:\&\(cq), +that does not match the location of the +\fIzoneinfo\fR +directory. +.PD +.TP 3n +\fB\(bu\fR +It contains a +\fI..\fR +path element. +.TP 3n +\fB\(bu\fR +It contains white space or non-printable characters. +.TP 3n +\fB\(bu\fR +It is longer than the value of +\fRPATH_MAX\fR. +.PP +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using +the +\fR=\fR, +\fR+=\fR, +\fR-=\fR, +and +\fR\&!\fR +operators respectively. +Regardless of whether the +\fRenv_reset\fR +option is enabled or disabled, variables specified by +\fRenv_check\fR +will be preserved in the environment if they pass the aforementioned check. +The global list of environment variables to check is displayed when +\fBsudo\fR +is run by root with +the +\fB\-V\fR +option. +.RE +.TP 18n +env_delete +Environment variables to be removed from the user's environment when the +\fIenv_reset\fR +option is not in effect. +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using the +\fR=\fR, +\fR+=\fR, +\fR-=\fR, +and +\fR\&!\fR +operators respectively. +The global list of environment variables to remove is displayed when +\fBsudo\fR +is run by root with the +\fB\-V\fR +option. +Note that many operating systems will remove potentially dangerous +variables from the environment of any set-user-ID process (such as +\fBsudo\fR). +.TP 18n +env_keep +Environment variables to be preserved in the user's environment when the +\fIenv_reset\fR +option is in effect. +This allows fine-grained control over the environment +\fBsudo\fR-spawned +processes will receive. +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using the +\fR=\fR, +\fR+=\fR, +\fR-=\fR, +and +\fR\&!\fR +operators respectively. +The global list of variables to keep +is displayed when +\fBsudo\fR +is run by root with the +\fB\-V\fR +option. +.sp +Preserving the +\fRHOME\fR +environment variable has security implications since many programs use it +when searching for configuration or data files. +Adding +\fRHOME\fR +to +\fIenv_keep\fR +may enable a user to run unrestricted commands via +\fBsudo\fR +and is strongly discouraged. +Users wishing to edit files with +\fBsudo\fR +should run +\fBsudoedit\fR +(or +\fBsudo\fR \fB\-e\fR) +to get their accustomed editor configuration instead of +invoking the editor directly. +.TP 18n +log_servers +A list of one or more servers to use for remote event and I/O log storage, +separated by white space. +Log servers must be running +\fBsudo_logsrvd\fR +or another service that implements the protocol described by +sudo_logsrv.proto(@mansectform@). +.sp +Server addresses should be of the form +\(lqhost[:port][(tls)]\(rq. +The host portion may be a host name, an IPv4 address, or an IPv6 address +in square brackets. +.sp +If the optional +\fItls\fR +flag is present, the connection will be secured +with Transport Layer Security (TLS) version 1.2 or 1.3. +Versions of TLS prior to 1.2 are not supported. +.sp +If a port is specified, it may either be a port number or a well-known +service name as defined by the system service name database. +If no port is specified, port 30343 will be used for plaintext +connections and port 30344 will be used for TLS connections. +.sp +When +\fIlog_servers\fR +is set, event log data will be logged both locally (see the +\fIsyslog\fR +and +\fIlog_file\fR +settings) as well as remotely, but I/O log data will only be logged remotely. +If multiple hosts are specified, they will be attempted in reverse order. +If no log servers are available, the user will not be able to run +a command unless either the +\fIignore_iolog_errors\fR +flag (I/O logging enabled) or the +\fIignore_log_errors\fR +flag (I/O logging disabled) is set. +Likewise, if the connection to the log server is interrupted while +\fBsudo\fR +is running, the command will be terminated unless the +\fIignore_iolog_errors\fR +flag (I/O logging enabled) or the +\fIignore_log_errors\fR +flag (I/O logging disabled) is set. +.sp +This setting is only supported by version 1.9.0 or higher. +.SH "GROUP PROVIDER PLUGINS" +The +\fBsudoers\fR +plugin supports its own plugin interface to allow non-Unix +group lookups which can query a group source other +than the standard Unix group database. +This can be used to implement support for the +\fRnonunix_group\fR +syntax described earlier. +.PP +Group provider plugins are specified via the +\fIgroup_plugin\fR +setting. +The argument to +\fIgroup_plugin\fR +should consist of the plugin path, either fully-qualified or relative to the +\fI@plugindir@\fR +directory, followed by any configuration options the plugin requires. +These options (if specified) will be passed to the plugin's initialization +function. +If options are present, the string must be enclosed in double quotes +(\&""). +.PP +The following group provider plugins are installed by default: +.TP 10n +group_file +The +\fIgroup_file\fR +plugin supports an alternate group file that uses the same syntax as the +\fI/etc/group\fR +file. +The path to the group file should be specified as an option +to the plugin. +For example, if the group file to be used is +\fI/etc/sudo-group\fR: +.nf +.sp +.RS 10n +Defaults group_plugin="group_file.so /etc/sudo-group" +.RE +.fi +.TP 10n +system_group +The +\fIsystem_group\fR +plugin supports group lookups via the standard C library functions +\fBgetgrnam\fR() +and +\fBgetgrid\fR(). +This plugin can be used in instances where the user belongs to +groups not present in the user's supplemental group vector. +This plugin takes no options: +.nf +.sp +.RS 10n +Defaults group_plugin=system_group.so +.RE +.fi +.PP +The group provider plugin API is described in detail in +sudo_plugin(@mansectform@). +.SH "LOG FORMAT" +\fBsudoers\fR +can log events in either JSON or +\fIsudo\fR +format, +this section describes the +\fIsudo\fR +log format. +Depending on +\fIsudoers\fR +configuration, +\fBsudoers\fR +can log events via +syslog(3), +to a local log file, or both. +The log format is almost identical in both cases. +.SS "Accepted command log entries" +Commands that sudo runs are logged using the following format (split +into multiple lines for readability): +.nf +.sp +.RS 4n +date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e + USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e + ENV=env_vars COMMAND=command +.RE +.fi +.PP +Where the fields are as follows: +.TP 14n +date +The date the command was run. +Typically, this is in the format +\(lqMMM, DD, HH:MM:SS\(rq. +If logging via +syslog(3), +the actual date format is controlled by the syslog daemon. +If logging to a file and the +\fIlog_year\fR +option is enabled, +the date will also include the year. +.TP 14n +hostname +The name of the host +\fBsudo\fR +was run on. +This field is only present when logging via +syslog(3). +.TP 14n +progname +The name of the program, usually +\fIsudo\fR +or +\fIsudoedit\fR. +This field is only present when logging via +syslog(3). +.TP 14n +username +The login name of the user who ran +\fBsudo\fR. +.TP 14n +ttyname +The short name of the terminal (e.g., +\(lqconsole\(rq, +\(lqtty01\(rq, +or +\(lqpts/0\(rq) +\fBsudo\fR +was run on, or +\(lqunknown\(rq +if there was no terminal present. +.TP 14n +cwd +The current working directory that +\fBsudo\fR +was run in. +.TP 14n +runasuser +The user the command was run as. +.TP 14n +runasgroup +The group the command was run as if one was specified on the command line. +.TP 14n +logid +An I/O log identifier that can be used to replay the command's output. +This is only present when the +\fIlog_input\fR +or +\fIlog_output\fR +option is enabled. +.TP 14n +env_vars +A list of environment variables specified on the command line, +if specified. +.TP 14n +command +The actual command that was executed. +.PP +Messages are logged using the locale specified by +\fIsudoers_locale\fR, +which defaults to the +\(lq\fRC\fR\(rq +locale. +.SS "Denied command log entries" +If the user is not allowed to run the command, the reason for the denial +will follow the user name. +Possible reasons include: +.TP 3n +user NOT in sudoers +The user is not listed in the +\fIsudoers\fR +file. +.TP 3n +user NOT authorized on host +The user is listed in the +\fIsudoers\fR +file but is not allowed to run commands on the host. +.TP 3n +command not allowed +The user is listed in the +\fIsudoers\fR +file for the host but they are not allowed to run the specified command. +.TP 3n +3 incorrect password attempts +The user failed to enter their password after 3 tries. +The actual number of tries will vary based on the number of +failed attempts and the value of the +\fIpasswd_tries\fR +option. +.TP 3n +a password is required +The +\fB\-n\fR +option was specified but a password was required. +.TP 3n +sorry, you are not allowed to set the following environment variables +The user specified environment variables on the command line that +were not allowed by +\fIsudoers\fR. +.SS "Error log entries" +If an error occurs, +\fBsudoers\fR +will log a message and, in most cases, send a message to the +administrator via email. +Possible errors include: +.TP 3n +parse error in @sysconfdir@/sudoers near line N +\fBsudoers\fR +encountered an error when parsing the specified file. +In some cases, the actual error may be one line above or below the +line number listed, depending on the type of error. +.TP 3n +problem with defaults entries +The +\fIsudoers\fR +file contains one or more unknown Defaults settings. +This does not prevent +\fBsudo\fR +from running, but the +\fIsudoers\fR +file should be checked using +\fBvisudo\fR. +.TP 3n +timestamp owner (username): \&No such user +The time stamp directory owner, as specified by the +\fItimestampowner\fR +setting, could not be found in the password database. +.TP 3n +unable to open/read @sysconfdir@/sudoers +The +\fIsudoers\fR +file could not be opened for reading. +This can happen when the +\fIsudoers\fR +file is located on a remote file system that maps user-ID 0 to +a different value. +Normally, +\fBsudoers\fR +tries to open the +\fIsudoers\fR +file using group permissions to avoid this problem. +Consider either changing the ownership of +\fI@sysconfdir@/sudoers\fR +or adding an argument like +\(lqsudoers_uid=N\(rq +(where +\(oqN\(cq +is the user-ID that owns the +\fIsudoers\fR +file) to the end of the +\fBsudoers\fR +\fRPlugin\fR +line in the +sudo.conf(@mansectform@) +file. +.TP 3n +unable to stat @sysconfdir@/sudoers +The +\fI@sysconfdir@/sudoers\fR +file is missing. +.TP 3n +@sysconfdir@/sudoers is not a regular file +The +\fI@sysconfdir@/sudoers\fR +file exists but is not a regular file or symbolic link. +.TP 3n +@sysconfdir@/sudoers is owned by uid N, should be 0 +The +\fIsudoers\fR +file has the wrong owner. +If you wish to change the +\fIsudoers\fR +file owner, please add +\(lqsudoers_uid=N\(rq +(where +\(oqN\(cq +is the user-ID that owns the +\fIsudoers\fR +file) to the +\fBsudoers\fR +\fRPlugin\fR +line in the +sudo.conf(@mansectform@) +file. +.TP 3n +@sysconfdir@/sudoers is world writable +The permissions on the +\fIsudoers\fR +file allow all users to write to it. +The +\fIsudoers\fR +file must not be world-writable, the default file mode +is 0440 (readable by owner and group, writable by none). +The default mode may be changed via the +\(lqsudoers_mode\(rq +option to the +\fBsudoers\fR +\fRPlugin\fR +line in the +sudo.conf(@mansectform@) +file. +.TP 3n +@sysconfdir@/sudoers is owned by gid N, should be 1 +The +\fIsudoers\fR +file has the wrong group ownership. +If you wish to change the +\fIsudoers\fR +file group ownership, please add +\(lqsudoers_gid=N\(rq +(where +\(oqN\(cq +is the group-ID that owns the +\fIsudoers\fR +file) to the +\fBsudoers\fR +\fRPlugin\fR +line in the +sudo.conf(@mansectform@) +file. +.TP 3n +unable to open @rundir@/ts/username +\fBsudoers\fR +was unable to read or create the user's time stamp file. +This can happen when +\fItimestampowner\fR +is set to a user other than root and the mode on +\fI@rundir@\fR +is not searchable by group or other. +The default mode for +\fI@rundir@\fR +is 0711. +.TP 3n +unable to write to @rundir@/ts/username +\fBsudoers\fR +was unable to write to the user's time stamp file. +.TP 3n +@rundir@/ts is owned by uid X, should be Y +The time stamp directory is owned by a user other than +\fItimestampowner\fR. +This can occur when the value of +\fItimestampowner\fR +has been changed. +\fBsudoers\fR +will ignore the time stamp directory until the owner is corrected. +.TP 3n +@rundir@/ts is group writable +The time stamp directory is group-writable; it should be writable only by +\fItimestampowner\fR. +The default mode for the time stamp directory is 0700. +\fBsudoers\fR +will ignore the time stamp directory until the mode is corrected. +.SS "Notes on logging via syslog" +By default, +\fBsudoers\fR +logs messages via +syslog(3). +The +\fIdate\fR, +\fIhostname\fR, +and +\fIprogname\fR +fields are added by the system's +\fBsyslog\fR() +function, not +\fBsudoers\fR +itself. +As such, they may vary in format on different systems. +.PP +The maximum size of syslog messages varies from system to system. +The +\fIsyslog_maxlen\fR +setting can be used to change the maximum syslog message size +from the default value of 980 bytes. +For more information, see the description of +\fIsyslog_maxlen\fR. +.SS "Notes on logging to a file" +If the +\fIlogfile\fR +option is set, +\fBsudoers\fR +will log to a local file, such as +\fI/var/log/sudo\fR. +When logging to a file, +\fBsudoers\fR +uses a format similar to +syslog(3), +with a few important differences: +.TP 5n +1.\& +The +\fIprogname\fR +and +\fIhostname\fR +fields are not present. +.TP 5n +2.\& +If the +\fIlog_year\fR +option is enabled, +the date will also include the year. +.TP 5n +3.\& +Lines that are longer than +\fIloglinelen\fR +characters (80 by default) are word-wrapped and continued on the +next line with a four character indent. +This makes entries easier to read for a human being, but makes it +more difficult to use +grep(1) +on the log files. +If the +\fIloglinelen\fR +option is set to 0 (or negated with a +\(oq\&!\(cq), +word wrap will be disabled. +.SH "I/O LOG FILES" +When I/O logging is enabled, +\fBsudo\fR +will run the command in a pseudo-terminal and log all user input and/or output, +depending on which options are enabled. +I/O can be logged either to the local machine or to a remote log server. +For local logs, I/O is logged to the directory specified by the +\fIiolog_dir\fR +option +(\fI@iolog_dir@\fR +by default) +using a unique session ID that is included in the +\fBsudo\fR +log line, prefixed with +\(lq\fRTSID=\fR\(rq. +The +\fIiolog_file\fR +option may be used to control the format of the session ID. +For remote logs, the +\fIlog_servers\fR +setting is used to specify one or more log servers running +\fBsudo_logsrvd\fR +or another server that implements the protocol described by +sudo_logsrv.proto(@mansectform@). +.PP +For both local and remote I/O logs, each log is stored in a separate +directory that contains the following files: +.TP 10n +\fIlog\fR +A text file containing information about the command. +The first line consists of the following colon-delimited fields: +the time the command was run, the name of the user +who ran +\fBsudo\fR, +the name of the target user, the name of the target group (optional), +the terminal that +\fBsudo\fR +was run from, and the number of lines and columns of the terminal. +The second and third lines contain the working directory the command +was run from and the path name of the command itself (with arguments +if present). +.TP 10n +\fIlog.json\fR +A JSON-formatted file containing information about the command. +This is similar to the +\fIlog\fR +file but contains additional information and is easily extensible. +The +\fIlog.json\fR +file will be used by +sudoreplay(@mansectsu@) +in preference to the +\fIlog\fR +file if it exists. +The file may contain the following elements: +.PP +.RS 10n +.PD 0 +.TP 10n +timestamp +.br +A JSON object containing time the command was run. +It consists of two values, +\fIseconds\fR +and +\fInanoseconds\fR. +.PD +.TP 10n +columns +The number of columns of the terminal the command ran on, or zero +if no terminal was present. +.TP 10n +command +The fully-qualified path of the command that was run. +.TP 10n +lines +The number of lines of the terminal the command ran on, or zero +if no terminal was present. +.TP 10n +runargv +A JSON array representing the command's argument vector as passed to the +execve(2) +system call. +.TP 10n +runenv +A JSON array representing the command's environment as passed to the +execve(2) +system call. +.TP 10n +rungid +The group ID the command ran as. +This element is only present when the user specifies a group on the +command line. +.TP 10n +rungroup +The name of the group the command ran as. +This element is only present when the user specifies a group on the +command line. +.TP 10n +runuid +The user ID the command ran as. +.TP 10n +runuser +The name of the user the command ran as. +.TP 10n +submitcwd +.br +The current working directory at the time +\fBsudo\fR +was run. +.TP 10n +submithost +The name of the host the command was run on. +.TP 10n +submituser +The name of the user who ran the command via +\fBsudo\fR. +.TP 10n +ttyname +The path name of the terminal the user invoked +\fBsudo\fR +from. +If the command was run in a pseudo-terminal, +\fIttyname\fR +will be different from the terminal the command actually ran in. +.PD 0 +.PP +.RE +.PD +.TP 10n +\fItiming\fR +Timing information used to replay the session. +Each line consists of the I/O log entry type and amount of time +since the last entry, followed by type-specific data. +The I/O log entry types and their corresponding type-specific data are: +.PP +.RS 10n +.PD 0 +.TP 6n +0 +standard input, number of bytes in the entry +.TP 6n +1 +standard output, number of bytes in the entry +.TP 6n +2 +standard error, number of bytes in the entry +.TP 6n +3 +terminal input, number of bytes in the entry +.TP 6n +4 +terminal output, number of bytes in the entry +.TP 6n +5 +window change, new number lines and columns +.TP 6n +6 +bug compatibility for +\fBsudo\fR +1.8.7 terminal output +.TP 6n +7 +command suspend or resume, signal received +.PP +.RE +.PD +.TP 10n +\fIttyin\fR +Raw input from the user's terminal, exactly as it was received. +No post-processing is performed. +For manual viewing, you may wish to convert carriage return characters +in the log to line feeds. +For example: +\(oqgunzip -c ttyin | tr \&"\er\&" \&"\en\&"\(cq +.TP 10n +\fIstdin\fR +The standard input when no terminal is present, or input redirected from +a pipe or file. +.TP 10n +\fIttyout\fR +Output from the pseudo-terminal (what the command writes to the screen). +Note that terminal-specific post-processing is performed before the +data is logged. +This means that, for example, line feeds are usually converted to +line feed/carriage return pairs and tabs may be expanded to spaces. +.TP 10n +\fIstdout\fR +The standard output when no terminal is present, or output redirected to +a pipe or file. +.TP 10n +\fIstderr\fR +The standard error redirected to a pipe or file. +.PP +All files other than +\fIlog\fR +are compressed in gzip format unless the +\fIcompress_io\fR +flag has been disabled. +Due to buffering, it is not normally possible to display the I/O logs in +real-time as the program is executing. +The I/O log data will not be complete until the program run by +\fBsudo\fR +has exited or has been terminated by a signal. +The +\fIiolog_flush\fR +flag can be used to disable buffering, in which case I/O log data +is written to disk as soon as it is available. +The output portion of an I/O log file can be viewed with the +sudoreplay(@mansectsu@) +utility, which can also be used to list or search the available logs. +.PP +Note that user input may contain sensitive information such as +passwords (even if they are not echoed to the screen), which will +be stored in the log file unencrypted. +In most cases, logging the command output via +\fIlog_output\fR +or +\fRLOG_OUTPUT\fR +is all that is required. +.PP +Since each session's I/O logs are stored in a separate directory, +traditional log rotation utilities cannot be used to limit the +number of I/O logs. +The simplest way to limit the number of I/O is by setting the +\fImaxseq\fR +option to the maximum number of logs you wish to store. +Once the I/O log sequence number reaches +\fImaxseq\fR, +it will be reset to zero and +\fBsudoers\fR +will truncate and re-use any existing I/O logs. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +Sudo front end configuration +.TP 26n +\fI@sysconfdir@/sudoers\fR +List of who can run what +.TP 26n +\fI/etc/group\fR +Local groups file +.TP 26n +\fI/etc/netgroup\fR +List of network groups +.TP 26n +\fI@iolog_dir@\fR +I/O log files +.TP 26n +\fI@rundir@/ts\fR +Directory containing time stamps for the +\fBsudoers\fR +security policy +.TP 26n +\fI@vardir@/lectured\fR +Directory containing lecture status files for the +\fBsudoers\fR +security policy +.TP 26n +\fI/etc/environment\fR +Initial environment for +\fB\-i\fR +mode on AIX and Linux systems +.SH "EXAMPLES" +Below are example +\fIsudoers\fR +file entries. +Admittedly, some of these are a bit contrived. +First, we allow a few environment variables to pass and then define our +\fIaliases\fR: +.nf +.sp +.RS 0n +# Run X applications through sudo; HOME is used to find the +# .Xauthority file. Note that other programs use HOME to find +# configuration files and this may lead to privilege escalation! +Defaults env_keep += "DISPLAY HOME" + +# User alias specification +User_Alias FULLTIMERS = millert, mikef, dowdy +User_Alias PARTTIMERS = bostley, jwfox, crawl +User_Alias WEBADMIN = will, wendy, wim + +# Runas alias specification +Runas_Alias OP = root, operator +Runas_Alias DB = oracle, sybase +Runas_Alias ADMINGRP = adm, oper + +# Host alias specification +Host_Alias SPARC = bigtime, eclipse, moet, anchor :\e + SGI = grolsch, dandelion, black :\e + ALPHA = widget, thalamus, foobar :\e + HPPA = boa, nag, python +Host_Alias CUNETS = 128.138.0.0/255.255.0.0 +Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0 +Host_Alias SERVERS = primary, mail, www, ns +Host_Alias CDROM = orion, perseus, hercules + +# Cmnd alias specification +Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e + /usr/sbin/restore, /usr/sbin/rrestore,\e + sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e + /home/operator/bin/start_backups +Cmnd_Alias KILL = /usr/bin/kill +Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm +Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown +Cmnd_Alias HALT = /usr/sbin/halt +Cmnd_Alias REBOOT = /usr/sbin/reboot +Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\e + /usr/local/bin/tcsh, /usr/bin/rsh,\e + /usr/local/bin/zsh +Cmnd_Alias SU = /usr/bin/su +Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less +.RE +.fi +.PP +Here we override some of the compiled in default values. +We want +\fBsudo\fR +to log via +syslog(3) +using the +\fIauth\fR +facility in all cases and for commands to be run with +the target user's home directory as the working directory. +We don't want to subject the full time staff to the +\fBsudo\fR +lecture and we want to allow them to run commands in a +chroot(2) +\(lqsandbox\(rq +via the +\fB\-R\fR +option. +User +\fBmillert\fR +need not provide a password and we don't want to reset the +\fRLOGNAME\fR +or +\fRUSER\fR +environment variables when running commands as root. +Additionally, on the machines in the +\fISERVERS\fR +\fRHost_Alias\fR, +we keep an additional local log file and make sure we log the year +in each log line since the log entries will be kept around for several years. +Lastly, we disable shell escapes for the commands in the PAGERS +\fRCmnd_Alias\fR +(\fI/usr/bin/more\fR, +\fI/usr/bin/pg\fR +and +\fI/usr/bin/less\fR) +\&. +Note that this will not effectively constrain users with +\fBsudo\fR +\fBALL\fR +privileges. +.nf +.sp +.RS 0n +# Override built-in defaults +Defaults syslog=auth,runcwd=~ +Defaults>root !set_logname +Defaults:FULLTIMERS !lecture,runchroot=* +Defaults:millert !authenticate +Defaults@SERVERS log_year, logfile=/var/log/sudo.log +Defaults!PAGERS noexec +.RE +.fi +.PP +The +\fIUser specification\fR +is the part that actually determines who may run what. +.nf +.sp +.RS 0n +root ALL = (ALL) ALL +%wheel ALL = (ALL) ALL +.RE +.fi +.PP +We let +\fBroot\fR +and any user in group +\fBwheel\fR +run any command on any host as any user. +.nf +.sp +.RS 0n +FULLTIMERS ALL = NOPASSWD: ALL +.RE +.fi +.PP +Full time sysadmins +(\fBmillert\fR, +\fBmikef\fR, +and +\fBdowdy\fR) +may run any command on any host without authenticating themselves. +.nf +.sp +.RS 0n +PARTTIMERS ALL = ALL +.RE +.fi +.PP +Part time sysadmins +\fBbostley\fR, +\fBjwfox\fR, +and +\fBcrawl\fR) +may run any command on any host but they must authenticate themselves +first (since the entry lacks the +\fRNOPASSWD\fR +tag). +.nf +.sp +.RS 0n +jack CSNETS = ALL +.RE +.fi +.PP +The user +\fBjack\fR +may run any command on the machines in the +\fICSNETS\fR +alias (the networks +\fR128.138.243.0\fR, +\fR128.138.204.0\fR, +and +\fR128.138.242.0\fR). +Of those networks, only +\fR128.138.204.0\fR +has an explicit netmask (in CIDR notation) indicating it is a class C network. +For the other networks in +\fICSNETS\fR, +the local machine's netmask will be used during matching. +.nf +.sp +.RS 0n +lisa CUNETS = ALL +.RE +.fi +.PP +The user +\fBlisa\fR +may run any command on any host in the +\fICUNETS\fR +alias (the class B network +\fR128.138.0.0\fR). +.nf +.sp +.RS 0n +operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\e + sudoedit /etc/printcap, /usr/oper/bin/ +.RE +.fi +.PP +The +\fBoperator\fR +user may run commands limited to simple maintenance. +Here, those are commands related to backups, killing processes, the +printing system, shutting down the system, and any commands in the +directory +\fI/usr/oper/bin/\fR. +Note that one command in the +\fRDUMPS\fR +Cmnd_Alias includes a sha224 digest, +\fI/home/operator/bin/start_backups\fR. +This is because the directory containing the script is writable by the +operator user. +If the script is modified (resulting in a digest mismatch) it will no longer +be possible to run it via +\fBsudo\fR. +.nf +.sp +.RS 0n +joe ALL = /usr/bin/su operator +.RE +.fi +.PP +The user +\fBjoe\fR +may only +su(1) +to operator. +.nf +.sp +.RS 0n +pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root* + +%opers ALL = (: ADMINGRP) /usr/sbin/ +.RE +.fi +.PP +Users in the +\fBopers\fR +group may run commands in +\fI/usr/sbin/\fR +as themselves +with any group in the +\fIADMINGRP\fR +\fRRunas_Alias\fR +(the +\fBadm\fR +and +\fBoper\fR +groups). +.PP +The user +\fBpete\fR +is allowed to change anyone's password except for +root on the +\fIHPPA\fR +machines. +Because command line arguments are matched as a single, +concatenated string, the +\(oq*\(cq +wildcard will match +\fImultiple\fR +words. +This example assumes that +passwd(1) +does not take multiple user names on the command line. +Note that on GNU systems, options to +passwd(1) +may be specified after the user argument. +As a result, this rule will also allow: +.nf +.sp +.RS 4n +passwd username --expire +.RE +.fi +.PP +which may not be desirable. +.nf +.sp +.RS 0n +bob SPARC = (OP) ALL : SGI = (OP) ALL +.RE +.fi +.PP +The user +\fBbob\fR +may run anything on the +\fISPARC\fR +and +\fISGI\fR +machines as any user listed in the +\fIOP\fR +\fRRunas_Alias\fR +(\fBroot\fR +and +\fBoperator\fR.) +.nf +.sp +.RS 0n +jim +biglab = ALL +.RE +.fi +.PP +The user +\fBjim\fR +may run any command on machines in the +\fIbiglab\fR +netgroup. +\fBsudo\fR +knows that +\(lqbiglab\(rq +is a netgroup due to the +\(oq+\(cq +prefix. +.nf +.sp +.RS 0n ++secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser +.RE +.fi +.PP +Users in the +\fBsecretaries\fR +netgroup need to help manage the printers as well as add and remove users, +so they are allowed to run those commands on all machines. +.nf +.sp +.RS 0n +fred ALL = (DB) NOPASSWD: ALL +.RE +.fi +.PP +The user +\fBfred\fR +can run commands as any user in the +\fIDB\fR +\fRRunas_Alias\fR +(\fBoracle\fR +or +\fBsybase\fR) +without giving a password. +.nf +.sp +.RS 0n +john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root* +.RE +.fi +.PP +On the +\fIALPHA\fR +machines, user +\fBjohn\fR +may su to anyone except root but he is not allowed to specify any options +to the +su(1) +command. +.nf +.sp +.RS 0n +jen ALL, !SERVERS = ALL +.RE +.fi +.PP +The user +\fBjen\fR +may run any command on any machine except for those in the +\fISERVERS\fR +\fRHost_Alias\fR +(primary, mail, www and ns). +.nf +.sp +.RS 0n +jill SERVERS = /usr/bin/, !SU, !SHELLS +.RE +.fi +.PP +For any machine in the +\fISERVERS\fR +\fRHost_Alias\fR, +\fBjill\fR +may run +any commands in the directory +\fI/usr/bin/\fR +except for those commands +belonging to the +\fISU\fR +and +\fISHELLS\fR +\fRCmnd_Aliases\fR. +While not specifically mentioned in the rule, the commands in the +\fIPAGERS\fR +\fRCmnd_Alias\fR +all reside in +\fI/usr/bin\fR +and have the +\fInoexec\fR +option set. +.nf +.sp +.RS 0n +steve CSNETS = (operator) /usr/local/op_commands/ +.RE +.fi +.PP +The user +\fBsteve\fR +may run any command in the directory /usr/local/op_commands/ +but only as user operator. +.nf +.sp +.RS 0n +matt valkyrie = KILL +.RE +.fi +.PP +On his personal workstation, valkyrie, +\fBmatt\fR +needs to be able to kill hung processes. +.nf +.sp +.RS 0n +WEBADMIN www = (www) ALL, (root) /usr/bin/su www +.RE +.fi +.PP +On the host www, any user in the +\fIWEBADMIN\fR +\fRUser_Alias\fR +(will, wendy, and wim), may run any command as user www (which owns the +web pages) or simply +su(1) +to www. +.nf +.sp +.RS 0n +ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\e + /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM +.RE +.fi +.PP +Any user may mount or unmount a CD-ROM on the machines in the CDROM +\fRHost_Alias\fR +(orion, perseus, hercules) without entering a password. +This is a bit tedious for users to type, so it is a prime candidate +for encapsulating in a shell script. +.SH "SECURITY NOTES" +.SS "Limitations of the \(oq!\&\(cq operator" +It is generally not effective to +\(lqsubtract\(rq +commands from +\fBALL\fR +using the +\(oq!\&\(cq +operator. +A user can trivially circumvent this by copying the desired command +to a different name and then executing that. +For example: +.nf +.sp +.RS 0n +bill ALL = ALL, !SU, !SHELLS +.RE +.fi +.PP +Doesn't really prevent +\fBbill\fR +from running the commands listed in +\fISU\fR +or +\fISHELLS\fR +since he can simply copy those commands to a different name, or use +a shell escape from an editor or other program. +Therefore, these kind of restrictions should be considered +advisory at best (and reinforced by policy). +.PP +In general, if a user has sudo +\fBALL\fR +there is nothing to prevent them from creating their own program that gives +them a root shell (or making their own copy of a shell) regardless of any +\(oq!\&\(cq +elements in the user specification. +.SS "Security implications of \fIfast_glob\fR" +If the +\fIfast_glob\fR +option is in use, it is not possible to reliably negate commands where the +path name includes globbing (aka wildcard) characters. +This is because the C library's +fnmatch(3) +function cannot resolve relative paths. +While this is typically only an inconvenience for rules that grant privileges, +it can result in a security issue for rules that subtract or revoke privileges. +.PP +For example, given the following +\fIsudoers\fR +file entry: +.nf +.sp +.RS 0n +john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\e + /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root +.RE +.fi +.PP +User +\fBjohn\fR +can still run +\fR/usr/bin/passwd root\fR +if +\fIfast_glob\fR +is enabled by changing to +\fI/usr/bin\fR +and running +\fR./passwd root\fR +instead. +.SS "Preventing shell escapes" +Once +\fBsudo\fR +executes a program, that program is free to do whatever +it pleases, including run other programs. +This can be a security issue since it is not uncommon for a program to +allow shell escapes, which lets a user bypass +\fBsudo\fR's +access control and logging. +Common programs that permit shell escapes include shells (obviously), +editors, paginators, mail and terminal programs. +.PP +There are two basic approaches to this problem: +.TP 10n +restrict +Avoid giving users access to commands that allow the user to run +arbitrary commands. +Many editors have a restricted mode where shell +escapes are disabled, though +\fBsudoedit\fR +is a better solution to +running editors via +\fBsudo\fR. +Due to the large number of programs that +offer shell escapes, restricting users to the set of programs that +do not is often unworkable. +.TP 10n +noexec +Many systems that support shared libraries have the ability to +override default library functions by pointing an environment +variable (usually +\fRLD_PRELOAD\fR) +to an alternate shared library. +On such systems, +\fBsudo\fR's +\fInoexec\fR +functionality can be used to prevent a program run by +\fBsudo\fR +from executing any other programs. +Note, however, that this applies only to dynamically-linked +executables. +Statically-linked executables and executables +running under binary emulation are not affected. +.sp +The +\fInoexec\fR +feature is known to work on SunOS, Solaris, *BSD, +Linux, IRIX, Tru64 UNIX, macOS, HP-UX 11.x and AIX 5.3 and above. +It should be supported on most operating systems that support the +\fRLD_PRELOAD\fR +environment variable. +Check your operating system's manual pages for the dynamic linker +(usually ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if +\fRLD_PRELOAD\fR +is supported. +.sp +On Solaris 10 and higher, +\fInoexec\fR +uses Solaris privileges instead of the +\fRLD_PRELOAD\fR +environment variable. +.sp +To enable +\fInoexec\fR +for a command, use the +\fRNOEXEC\fR +tag as documented +in the User Specification section above. +Here is that example again: +.nf +.sp +.RS 10n +aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi +.RE +.fi +.RS 10n +.sp +This allows user +\fBaaron\fR +to run +\fI/usr/bin/more\fR +and +\fI/usr/bin/vi\fR +with +\fInoexec\fR +enabled. +This will prevent those two commands from +executing other commands (such as a shell). +If you are unsure whether or not your system is capable of supporting +\fInoexec\fR +you can always just try it out and check whether shell escapes work when +\fInoexec\fR +is enabled. +.RE +.PP +Note that restricting shell escapes is not a panacea. +Programs running as root are still capable of many potentially hazardous +operations (such as changing or overwriting files) that could lead +to unintended privilege escalation. +In the specific case of an editor, a safer approach is to give the +user permission to run +\fBsudoedit\fR +(see below). +.SS "Secure editing" +The +\fBsudoers\fR +plugin includes +\fBsudoedit\fR +support which allows users to securely edit files with the editor +of their choice. +As +\fBsudoedit\fR +is a built-in command, it must be specified in the +\fIsudoers\fR +file without a leading path. +However, it may take command line arguments just as a normal command does. +Wildcards used in +\fIsudoedit\fR +command line arguments are expected to be path names, so a forward slash +(\(oq/\(cq) +will not be matched by a wildcard. +.PP +Unlike other +\fBsudo\fR +commands, the editor is run with the permissions of the invoking +user and with the environment unmodified. +More information may be found in the description of the +\fB\-e\fR +option in +sudo(@mansectsu@). +.PP +For example, to allow user operator to edit the +\(lqmessage of the day\(rq +file: +.nf +.sp +.RS 6n +operator sudoedit /etc/motd +.RE +.fi +.PP +The operator user then runs +\fBsudoedit\fR +as follows: +.nf +.sp +.RS 6n +$ sudoedit /etc/motd +.RE +.fi +.PP +The editor will run as the operator user, not root, on a temporary copy of +\fI/etc/motd\fR. +After the file has been edited, +\fI/etc/motd\fR +will be updated with the contents of the temporary copy. +.PP +Users should +\fInever\fR +be granted +\fBsudoedit\fR +permission to edit a file that resides in a directory the user +has write access to, either directly or via a wildcard. +If the user has write access to the directory it is possible to +replace the legitimate file with a link to another file, +allowing the editing of arbitrary files. +To prevent this, starting with version 1.8.16, symbolic links will +not be followed in writable directories and +\fBsudoedit\fR +will refuse to edit a file located in a writable directory +unless the +\fIsudoedit_checkdir\fR +option has been disabled or the invoking user is root. +Additionally, in version 1.8.15 and higher, +\fBsudoedit\fR +will refuse to open a symbolic link unless either the +\fIsudoedit_follow\fR +option is enabled or the +\fIsudoedit\fR +command is prefixed with the +\fRFOLLOW\fR +tag in the +\fIsudoers\fR +file. +.SS "Time stamp file checks" +\fBsudoers\fR +will check the ownership of its time stamp directory +(\fI@rundir@/ts\fR +by default) +and ignore the directory's contents if it is not owned by root or +if it is writable by a user other than root. +Older versions of +\fBsudo\fR +stored time stamp files in +\fI/tmp\fR; +this is no longer recommended as it may be possible for a user +to create the time stamp themselves on systems that allow +unprivileged users to change the ownership of files they create. +.PP +While the time stamp directory +\fIshould\fR +be cleared at reboot time, not all systems contain a +\fI/run\fR +or +\fI/var/run\fR +directory. +To avoid potential problems, +\fBsudoers\fR +will ignore time stamp files that date from before the machine booted +on systems where the boot time is available. +.PP +Some systems with graphical desktop environments allow unprivileged +users to change the system clock. +Since +\fBsudoers\fR +relies on the system clock for time stamp validation, it may be +possible on such systems for a user to run +\fBsudo\fR +for longer than +\fItimestamp_timeout\fR +by setting the clock back. +To combat this, +\fBsudoers\fR +uses a monotonic clock (which never moves backwards) for its time stamps +if the system supports it. +.PP +\fBsudoers\fR +will not honor time stamps set far in the future. +Time stamps with a date greater than current_time + 2 * +\fRTIMEOUT\fR +will be ignored and +\fBsudoers\fR +will log and complain. +.PP +If the +\fItimestamp_type\fR +option is set to +\(lqtty\(rq, +the time stamp record includes the device number of the terminal +the user authenticated with. +This provides per-terminal granularity but time stamp records may still +outlive the user's session. +.PP +Unless the +\fItimestamp_type\fR +option is set to +\(lqglobal\(rq, +the time stamp record also includes the session ID of the process +that last authenticated. +This prevents processes in different terminal sessions from using +the same time stamp record. +On systems where a process's start time can be queried, +the start time of the session leader +is recorded in the time stamp record. +If no terminal is present or the +\fItimestamp_type\fR +option is set to +\(lqppid\(rq, +the start time of the parent process is used instead. +In most cases this will prevent a time stamp record from being re-used +without the user entering a password when logging out and back in again. +.SH "DEBUGGING" +Versions 1.8.4 and higher of the +\fBsudoers\fR +plugin support a flexible debugging framework that can help track +down what the plugin is doing internally if there is a problem. +This can be configured in the +sudo.conf(@mansectform@) +file. +.PP +The +\fBsudoers\fR +plugin uses the same debug flag format as the +\fBsudo\fR +front-end: +\fIsubsystem\fR@\fIpriority\fR. +.PP +The priorities used by +\fBsudoers\fR, +in order of decreasing severity, +are: +\fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR, \fIinfo\fR, \fItrace\fR +and +\fIdebug\fR. +Each priority, when specified, also includes all priorities higher +than it. +For example, a priority of +\fInotice\fR +would include debug messages logged at +\fInotice\fR +and higher. +.PP +The following subsystems are used by the +\fBsudoers\fR +plugin: +.TP 10n +\fIalias\fR +\fRUser_Alias\fR, +\fRRunas_Alias\fR, +\fRHost_Alias\fR +and +\fRCmnd_Alias\fR +processing +.TP 10n +\fIall\fR +matches every subsystem +.TP 10n +\fIaudit\fR +BSM and Linux audit code +.TP 10n +\fIauth\fR +user authentication +.TP 10n +\fIdefaults\fR +\fIsudoers\fR +file +\fIDefaults\fR +settings +.TP 10n +\fIenv\fR +environment handling +.TP 10n +\fIldap\fR +LDAP-based sudoers +.TP 10n +\fIlogging\fR +logging support +.TP 10n +\fImatch\fR +matching of users, groups, hosts and netgroups in the +\fIsudoers\fR +file +.TP 10n +\fInetif\fR +network interface handling +.TP 10n +\fInss\fR +network service switch handling in +\fBsudoers\fR +.TP 10n +\fIparser\fR +\fIsudoers\fR +file parsing +.TP 10n +\fIperms\fR +permission setting +.TP 10n +\fIplugin\fR +The equivalent of +\fImain\fR +for the plugin. +.TP 10n +\fIpty\fR +pseudo-terminal related code +.TP 10n +\fIrbtree\fR +redblack tree internals +.TP 10n +\fIsssd\fR +SSSD-based sudoers +.TP 10n +\fIutil\fR +utility functions +.PD 0 +.PP +For example: +.nf +.sp +.RS 0n +Debug sudo /var/log/sudo_debug match@info,nss@info +.RE +.fi +.PD +.PP +For more information, see the +sudo.conf(@mansectform@) +manual. +.SH "SEE ALSO" +ssh(1), +su(1), +fnmatch(3), +glob(3), +mktemp(3), +strftime(3), +sudo.conf(@mansectform@), +sudo_plugin(@mansectform@), +sudoers.ldap(@mansectform@), +sudoers_timestamp(@mansectform@), +sudo(@mansectsu@), +visudo(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "CAVEATS" +The +\fIsudoers\fR +file should +\fBalways\fR +be edited by the +\fBvisudo\fR +utility which locks the file and checks for syntax errors. +If +\fIsudoers\fR +contains syntax errors, +\fBsudo\fR +may refuse to run, which is a serious problem if +\fBsudo\fR +is your only method of obtaining superuser privileges. +Recent versions of +\fBsudoers\fR +will attempt to recover after a syntax error by ignoring the rest of +the line after encountering an error. +Older versions of +\fBsudo\fR +will not run if +\fIsudoers\fR +contains a syntax error. +.PP +When using netgroups of machines (as opposed to users), if you +store fully qualified host name in the netgroup (as is usually the +case), you either need to have the machine's host name be fully qualified +as returned by the +\fRhostname\fR +command or use the +\fIfqdn\fR +option in +\fIsudoers\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers.man.in.sed b/doc/sudoers.man.in.sed new file mode 100644 index 0000000..eca83a3 --- /dev/null +++ b/doc/sudoers.man.in.sed @@ -0,0 +1,150 @@ +s/^\(.TH .*\)/.nr SL @SEMAN@\ +.nr BA @BAMAN@\ +.nr LC @LCMAN@\ +.nr PS @PSMAN@\ +\1/ + +/^On$/N +/^On\nBSD$/,/^.*\.$/ { + /^On\nBSD$/i\ +.if \\n(LC \\{\\ + /\.$/a\ +.\\} +} + +/^\.SS "SELinux_Spec"$/,/^\.SS/ { + /^\.SS / { + /^\.SS "SELinux_Spec"$/i\ +.if \\n(SL \\{\\ + /^\.SS "SELinux_Spec"$/!i\ +.\\} + } +} + +/^\.SS "Solaris_Priv_Spec"$/,/^\.SS/ { + /^\.SS / { + /^\.SS "Solaris_Priv_Spec"$/i\ +.if \\n(PS \\{\\ + /^\.SS "Solaris_Priv_Spec"$/!i\ +.\\} + } +} + +/^Option_Spec ::= / { + s/^.*$/.ie \\n(SL \\{\\\ +.ie \\n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec)\ +.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec)\ +.\\}\ +.el \\{\\\ +.ie \\n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec)\ +.el Option_Spec ::= (Date_Spec | Timeout_Spec)\ +.\\}/ +} + +/^SELinux_Spec ::=/ { + i\ +.if \\n(SL \\{\\ + N + a\ +.\\} +} + +/^Solaris_Priv_Spec ::=/ { + i\ +.if \\n(PS \\{\\ + N + a\ +.\\} +} + +/^SELinux roles.*types,/ { + i\ +.if \\n(SL \\{\\ + a\ +.\\} +} + +/^Solaris privileges sets,/ { + i\ +.if \\n(PS \\{\\ + a\ +.\\} +} + +/^\.TP 18n$/ { + N + /^\.TP 18n\nuse_loginclass$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\nuse_loginclass$/i\ +.if \\n(BA \\{\\ + /^\.TP 18n\nuse_loginclass$/!i\ +.\\} + } + } + /^\.TP 18n\nlimitprivs$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\nlimitprivs$/i\ +.if \\n(PS \\{\\ + /^\.TP 18n\nlimitprivs$/!i\ +.\\} + } + } + /^\.TP 18n\nprivs$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\nprivs$/i\ +.if \\n(PS \\{\\ + /^\.TP 18n\nprivs$/!i\ +.\\} + } + } + /^\.TP 18n\nselinux$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\nselinux$/i\ +.if \\n(SL \\{\\ + /^\.TP 18n\nselinux$/!i\ +.\\} + } + } + /^\.TP 18n\nrole$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\nrole$/i\ +.if \\n(SL \\{\\ + /^\.TP 18n\nrole$/!i\ +.\\} + } + } + /^\.TP 18n\ntype$/,/^\.TP 18n/ { + /^\.TP 18n/ { + /^\.TP 18n\ntype$/i\ +.if \\n(SL \\{\\ + /^\.TP 18n\ntype$/!i\ +.\\} + } + } +} + +/^\\fRPRIVS\\fR,/ { + i\ +.if \\n(PS \\{\\ + a\ +.\\} +} +/^\\fRLIMITPRIVS\\fR,/ { + i\ +.if \\n(PS \\{\\ + a\ +.\\} +} + +/^\\fRROLE\\fR,/ { + i\ +.if \\n(SL \\{\\ + a\ +.\\} +} +/^\\fRTYPE\\fR,/ { + i\ +.if \\n(SL \\{\\ + a\ +.\\} +} diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in new file mode 100644 index 0000000..c14855b --- /dev/null +++ b/doc/sudoers.mdoc.in @@ -0,0 +1,6051 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1994-1996, 1998-2005, 2007-2021 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.nr SL @SEMAN@ +.nr BA @BAMAN@ +.nr LC @LCMAN@ +.nr PS @PSMAN@ +.Dd January 8, 2020 +.Dt SUDOERS @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudoers +.Nd default sudo security policy plugin +.Sh DESCRIPTION +The +.Nm +policy plugin determines a user's +.Nm sudo +privileges. +It is the default +.Nm sudo +policy plugin. +The policy is driven by +the +.Pa @sysconfdir@/sudoers +file or, optionally in LDAP. +The policy format is described in detail in the +.Sx SUDOERS FILE FORMAT +section. +For information on storing +.Nm +policy information +in LDAP, please see +.Xr sudoers.ldap @mansectform@ . +.Ss Configuring sudo.conf for sudoers +.Nm sudo +consults the +.Xr sudo.conf @mansectform@ +file to determine which policy and I/O logging plugins to load. +If no +.Xr sudo.conf @mansectform@ +file is present, or if it contains no +.Li Plugin +lines, +.Nm +will be used for policy decisions and I/O logging. +To explicitly configure +.Xr sudo.conf @mansectform@ +to use the +.Nm +plugin, the following configuration can be used. +.Bd -literal -offset indent +Plugin sudoers_audit sudoers.so +Plugin sudoers_policy sudoers.so +Plugin sudoers_io sudoers.so +.Ed +.Pp +Starting with +.Nm sudo +1.8.5, it is possible to specify optional arguments to the +.Nm +plugin in the +.Xr sudo.conf @mansectform@ +file. +Plugin arguments, if any, should be listed after the path to the plugin +(i.e., after +.Pa sudoers.so ) . +The arguments are only effective for the plugin that opens (and parses) the +.Em sudoers +file. +.Pp +For +.Nm sudo +version 1.9.1 and higher, this is the +.Em sudoers_audit +plugin. +For older versions, it is the +.Em sudoers_policy +plugin. +Multiple arguments may be specified, separated by white space. +For example: +.Bd -literal -offset indent +Plugin sudoers_audit sudoers.so sudoers_mode=0400 error_recovery=false +.Ed +.Pp +The following plugin arguments are supported: +.Bl -tag -width 8n +.It error_recovery=bool +The +.Em error_recovery +argument can be used to control whether +.Nm +should attempt to recover from syntax errors in the +.Em sudoers +file. +If set to +.Em true +(the default), +.Nm +will try to recover from a syntax error by discarding the portion +of the line that contains the error until the end of the line. +A value of +.Em false +will disable error recovery. +Prior to version 1.9.3, no error recovery was performed. +.It ldap_conf=pathname +The +.Em ldap_conf +argument can be used to override the default path to the +.Pa ldap.conf +file. +.It ldap_secret=pathname +The +.Em ldap_secret +argument can be used to override the default path to the +.Pa ldap.secret +file. +.It sudoers_file=pathname +The +.Em sudoers_file +argument can be used to override the default path to the +.Em sudoers +file. +.It sudoers_uid=uid +The +.Em sudoers_uid +argument can be used to override the default owner of the sudoers file. +It should be specified as a numeric user-ID. +.It sudoers_gid=gid +The +.Em sudoers_gid +argument can be used to override the default group of the sudoers file. +It must be specified as a numeric group-ID (not a group name). +.It sudoers_mode=mode +The +.Em sudoers_mode +argument can be used to override the default file mode for the sudoers file. +It should be specified as an octal value. +.El +.Pp +For more information on configuring +.Xr sudo.conf @mansectform@ , +please refer to its manual. +.Ss User Authentication +The +.Nm +security policy requires that most users authenticate +themselves before they can use +.Nm sudo . +A password is not required +if the invoking user is root, if the target user is the same as the +invoking user, or if the policy has disabled authentication for the +user or command. +Unlike +.Xr su 1 , +when +.Nm +requires +authentication, it validates the invoking user's credentials, not +the target user's (or root's) credentials. +This can be changed via +the +.Em rootpw , +.Em targetpw +and +.Em runaspw +flags, described later. +.Pp +If a user who is not listed in the policy tries to run a command +via +.Nm sudo , +mail is sent to the proper authorities. +The address +used for such mail is configurable via the +.Em mailto +Defaults entry +(described later) and defaults to +.Li @mailto@ . +.Pp +Note that no mail will be sent if an unauthorized user tries to run +.Nm sudo +with the +.Fl l +or +.Fl v +option unless there is an authentication error and +either the +.Em mail_always +or +.Em mail_badpass +flags are enabled. +This allows users to +determine for themselves whether or not they are allowed to use +.Nm sudo . +By default, all attempts to run +.Nm sudo +(successful or not) +are logged, regardless of whether or not mail is sent. +.Pp +If +.Nm sudo +is run by root and the +.Ev SUDO_USER +environment variable +is set, the +.Nm +policy will use this value to determine who +the actual user is. +This can be used by a user to log commands +through sudo even when a root shell has been invoked. +It also +allows the +.Fl e +option to remain useful even when invoked via a +sudo-run script or program. +Note, however, that the +.Em sudoers +file lookup is still done for root, not the user specified by +.Ev SUDO_USER . +.Pp +.Nm +uses per-user time stamp files for credential caching. +Once a user has been authenticated, a record is written +containing the user-ID that was used to authenticate, the +terminal session ID, the start time of the session leader +(or parent process) and a time stamp +(using a monotonic clock if one is available). +The user may then use +.Nm sudo +without a password for a short period of time +.Po +.Li @timeout@ +minutes unless overridden by the +.Em timestamp_timeout +option +.Pc . +By default, +.Nm +uses a separate record for each terminal, which means that +a user's login sessions are authenticated separately. +The +.Em timestamp_type +option can be used to select the type of time stamp record +.Nm +will use. +.Ss Logging +By default, +.Nm +logs both successful and unsuccessful attempts (as well +as errors). +The +.Em log_allowed +and +.Em log_denied +flags can be used to control this behavior. +Messages can be logged to +.Xr syslog 3 , +a log file, or both. +The default is to log to +.Xr syslog 3 +but this is configurable via the +.Em syslog +and +.Em logfile +settings. +See +.Sx "LOG FORMAT" +for a description of the log file format. +.Pp +.Nm +is also capable of running a command in a pseudo-terminal and logging all +input and/or output. +The standard input, standard output and standard error can be logged +even when not associated with a terminal. +I/O logging is not on by default but can be enabled using +the +.Em log_input +and +.Em log_output +options as well as the +.Li LOG_INPUT +and +.Li LOG_OUTPUT +command tags. +See +.Sx "I/O LOG FILES" +for details on how I/O log files are stored. +.Pp +Starting with version 1.9, the +.Em log_servers +setting may be used to send event and I/O log data to a remote server running +.Nm sudo_logsrvd +or another service that implements the protocol described by +.Xr sudo_logsrv.proto @mansectform@ . +.Ss Command environment +Since environment variables can influence program behavior, +.Nm +provides a means to restrict which variables from the user's +environment are inherited by the command to be run. +There are two +distinct ways +.Nm +can deal with environment variables. +.Pp +By default, the +.Em env_reset +flag is enabled. +This causes commands +to be executed with a new, minimal environment. +On AIX (and Linux +systems without PAM), the environment is initialized with the +contents of the +.Pa /etc/environment +file. +.if \n(LC \{\ +On +.Bx +systems, if the +.Em use_loginclass +flag is enabled, the environment is initialized +based on the +.Em path +and +.Em setenv +settings in +.Pa /etc/login.conf . +.\} +The +.Ev HOME , +.Ev MAIL , +.Ev SHELL , +.Ev LOGNAME +and +.Ev USER +environment variables are initialized based on the target user +and the +.Ev SUDO_* +variables are set based on the invoking user. +Additional variables, such as +.Ev DISPLAY , +.Ev PATH +and +.Ev TERM , +are preserved from the invoking user's environment if permitted by the +.Em env_check +or +.Em env_keep +options. +A few environment variables are treated specially. +If the +.Ev PATH +and +.Ev TERM +variables are not preserved from the user's environment, they will be set +to default values. +The +.Ev LOGNAME +and +.Ev USER +are handled as a single entity. +If one of them is preserved (or removed) from the user's environment, +the other will be as well. +If +.Ev LOGNAME +and +.Ev USER +are to be preserved but only one of them is present in the user's environment, +the other will be set to the same value. +This avoids an inconsistent environment where one of the variables +describing the user name is set to the invoking user and one is +set to the target user. +Environment variables with a value beginning with +.Li () +are removed unless both the name and value parts are matched by +.Em env_keep +or +.Em env_check , +as they may be interpreted as functions by the +.Sy bash +shell. +Prior to version 1.8.11, such variables were always removed. +.Pp +If, however, the +.Em env_reset +flag is disabled, any variables not +explicitly denied by the +.Em env_check +and +.Em env_delete +options are allowed and their values are +inherited from the invoking process. +Prior to version 1.8.21, environment variables with a value beginning with +.Li () +were always removed. +Beginning with version 1.8.21, a pattern in +.Em env_delete +is used to match +.Sy bash +shell functions instead. +Since it is not possible +to block all potentially dangerous environment variables, use +of the default +.Em env_reset +behavior is encouraged. +.Pp +Environment variables specified by +.Em env_check , +.Em env_delete , +or +.Em env_keep +may include one or more +.Ql * +characters which will match zero or more characters. +No other wildcard characters are supported. +.Pp +By default, environment variables are matched by name. +However, if the pattern includes an equal sign +.Pq Ql =\& , +both the variables name and value must match. +For example, a +.Sy bash +shell function could be matched as follows: +.Bd -literal -offset 4n +env_keep += "BASH_FUNC_my_func%%=()*" +.Ed +.Pp +Without the +.Dq Li =()* +suffix, this would not match, as +.Sy bash +shell functions are not preserved by default. +.Pp +The complete list of environment variables that are preserved or removed, +as modified by global Defaults parameters in +.Em sudoers , +is displayed when +.Nm sudo +is run by root with the +.Fl V +option. +Please note that the list of environment variables to remove +varies based on the operating system +.Nm sudo +is running on. +.Pp +Other +.Nm +options may influence the command environment, such as +.Em always_set_home , +.Em secure_path , +.Em set_logname , +and +.Em set_home . +.Pp +On systems that support PAM where the +.Sy pam_env +module is enabled for +.Nm sudo , +variables in the PAM environment may be merged in to the environment. +If a variable in the PAM environment is already present in the +user's environment, the value will only be overridden if the variable +was not preserved by +.Nm . +When +.Em env_reset +is enabled, variables preserved from the invoking user's environment +by the +.Em env_keep +list take precedence over those in the PAM environment. +When +.Em env_reset +is disabled, variables present the invoking user's environment +take precedence over those in the PAM environment unless they +match a pattern in the +.Em env_delete +list. +.Pp +Note that the dynamic linker on most operating systems will remove +variables that can control dynamic linking from the environment of +set-user-ID executables, including +.Nm sudo . +Depending on the operating +system this may include +.Ev _RLD* , +.Ev DYLD_* , +.Ev LD_* , +.Ev LDR_* , +.Ev LIBPATH , +.Ev SHLIB_PATH , +and others. +These type of variables are +removed from the environment before +.Nm sudo +even begins execution +and, as such, it is not possible for +.Nm sudo +to preserve them. +.Pp +As a special case, if the +.Fl i +option (initial login) is +specified, +.Nm +will initialize the environment regardless +of the value of +.Em env_reset . +The +.Ev DISPLAY , +.Ev PATH +and +.Ev TERM +variables remain unchanged; +.Ev HOME , +.Ev MAIL , +.Ev SHELL , +.Ev USER , +and +.Ev LOGNAME +are set based on the target user. +On AIX (and Linux +systems without PAM), the contents of +.Pa /etc/environment +are also +included. +.if \n(LC \{\ +On +.Bx +systems, if the +.Em use_loginclass +flag is +enabled, the +.Em path +and +.Em setenv +variables in +.Pa /etc/login.conf +are also applied. +.\} +All other environment variables are removed unless permitted by +.Em env_keep +or +.Em env_check , +described above. +.Pp +Finally, the +.Em restricted_env_file +and +.Em env_file +files are applied, if present. +The variables in +.Em restricted_env_file +are applied first and are subject to the same restrictions as the +invoking user's environment, as detailed above. +The variables in +.Em env_file +are applied last and are not subject to these restrictions. +In both cases, variables present in the files will only be set to +their specified values if they would not conflict with an existing +environment variable. +.Sh SUDOERS FILE FORMAT +The +.Em sudoers +file is composed of two types of entries: aliases +(basically variables) and user specifications (which specify who +may run what). +.Pp +When multiple entries match for a user, they are applied in order. +Where there are multiple matches, the last match is used (which is +not necessarily the most specific match). +.Pp +The +.Em sudoers +file grammar will be described below in Extended Backus-Naur +Form (EBNF). +Don't despair if you are unfamiliar with EBNF; it is fairly simple, +and the definitions below are annotated. +.Ss Quick guide to EBNF +EBNF is a concise and exact way of describing the grammar of a language. +Each EBNF definition is made up of +.Em production rules . +E.g., +.Pp +.Li symbol ::= definition | alternate1 | alternate2 ... +.Pp +Each +.Em production rule +references others and thus makes up a +grammar for the language. +EBNF also contains the following +operators, which many readers will recognize from regular +expressions. +Do not, however, confuse them with +.Dq wildcard +characters, which have different meanings. +.Bl -tag -width 4n +.It Li \&? +Means that the preceding symbol (or group of symbols) is optional. +That is, it may appear once or not at all. +.It Li * +Means that the preceding symbol (or group of symbols) may appear +zero or more times. +.It Li + +Means that the preceding symbol (or group of symbols) may appear +one or more times. +.El +.Pp +Parentheses may be used to group symbols together. +For clarity, +we will use single quotes +.Pq '' +to designate what is a verbatim character string (as opposed to a symbol name). +.Ss Aliases +There are four kinds of aliases: +.Li User_Alias , +.Li Runas_Alias , +.Li Host_Alias +and +.Li Cmnd_Alias . +Beginning with +.Nm sudo +1.9.0, +.Li Cmd_Alias +may be used in place of +.Li Cmnd_Alias +if desired. +.Bd -literal +Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* | + 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* | + 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* | + 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)* | + 'Cmd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)* + +User_Alias ::= NAME + +User_Alias_Spec ::= User_Alias '=' User_List + +Runas_Alias ::= NAME + +Runas_Alias_Spec ::= Runas_Alias '=' Runas_List + +Host_Alias ::= NAME + +Host_Alias_Spec ::= Host_Alias '=' Host_List + +Cmnd_Alias ::= NAME + +Cmnd_Alias_Spec ::= Cmnd_Alias '=' Cmnd_List + +NAME ::= [A-Z]([A-Z][0-9]_)* +.Ed +.Pp +Each +.Em alias +definition is of the form +.Bd -literal +Alias_Type NAME = item1, item2, ... +.Ed +.Pp +where +.Em Alias_Type +is one of +.Li User_Alias , +.Li Runas_Alias , +.Li Host_Alias , +or +.Li Cmnd_Alias . +A +.Li NAME +is a string of uppercase letters, numbers, +and underscore characters +.Pq Ql _ . +A +.Li NAME +.Sy must +start with an +uppercase letter. +It is possible to put several alias definitions +of the same type on a single line, joined by a colon +.Pq Ql :\& . +E.g., +.Bd -literal +Alias_Type NAME = item1, item2, item3 : NAME = item4, item5 +.Ed +.Pp +It is a syntax error to redefine an existing +.Em alias . +It is possible to use the same name for +.Em aliases +of different types, but this is not recommended. +.Pp +The definitions of what constitutes a valid +.Em alias +member follow. +.Bd -literal +User_List ::= User | + User ',' User_List + +User ::= '!'* user name | + '!'* #uid | + '!'* %group | + '!'* %#gid | + '!'* +netgroup | + '!'* %:nonunix_group | + '!'* %:#nonunix_gid | + '!'* User_Alias +.Ed +.Pp +A +.Li User_List +is made up of one or more user names, user-IDs +(prefixed with +.Ql # ) , +system group names and IDs (prefixed with +.Ql % +and +.Ql %# +respectively), netgroups (prefixed with +.Ql + ) , +non-Unix group names and IDs (prefixed with +.Ql %: +and +.Ql %:# +respectively) and +.Li User_Alias Ns es. +Each list item may be prefixed with zero or more +.Ql \&! +operators. +An odd number of +.Ql \&! +operators negate the value of +the item; an even number just cancel each other out. +User netgroups are matched using the user and domain members only; +the host member is not used when matching. +.Pp +A +.Li user name , +.Li uid , +.Li group , +.Li gid , +.Li netgroup , +.Li nonunix_group +or +.Li nonunix_gid +may be enclosed in double quotes to avoid the +need for escaping special characters. +Alternately, special characters +may be specified in escaped hex mode, e.g., \ex20 for space. +When +using double quotes, any prefix characters must be included inside +the quotes. +.Pp +The actual +.Li nonunix_group +and +.Li nonunix_gid +syntax depends on +the underlying group provider plugin. +For instance, the QAS AD plugin supports the following formats: +.Bl -bullet -width 1n +.It +Group in the same domain: "%:Group Name" +.It +Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN" +.It +Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567" +.El +.Pp +See +.Sx "GROUP PROVIDER PLUGINS" +for more information. +.Pp +Note that quotes around group names are optional. +Unquoted strings must use a backslash +.Pq Ql \e +to escape spaces and special characters. +See +.Sx Other special characters and reserved words +for a list of +characters that need to be escaped. +.Bd -literal +Runas_List ::= Runas_Member | + Runas_Member ',' Runas_List + +Runas_Member ::= '!'* user name | + '!'* #uid | + '!'* %group | + '!'* %#gid | + '!'* %:nonunix_group | + '!'* %:#nonunix_gid | + '!'* +netgroup | + '!'* Runas_Alias +.Ed +.Pp +A +.Li Runas_List +is similar to a +.Li User_List +except that instead +of +.Li User_Alias Ns es +it can contain +.Li Runas_Alias Ns es . +Note that +user names and groups are matched as strings. +In other words, two users (groups) with the same user (group) ID +are considered to be distinct. +If you wish to match all user names with the same user-ID (e.g., root and +toor), you can use a user-ID instead of a name (#0 in the example given). +Note that the user-ID or group-ID specified in a +.Li Runas_Member +need not be listed in the password or group database. +.Bd -literal +Host_List ::= Host | + Host ',' Host_List + +Host ::= '!'* host name | + '!'* ip_addr | + '!'* network(/netmask)? | + '!'* +netgroup | + '!'* Host_Alias +.Ed +.Pp +A +.Li Host_List +is made up of one or more host names, IP addresses, +network numbers, netgroups (prefixed with +.Ql + ) +and other aliases. +Again, the value of an item may be negated with the +.Ql \&! +operator. +Host netgroups are matched using the host (both qualified and unqualified) +and domain members only; the user member is not used when matching. +If you specify a network number without a netmask, +.Nm sudo +will query each of the local host's network interfaces and, +if the network number corresponds to one of the hosts's network +interfaces, will use the netmask of that interface. +The netmask may be specified either in standard IP address notation +(e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::), +or CIDR notation (number of bits, e.g., 24 or 64). +A host name may include shell-style wildcards (see the +.Sx Wildcards +section below), +but unless the +.Li host name +command on your machine returns the fully +qualified host name, you'll need to use the +.Em fqdn +flag for wildcards to be useful. +Note that +.Nm sudo +only inspects actual network interfaces; this means that IP address +127.0.0.1 (localhost) will never match. +Also, the host name +.Dq localhost +will only match if that is the actual host name, which is usually +only the case for non-networked systems. +.Bd -literal +digest ::= [A-Fa-f0-9]+ | + [A-Za-z0-9\e+/=]+ + +Digest_Spec ::= "sha224" ':' digest | + "sha256" ':' digest | + "sha384" ':' digest | + "sha512" ':' digest + +Digest_List ::= Digest_Spec | + Digest_Spec ',' Digest_List + +Cmnd_List ::= Cmnd | + Cmnd ',' Cmnd_List + +command name ::= file name | + file name args | + file name '""' + +Edit_Spec ::= "sudoedit" file name+ + +Cmnd ::= Digest_List? '!'* command name | + '!'* directory | + '!'* Edit_Spec | + '!'* Cmnd_Alias +.Ed +.Pp +A +.Li Cmnd_List +is a list of one or more command names, directories, and other aliases. +A command name is a fully qualified file name which may include +shell-style wildcards (see the +.Sx Wildcards +section below). +A simple file name allows the user to run the command with any +arguments they wish. +However, you may also specify command line arguments (including +wildcards). +Alternately, you can specify +.Li \&"" +to indicate that the command +may only be run +.Sy without +command line arguments. +A directory is a +fully qualified path name ending in a +.Ql / . +When you specify a directory in a +.Li Cmnd_List , +the user will be able to run any file within that directory +(but not in any sub-directories therein). +.Pp +If a +.Li Cmnd +has associated command line arguments, then the arguments +in the +.Li Cmnd +must match exactly those given by the user on the command line +(or match the wildcards if there are any). +Note that the following characters must be escaped with a +.Ql \e +if they are used in command arguments: +.Ql ,\& , +.Ql :\& , +.Ql =\& , +.Ql \e . +The built-in command +.Dq Li sudoedit +is used to permit a user to run +.Nm sudo +with the +.Fl e +option (or as +.Nm sudoedit ) . +It may take command line arguments just as a normal command does. +Note that +.Dq Li sudoedit +is a command built into +.Nm sudo +itself and must be specified in the +.Em sudoers +file +.Sy without +a leading path. +If a leading path is present, for example +.Pa /usr/bin/sudoedit , +the path name will be silently converted to +.Dq Li sudoedit . +A fully-qualified path for +.Nm sudoedit +is treated as an error by +.Nm visudo . +.Pp +A +.Li command name +may be preceded by a +.Li Digest_List , +a comma-separated list of one or more +.Li Digest_Spec +entries. +If a +.Li Digest_List +is present, the command will only match successfully if it can be verified +using one of the SHA-2 digests in the list. +Starting with version 1.9.0, the +.Sy ALL +reserved word can be used in conjunction with a +.Li Digest_List . +The following digest formats are supported: sha224, sha256, sha384 and sha512. +The string may be specified in either hex or base64 format +(base64 is more compact). +There are several utilities capable of generating SHA-2 digests in hex +format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum. +.Pp +For example, using openssl: +.Bd -literal +$ openssl dgst -sha224 /bin/ls +SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25 +.Ed +.Pp +It is also possible to use openssl to generate base64 output: +.Bd -literal +$ openssl dgst -binary -sha224 /bin/ls | openssl base64 +EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ== +.Ed +.Pp +Warning, if the user has write access to the command itself (directly or via a +.Nm sudo +command), it may be possible for the user to replace the command after the +digest check has been performed but before the command is executed. +A similar race condition exists on systems that lack the +.Xr fexecve 2 +system call when the directory in which the command is located +is writable by the user. +See the description of the +.Em fdexec +setting for more information on how +.Nm sudo +executes commands that have an associated digest. +.Pp +Command digests are only supported by version 1.8.7 or higher. +.Ss Defaults +Certain configuration options may be changed from their default +values at run-time via one or more +.Li Default_Entry +lines. +These may affect all users on any host, all users on a specific host, a +specific user, a specific command, or commands being run as a specific user. +Note that per-command entries may not include command line arguments. +If you need to specify arguments, define a +.Li Cmnd_Alias +and reference +that instead. +.Bd -literal +Default_Type ::= 'Defaults' | + 'Defaults' '@' Host_List | + 'Defaults' ':' User_List | + 'Defaults' '!' Cmnd_List | + 'Defaults' '>' Runas_List + +Default_Entry ::= Default_Type Parameter_List + +Parameter_List ::= Parameter | + Parameter ',' Parameter_List + +Parameter ::= Parameter '=' Value | + Parameter '+=' Value | + Parameter '-=' Value | + '!'* Parameter +.Ed +.Pp +Parameters may be +.Sy flags , +.Sy integer +values, +.Sy strings , +or +.Sy lists . +Flags are implicitly boolean and can be turned off via the +.Ql \&! +operator. +Some integer, string and list parameters may also be +used in a boolean context to disable them. +Values may be enclosed +in double quotes +.Pq \&"" +when they contain multiple words. +Special characters may be escaped with a backslash +.Pq Ql \e . +.Pp +Lists have two additional assignment operators, +.Li += +and +.Li -= . +These operators are used to add to and delete from a list respectively. +It is not an error to use the +.Li -= +operator to remove an element +that does not exist in a list. +.Pp +Defaults entries are parsed in the following order: generic, host, +user and runas Defaults first, then command defaults. +If there are multiple Defaults settings of the same type, the last +matching setting is used. +The following Defaults settings are parsed before all others since +they may affect subsequent entries: +.Em fqdn , +.Em group_plugin , +.Em runas_default , +.Em sudoers_locale . +.Pp +See +.Sx SUDOERS OPTIONS +for a list of supported Defaults parameters. +.Ss User specification +.Bd -literal +User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e + (':' Host_List '=' Cmnd_Spec_List)* + +Cmnd_Spec_List ::= Cmnd_Spec | + Cmnd_Spec ',' Cmnd_Spec_List + +Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd + +Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')' + +.ie \n(SL \{\ +.ie \n(PS Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Date_Spec | Timeout_Spec | Chdir_Spec | Chroot_Spec) +.el Option_Spec ::= (SELinux_Spec | Date_Spec | Timeout_Spec | Chdir_Spec | Chroot_Spec) +.\} +.el \{\ +.ie \n(PS Option_Spec ::= (Solaris_Priv_Spec | Date_Spec | Timeout_Spec | Chdir_Spec | Chroot_Spec) +.el Option_Spec ::= (Date_Spec | Timeout_Spec | Chdir_Spec | Chroot_Spec) +.\} + +.if \n(SL \{\ +SELinux_Spec ::= ('ROLE=role' | 'TYPE=type') + +.\} +.if \n(PS \{\ +Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset') + +.\} +Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp') + +Timeout_Spec ::= 'TIMEOUT=timeout' + +Chdir_Spec ::= 'CWD=directory' + +Chroot_Spec ::= 'CHROOT=directory' + +Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' | + 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' | + 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'PASSWD:' | + 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:') +.Ed +.Pp +A +.Sy user specification +determines which commands a user may run +(and as what user) on specified hosts. +By default, commands are +run as +.Sy root , +but this can be changed on a per-command basis. +.Pp +The basic structure of a user specification is +.Dq who where = (as_whom) what . +Let's break that down into its constituent parts: +.Ss Runas_Spec +A +.Li Runas_Spec +determines the user and/or the group that a command +may be run as. +A fully-specified +.Li Runas_Spec +consists of two +.Li Runas_List Ns s +(as defined above) separated by a colon +.Pq Ql :\& +and enclosed in a set of parentheses. +The first +.Li Runas_List +indicates which users the command may be run as via the +.Fl u +option. +The second defines a list of groups that can be specified via the +.Fl g +option in addition to any of the target user's groups. +If both +.Li Runas_List Ns s +are specified, the command may be run with any combination of users +and groups listed in their respective +.Li Runas_List Ns s. +If only the first is specified, the command may be run as any user +in the list but no +.Fl g +option +may be specified. +If the first +.Li Runas_List +is empty but the +second is specified, the command may be run as the invoking user +with the group set to any listed in the +.Li Runas_List . +If both +.Li Runas_List Ns s +are empty, the command may only be run as the invoking user. +If no +.Li Runas_Spec +is specified the command may be run as +.Sy root +and +no group may be specified. +.Pp +A +.Li Runas_Spec +sets the default for the commands that follow it. +What this means is that for the entry: +.Bd -literal +dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/lprm +.Ed +.Pp +The user +.Sy dgb +may run +.Pa /bin/ls , +.Pa /bin/kill , +and +.Pa /usr/bin/lprm +on the host +.No boulder Ns \(em Ns but +only as +.Sy operator . +E.g., +.Bd -literal +$ sudo -u operator /bin/ls +.Ed +.Pp +It is also possible to override a +.Li Runas_Spec +later on in an entry. +If we modify the entry like so: +.Bd -literal +dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm +.Ed +.Pp +Then user +.Sy dgb +is now allowed to run +.Pa /bin/ls +as +.Sy operator , +but +.Pa /bin/kill +and +.Pa /usr/bin/lprm +as +.Sy root . +.Pp +We can extend this to allow +.Sy dgb +to run +.Li /bin/ls +with either +the user or group set to +.Sy operator : +.Bd -literal +dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\e + /usr/bin/lprm +.Ed +.Pp +Note that while the group portion of the +.Li Runas_Spec +permits the +user to run as command with that group, it does not force the user +to do so. +If no group is specified on the command line, the command +will run with the group listed in the target user's password database +entry. +The following would all be permitted by the sudoers entry above: +.Bd -literal +$ sudo -u operator /bin/ls +$ sudo -u operator -g operator /bin/ls +$ sudo -g operator /bin/ls +.Ed +.Pp +In the following example, user +.Sy tcm +may run commands that access +a modem device file with the dialer group. +.Bd -literal +tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\e + /usr/local/bin/minicom +.Ed +.Pp +Note that in this example only the group will be set, the command +still runs as user +.Sy tcm . +E.g.\& +.Bd -literal +$ sudo -g dialer /usr/bin/cu +.Ed +.Pp +Multiple users and groups may be present in a +.Li Runas_Spec , +in which case the user may select any combination of users and groups via the +.Fl u +and +.Fl g +options. +In this example: +.Bd -literal +alan ALL = (root, bin : operator, system) ALL +.Ed +.Pp +user +.Sy alan +may run any command as either user root or bin, +optionally setting the group to operator or system. +.Ss Option_Spec +A +.Li Cmnd +may have zero or more options associated with it. +Options may consist of +.if \n(SL \{\ +SELinux roles and/or types, +.\} +.if \n(PS \{\ +Solaris privileges sets, +.\} +start and/or end dates and command timeouts. +Once an option is set for a +.Li Cmnd , +subsequent +.Li Cmnd Ns s +in the +.Li Cmnd_Spec_List , +inherit that option unless it is overridden by another option. +Note that the option names are reserved words in +.Em sudoers . +This means that none of the valid option names (see below) can be used +when declaring an alias. +.if \n(SL \{\ +.Ss SELinux_Spec +On systems with SELinux support, +.Em sudoers +file entries may optionally have an SELinux role and/or type associated +with a command. +If a role or +type is specified with the command it will override any default values +specified in +.Em sudoers . +A role or type specified on the command line, +however, will supersede the values in +.Em sudoers . +.\} +.if \n(PS \{\ +.Ss Solaris_Priv_Spec +On Solaris systems, +.Em sudoers +file entries may optionally specify Solaris privilege set and/or limit +privilege set associated with a command. +If privileges or limit privileges are specified with the command +it will override any default values specified in +.Em sudoers . +.Pp +A privilege set is a comma-separated list of privilege names. +The +.Xr ppriv 1 +command can be used to list all privileges known to the system. +For example: +.Bd -literal +$ ppriv -l +.Ed +.Pp +In addition, there are several +.Dq special +privilege strings: +.Bl -tag -width 8n +.It none +the empty set +.It all +the set of all privileges +.It zone +the set of all privileges available in the current zone +.It basic +the default set of privileges normal users are granted at login time +.El +.Pp +Privileges can be excluded from a set by prefixing the privilege +name with either an +.Ql \&! +or +.Ql \- +character. +.\} +.Ss Date_Spec +.Nm +rules can be specified with a start and end date via the +.Li NOTBEFORE +and +.Li NOTAFTER +settings. +The time stamp must be specified in +.Em Generalized Time +as defined by RFC 4517. +The format is effectively +.Li yyyymmddHHMMSSZ +where the minutes and seconds are optional. +The +.Ql Z +suffix indicates that the time stamp is in Coordinated Universal Time (UTC). +It is also possible to specify a timezone offset from UTC in hours +and minutes instead of a +.Ql Z . +For example, +.Ql -0500 +would correspond to Eastern Standard time in the US. +As an extension, if no +.Ql Z +or timezone offset is specified, local time will be used. +.Pp +The following are all valid time stamps: +.Bd -literal -offset 4n +20170214083000Z +2017021408Z +20160315220000-0500 +20151201235900 +.Ed +.Ss Timeout_Spec +A command may have a timeout associated with it. +If the timeout expires before the command has exited, the +command will be terminated. +The timeout may be specified in combinations of days, hours, +minutes and seconds with a single-letter case-insensitive suffix +that indicates the unit of time. +For example, a timeout of 7 days, 8 hours, 30 minutes and +10 seconds would be written as +.Li 7d8h30m10s . +If a number is specified without a unit, seconds are assumed. +Any of the days, minutes, hours or seconds may be omitted. +The order must be from largest to smallest unit and a unit +may not be specified more than once. +.Pp +The following are all +.Em valid +timeout values: +.Li 7d8h30m10s , +.Li 14d , +.Li 8h30m , +.Li 600s , +.Li 3600 . +The following are +.Em invalid +timeout values: +.Li 12m2w1d , +.Li 30s10m4h , +.Li 1d2d3h . +.Pp +This setting is only supported by version 1.8.20 or higher. +.Ss Chdir_Spec +The working directory that the command will be run in can be specified +using the +.Li CWD +setting. +The +.Fa directory +must be a fully-qualified path name beginning with a +.Sq / +or +.Sq ~ +character, or the special value +.Dq * . +A value of +.Dq * +indicates that the user may specify the working directory by running +.Nm sudo +with the +.Fl D +option. +By default, commands are run from the invoking user's current working +directory, unless the +.Fl i +option is given. +Path names of the form +.Li ~user/path/name +are interpreted as being relative to the named user's home directory. +If the user name is omitted, the path will be relative to the runas +user's home directory. +.Pp +This setting is only supported by version 1.9.3 or higher. +.Ss Chroot_Spec +The root directory that the command will be run in can be specified +using the +.Li CHROOT +setting. +The +.Fa directory +must be a fully-qualified path name beginning with a +.Sq / +or +.Sq ~ +character, or the special value +.Dq * . +A value of +.Dq * +indicates that the user may specify the root directory by running +.Nm sudo +with the +.Fl R +option. +This setting can be used to run the command in a +.Xr chroot 2 +.Dq sandbox +similar to the +.Xr chroot @mansectsu@ +utility. +Path names of the form +.Li ~user/path/name +are interpreted as being relative to the named user's home directory. +If the user name is omitted, the path will be relative to the runas +user's home directory. +.Pp +This setting is only supported by version 1.9.3 or higher. +.Ss Tag_Spec +A command may have zero or more tags associated with it. +The following tag values are supported: +.Li EXEC , +.Li NOEXEC , +.Li FOLLOW , +.Li NOFOLLOW , +.Li LOG_INPUT , +.Li NOLOG_INPUT , +.Li LOG_OUTPUT , +.Li NOLOG_OUTPUT , +.Li MAIL , +.Li NOMAIL , +.Li PASSWD , +.Li NOPASSWD , +.Li SETENV , +and +.Li NOSETENV . +Once a tag is set on a +.Li Cmnd , +subsequent +.Li Cmnd Ns s +in the +.Li Cmnd_Spec_List , +inherit the tag unless it is overridden by the opposite tag (in other words, +.Li PASSWD +overrides +.Li NOPASSWD +and +.Li NOEXEC +overrides +.Li EXEC ) . +.Bl -hang -width 0n +.It Em EXEC No and Em NOEXEC +.sp +If +.Nm sudo +has been compiled with +.Em noexec +support and the underlying operating system supports it, the +.Li NOEXEC +tag can be used to prevent a dynamically-linked executable from +running further commands itself. +.Pp +In the following example, user +.Sy aaron +may run +.Pa /usr/bin/more +and +.Pa /usr/bin/vi +but shell escapes will be disabled. +.Bd -literal +aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi +.Ed +.Pp +See the +.Sx Preventing shell escapes +section below for more details on how +.Li NOEXEC +works and whether or not it will work on your system. +.It Em FOLLOW No and Em NOFOLLOW +Starting with version 1.8.15, +.Nm sudoedit +will not open a file that is a symbolic link unless the +.Em sudoedit_follow +flag is enabled. +The +.Em FOLLOW +and +.Em NOFOLLOW +tags override the value of +.Em sudoedit_follow +and can be used to permit (or deny) the editing of symbolic links +on a per-command basis. +These tags are only effective for the +.Em sudoedit +command and are ignored for all other commands. +.It Em LOG_INPUT No and Em NOLOG_INPUT +.sp +These tags override the value of the +.Em log_input +flag on a per-command basis. +For more information, see the description of +.Em log_input +in the +.Sx SUDOERS OPTIONS +section below. +.It Em LOG_OUTPUT No and Em NOLOG_OUTPUT +.sp +These tags override the value of the +.Em log_output +flag on a per-command basis. +For more information, see the description of +.Em log_output +in the +.Sx SUDOERS OPTIONS +section below. +.It Em MAIL No and Em NOMAIL +.sp +These tags provide fine-grained control over whether +mail will be sent when a user runs a command by +overriding the value of the +.Em mail_all_cmnds +flag on a per-command basis. +They have no effect when +.Nm sudo +is run with the +.Fl l +or +.Fl v +options. +A +.Em NOMAIL +tag will also override the +.Em mail_always +and +.Em mail_no_perms +options. +For more information, see the descriptions of +.Em mail_all_cmnds , +.Em mail_always , +and +.Em mail_no_perms +in the +.Sx SUDOERS OPTIONS +section below. +.It Em PASSWD No and Em NOPASSWD +.sp +By default, +.Nm sudo +requires that a user authenticate him or herself +before running a command. +This behavior can be modified via the +.Li NOPASSWD +tag. +Like a +.Li Runas_Spec , +the +.Li NOPASSWD +tag sets +a default for the commands that follow it in the +.Li Cmnd_Spec_List . +Conversely, the +.Li PASSWD +tag can be used to reverse things. +For example: +.Bd -literal +ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm +.Ed +.Pp +would allow the user +.Sy ray +to run +.Pa /bin/kill , +.Pa /bin/ls , +and +.Pa /usr/bin/lprm +as +.Sy root +on the machine rushmore without authenticating himself. +If we only want +.Sy ray +to be able to +run +.Pa /bin/kill +without a password the entry would be: +.Bd -literal +ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm +.Ed +.Pp +Note, however, that the +.Li PASSWD +tag has no effect on users who are in the group specified by the +.Em exempt_group +setting. +.Pp +By default, if the +.Li NOPASSWD +tag is applied to any of a user's entries for the current host, +the user will be able to run +.Dq Li sudo -l +without a password. +Additionally, a user may only run +.Dq Li sudo -v +without a password if all of the user's entries for the current +host have the +.Li NOPASSWD +tag. +This behavior may be overridden via the +.Em verifypw +and +.Em listpw +options. +.It Em SETENV No and Em NOSETENV +.sp +These tags override the value of the +.Em setenv +flag on a per-command basis. +Note that if +.Li SETENV +has been set for a command, the user may disable the +.Em env_reset +flag from the command line via the +.Fl E +option. +Additionally, environment variables set on the command +line are not subject to the restrictions imposed by +.Em env_check , +.Em env_delete , +or +.Em env_keep . +As such, only trusted users should be allowed to set variables in this manner. +If the command matched is +.Sy ALL , +the +.Li SETENV +tag is implied for that command; this default may be overridden by use of the +.Li NOSETENV +tag. +.El +.Ss Wildcards +.Nm sudo +allows shell-style +.Em wildcards +(aka meta or glob characters) +to be used in host names, path names and command line arguments in the +.Em sudoers +file. +Wildcard matching is done via the +.Xr glob 3 +and +.Xr fnmatch 3 +functions as specified by +.St -p1003.1 . +.Bl -tag -width 8n +.It Li * +Matches any set of zero or more characters (including white space). +.It Li \&? +Matches any single character (including white space). +.It Li [...] +Matches any character in the specified range. +.It Li [!...] +Matches any character +.Em not +in the specified range. +.It Li \ex +For any character +.Sq x , +evaluates to +.Sq x . +This is used to escape special characters such as: +.Ql * , +.Ql \&? , +.Ql [\& , +and +.Ql ]\& . +.El +.Pp +.Bf -symbolic +Note that these are not regular expressions. +.Ef +Unlike a regular expression there is no way to match one or more +characters within a range. +.Pp +Character classes may be used if your system's +.Xr glob 3 +and +.Xr fnmatch 3 +functions support them. +However, because the +.Ql :\& +character has special meaning in +.Em sudoers , +it must be +escaped. +For example: +.Bd -literal -offset 4n +/bin/ls [[\e:\&alpha\e:\&]]* +.Ed +.Pp +Would match any file name beginning with a letter. +.Pp +Note that a forward slash +.Pq Ql / +will +.Em not +be matched by +wildcards used in the file name portion of the command. +This is to make a path like: +.Bd -literal -offset 4n +/usr/bin/* +.Ed +.Pp +match +.Pa /usr/bin/who +but not +.Pa /usr/bin/X11/xterm . +.Pp +When matching the command line arguments, however, a slash +.Em does +get matched by wildcards since command line arguments may contain +arbitrary strings and not just path names. +.Pp +.Bf -symbolic +Wildcards in command line arguments should be used with care. +.Ef +.br +Command line arguments are matched as a single, concatenated string. +This mean a wildcard character such as +.Ql \&? +or +.Ql * +will match across word boundaries, which may be unexpected. +For example, while a sudoers entry like: +.Bd -literal -offset 4n +%operator ALL = /bin/cat /var/log/messages* +.Ed +.Pp +will allow command like: +.Bd -literal -offset 4n +$ sudo cat /var/log/messages.1 +.Ed +.Pp +It will also allow: +.Bd -literal -offset 4n +$ sudo cat /var/log/messages /etc/shadow +.Ed +.Pp +which is probably not what was intended. +In most cases it is better to do command line processing +outside of the +.Em sudoers +file in a scripting language. +.Ss Exceptions to wildcard rules +The following exceptions apply to the above rules: +.Bl -tag -width 8n +.It Li \&"" +If the empty string +.Li \&"" +is the only command line argument in the +.Em sudoers +file entry it means that command is not allowed to be run with +.Em any +arguments. +.It sudoedit +Command line arguments to the +.Em sudoedit +built-in command should always be path names, so a forward slash +.Pq Ql / +will not be matched by a wildcard. +.El +.Ss Including other files from within sudoers +It is possible to include other +.Em sudoers +files from within the +.Em sudoers +file currently being parsed using the +.Li @include +and +.Li @includedir +directives. +For compatibility with sudo versions prior to 1.9.1, +.Li #include +and +.Li #includedir +are also accepted. +.Pp +An include file can be used, for example, to keep a site-wide +.Em sudoers +file in addition to a local, per-machine file. +For the sake of this example the site-wide +.Em sudoers +file will be +.Pa /etc/sudoers +and the per-machine one will be +.Pa /etc/sudoers.local . +To include +.Pa /etc/sudoers.local +from within +.Pa /etc/sudoers +one would use the following line in +.Pa /etc/sudoers : +.Bd -literal -offset 4n +@include /etc/sudoers.local +.Ed +.Pp +When +.Nm sudo +reaches this line it will suspend processing of the current file +.Pq Pa /etc/sudoers +and switch to +.Pa /etc/sudoers.local . +Upon reaching the end of +.Pa /etc/sudoers.local , +the rest of +.Pa /etc/sudoers +will be processed. +Files that are included may themselves include other files. +A hard limit of 128 nested include files is enforced to prevent include +file loops. +.Pp +The path to the include file may contain white space if it is +escaped with a backslash +.Pq Ql \e . +Alternately, the entire path may be enclosed in double quotes +.Pq \&"" , +in which case no escaping is necessary. +To include a literal backslash in the path, +.Ql \e\e +should be used. +.Pp +If the path to the include file is not fully-qualified (does not +begin with a +.Ql / ) , +it must be located in the same directory as the sudoers file it was +included from. +For example, if +.Pa /etc/sudoers +contains the line: +.Bd -literal -offset 4n +.Li @include sudoers.local +.Ed +.Pp +the file that will be included is +.Pa /etc/sudoers.local . +.Pp +The file name may also include the +.Li %h +escape, signifying the short form of the host name. +In other words, if the machine's host name is +.Dq xerxes , +then +.Bd -literal -offset 4n +@include /etc/sudoers.%h +.Ed +.Pp +will cause +.Nm sudo +to include the file +.Pa /etc/sudoers.xerxes . +.Pp +The +.Li @includedir +directive can be used to create a +.Pa sudoers.d +directory that the system package manager can drop +.Em sudoers +file rules into as part of package installation. +For example, given: +.Bd -literal -offset 4n +@includedir /etc/sudoers.d +.Ed +.Pp +.Nm sudo +will suspend processing of the current file and read each file in +.Pa /etc/sudoers.d , +skipping file names that end in +.Ql ~ +or contain a +.Ql .\& +character to avoid causing problems with package manager or editor +temporary/backup files. +Files are parsed in sorted lexical order. +That is, +.Pa /etc/sudoers.d/01_first +will be parsed before +.Pa /etc/sudoers.d/10_second . +Be aware that because the sorting is lexical, not numeric, +.Pa /etc/sudoers.d/1_whoops +would be loaded +.Em after +.Pa /etc/sudoers.d/10_second . +Using a consistent number of leading zeroes in the file names can be used +to avoid such problems. +After parsing the files in the directory, control returns to the +file that contained the +.Li @includedir +directive. +.Pp +Note that unlike files included via +.Li @include , +.Nm visudo +will not edit the files in a +.Li @includedir +directory unless one of them contains a syntax error. +It is still possible to run +.Nm visudo +with the +.Fl f +flag to edit the files directly, but this will not catch the +redefinition of an +.Em alias +that is also present in a different file. +.Ss Other special characters and reserved words +The pound sign +.Pq Ql # +is used to indicate a comment (unless it is part of a #include +directive or unless it occurs in the context of a user name and is +followed by one or more digits, in which case it is treated as a +user-ID). +Both the comment character and any text after it, up to the end of +the line, are ignored. +.Pp +The reserved word +.Sy ALL +is a built-in +.Em alias +that always causes a match to succeed. +It can be used wherever one might otherwise use a +.Li Cmnd_Alias , +.Li User_Alias , +.Li Runas_Alias , +or +.Li Host_Alias . +Attempting to define an +.Em alias +named +.Sy ALL +will result in a syntax error. +Please note that using +.Sy ALL +can be dangerous since in a command context, it allows the user to run +.Em any +command on the system. +.Pp +The following option names permitted in an +.Li Option_Spec +are also considered reserved words: +.Li CHROOT , +.if \n(PS \{\ +.Li PRIVS , +.Li LIMITPRIVS , +.\} +.if \n(SL \{\ +.Li ROLE , +.Li TYPE , +.\} +.Li TIMEOUT , +.Li CWD , +.Li NOTBEFORE +and +.Li NOTAFTER . +Attempting to define an +.Em alias +with the same name as one of the options will result in a syntax error. +.Pp +An exclamation point +.Pq Ql \&! +can be used as a logical +.Em not +operator in a list or +.Em alias +as well as in front of a +.Li Cmnd . +This allows one to exclude certain values. +For the +.Ql \&! +operator to be effective, there must be something for it to exclude. +For example, to match all users except for root one would use: +.Bd -literal -offset 4n +ALL,!root +.Ed +.Pp +If the +.Sy ALL , +is omitted, as in: +.Bd -literal -offset 4n +!root +.Ed +.Pp +it would explicitly deny root but not match any other users. +This is different from a true +.Dq negation +operator. +.Pp +Note, however, that using a +.Ql \&! +in conjunction with the built-in +.Sy ALL +alias to allow a user to run +.Dq all but a few +commands rarely works as intended (see +.Sx SECURITY NOTES +below). +.Pp +Long lines can be continued with a backslash +.Pq Ql \e +as the last character on the line. +.Pp +White space between elements in a list as well as special syntactic +characters in a +.Em User Specification +.Po +.Ql =\& , +.Ql :\& , +.Ql (\& , +.Ql )\& +.Pc +is optional. +.Pp +The following characters must be escaped with a backslash +.Pq Ql \e +when used as part of a word (e.g., a user name or host name): +.Ql \&! , +.Ql =\& , +.Ql :\& , +.Ql ,\& , +.Ql (\& , +.Ql )\& , +.Ql \e . +.Sh SUDOERS OPTIONS +.Nm sudo Ns 's +behavior can be modified by +.Li Default_Entry +lines, as explained earlier. +A list of all supported Defaults parameters, grouped by type, are listed below. +.Pp +.Sy Boolean Flags : +.Bl -tag -width 16n +.It always_query_group_plugin +If a +.Em group_plugin +is configured, use it to resolve groups of the form %group as long +as there is not also a system group of the same name. +Normally, only groups of the form %:group are passed to the +.Em group_plugin . +This flag is +.Em off +by default. +.It always_set_home +If enabled, +.Nm sudo +will set the +.Ev HOME +environment variable to the home directory of the target user +(which is the root user unless the +.Fl u +option is used). +This flag is largely obsolete and has no effect unless the +.Em env_reset +flag has been disabled or +.Ev HOME +is present in the +.Em env_keep +list, both of which are strongly discouraged. +This flag is +.Em off +by default. +.It authenticate +If set, users must authenticate themselves via a password (or other +means of authentication) before they may run commands. +This default may be overridden via the +.Li PASSWD +and +.Li NOPASSWD +tags. +This flag is +.Em on +by default. +.It case_insensitive_group +If enabled, group names in +.Em sudoers +will be matched in a case insensitive manner. +This may be necessary when users are stored in LDAP or AD. +This flag is +.Em on +by default. +.It case_insensitive_user +If enabled, user names in +.Em sudoers +will be matched in a case insensitive manner. +This may be necessary when groups are stored in LDAP or AD. +This flag is +.Em on +by default. +.It closefrom_override +If set, the user may use the +.Fl C +option which overrides the default starting point at which +.Nm sudo +begins closing open file descriptors. +This flag is +.Em off +by default. +.It compress_io +If set, and +.Nm sudo +is configured to log a command's input or output, +the I/O logs will be compressed using +.Sy zlib . +This flag is +.Em on +by default when +.Nm sudo +is compiled with +.Sy zlib +support. +.It exec_background +By default, +.Nm sudo +runs a command as the foreground process as long as +.Nm sudo +itself is running in the foreground. +When the +.Em exec_background +flag is enabled and the command is being run in a pseudo-terminal +(due to I/O logging or the +.Em use_pty +flag), the command will be run as a background process. +Attempts to read from the controlling terminal (or to change terminal +settings) will result in the command being suspended with the +.Dv SIGTTIN +signal (or +.Dv SIGTTOU +in the case of terminal settings). +If this happens when +.Nm sudo +is a foreground process, the command will be granted the controlling terminal +and resumed in the foreground with no user intervention required. +The advantage of initially running the command in the background is that +.Nm sudo +need not read from the terminal unless the command explicitly requests it. +Otherwise, any terminal input must be passed to the command, whether it +has required it or not (the kernel buffers terminals so it is not possible +to tell whether the command really wants the input). +This is different from historic +.Em sudo +behavior or when the command is not being run in a pseudo-terminal. +.Pp +For this to work seamlessly, the operating system must support the +automatic restarting of system calls. +Unfortunately, not all operating systems do this by default, +and even those that do may have bugs. +For example, macOS fails to restart the +.Fn tcgetattr +and +.Fn tcsetattr +system calls (this is a bug in macOS). +Furthermore, because this behavior depends on the command stopping with the +.Dv SIGTTIN +or +.Dv SIGTTOU +signals, programs that catch these signals and suspend themselves +with a different signal (usually +.Dv SIGTOP ) +will not be automatically foregrounded. +Some versions of the linux +.Xr su 1 +command behave this way. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.7 or higher. +It has no effect unless I/O logging is enabled or the +.Em use_pty +flag is enabled. +.It env_editor +If set, +.Nm visudo +will use the value of the +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variables before falling back on the default editor list. +Note that +.Nm visudo +is typically run as root so this flag may allow a user with +.Nm visudo +privileges to run arbitrary commands as root without logging. +An alternative is to place a colon-separated list of +.Dq safe +editors int the +.Em editor +variable. +.Nm visudo +will then only use +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +if they match a value specified in +.Em editor . +If the +.Em env_reset +flag is enabled, the +.Ev SUDO_EDITOR , +.Ev VISUAL +and/or +.Ev EDITOR +environment variables must be present in the +.Em env_keep +list for the +.Em env_editor +flag to function when +.Nm visudo +is invoked via +.Nm sudo . +This flag is +.Em @env_editor@ +by default. +.It env_reset +If set, +.Nm sudo +will run the command in a minimal environment containing the +.Ev TERM , +.Ev PATH , +.Ev HOME , +.Ev MAIL , +.Ev SHELL , +.Ev LOGNAME , +.Ev USER +and +.Ev SUDO_* +variables. +Any variables in the caller's environment or in the file specified +by the +.Em restricted_env_file +setting that match the +.Li env_keep +and +.Li env_check +lists are then added, followed by any variables present in the file +specified by the +.Em env_file +setting (if any). +The contents of the +.Li env_keep +and +.Li env_check +lists, as modified by global Defaults parameters in +.Em sudoers , +are displayed when +.Nm sudo +is run by root with the +.Fl V +option. +If the +.Em secure_path +setting is enabled, its value will be used for the +.Ev PATH +environment variable. +This flag is +.Em @env_reset@ +by default. +.It fast_glob +Normally, +.Nm sudo +uses the +.Xr glob 3 +function to do shell-style globbing when matching path names. +However, since it accesses the file system, +.Xr glob 3 +can take a long time to complete for some patterns, especially +when the pattern references a network file system that is mounted +on demand (auto mounted). +The +.Em fast_glob +flag causes +.Nm sudo +to use the +.Xr fnmatch 3 +function, which does not access the file system to do its matching. +The disadvantage of +.Em fast_glob +is that it is unable to match relative path names such as +.Pa ./ls +or +.Pa ../bin/ls . +This has security implications when path names that include globbing +characters are used with the negation operator, +.Ql !\& , +as such rules can be trivially bypassed. +As such, this flag should not be used when the +.Em sudoers +file contains rules that contain negated path names which include globbing +characters. +This flag is +.Em off +by default. +.It fqdn +Set this flag if you want to put fully qualified host names in the +.Em sudoers +file when the local host name (as returned by the +.Li hostname +command) does not contain the domain name. +In other words, instead of myhost you would use myhost.mydomain.edu. +You may still use the short form if you wish (and even mix the two). +This flag is only effective when the +.Dq canonical +host name, as returned by the +.Fn getaddrinfo +or +.Fn gethostbyname +function, is a fully-qualified domain name. +This is usually the case when the system is configured to use DNS +for host name resolution. +.Pp +If the system is configured to use the +.Pa /etc/hosts +file in preference to DNS, the +.Dq canonical +host name may not be fully-qualified. +The order that sources are queried for host name resolution +is usually specified in the +.Pa @nsswitch_conf@ , +.Pa @netsvc_conf@ , +.Pa /etc/host.conf , +or, in some cases, +.Pa /etc/resolv.conf +file. +In the +.Pa /etc/hosts +file, the first host name of the entry is considered to be the +.Dq canonical +name; subsequent names are aliases that are not used by +.Nm . +For example, the following hosts file line for the machine +.Dq xyzzy +has the fully-qualified domain name as the +.Dq canonical +host name, and the short version as an alias. +.sp +.Dl 192.168.1.1 xyzzy.sudo.ws xyzzy +.sp +If the machine's hosts file entry is not formatted properly, the +.Em fqdn +flag will not be effective if it is queried before DNS. +.Pp +Beware that when using DNS for host name resolution, turning on +.Em fqdn +requires +.Nm +to make DNS lookups which renders +.Nm sudo +unusable if DNS stops working (for example if the machine is disconnected +from the network). +Also note that just like with the hosts file, you must use the +.Dq canonical +name as DNS knows it. +That is, you may not use a host alias +.Po +.Li CNAME +entry +.Pc +due to performance issues and the fact that there is no way to get all +aliases from DNS. +.Pp +This flag is +.Em @fqdn@ +by default. +.It ignore_audit_errors +Allow commands to be run even if +.Nm +cannot write to the audit log. +If enabled, an audit log write failure is not treated as a fatal error. +If disabled, a command may only be run after the audit event is successfully +written. +This flag is only effective on systems for which +.Nm +supports audit logging, including +.Fx , +Linux, macOS and Solaris. +This flag is +.Em on +by default. +.It ignore_dot +If set, +.Nm sudo +will ignore "." or "" (both denoting current directory) in the +.Ev PATH +environment variable; the +.Ev PATH +itself is not modified. +This flag is +.Em @ignore_dot@ +by default. +.It ignore_iolog_errors +Allow commands to be run even if +.Nm +cannot write to the I/O log (local or remote). +If enabled, an I/O log write failure is not treated as a fatal error. +If disabled, the command will be terminated if the I/O log cannot be written to. +This flag is +.Em off +by default. +.It ignore_logfile_errors +Allow commands to be run even if +.Nm +cannot write to the log file. +If enabled, a log file write failure is not treated as a fatal error. +If disabled, a command may only be run after the log file entry is successfully +written. +This flag only has an effect when +.Nm +is configured to use file-based logging via the +.Em logfile +setting. +This flag is +.Em on +by default. +.It ignore_local_sudoers +If set via LDAP, parsing of +.Pa @sysconfdir@/sudoers +will be skipped. +This is intended for Enterprises that wish to prevent the usage of local +sudoers files so that only LDAP is used. +This thwarts the efforts of rogue operators who would attempt to add roles to +.Pa @sysconfdir@/sudoers . +When this flag is enabled, +.Pa @sysconfdir@/sudoers +does not even need to exist. +Since this flag tells +.Nm sudo +how to behave when no specific LDAP entries have been matched, this +sudoOption is only meaningful for the +.Li cn=defaults +section. +This flag is +.Em off +by default. +.It ignore_unknown_defaults +If set, +.Nm sudo +will not produce a warning if it encounters an unknown Defaults entry +in the +.Em sudoers +file or an unknown sudoOption in LDAP. +This flag is +.Em off +by default. +.It insults +If set, +.Nm sudo +will insult users when they enter an incorrect password. +This flag is +.Em @insults@ +by default. +.It log_allowed +If set, +.Nm +will log commands allowed by the policy to the system audit log +(where supported) as well as to syslog and/or a log file. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.8.29 or higher. +.It log_denied +If set, +.Nm +will log commands denied by the policy to the system audit log +(where supported) as well as to syslog and/or a log file. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.8.29 or higher. +.It log_host +If set, the host name will be included in log entries written to +the file configured by the +.Em logfile +setting. +This flag is +.Em off +by default. +.It log_input +If set, +.Nm sudo +will run the command in a pseudo-terminal and log all user input. +If the standard input is not connected to the user's tty, due to +I/O redirection or because the command is part of a pipeline, that +input is also captured and stored in a separate log file. +Anything sent to the standard input will be consumed, regardless of +whether or not the command run via +.Nm sudo +is actually reading the standard input. +This may have unexpected results when using +.Nm sudo +in a shell script that expects to process the standard input. +For more information about I/O logging, see the +.Sx "I/O LOG FILES" +section. +This flag is +.Em off +by default. +.It log_output +If set, +.Nm sudo +will run the command in a pseudo-terminal and log all output that is sent +to the screen, similar to the +.Xr script 1 +command. +For more information about I/O logging, see the +.Sx "I/O LOG FILES" +section. +This flag is +.Em off +by default. +.It log_server_keepalive +If set, +.Nm sudo +will enable the TCP keepalive socket option on the connection to the log server. +This enables the periodic transmission of keepalive messages to the server. +If the server does not respond to a message, the connection will +be closed and the running command will be terminated unless the +.Em ignore_iolog_errors +flag (I/O logging enabled) or the +.Em ignore_log_errors +flag (I/O logging disabled) is set. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It log_server_verify +If set, the server certificate received during the TLS handshake +must be valid and it must contain either the server name (from +.Em log_servers ) +or its IP address. +If either of these conditions is not met, the TLS handshake will fail. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It log_year +If set, the four-digit year will be logged in the (non-syslog) +.Nm sudo +log file. +This flag is +.Em off +by default. +.It long_otp_prompt +When validating with a One Time Password (OTP) scheme such as +.Sy S/Key +or +.Sy OPIE , +a two-line prompt is used to make it easier +to cut and paste the challenge to a local window. +It's not as pretty as the default but some people find it more convenient. +This flag is +.Em @long_otp_prompt@ +by default. +.It mail_all_cmnds +Send mail to the +.Em mailto +user every time a user attempts to run a command via +.Nm sudo +(this includes +.Nm sudoedit ) . +No mail will be sent if the user runs +.Nm sudo +with the +.Fl l +or +.Fl v +option unless there is an authentication error and the +.Em mail_badpass +flag is also set. +This flag is +.Em off +by default. +.It mail_always +Send mail to the +.Em mailto +user every time a user runs +.Nm sudo . +This flag is +.Em off +by default. +.It mail_badpass +Send mail to the +.Em mailto +user if the user running +.Nm sudo +does not enter the correct password. +If the command the user is attempting to run is not permitted by +.Nm +and one of the +.Em mail_all_cmnds , +.Em mail_always , +.Em mail_no_host , +.Em mail_no_perms +or +.Em mail_no_user +flags are set, this flag will have no effect. +This flag is +.Em off +by default. +.It mail_no_host +If set, mail will be sent to the +.Em mailto +user if the invoking user exists in the +.Em sudoers +file, but is not allowed to run commands on the current host. +This flag is +.Em @mail_no_host@ +by default. +.It mail_no_perms +If set, mail will be sent to the +.Em mailto +user if the invoking user is allowed to use +.Nm sudo +but the command they are trying is not listed in their +.Em sudoers +file entry or is explicitly denied. +This flag is +.Em @mail_no_perms@ +by default. +.It mail_no_user +If set, mail will be sent to the +.Em mailto +user if the invoking user is not in the +.Em sudoers +file. +This flag is +.Em @mail_no_user@ +by default. +.It match_group_by_gid +By default, +.Nm +will look up each group the user is a member of by group-ID to +determine the group name (this is only done once). +The resulting list of the user's group names is used when matching +groups listed in the +.Em sudoers +file. +This works well on systems where the number of groups listed in the +.Em sudoers +file is larger than the number of groups a typical user belongs to. +On systems where group lookups are slow, where users may belong +to a large number of groups, and where the number of groups listed +in the +.Em sudoers +file is relatively small, it may be prohibitively expensive and +running commands via +.Nm sudo +may take longer than normal. +On such systems it may be faster to use the +.Em match_group_by_gid +flag to avoid resolving the user's group-IDs to group names. +In this case, +.Nm +must look up any group name listed in the +.Em sudoers +file and use the group-ID instead of the group name when determining +whether the user is a member of the group. +.Pp +Note that if +.Em match_group_by_gid +is enabled, group database lookups performed by +.Nm +will be keyed by group name as opposed to group-ID. +On systems where there are multiple sources for the group database, +it is possible to have conflicting group names or group-IDs in the local +.Pa /etc/group +file and the remote group database. +On such systems, enabling or disabling +.Em match_group_by_gid +can be used to choose whether group database queries are performed +by name (enabled) or ID (disabled), which may aid in working around +group entry conflicts. +.Pp +The +.Em match_group_by_gid +flag has no effect when +.Em sudoers +data is stored in LDAP. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.18 or higher. +.It netgroup_tuple +If set, netgroup lookups will be performed using the full netgroup +tuple: host name, user name and domain (if one is set). +Historically, +.Nm sudo +only matched the user name and domain for netgroups used in a +.Li User_List +and only matched the host name and domain for netgroups used in a +.Li Host_List . +This flag is +.Em off +by default. +.It noexec +If set, all commands run via +.Nm sudo +will behave as if the +.Li NOEXEC +tag has been set, unless overridden by an +.Li EXEC +tag. +See the description of +.Em EXEC and NOEXEC +above as well as the +.Sx Preventing shell escapes +section at the end of this manual. +This flag is +.Em off +by default. +.It pam_acct_mgmt +On systems that use PAM for authentication, +.Nm sudo +will perform PAM account validation for the invoking user by default. +The actual checks performed depend on which PAM modules are configured. +If enabled, account validation will be performed regardless of whether +or not a password is required. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.8.28 or higher. +.It pam_rhost +On systems that use PAM for authentication, +.Nm sudo +will set the PAM remote host value to the name of the local host +when the +.Em pam_rhost +flag is enabled. +On Linux systems, enabling +.Em pam_rhost +may result in DNS lookups of the local host name when PAM is initialized. +On Solaris versions prior to Solaris 8, +.Em pam_rhost +must be enabled if +.Em pam_ruser +is also enabled to avoid a crash in the Solaris PAM implementation. +.Pp +This flag is +.Em off +by default on systems other than Solaris. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It pam_ruser +On systems that use PAM for authentication, +.Nm sudo +will set the PAM remote user value to the name of the user that invoked sudo +when the +.Em pam_ruser +flag is enabled. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It pam_session +On systems that use PAM for authentication, +.Nm sudo +will create a new PAM session for the command to be run in. +Unless +.Nm sudo +is given the +.Fl i +or +.Fl s +options, PAM session modules are run with the +.Dq silent +flag enabled. +This prevents last login information from being displayed for every +command on some systems. +Disabling +.Em pam_session +may be needed on older PAM implementations or on operating systems where +opening a PAM session changes the utmp or wtmp files. +If PAM session support is disabled, resource limits may not be updated +for the command being run. +If +.Em pam_session , +.Em pam_setcred , +and +.Em use_pty +are disabled, +.Em log_servers +has not been set and I/O logging has not been configured, +.Nm sudo +will execute the command directly instead of running it as a child +process. +This flag is +.Em @pam_session@ +by default. +.Pp +This setting is only supported by version 1.8.7 or higher. +.It pam_setcred +On systems that use PAM for authentication, +.Nm sudo +will attempt to establish credentials for the target user by default, +if supported by the underlying authentication system. +One example of a credential is a Kerberos ticket. +If +.Em pam_session , +.Em pam_setcred , +and +.Em use_pty +are disabled, +.Em log_servers +has not been set and I/O logging has not been configured, +.Nm sudo +will execute the command directly instead of running it as a child +process. +This flag is +.Em on +by default. +.Pp +This setting is only supported by version 1.8.8 or higher. +.It passprompt_override +If set, the prompt specified by +.Em passprompt +or the +.Ev SUDO_PROMPT +environment variable will always be used and will replace the +prompt provided by a PAM module or other authentication method. +This flag is +.Em off +by default. +.It path_info +Normally, +.Nm sudo +will tell the user when a command could not be +found in their +.Ev PATH +environment variable. +Some sites may wish to disable this as it could be used to gather +information on the location of executables that the normal user does +not have access to. +The disadvantage is that if the executable is simply not in the user's +.Ev PATH , +.Nm sudo +will tell the user that they are not allowed to run it, which can be confusing. +This flag is +.Em @path_info@ +by default. +.It preserve_groups +By default, +.Nm sudo +will initialize the group vector to the list of groups the target user is in. +When +.Em preserve_groups +is set, the user's existing group vector is left unaltered. +The real and effective group-IDs, however, are still set to match the +target user. +This flag is +.Em off +by default. +.It pwfeedback +By default, +.Nm sudo +reads the password like most other Unix programs, +by turning off echo until the user hits the return (or enter) key. +Some users become confused by this as it appears to them that +.Nm sudo +has hung at this point. +When +.Em pwfeedback +is set, +.Nm sudo +will provide visual feedback when the user presses a key. +Note that this does have a security impact as an onlooker may be able to +determine the length of the password being entered. +This flag is +.Em off +by default. +.It requiretty +If set, +.Nm sudo +will only run when the user is logged in to a real tty. +When this flag is set, +.Nm sudo +can only be run from a login session and not via other means such as +.Xr cron @mansectsu@ +or cgi-bin scripts. +This flag is +.Em off +by default. +.It root_sudo +If set, root is allowed to run +.Nm sudo +too. +Disabling this prevents users from +.Dq chaining +.Nm sudo +commands to get a root shell by doing something like +.Dq Li sudo sudo /bin/sh . +Note, however, that turning off +.Em root_sudo +will also prevent root from running +.Nm sudoedit . +Disabling +.Em root_sudo +provides no real additional security; it exists purely for historical reasons. +This flag is +.Em @root_sudo@ +by default. +.It rootpw +If set, +.Nm sudo +will prompt for the root password instead of the password of the invoking user +when running a command or editing a file. +This flag is +.Em off +by default. +.It runas_allow_unknown_id +If enabled, allow matching of runas user and group IDs that are +not present in the password or group databases. +In addition to explicitly matching unknown user or group IDs in a +.Li Runas_List , +this option also allows the +.Sy ALL +alias to match unknown IDs. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.30 or higher. +Older versions of +.Nm sudo +always allowed matching of unknown user and group IDs. +.It runas_check_shell +If enabled, +.Nm sudo +will only run commands as a user whose shell appears in the +.Pa /etc/shells +file, even if the invoking user's +.Li Runas_List +would otherwise permit it. +If no +.Pa /etc/shells +file is present, a system-dependent list of built-in default shells is used. +On many operating systems, system users such as +.Dq bin , +do not have a valid shell and this flag can be used to prevent +commands from being run as those users. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.30 or higher. +.It runaspw +If set, +.Nm sudo +will prompt for the password of the user defined by the +.Em runas_default +option (defaults to +.Li @runas_default@ ) +instead of the password of the invoking user +when running a command or editing a file. +This flag is +.Em off +by default. +.if \n(SL \{\ +.It selinux +If enabled, the user may specify an SELinux role and/or type to use +when running the command, as permitted by the SELinux policy. +If SELinux is disabled on the system, this flag has no effect. +This flag is +.Em on +by default. +.\} +.It set_home +If enabled and +.Nm sudo +is invoked with the +.Fl s +option, the +.Ev HOME +environment variable will be set to the home directory of the target +user (which is the root user unless the +.Fl u +option is used). +This flag is largely obsolete and has no effect unless the +.Em env_reset +flag has been disabled or +.Ev HOME +is present in the +.Em env_keep +list, both of which are strongly discouraged. +This flag is +.Em off +by default. +.It set_logname +Normally, +.Nm sudo +will set the +.Ev LOGNAME +and +.Ev USER +environment variables to the name of the target user (usually root unless the +.Fl u +option is given). +However, since some programs (including the RCS revision control system) use +.Ev LOGNAME +to determine the real identity of the user, it may be desirable to +change this behavior. +This can be done by negating the set_logname option. +Note that +.Em set_logname +will have no effect +if the +.Em env_reset +option has not been disabled and the +.Em env_keep +list contains +.Ev LOGNAME +or +.Ev USER . +This flag is +.Em on +by default. +.It set_utmp +When enabled, +.Nm sudo +will create an entry in the utmp (or utmpx) file when a pseudo-terminal +is allocated. +A pseudo-terminal is allocated by +.Nm sudo +when it is running in a terminal and one or more of the +.Em log_input , +.Em log_output +or +.Em use_pty +flags is enabled. +By default, the new entry will be a copy of the user's existing utmp +entry (if any), with the tty, time, type and pid fields updated. +This flag is +.Em on +by default. +.It setenv +Allow the user to disable the +.Em env_reset +option from the command line via the +.Fl E +option. +Additionally, environment variables set via the command line are +not subject to the restrictions imposed by +.Em env_check , +.Em env_delete , +or +.Em env_keep . +As such, only trusted users should be allowed to set variables in this manner. +This flag is +.Em off +by default. +.It shell_noargs +If set and +.Nm sudo +is invoked with no arguments it acts as if the +.Fl s +option had been given. +That is, it runs a shell as root (the shell is determined by the +.Ev SHELL +environment variable if it is set, falling back on the shell listed +in the invoking user's /etc/passwd entry if not). +This flag is +.Em off +by default. +.It stay_setuid +Normally, when +.Nm sudo +executes a command the real and effective UIDs are set to the target +user (root by default). +This option changes that behavior such that the real UID is left +as the invoking user's UID. +In other words, this makes +.Nm sudo +act as a set-user-ID wrapper. +This can be useful on systems that disable some potentially +dangerous functionality when a program is run set-user-ID. +This option is only effective on systems that support either the +.Xr setreuid 2 +or +.Xr setresuid 2 +system call. +This flag is +.Em off +by default. +.It sudoedit_checkdir +If set, +.Nm sudoedit +will check all directory components of the path to be edited for writability +by the invoking user. +Symbolic links will not be followed in writable directories and +.Nm sudoedit +will refuse to edit a file located in a writable directory. +These restrictions are not enforced when +.Nm sudoedit +is run by root. +On some systems, if all directory components of the path to be edited +are not readable by the target user, +.Nm sudoedit +will be unable to edit the file. +This flag is +.Em on +by default. +.Pp +This setting was first introduced in version 1.8.15 but initially +suffered from a race condition. +The check for symbolic links in writable intermediate directories +was added in version 1.8.16. +.It sudoedit_follow +By default, +.Nm sudoedit +will not follow symbolic links when opening files. +The +.Em sudoedit_follow +option can be enabled to allow +.Nm sudoedit +to open symbolic links. +It may be overridden on a per-command basis by the +.Em FOLLOW +and +.Em NOFOLLOW +tags. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.15 or higher. +.It syslog_pid +When logging via +.Xr syslog 3 , +include the process ID in the log entry. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.21 or higher. +.It targetpw +If set, +.Nm sudo +will prompt for the password of the user specified +by the +.Fl u +option (defaults to +.Li root ) +instead of the password of the invoking user +when running a command or editing a file. +Note that this flag precludes the use of a user-ID not listed in the passwd +database as an argument to the +.Fl u +option. +This flag is +.Em off +by default. +.It tty_tickets +If set, users must authenticate on a per-tty basis. +With this flag enabled, +.Nm sudo +will use a separate record in the time stamp file for each terminal. +If disabled, a single record is used for all login sessions. +.Pp +This option has been superseded by the +.Em timestamp_type +option. +.It umask_override +If set, +.Nm sudo +will set the umask as specified in the +.Em sudoers +file without modification. +This makes it possible to specify a umask in the +.Em sudoers +file that is more permissive than the user's own umask and matches +historical behavior. +If +.Em umask_override +is not set, +.Nm sudo +will set the umask to be the union of the user's umask and what is specified in +.Em sudoers . +This flag is +.Em @umask_override@ +by default. +.if \n(LC \{\ +.It use_loginclass +If set, +.Nm sudo +will apply the defaults specified for the target user's login class +if one exists. +Only available if +.Nm sudo +is configured with the +.Li --with-logincap +option. +This flag is +.Em off +by default. +.\} +.It use_netgroups +If set, netgroups (prefixed with +.Ql + ) , +may be used in place of a user or host. +For LDAP-based sudoers, netgroup support requires an expensive +sub-string match on the server unless the +.Sy NETGROUP_BASE +directive is present in the +.Pa @ldap_conf@ +file. +If netgroups are not needed, this option can be disabled to reduce the +load on the LDAP server. +This flag is +.Em on +by default. +.It use_pty +If set, and +.Nm sudo +is running in a terminal, the command will be run in a pseudo-terminal +(even if no I/O logging is being done). +If the +.Nm sudo +process is not attached to a terminal, +.Em use_pty +has no effect. +.Pp +A malicious program run under +.Nm sudo +may be capable of injecting commands into the user's +terminal or running a background process that retains access to the +user's terminal device even after the main program has finished +executing. +By running the command in a separate pseudo-terminal, this attack is +no longer possible. +This flag is +.Em off +by default. +.It user_command_timeouts +If set, the user may specify a timeout on the command line. +If the timeout expires before the command has exited, the +command will be terminated. +If a timeout is specified both in the +.Pa sudoers +file and on the command line, the smaller of the two timeouts will be used. +See the +.Li Timeout_Spec +section for a description of the timeout syntax. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.20 or higher. +.It utmp_runas +If set, +.Nm sudo +will store the name of the runas user when updating the utmp (or utmpx) file. +By default, +.Nm sudo +stores the name of the invoking user. +This flag is +.Em off +by default. +.It visiblepw +By default, +.Nm sudo +will refuse to run if the user must enter a password but it is not +possible to disable echo on the terminal. +If the +.Em visiblepw +flag is set, +.Nm sudo +will prompt for a password even when it would be visible on the screen. +This makes it possible to run things like +.Dq Li ssh somehost sudo ls +since by default, +.Xr ssh 1 +does +not allocate a tty when running a command. +This flag is +.Em off +by default. +.El +.Pp +.Sy Integers : +.Bl -tag -width 16n +.It closefrom +Before it executes a command, +.Nm sudo +will close all open file descriptors other than standard input, +standard output and standard error (ie: file descriptors 0-2). +The +.Em closefrom +option can be used to specify a different file descriptor at which +to start closing. +The default is +.Li 3 . +.It command_timeout +The maximum amount of time a command is allowed to run before +it is terminated. +See the +.Li Timeout_Spec +section for a description of the timeout syntax. +.Pp +This setting is only supported by version 1.8.20 or higher. +.It log_server_timeout +The maximum amount of time to wait when connecting to a log server +or waiting for a server response. +See the +.Li Timeout_Spec +section for a description of the timeout syntax. +The default value is 30 seconds. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It maxseq +The maximum sequence number that will be substituted for the +.Dq Li %{seq} +escape in the I/O log file (see the +.Em iolog_dir +description below for more information). +While the value substituted for +.Dq Li %{seq} +is in base 36, +.Em maxseq +itself should be expressed in decimal. +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. +.Pp +Once the local sequence number reaches the value of +.Em maxseq , +it will +.Dq roll over +to zero, after which +.Nm +will truncate and re-use any existing I/O log path names. +.Pp +This setting is only supported by version 1.8.7 or higher. +.It passwd_tries +The number of tries a user gets to enter his/her password before +.Nm sudo +logs the failure and exits. +The default is +.Li @passwd_tries@ . +.It syslog_maxlen +On many systems, +.Xr syslog 3 +has a relatively small log buffer. +IETF RFC 5424 states that syslog servers must support messages of +at least 480 bytes and should support messages up to 2048 bytes. +By default, +.Nm +creates log messages up to 980 bytes which corresponds to the +historic +.Bx +syslog implementation which used a 1024 byte buffer +to store the message, date, hostname and program name. +To prevent syslog messages from being truncated, +.Nm +will split up log messages that are larger than +.Em syslog_maxlen +bytes. +When a message is split, additional parts will include the string +.Dq Pq command continued +after the user name and before the continued command line arguments. +.Pp +This setting is only supported by version 1.8.19 or higher. +.El +.Pp +.Sy Integers that can be used in a boolean context : +.Bl -tag -width 16n +.It loglinelen +Number of characters per line for the file log. +This value is used to decide when to wrap lines for nicer log files. +This has no effect on the syslog log file, only the file log. +The default is +.Li @loglen@ +(use 0 or negate the option to disable word wrap). +.It passwd_timeout +Number of minutes before the +.Nm sudo +password prompt times out, or +.Li 0 +for no timeout. +The timeout may include a fractional component +if minute granularity is insufficient, for example +.Li 2.5 . +The +default is +.Li @password_timeout@ . +.It timestamp_timeout +Number of minutes that can elapse before +.Nm sudo +will ask for a passwd again. +The timeout may include a fractional component if +minute granularity is insufficient, for example +.Li 2.5 . +The default is +.Li @timeout@ . +Set this to +.Li 0 +to always prompt for a password. +If set to a value less than +.Li 0 +the user's time stamp will not expire until the system is rebooted. +This can be used to allow users to create or delete their own time stamps via +.Dq Li sudo -v +and +.Dq Li sudo -k +respectively. +.It umask +File mode creation mask to use when running the command. +Negate this option or set it to 0777 to prevent +.Nm +from changing the umask. +Unless the +.Em umask_override +flag is set, the actual umask will be the union of the +user's umask and the value of the +.Em umask +setting, which defaults to +.Li @sudo_umask@ . +This guarantees +that +.Nm sudo +never lowers the umask when running a command. +.Pp +If +.Em umask +is explicitly set in +.Em sudoers , +it will override any umask setting in PAM or login.conf. +If +.Em umask +is not set in +.Em sudoers , +the umask specified by PAM or login.conf will take precedence. +The umask setting in PAM is not used for +.Nm sudoedit , +which does not create a new PAM session. +.El +.Pp +.Sy Strings : +.Bl -tag -width 16n +.It authfail_message +Message that is displayed after a user fails to authenticate. +The message may include the +.Ql %d +escape which will expand to the number of failed password attempts. +If set, it overrides the default message, +.Li %d incorrect password attempt(s) . +.It badpass_message +Message that is displayed if a user enters an incorrect password. +The default is +.Li @badpass_message@ +unless insults are enabled. +.It editor +A colon +.Pq Ql :\& +separated list of editors path names used by +.Nm sudoedit +and +.Nm visudo . +For +.Nm sudoedit , +this list is used to find an editor when none of the +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variables are set to an editor that exists and is executable. +For +.Nm visudo , +it is used as a white list of allowed editors; +.Nm visudo +will choose the editor that matches the user's +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variable if possible, or the first editor in the +list that exists and is executable if not. +Unless invoked as +.Nm sudoedit , +.Nm sudo +does not preserve the +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variables unless they are present in the +.Em env_keep +list or the +.Em env_reset +option is disabled. +The default is +.Pa @editor@ . +.It iolog_dir +The top-level directory to use when constructing the path name for +the input/output log directory. +Only used if the +.Em log_input +or +.Em log_output +options are enabled or when the +.Li LOG_INPUT +or +.Li LOG_OUTPUT +tags are present for a command. +The session sequence number, if any, is stored in the directory. +The default is +.Pa @iolog_dir@ . +.Pp +The following percent +.Pq Ql % +escape sequences are supported: +.Bl -tag -width 4n +.It Li %{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} +expanded to the invoking user's login name +.It Li %{group} +expanded to the name of the invoking user's real group-ID +.It Li %{runas_user} +expanded to the login name of the user the command will +be run as (e.g., root) +.It Li %{runas_group} +expanded to the group name of the user the command will +be run as (e.g., wheel) +.It Li %{hostname} +expanded to the local host name without the domain name +.It Li %{command} +expanded to the base name of the command being run +.El +.Pp +In addition, any escape sequences supported by the system's +.Xr strftime 3 +function will be expanded. +.Pp +To include a literal +.Ql % +character, the string +.Ql %% +should be used. +.It iolog_file +The path name, relative to +.Em iolog_dir , +in which to store input/output logs when the +.Em log_input +or +.Em log_output +options are enabled or when the +.Li LOG_INPUT +or +.Li LOG_OUTPUT +tags are present for a command. +Note that +.Em iolog_file +may contain directory components. +The default is +.Dq Li %{seq} . +.Pp +See the +.Em iolog_dir +option above for a list of supported percent +.Pq Ql % +escape sequences. +.Pp +In addition to the escape sequences, path names that end in six or +more +.Li X Ns s +will have the +.Li X Ns s +replaced with a unique combination of digits and letters, similar to the +.Xr mktemp 3 +function. +.Pp +If the path created by concatenating +.Em iolog_dir +and +.Em iolog_file +already exists, the existing I/O log file will be truncated and +overwritten unless +.Em iolog_file +ends in six or +more +.Li X Ns s . +.It iolog_flush +If set, +.Nm sudo +will flush I/O log data to disk after each write instead of buffering it. +This makes it possible to view the logs in real-time as the program +is executing but may significantly reduce the effectiveness of I/O +log compression. +This flag is +.Em off +by default. +.Pp +This setting is only supported by version 1.8.20 or higher. +.It iolog_group +The group name to look up when setting the group-ID on new I/O log +files and directories. +If +.Em iolog_group +is not set, +the primary group-ID of the user specified by +.Em iolog_user +is used. +If neither +.Em iolog_group +nor +.Em iolog_user +are set, I/O log files and directories are created with group-ID 0. +.Pp +This setting is only supported by version 1.8.19 or higher. +.It iolog_mode +The file mode to use when creating I/O log files. +Mode bits for read and write permissions for owner, group or other +are honored, everything else is ignored. +The file permissions will always include the owner read and +write bits, even if they are not present in the specified mode. +When creating I/O log directories, search (execute) bits are added +to match the read and write bits specified by +.Em iolog_mode . +Defaults to 0600 (read and write by user only). +.Pp +This setting is only supported by version 1.8.19 or higher. +.It iolog_user +The user name to look up when setting the user and group-IDs on new +I/O log files and directories. +If +.Em iolog_group +is set, it will be used instead of the user's primary group-ID. +By default, I/O log files and directories are created with user and +group-ID 0. +.Pp +This setting can be useful when the I/O logs are stored on a Network +File System (NFS) share. +Having a dedicated user own the I/O log files means that +.Nm +does not write to the log files as user-ID 0, which is usually +not permitted by NFS. +.Pp +This setting is only supported by version 1.8.19 or higher. +.It lecture_status_dir +The directory in which +.Nm sudo +stores per-user lecture status files. +Once a user has received the lecture, a zero-length file is +created in this directory so that +.Nm sudo +will not lecture the user again. +This directory should +.Em not +be cleared when the system reboots. +The default is +.Pa @vardir@/lectured . +.if \n(PS \{\ +.It limitprivs +The default Solaris limit privileges to use when constructing a new +privilege set for a command. +This bounds all privileges of the executing process. +The default limit privileges may be overridden on a per-command basis in +.Em sudoers . +This option is only available if +.Nm +is built on Solaris 10 or higher. +.\} +.It log_server_cabundle +The path to a certificate authority bundle file, in PEM format, +to use instead of the system's default certificate authority database +when authenticating the log server. +The default is to use the system's default certificate authority database. +This setting has no effect unless +.Em log_servers +is set and the remote log server is secured with TLS. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It log_server_peer_cert +The path to the client's certificate file, in PEM format. +This setting is required when +.Em log_servers +is set and the remote log server is secured with TLS. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It log_server_peer_key +The path to the client's private key file, in PEM format. +This setting is required when +.Em log_servers +is set and the remote log server is secured with TLS. +.Pp +This setting is only supported by version 1.9.0 or higher. +.It mailsub +Subject of the mail sent to the +.Em mailto +user. +The escape +.Li %h +will expand to the host name of the machine. +Default is +.Dq Li @mailsub@ . +.It noexec_file +As of +.Nm sudo +version 1.8.1 this option is no longer supported. +The path to the noexec file should now be set in the +.Xr sudo.conf @mansectform@ +file. +.It pam_login_service +On systems that use PAM for authentication, this is the service +name used when the +.Fl i +option is specified. +The default value is +.Dq Li @pam_login_service@ . +See the description of +.Em pam_service +for more information. +.Pp +This setting is only supported by version 1.8.8 or higher. +.It pam_service +On systems that use PAM for authentication, the service name +specifies the PAM policy to apply. +This usually corresponds to an entry in the +.Pa pam.conf +file or a file in the +.Pa /etc/pam.d +directory. +The default value is +.Dq Li sudo . +.Pp +This setting is only supported by version 1.8.8 or higher. +.It passprompt +The default prompt to use when asking for a password; can be overridden via the +.Fl p +option or the +.Ev SUDO_PROMPT +environment variable. +The following percent +.Pq Ql % +escape sequences are supported: +.Bl -tag -width 4n +.It Li %H +expanded to the local host name including the domain name +(only if the machine's host name is fully qualified or the +.Em fqdn +option is set) +.It Li %h +expanded to the local host name without the domain name +.It Li %p +expanded to the user whose password is being asked for (respects the +.Em rootpw , +.Em targetpw +and +.Em runaspw +flags in +.Em sudoers ) +.It Li \&%U +expanded to the login name of the user the command will +be run as (defaults to root) +.It Li %u +expanded to the invoking user's login name +.It Li %% +two consecutive +.Li % +characters are collapsed into a single +.Li % +character +.El +.Pp +On systems that use PAM for authentication, +.Em passprompt +will only be used if the prompt provided by the PAM module matches the string +.Dq "Password: " +or +.Dq "username's Password: " . +This ensures that the +.Em passprompt +setting does not interfere with challenge-response style authentication. +The +.Em passprompt_override +flag can be used to change this behavior. +.Pp +The default value is +.Dq Li "@passprompt@" . +.if \n(PS \{\ +.It privs +The default Solaris privileges to use when constructing a new +privilege set for a command. +This is passed to the executing process via the inherited privilege set, +but is bounded by the limit privileges. +If the +.Em privs +option is specified but the +.Em limitprivs +option is not, the limit privileges of the executing process is set to +.Em privs . +The default privileges may be overridden on a per-command basis in +.Em sudoers . +This option is only available if +.Nm +is built on Solaris 10 or higher. +.\} +.if \n(SL \{\ +.It role +The default SELinux role to use when constructing a new security +context to run the command. +The default role may be overridden on a per-command basis in the +.Em sudoers +file or via command line options. +This option is only available when +.Nm sudo +is built with SELinux support. +.\} +.It runas_default +The default user to run commands as if the +.Fl u +option is not specified on the command line. +This defaults to +.Li @runas_default@ . +.It sudoers_locale +Locale to use when parsing the sudoers file, logging commands, and +sending email. +Note that changing the locale may affect how sudoers is interpreted. +Defaults to +.Dq Li C . +.It timestamp_type +.Nm +uses per-user time stamp files for credential caching. +The +.Em timestamp_type +option can be used to specify the type of time stamp record used. +It has the following possible values: +.Bl -tag -width 6n +.It global +A single time stamp record is used for all of a user's login sessions, +regardless of the terminal or parent process ID. +An additional record is used to serialize password prompts when +.Nm sudo +is used multiple times in a pipeline, but this does not affect authentication. +.It ppid +A single time stamp record is used for all processes with the same parent +process ID (usually the shell). +Commands run from the same shell (or other common parent process) +will not require a password for +.Em timestamp_timeout +minutes +.Po +.Li @timeout@ +by default +.Pc . +Commands run via +.Nm sudo +with a different parent process ID, for example from a shell script, +will be authenticated separately. +.It tty +One time stamp record is used for each terminal, +which means that a user's login sessions are authenticated separately. +If no terminal is present, the behavior is the same as +.Em ppid . +Commands run from the same terminal will not require a password for +.Em timestamp_timeout +minutes +.Po +.Li @timeout@ +by default +.Pc . +.It kernel +The time stamp is stored in the kernel as an attribute of the terminal +device. +If no terminal is present, the behavior is the same as +.Em ppid . +Negative +.Em timestamp_timeout +values are not supported and positive values are limited to a maximum +of 60 minutes. +This is currently only supported on +.Ox . +.El +.Pp +The default value is +.Em @timestamp_type@ . +.Pp +This setting is only supported by version 1.8.21 or higher. +.It timestampdir +The directory in which +.Nm sudo +stores its time stamp files. +This directory should be cleared when the system reboots. +The default is +.Pa @rundir@/ts . +.It timestampowner +The owner of the lecture status directory, time stamp directory and all +files stored therein. +The default is +.Li root . +.if \n(SL \{\ +.It type +The default SELinux type to use when constructing a new security +context to run the command. +The default type may be overridden on a per-command basis in the +.Em sudoers +file or via command line options. +This option is only available when +.Nm sudo +is built with SELinux support. +.\} +.El +.Pp +.Sy Strings that can be used in a boolean context : +.Bl -tag -width 12n +.It env_file +The +.Em env_file +option specifies the fully qualified path to a file containing variables +to be set in the environment of the program being run. +Entries in this file should either be of the form +.Dq Li VARIABLE=value +or +.Dq Li export VARIABLE=value . +The value may optionally be enclosed in single or double quotes. +Variables in this file are only added if the variable does not already +exist in the environment. +This file is considered to be part of the security policy, +its contents are not subject to other +.Nm sudo +environment restrictions such as +.Em env_keep +and +.Em env_check . +.It exempt_group +Users in this group are exempt from password and PATH requirements. +The group name specified should not include a +.Li % +prefix. +This is not set by default. +.It fdexec +Determines whether +.Nm sudo +will execute a command by its path or by an open file descriptor. +It has the following possible values: +.Bl -tag -width 6n +.It always +Always execute by file descriptor. +.It never +Never execute by file descriptor. +.It digest_only +Only execute by file descriptor if the command has an associated digest +in the +.Em sudoers +file. +.El +.Pp +The default value is +.Em digest_only . +This avoids a time of check versus time of use race condition when +the command is located in a directory writable by the invoking user. +.Pp +Note that +.Em fdexec +will change the first element of the argument vector for scripts +($0 in the shell) due to the way the kernel runs script interpreters. +Instead of being a normal path, it will refer to a file descriptor. +For example, +.Pa /dev/fd/4 +on Solaris and +.Pa /proc/self/fd/4 +on Linux. +A workaround is to use the +.Dv SUDO_COMMAND +environment variable instead. +.Pp +The +.Em fdexec +setting is only used when the command is matched by path name. +It has no effect if the command is matched by the built-in +.Sy ALL +alias. +.Pp +This setting is only supported by version 1.8.20 or higher. +If the operating system does not support the +.Xr fexecve 2 +system call, this setting has no effect. +.It group_plugin +A string containing a +.Nm +group plugin with optional arguments. +The string should consist of the plugin +path, either fully-qualified or relative to the +.Pa @plugindir@ +directory, followed by any configuration arguments the plugin requires. +These arguments (if any) will be passed to the plugin's initialization function. +If arguments are present, the string must be enclosed in double quotes +.Pq \&"" . +.Pp +For more information see +.Sx "GROUP PROVIDER PLUGINS" . +.It lecture +This option controls when a short lecture will be printed along with +the password prompt. +It has the following possible values: +.Bl -tag -width 6n +.It always +Always lecture the user. +.It never +Never lecture the user. +.It once +Only lecture the user the first time they run +.Nm sudo . +.El +.Pp +If no value is specified, a value of +.Em once +is implied. +Negating the option results in a value of +.Em never +being used. +The default value is +.Em @lecture@ . +.It lecture_file +Path to a file containing an alternate +.Nm sudo +lecture that will be used in place of the standard lecture if the named +file exists. +By default, +.Nm sudo +uses a built-in lecture. +.It listpw +This option controls when a password will be required when a user runs +.Nm sudo +with the +.Fl l +option. +It has the following possible values: +.Bl -tag -width 8n +.It all +All the user's +.Em sudoers +file entries for the current host must have +the +.Li NOPASSWD +flag set to avoid entering a password. +.It always +The user must always enter a password to use the +.Fl l +option. +.It any +At least one of the user's +.Em sudoers +file entries for the current host +must have the +.Li NOPASSWD +flag set to avoid entering a password. +.It never +The user need never enter a password to use the +.Fl l +option. +.El +.Pp +If no value is specified, a value of +.Em any +is implied. +Negating the option results in a value of +.Em never +being used. +The default value is +.Em any . +.It log_format +The event log format. +Supported log formats are: +.Bl -tag -width 8n +.It json +Logs in JSON format. +JSON log entries contain the full user details as well as the execution +environment if the command was allowed. +Due to limitations of the protocol, JSON events sent via +.Em syslog +may be truncated. +.It sudo +Traditional sudo-style logs, see +.Sx "LOG FORMAT" +for a description of the log file format. +.El +.Pp +This setting affects logs sent via +.Xr syslog 3 +as well as the file specified by the +.Em logfile +setting, if any. +The default value is +.Em sudo . +.It logfile +Path to the +.Nm sudo +log file (not the syslog log file). +Setting a path turns on logging to a file; +negating this option turns it off. +By default, +.Nm sudo +logs via syslog. +.It mailerflags +Flags to use when invoking mailer. +Defaults to +.Fl t . +.It mailerpath +Path to mail program used to send warning mail. +Defaults to the path to sendmail found at configure time. +.It mailfrom +Address to use for the +.Dq from +address when sending warning and error mail. +The address should be enclosed in double quotes +.Pq \&"" +to protect against +.Nm sudo +interpreting the +.Li @ +sign. +Defaults to the name of the user running +.Nm sudo . +.It mailto +Address to send warning and error mail to. +The address should be enclosed in double quotes +.Pq \&"" +to protect against +.Nm sudo +interpreting the +.Li @ +sign. +Defaults to +.Li @mailto@ . +.It restricted_env_file +The +.Em restricted_env_file +option specifies the fully qualified path to a file containing variables +to be set in the environment of the program being run. +Entries in this file should either be of the form +.Dq Li VARIABLE=value +or +.Dq Li export VARIABLE=value . +The value may optionally be enclosed in single or double quotes. +Variables in this file are only added if the variable does not already +exist in the environment. +Unlike +.Em env_file , +the file's contents are not trusted and are processed in a manner +similar to that of the invoking user's environment. +If +.Em env_reset +is enabled, variables in the file will only be added if they are +matched by either the +.Em env_check +or +.Em env_keep +list. +If +.Em env_reset +is disabled, variables in the file are added as long as they +are not matched by the +.Em env_delete +list. +In either case, the contents of +.Em restricted_env_file +are processed before the contents of +.Em env_file . +.It runchroot +If set, +.Nm sudo +will use this value for the root directory when running a command. +The special value +.Dq * +will allow the user to specify the root directory via +.Nm sudo Ns 's +.Fl R +option. +See the +.Sx Chroot_Spec +section for more details. +.Pp +It is only possible to use +.Em runchroot +as a command-specific Defaults setting if the command exists with +the same path both inside and outside the chroot jail. +This restriction does not apply to generic, host or user-based +Defaults settings or to a +.Em Cmnd_Spec +that includes a +.Em Chroot_Spec . +.Pp +This setting is only supported by version 1.9.3 or higher. +.It runcwd +If set, +.Nm sudo +will use this value for the working directory when running a command. +The special value +.Dq * +will allow the user to specify the working directory via +.Nm sudo Ns 's +.Fl D +option. +See the +.Sx Chdir_Spec +section for more details. +.Pp +This setting is only supported by version 1.9.3 or higher. +.It secure_path +If set, +.Nm sudo +will use this value in place of the user's +.Ev PATH +environment variable. +This option can be used to reset the +.Ev PATH +to a known good value that contains directories for system administrator +commands such as +.Pa /usr/sbin . +.Pp +Users in the group specified by the +.Em exempt_group +option are not affected by +.Em secure_path . +This option is @secure_path@ by default. +.It syslog +Syslog facility if syslog is being used for logging (negate to +disable syslog logging). +Defaults to +.Li @logfac@ . +.Pp +The following syslog facilities are supported: +.Sy authpriv +(if your +OS supports it), +.Sy auth , +.Sy daemon , +.Sy user , +.Sy local0 , +.Sy local1 , +.Sy local2 , +.Sy local3 , +.Sy local4 , +.Sy local5 , +.Sy local6 , +and +.Sy local7 . +.It syslog_badpri +Syslog priority to use when the user is not allowed to run a command or +when authentication is unsuccessful. +Defaults to +.Li @badpri@ . +.Pp +The following syslog priorities are supported: +.Sy alert , +.Sy crit , +.Sy debug , +.Sy emerg , +.Sy err , +.Sy info , +.Sy notice , +.Sy warning , +and +.Sy none . +Negating the option or setting it to a value of +.Sy none +will disable logging of unsuccessful commands. +.It syslog_goodpri +Syslog priority to use when the user is allowed to run a command and +authentication is successful. +Defaults to +.Li @goodpri@ . +.Pp +See +.Em syslog_badpri +for the list of supported syslog priorities. +Negating the option or setting it to a value of +.Sy none +will disable logging of successful commands. +.It verifypw +This option controls when a password will be required when a user runs +.Nm sudo +with the +.Fl v +option. +It has the following possible values: +.Bl -tag -width 6n +.It all +All the user's +.Em sudoers +file entries for the current host must have the +.Li NOPASSWD +flag set to avoid entering a password. +.It always +The user must always enter a password to use the +.Fl v +option. +.It any +At least one of the user's +.Em sudoers +file entries for the current host must have the +.Li NOPASSWD +flag set to avoid entering a password. +.It never +The user need never enter a password to use the +.Fl v +option. +.El +.Pp +If no value is specified, a value of +.Em all +is implied. +Negating the option results in a value of +.Em never +being used. +The default value is +.Em all . +.El +.Pp +.Sy Lists that can be used in a boolean context : +.Bl -tag -width 16n +.It env_check +Environment variables to be removed from the user's environment +unless they are considered +.Dq safe . +For all variables except +.Li TZ , +.Dq safe +means that the variable's value does not contain any +.Ql % +or +.Ql / +characters. +This can be used to guard against printf-style format vulnerabilities +in poorly-written programs. +The +.Li TZ +variable is considered unsafe if any of the following are true: +.Bl -bullet -width 1n +.It +It consists of a fully-qualified path name, +optionally prefixed with a colon +.Pq Ql :\& , +that does not match the location of the +.Pa zoneinfo +directory. +.It +It contains a +.Pa .. +path element. +.It +It contains white space or non-printable characters. +.It +It is longer than the value of +.Li PATH_MAX . +.El +.Pp +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using +the +.Li = , +.Li += , +.Li -= , +and +.Li \&! +operators respectively. +Regardless of whether the +.Li env_reset +option is enabled or disabled, variables specified by +.Li env_check +will be preserved in the environment if they pass the aforementioned check. +The global list of environment variables to check is displayed when +.Nm sudo +is run by root with +the +.Fl V +option. +.It env_delete +Environment variables to be removed from the user's environment when the +.Em env_reset +option is not in effect. +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using the +.Li = , +.Li += , +.Li -= , +and +.Li \&! +operators respectively. +The global list of environment variables to remove is displayed when +.Nm sudo +is run by root with the +.Fl V +option. +Note that many operating systems will remove potentially dangerous +variables from the environment of any set-user-ID process (such as +.Nm sudo ) . +.It env_keep +Environment variables to be preserved in the user's environment when the +.Em env_reset +option is in effect. +This allows fine-grained control over the environment +.Nm sudo Ns -spawned +processes will receive. +The argument may be a double-quoted, space-separated list or a +single value without double-quotes. +The list can be replaced, added to, deleted from, or disabled by using the +.Li = , +.Li += , +.Li -= , +and +.Li \&! +operators respectively. +The global list of variables to keep +is displayed when +.Nm sudo +is run by root with the +.Fl V +option. +.Pp +Preserving the +.Ev HOME +environment variable has security implications since many programs use it +when searching for configuration or data files. +Adding +.Ev HOME +to +.Em env_keep +may enable a user to run unrestricted commands via +.Nm sudo +and is strongly discouraged. +Users wishing to edit files with +.Nm sudo +should run +.Nm sudoedit +(or +.Nm sudo Fl e ) +to get their accustomed editor configuration instead of +invoking the editor directly. +.It log_servers +A list of one or more servers to use for remote event and I/O log storage, +separated by white space. +Log servers must be running +.Nm sudo_logsrvd +or another service that implements the protocol described by +.Xr sudo_logsrv.proto @mansectform@ . +.Pp +Server addresses should be of the form +.Dq host Ns Oo : Ns port Oc Ns Op (tls) . +The host portion may be a host name, an IPv4 address, or an IPv6 address +in square brackets. +.Pp +If the optional +.Em tls +flag is present, the connection will be secured +with Transport Layer Security (TLS) version 1.2 or 1.3. +Versions of TLS prior to 1.2 are not supported. +.Pp +If a port is specified, it may either be a port number or a well-known +service name as defined by the system service name database. +If no port is specified, port 30343 will be used for plaintext +connections and port 30344 will be used for TLS connections. +.Pp +When +.Em log_servers +is set, event log data will be logged both locally (see the +.Em syslog +and +.Em log_file +settings) as well as remotely, but I/O log data will only be logged remotely. +If multiple hosts are specified, they will be attempted in reverse order. +If no log servers are available, the user will not be able to run +a command unless either the +.Em ignore_iolog_errors +flag (I/O logging enabled) or the +.Em ignore_log_errors +flag (I/O logging disabled) is set. +Likewise, if the connection to the log server is interrupted while +.Nm sudo +is running, the command will be terminated unless the +.Em ignore_iolog_errors +flag (I/O logging enabled) or the +.Em ignore_log_errors +flag (I/O logging disabled) is set. +.Pp +This setting is only supported by version 1.9.0 or higher. +.El +.Sh GROUP PROVIDER PLUGINS +The +.Nm +plugin supports its own plugin interface to allow non-Unix +group lookups which can query a group source other +than the standard Unix group database. +This can be used to implement support for the +.Li nonunix_group +syntax described earlier. +.Pp +Group provider plugins are specified via the +.Em group_plugin +setting. +The argument to +.Em group_plugin +should consist of the plugin path, either fully-qualified or relative to the +.Pa @plugindir@ +directory, followed by any configuration options the plugin requires. +These options (if specified) will be passed to the plugin's initialization +function. +If options are present, the string must be enclosed in double quotes +.Pq \&"" . +.Pp +The following group provider plugins are installed by default: +.Bl -tag -width 8n +.It group_file +The +.Em group_file +plugin supports an alternate group file that uses the same syntax as the +.Pa /etc/group +file. +The path to the group file should be specified as an option +to the plugin. +For example, if the group file to be used is +.Pa /etc/sudo-group : +.Bd -literal +Defaults group_plugin="group_file.so /etc/sudo-group" +.Ed +.It system_group +The +.Em system_group +plugin supports group lookups via the standard C library functions +.Fn getgrnam +and +.Fn getgrid . +This plugin can be used in instances where the user belongs to +groups not present in the user's supplemental group vector. +This plugin takes no options: +.Bd -literal +Defaults group_plugin=system_group.so +.Ed +.El +.Pp +The group provider plugin API is described in detail in +.Xr sudo_plugin @mansectform@ . +.Sh LOG FORMAT +.Nm +can log events in either JSON or +.Em sudo +format, +this section describes the +.Em sudo +log format. +Depending on +.Em sudoers +configuration, +.Nm +can log events via +.Xr syslog 3 , +to a local log file, or both. +The log format is almost identical in both cases. +.Ss Accepted command log entries +Commands that sudo runs are logged using the following format (split +into multiple lines for readability): +.Bd -literal -offset 4n +date hostname progname: username : TTY=ttyname ; PWD=cwd ; \e + USER=runasuser ; GROUP=runasgroup ; TSID=logid ; \e + ENV=env_vars COMMAND=command +.Ed +.Pp +Where the fields are as follows: +.Bl -tag -width 12n +.It date +The date the command was run. +Typically, this is in the format +.Dq MMM, DD, HH:MM:SS . +If logging via +.Xr syslog 3 , +the actual date format is controlled by the syslog daemon. +If logging to a file and the +.Em log_year +option is enabled, +the date will also include the year. +.It hostname +The name of the host +.Nm sudo +was run on. +This field is only present when logging via +.Xr syslog 3 . +.It progname +The name of the program, usually +.Em sudo +or +.Em sudoedit . +This field is only present when logging via +.Xr syslog 3 . +.It username +The login name of the user who ran +.Nm sudo . +.It ttyname +The short name of the terminal (e.g., +.Dq console , +.Dq tty01 , +or +.Dq pts/0 ) +.Nm sudo +was run on, or +.Dq unknown +if there was no terminal present. +.It cwd +The current working directory that +.Nm sudo +was run in. +.It runasuser +The user the command was run as. +.It runasgroup +The group the command was run as if one was specified on the command line. +.It logid +An I/O log identifier that can be used to replay the command's output. +This is only present when the +.Em log_input +or +.Em log_output +option is enabled. +.It env_vars +A list of environment variables specified on the command line, +if specified. +.It command +The actual command that was executed. +.El +.Pp +Messages are logged using the locale specified by +.Em sudoers_locale , +which defaults to the +.Dq Li C +locale. +.Ss Denied command log entries +If the user is not allowed to run the command, the reason for the denial +will follow the user name. +Possible reasons include: +.Bl -tag -width 4 +.It user NOT in sudoers +The user is not listed in the +.Em sudoers +file. +.It user NOT authorized on host +The user is listed in the +.Em sudoers +file but is not allowed to run commands on the host. +.It command not allowed +The user is listed in the +.Em sudoers +file for the host but they are not allowed to run the specified command. +.It 3 incorrect password attempts +The user failed to enter their password after 3 tries. +The actual number of tries will vary based on the number of +failed attempts and the value of the +.Em passwd_tries +option. +.It a password is required +The +.Fl n +option was specified but a password was required. +.It sorry, you are not allowed to set the following environment variables +The user specified environment variables on the command line that +were not allowed by +.Em sudoers . +.El +.Ss Error log entries +If an error occurs, +.Nm +will log a message and, in most cases, send a message to the +administrator via email. +Possible errors include: +.Bl -tag -width 4 +.It parse error in @sysconfdir@/sudoers near line N +.Nm +encountered an error when parsing the specified file. +In some cases, the actual error may be one line above or below the +line number listed, depending on the type of error. +.It problem with defaults entries +The +.Em sudoers +file contains one or more unknown Defaults settings. +This does not prevent +.Nm sudo +from running, but the +.Em sudoers +file should be checked using +.Nm visudo . +.It timestamp owner (username): \&No such user +The time stamp directory owner, as specified by the +.Em timestampowner +setting, could not be found in the password database. +.It unable to open/read @sysconfdir@/sudoers +The +.Em sudoers +file could not be opened for reading. +This can happen when the +.Em sudoers +file is located on a remote file system that maps user-ID 0 to +a different value. +Normally, +.Nm +tries to open the +.Em sudoers +file using group permissions to avoid this problem. +Consider either changing the ownership of +.Pa @sysconfdir@/sudoers +or adding an argument like +.Dq sudoers_uid=N +(where +.Sq N +is the user-ID that owns the +.Em sudoers +file) to the end of the +.Nm +.Li Plugin +line in the +.Xr sudo.conf @mansectform@ +file. +.It unable to stat @sysconfdir@/sudoers +The +.Pa @sysconfdir@/sudoers +file is missing. +.It @sysconfdir@/sudoers is not a regular file +The +.Pa @sysconfdir@/sudoers +file exists but is not a regular file or symbolic link. +.It @sysconfdir@/sudoers is owned by uid N, should be 0 +The +.Em sudoers +file has the wrong owner. +If you wish to change the +.Em sudoers +file owner, please add +.Dq sudoers_uid=N +(where +.Sq N +is the user-ID that owns the +.Em sudoers +file) to the +.Nm +.Li Plugin +line in the +.Xr sudo.conf @mansectform@ +file. +.It @sysconfdir@/sudoers is world writable +The permissions on the +.Em sudoers +file allow all users to write to it. +The +.Em sudoers +file must not be world-writable, the default file mode +is 0440 (readable by owner and group, writable by none). +The default mode may be changed via the +.Dq sudoers_mode +option to the +.Nm +.Li Plugin +line in the +.Xr sudo.conf @mansectform@ +file. +.It @sysconfdir@/sudoers is owned by gid N, should be 1 +The +.Em sudoers +file has the wrong group ownership. +If you wish to change the +.Em sudoers +file group ownership, please add +.Dq sudoers_gid=N +(where +.Sq N +is the group-ID that owns the +.Em sudoers +file) to the +.Nm +.Li Plugin +line in the +.Xr sudo.conf @mansectform@ +file. +.It unable to open @rundir@/ts/username +.Nm +was unable to read or create the user's time stamp file. +This can happen when +.Em timestampowner +is set to a user other than root and the mode on +.Pa @rundir@ +is not searchable by group or other. +The default mode for +.Pa @rundir@ +is 0711. +.It unable to write to @rundir@/ts/username +.Nm +was unable to write to the user's time stamp file. +.It @rundir@/ts is owned by uid X, should be Y +The time stamp directory is owned by a user other than +.Em timestampowner . +This can occur when the value of +.Em timestampowner +has been changed. +.Nm +will ignore the time stamp directory until the owner is corrected. +.It @rundir@/ts is group writable +The time stamp directory is group-writable; it should be writable only by +.Em timestampowner . +The default mode for the time stamp directory is 0700. +.Nm +will ignore the time stamp directory until the mode is corrected. +.El +.Ss Notes on logging via syslog +By default, +.Nm +logs messages via +.Xr syslog 3 . +The +.Em date , +.Em hostname , +and +.Em progname +fields are added by the system's +.Fn syslog +function, not +.Nm +itself. +As such, they may vary in format on different systems. +.Pp +The maximum size of syslog messages varies from system to system. +The +.Em syslog_maxlen +setting can be used to change the maximum syslog message size +from the default value of 980 bytes. +For more information, see the description of +.Em syslog_maxlen . +.Ss Notes on logging to a file +If the +.Em logfile +option is set, +.Nm +will log to a local file, such as +.Pa /var/log/sudo . +When logging to a file, +.Nm +uses a format similar to +.Xr syslog 3 , +with a few important differences: +.Bl -enum +.It +The +.Em progname +and +.Em hostname +fields are not present. +.It +If the +.Em log_year +option is enabled, +the date will also include the year. +.It +Lines that are longer than +.Em loglinelen +characters (80 by default) are word-wrapped and continued on the +next line with a four character indent. +This makes entries easier to read for a human being, but makes it +more difficult to use +.Xr grep 1 +on the log files. +If the +.Em loglinelen +option is set to 0 (or negated with a +.Ql \&! ) , +word wrap will be disabled. +.El +.Sh I/O LOG FILES +When I/O logging is enabled, +.Nm sudo +will run the command in a pseudo-terminal and log all user input and/or output, +depending on which options are enabled. +I/O can be logged either to the local machine or to a remote log server. +For local logs, I/O is logged to the directory specified by the +.Em iolog_dir +option +.Po +.Pa @iolog_dir@ +by default +.Pc +using a unique session ID that is included in the +.Nm sudo +log line, prefixed with +.Dq Li TSID= . +The +.Em iolog_file +option may be used to control the format of the session ID. +For remote logs, the +.Em log_servers +setting is used to specify one or more log servers running +.Nm sudo_logsrvd +or another server that implements the protocol described by +.Xr sudo_logsrv.proto @mansectform@ . +.Pp +For both local and remote I/O logs, each log is stored in a separate +directory that contains the following files: +.Bl -tag -width 8n +.It Pa log +A text file containing information about the command. +The first line consists of the following colon-delimited fields: +the time the command was run, the name of the user +who ran +.Nm sudo , +the name of the target user, the name of the target group (optional), +the terminal that +.Nm sudo +was run from, and the number of lines and columns of the terminal. +The second and third lines contain the working directory the command +was run from and the path name of the command itself (with arguments +if present). +.It Pa log.json +A JSON-formatted file containing information about the command. +This is similar to the +.Pa log +file but contains additional information and is easily extensible. +The +.Pa log.json +file will be used by +.Xr sudoreplay @mansectsu@ +in preference to the +.Pa log +file if it exists. +The file may contain the following elements: +.Bl -tag -width 8n +.It timestamp +A JSON object containing time the command was run. +It consists of two values, +.Em seconds +and +.Em nanoseconds . +.It columns +The number of columns of the terminal the command ran on, or zero +if no terminal was present. +.It command +The fully-qualified path of the command that was run. +.It lines +The number of lines of the terminal the command ran on, or zero +if no terminal was present. +.It runargv +A JSON array representing the command's argument vector as passed to the +.Xr execve 2 +system call. +.It runenv +A JSON array representing the command's environment as passed to the +.Xr execve 2 +system call. +.It rungid +The group ID the command ran as. +This element is only present when the user specifies a group on the +command line. +.It rungroup +The name of the group the command ran as. +This element is only present when the user specifies a group on the +command line. +.It runuid +The user ID the command ran as. +.It runuser +The name of the user the command ran as. +.It submitcwd +The current working directory at the time +.Nm sudo +was run. +.It submithost +The name of the host the command was run on. +.It submituser +The name of the user who ran the command via +.Nm sudo . +.It ttyname +The path name of the terminal the user invoked +.Nm sudo +from. +If the command was run in a pseudo-terminal, +.Em ttyname +will be different from the terminal the command actually ran in. +.El +.It Pa timing +Timing information used to replay the session. +Each line consists of the I/O log entry type and amount of time +since the last entry, followed by type-specific data. +The I/O log entry types and their corresponding type-specific data are: +.Pp +.Bl -tag -width 4n -compact +.It 0 +standard input, number of bytes in the entry +.It 1 +standard output, number of bytes in the entry +.It 2 +standard error, number of bytes in the entry +.It 3 +terminal input, number of bytes in the entry +.It 4 +terminal output, number of bytes in the entry +.It 5 +window change, new number lines and columns +.It 6 +bug compatibility for +.Nm sudo +1.8.7 terminal output +.It 7 +command suspend or resume, signal received +.El +.It Pa ttyin +Raw input from the user's terminal, exactly as it was received. +No post-processing is performed. +For manual viewing, you may wish to convert carriage return characters +in the log to line feeds. +For example: +.Ql gunzip -c ttyin | tr \&"\er\&" \&"\en\&" +.It Pa stdin +The standard input when no terminal is present, or input redirected from +a pipe or file. +.It Pa ttyout +Output from the pseudo-terminal (what the command writes to the screen). +Note that terminal-specific post-processing is performed before the +data is logged. +This means that, for example, line feeds are usually converted to +line feed/carriage return pairs and tabs may be expanded to spaces. +.It Pa stdout +The standard output when no terminal is present, or output redirected to +a pipe or file. +.It Pa stderr +The standard error redirected to a pipe or file. +.El +.Pp +All files other than +.Pa log +are compressed in gzip format unless the +.Em compress_io +flag has been disabled. +Due to buffering, it is not normally possible to display the I/O logs in +real-time as the program is executing. +The I/O log data will not be complete until the program run by +.Nm sudo +has exited or has been terminated by a signal. +The +.Em iolog_flush +flag can be used to disable buffering, in which case I/O log data +is written to disk as soon as it is available. +The output portion of an I/O log file can be viewed with the +.Xr sudoreplay @mansectsu@ +utility, which can also be used to list or search the available logs. +.Pp +Note that user input may contain sensitive information such as +passwords (even if they are not echoed to the screen), which will +be stored in the log file unencrypted. +In most cases, logging the command output via +.Em log_output +or +.Li LOG_OUTPUT +is all that is required. +.Pp +Since each session's I/O logs are stored in a separate directory, +traditional log rotation utilities cannot be used to limit the +number of I/O logs. +The simplest way to limit the number of I/O is by setting the +.Em maxseq +option to the maximum number of logs you wish to store. +Once the I/O log sequence number reaches +.Em maxseq , +it will be reset to zero and +.Nm +will truncate and re-use any existing I/O logs. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +Sudo front end configuration +.It Pa @sysconfdir@/sudoers +List of who can run what +.It Pa /etc/group +Local groups file +.It Pa /etc/netgroup +List of network groups +.It Pa @iolog_dir@ +I/O log files +.It Pa @rundir@/ts +Directory containing time stamps for the +.Nm +security policy +.It Pa @vardir@/lectured +Directory containing lecture status files for the +.Nm +security policy +.It Pa /etc/environment +Initial environment for +.Fl i +mode on AIX and Linux systems +.El +.Sh EXAMPLES +Below are example +.Em sudoers +file entries. +Admittedly, some of these are a bit contrived. +First, we allow a few environment variables to pass and then define our +.Em aliases : +.Bd -literal +# Run X applications through sudo; HOME is used to find the +# .Xauthority file. Note that other programs use HOME to find +# configuration files and this may lead to privilege escalation! +Defaults env_keep += "DISPLAY HOME" + +# User alias specification +User_Alias FULLTIMERS = millert, mikef, dowdy +User_Alias PARTTIMERS = bostley, jwfox, crawl +User_Alias WEBADMIN = will, wendy, wim + +# Runas alias specification +Runas_Alias OP = root, operator +Runas_Alias DB = oracle, sybase +Runas_Alias ADMINGRP = adm, oper + +# Host alias specification +Host_Alias SPARC = bigtime, eclipse, moet, anchor :\e + SGI = grolsch, dandelion, black :\e + ALPHA = widget, thalamus, foobar :\e + HPPA = boa, nag, python +Host_Alias CUNETS = 128.138.0.0/255.255.0.0 +Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0 +Host_Alias SERVERS = primary, mail, www, ns +Host_Alias CDROM = orion, perseus, hercules + +# Cmnd alias specification +Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e + /usr/sbin/restore, /usr/sbin/rrestore,\e + sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e + /home/operator/bin/start_backups +Cmnd_Alias KILL = /usr/bin/kill +Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm +Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown +Cmnd_Alias HALT = /usr/sbin/halt +Cmnd_Alias REBOOT = /usr/sbin/reboot +Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh,\e + /usr/local/bin/tcsh, /usr/bin/rsh,\e + /usr/local/bin/zsh +Cmnd_Alias SU = /usr/bin/su +Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less +.Ed +.Pp +Here we override some of the compiled in default values. +We want +.Nm sudo +to log via +.Xr syslog 3 +using the +.Em auth +facility in all cases and for commands to be run with +the target user's home directory as the working directory. +We don't want to subject the full time staff to the +.Nm sudo +lecture and we want to allow them to run commands in a +.Xr chroot 2 +.Dq sandbox +via the +.Fl R +option. +User +.Sy millert +need not provide a password and we don't want to reset the +.Ev LOGNAME +or +.Ev USER +environment variables when running commands as root. +Additionally, on the machines in the +.Em SERVERS +.Li Host_Alias , +we keep an additional local log file and make sure we log the year +in each log line since the log entries will be kept around for several years. +Lastly, we disable shell escapes for the commands in the PAGERS +.Li Cmnd_Alias +.Po +.Pa /usr/bin/more , +.Pa /usr/bin/pg +and +.Pa /usr/bin/less +.Pc . +Note that this will not effectively constrain users with +.Nm sudo +.Sy ALL +privileges. +.Bd -literal +# Override built-in defaults +Defaults syslog=auth,runcwd=~ +Defaults>root !set_logname +Defaults:FULLTIMERS !lecture,runchroot=* +Defaults:millert !authenticate +Defaults@SERVERS log_year, logfile=/var/log/sudo.log +Defaults!PAGERS noexec +.Ed +.Pp +The +.Em User specification +is the part that actually determines who may run what. +.Bd -literal +root ALL = (ALL) ALL +%wheel ALL = (ALL) ALL +.Ed +.Pp +We let +.Sy root +and any user in group +.Sy wheel +run any command on any host as any user. +.Bd -literal +FULLTIMERS ALL = NOPASSWD: ALL +.Ed +.Pp +Full time sysadmins +.Po +.Sy millert , +.Sy mikef , +and +.Sy dowdy +.Pc +may run any command on any host without authenticating themselves. +.Bd -literal +PARTTIMERS ALL = ALL +.Ed +.Pp +Part time sysadmins +.Sy bostley , +.Sy jwfox , +and +.Sy crawl ) +may run any command on any host but they must authenticate themselves +first (since the entry lacks the +.Li NOPASSWD +tag). +.Bd -literal +jack CSNETS = ALL +.Ed +.Pp +The user +.Sy jack +may run any command on the machines in the +.Em CSNETS +alias (the networks +.Li 128.138.243.0 , +.Li 128.138.204.0 , +and +.Li 128.138.242.0 ) . +Of those networks, only +.Li 128.138.204.0 +has an explicit netmask (in CIDR notation) indicating it is a class C network. +For the other networks in +.Em CSNETS , +the local machine's netmask will be used during matching. +.Bd -literal +lisa CUNETS = ALL +.Ed +.Pp +The user +.Sy lisa +may run any command on any host in the +.Em CUNETS +alias (the class B network +.Li 128.138.0.0 ) . +.Bd -literal +operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\e + sudoedit /etc/printcap, /usr/oper/bin/ +.Ed +.Pp +The +.Sy operator +user may run commands limited to simple maintenance. +Here, those are commands related to backups, killing processes, the +printing system, shutting down the system, and any commands in the +directory +.Pa /usr/oper/bin/ . +Note that one command in the +.Li DUMPS +Cmnd_Alias includes a sha224 digest, +.Pa /home/operator/bin/start_backups . +This is because the directory containing the script is writable by the +operator user. +If the script is modified (resulting in a digest mismatch) it will no longer +be possible to run it via +.Nm sudo . +.Bd -literal +joe ALL = /usr/bin/su operator +.Ed +.Pp +The user +.Sy joe +may only +.Xr su 1 +to operator. +.Bd -literal +pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd *root* + +%opers ALL = (: ADMINGRP) /usr/sbin/ +.Ed +.Pp +Users in the +.Sy opers +group may run commands in +.Pa /usr/sbin/ +as themselves +with any group in the +.Em ADMINGRP +.Li Runas_Alias +(the +.Sy adm +and +.Sy oper +groups). +.Pp +The user +.Sy pete +is allowed to change anyone's password except for +root on the +.Em HPPA +machines. +Because command line arguments are matched as a single, +concatenated string, the +.Ql * +wildcard will match +.Em multiple +words. +This example assumes that +.Xr passwd 1 +does not take multiple user names on the command line. +Note that on GNU systems, options to +.Xr passwd 1 +may be specified after the user argument. +As a result, this rule will also allow: +.Bd -literal -offset 4n +passwd username --expire +.Ed +.Pp +which may not be desirable. +.Bd -literal +bob SPARC = (OP) ALL : SGI = (OP) ALL +.Ed +.Pp +The user +.Sy bob +may run anything on the +.Em SPARC +and +.Em SGI +machines as any user listed in the +.Em OP +.Li Runas_Alias +.Po +.Sy root +and +.Sy operator . +.Pc +.Bd -literal +jim +biglab = ALL +.Ed +.Pp +The user +.Sy jim +may run any command on machines in the +.Em biglab +netgroup. +.Nm sudo +knows that +.Dq biglab +is a netgroup due to the +.Ql + +prefix. +.Bd -literal ++secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser +.Ed +.Pp +Users in the +.Sy secretaries +netgroup need to help manage the printers as well as add and remove users, +so they are allowed to run those commands on all machines. +.Bd -literal +fred ALL = (DB) NOPASSWD: ALL +.Ed +.Pp +The user +.Sy fred +can run commands as any user in the +.Em DB +.Li Runas_Alias +.Po +.Sy oracle +or +.Sy sybase +.Pc +without giving a password. +.Bd -literal +john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root* +.Ed +.Pp +On the +.Em ALPHA +machines, user +.Sy john +may su to anyone except root but he is not allowed to specify any options +to the +.Xr su 1 +command. +.Bd -literal +jen ALL, !SERVERS = ALL +.Ed +.Pp +The user +.Sy jen +may run any command on any machine except for those in the +.Em SERVERS +.Li Host_Alias +(primary, mail, www and ns). +.Bd -literal +jill SERVERS = /usr/bin/, !SU, !SHELLS +.Ed +.Pp +For any machine in the +.Em SERVERS +.Li Host_Alias , +.Sy jill +may run +any commands in the directory +.Pa /usr/bin/ +except for those commands +belonging to the +.Em SU +and +.Em SHELLS +.Li Cmnd_Aliases . +While not specifically mentioned in the rule, the commands in the +.Em PAGERS +.Li Cmnd_Alias +all reside in +.Pa /usr/bin +and have the +.Em noexec +option set. +.Bd -literal +steve CSNETS = (operator) /usr/local/op_commands/ +.Ed +.Pp +The user +.Sy steve +may run any command in the directory /usr/local/op_commands/ +but only as user operator. +.Bd -literal +matt valkyrie = KILL +.Ed +.Pp +On his personal workstation, valkyrie, +.Sy matt +needs to be able to kill hung processes. +.Bd -literal +WEBADMIN www = (www) ALL, (root) /usr/bin/su www +.Ed +.Pp +On the host www, any user in the +.Em WEBADMIN +.Li User_Alias +(will, wendy, and wim), may run any command as user www (which owns the +web pages) or simply +.Xr su 1 +to www. +.Bd -literal +ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\e + /sbin/mount -o nosuid\e,nodev /dev/cd0a /CDROM +.Ed +.Pp +Any user may mount or unmount a CD-ROM on the machines in the CDROM +.Li Host_Alias +(orion, perseus, hercules) without entering a password. +This is a bit tedious for users to type, so it is a prime candidate +for encapsulating in a shell script. +.Sh SECURITY NOTES +.Ss Limitations of the So !\& Sc operator +It is generally not effective to +.Dq subtract +commands from +.Sy ALL +using the +.Ql !\& +operator. +A user can trivially circumvent this by copying the desired command +to a different name and then executing that. +For example: +.Bd -literal +bill ALL = ALL, !SU, !SHELLS +.Ed +.Pp +Doesn't really prevent +.Sy bill +from running the commands listed in +.Em SU +or +.Em SHELLS +since he can simply copy those commands to a different name, or use +a shell escape from an editor or other program. +Therefore, these kind of restrictions should be considered +advisory at best (and reinforced by policy). +.Pp +In general, if a user has sudo +.Sy ALL +there is nothing to prevent them from creating their own program that gives +them a root shell (or making their own copy of a shell) regardless of any +.Ql !\& +elements in the user specification. +.Ss Security implications of Em fast_glob +If the +.Em fast_glob +option is in use, it is not possible to reliably negate commands where the +path name includes globbing (aka wildcard) characters. +This is because the C library's +.Xr fnmatch 3 +function cannot resolve relative paths. +While this is typically only an inconvenience for rules that grant privileges, +it can result in a security issue for rules that subtract or revoke privileges. +.Pp +For example, given the following +.Em sudoers +file entry: +.Bd -literal +john ALL = /usr/bin/passwd [a-zA-Z0-9]*, /usr/bin/chsh [a-zA-Z0-9]*,\e + /usr/bin/chfn [a-zA-Z0-9]*, !/usr/bin/* root +.Ed +.Pp +User +.Sy john +can still run +.Li /usr/bin/passwd root +if +.Em fast_glob +is enabled by changing to +.Pa /usr/bin +and running +.Li ./passwd root +instead. +.Ss Preventing shell escapes +Once +.Nm sudo +executes a program, that program is free to do whatever +it pleases, including run other programs. +This can be a security issue since it is not uncommon for a program to +allow shell escapes, which lets a user bypass +.Nm sudo Ns 's +access control and logging. +Common programs that permit shell escapes include shells (obviously), +editors, paginators, mail and terminal programs. +.Pp +There are two basic approaches to this problem: +.Bl -tag -width 8n +.It restrict +Avoid giving users access to commands that allow the user to run +arbitrary commands. +Many editors have a restricted mode where shell +escapes are disabled, though +.Nm sudoedit +is a better solution to +running editors via +.Nm sudo . +Due to the large number of programs that +offer shell escapes, restricting users to the set of programs that +do not is often unworkable. +.It noexec +Many systems that support shared libraries have the ability to +override default library functions by pointing an environment +variable (usually +.Ev LD_PRELOAD ) +to an alternate shared library. +On such systems, +.Nm sudo Ns 's +.Em noexec +functionality can be used to prevent a program run by +.Nm sudo +from executing any other programs. +Note, however, that this applies only to dynamically-linked +executables. +Statically-linked executables and executables +running under binary emulation are not affected. +.Pp +The +.Em noexec +feature is known to work on SunOS, Solaris, *BSD, +Linux, IRIX, Tru64 UNIX, macOS, HP-UX 11.x and AIX 5.3 and above. +It should be supported on most operating systems that support the +.Ev LD_PRELOAD +environment variable. +Check your operating system's manual pages for the dynamic linker +(usually ld.so, ld.so.1, dyld, dld.sl, rld, or loader) to see if +.Ev LD_PRELOAD +is supported. +.Pp +On Solaris 10 and higher, +.Em noexec +uses Solaris privileges instead of the +.Ev LD_PRELOAD +environment variable. +.Pp +To enable +.Em noexec +for a command, use the +.Li NOEXEC +tag as documented +in the User Specification section above. +Here is that example again: +.Bd -literal +aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi +.Ed +.Pp +This allows user +.Sy aaron +to run +.Pa /usr/bin/more +and +.Pa /usr/bin/vi +with +.Em noexec +enabled. +This will prevent those two commands from +executing other commands (such as a shell). +If you are unsure whether or not your system is capable of supporting +.Em noexec +you can always just try it out and check whether shell escapes work when +.Em noexec +is enabled. +.El +.Pp +Note that restricting shell escapes is not a panacea. +Programs running as root are still capable of many potentially hazardous +operations (such as changing or overwriting files) that could lead +to unintended privilege escalation. +In the specific case of an editor, a safer approach is to give the +user permission to run +.Nm sudoedit +(see below). +.Ss Secure editing +The +.Nm +plugin includes +.Nm sudoedit +support which allows users to securely edit files with the editor +of their choice. +As +.Nm sudoedit +is a built-in command, it must be specified in the +.Em sudoers +file without a leading path. +However, it may take command line arguments just as a normal command does. +Wildcards used in +.Em sudoedit +command line arguments are expected to be path names, so a forward slash +.Pq Ql / +will not be matched by a wildcard. +.Pp +Unlike other +.Nm sudo +commands, the editor is run with the permissions of the invoking +user and with the environment unmodified. +More information may be found in the description of the +.Fl e +option in +.Xr sudo @mansectsu@ . +.Pp +For example, to allow user operator to edit the +.Dq message of the day +file: +.Bd -literal -offset indent +operator sudoedit /etc/motd +.Ed +.Pp +The operator user then runs +.Nm sudoedit +as follows: +.Bd -literal -offset indent +$ sudoedit /etc/motd +.Ed +.Pp +The editor will run as the operator user, not root, on a temporary copy of +.Pa /etc/motd . +After the file has been edited, +.Pa /etc/motd +will be updated with the contents of the temporary copy. +.Pp +Users should +.Em never +be granted +.Nm sudoedit +permission to edit a file that resides in a directory the user +has write access to, either directly or via a wildcard. +If the user has write access to the directory it is possible to +replace the legitimate file with a link to another file, +allowing the editing of arbitrary files. +To prevent this, starting with version 1.8.16, symbolic links will +not be followed in writable directories and +.Nm sudoedit +will refuse to edit a file located in a writable directory +unless the +.Em sudoedit_checkdir +option has been disabled or the invoking user is root. +Additionally, in version 1.8.15 and higher, +.Nm sudoedit +will refuse to open a symbolic link unless either the +.Em sudoedit_follow +option is enabled or the +.Em sudoedit +command is prefixed with the +.Li FOLLOW +tag in the +.Em sudoers +file. +.Ss Time stamp file checks +.Nm +will check the ownership of its time stamp directory +.Po +.Pa @rundir@/ts +by default +.Pc +and ignore the directory's contents if it is not owned by root or +if it is writable by a user other than root. +Older versions of +.Nm sudo +stored time stamp files in +.Pa /tmp ; +this is no longer recommended as it may be possible for a user +to create the time stamp themselves on systems that allow +unprivileged users to change the ownership of files they create. +.Pp +While the time stamp directory +.Em should +be cleared at reboot time, not all systems contain a +.Pa /run +or +.Pa /var/run +directory. +To avoid potential problems, +.Nm +will ignore time stamp files that date from before the machine booted +on systems where the boot time is available. +.Pp +Some systems with graphical desktop environments allow unprivileged +users to change the system clock. +Since +.Nm +relies on the system clock for time stamp validation, it may be +possible on such systems for a user to run +.Nm sudo +for longer than +.Em timestamp_timeout +by setting the clock back. +To combat this, +.Nm +uses a monotonic clock (which never moves backwards) for its time stamps +if the system supports it. +.Pp +.Nm +will not honor time stamps set far in the future. +Time stamps with a date greater than current_time + 2 * +.Li TIMEOUT +will be ignored and +.Nm +will log and complain. +.Pp +If the +.Em timestamp_type +option is set to +.Dq tty , +the time stamp record includes the device number of the terminal +the user authenticated with. +This provides per-terminal granularity but time stamp records may still +outlive the user's session. +.Pp +Unless the +.Em timestamp_type +option is set to +.Dq global , +the time stamp record also includes the session ID of the process +that last authenticated. +This prevents processes in different terminal sessions from using +the same time stamp record. +On systems where a process's start time can be queried, +the start time of the session leader +is recorded in the time stamp record. +If no terminal is present or the +.Em timestamp_type +option is set to +.Dq ppid , +the start time of the parent process is used instead. +In most cases this will prevent a time stamp record from being re-used +without the user entering a password when logging out and back in again. +.Sh DEBUGGING +Versions 1.8.4 and higher of the +.Nm +plugin support a flexible debugging framework that can help track +down what the plugin is doing internally if there is a problem. +This can be configured in the +.Xr sudo.conf @mansectform@ +file. +.Pp +The +.Nm +plugin uses the same debug flag format as the +.Nm sudo +front-end: +.Em subsystem Ns @ Ns Em priority . +.Pp +The priorities used by +.Nm , +in order of decreasing severity, +are: +.Em crit , err , warn , notice , diag , info , trace +and +.Em debug . +Each priority, when specified, also includes all priorities higher +than it. +For example, a priority of +.Em notice +would include debug messages logged at +.Em notice +and higher. +.Pp +The following subsystems are used by the +.Nm +plugin: +.Bl -tag -width 8n +.It Em alias +.Li User_Alias , +.Li Runas_Alias , +.Li Host_Alias +and +.Li Cmnd_Alias +processing +.It Em all +matches every subsystem +.It Em audit +BSM and Linux audit code +.It Em auth +user authentication +.It Em defaults +.Em sudoers +file +.Em Defaults +settings +.It Em env +environment handling +.It Em ldap +LDAP-based sudoers +.It Em logging +logging support +.It Em match +matching of users, groups, hosts and netgroups in the +.Em sudoers +file +.It Em netif +network interface handling +.It Em nss +network service switch handling in +.Nm +.It Em parser +.Em sudoers +file parsing +.It Em perms +permission setting +.It Em plugin +The equivalent of +.Em main +for the plugin. +.It Em pty +pseudo-terminal related code +.It Em rbtree +redblack tree internals +.It Em sssd +SSSD-based sudoers +.It Em util +utility functions +.El +For example: +.Bd -literal +Debug sudo /var/log/sudo_debug match@info,nss@info +.Ed +.Pp +For more information, see the +.Xr sudo.conf @mansectform@ +manual. +.Sh SEE ALSO +.Xr ssh 1 , +.Xr su 1 , +.Xr fnmatch 3 , +.Xr glob 3 , +.Xr mktemp 3 , +.Xr strftime 3 , +.Xr sudo.conf @mansectform@ , +.Xr sudo_plugin @mansectform@ , +.Xr sudoers.ldap @mansectform@ , +.Xr sudoers_timestamp @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr visudo @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh CAVEATS +The +.Em sudoers +file should +.Sy always +be edited by the +.Nm visudo +utility which locks the file and checks for syntax errors. +If +.Em sudoers +contains syntax errors, +.Nm sudo +may refuse to run, which is a serious problem if +.Nm sudo +is your only method of obtaining superuser privileges. +Recent versions of +.Nm +will attempt to recover after a syntax error by ignoring the rest of +the line after encountering an error. +Older versions of +.Nm sudo +will not run if +.Em sudoers +contains a syntax error. +.Pp +When using netgroups of machines (as opposed to users), if you +store fully qualified host name in the netgroup (as is usually the +case), you either need to have the machine's host name be fully qualified +as returned by the +.Li hostname +command or use the +.Em fqdn +option in +.Em sudoers . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers_timestamp.man.in b/doc/sudoers_timestamp.man.in new file mode 100644 index 0000000..2f60f03 --- /dev/null +++ b/doc/sudoers_timestamp.man.in @@ -0,0 +1,312 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2017-2020 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. +.\" +.TH "SUDOERS_TIMESTAMP" "@mansectform@" "October 20, 2019" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudoers_timestamp\fR +\- Sudoers Time Stamp Format +.SH "DESCRIPTION" +The +\fBsudoers\fR +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 +minutes unless overridden by the +\fItimestamp_timeout\fR +option) +\&. +By default, +\fBsudoers\fR +uses a separate record for each terminal, which means that +a user's login sessions are authenticated separately. +The +\fItimestamp_type\fR +option can be used to select the type of time stamp record +\fBsudoers\fR +will use. +.PP +A multi-record time stamp file format was introduced in +\fBsudo\fR +1.8.10 that uses a single file per user. +Previously, a separate file was used for each user and terminal +combination unless tty-based time stamps were disabled. +The new format is extensible and records of multiple types and versions +may coexist within the same file. +.PP +All records, regardless of type or version, begin with a 16-bit version +number and a 16-bit record size. +.PP +Time stamp records have the following structure: +.nf +.sp +.RS 0n +/* Time stamp entry types */ +#define TS_GLOBAL 0x01 /* not restricted by tty or ppid */ +#define TS_TTY 0x02 /* restricted by tty */ +#define TS_PPID 0x03 /* restricted by ppid */ +#define TS_LOCKEXCL 0x04 /* special lock record */ + +/* Time stamp flags */ +#define TS_DISABLED 0x01 /* entry disabled */ +#define TS_ANYUID 0x02 /* ignore uid, only valid in key */ + +struct timestamp_entry { + unsigned short version; /* version number */ + unsigned short size; /* entry size */ + unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */ + unsigned short flags; /* TS_DISABLED, TS_ANYUID */ + uid_t auth_uid; /* uid to authenticate as */ + pid_t sid; /* session ID associated with tty/ppid */ + struct timespec start_time; /* session/ppid start time */ + struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */ + union { + dev_t ttydev; /* tty device number */ + pid_t ppid; /* parent pid */ + } u; +}; +.RE +.fi +.PP +The timestamp_entry struct fields are as follows: +.TP 6n +version +The version number of the timestamp_entry struct. +New entries are created with a version number of 2. +Records with different version numbers may coexist in the +same file but are not inter-operable. +.TP 6n +size +The size of the record in bytes. +.TP 6n +type +The record type, currently +\fRTS_GLOBAL\fR, +\fRTS_TTY\fR, +or +\fRTS_PPID\fR. +.TP 6n +flags +.br +Zero or more record flags which can be bit-wise ORed together. +Supported flags are +\fRTS_DISABLED\fR, +for records disabled via +\fBsudo\fR +\fB\-k\fR +and +\fRTS_ANYUID\fR, +which is used only when matching records. +.TP 6n +auth_uid +The user-ID that was used for authentication. +Depending on the value of the +\fIrootpw\fR, +\fIrunaspw\fR +and +\fItargetpw\fR +options, the user-ID may be that of the invoking user, the root user, +the default runas user or the target user. +.TP 6n +sid +The ID of the user's terminal session, if present. +The session ID is only used when matching records of type +\fRTS_TTY\fR. +.TP 6n +start_time +The start time of the session leader for records of type +\fRTS_TTY\fR +or of the parent process for records of type +\fRTS_PPID\fR. +The +\fIstart_time\fR +is used to help prevent re-use of a time stamp record after a +user has logged out. +Not all systems support a method to easily retrieve a process's +start time. +The +\fIstart_time\fR +field was added in +\fBsudoers\fR +version 1.8.22 for the second revision of the timestamp_entry struct. +.TP 6n +ts +The actual time stamp. +A monotonic time source (which does not move backward) is used if the +system supports it. +Where possible, +\fBsudoers\fR +uses a monotonic timer that increments even while the system +is suspended. +The value of +\fIts\fR +is updated each time a command is run via +\fBsudo\fR. +If the difference between +\fIts\fR +and the current time is less than the value of the +\fItimestamp_timeout\fR +option, no password is required. +.TP 6n +u.ttydev +The device number of the terminal associated with the session for +records of type +\fRTS_TTY\fR. +.TP 6n +u.ppid +The ID of the parent process for records of type +\fRTS_PPID\fR. +.SH "LOCKING" +In +\fBsudoers\fR +versions 1.8.10 through 1.8.14, the entire time stamp file was +locked for exclusive access when reading or writing to the file. +Starting in +\fBsudoers\fR +1.8.15, individual records are locked in the time stamp file instead +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 +\fRTS_LOCKEXCL\fR +and is used as a +\fIlock\fR +record to prevent more than one +\fBsudo\fR +process from adding a new record at the same time. +Once the desired time stamp record has been located or created (and +locked), the +\fRTS_LOCKEXCL\fR +record is unlocked. +The lock on the individual time stamp record, however, is held until +authentication is complete. +This allows +\fBsudoers\fR +to avoid prompting for a password multiple times when it +is used more than once in a pipeline. +.PP +Records of type +\fRTS_GLOBAL\fR +cannot be locked for a long period of time since doing so would +interfere with other +\fBsudo\fR +processes. +Instead, a separate lock record is used to prevent multiple +\fBsudo\fR +processes using the same terminal (or parent process ID) from +prompting for a password as the same time. +.SH "SEE ALSO" +sudoers(@mansectform@), +sudo(@mansectsu@) +.SH "HISTORY" +Originally, +\fBsudo\fR +used a single zero-length file per user and the file's modification +time was used as the time stamp. +Later versions of +\fBsudo\fR +added restrictions on the ownership of the time stamp files and +directory as well as checks on the validity of the time stamp itself. +Notable changes were introduced in the following +\fBsudo\fR +versions: +.TP 6n +1.4.0 +.br +Support for tty-based time stamp file was added +by appending the terminal name to the time stamp file name. +.TP 6n +1.6.2 +.br +The time stamp file was replaced by a per-user directory which +contained any tty-based time stamp files. +.TP 6n +1.6.3p2 +The target user name was added to the time stamp file name when the +\fItargetpw\fR +option was set. +.TP 6n +1.7.3 +.br +Information about the terminal device was stored in +tty-based time stamp files for validity checks. +This included the terminal device numbers, inode number and, on systems +where it was not updated when the device was written to, the inode change time. +This helped prevent re-use of the time stamp file after logout. +.TP 6n +1.8.6p7 +The terminal session ID was added to tty-based time stamp files to +prevent re-use of the time stamp by the same user in a different +terminal session. +It also helped prevent re-use of the time stamp file on systems where +the terminal device's inode change time was updated by writing. +.TP 6n +1.8.10 +A new, multi-record time stamp file format was introduced that uses a +single file per user. +The terminal device's change time was not included since most +systems now update the change time after a write is performed +as required by POSIX. +.TP 6n +1.8.15 +Individual records are locked in the time stamp file instead of the +entire file and the lock is held until authentication is complete. +.TP 6n +1.8.22 +The start time of the terminal session leader or parent process is +now stored in non-global time stamp records. +This prevents re-use of the time stamp file after logout in most cases. +.sp +Support was added for the kernel-based tty time stamps available in +OpenBSD +which do not use an on-disk time stamp file. +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoers_timestamp.mdoc.in b/doc/sudoers_timestamp.mdoc.in new file mode 100644 index 0000000..d879bfa --- /dev/null +++ b/doc/sudoers_timestamp.mdoc.in @@ -0,0 +1,290 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2017-2020 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. +.\" +.Dd October 20, 2019 +.Dt SUDOERS_TIMESTAMP @mansectform@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudoers_timestamp +.Nd Sudoers Time Stamp Format +.Sh DESCRIPTION +The +.Nm sudoers +plugin uses per-user time stamp files for credential caching. +Once a user has been authenticated, they may use +.Nm sudo +without a password for a short period of time +.Po +.Li @timeout@ +minutes unless overridden by the +.Em timestamp_timeout +option +.Pc . +By default, +.Nm sudoers +uses a separate record for each terminal, which means that +a user's login sessions are authenticated separately. +The +.Em timestamp_type +option can be used to select the type of time stamp record +.Nm sudoers +will use. +.Pp +A multi-record time stamp file format was introduced in +.Nm sudo +1.8.10 that uses a single file per user. +Previously, a separate file was used for each user and terminal +combination unless tty-based time stamps were disabled. +The new format is extensible and records of multiple types and versions +may coexist within the same file. +.Pp +All records, regardless of type or version, begin with a 16-bit version +number and a 16-bit record size. +.Pp +Time stamp records have the following structure: +.Bd -literal +/* Time stamp entry types */ +#define TS_GLOBAL 0x01 /* not restricted by tty or ppid */ +#define TS_TTY 0x02 /* restricted by tty */ +#define TS_PPID 0x03 /* restricted by ppid */ +#define TS_LOCKEXCL 0x04 /* special lock record */ + +/* Time stamp flags */ +#define TS_DISABLED 0x01 /* entry disabled */ +#define TS_ANYUID 0x02 /* ignore uid, only valid in key */ + +struct timestamp_entry { + unsigned short version; /* version number */ + unsigned short size; /* entry size */ + unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */ + unsigned short flags; /* TS_DISABLED, TS_ANYUID */ + uid_t auth_uid; /* uid to authenticate as */ + pid_t sid; /* session ID associated with tty/ppid */ + struct timespec start_time; /* session/ppid start time */ + struct timespec ts; /* time stamp (CLOCK_MONOTONIC) */ + union { + dev_t ttydev; /* tty device number */ + pid_t ppid; /* parent pid */ + } u; +}; +.Ed +.Pp +The timestamp_entry struct fields are as follows: +.Bl -tag -width 4n +.It version +The version number of the timestamp_entry struct. +New entries are created with a version number of 2. +Records with different version numbers may coexist in the +same file but are not inter-operable. +.It size +The size of the record in bytes. +.It type +The record type, currently +.Li TS_GLOBAL , +.Li TS_TTY , +or +.Li TS_PPID . +.It flags +Zero or more record flags which can be bit-wise ORed together. +Supported flags are +.Li TS_DISABLED , +for records disabled via +.Nm sudo +.Fl k +and +.Li TS_ANYUID , +which is used only when matching records. +.It auth_uid +The user-ID that was used for authentication. +Depending on the value of the +.Em rootpw , +.Em runaspw +and +.Em targetpw +options, the user-ID may be that of the invoking user, the root user, +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 . +.It start_time +The start time of the session leader for records of type +.Li TS_TTY +or of the parent process for records of type +.Li TS_PPID . +The +.Em start_time +is used to help prevent re-use of a time stamp record after a +user has logged out. +Not all systems support a method to easily retrieve a process's +start time. +The +.Em start_time +field was added in +.Nm sudoers +version 1.8.22 for the second revision of the timestamp_entry struct. +.It ts +The actual time stamp. +A monotonic time source (which does not move backward) is used if the +system supports it. +Where possible, +.Nm sudoers +uses a monotonic timer that increments even while the system +is suspended. +The value of +.Em ts +is updated each time a command is run via +.Nm sudo . +If the difference between +.Em ts +and the current time is less than the value of the +.Em timestamp_timeout +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 . +.It u.ppid +The ID of the parent process for records of type +.Li TS_PPID . +.El +.Sh LOCKING +In +.Nm sudoers +versions 1.8.10 through 1.8.14, the entire time stamp file was +locked for exclusive access when reading or writing to the file. +Starting in +.Nm sudoers +1.8.15, individual records are locked in the time stamp file instead +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 +and is used as a +.Em lock +record to prevent more than one +.Nm sudo +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 +record is unlocked. +The lock on the individual time stamp record, however, is held until +authentication is complete. +This allows +.Nm sudoers +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 +cannot be locked for a long period of time since doing so would +interfere with other +.Nm sudo +processes. +Instead, a separate lock record is used to prevent multiple +.Nm sudo +processes using the same terminal (or parent process ID) from +prompting for a password as the same time. +.Sh SEE ALSO +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ +.Sh HISTORY +Originally, +.Nm sudo +used a single zero-length file per user and the file's modification +time was used as the time stamp. +Later versions of +.Nm sudo +added restrictions on the ownership of the time stamp files and +directory as well as checks on the validity of the time stamp itself. +Notable changes were introduced in the following +.Nm sudo +versions: +.Bl -tag -width 4n +.It 1.4.0 +Support for tty-based time stamp file was added +by appending the terminal name to the time stamp file name. +.It 1.6.2 +The time stamp file was replaced by a per-user directory which +contained any tty-based time stamp files. +.It 1.6.3p2 +The target user name was added to the time stamp file name when the +.Em targetpw +option was set. +.It 1.7.3 +Information about the terminal device was stored in +tty-based time stamp files for validity checks. +This included the terminal device numbers, inode number and, on systems +where it was not updated when the device was written to, the inode change time. +This helped prevent re-use of the time stamp file after logout. +.It 1.8.6p7 +The terminal session ID was added to tty-based time stamp files to +prevent re-use of the time stamp by the same user in a different +terminal session. +It also helped prevent re-use of the time stamp file on systems where +the terminal device's inode change time was updated by writing. +.It 1.8.10 +A new, multi-record time stamp file format was introduced that uses a +single file per user. +The terminal device's change time was not included since most +systems now update the change time after a write is performed +as required by POSIX. +.It 1.8.15 +Individual records are locked in the time stamp file instead of the +entire file and the lock is held until authentication is complete. +.It 1.8.22 +The start time of the terminal session leader or parent process is +now stored in non-global time stamp records. +This prevents re-use of the time stamp file after logout in most cases. +.Pp +Support was added for the kernel-based tty time stamps available in +.Ox +which do not use an on-disk time stamp file. +.El +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm sudo , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm sudo +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoreplay.man.in b/doc/sudoreplay.man.in new file mode 100644 index 0000000..4401516 --- /dev/null +++ b/doc/sudoreplay.man.in @@ -0,0 +1,519 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2009-2020 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. +.\" +.TH "SUDOREPLAY" "@mansectsu@" "May 18, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.nh +.if n .ad l +.SH "NAME" +\fBsudoreplay\fR +\- replay sudo session logs +.SH "SYNOPSIS" +.HP 11n +\fBsudoreplay\fR +[\fB\-FhnRS\fR] +[\fB\-d\fR\ \fIdir\fR] +[\fB\-f\fR\ \fIfilter\fR] +[\fB\-m\fR\ \fInum\fR] +[\fB\-s\fR\ \fInum\fR] +ID +.HP 11n +\fBsudoreplay\fR +[\fB\-h\fR] +[\fB\-d\fR\ \fIdir\fR] +\fB\-l\fR +[search\ expression] +.SH "DESCRIPTION" +\fBsudoreplay\fR +plays back or lists the output logs created by +\fBsudo\fR. +When replaying, +\fBsudoreplay\fR +can play the session back in real-time, or the playback speed may be +adjusted (faster or slower) based on the command line options. +.PP +The +\fIID\fR +should either be a six character sequence of digits and +upper case letters, e.g., +\fR0100A5\fR, +a pattern matching the +\fIiolog_file\fR +option in the +\fIsudoers\fR +file, or a path name. +Path names may be relative to the +\fIiolog_dir\fR +option in the +\fIsudoers\fR +file (unless overridden by the +\fB\-d\fR +option) or fully qualified, beginning with a +\(oq/\(cq +character. +When a command is run via +\fBsudo\fR +with +\fIlog_output\fR +enabled in the +\fIsudoers\fR +file, a +\fRTSID=ID\fR +string is logged via syslog or to the +\fBsudo\fR +log file. +The +\fIID\fR +may also be determined using +\fBsudoreplay\fR's +list mode. +.PP +In list mode, +\fBsudoreplay\fR +can be used to find the ID of a session based on a number of criteria +such as the user, tty or command run. +.PP +In replay mode, if the standard input and output are connected to a terminal +and the +\fB\-n\fR +option is not specified, +\fBsudoreplay\fR +will operate interactively. +In interactive mode, +\fBsudoreplay\fR +will attempt to adjust the terminal size to match that of the session and +write directly to the terminal (not all terminals support this). +Additionally, it will poll the keyboard and act on the following keys: +.TP 14n +\(oq\fR\en\fR\(cq or \(oq\fR\er\fR\(cq +Skip to the next replay event; useful for long pauses. +.TP 14n +\(oq\fR\ \fR\(cq (space) +Pause output; press any key to resume. +.TP 14n +\(oq<\(cq +Reduce the playback speed by one half. +.TP 14n +\(oq>\(cq +Double the playback speed. +.PP +The session can be interrupted via control-C. +When the session has finished, the terminal is restored to its +original size if it was changed during playback. +.PP +The options are as follows: +.TP 12n +\fB\-d\fR \fIdir\fR, \fB\--directory\fR=\fIdir\fR +Store session logs in +\fIdir\fR +instead of the default, +\fI@iolog_dir@\fR. +.TP 12n +\fB\-f\fR \fIfilter\fR, \fB\--filter\fR=\fIfilter\fR +Select which I/O type(s) to display. +By default, +\fBsudoreplay\fR +will display the command's standard output, standard error and tty output. +The +\fIfilter\fR +argument is a comma-separated list, consisting of one or more of following: +\fIstdin\fR, +\fIstdout\fR, +\fIstderr\fR, +\fIttyin\fR, +and +\fIttyout\fR. +.TP 12n +\fB\-F\fR, \fB\--follow\fR +Enable +\(lqfollow mode\(rq. +When replaying a session, +\fBsudoreplay\fR +will ignore end-of-file and keep replaying until the log is complete. +This can be used to replay a session that is still in progress, +similar to +\(lqtail -f\(rq. +An I/O log file is considered to be complete when the write bits +have been cleared on the session's timing file. +Note that versions of +\fBsudo\fR +prior to 1.9.1 do not clear the write bits upon completion. +.TP 12n +\fB\-h\fR, \fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-l\fR, \fB\--list\fR [\fIsearch expression\fR] +Enable +\(lqlist mode\(rq. +In this mode, +\fBsudoreplay\fR +will list available sessions in a format similar to the +\fBsudo\fR +log file format, sorted by file name (or sequence number). +If a +\fIsearch expression\fR +is specified, it will be used to restrict the IDs that are displayed. +An expression is composed of the following predicates: +.PP +.RS 12n +.PD 0 +.TP 8n +command \fIpattern\fR +Evaluates to true if the command run matches the POSIX extended +regular expression +\fIpattern\fR. +.PD +.TP 8n +cwd \fIdirectory\fR +Evaluates to true if the command was run with the specified current +working directory. +.TP 8n +fromdate \fIdate\fR +Evaluates to true if the command was run on or after +\fIdate\fR. +See +\fIDate and time format\fR +for a description of supported date and time formats. +.TP 8n +group \fIrunas_group\fR +Evaluates to true if the command was run with the specified +\fIrunas_group\fR. +Note that unless a +\fIrunas_group\fR +was explicitly specified when +\fBsudo\fR +was run this field will be empty in the log. +.TP 8n +host \fIhostname\fR +Evaluates to true if the command was run on the specified +\fIhostname\fR. +.TP 8n +runas \fIrunas_user\fR +Evaluates to true if the command was run as the specified +\fIrunas_user\fR. +Note that +\fBsudo\fR +runs commands as user +\fIroot\fR +by default. +.TP 8n +todate \fIdate\fR +Evaluates to true if the command was run on or prior to +\fIdate\fR. +See +\fIDate and time format\fR +for a description of supported date and time formats. +.TP 8n +tty \fItty name\fR +Evaluates to true if the command was run on the specified terminal device. +The +\fItty name\fR +should be specified without the +\fI/dev/\fR +prefix, e.g., +\fItty01\fR +instead of +\fI/dev/tty01\fR. +.TP 8n +user \fIuser name\fR +Evaluates to true if the ID matches a command run by +\fIuser name\fR. +.PP +Predicates may be abbreviated to the shortest unique string. +.sp +Predicates may be combined using +\fIand\fR, +\fIor\fR +and +\fI\&!\fR +operators as well as +\(oq\&(\(cq +and +\(oq\&)\(cq +grouping (note that parentheses must generally be escaped from the shell). +The +\fIand\fR +operator is optional, adjacent predicates have an implied +\fIand\fR +unless separated by an +\fIor\fR. +.RE +.TP 12n +\fB\-m\fR, \fB\--max-wait\fR \fImax_wait\fR +Specify an upper bound on how long to wait between key presses or output data. +By default, +\fBsudoreplay\fR +will accurately reproduce the delays between key presses or program output. +However, this can be tedious when the session includes long pauses. +When the +\fB\-m\fR +option is specified, +\fBsudoreplay\fR +will limit these pauses to at most +\fImax_wait\fR +seconds. +The value may be specified as a floating point number, e.g., +\fI2.5\fR. +A +\fImax_wait\fR +of zero or less will eliminate the pauses entirely. +.TP 12n +\fB\-n\fR, \fB\--non-interactive\fR +Do not prompt for user input or attempt to re-size the terminal. +The session is written to the standard output, not directly to +the user's terminal. +.TP 12n +\fB\-R\fR, \fB\--no-resize\fR +Do not attempt to re-size the terminal to match the terminal size +of the session. +.TP 12n +\fB\-S\fR, \fB\--suspend-wait\fR +Wait while the command was suspended. +By default, +\fBsudoreplay\fR +will ignore the time interval between when the command was suspended +and when it was resumed. +If the +\fB\-S\fR +option is specified, +\fBsudoreplay\fR +will wait instead. +.TP 12n +\fB\-s\fR, \fB\--speed\fR \fIspeed_factor\fR +This option causes +\fBsudoreplay\fR +to adjust the number of seconds it will wait between key presses or +program output. +This can be used to slow down or speed up the display. +For example, a +\fIspeed_factor\fR +of +\fI2\fR +would make the output twice as fast whereas a +\fIspeed_factor\fR +of +\fI.5\fR +would make the output twice as slow. +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBsudoreplay\fR +versions version number and exit. +.SS "Date and time format" +The time and date may be specified multiple ways, common formats include: +.TP 8n +HH:MM:SS am MM/DD/CCYY timezone +24 hour time may be used in place of am/pm. +.TP 8n +HH:MM:SS am Month, Day Year timezone +24 hour time may be used in place of am/pm, and month and day names +may be abbreviated. +Note that month and day of the week names must be specified in English. +.TP 8n +CCYY-MM-DD HH:MM:SS +ISO time format +.TP 8n +DD Month CCYY HH:MM:SS +The month name may be abbreviated. +.PP +Either time or date may be omitted, the am/pm and timezone are optional. +If no date is specified, the current day is assumed; if no time is +specified, the first second of the specified date is used. +The less significant parts of both time and date may also be omitted, +in which case zero is assumed. +.PP +The following are all valid time and date specifications: +.TP 8n +now +The current time and date. +.TP 8n +tomorrow +Exactly one day from now. +.TP 8n +yesterday +24 hours ago. +.TP 8n +2 hours ago +2 hours ago. +.TP 8n +next Friday +The first second of the Friday in the next (upcoming) week. +Not to be confused with +\(lqthis Friday\(rq +which would match the Friday of the current week. +.TP 8n +last week +The current time but 7 days ago. +This is equivalent to +\(lqa week ago\(rq. +.TP 8n +a fortnight ago +The current time but 14 days ago. +.TP 8n +10:01 am 9/17/2009 +10:01 am, September 17, 2009. +.TP 8n +10:01 am +10:01 am on the current day. +.TP 8n +10 +10:00 am on the current day. +.TP 8n +9/17/2009 +00:00 am, September 17, 2009. +.TP 8n +10:01 am Sep 17, 2009 +10:01 am, September 17, 2009. +.PP +Note that relative time specifications do not always work as expected. +For example, the +\(lqnext\(rq +qualifier is intended to be used in conjunction with a day such as +\(lqnext Monday\(rq. +When used with units of weeks, months, years, etc +the result will be one more than expected. +For example, +\(lqnext week\(rq +will result in a time exactly two weeks from now, which is probably +not what was intended. +This will be addressed in a future version of +\fBsudoreplay\fR. +.SS "Debugging sudoreplay" +\fBsudoreplay\fR +versions 1.8.4 and higher support a flexible debugging framework +that is configured via +\fRDebug\fR +lines in the +sudo.conf(@mansectform@) +file. +.PP +For more information on configuring +sudo.conf(@mansectform@), +please refer to its manual. +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +Debugging framework configuration +.TP 26n +\fI@iolog_dir@\fR +The default I/O log directory. +.TP 26n +\fI@iolog_dir@/00/00/01/log\fR +Example session log info. +.TP 26n +\fI@iolog_dir@/00/00/01/log.json\fR +Example session log info (JSON format). +.TP 26n +\fI@iolog_dir@/00/00/01/stdin\fR +Example session standard input log. +.TP 26n +\fI@iolog_dir@/00/00/01/stdout\fR +Example session standard output log. +.TP 26n +\fI@iolog_dir@/00/00/01/stderr\fR +Example session standard error log. +.TP 26n +\fI@iolog_dir@/00/00/01/ttyin\fR +Example session tty input file. +.TP 26n +\fI@iolog_dir@/00/00/01/ttyout\fR +Example session tty output file. +.TP 26n +\fI@iolog_dir@/00/00/01/timing\fR +Example session timing file. +.PP +Note that the +\fIstdin\fR, +\fIstdout\fR +and +\fIstderr\fR +files will be empty unless +\fBsudo\fR +was used as part of a pipeline for a particular command. +.SH "EXAMPLES" +List sessions run by user +\fImillert\fR: +.nf +.sp +.RS 6n +# sudoreplay -l user millert +.RE +.fi +.PP +List sessions run by user +\fIbob\fR +with a command containing the string vi: +.nf +.sp +.RS 6n +# sudoreplay -l user bob command vi +.RE +.fi +.PP +List sessions run by user +\fIjeff\fR +that match a regular expression: +.nf +.sp +.RS 6n +# sudoreplay -l user jeff command '/bin/[a-z]*sh' +.RE +.fi +.PP +List sessions run by jeff or bob on the console: +.nf +.sp +.RS 6n +# sudoreplay -l ( user jeff or user bob ) tty console +.RE +.fi +.SH "SEE ALSO" +script(1), +sudo.conf(@mansectform@), +sudo(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "BUGS" +If you feel you have found a bug in +\fBsudoreplay\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBsudoreplay\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/sudoreplay.mdoc.in b/doc/sudoreplay.mdoc.in new file mode 100644 index 0000000..f7adfa8 --- /dev/null +++ b/doc/sudoreplay.mdoc.in @@ -0,0 +1,461 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 2009-2020 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. +.\" +.Dd May 18, 2020 +.Dt SUDOREPLAY @mansectsu@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm sudoreplay +.Nd replay sudo session logs +.Sh SYNOPSIS +.Nm sudoreplay +.Op Fl FhnRS +.Op Fl d Ar dir +.Op Fl f Ar filter +.Op Fl m Ar num +.Op Fl s Ar num +ID +.Pp +.Nm +.Op Fl h +.Op Fl d Ar dir +.Fl l +.Op search expression +.Sh DESCRIPTION +.Nm +plays back or lists the output logs created by +.Nm sudo . +When replaying, +.Nm +can play the session back in real-time, or the playback speed may be +adjusted (faster or slower) based on the command line options. +.Pp +The +.Em ID +should either be a six character sequence of digits and +upper case letters, e.g., +.Li 0100A5 , +a pattern matching the +.Em iolog_file +option in the +.Em sudoers +file, or a path name. +Path names may be relative to the +.Em iolog_dir +option in the +.Em sudoers +file (unless overridden by the +.Fl d +option) or fully qualified, beginning with a +.Ql / +character. +When a command is run via +.Nm sudo +with +.Em log_output +enabled in the +.Em sudoers +file, a +.Li TSID=ID +string is logged via syslog or to the +.Nm sudo +log file. +The +.Em ID +may also be determined using +.Nm sudoreplay Ns 's +list mode. +.Pp +In list mode, +.Nm +can be used to find the ID of a session based on a number of criteria +such as the user, tty or command run. +.Pp +In replay mode, if the standard input and output are connected to a terminal +and the +.Fl n +option is not specified, +.Nm +will operate interactively. +In interactive mode, +.Nm +will attempt to adjust the terminal size to match that of the session and +write directly to the terminal (not all terminals support this). +Additionally, it will poll the keyboard and act on the following keys: +.Bl -tag -width 12n +.It So Li \en Sc No or So Li \er Sc +Skip to the next replay event; useful for long pauses. +.It So Li \ Sc Pq space +Pause output; press any key to resume. +.It Ql < +Reduce the playback speed by one half. +.It Ql > +Double the playback speed. +.El +.Pp +The session can be interrupted via control-C. +When the session has finished, the terminal is restored to its +original size if it was changed during playback. +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl d Ar dir , Fl -directory Ns = Ns Ar dir +Store session logs in +.Ar dir +instead of the default, +.Pa @iolog_dir@ . +.It Fl f Ar filter , Fl -filter Ns = Ns Ar filter +Select which I/O type(s) to display. +By default, +.Nm +will display the command's standard output, standard error and tty output. +The +.Ar filter +argument is a comma-separated list, consisting of one or more of following: +.Em stdin , +.Em stdout , +.Em stderr , +.Em ttyin , +and +.Em ttyout . +.It Fl F , -follow +Enable +.Dq follow mode . +When replaying a session, +.Nm +will ignore end-of-file and keep replaying until the log is complete. +This can be used to replay a session that is still in progress, +similar to +.Dq tail -f . +An I/O log file is considered to be complete when the write bits +have been cleared on the session's timing file. +Note that versions of +.Nm sudo +prior to 1.9.1 do not clear the write bits upon completion. +.It Fl h , -help +Display a short help message to the standard output and exit. +.It Fl l , -list Op Ar search expression +Enable +.Dq list mode . +In this mode, +.Nm +will list available sessions in a format similar to the +.Nm sudo +log file format, sorted by file name (or sequence number). +If a +.Ar search expression +is specified, it will be used to restrict the IDs that are displayed. +An expression is composed of the following predicates: +.Bl -tag -width 6n +.It command Ar pattern +Evaluates to true if the command run matches the POSIX extended +regular expression +.Ar pattern . +.It cwd Ar directory +Evaluates to true if the command was run with the specified current +working directory. +.It fromdate Ar date +Evaluates to true if the command was run on or after +.Ar date . +See +.Sx Date and time format +for a description of supported date and time formats. +.It group Ar runas_group +Evaluates to true if the command was run with the specified +.Ar runas_group . +Note that unless a +.Ar runas_group +was explicitly specified when +.Nm sudo +was run this field will be empty in the log. +.It host Ar hostname +Evaluates to true if the command was run on the specified +.Ar hostname . +.It runas Ar runas_user +Evaluates to true if the command was run as the specified +.Ar runas_user . +Note that +.Nm sudo +runs commands as user +.Em root +by default. +.It todate Ar date +Evaluates to true if the command was run on or prior to +.Ar date . +See +.Sx Date and time format +for a description of supported date and time formats. +.It tty Ar tty name +Evaluates to true if the command was run on the specified terminal device. +The +.Ar tty name +should be specified without the +.Pa /dev/ +prefix, e.g., +.Pa tty01 +instead of +.Pa /dev/tty01 . +.It user Ar user name +Evaluates to true if the ID matches a command run by +.Ar user name . +.El +.Pp +Predicates may be abbreviated to the shortest unique string. +.Pp +Predicates may be combined using +.Em and , +.Em or +and +.Em \&! +operators as well as +.Ql \&( +and +.Ql \&) +grouping (note that parentheses must generally be escaped from the shell). +The +.Em and +operator is optional, adjacent predicates have an implied +.Em and +unless separated by an +.Em or . +.It Fl m , -max-wait Ar max_wait +Specify an upper bound on how long to wait between key presses or output data. +By default, +.Nm +will accurately reproduce the delays between key presses or program output. +However, this can be tedious when the session includes long pauses. +When the +.Fl m +option is specified, +.Nm +will limit these pauses to at most +.Em max_wait +seconds. +The value may be specified as a floating point number, e.g., +.Em 2.5 . +A +.Em max_wait +of zero or less will eliminate the pauses entirely. +.It Fl n , -non-interactive +Do not prompt for user input or attempt to re-size the terminal. +The session is written to the standard output, not directly to +the user's terminal. +.It Fl R , -no-resize +Do not attempt to re-size the terminal to match the terminal size +of the session. +.It Fl S , -suspend-wait +Wait while the command was suspended. +By default, +.Nm +will ignore the time interval between when the command was suspended +and when it was resumed. +If the +.Fl S +option is specified, +.Nm +will wait instead. +.It Fl s , -speed Ar speed_factor +This option causes +.Nm +to adjust the number of seconds it will wait between key presses or +program output. +This can be used to slow down or speed up the display. +For example, a +.Ar speed_factor +of +.Em 2 +would make the output twice as fast whereas a +.Ar speed_factor +of +.Em .5 +would make the output twice as slow. +.It Fl V , -version +Print the +.Nm +versions version number and exit. +.El +.Ss Date and time format +The time and date may be specified multiple ways, common formats include: +.Bl -tag -width 6n +.It HH:MM:SS am MM/DD/CCYY timezone +24 hour time may be used in place of am/pm. +.It HH:MM:SS am Month, Day Year timezone +24 hour time may be used in place of am/pm, and month and day names +may be abbreviated. +Note that month and day of the week names must be specified in English. +.It CCYY-MM-DD HH:MM:SS +ISO time format +.It DD Month CCYY HH:MM:SS +The month name may be abbreviated. +.El +.Pp +Either time or date may be omitted, the am/pm and timezone are optional. +If no date is specified, the current day is assumed; if no time is +specified, the first second of the specified date is used. +The less significant parts of both time and date may also be omitted, +in which case zero is assumed. +.Pp +The following are all valid time and date specifications: +.Bl -tag -width 6n +.It now +The current time and date. +.It tomorrow +Exactly one day from now. +.It yesterday +24 hours ago. +.It 2 hours ago +2 hours ago. +.It next Friday +The first second of the Friday in the next (upcoming) week. +Not to be confused with +.Dq this Friday +which would match the Friday of the current week. +.It last week +The current time but 7 days ago. +This is equivalent to +.Dq a week ago . +.It a fortnight ago +The current time but 14 days ago. +.It 10:01 am 9/17/2009 +10:01 am, September 17, 2009. +.It 10:01 am +10:01 am on the current day. +.It 10 +10:00 am on the current day. +.It 9/17/2009 +00:00 am, September 17, 2009. +.It 10:01 am Sep 17, 2009 +10:01 am, September 17, 2009. +.El +.Pp +Note that relative time specifications do not always work as expected. +For example, the +.Dq next +qualifier is intended to be used in conjunction with a day such as +.Dq next Monday . +When used with units of weeks, months, years, etc +the result will be one more than expected. +For example, +.Dq next week +will result in a time exactly two weeks from now, which is probably +not what was intended. +This will be addressed in a future version of +.Nm . +.Ss Debugging sudoreplay +.Nm +versions 1.8.4 and higher support a flexible debugging framework +that is configured via +.Li Debug +lines in the +.Xr sudo.conf @mansectform@ +file. +.Pp +For more information on configuring +.Xr sudo.conf @mansectform@ , +please refer to its manual. +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +Debugging framework configuration +.It Pa @iolog_dir@ +The default I/O log directory. +.It Pa @iolog_dir@/00/00/01/log +Example session log info. +.It Pa @iolog_dir@/00/00/01/log.json +Example session log info (JSON format). +.It Pa @iolog_dir@/00/00/01/stdin +Example session standard input log. +.It Pa @iolog_dir@/00/00/01/stdout +Example session standard output log. +.It Pa @iolog_dir@/00/00/01/stderr +Example session standard error log. +.It Pa @iolog_dir@/00/00/01/ttyin +Example session tty input file. +.It Pa @iolog_dir@/00/00/01/ttyout +Example session tty output file. +.It Pa @iolog_dir@/00/00/01/timing +Example session timing file. +.El +.Pp +Note that the +.Em stdin , +.Em stdout +and +.Em stderr +files will be empty unless +.Nm sudo +was used as part of a pipeline for a particular command. +.Sh EXAMPLES +List sessions run by user +.Em millert : +.Bd -literal -offset indent +# sudoreplay -l user millert +.Ed +.Pp +List sessions run by user +.Em bob +with a command containing the string vi: +.Bd -literal -offset indent +# sudoreplay -l user bob command vi +.Ed +.Pp +List sessions run by user +.Em jeff +that match a regular expression: +.Bd -literal -offset indent +# sudoreplay -l user jeff command '/bin/[a-z]*sh' +.Ed +.Pp +List sessions run by jeff or bob on the console: +.Bd -literal -offset indent +# sudoreplay -l ( user jeff or user bob ) tty console +.Ed +.Sh SEE ALSO +.Xr script 1 , +.Xr sudo.conf @mansectform@ , +.Xr sudo @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/visudo.man.in b/doc/visudo.man.in new file mode 100644 index 0000000..d068e83 --- /dev/null +++ b/doc/visudo.man.in @@ -0,0 +1,475 @@ +.\" Automatically generated from an mdoc input file. Do not edit. +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1996,1998-2005, 2007-2020 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.TH "VISUDO" "@mansectsu@" "August 27, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.nh +.if n .ad l +.SH "NAME" +\fBvisudo\fR +\- edit the sudoers file +.SH "SYNOPSIS" +.HP 7n +\fBvisudo\fR +[\fB\-chqsV\fR] +[[\fB\-f\fR]\ \fIsudoers\fR] +.SH "DESCRIPTION" +\fBvisudo\fR +edits the +\fIsudoers\fR +file in a safe fashion, analogous to +vipw(@mansectsu@). +\fBvisudo\fR +locks the +\fIsudoers\fR +file against multiple simultaneous edits, performs basic validity checks, +and checks for syntax errors before installing the edited file. +If the +\fIsudoers\fR +file is currently being edited you will receive a message to try again later. +.PP +\fBvisudo\fR +parses the +\fIsudoers\fR +file after editing and will not save the changes if there is a syntax error. +Upon finding an error, +\fBvisudo\fR +will print a message stating the line number(s) +where the error occurred and the user will receive the +\(lqWhat now?\(rq +prompt. +At this point the user may enter +\(oqe\(cq +to re-edit the +\fIsudoers\fR +file, +\(oqx\(cq +to exit without saving the changes, or +\(oqQ\(cq +to quit and save changes. +The +\(oqQ\(cq +option should be used with extreme caution because if +\fBvisudo\fR +believes there to be a syntax error, so will +\fBsudo\fR +and no one will be able to run +\fBsudo\fR +again until the error is fixed. +If +\(oqe\(cq +is typed to edit the +\fIsudoers\fR +file after a syntax error has been detected, the cursor will be placed on +the line where the error occurred (if the editor supports this feature). +.PP +There are two +\fIsudoers\fR +settings that determine which editor +\fBvisudo\fR +will run. +.TP 10n +editor +A colon +(\(oq:\&\(cq) +separated list of editors allowed to be used with +\fBvisudo\fR. +\fBvisudo\fR +will choose the editor that matches the user's +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variable if possible, or the first editor in the +list that exists and is executable. +Note that +\fBsudo\fR +does not preserve the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variables unless they are present in the +\fIenv_keep\fR +list or the +\fIenv_reset\fR +option is disabled in the +\fIsudoers\fR +file. +The default editor path is +\fI@editor@\fR +which can be set at compile time via the +\fR--with-editor\fR +configure option. +.TP 10n +env_editor +If set, +\fBvisudo\fR +will use the value of the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +environment variables before falling back on the default editor list. +Note that +\fBvisudo\fR +is typically run as root so this option may allow a user with +\fBvisudo\fR +privileges to run arbitrary commands as root without logging. +An alternative is to place a colon-separated list of +\(lqsafe\(rq +editors int the +\fIeditor\fR +variable. +\fBvisudo\fR +will then only use +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +or +\fREDITOR\fR +if they match a value specified in +\fIeditor\fR. +If the +\fIenv_reset\fR +flag is enabled, the +\fRSUDO_EDITOR\fR, +\fRVISUAL\fR +and/or +\fREDITOR\fR +environment variables must be present in the +\fIenv_keep\fR +list for the +\fIenv_editor\fR +flag to function when +\fBvisudo\fR +is invoked via +\fBsudo\fR. +The default value is +\fI@env_editor@\fR, +which can be set at compile time via the +\fR--with-env-editor\fR +configure option. +.PP +The options are as follows: +.TP 12n +\fB\-c\fR, \fB\--check\fR +Enable +\fIcheck-only\fR +mode. +The existing +\fIsudoers\fR +file (and any other files it includes) will be +checked for syntax errors. +If the path to the +\fIsudoers\fR +file was not specified, +\fBvisudo\fR +will also check the file owner and mode. +A message will be printed to the standard output describing the status of +\fIsudoers\fR +unless the +\fB\-q\fR +option was specified. +If the check completes successfully, +\fBvisudo\fR +will exit with a value of 0. +If an error is encountered, +\fBvisudo\fR +will exit with a value of 1. +.TP 12n +\fB\-f\fR \fIsudoers\fR, \fB\--file\fR=\fIsudoers\fR +Specify an alternate +\fIsudoers\fR +file location, see below. +As of version 1.8.27, the +\fIsudoers\fR +path can be specified without using the +\fB\-f\fR +option. +.TP 12n +\fB\-h\fR, \fB\--help\fR +Display a short help message to the standard output and exit. +.TP 12n +\fB\-q\fR, \fB\--quiet\fR +Enable +\fIquiet\fR +mode. +In this mode details about syntax errors are not printed. +This option is only useful when combined with +the +\fB\-c\fR +option. +.TP 12n +\fB\-s\fR, \fB\--strict\fR +Enable +\fIstrict\fR +checking of the +\fIsudoers\fR +file. +If an alias is referenced but not actually defined +or if there is a cycle in an alias, +\fBvisudo\fR +will consider this a syntax error. +Note that it is not possible to differentiate between an +alias and a host name or user name that consists solely of uppercase +letters, digits, and the underscore +(\(oq_\(cq) +character. +.TP 12n +\fB\-V\fR, \fB\--version\fR +Print the +\fBvisudo\fR +and +\fIsudoers\fR +grammar versions and exit. +.PP +A +\fIsudoers\fR +file may be specified instead of the default, +\fI@sysconfdir@/sudoers\fR. +The temporary file used is the specified +\fIsudoers\fR +file with +\(lq\.tmp\(rq +appended to it. +In +\fIcheck-only\fR +mode only, +\(oq-\(cq +may be used to indicate that +\fIsudoers\fR +will be read from the standard input. +Because the policy is evaluated in its entirety, it is not sufficient +to check an individual +\fIsudoers\fR +include file for syntax errors. +.SS "Debugging and sudoers plugin arguments" +\fBvisudo\fR +versions 1.8.4 and higher support a flexible debugging framework +that is configured via +\fRDebug\fR +lines in the +sudo.conf(@mansectform@) +file. +.PP +Starting with +\fBsudo\fR +1.8.12, +\fBvisudo\fR +will also parse the arguments to the +\fIsudoers\fR +plugin to override the default +\fIsudoers\fR +path name, UID, GID and file mode. +These arguments, if present, should be listed after the path to the plugin +(i.e., after +\fIsudoers.so\fR). +Multiple arguments may be specified, separated by white space. +For example: +.nf +.sp +.RS 6n +Plugin sudoers_policy sudoers.so sudoers_mode=0400 +.RE +.fi +.PP +The following arguments are supported: +.TP 10n +sudoers_file=pathname +The +\fIsudoers_file\fR +argument can be used to override the default path to the +\fIsudoers\fR +file. +.TP 10n +sudoers_uid=uid +The +\fIsudoers_uid\fR +argument can be used to override the default owner of the sudoers file. +It should be specified as a numeric user-ID. +.TP 10n +sudoers_gid=gid +The +\fIsudoers_gid\fR +argument can be used to override the default group of the sudoers file. +It must be specified as a numeric group-ID (not a group name). +.TP 10n +sudoers_mode=mode +The +\fIsudoers_mode\fR +argument can be used to override the default file mode for the sudoers file. +It should be specified as an octal value. +.PP +For more information on configuring +sudo.conf(@mansectform@), +please refer to its manual. +.SH "ENVIRONMENT" +The following environment variables may be consulted depending on +the value of the +\fIeditor\fR +and +\fIenv_editor\fR +\fIsudoers\fR +settings: +.TP 17n +\fRSUDO_EDITOR\fR +Invoked by +\fBvisudo\fR +as the editor to use +.TP 17n +\fRVISUAL\fR +Used by +\fBvisudo\fR +if +\fRSUDO_EDITOR\fR +is not set +.TP 17n +\fREDITOR\fR +Used by +\fBvisudo\fR +if neither +\fRSUDO_EDITOR\fR +nor +\fRVISUAL\fR +is set +.SH "FILES" +.TP 26n +\fI@sysconfdir@/sudo.conf\fR +Sudo front end configuration +.TP 26n +\fI@sysconfdir@/sudoers\fR +List of who can run what +.TP 26n +\fI@sysconfdir@/sudoers.tmp\fR +Default temporary file used by visudo +.SH "DIAGNOSTICS" +In addition to reporting +\fIsudoers\fR +syntax errors, +\fBvisudo\fR +may produce the following messages: +.TP 6n +\fRsudoers file busy, try again later.\fR +Someone else is currently editing the +\fIsudoers\fR +file. +.TP 6n +\fR@sysconfdir@/sudoers: Permission denied\fR +You didn't run +\fBvisudo\fR +as root. +.TP 6n +\fRyou do not exist in the passwd database\fR +Your user-ID does not appear in the system passwd database. +.TP 6n +\fRWarning: {User,Runas,Host,Cmnd}_Alias referenced but not defined\fR +Either you are trying to use an undeclared {User,Runas,Host,Cmnd}_Alias +or you have a user or host name listed that consists solely of +uppercase letters, digits, and the underscore +(\(oq_\(cq) +character. +In the latter case, you can ignore the warnings +(\fBsudo\fR +will not complain) +\&. +The message is prefixed with the path name of the +\fIsudoers\fR +file and the line number where the undefined alias was used. +In +\fB\-s\fR +(strict) mode these are errors, not warnings. +.TP 6n +\fRWarning: unused {User,Runas,Host,Cmnd}_Alias\fR +The specified {User,Runas,Host,Cmnd}_Alias was defined but never +used. +The message is prefixed with the path name of the +\fIsudoers\fR +file and the line number where the unused alias was defined. +You may wish to comment out or remove the unused alias. +.TP 6n +\fRWarning: cycle in {User,Runas,Host,Cmnd}_Alias\fR +The specified {User,Runas,Host,Cmnd}_Alias includes a reference to +itself, either directly or through an alias it includes. +The message is prefixed with the path name of the +\fIsudoers\fR +file and the line number where the cycle was detected. +This is only a warning unless +\fBvisudo\fR +is run in +\fB\-s\fR +(strict) mode as +\fBsudo\fR +will ignore cycles when parsing +the +\fIsudoers\fR +file. +.TP 6n +\fRunknown defaults entry \&"name\&"\fR +The +\fIsudoers\fR +file contains a +\fRDefaults\fR +setting not recognized by +\fBvisudo\fR. +.SH "SEE ALSO" +vi(1), +sudo.conf(@mansectform@), +sudoers(@mansectform@), +sudo(@mansectsu@), +vipw(@mansectsu@) +.SH "AUTHORS" +Many people have worked on +\fBsudo\fR +over the years; this version consists of code written primarily by: +.sp +.RS 6n +Todd C. Miller +.RE +.PP +See the CONTRIBUTORS file in the +\fBsudo\fR +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +\fBsudo\fR. +.SH "CAVEATS" +There is no easy way to prevent a user from gaining a root shell if +the editor used by +\fBvisudo\fR +allows shell escapes. +.SH "BUGS" +If you feel you have found a bug in +\fBvisudo\fR, +please submit a bug report at https://bugzilla.sudo.ws/ +.SH "SUPPORT" +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.SH "DISCLAIMER" +\fBvisudo\fR +is provided +\(lqAS IS\(rq +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +\fBsudo\fR +or https://www.sudo.ws/license.html for complete details. diff --git a/doc/visudo.mdoc.in b/doc/visudo.mdoc.in new file mode 100644 index 0000000..278040b --- /dev/null +++ b/doc/visudo.mdoc.in @@ -0,0 +1,457 @@ +.\" +.\" SPDX-License-Identifier: ISC +.\" +.\" Copyright (c) 1996,1998-2005, 2007-2020 +.\" 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. +.\" +.\" Sponsored in part by the Defense Advanced Research Projects +.\" Agency (DARPA) and Air Force Research Laboratory, Air Force +.\" Materiel Command, USAF, under agreement number F39502-99-1-0512. +.\" +.Dd August 27, 2020 +.Dt VISUDO @mansectsu@ +.Os Sudo @PACKAGE_VERSION@ +.Sh NAME +.Nm visudo +.Nd edit the sudoers file +.Sh SYNOPSIS +.Nm visudo +.Op Fl chqsV +.Op Bo Fl f Bc Ar sudoers +.Sh DESCRIPTION +.Nm +edits the +.Em sudoers +file in a safe fashion, analogous to +.Xr vipw @mansectsu@ . +.Nm +locks the +.Em sudoers +file against multiple simultaneous edits, performs basic validity checks, +and checks for syntax errors before installing the edited file. +If the +.Em sudoers +file is currently being edited you will receive a message to try again later. +.Pp +.Nm +parses the +.Em sudoers +file after editing and will not save the changes if there is a syntax error. +Upon finding an error, +.Nm +will print a message stating the line number(s) +where the error occurred and the user will receive the +.Dq What now? +prompt. +At this point the user may enter +.Ql e +to re-edit the +.Em sudoers +file, +.Ql x +to exit without saving the changes, or +.Ql Q +to quit and save changes. +The +.Ql Q +option should be used with extreme caution because if +.Nm +believes there to be a syntax error, so will +.Nm sudo +and no one will be able to run +.Nm sudo +again until the error is fixed. +If +.Ql e +is typed to edit the +.Em sudoers +file after a syntax error has been detected, the cursor will be placed on +the line where the error occurred (if the editor supports this feature). +.Pp +There are two +.Em sudoers +settings that determine which editor +.Nm visudo +will run. +.Bl -tag -width 8n +.It editor +A colon +.Pq Ql :\& +separated list of editors allowed to be used with +.Nm . +.Nm +will choose the editor that matches the user's +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variable if possible, or the first editor in the +list that exists and is executable. +Note that +.Nm sudo +does not preserve the +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variables unless they are present in the +.Em env_keep +list or the +.Em env_reset +option is disabled in the +.Em sudoers +file. +The default editor path is +.Pa @editor@ +which can be set at compile time via the +.Li --with-editor +configure option. +.It env_editor +If set, +.Nm +will use the value of the +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +environment variables before falling back on the default editor list. +Note that +.Nm visudo +is typically run as root so this option may allow a user with +.Nm visudo +privileges to run arbitrary commands as root without logging. +An alternative is to place a colon-separated list of +.Dq safe +editors int the +.Em editor +variable. +.Nm +will then only use +.Ev SUDO_EDITOR , +.Ev VISUAL +or +.Ev EDITOR +if they match a value specified in +.Em editor . +If the +.Em env_reset +flag is enabled, the +.Ev SUDO_EDITOR , +.Ev VISUAL +and/or +.Ev EDITOR +environment variables must be present in the +.Em env_keep +list for the +.Em env_editor +flag to function when +.Nm +is invoked via +.Nm sudo . +The default value is +.Em @env_editor@ , +which can be set at compile time via the +.Li --with-env-editor +configure option. +.El +.Pp +The options are as follows: +.Bl -tag -width Fl +.It Fl c , -check +Enable +.Em check-only +mode. +The existing +.Em sudoers +file (and any other files it includes) will be +checked for syntax errors. +If the path to the +.Em sudoers +file was not specified, +.Nm +will also check the file owner and mode. +A message will be printed to the standard output describing the status of +.Em sudoers +unless the +.Fl q +option was specified. +If the check completes successfully, +.Nm +will exit with a value of 0. +If an error is encountered, +.Nm +will exit with a value of 1. +.It Fl f Ar sudoers , Fl -file Ns = Ns Ar sudoers +Specify an alternate +.Em sudoers +file location, see below. +As of version 1.8.27, the +.Em sudoers +path can be specified without using the +.Fl f +option. +.It Fl h , -help +Display a short help message to the standard output and exit. +.It Fl q , -quiet +Enable +.Em quiet +mode. +In this mode details about syntax errors are not printed. +This option is only useful when combined with +the +.Fl c +option. +.It Fl s , -strict +Enable +.Em strict +checking of the +.Em sudoers +file. +If an alias is referenced but not actually defined +or if there is a cycle in an alias, +.Nm +will consider this a syntax error. +Note that it is not possible to differentiate between an +alias and a host name or user name that consists solely of uppercase +letters, digits, and the underscore +.Pq Ql _ +character. +.It Fl V , -version +Print the +.Nm +and +.Em sudoers +grammar versions and exit. +.El +.Pp +A +.Em sudoers +file may be specified instead of the default, +.Pa @sysconfdir@/sudoers . +The temporary file used is the specified +.Em sudoers +file with +.Dq \.tmp +appended to it. +In +.Em check-only +mode only, +.Ql - +may be used to indicate that +.Em sudoers +will be read from the standard input. +Because the policy is evaluated in its entirety, it is not sufficient +to check an individual +.Em sudoers +include file for syntax errors. +.Ss Debugging and sudoers plugin arguments +.Nm +versions 1.8.4 and higher support a flexible debugging framework +that is configured via +.Li Debug +lines in the +.Xr sudo.conf @mansectform@ +file. +.Pp +Starting with +.Nm sudo +1.8.12, +.Nm +will also parse the arguments to the +.Em sudoers +plugin to override the default +.Em sudoers +path name, UID, GID and file mode. +These arguments, if present, should be listed after the path to the plugin +(i.e., after +.Pa sudoers.so ) . +Multiple arguments may be specified, separated by white space. +For example: +.Bd -literal -offset indent +Plugin sudoers_policy sudoers.so sudoers_mode=0400 +.Ed +.Pp +The following arguments are supported: +.Bl -tag -width 8n +.It sudoers_file=pathname +The +.Em sudoers_file +argument can be used to override the default path to the +.Em sudoers +file. +.It sudoers_uid=uid +The +.Em sudoers_uid +argument can be used to override the default owner of the sudoers file. +It should be specified as a numeric user-ID. +.It sudoers_gid=gid +The +.Em sudoers_gid +argument can be used to override the default group of the sudoers file. +It must be specified as a numeric group-ID (not a group name). +.It sudoers_mode=mode +The +.Em sudoers_mode +argument can be used to override the default file mode for the sudoers file. +It should be specified as an octal value. +.El +.Pp +For more information on configuring +.Xr sudo.conf @mansectform@ , +please refer to its manual. +.Sh ENVIRONMENT +The following environment variables may be consulted depending on +the value of the +.Em editor +and +.Em env_editor +.Em sudoers +settings: +.Bl -tag -width 15n +.It Ev SUDO_EDITOR +Invoked by +.Nm +as the editor to use +.It Ev VISUAL +Used by +.Nm +if +.Ev SUDO_EDITOR +is not set +.It Ev EDITOR +Used by +.Nm +if neither +.Ev SUDO_EDITOR +nor +.Ev VISUAL +is set +.El +.Sh FILES +.Bl -tag -width 24n +.It Pa @sysconfdir@/sudo.conf +Sudo front end configuration +.It Pa @sysconfdir@/sudoers +List of who can run what +.It Pa @sysconfdir@/sudoers.tmp +Default temporary file used by visudo +.El +.Sh DIAGNOSTICS +In addition to reporting +.Em sudoers +syntax errors, +.Nm +may produce the following messages: +.Bl -tag -width 4n +.It Li sudoers file busy, try again later. +Someone else is currently editing the +.Em sudoers +file. +.It Li @sysconfdir@/sudoers: Permission denied +You didn't run +.Nm +as root. +.It Li you do not exist in the passwd database +Your user-ID does not appear in the system passwd database. +.It Li Warning: {User,Runas,Host,Cmnd}_Alias referenced but not defined +Either you are trying to use an undeclared {User,Runas,Host,Cmnd}_Alias +or you have a user or host name listed that consists solely of +uppercase letters, digits, and the underscore +.Pq Ql _ +character. +In the latter case, you can ignore the warnings +.Po +.Nm sudo +will not complain +.Pc . +The message is prefixed with the path name of the +.Em sudoers +file and the line number where the undefined alias was used. +In +.Fl s +(strict) mode these are errors, not warnings. +.It Li Warning: unused {User,Runas,Host,Cmnd}_Alias +The specified {User,Runas,Host,Cmnd}_Alias was defined but never +used. +The message is prefixed with the path name of the +.Em sudoers +file and the line number where the unused alias was defined. +You may wish to comment out or remove the unused alias. +.It Li Warning: cycle in {User,Runas,Host,Cmnd}_Alias +The specified {User,Runas,Host,Cmnd}_Alias includes a reference to +itself, either directly or through an alias it includes. +The message is prefixed with the path name of the +.Em sudoers +file and the line number where the cycle was detected. +This is only a warning unless +.Nm +is run in +.Fl s +(strict) mode as +.Nm sudo +will ignore cycles when parsing +the +.Em sudoers +file. +.It Li unknown defaults entry \&"name\&" +The +.Em sudoers +file contains a +.Li Defaults +setting not recognized by +.Nm . +.El +.Sh SEE ALSO +.Xr vi 1 , +.Xr sudo.conf @mansectform@ , +.Xr sudoers @mansectform@ , +.Xr sudo @mansectsu@ , +.Xr vipw @mansectsu@ +.Sh AUTHORS +Many people have worked on +.Nm sudo +over the years; this version consists of code written primarily by: +.Bd -ragged -offset indent +.An Todd C. Miller +.Ed +.Pp +See the CONTRIBUTORS file in the +.Nm sudo +distribution (https://www.sudo.ws/contributors.html) for an +exhaustive list of people who have contributed to +.Nm sudo . +.Sh CAVEATS +There is no easy way to prevent a user from gaining a root shell if +the editor used by +.Nm +allows shell escapes. +.Sh BUGS +If you feel you have found a bug in +.Nm , +please submit a bug report at https://bugzilla.sudo.ws/ +.Sh SUPPORT +Limited free support is available via the sudo-users mailing list, +see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or +search the archives. +.Sh DISCLAIMER +.Nm +is provided +.Dq AS IS +and any express or implied warranties, including, but not limited +to, the implied warranties of merchantability and fitness for a +particular purpose are disclaimed. +See the LICENSE file distributed with +.Nm sudo +or https://www.sudo.ws/license.html for complete details. |