1999-07-11 00:32:11 +00:00
|
|
|
/*
|
2019-04-29 07:21:51 -06:00
|
|
|
* SPDX-License-Identifier: ISC
|
|
|
|
*
|
2020-04-01 14:41:38 -06:00
|
|
|
* Copyright (c) 1999-2005, 2008-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
1999-07-11 00:32:11 +00:00
|
|
|
*
|
2004-02-13 21:36:49 +00:00
|
|
|
* 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.
|
1999-07-31 16:19:50 +00:00
|
|
|
*
|
2004-02-13 21:36:49 +00:00
|
|
|
* 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.
|
2003-04-16 00:42:10 +00:00
|
|
|
*
|
|
|
|
* 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.
|
1999-07-11 00:32:11 +00:00
|
|
|
*/
|
|
|
|
|
2018-10-26 08:39:09 -06:00
|
|
|
/*
|
|
|
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
|
|
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
|
|
|
*/
|
2018-10-21 08:46:05 -06:00
|
|
|
|
2004-11-19 18:39:14 +00:00
|
|
|
#include <config.h>
|
1999-07-11 00:32:11 +00:00
|
|
|
|
2001-12-09 05:17:00 +00:00
|
|
|
#include <sys/types.h>
|
1999-07-11 00:32:11 +00:00
|
|
|
#include <stdio.h>
|
2015-06-19 14:29:27 -06:00
|
|
|
#include <stdlib.h>
|
2018-05-24 21:04:23 -06:00
|
|
|
#if defined(HAVE_STDINT_H)
|
|
|
|
# include <stdint.h>
|
|
|
|
#elif defined(HAVE_INTTYPES_H)
|
|
|
|
# include <inttypes.h>
|
|
|
|
#endif
|
2020-05-18 07:59:24 -06:00
|
|
|
#include <string.h>
|
2015-07-02 09:08:28 -06:00
|
|
|
#include <unistd.h>
|
1999-07-11 00:32:11 +00:00
|
|
|
#include <pwd.h>
|
1999-08-12 16:24:10 +00:00
|
|
|
#include <time.h>
|
2001-12-09 05:17:00 +00:00
|
|
|
#include <signal.h>
|
1999-07-11 00:32:11 +00:00
|
|
|
|
2010-03-14 19:58:47 -04:00
|
|
|
#include "sudoers.h"
|
1999-07-11 00:32:11 +00:00
|
|
|
#include "sudo_auth.h"
|
|
|
|
#include "insults.h"
|
2023-08-29 11:16:23 -06:00
|
|
|
#include "timestamp.h"
|
1999-07-11 00:32:11 +00:00
|
|
|
|
2010-05-27 14:53:11 -04:00
|
|
|
static sudo_auth auth_switch[] = {
|
|
|
|
/* Standalone entries first */
|
2015-02-23 11:12:43 -07:00
|
|
|
#ifdef HAVE_AIXAUTH
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("aixauth", FLAG_STANDALONE, sudo_aix_init, NULL, sudo_aix_verify, NULL, sudo_aix_cleanup, NULL, NULL)
|
2015-02-23 11:12:43 -07:00
|
|
|
#endif
|
2010-05-27 14:53:11 -04:00
|
|
|
#ifdef HAVE_PAM
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("pam", FLAG_STANDALONE, sudo_pam_init, NULL, sudo_pam_verify, sudo_pam_approval, sudo_pam_cleanup, sudo_pam_begin_session, sudo_pam_end_session)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SECURID
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("SecurId", FLAG_STANDALONE, sudo_securid_init, sudo_securid_setup, sudo_securid_verify, NULL, NULL, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SIA_SES_INIT
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("sia", FLAG_STANDALONE, NULL, sudo_sia_setup, sudo_sia_verify, NULL, sudo_sia_cleanup, sudo_sia_begin_session, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_FWTK
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("fwtk", FLAG_STANDALONE, sudo_fwtk_init, NULL, sudo_fwtk_verify, NULL, sudo_fwtk_cleanup, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_BSD_AUTH_H
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("bsdauth", FLAG_STANDALONE, bsdauth_init, NULL, bsdauth_verify, bsdauth_approval, bsdauth_cleanup, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Non-standalone entries */
|
|
|
|
#ifndef WITHOUT_PASSWD
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("passwd", 0, sudo_passwd_init, NULL, sudo_passwd_verify, NULL, sudo_passwd_cleanup, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#if defined(HAVE_GETPRPWNAM) && !defined(WITHOUT_PASSWD)
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("secureware", 0, sudo_secureware_init, NULL, sudo_secureware_verify, NULL, sudo_secureware_cleanup, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_AFS
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("afs", 0, NULL, NULL, sudo_afs_verify, NULL, NULL, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_DCE
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("dce", 0, NULL, NULL, sudo_dce_verify, NULL, NULL, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_KERB5
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("kerb5", 0, sudo_krb5_init, sudo_krb5_setup, sudo_krb5_verify, NULL, sudo_krb5_cleanup, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_SKEY
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("S/Key", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_OPIE
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY("OPIE", 0, NULL, sudo_rfc1938_setup, sudo_rfc1938_verify, NULL, NULL, NULL, NULL)
|
2010-05-27 14:53:11 -04:00
|
|
|
#endif
|
2018-01-16 10:27:58 -07:00
|
|
|
AUTH_ENTRY(NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
|
1999-07-11 00:32:11 +00:00
|
|
|
};
|
|
|
|
|
2016-01-27 16:19:22 -07:00
|
|
|
static bool standalone;
|
2011-09-27 13:18:46 -04:00
|
|
|
|
2012-07-10 12:42:33 -04:00
|
|
|
/*
|
|
|
|
* Initialize sudoers authentication method(s).
|
2023-09-09 14:07:07 -06:00
|
|
|
* Returns AUTH_SUCCESS on success and AUTH_ERROR on error.
|
2012-07-10 12:42:33 -04:00
|
|
|
*/
|
2010-03-14 19:58:47 -04:00
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
sudo_auth_init(const struct sudoers_context *ctx, struct passwd *pw,
|
|
|
|
unsigned int mode)
|
1999-07-11 00:32:11 +00:00
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_init, SUDOERS_DEBUG_AUTH);
|
1999-07-11 00:32:11 +00:00
|
|
|
|
2011-09-27 13:18:46 -04:00
|
|
|
if (auth_switch[0].name == NULL)
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_SUCCESS);
|
1999-08-28 09:50:27 +00:00
|
|
|
|
1999-07-22 19:48:27 +00:00
|
|
|
/* Initialize auth methods and unconfigure the method if necessary. */
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
2022-01-04 18:57:36 -07:00
|
|
|
if (ISSET(mode, MODE_NONINTERACTIVE))
|
|
|
|
SET(auth->flags, FLAG_NONINTERACTIVE);
|
2010-05-27 14:53:11 -04:00
|
|
|
if (auth->init && !IS_DISABLED(auth)) {
|
2012-07-10 12:42:33 -04:00
|
|
|
/* Disable if it failed to init unless there was a fatal error. */
|
2023-09-09 14:07:07 -06:00
|
|
|
switch ((auth->init)(ctx, pw, auth)) {
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
case AUTH_SUCCESS:
|
|
|
|
break;
|
|
|
|
case AUTH_FAILURE:
|
2011-09-27 15:22:08 -04:00
|
|
|
SET(auth->flags, FLAG_DISABLED);
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Assume error msg already printed. */
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_ERROR);
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
}
|
2011-09-27 13:18:46 -04:00
|
|
|
}
|
|
|
|
}
|
2015-02-23 11:12:43 -07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure we haven't mixed standalone and shared auth methods.
|
|
|
|
* If there are multiple standalone methods, only use the first one.
|
|
|
|
*/
|
|
|
|
if ((standalone = IS_STANDALONE(&auth_switch[0]))) {
|
|
|
|
bool found = false;
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
|
|
|
if (IS_DISABLED(auth))
|
|
|
|
continue;
|
|
|
|
if (!IS_STANDALONE(auth)) {
|
2023-08-21 09:22:24 -06:00
|
|
|
audit_failure(ctx, ctx->runas.argv,
|
2023-08-21 09:21:49 -06:00
|
|
|
N_("invalid authentication methods"));
|
|
|
|
log_warningx(ctx, SLOG_SEND_MAIL,
|
2015-02-23 11:12:43 -07:00
|
|
|
N_("Invalid authentication methods compiled into sudo! "
|
|
|
|
"You may not mix standalone and non-standalone authentication."));
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_ERROR);
|
2015-02-23 11:12:43 -07:00
|
|
|
}
|
|
|
|
if (!found) {
|
|
|
|
/* Found first standalone method. */
|
|
|
|
found = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Disable other standalone methods. */
|
|
|
|
SET(auth->flags, FLAG_DISABLED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set FLAG_ONEANDONLY if there is only one auth method. */
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
|
|
|
/* Find first enabled auth method. */
|
|
|
|
if (!IS_DISABLED(auth)) {
|
|
|
|
sudo_auth *first = auth;
|
|
|
|
/* Check for others. */
|
|
|
|
for (; auth->name; auth++) {
|
|
|
|
if (!IS_DISABLED(auth))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (auth->name == NULL)
|
|
|
|
SET(first->flags, FLAG_ONEANDONLY);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_SUCCESS);
|
2011-09-27 13:18:46 -04:00
|
|
|
}
|
|
|
|
|
2018-01-16 10:27:58 -07:00
|
|
|
/*
|
2023-09-09 14:07:07 -06:00
|
|
|
* Call all authentication approval methods, if any.
|
|
|
|
* Returns AUTH_SUCCESS, AUTH_FAILURE or AUTH_ERROR.
|
2018-01-16 10:27:58 -07:00
|
|
|
*/
|
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
sudo_auth_approval(const struct sudoers_context *ctx, struct passwd *pw,
|
|
|
|
unsigned int validated, bool exempt)
|
2018-01-16 10:27:58 -07:00
|
|
|
{
|
2023-09-09 14:07:07 -06:00
|
|
|
int ret = AUTH_SUCCESS;
|
2018-01-16 10:27:58 -07:00
|
|
|
sudo_auth *auth;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_approval, SUDOERS_DEBUG_AUTH);
|
2018-01-16 10:27:58 -07:00
|
|
|
|
|
|
|
/* Call approval routines. */
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
|
|
|
if (auth->approval && !IS_DISABLED(auth)) {
|
2023-09-09 14:07:07 -06:00
|
|
|
ret = (auth->approval)(ctx, pw, auth, exempt);
|
|
|
|
if (ret != AUTH_SUCCESS) {
|
2018-01-16 10:27:58 -07:00
|
|
|
/* Assume error msg already printed. */
|
2023-08-21 09:21:49 -06:00
|
|
|
log_auth_failure(ctx, validated, 0);
|
2023-09-09 14:07:07 -06:00
|
|
|
break;
|
2018-01-16 10:27:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(ret);
|
2018-01-16 10:27:58 -07:00
|
|
|
}
|
|
|
|
|
2012-07-10 12:42:33 -04:00
|
|
|
/*
|
|
|
|
* Cleanup all authentication methods.
|
2023-09-09 14:07:07 -06:00
|
|
|
* Returns AUTH_SUCCESS on success and AUTH_ERROR on error.
|
2012-07-10 12:42:33 -04:00
|
|
|
*/
|
2011-09-27 13:18:46 -04:00
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
sudo_auth_cleanup(const struct sudoers_context *ctx, struct passwd *pw,
|
|
|
|
bool force)
|
2011-09-27 13:18:46 -04:00
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_cleanup, SUDOERS_DEBUG_AUTH);
|
2011-09-27 13:18:46 -04:00
|
|
|
|
|
|
|
/* Call cleanup routines. */
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
|
|
|
if (auth->cleanup && !IS_DISABLED(auth)) {
|
2023-08-21 09:21:49 -06:00
|
|
|
int status = (auth->cleanup)(ctx, pw, auth, force);
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
if (status != AUTH_SUCCESS) {
|
2018-01-16 10:27:58 -07:00
|
|
|
/* Assume error msg already printed. */
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_ERROR);
|
2018-01-16 10:27:58 -07:00
|
|
|
}
|
1999-07-22 19:48:27 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_SUCCESS);
|
2011-09-27 13:18:46 -04:00
|
|
|
}
|
|
|
|
|
2014-09-26 20:39:40 -06:00
|
|
|
static void
|
|
|
|
pass_warn(void)
|
|
|
|
{
|
|
|
|
const char *warning = def_badpass_message;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(pass_warn, SUDOERS_DEBUG_AUTH);
|
2014-09-26 20:39:40 -06:00
|
|
|
|
|
|
|
#ifdef INSULT
|
|
|
|
if (def_insults)
|
|
|
|
warning = INSULT;
|
|
|
|
#endif
|
2019-08-26 19:30:11 -06:00
|
|
|
sudo_printf(SUDO_CONV_ERROR_MSG|SUDO_CONV_PREFER_TTY, "%s\n", warning);
|
2014-09-26 20:39:40 -06:00
|
|
|
|
|
|
|
debug_return;
|
|
|
|
}
|
|
|
|
|
2014-09-27 10:16:31 -06:00
|
|
|
static bool
|
|
|
|
user_interrupted(void)
|
|
|
|
{
|
|
|
|
sigset_t mask;
|
|
|
|
|
|
|
|
return (sigpending(&mask) == 0 &&
|
|
|
|
(sigismember(&mask, SIGINT) || sigismember(&mask, SIGQUIT)));
|
|
|
|
}
|
|
|
|
|
2012-07-10 12:42:33 -04:00
|
|
|
/*
|
|
|
|
* Verify the specified user.
|
2023-09-09 14:07:07 -06:00
|
|
|
* Returns AUTH_SUCCESS, AUTH_FAILURE or AUTH_ERROR.
|
2012-07-10 12:42:33 -04:00
|
|
|
*/
|
2011-09-27 13:18:46 -04:00
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
verify_user(const struct sudoers_context *ctx, struct passwd *pw, char *prompt,
|
|
|
|
unsigned int validated, struct sudo_conv_callback *callback)
|
2011-09-27 13:18:46 -04:00
|
|
|
{
|
2023-09-09 14:07:07 -06:00
|
|
|
struct sigaction sa, saved_sigtstp;
|
|
|
|
int ret = AUTH_FAILURE;
|
2014-09-27 10:17:21 -06:00
|
|
|
unsigned int ntries;
|
2014-09-27 10:16:31 -06:00
|
|
|
sigset_t mask, omask;
|
2023-09-09 14:07:07 -06:00
|
|
|
sudo_auth *auth;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(verify_user, SUDOERS_DEBUG_AUTH);
|
2011-09-27 13:18:46 -04:00
|
|
|
|
|
|
|
/* Make sure we have at least one auth method. */
|
|
|
|
if (auth_switch[0].name == NULL) {
|
2023-08-21 09:22:24 -06:00
|
|
|
audit_failure(ctx, ctx->runas.argv, N_("no authentication methods"));
|
2023-08-21 09:21:49 -06:00
|
|
|
log_warningx(ctx, SLOG_SEND_MAIL,
|
2012-11-08 15:37:44 -05:00
|
|
|
N_("There are no authentication methods compiled into sudo! "
|
2011-09-27 13:18:46 -04:00
|
|
|
"If you want to turn off authentication, use the "
|
|
|
|
"--disable-authentication configure option."));
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_ERROR);
|
2011-09-27 13:18:46 -04:00
|
|
|
}
|
1999-07-22 19:48:27 +00:00
|
|
|
|
2014-09-27 10:16:31 -06:00
|
|
|
/* Enable suspend during password entry. */
|
|
|
|
sigemptyset(&sa.sa_mask);
|
|
|
|
sa.sa_flags = SA_RESTART;
|
|
|
|
sa.sa_handler = SIG_DFL;
|
|
|
|
(void) sigaction(SIGTSTP, &sa, &saved_sigtstp);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We treat authentication as a critical section and block
|
|
|
|
* keyboard-generated signals such as SIGINT and SIGQUIT
|
|
|
|
* which might otherwise interrupt a sleep(3).
|
|
|
|
* They are temporarily unblocked by auth_getpass().
|
|
|
|
*/
|
|
|
|
sigemptyset(&mask);
|
|
|
|
sigaddset(&mask, SIGINT);
|
|
|
|
sigaddset(&mask, SIGQUIT);
|
|
|
|
(void) sigprocmask(SIG_BLOCK, &mask, &omask);
|
|
|
|
|
2014-09-27 10:17:21 -06:00
|
|
|
for (ntries = 0; ntries < def_passwd_tries; ntries++) {
|
2014-09-26 20:55:19 -06:00
|
|
|
int num_methods = 0;
|
2016-01-27 16:19:22 -07:00
|
|
|
char *pass = NULL;
|
2014-09-26 20:55:19 -06:00
|
|
|
|
2014-09-27 10:16:31 -06:00
|
|
|
/* If user attempted to interrupt password verify, quit now. */
|
|
|
|
if (user_interrupted())
|
|
|
|
goto done;
|
|
|
|
|
2014-09-27 10:17:21 -06:00
|
|
|
if (ntries != 0)
|
2014-09-27 10:16:31 -06:00
|
|
|
pass_warn();
|
|
|
|
|
1999-07-11 00:32:11 +00:00
|
|
|
/* Do any per-method setup and unconfigure the method if needed */
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
2014-09-26 20:55:19 -06:00
|
|
|
if (IS_DISABLED(auth))
|
|
|
|
continue;
|
|
|
|
num_methods++;
|
|
|
|
if (auth->setup != NULL) {
|
2023-09-09 14:07:07 -06:00
|
|
|
switch ((auth->setup)(ctx, pw, &prompt, auth)) {
|
|
|
|
case AUTH_SUCCESS:
|
|
|
|
if (user_interrupted())
|
|
|
|
goto done; /* assume error msg already printed */
|
|
|
|
break;
|
|
|
|
case AUTH_FAILURE:
|
2010-05-27 14:53:11 -04:00
|
|
|
SET(auth->flags, FLAG_DISABLED);
|
2023-09-09 14:07:07 -06:00
|
|
|
break;
|
|
|
|
case AUTH_NONINTERACTIVE:
|
|
|
|
/* Non-interactive mode, cannot prompt user. */
|
|
|
|
goto done;
|
|
|
|
default:
|
|
|
|
ret = AUTH_ERROR;
|
2022-01-04 18:57:36 -07:00
|
|
|
goto done;
|
2023-09-09 14:07:07 -06:00
|
|
|
}
|
1999-07-11 00:32:11 +00:00
|
|
|
}
|
|
|
|
}
|
2014-09-26 20:55:19 -06:00
|
|
|
if (num_methods == 0) {
|
2023-08-21 09:22:24 -06:00
|
|
|
audit_failure(ctx, ctx->runas.argv,
|
|
|
|
N_("no authentication methods"));
|
2023-08-21 09:21:49 -06:00
|
|
|
log_warningx(ctx, SLOG_SEND_MAIL,
|
2014-09-26 20:55:19 -06:00
|
|
|
N_("Unable to initialize authentication methods."));
|
2023-09-09 14:07:07 -06:00
|
|
|
debug_return_int(AUTH_ERROR);
|
2014-09-26 20:55:19 -06:00
|
|
|
}
|
1999-07-11 00:32:11 +00:00
|
|
|
|
|
|
|
/* Get the password unless the auth function will do it for us */
|
2016-01-27 16:19:22 -07:00
|
|
|
if (!standalone) {
|
2022-01-05 11:04:18 -07:00
|
|
|
if (IS_NONINTERACTIVE(&auth_switch[0])) {
|
2023-09-09 14:07:07 -06:00
|
|
|
ret = AUTH_NONINTERACTIVE;
|
2022-01-04 18:57:36 -07:00
|
|
|
goto done;
|
|
|
|
}
|
2018-01-22 12:18:48 -07:00
|
|
|
pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
|
2016-01-27 16:19:22 -07:00
|
|
|
if (pass == NULL)
|
2010-08-06 17:16:57 -04:00
|
|
|
break;
|
|
|
|
}
|
1999-07-11 00:32:11 +00:00
|
|
|
|
|
|
|
/* Call authentication functions. */
|
2010-08-06 17:16:57 -04:00
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
2010-05-27 14:53:11 -04:00
|
|
|
if (IS_DISABLED(auth))
|
1999-07-11 00:32:11 +00:00
|
|
|
continue;
|
|
|
|
|
2023-09-09 14:07:07 -06:00
|
|
|
ret = auth->status = (auth->verify)(ctx, pw,
|
2023-08-21 09:21:49 -06:00
|
|
|
standalone ? prompt : pass, auth, callback);
|
2023-09-09 14:07:07 -06:00
|
|
|
if (ret != AUTH_FAILURE)
|
2014-09-27 10:16:31 -06:00
|
|
|
break;
|
1999-07-11 00:32:11 +00:00
|
|
|
}
|
2020-08-10 19:24:33 -06:00
|
|
|
if (pass != NULL)
|
|
|
|
freezero(pass, strlen(pass));
|
2014-09-27 10:16:31 -06:00
|
|
|
|
2023-09-09 14:07:07 -06:00
|
|
|
if (ret != AUTH_FAILURE)
|
2014-09-27 10:16:31 -06:00
|
|
|
goto done;
|
1999-07-11 00:32:11 +00:00
|
|
|
}
|
|
|
|
|
2011-09-27 13:18:46 -04:00
|
|
|
done:
|
2014-09-27 10:16:31 -06:00
|
|
|
/* Restore signal handlers and signal mask. */
|
|
|
|
(void) sigaction(SIGTSTP, &saved_sigtstp, NULL);
|
|
|
|
(void) sigprocmask(SIG_SETMASK, &omask, NULL);
|
|
|
|
|
2023-09-09 14:07:07 -06:00
|
|
|
switch (ret) {
|
1999-07-11 00:32:11 +00:00
|
|
|
case AUTH_SUCCESS:
|
2010-03-14 19:58:47 -04:00
|
|
|
break;
|
2023-08-29 10:02:09 -06:00
|
|
|
case AUTH_INTR:
|
2023-09-09 14:07:07 -06:00
|
|
|
ret = AUTH_FAILURE;
|
|
|
|
FALLTHROUGH;
|
1999-07-11 00:32:11 +00:00
|
|
|
case AUTH_FAILURE:
|
2014-09-27 10:17:21 -06:00
|
|
|
if (ntries != 0)
|
2022-01-04 18:57:36 -07:00
|
|
|
SET(validated, FLAG_BAD_PASSWORD);
|
2023-08-21 09:21:49 -06:00
|
|
|
log_auth_failure(ctx, validated, ntries);
|
2010-03-14 19:58:47 -04:00
|
|
|
break;
|
2022-01-04 18:57:36 -07:00
|
|
|
case AUTH_NONINTERACTIVE:
|
|
|
|
SET(validated, FLAG_NO_USER_INPUT);
|
|
|
|
FALLTHROUGH;
|
2010-03-14 19:58:47 -04:00
|
|
|
default:
|
2023-08-21 09:21:49 -06:00
|
|
|
log_auth_failure(ctx, validated, 0);
|
2023-09-09 14:07:07 -06:00
|
|
|
ret = AUTH_ERROR;
|
2010-03-14 19:58:47 -04:00
|
|
|
break;
|
1999-07-11 00:32:11 +00:00
|
|
|
}
|
2010-03-14 19:58:47 -04:00
|
|
|
|
2016-09-08 16:38:08 -06:00
|
|
|
debug_return_int(ret);
|
1999-07-11 00:32:11 +00:00
|
|
|
}
|
|
|
|
|
2012-07-10 12:42:33 -04:00
|
|
|
/*
|
|
|
|
* Call authentication method begin session hooks.
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
* Returns true on success, false on failure and -1 on error.
|
2012-07-10 12:42:33 -04:00
|
|
|
*/
|
2011-09-27 13:18:46 -04:00
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
sudo_auth_begin_session(const struct sudoers_context *ctx, struct passwd *pw,
|
|
|
|
char **user_env[])
|
2010-05-26 17:57:47 -04:00
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
int ret = true;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH);
|
2010-05-26 17:57:47 -04:00
|
|
|
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
2010-05-27 14:53:11 -04:00
|
|
|
if (auth->begin_session && !IS_DISABLED(auth)) {
|
2023-08-21 09:21:49 -06:00
|
|
|
int status = (auth->begin_session)(ctx, pw, user_env, auth);
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
switch (status) {
|
|
|
|
case AUTH_SUCCESS:
|
|
|
|
break;
|
|
|
|
case AUTH_FAILURE:
|
|
|
|
ret = false;
|
|
|
|
break;
|
|
|
|
default:
|
2018-01-16 10:27:58 -07:00
|
|
|
/* Assume error msg already printed. */
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
ret = -1;
|
|
|
|
break;
|
2018-01-16 10:27:58 -07:00
|
|
|
}
|
2010-05-26 17:57:47 -04:00
|
|
|
}
|
|
|
|
}
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
debug_return_int(ret);
|
2010-05-26 17:57:47 -04:00
|
|
|
}
|
|
|
|
|
2013-02-24 05:54:57 -05:00
|
|
|
bool
|
|
|
|
sudo_auth_needs_end_session(void)
|
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
|
|
|
bool needed = false;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_needs_end_session, SUDOERS_DEBUG_AUTH);
|
2013-02-24 05:54:57 -05:00
|
|
|
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
|
|
|
if (auth->end_session && !IS_DISABLED(auth)) {
|
|
|
|
needed = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
debug_return_bool(needed);
|
|
|
|
}
|
|
|
|
|
2012-07-10 12:42:33 -04:00
|
|
|
/*
|
|
|
|
* Call authentication method end session hooks.
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
* Returns true on success, false on failure and -1 on error.
|
2012-07-10 12:42:33 -04:00
|
|
|
*/
|
2011-09-27 13:18:46 -04:00
|
|
|
int
|
2023-08-21 09:21:49 -06:00
|
|
|
sudo_auth_end_session(void)
|
2010-05-26 17:57:47 -04:00
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
int ret = true;
|
2018-01-16 10:27:58 -07:00
|
|
|
int status;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH);
|
2010-05-26 17:57:47 -04:00
|
|
|
|
|
|
|
for (auth = auth_switch; auth->name; auth++) {
|
2010-05-27 14:53:11 -04:00
|
|
|
if (auth->end_session && !IS_DISABLED(auth)) {
|
2023-08-21 09:21:49 -06:00
|
|
|
status = (auth->end_session)(auth);
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
switch (status) {
|
|
|
|
case AUTH_SUCCESS:
|
|
|
|
break;
|
|
|
|
case AUTH_FAILURE:
|
|
|
|
ret = false;
|
|
|
|
break;
|
|
|
|
default:
|
2018-01-16 10:27:58 -07:00
|
|
|
/* Assume error msg already printed. */
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
ret = -1;
|
|
|
|
break;
|
2018-01-16 10:27:58 -07:00
|
|
|
}
|
2010-05-26 17:57:47 -04:00
|
|
|
}
|
|
|
|
}
|
Try to make sudo less vulnerable to ROWHAMMER attacks.
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
explicitly test for expected values instead of using a negated test
against an error value. In the parser match functions this means
explicitly checking for ALLOW or DENY instead of accepting anything
that is not set to UNSPEC.
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
Sunar, all affiliated with the Vernam Applied Cryptography and
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
Paper preprint: https://arxiv.org/abs/2309.02545
2023-09-09 14:07:04 -06:00
|
|
|
debug_return_int(ret);
|
2010-05-26 17:57:47 -04:00
|
|
|
}
|
|
|
|
|
2016-01-27 15:36:50 -07:00
|
|
|
/*
|
|
|
|
* Prompts the user for a password using the conversation function.
|
|
|
|
* Returns the plaintext password or NULL.
|
|
|
|
* The user is responsible for freeing the returned value.
|
|
|
|
*/
|
2010-03-14 19:58:47 -04:00
|
|
|
char *
|
2018-01-22 12:18:48 -07:00
|
|
|
auth_getpass(const char *prompt, int type, struct sudo_conv_callback *callback)
|
2010-03-14 19:58:47 -04:00
|
|
|
{
|
|
|
|
struct sudo_conv_message msg;
|
|
|
|
struct sudo_conv_reply repl;
|
2014-09-27 10:16:31 -06:00
|
|
|
sigset_t mask, omask;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(auth_getpass, SUDOERS_DEBUG_AUTH);
|
2010-03-14 19:58:47 -04:00
|
|
|
|
2022-02-21 19:34:06 -07:00
|
|
|
/* Display lecture if needed and we haven't already done so. */
|
|
|
|
display_lecture(callback);
|
|
|
|
|
2010-06-09 10:31:05 -04:00
|
|
|
/* Mask user input if pwfeedback set and echo is off. */
|
|
|
|
if (type == SUDO_CONV_PROMPT_ECHO_OFF && def_pwfeedback)
|
|
|
|
type = SUDO_CONV_PROMPT_MASK;
|
|
|
|
|
2010-06-10 15:02:32 -04:00
|
|
|
/* If visiblepw set, do not error out if there is no tty. */
|
|
|
|
if (def_visiblepw)
|
|
|
|
type |= SUDO_CONV_PROMPT_ECHO_OK;
|
|
|
|
|
2014-09-27 10:16:31 -06:00
|
|
|
/* Unblock SIGINT and SIGQUIT during password entry. */
|
|
|
|
/* XXX - do in tgetpass() itself instead? */
|
|
|
|
sigemptyset(&mask);
|
|
|
|
sigaddset(&mask, SIGINT);
|
|
|
|
sigaddset(&mask, SIGQUIT);
|
|
|
|
(void) sigprocmask(SIG_UNBLOCK, &mask, &omask);
|
|
|
|
|
|
|
|
/* Call conversation function. */
|
2010-03-14 19:58:47 -04:00
|
|
|
memset(&msg, 0, sizeof(msg));
|
2010-06-09 10:31:05 -04:00
|
|
|
msg.msg_type = type;
|
2023-07-07 15:07:04 -06:00
|
|
|
msg.timeout = (int)def_passwd_timeout.tv_sec;
|
2010-03-14 19:58:47 -04:00
|
|
|
msg.msg = prompt;
|
|
|
|
memset(&repl, 0, sizeof(repl));
|
2015-09-07 06:06:08 -06:00
|
|
|
sudo_conv(1, &msg, &repl, callback);
|
2010-03-14 19:58:47 -04:00
|
|
|
/* XXX - check for ENOTTY? */
|
2014-09-27 10:16:31 -06:00
|
|
|
|
|
|
|
/* Restore previous signal mask. */
|
|
|
|
(void) sigprocmask(SIG_SETMASK, &omask, NULL);
|
|
|
|
|
2011-10-22 14:40:21 -04:00
|
|
|
debug_return_str_masked(repl.reply);
|
2010-03-14 19:58:47 -04:00
|
|
|
}
|
|
|
|
|
1999-09-08 08:06:28 +00:00
|
|
|
void
|
2010-03-14 19:58:47 -04:00
|
|
|
dump_auth_methods(void)
|
1999-09-08 08:06:28 +00:00
|
|
|
{
|
|
|
|
sudo_auth *auth;
|
2019-12-22 08:48:16 -07:00
|
|
|
debug_decl(dump_auth_methods, SUDOERS_DEBUG_AUTH);
|
1999-09-08 08:06:28 +00:00
|
|
|
|
2011-05-16 16:32:05 -04:00
|
|
|
sudo_printf(SUDO_CONV_INFO_MSG, _("Authentication methods:"));
|
1999-09-08 08:06:28 +00:00
|
|
|
for (auth = auth_switch; auth->name; auth++)
|
2010-05-28 12:01:06 -04:00
|
|
|
sudo_printf(SUDO_CONV_INFO_MSG, " '%s'", auth->name);
|
|
|
|
sudo_printf(SUDO_CONV_INFO_MSG, "\n");
|
2011-10-22 14:40:21 -04:00
|
|
|
|
|
|
|
debug_return;
|
1999-09-08 08:06:28 +00:00
|
|
|
}
|