Bash: Permission denied when trying to open a file - linux

I recently decided to try to learn some bash scripting and as a fun exercise I decided to make a script to open up a daily file for me to write notes in whenever the script is run.
It worked fine until I logged out and back in to the system later, when I received an error
/usr/local/bin/notes: line 45: /home/MY_USERNAME/notes/2010-10-01:Permission denied
Code
I might be mistaken, but this certainly doesn't seem like something that shouldn't require extra permissions, does it?
Editor is set to nano
File's permissions are -rw-rw-r--
Script's permissions are -rwxr-xr-x

check the permission on the file with
ls -l /path/to/your/file
you should see something like
-rw-r--r--
r mean readable, w writeable, and x executable.
the first set is for your user, the second set of three is for your group, and the third set is for anyone.
so in my example, the file i have shown is read/write for me, and read only for my group and for any other user.
Use the chmod command to change permissions.
chmod 744 file
will make the file read/write/exec for you, and just read for user/world.

My guess is that in
$EDITOR $DAILY_FILENAME
$EDITOR is null, so it's trying to execute $DAILY_FILENAME which not executable. Probably while you were testing you set EDITOR manually, but didn't add it to your .bashrc (or whatever) file.
Use the -x option to prove it.

If I had to guess, I would suggest that the $EDITOR environment variable is undefined for some reason. It looks like your script is attempting to execute the notes file - as this isn't executable you get the unhelpful error message.

Related

bash: No such file or directory when file is clearly present

I have a shell script located at "/home/pi/scripts/take-snapshot.sh" but when ever I try to execute it I get a error that the file is not present.
the following commands do not work (assuming in script directory):
/home/pi/scripts/take-snapshot.sh
./take-snapshot.sh
take-snapshot.sh
bash /home/pi/scripts/take-snapshot.sh
the following do work and will bring up the shell file (not a new file):
vi take-snapshot.sh
nano take-snapshot.sh
The most likely cause is that your file is not executable. Bash is a bit confusing in that it reports the file as "not found", even though you only don't have permissions to execute it. Run ls -l and check the permissions. The leftmost column should show an "x" at least for the current user. It will usually look something like -rwxr-xr-x for a file you have created yourself.
Run chmod +x take-snapshot.sh to fix the permissions if they don't match.
I have seen this error when the line endings are windows EOL characters. It doesn't give any other error, just the above "No file or directory".
Check the EOL character and convert it to linux EOL, if it is windows and try to run the script again.

Linux setuid bit [duplicate]

I created this simple script to allow the user to remove files created by the web server in his home directory without giving him "su". Both scripts are set with "chmod 4750".
The craziest thing is that they DID work and now they don't. Here's the scripts:
#!/bin/bash
# Ask for directory to delete
echo "Enter the file or directory you would like to delete, the assumed path is /home/user"
read DIRECTORY
rm -rf /home/user/"$DIRECTORY"
echo "Deleting /home/user/$DIRECTORY ..."
exit 0
2:
#!/bin/bash
# Reset permissions
echo "Resetting the ownership of the contents of /home/user to user."
chown -R user /home/user
exit 0
I will make them a little more advanced and work for multiple users but right now I cannot even get the simple version to work. It works when run as root of course. It used to work when run as user 'user' but now it doesn't. I get this:
user#dev:/home/user$ delete.sh
Enter the file or directory you would like to delete, the assumed path is /home/user/[your input]
test-dir
rm: cannot remove ‘/home/user/test-dir/test-file’: Permission denied
Deleting /home/user/test-dir ...
and
chown: changing ownership of ‘/home/user/test-dir’: Operation not permitted
What can possibly be the problem?
-rwsr-x--- 1 root user 291 Nov 6 05:23 delete.sh
-rwsr-x--- 1 root user 177 Nov 6 05:45 perms.sh
There is a pretty comprehansive answer at https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts
Bottom line is that there are two main points against it:
A race condition between when the Kernel opens the file to find which interpreter it should execute and when the interpreter opens the file to read the script.
Shell scripts which execute many external programs without proper checks can be fooled into executing the wrong program (e.g. using malicious PATH), or expand variables in a broken way (e.g. having white space in variable values), and generally it has less control on how well the external programs it executes handle the input.
Historically, there was a famous bug in the original Bourne shell (at least on 4.2BSD, which is where I saw this in action) which allowed anyone to get interactive root shell by creating a symlink called -i to a suid shell script. That's possibly the original trigger for this being prohibited.
EDIT: To answer "How do I fix it" - configure sudo to allow users to execute only these scripts as user root, and perhaps use a trick like in https://stackoverflow.com/a/4598126/164137 to find the original user's name and force operation on their own home directory, instead of letting them pass in any arbitrary input (i.e. in their current state, nothing in the scripts you include in your question prevents user1 from executing the scripts and passing them users2's directory, or any directory for that matter)

Using mkdir in my bash script and getting permission denied

