1

I have two files A and B. I need the contents of A to be accessible only by root, so I have run the command chmod 000 A.

Now, I want file B to be able to access file A without asking for the root password. How can I go about this?

Zanna
  • 70,465

1 Answers1

4

Let's assume we have two files A and B. The both files are located in the home directory of a regular user. The file A is owned by root and only that user has read permissions as follow:

$ cat A                   # output the content of the file
"Test content of file A"

$ chmod 400 A             # change the permissions of file A to read only by the user/owner
$ sudo chown root:root A  # change the ownership of the file to user and :group 'root'

$ ls -l A                 # check the permissions and the ownership, 'stat -c "%a %n" A' to get them in octal
-r-------- 1 root root 24 яну 22 10:17 A

$ sudo cat A              # output the content of the file A, that is ownes by 'root'
"Test content of file A"

The file B is simple script that outputs the content of A, it is owned by the regular user. B has executable permissions as follow:

$ cat B                   # output the content of the file
#!/bin/bash
cat /home/<user>/A

$ chmod +x B              # add executable permissions to the file for all users

$ ./B                     # execute file B by a regular user
cat: /home/<user>/A: Permission denied

$ sudo ./B                # execute file B with root privileges
[sudo] password for <user>: 
"Test content of file A"

To execute the last command above without password we can use NOPASSWD directive within the file /etc/sudoers or we can create separate file, dedicated to this task, located in /etc/sudoers.d/ (as it is in the next example). Note, the use of the command visudo is absolutely necessary when you edit files as these. So, run the command:

$ sudo visudo -f /etc/sudoers.d/no-passwd-A-B

Add the following content inside, save and close:

<user> ALL=(ALL) NOPASSWD: /bin/cat /home/<user>/A

Now you will be able to execute the following command and you will not be asked for a password:

$ sudo ./B
"Test content of file A"

If you do not want to type sudo in front of the command, you can put it inside the script:

$ cat B                   # output the content of the file
#!/bin/bash
sudo cat /home/<user>/A

$ ./B
"Test content of file A"

NOTE: In the previous version of the answer is described how to add NOPASSWD directive in sudoers file for a script (file B in our case), but, as @RoVo said, this approach is pretty dangerous, because if the user has write permissions to the file it can make harmful changes inside. Practically the user will be able to do/crash anything.

If you want to use this variant, where the content of /etc/sudoers.d/no-passwd-A-B is:

<user> ALL=(ALL) NOPASSWD: /home/<user>/B

Then for security reasons, change the ownership of the file B to root and grant it only read and execute (but not write) permissions for the other users, something like:

$ chmod 605 B
$ sudo chown root:root B

$ ls -l B
-rw----r-x 1 root root 38 яну 22 15:31 B

Another way to add more security in your system, provided by @PerlDuck, is to have sudo check the executable against manipulation:

  1. For this purpose get the sha256sum of the executable file:

    $ openssl dgst -binary -sha256 /home/<user>/B | openssl base64
    sfDELCTNqfrDY9QKzz8Ra2wTnIpFXyyN8sG9JFxUJtA=
    
  2. Add that sha256sum to the sudoers file like so:

     <user> ALL=(ALL) NOPASSWD: sha256:sfDEL...xUJtA= /home/<user>/B
    

Then sudo will complain if the sha256 of the script doesn't match the value in the sudoers file.

pa4080
  • 29,831
  • Isn't it pretty dangerous to add NOPASSWD in sudoers file for a script the user has write access ? He can then do pretty much anything without sudo or am I wrong ? So the second solution is to preferred I'd say. – pLumo Jan 22 '19 at 12:58
  • @RoVo, I think you are right! Probably the second approach is more safe. I will update the answer. – pa4080 Jan 22 '19 at 13:02
  • or make B owned by root and readable by others. – pLumo Jan 22 '19 at 13:08
  • Thanks for this note @RoVo, I've updated and simplified the answer. – pa4080 Jan 22 '19 at 13:26
  • 2
    @RoVo You can have sudo check the executable against manipulation: 1) run openssl dgst -binary -sha256 /home/<user>/B | openssl base64 and 2) add that sha256 to the sudoers file like so: <user> ALL=(ALL) NOPASSWD: sha256:wQ2G5...rHpSM= /home/<user>/B. Then sudo will complain if the sha256 of the script doesn't match the value in the sudoers file. – PerlDuck Jan 22 '19 at 15:03
  • That is great, didn't know. Thanks! – pLumo Jan 22 '19 at 16:04
  • @PerlDuck, great idea. I've added it to the answer ... but probably I'm missing something, because when I changed the content of B to echo "test" > /root/test, the file change wasn't indicated in any way by the sudo command, and I successfully executed sudo ./B. Any ideas? – pa4080 Jan 22 '19 at 20:56
  • 1
    What does "successfully executed" mean? Without password? I think the sha256 check only works for the exact command as given in the sudoers file, i.e. sudo /home/user/B and not sudo ./B. Cannot verify right now (am on my mobile). – PerlDuck Jan 22 '19 at 21:11