LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-28-2022, 10:46 AM   #1
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
How to source inside a sudo environment


So I recently hit this issue at work and have discovered it is to do with the version of bash being run.
That being said, I need to find an alternative to get this option to work again.

The scenario is, I need to be able to source a file into my environment and then utilise the functions/variables that are from the sourced file.
So in bash v4.1:
Code:
$ sudo -u user cat /home/user/file
x=hello
$ sudo -u user -i bash -c '. file && set | grep hello && echo "#$x#"'
BASH_EXECUTION_STRING='. f1 && set | grep hello && echo "#$x#"'
SUDO_COMMAND='/bin/bash -c bash -c .\ f1\ &&\ set\ |\ grep\ hello\ &&\ echo\ "#$x#"'
x=hello
#hello#
Current version at work is 4.2+ and at home is 5.1.16, and they both produce this:
Code:
$ sudo -u user cat /home/user/file
x=hello
$ sudo -u user -i bash -c '. file && set | grep hello && echo "#$x#"'
BASH_EXECUTION_STRING='. f1 && set | grep hello && echo "##"'
SUDO_COMMAND='/bin/bash -c bash -c .\ f1\ &&\ set\ |\ grep\ hello\ &&\ echo\ "#$x#"'
x=hello
##
Now there are two things to note here:

1. The line after x=hello which is my echo'ed output (which should be #hello#)

2. If you look at the BASH_EXECUTION_STRING it has already expanded the $x to be nothing?? My understanding here is as the commands
being run are in single quotes the variable should not get expanded until after the login and see the exported variable

My understanding is this is probably some kind of security feature, however, is it possible at all to source a file once logged in
via sudo as a user and then recall the source'd material?

Please let me know if any additional information is required?
 
Old 06-28-2022, 11:00 AM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,027

Rep: Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343
in general it should work.
I would use full path, like this:
Code:
sudo -u user -i bash -c '. /home/user/file && set | grep hello && echo "#$x#"'
But as usual better to write a script containing everything you need and execute that with sudo.
 
Old 06-28-2022, 11:22 AM   #3
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Original Poster
Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
No different:
Code:
$ sudo -u user -i bash -c '. /home/user/f1 && set | grep hello && echo "#$x#"'
[sudo] password for grail:
BASH_EXECUTION_STRING='. /home/user/f1 && set | grep hello && echo "##"'
SUDO_COMMAND='/bin/bash -c bash -c .\ /home/user/f1\ &&\ set\ |\ grep\ hello\ &&\ echo\ "#$x#"'
x=hello
##
Not that I expected it to, but happy to test any option

As this is how we run many different commands on our system and with varying uses of the source'd material, it is less than practical to have a script for all of them

Also, the general feedback is, "Why did it just stop working?"
 
Old 06-28-2022, 11:35 AM   #4
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,625

Rep: Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556

I'm not sure I understand, so this might not make sense, but since you're using Sudo to run Bash, can you not use either --rcfile or BASH_ENV to do this, as per https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html ?


As for why it changed, if you've identified the version when it changed, you should be able to consult the relevant section of the bash changelog, then identify the relevant issue / commit message to find out the reason.

 
Old 06-28-2022, 11:36 AM   #5
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,027

Rep: Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343
So it was working. If I remember well there were some incompatible changes around bash 4.2, but I can't recall it (which was probably related to it).
You might want to escape that $ sign anyway.
 
Old 06-28-2022, 11:46 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Original Poster
Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
@pan64 --- yep tried with escaping, still no change

@boughtonp --- whilst you are correct that shifting some into .bash_profile can fix the issue, we also have a situation where the same variable gets over-written by source'ing a different
file, so this would only fix some of our issues and not the main issue as a whole

I will see if I can find the correct changelog, however, not sure this will change the outcome?
 
Old 06-28-2022, 11:58 AM   #7
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,625

Rep: Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556Reputation: 2556
Quote:
Originally Posted by grail View Post
I will see if I can find the correct changelog, however, not sure this will change the outcome?
Depends on the reason for the change - it may involve a comment such as "disable insecure X; correct method is Y" or whatever.

