[sf-lug] sudo

Michael Paoli Michael.Paoli at cal.berkeley.edu
Thu Nov 9 22:32:30 PST 2017

> From: "Alex Kleider" <akleider at sonic.net>
> Subject: Re: [sf-lug] sudo
> Date: Thu, 09 Nov 2017 10:02:56 -0800

> Thanks, Michael, for your further input.  I've spent some time  
> trying to understand.
> The following is what I've been using to test:
> (It seems to make no difference if I source or run as executable:
> i.e.
> source t.sh
> or
> ./source t.sh
> I expect the latter would not work if the export statement hadn't  
> been included but haven't tested for that.)
> """
> #!/bin/bash
> # File: t.sh
> export ap_ip=
> sudo -E sh -c 'echo "$ap_ip  library library.lan rachel rachel.lan"  
> >> /etc/hosts'
> # the above command works and seems to me to be the correct way to go.

Well, that's very/highly hazardous, depending what is or may be in the
environment.  As that example is shown, you're 100% trusting the
invoking ID to not intentionally, accidentally, or via compromise,
do anything nefarious with its environment.

> sudo sh -c "echo $ap_ip  library library.lan rachel rachel.lan >> /etc/hosts"
> # The above also works (i.e. the var gets included in the appended

Yes, within pair of " characters, variable / named parameter
interpolation takes place.

> # line. The question now is 'why does this work but the next doesn't.
> sudo sh -c 'echo "$ap_ip  library library.lan rachel rachel.lan" >>  
> /etc/hosts'
> # the above command executes without error but the var is NOT included
> # in the appended line.

No interpolation within pair of ' characters.
So, sudo gets arguments:
sh -c echo "$ap_ip  library library.lan rachel rachel.lan" >> /etc/hosts
with the 3rd argument being echo and everything following it,
then sh -c gets as its option argument to the -c option,
as one single argument:
echo "$ap_ip  library library.lan rachel rachel.lan" >> /etc/hosts
The shell does interpolation within pair of ", so $ap_ip is
interpolated, and, at least by default, if it's unset or null,
then precisely nothing is substituted for it.  So, if it's not
set by shell, or environment, then as unset, the substitution
yields empty string for that portion.

> sudo echo "$ap_ip  library library.lan rachel rachel.lan" >> /etc/hosts
> # the above command fails with "Permission denied" notice.

Yup, the redirection (or attempt thereof) is being done by shell,
before sudo is even attempted.

> """
> From what you've written I would have expected that only the first  
> version would succeed but in fact the second one does as well.
>>> I'm not sure why the export doesn't pass ap_ip through to the su
>>> shell. Seems like that should work, but you're right, it doesn't.
>> Because, security, "of course".  :-)
>> sudoers(5) ...
>>   Command environment
>>     Since environment variables can influence program behavior, sudoers pro-
>>     vides a means to restrict which variables from the user's  
>> environment are
>>     inherited by the command to be run.  There are two distinct ways sudoers
>>     can deal with environment variables.
>>     By default, the env_reset option is enabled.  This causes commands to be
>>     executed with a new, minimal environment. ...

More information about the sf-lug mailing list