1

I tried to set up key bindings for changing the virtual terminal (VT) in X, as described in this post. Typing sudo chvt $(($XDG_VTNR-1)) into a terminal emulator appropriately changes the VT. However, I find that running chvt with elevated privileges works only when executed as a command to a terminal emulator (e.g., xterm -e), a requirement that I am trying to circumvent.

To describe my setup:

The following line was added to /etc/sudoers:

me    ALL=NOPASSWD:/bin/chvt

where me is the output of whoami. I also tried variations on this line (e.g., me ALL=(ALL) NOPASSWD:/bin/chvt and me ALL=(ALL:ALL) NOPASSWD:/bin/chvt)

To ~/.xbindkeysrc, I added key bindings, either:

"sudo chvt $(($XDG_VTNR-1))"
   alt + c:113

"sudo chvt $(($XDG_VTNR+1))"
   alt + c:114

or

"sudo chvt $(($XDG_VTNR-1))"
   m:0x8 + c:113

"sudo chvt $(($XDG_VTNR+1))"
   m:0x8 + c:114

The first was suggested by the author of the linked post and the latter was determined by running xbindkeys -k on my system.

The key bindings failed and I ran xbindkeys in non-daemon mode to investigate. Pressing Alt+left or Alt+right while running xbindkeys -n gives the following error:

sudo: no tty present and no askpass program specified

Changing the command in ~/.xbindkeysrc to xterm -e sudo chvt ... produces a working key binding (but at the cost of opening an xterm instance and prompting for a password), which confirms that the lack of a tty is the issue. How can the invocation of sudo in .xbindkeys be achieved without first summoning a terminal?

System details: debian v9.2., dwm v6.1, openbox v.3.6.1, xbindkeys v1.8.6, sudo v1.8.19p1

user001
  • 3,598
  • 5
  • 39
  • 54

1 Answers1

1

The security-sensible default (or at least put in your distribution's default sudoers) is to not allow a sudo command without a tty, in order to prevent privilege escalation from a breach in an application. The command run with a shortcut has no tty, so it won't run. You could disable this setting globally, but it's better to disable it for everything except this command. The option is named requiretty:

Cmnd_Alias    CHVT = /bin/chvt
me            ALL = NOPASSWD: CHVT
Defaults!CHVT !requiretty

The first ! means what follows is a Cmnd_Alias, the second ! is the logical not operator. So running chvt is exempted from requiretty. Here the use of Cmnd_Alias wasn't needed, but should you use a command with options, or want to disable requiretty for two commands the syntax requires it.

NOTE: Some other settings might cancel some of these lines. So putting it last in sudoers might be required. It appears the OP also needed to do this to have it working, perhaps because of %sudo ALL=(ALL:ALL) ALL

A.B
  • 31,762
  • 2
  • 62
  • 101
  • Thanks for the helpful explanation. I get the same error message ("sudo: no tty/askpass ...") after adding what you wrote to `/etc/sudoers`. If I omit `sudo` from the `xbindkeys` file, then I instead get `Couldn't get a file descriptor referring to the consol` (which is the same error I get when typing `chvt N` into a terminal without `sudo`). – user001 Oct 30 '17 at 20:18
  • use `sudo -l` and see if you see `Defaults!/bin/chvt !requiretty` in the result. Maybe an other part of your configuration erases this setting – A.B Oct 30 '17 at 20:39
  • Yes, it is present: "Runas and Command-specific defaults for : Defaults!/bin/chvt !requiretty" (command alias substitution has taken place). I might also note that my `/etc/sudoers` file does not set `requiretty` generally. – user001 Oct 30 '17 at 20:43
  • Same result: `$ setsid sudo chvt 7 – user001 Oct 30 '17 at 20:47