Owen_Parker
asked on
bash script permissions muddle
Kind of embarassing, but the ridiculously easy 'programming' is certainly forcing me to learn lots about Linux. I suspect this is another such instance.
I am writing a simple script to check to see if a device has a proper 2 way connection to the internet. It is used in a hotel space and many times it gets connected behind the HSIA and requires auth to get connected and it costs way too much time for the installers to figure out and yes, I realize how ridiculous that sounds unto itself. Anyway, I want them to be able to run a simple script that will:
check for a file and delete it if it exists
do a simple wget to a known URL
evaluate the result
post a message saying yea or nay to the 2-way connection being clear or not
All of this stuff works great from the command line, but I am putting it all into a simple gui. Our installers are not computer people as a rule. Running this stuff via the gui is causing permissions issues I cannot figure.
The script:
When I run this, I get a permission error on the write:
If I run the same command from the command line, it downloads the file. When I run the program with the file already present from the command line run instance I get a delete error, permissions again.
I stuck a whoami into the script and it output wwwrun. Looked familiar. Yes, it is the user added as part of the thttpd config.
So, to do some testing, I go to the command line and do a su - wwwrun. No good. This is not a user that you can switch to or log in as, etc. This makes sense because I never added it.
At this point, I am muddled. I cannot possibly believe this is not some permissions 101 sort of thing. Unfortunately, I cannot find anything that is helping me via good ol' google. I've paid for this service for years and have asked half a dozen questions. Figured I would try here. A pointer to the proper documentation would suit me fine, so long as it specifically deals with this sort of thing and not just some Linux tome...
TIA
O
I am writing a simple script to check to see if a device has a proper 2 way connection to the internet. It is used in a hotel space and many times it gets connected behind the HSIA and requires auth to get connected and it costs way too much time for the installers to figure out and yes, I realize how ridiculous that sounds unto itself. Anyway, I want them to be able to run a simple script that will:
check for a file and delete it if it exists
do a simple wget to a known URL
evaluate the result
post a message saying yea or nay to the 2-way connection being clear or not
All of this stuff works great from the command line, but I am putting it all into a simple gui. Our installers are not computer people as a rule. Running this stuff via the gui is causing permissions issues I cannot figure.
The script:
#!/bin/bash
echo "Content-type: text/html<html><head><title>HSIA Auth test</title></head><body>"
FILE="authtestok.html"
if [ -f "$FILE" ]
then
`/bin/rm authtestok.html`
fi
output=`/usr/bin/wget domain/authtestok.html`
if [ "$output" = "" ]; then
echo "<pre>The current WAN connection is NOT a proper 2-way open connection!!</pre>"
else
output2 = `/bin/grep Passed authtestok.html`
if [ "$output2" = "<html><head></head><body>HSIA Authorization test Passed!</body></html>" ]; then
echo "<pre>The current WAN connection IS a proper 2-3way open connection!!</pre>"
fi
fi
When I run this, I get a permission error on the write:
Cannot write to `authtestok.html' (Permission denied).
If I run the same command from the command line, it downloads the file. When I run the program with the file already present from the command line run instance I get a delete error, permissions again.
/bin/rm: cannot remove `authtestok.html': Permission denied
I stuck a whoami into the script and it output wwwrun. Looked familiar. Yes, it is the user added as part of the thttpd config.
# cat /etc/thttpd.conf
host=127.0.0.1
port=8000
user=wwwrun
logfile=/var/log/thttpd.log
pidfile=/var/run/thttpd.pid
dir=/srv/www
cgipat=**.cgi|**.pl
nochroot
So, to do some testing, I go to the command line and do a su - wwwrun. No good. This is not a user that you can switch to or log in as, etc. This makes sense because I never added it.
At this point, I am muddled. I cannot possibly believe this is not some permissions 101 sort of thing. Unfortunately, I cannot find anything that is helping me via good ol' google. I've paid for this service for years and have asked half a dozen questions. Figured I would try here. A pointer to the proper documentation would suit me fine, so long as it specifically deals with this sort of thing and not just some Linux tome...
TIA
O
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much helge000. I'd like to think I might have eventually remembered curl, but now I don;t have to! That is the perfectly simple test I need, and no writing, downloading etc. ideal solution to what i need. I also wanted to let them enter the Ip info so i could build the ifcfg-eth0, route and resolv.conf files, so I will need to know about the files permissions stuff eventually. I really do like your solution for the internet access test, however. :)
The permission error comes most likely from the user you run the script with. I do not know which user needs to run it (root?) - say you run it with sudo or root first. The user creating the file 'authtestok.html' was root, denying permissions to any other user wanting to delete the file. Keep in mind, the rm error is not in any way related to the permissions in /var/www but it means the permission of the previously downloaded file in your working dir.
You can circumvent this in many ways. The best would be to let every user write his own file to a private/relative location like $HOME. If you really need the file to be world writable, consider writing it with another umask somewhere before the write, eg:
http://en.wikipedia.org/wiki/File_system_permissions
You can circumvent this in many ways. The best would be to let every user write his own file to a private/relative location like $HOME. If you really need the file to be world writable, consider writing it with another umask somewhere before the write, eg:
...
umask 0555
touch /tmp/mytestfile
ls -l /tmp/mytestfile
-w--w--w- /tmp/mytestfile
...
This umask uses w permissions only. So, one can delete the file but only root can read it.http://en.wikipedia.org/wiki/File_system_permissions
When you run the script via a browser as a CGI script, it will be running as the owner of the web server process, typically, the httpd or apache2 user.
Make sure the script is writing to a location where the web server owner has permissions to write to.
Make sure the script is writing to a location where the web server owner has permissions to write to.
ASKER
Well, it would seem I am back in some similar place. I now have simply:
if (/usr/bin/curl -f http://www.google.com >/dev/null 2>&1); then echo Internet is good.; else echo Internet is not working as expected.; fi
It attempts the curl but pops a 502 bad gateway. When I run that very same exact command at the command line I get:
/srv/www/cgi-bin # if (curl -f http://www.google.com >/dev/null 2>&1); then echo Internet is good.; else echo Internet is not working as expected; fi
Internet is good.
I am feeling like I need to fix the root cause of all of this. I have a bunhc of other scripts that run from the gui just fine. The key to getting them working was to use the entire path to the program they were using like
/usr/bin/curl
versus
curl
I have done this for a bunch of ping, traceroute, cat type simple scripts but this one just won't cooperate... Is there any way I can use su - root before the command? I do n0t want them to have to enter a password and would really rather not share the root password if avoidable...
if (/usr/bin/curl -f http://www.google.com >/dev/null 2>&1); then echo Internet is good.; else echo Internet is not working as expected.; fi
It attempts the curl but pops a 502 bad gateway. When I run that very same exact command at the command line I get:
/srv/www/cgi-bin # if (curl -f http://www.google.com >/dev/null 2>&1); then echo Internet is good.; else echo Internet is not working as expected; fi
Internet is good.
I am feeling like I need to fix the root cause of all of this. I have a bunhc of other scripts that run from the gui just fine. The key to getting them working was to use the entire path to the program they were using like
/usr/bin/curl
versus
curl
I have done this for a bunch of ping, traceroute, cat type simple scripts but this one just won't cooperate... Is there any way I can use su - root before the command? I do n0t want them to have to enter a password and would really rather not share the root password if avoidable...
ASKER
Thank you Tintin. That was what I was trying to do when i gave up and came running here. I know the script is running as user wwwrun which is assigned as the user for the httpd server in the thttpd.conf file. The config specifies this line:
dir=/srv/www
so I assumed I could write to that directory maybe. I need to take a break. I am getting stupider by the minute. I could not get the curl command to get past a 502 bad gateway. So i took a working script, stuck the curl command in amongst some other things and it worked perfectly. ARGH! makes me crazy. I will try the file creation process.
What I ultimately need is to be able to run these scripts as root to ensure absolutely no issues. That is my opus wth this little proj... LOL
Thanks again.
dir=/srv/www
so I assumed I could write to that directory maybe. I need to take a break. I am getting stupider by the minute. I could not get the curl command to get past a 502 bad gateway. So i took a working script, stuck the curl command in amongst some other things and it worked perfectly. ARGH! makes me crazy. I will try the file creation process.
What I ultimately need is to be able to run these scripts as root to ensure absolutely no issues. That is my opus wth this little proj... LOL
Thanks again.
ASKER
Helge000, just saw your second comment. The primary issue I have is I want to allow the user to enter some IP info and then take that info and configure the device with a static IP, add the default route ro route file and add the dns servers specified to resolve.conf. Those files have to be root readable and must reside is specific directories and such (or at least I want them to stay in default directories) Once they are configured properly and online, puppet will take them over and completely configure them properly. This is just to simply allow a non computer/Linux person to get them online in the case that the IP info has changed since it was originally configed in the warehouse or if the IP info was not even in existence as the site is new construction.
Thank
O
Thank
O
Ok, new to me you do cgi's ;)
This is a $path thing. Next time, just add bash as interpreter in the first line. This way even the wwwrun user should have the correct env:
This is a $path thing. Next time, just add bash as interpreter in the first line. This way even the wwwrun user should have the correct env:
#!/bin/bash
...
ASKER
Oh how I wish that were true :) if you check the code I posted originally, that is the first line.
I got around this with the curl example you provided. But I still have the same issue. This script, for instance, I am displaying the last x number of lines from the message log.
Result is:
Is there some way to run a script as root without having to enter the password? I seem to recall reading how to do that with su but I have read a half dozen man pages and such and it is not evident that that is an option.
I have tried
su -c "/usr/bin/tail -50 /var/log/messages"
which prompts for a password, of course.
I got around this with the curl example you provided. But I still have the same issue. This script, for instance, I am displaying the last x number of lines from the message log.
#!/bin/bash
echo "Content-type: text/html"
echo "<html><body>"
echo "Message Log"
echo "<pre>whoami="
whoami;/usr/bin/tail -50 /var/log/messages
echo "</pre></font>"
echo "</body></html>"
Result is:
Message Log
whoami=
wwwrun
/usr/bin/tail: cannot open `/var/log/messages' for reading: Permission denied
Is there some way to run a script as root without having to enter the password? I seem to recall reading how to do that with su but I have read a half dozen man pages and such and it is not evident that that is an option.
I have tried
su -c "/usr/bin/tail -50 /var/log/messages"
which prompts for a password, of course.
There are certain things you cannot do as a normal user - reading /var/log/messages is one of those things; and this is good! Why should a cgi - script be able to sudo things? Everything is possible (in this case, visudo with the correct entries).
If you have trouble with $PATH - this can be fixed easily tough. Simply add:
If you have trouble with $PATH - this can be fixed easily tough. Simply add:
PATH=$PATH:/usr/sbin:/usr/bin:/sbin
This should fix most of the stuff - and you can just add your own. If you want this persistent for all users, add this path script in /etc/profile.d
ASKER
Thanks again Helge000. I'm working on figuring out how to configure sudo to allow me to do the tasks necessary through the gui. We'll call this one resolved for now. Thanks for all the great suggestions...
ASKER
My original issue got resolved by using curl versus wget. There are other good suggestions for issues with permissions as well.
ASKER
Ok, for those that may follow, this was my solution for running scripts/cgi from a gui as a non-root user. Hope it helps get you past the issue...
As I had installed thttpd as my web server, the cgis are all run as the user specified in the thttpd config, wwwrun in this example.
I created a group called admin.
I added wwwrun to that group
I changed properties of /etc/sudoers to make it writable and added this line to the config
I changed properties back (need to for sudo to run) and voila. I was able to successfully run the command from within the cgi:
As I had installed thttpd as my web server, the cgis are all run as the user specified in the thttpd config, wwwrun in this example.
I created a group called admin.
I added wwwrun to that group
I changed properties of /etc/sudoers to make it writable and added this line to the config
%admin ALL=(ALL) NOPASSWD: ALL
I changed properties back (need to for sudo to run) and voila. I was able to successfully run the command from within the cgi:
/usr/bin/sudo /bin/su -c "/usr/bin/tail -50 /var/log/messages"
I created a group called admin.
I added wwwrun to that group
I changed properties of /etc/sudoers to make it writable and added this line to the config
Owen_Parker, this is surely no production/public server. Doing this is suicide - calling it the least. Do yourself a favor and reverse this!
ASKER
I understand your concern Helge000. However, this device leaves the warehouse pre-configured as best it can be with the network details we have at that time. The installer simply has to get it connected to the LAN and WAN successfully. Once it is online at the site, a process is run remotely as soon as puppet-master can see the device online calling home, so to speak. That process includes a complete reconfiguration of the device with a preset configuration which will wipe out the current one entirely. My goal is merely to allow the installer to better be able to deal with the issues they face getting the device online in the first place as most of them are not computer people and certainly not Linux people. By the time the device is anywhere near production, all of this has been wiped completely away, I assure you...
Note that
should really be
and your sudoers entry should be:
That way you restrict what the admin group has access to.
/usr/bin/sudo /bin/su -c "/usr/bin/tail -50 /var/log/messages"
should really be
/usr/bin/sudo /usr/bin/tail -50 /var/log/messages
and your sudoers entry should be:
%admin ALL=(ALL) NOPASSWD: ALL /usr/bin/tail
That way you restrict what the admin group has access to.
ASKER
Thanks TinTin. I had planned to add just the commands I was going to use to the group permissions in the sudoers conf file. I also added the email option to hget an email whenever someone access it. I also discussed with an engineer and he said the wwwrun user is not a user name someone can guess the password to so he was not too concerned, and, trust me, he is a freak about security. I did not know I could get away without the
/bin/su -c part though. ignorance leads you to follow examples too closely :)
Thanks again TinTin for your most appreciated comments.
/bin/su -c part though. ignorance leads you to follow examples too closely :)
Thanks again TinTin for your most appreciated comments.
ASKER
TinTin, I was thinking I should remove the ALL and have JUST the list of commands I wanted them to be allowed to use. What is your opinion? Would that be best? I am not sure why the ALL would be left in... in the sudoers conf entry I mean:
I thought this:
%admin ALL=(ALL) NOPASSWD: ALL /usr/bin/tail
should be
%admin ALL=(ALL) NOPASSWD: /usr/bin/tail
I expect I can look this up online somewhere. Surprising how many variations of things there are...
I thought this:
%admin ALL=(ALL) NOPASSWD: ALL /usr/bin/tail
should be
%admin ALL=(ALL) NOPASSWD: /usr/bin/tail
I expect I can look this up online somewhere. Surprising how many variations of things there are...
ASKER
Open in new window