[sudo-users] When having multiple simultanious SSH connections, only the first two can `sudo`

Manuel Wagesreither ManWag at FastMail.FM
Wed Dec 13 07:53:46 MST 2017


Dear subscribers,

When there are multiple simultaneous SSH connections to my remote machine, only the first two can sudo. In the third connection, one gets asked for a password, altough neither the sudoing user nor root has a password set.


First and second connection: (Good case)

> manuel at manuelthinkpad:~$ ssh manuel-nas-wan 
> Enter passphrase for key '/home/manuel/.ssh/manuel-thinkpad-arbeit.ed25519': 
> Linux manuel-nas 4.9.0-4-amd64 #1 SMP Debian 4.9.51-1 (2017-09-28) x86_64
> 
> The programs included with the Debian GNU/Linux system are free software;
> the exact distribution terms for each program are described in the
> individual files in /usr/share/doc/*/copyright.
> 
> Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
> permitted by applicable law.
> Last login: Tue Dec  5 13:59:52 2017 from xxx.xxx.xxx.xxx
> 
> user at manuel-nas:~$ sudo pwd
> /home/user


Third connection: (Bad case)

> manuel at manuelthinkpad:~$ ssh manuel-nas-wan
> Enter passphrase for key '/home/manuel/.ssh/manuel-thinkpad-arbeit.ed25519': 
> Linux manuel-nas 4.9.0-4-amd64 #1 SMP Debian 4.9.51-1 (2017-09-28) x86_64
> 
> The programs included with the Debian GNU/Linux system are free software;
> the exact distribution terms for each program are described in the
> individual files in /usr/share/doc/*/copyright.
> 
> Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
> permitted by applicable law.
> Last login: Tue Dec  5 14:27:00 2017 from xxx.xxx.xxx.xxx
> 
> user at manuel-nas:~$ sudo pwd
> [sudo] password for user: <enter>
> Sorry, try again.
> [sudo] password for user:  <enter>
> Sorry, try again.
> [sudo] password for user:  <enter>
> sudo: 3 incorrect password attempts


I have enabled sudo debugging by creating a file `/etc/sudo.conf` with following content:

> Debug sudo /var/log/sudo_debug all at warn


After running sudo and provoking a "good" case and a "bad" case, I analyzed this file. This is were they start to differ:

Good case, i. e. sudo completes successfully:

> Dec 12 20:54:21 sudo[6860] <- policy_open @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1292 := 1
> Dec 12 20:54:21 sudo[6860] -> policy_check @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1330
> Dec 12 20:54:21 sudo[6860] <- policy_check @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1340 := 1
> Dec 12 20:54:21 sudo[6860] policy plugin returns 1


Bad case, i. e. sudo asks for a non-existent password:

> Dec 12 20:54:43 sudo[6863] <- policy_open @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1292 := 1
> Dec 12 20:54:43 sudo[6863] -> policy_check @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1330
> Dec 12 20:54:43 sudo[6863] -> tgetpass @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:93
> Dec 12 20:54:43 sudo[6863] -> tty_present @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:360
> Dec 12 20:54:43 sudo[6863] <- tty_present @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:361 := true
> Dec 12 20:54:43 sudo[6863] -> sudo_term_noecho_v1 @ /build/sudo-oI7LKn/sudo-1.8.19p1/lib/util/term.c:130
> Dec 12 20:54:43 sudo[6863] <- sudo_term_noecho_v1 @ /build/sudo-oI7LKn/sudo-1.8.19p1/lib/util/term.c:141 := true
> Dec 12 20:54:43 sudo[6863] -> getln @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:303
> Dec 12 20:57:13 sudo[6863] <- getln @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:346 := (null)
> Dec 12 20:57:13 sudo[6863] -> sudo_term_restore_v1 @ /build/sudo-oI7LKn/sudo-1.8.19p1/lib/util/term.c:112
> Dec 12 20:57:13 sudo[6863] <- sudo_term_restore_v1 @ /build/sudo-oI7LKn/sudo-1.8.19p1/lib/util/term.c:120 := true
> Dec 12 20:57:13 sudo[6863] <- tgetpass @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/tgetpass.c:231 := (null)
> Dec 12 20:57:13 sudo[6863] <- policy_check @ /build/sudo-oI7LKn/sudo-1.8.19p1/src/sudo.c:1340 := 0
> Dec 12 20:57:13 sudo[6863] policy plugin returns 0


This is the source code of policy_check(), located at `sudo.c` at around line 1330:

> static int
> policy_check(struct plugin_container *plugin, int argc, char * const argv[],
>     char *env_add[], char **command_info[], char **argv_out[],
>     char **user_env_out[])
> {
>     int ret;
>     debug_decl(policy_check, SUDO_DEBUG_PCOMM) // line 1330
> 
>     if (plugin->u.policy->check_policy == NULL) {
> 	sudo_fatalx(U_("policy plugin %s is missing the `check_policy' method"),
> 	    plugin->name);
>     }
>     sudo_debug_set_active_instance(plugin->debug_instance);
>     ret = plugin->u.policy->check_policy(argc, argv, env_add, command_info,
> 	argv_out, user_env_out);
>     sudo_debug_set_active_instance(sudo_debug_instance);
>     debug_return_int(ret); // line 1340
> }


I think my attempt of finding the root cause is too low-level. I'm afraid to become acquainted with the code base requires more time than I can spare right now. Has anyone any further insights?

The server is a headless debian stretch live-system, that is, it boots from removable media and then runs entirely from RAM. (/ is a tmpfs.) The image file which I'm flashing onto the removable media is created by a selfwritten shell script which sets the whole system up using debootstrap and chroot commands.

The server is running "OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l 25 May 2017" and "Sudo version 1.8.19p1".


Best regards,
Manuel


More information about the sudo-users mailing list