From df5f61eb240b9ae1b67faad8f143a488c5c8f206 Mon Sep 17 00:00:00 2001
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
Date: Tue, 1 Feb 2022 20:08:26 -0700
Subject: [PATCH] Add sudoers option to perform authentication even in
 non-interative mode. If noninteractive_auth is set, authentication methods
 that do not require input from the user's terminal may proceed.  It is off by
 default, which restores the pre-1.9.9 behavior of "sudo -n".

(cherry picked from commit 85fef8b50f0847f4fce39a7fead9aae767be1dca)
---
 docs/sudoers.man.in         | 17 +++++++++++++++++
 docs/sudoers.mdoc.in        | 16 ++++++++++++++++
 plugins/sudoers/check.c     |  6 ++++++
 plugins/sudoers/def_data.c  |  4 ++++
 plugins/sudoers/def_data.h  |  2 ++
 plugins/sudoers/def_data.in |  3 +++
 plugins/sudoers/defaults.c  |  1 +
 7 files changed, 49 insertions(+)

diff --git a/docs/sudoers.man.in b/docs/sudoers.man.in
index 67ca7cec6..f7e53cfe7 100644
--- a/docs/sudoers.man.in
+++ b/docs/sudoers.man.in
@@ -3214,6 +3214,23 @@ This flag is
 \fIoff\fR
 by default.
 .TP 18n
+noninteractive_auth
+If set, authentication will be attempted even in non-interactive mode
+(when
+\fBsudo\fR's
+\fB\-n\fR
+option is specified).
+This allows authentication methods that don't require user interaction
+to succeed.
+Authentication methods that require input from the user's terminal
+will still fail.
+If disabled, authentication will not be attempted in non-interactive mode.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.9.10 or higher.
+.TP 18n
 pam_acct_mgmt
 On systems that use PAM for authentication,
 \fBsudo\fR
diff --git a/docs/sudoers.mdoc.in b/docs/sudoers.mdoc.in
index 1b9ea07cf..38b83b9af 100644
--- a/docs/sudoers.mdoc.in
+++ b/docs/sudoers.mdoc.in
@@ -3027,6 +3027,22 @@ section at the end of this manual.
 This flag is
 .Em off
 by default.
+.It noninteractive_auth
+If set, authentication will be attempted even in non-interactive mode
+(when
+.Nm sudo Ns 's
+.Fl n
+option is specified).
+This allows authentication methods that don't require user interaction
+to succeed.
+Authentication methods that require input from the user's terminal
+will still fail.
+If disabled, authentication will not be attempted in non-interactive mode.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.9.10 or higher.
 .It pam_acct_mgmt
 On systems that use PAM for authentication,
 .Nm sudo
diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c
index 2ba18d27e..25a2087b0 100644
--- a/plugins/sudoers/check.c
+++ b/plugins/sudoers/check.c
@@ -125,6 +125,12 @@ check_user_interactive(int validated, int mode, struct getpass_closure *closure)
 	FALLTHROUGH;
 
     default:
+	if (ISSET(mode, MODE_NONINTERACTIVE) && !def_noninteractive_auth) {
+	    validated |= FLAG_NO_USER_INPUT;
+	    log_auth_failure(validated, 0);
+	    goto done;
+	}
+
 	/* XXX - should not lecture if askpass helper is being used. */
 	lectured = display_lecture(closure->tstat);
 
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
index 0afddace8..2398f3c28 100644
--- a/plugins/sudoers/def_data.c
+++ b/plugins/sudoers/def_data.c
@@ -645,6 +645,10 @@ struct sudo_defs_types sudo_defs_table[] = {
 	"rlimit_stack", T_RLIMIT|T_BOOL,
 	N_("The maximum size to which the process's stack may grow (in bytes): %s"),
 	NULL,
+    }, {
+	"noninteractive_auth", T_FLAG,
+	N_("Attempt authentication even when in non-interactive mode"),
+	NULL,
     }, {
 	NULL, 0, NULL
     }
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
index 25bf3a71d..ae9182921 100644
--- a/plugins/sudoers/def_data.h
+++ b/plugins/sudoers/def_data.h
@@ -300,6 +300,8 @@
 #define def_rlimit_rss          (sudo_defs_table[I_RLIMIT_RSS].sd_un.str)
 #define I_RLIMIT_STACK          149
 #define def_rlimit_stack        (sudo_defs_table[I_RLIMIT_STACK].sd_un.str)
+#define I_NONINTERACTIVE_AUTH   150
+#define def_noninteractive_auth (sudo_defs_table[I_NONINTERACTIVE_AUTH].sd_un.flag)
 
 enum def_tuple {
     never,
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
index 8309779f7..03ed95607 100644
--- a/plugins/sudoers/def_data.in
+++ b/plugins/sudoers/def_data.in
@@ -466,3 +466,6 @@ rlimit_rss
 rlimit_stack
 	T_RLIMIT|T_BOOL
 	"The maximum size to which the process's stack may grow (in bytes): %s"
+noninteractive_auth
+	T_FLAG
+	"Attempt authentication even when in non-interactive mode"
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
index b7979f37e..53c2dc2a9 100644
--- a/plugins/sudoers/defaults.c
+++ b/plugins/sudoers/defaults.c
@@ -571,6 +571,7 @@ init_defaults(void)
     def_log_denied = true;
     def_log_format = sudo;
     def_runas_allow_unknown_id = false;
+    def_noninteractive_auth = false;
 
     /* Syslog options need special care since they both strings and ints */
 #if (LOGGING & SLOG_SYSLOG)
