GEEK ALERT
This post will make sense to probably about eight people on the planet. Posting here just in case I forget or so perhaps it can help explain this problem to the other seven people.
I just stumbled across this odd sudo issue on a couple of my servers when trying to do a password-less sudo through SSH. I want to be able to have a local user called sysadmin sudo a command (apt-get) to update the sources list and, if possible, run an automatic update without any interaction. We have 240 servers, so any sort of automation to make this easier is a good thing. (note: Landscape is not an option for us).
So, the basic thinking was that we would just add a NOPASSWD option to /etc/sudoers for the relevant command on every member server then from a management system (with appropriately-shared SSH keys, of course) we would just issue an SSH to that server followed by the appropriate sudo command, thus:
ssh sysadmin@someserver sudo apt-get update
On most of our systems, that works fine. But on a few, I keep seeing this:
sudo: no tty present and no askpass program specified
Well, that makes a little bit of sense. There’s no interactive TTY when using a one-shot through SSH like we’re doing. But if we add the needed ‘-t’ option to SSH, then we still get prompted for a password, which is contrary to what we put in /etc/sudoers on all of the member servers:
sysadmin ALL=(ALL) NOPASSWD: /usr/bin/apt-get
So everything looks perfectly fine there, but then I got to thinking about it and remembered a feature of sudoers and started looking a bit closer. I realized that the affected systems had a few additional entries beneath this one. One of them is the Ubuntu-defined “%admin” group:
%admin ALL=(ALL) ALL
Ah-ha!
That little feature in /etc/sudoers is that entries are processed first to last. That is, if there’s another entry that applies later in the file, it always takes priority. In this case, the “sysadmin” account was a member of the local “admin” group and, because %admin was after sysadmin in sudoers, sudo was requiring that sysadmin enter a password to continue.
Our solution? Simply move the sysadmin entry to the bottom of the file, save, then try kicking off the command again.
Fixed.
I suppose it helps to understand the function you’re using.