i have script that is owned by root in a directory owned by root. part of the script is to make a directory that will hold the inputs/outputs of that script. i also have a sim link to that script so any user can run it from anywhere. i don't use the temp directory so this info can be used as logs later.
Problem: when a user tries to run the script they get an error that the directory cannot be created because of permission denied.
Questions: why won't the script make the directory so root owns it independent of what user runs it? how can the script make the directory so root owns it instead of the user that ran it? only the script needs this info, not the user.
Additional info:
the directory is: drws--s--x.
the script is: -rwxr-xr-x.
(if you need to know) the line in the script is simply: mkdir $tempdirname
i am matching the permissions of other scripts on the same server that output text files correctly, but since mine is a directory i'm getting permission errors.
i have tried adding the permissions for suid and sgid. suid sounded like the correct solution since it should make the script run as if it were run by the user that owns the script. (why isn't this the correct solution?)
i would like any user to be able to type in the sim link name, that will run the script that is owned by root in the directory that is owned by root, and the directories created by that script will stay in its own directory. and the end user has no knowledge or access to the inner workings of this process. (hence owned by root)
Scripts run as the user that runs them; the owner of the file and/or the directory it's in are irrelevant (except that the user needs read and execute permission to the file and directory). Binary executables can have their setuid bit set to make them always run as the file's owner. Old unixes allowed this for scripts as well but this caused a security hole, so setuid is ignored on scripts in modern unixes/Linuxes.
If you need to let regular users run a script as root, there are a couple of other ways to do this. One is to add the script to your /etc/sudoers file, so that users can use sudo to run it as root. WARNING: if you mess up your /etc/sudoers file, it can be hard to recover access to clean it up and get back to normal. Make a backup first, don't edit it with anything except visudo, and I recommend having a root shell open so if something goes wrong you'll have the root access you need to fix it without having to promote via sudo. The line you'll need to add will be something like this:
%everyone ALL=NOPASSWD: /path/to/script
If you want to make this automatic, so that users don't have to explicitly use sudo to run the script, you can start the script like this:
#!/bin/bash
if [[ $EUID -ne 0 ]];
then
exec sudo "$BASH_SOURCE" "$#"
fi
EDIT: A simpler version occurred to me; rather than having the script re-run itself under sudo, just replace the symlink with a stub script like this:
#!/bin/bash
exec sudo /path/to/real/script "$#"
Note that with this option, the /etc/sudoers entry must refer to the real script's path, not that of the symlink. Also, if the script doesn't take arguments, you can leave the "$#" off. Or use it, it won't do any harm either.
If messing with /etc/sudoers sounds too scary, there's another option: you could "compile" the script with shc (which actually just makes a binary executable wrapper around it), and make that setuid root (chmod 4755 /path/to/compiled-script; chown root /path/to/compiled-script). Since it's in a binary wrapper, setuid will work.

How to assign execute permission to a .sh file in windows to be executed in linux

Here is my problem,
In Windows I am making a zip file in which there is a text .sh file which is supposed to be executed in Linux.
The user on the other end opens the zip file in Linux and tries to execute the .sh file but the execute permission is gone. So the user has to do it manually ( like explained here:add execute permission.
How can I in Windows make the .sh executable and add it to a zip file so that when the zip file opens in linux the .sh file still retains its execute permission ( so that user doesn't have to do it manually)
As far as I know the permission system in Linux is set up in such a way to prevent exactly what you are trying to accomplish.
I think the best you can do is to give your Linux user a custom unzip one-liner to run on the prompt:
unzip zip_name.zip && chmod +x script_name.sh
If there are multiple scripts that you need to give execute permission to, write a grant_perms.sh as follows:
#!/bin/bash
# file: grant_perms.sh
chmod +x script_1.sh
chmod +x script_2.sh
...
chmod +x script_n.sh
(You can put the scripts all on one line for chmod, but I found separate lines easier to work with in vim and with shell script commands.)
And now your unzip one-liner becomes:
unzip zip_name.zip && source grant_perms.sh
Note that since you are using source to run grant_perms.sh, it doesn't need execute permission
The ZIP file format does allow to store the permission bits, but Windows programs normally ignore it.
The zip utility on Cygwin however does preserve the x bit, just like it does on Linux.
If you do not want to use Cygwin, you can take a source code and tweak it so that all *.sh files get the executable bit set.
Or write a script like explained here
This is possible using the Info-Zip open-source Zip utilities. If unzip is run with the -X parameter, it will attempt to preserve the original permissions. If the source filesystem was NTFS and the destination is a Unix one, it will attempt to translate from one to the other. I do not have a Windows system available right now to test the translation, so you will have to experiment with which group needs to be awarded execute permissions. It'll be something like "Users" or "Any user"
Use my windows command line utility zip_exec.zip to set the executable flag for linux/unix and mac (tested on files created with Windows Explorer and 7zip). The cpp source is also available. I searched the internet a lot before making my own utility. It can be modified to set any file attribute.
This is not possible. Linux permissions and windows permissions do not translate. They are machine specific. It would be a security hole to allow permissions to be set on files before they even arrive on the target system.

In Unix shell, how to Check user's permission ,if the user doesn't have, how to produce an error message?

I was trying to write a script which will be able to perform some build-in command ,such as : cp, rm, ls or whatever.
The menu might be like this:
list the current directory
Rename a file
Remove a file
exit
when you executed that some commands like "ls -la $currentdirectory"
which will show almost all the information of the current directory.
SO: if the user does not have permission to do that, (the user doesn't have permission to "LS" that directory .
what command can check the permission?
How to produce an error message if that user does not have the permission?
Cheers
hope to get that answer.
You don't need any separate command to figure out permissions on a directory/file. ls itself will output an error kinda message.
For example, I take away all permissions from everyone,
chmod 000 some_folder
ls some_folder/
ls: some_folder/: The file access permissions do not allow the specified action.
Most commands in Unix like systems will automatically error out with an error message if they don't have sufficient permissions to do their job! The underlying framework will take care of not allowing under-privileged users/apps to run.
grep -i umask ~/.profile /etc/profile

Resources