11

I have a user with limited access on the system (that is, he is not a sudoer); let's call him Bob.

I have a script or a binary which I, the system administrator, trust, and would have no problems running it as root; let's call the script get-todays-passphrase.sh. The job of this script is to read data from a "private" (owned by a user/group other than Bob, or even root) file located in /srv/daily-passphrases, and only output a specific line from the file: the line that corresponds with today's date.

Users like Bob are not allowed to know tomorrow's passphrase, even though it is listed in the file. For this reason, the file /srv/daily-passphrases is protected by Unix permissions, so non-root users like Bob are not allowed to access the file directly. They are, however, allowed to run the get-todays-passphrase.sh script at any time, which returns the "filtered" data.


To summarize (the TL;DR version):

  1. Bob can't read the protected file
  2. The script can read the protected file
  3. At any time, Bob can run the script which can read the file

Is it possible to do this within Unix file permissions? Or if Bob starts a script, will the script always be doomed to run with the same permissions as Bob?

13

This is actually common and quite straightforward. sudo allows you to limit specific applications that a user can invoke. In other words, you don't have to give them all root or nothing; you can give them sudo permissions to run a specific command. This is exactly what you want, and is very common practice for things like allowing users to push Git repositories via SSH and the like.

To do this, all you have to do is add a line to /etc/sudoers that looks something like

bob ALL=(root) NOPASSWD: /path/to/command/you/trust

(The NOPASSWD: part is not required, but is very common in this situation.) At that point, bob can invoke /path/to/command/you/trust via sudo, but nothing else.

That said, giving someone root—what we're doing here—may not be quite what you want. Notably, if there were any flaw in your script whatsoever, you risk letting your box get rooted. For that reason, you may instead prefer to create a user specifically to own the special file—say, specialuser—then chown the file to them, and have the /etc/sudoers make bob be that special user. In that case, the line you add to sudoers would simply be

bob ALL=(specialuser) NOPASSWD: /path/to/command/you/trust
  • 7
    I'd suggest to not go the "root" way - create a special user/group for this purpose. – guntbert Dec 26 '14 at 20:13
  • Good point; I'll emend the answer. – Benjamin Pollack Dec 26 '14 at 20:45
7

Preface:

As has been pointed out in comments and for the reasons explained in this answer the linux kernel ignores the setuid/setguid bit when handling a script. I am not going to duplicate Benjamin's answer but will instead replace script with executabe to make my answer correct.


Short answer: use setgid

Detailed steps:

  1. Create a new group (e. g. readpass)
  2. Make that group the owner of the passphrase file sudo chown :readpass thatfile
  3. Make the file readable by its group only sudo chmod g=r,o= thatfile
  4. Make your executable sgid readpass: sudo chmod g+s thatfile

That way your executable will run with the permissions of the owning group and thus be able to read the file.

  • 2
    Setgid and setuid are not easily workable on scripts, right? – muru Dec 26 '14 at 17:01
  • 1
    You can't make a script setgid on Linux: the setgid bit will be ignored. Instead, add a sudo rule allowing bob to run thatfile with the group readpass. – Gilles 'SO- stop being evil' Dec 26 '14 at 22:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.