Link to home
Start Free TrialLog in
Avatar of Owen_Parker
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:
#!/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

Open in new window


When I run this, I get a permission error on the write:

Cannot write to `authtestok.html' (Permission denied).

Open in new window


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

Open in new window


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

Open in new window


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
Avatar of Owen_Parker
Owen_Parker

ASKER

I meant to include this as I am pretty sure it is relevant, but I could be wrong...

/srv/www # l
total 4
drwxr-xr-x 4 root root 1024 Jul 21  2011 ./
drwxr-xr-x 4 root root 1024 Jul 21  2011 ../
drwxr-xr-x 5 root root 1024 Oct 21 16:09 cgi-bin/
drwxr-xr-x 9 root root 1024 Oct  8 15:37 htdocs/

/srv/www/cgi-bin # l
total 3
drwxr-xr-x 5 root root 1024 Oct 21 16:09 ./
drwxr-xr-x 4 root root 1024 Jul 21  2011 ../
-rwxr-xr-x 1 root root 1178 Oct 21 15:09 authtest.cgi*
-rw-r--r-- 1 root root   74 Oct 18 21:30 authtestok.html

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Member_2_6582184
Member_2_6582184
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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:
...
umask 0555
touch /tmp/mytestfile
ls -l /tmp/mytestfile
-w--w--w-    /tmp/mytestfile 
...

Open in new window

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
Avatar of Tintin
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.
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...
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.
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
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:
#!/bin/bash
...

Open in new window

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.  

#!/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>"

Open in new window


Result is:

Message Log

whoami=
wwwrun
/usr/bin/tail: cannot open `/var/log/messages' for reading: Permission denied

Open in new window


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:
PATH=$PATH:/usr/sbin:/usr/bin:/sbin

Open in new window

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
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...
My original issue got resolved by using curl versus wget.  There are other good suggestions for issues with permissions as well.
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

%admin ALL=(ALL) NOPASSWD: ALL

Open in new window


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"

Open in new window

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!
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

/usr/bin/sudo /bin/su -c "/usr/bin/tail -50 /var/log/messages"

Open in new window


should really be
/usr/bin/sudo  /usr/bin/tail -50 /var/log/messages

Open in new window


and your sudoers entry should be:
%admin ALL=(ALL) NOPASSWD: ALL /usr/bin/tail

Open in new window


That way you restrict what the admin group has access to.
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.
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...