Also a chance it's not mentioned because it's an unintentional change (i.e. a bug), though that seems less likely given how old 4.2 is.

 
Old 06-28-2022, 10:13 PM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
I futzed around for a bit, and found that ${x} seems to work, even though $x doesn't!? Also, I suspect this might be a difference in sudo rather than bash (I don't have an older bash handy, but the difference seems to show up with just printf too):
Code:
$ sudo -u $USER -i bash -c '. f1 && set | grep hello && echo "#$x#${x}#"'
BASH_EXECUTION_STRING='. f1 && set | grep hello && echo "##${x}#"'
SUDO_COMMAND='/bin/bash -c bash -c .\ f1\ &&\ set\ |\ grep\ hello\ &&\ echo\ "#$x#${x}#"'
x=hello
##hello#
$ sudo -u $USER -i /usr/bin/printf '[%s]\n' '${x}' aa '#$x#'
[${x}]
[aa]
[##]
$ bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
vpsuser720@vpsuser-720:~$ sudo --version
Sudo version 1.8.27
Sudoers policy plugin version 1.8.27
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.27
 
3 members found this post helpful.
Old 06-28-2022, 11:20 PM   #9
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Original Poster
Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
ntubski for the win

Of all the tests I didn't think to try <doh>

Well I know some of my team mates will be less than happy as they already dread sudo with a passion, but adding curly braces definitely saves
me a lot of time

Thanks again ... as usual, still love this community after all this time
 
1 members found this post helpful.
Old 06-29-2022, 12:50 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 22,027

Rep: Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343Reputation: 7343
Quote:
Originally Posted by ntubski View Post
I futzed around for a bit, and found that ${x} seems to work, even though $x doesn't!? Also, I suspect this might be a difference in sudo rather than bash (I don't have an older bash handy, but the difference seems to show up with just printf too):
Very good. From my side I think it is related to bash, how it evaluates this command line and that had been "slightly" changed between 4.1 and 4.3. Unfortunately I can't find the relevant info and also I can't test it, but anyway you found it.
 
Old 06-29-2022, 01:09 AM   #11
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,880
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Edit: It might have something to do with the -i option of sudo:
Code:
$ sudo -u $USER bash -c 'x=hello; echo "#$x#${x}#"'
#hello#hello#

$ sudo -u $USER -i bash -c 'x=hello; echo "#$x#${x}#"'
##hello#
Edit: if either -i or -s is specified, sudo does something different than otherwise. That can be proved via `strace` (running as root).
Code:
$ strace -f -s 2048 sudo -u zsiga  -i ksh -c 'x=hello; echo "#$x#${x}#"' 2>ki.x
execve("/bin/bash", ["-bash", "--login", "-c", "ksh -c x\\=hello\\;\\ echo\\ \\\"\\#$x\\#$\\{x\\}\\#\\\""]

$ strace -f -s 2048 sudo -u zsiga ksh -c 'x=hello; echo "#$x#${x}#"' 2>ki.y
execve("/usr/bin/ksh", ["ksh", "-c", "x=hello; echo \"#$x#${x}#\""]

Last edited by NevemTeve; 06-29-2022 at 04:12 AM.
 
Old 06-29-2022, 04:14 AM   #12
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,011

Original Poster
Rep: Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194Reputation: 3194
@NevemTeve --- The -i is a requirement as the user's environment also sets many other options which are also required, in addition to the source'd material. Also, as advised initially, this all works with lower version of bash / sudo
 
Old 06-29-2022, 04:34 AM   #13
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,880
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
I've just tested it with sudo-1.9.11p3, same effect.

Now I think it is a version of 'shell quoting hell' let's name it 'sudo quoting hell'

Last edited by NevemTeve; 06-29-2022 at 05:15 AM.
 
Old 06-29-2022, 04:45 AM   #14
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Quote:
Originally Posted by NevemTeve View Post
Edit: if either -i or -s is specified, sudo does something different than otherwise. That can be proved via `strace` (running as root).
Code:
$ strace -f -s 2048 sudo -u zsiga  -i ksh -c 'x=hello; echo "#$x#${x}#"' 2>ki.x
execve("/bin/bash", ["-bash", "--login", "-c", "ksh -c x\\=hello\\;\\ echo\\ \\\"\\#$x\\#$\\{x\\}\\#\\\""]
Aha, so sudo is escaping "{}" but not "$" for the login shell. That seems wrong, but it could be intensional.
 
Old 06-29-2022, 05:45 AM   #15
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,880
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
This take us back to square 1: "use a script instead"
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: The Ultimate Sudo FAQ — To Sudo Or Not To Sudo? LXer Syndicated Linux News 13 04-13-2013 01:36 AM
Sleep inside for loop inside while loop causing issues. TheOnlyQ Programming 13 12-19-2012 12:59 PM
LXer: The Devil Inside: Creative Threat Detection Inside the Firewall LXer Syndicated Linux News 0 05-24-2012 07:30 PM
Possible to have a VM inside a VM, inside a VM? Into eternity? linus72 Linux - Newbie 8 05-15-2009 07:20 AM
iptables inside client to inside host with outside DNS or IP - Help! linuxhelp2 Linux - Networking 1 10-15-2005 06:19 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:33 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration