The preconditions are somewhat complex, so here is the context:

  • There is a program, that is launched through a shell script;
  • The shell script launches the program through a .jar file;
  • I want this program to store its cache in a /var/opt/ subfolder, say /var/opt/program/;
  • The cache content should not be accessible directly, only through the program
  • The program should be available for all local users in a system

The main idea I came up with is to create a group that has all required permissions to read and edit content of the cache folder. I don't want to add users to the group manually, so was looking for alternative options. If I understand it right, the setgid bit should suit me perfectly. My understanding as follows:

  • A folder with the setgid bit set force all its content to have the same owner group, as the folder has and force all its subfolders to follow the same rules. In the meantime it doesn't provide any extra permissions for the those not included in the folder owner group, that is, folder with mask drwxrws--x does not allow others to edit and read its content.
  • A program with the setgid bit set always run on behalf of the owner group, allowing users to perform actions respecting group permissions.

My steps as follows:

  • I created a group mygroup;
  • I created a folder /var/opt/program/ and set its owner group to mygroup;
  • I set setgid bit for the folder
  • I set the program shells script owner group to mygroup;
  • I set setgid bit for the shell script

The problem is that the program is not able to create and edit files in the cache folder being launched by a user without root permissions. Any advice will be appreciated.

UPD Environment:

OS: Ubuntu 16.04.2 LTS

2 Answers 2

  • A folder with the setgid bit set force all its content to have the same owner group as the folder

Yep. Newly created files get the group of the directory, the group of the file can of course be changed afterwards. (We call them directories, not folders.)

  • A program with the setgid bit set always run on behalf of the owner group

Yep. Though you don't need setgid on the directory if you're only creating files through a setgid binary. A setgid program gets the group in question as the primary group, so any files it creates are owned by that group by default (and not the calling user's group).

  • I set setgid bit for the shell script

This is the part that doesn't work. Most systems don't respect setuid and setgid bits on interpreted scripts, since it easily leads to a number of security issues.

What you need to do, is to write a C program wrapper that executes the script, and make the wrapper setgid; or (preferably) use something like sudo to allow your users to run the script with the rights of another group. (sudo already deals with things like cleaning up environment variables that might be problematic.) In both cases, make sure the script and its interpreter are in directories that the users can't modify.

For sudo, the required configuration (in /etc/sudoers) would be something like this:

username ALL=(:privgroup) /path/to/script

That would allow user username to run /path/to/script as the group privgroup. You could use %groupname instead of username to allow all members of groupname to run the script. The users will need to run the script using sudo -g privgroup /path/to/script because sudo by default tries to run the named command as root, and we didn't allow that. But you can write a wrapper for that command.

  • Thanks for the answer! I tried the approach with a c program, and it looks something like that: system("path/to/shellscript"); but for some reason the binary is being launched with the current user group (i also added system("id -gn")). I changed the binary group to the mygroup and set setgid bit (this is the bits for the binary: -rwxr-sr-x , owner root:mygroup ). Am i doing something wrong? Commented Jun 17, 2017 at 6:00
  • @AleksandrMedvedev, Well. If Bash is involved, it drops the privileges given by setuid/setgid (i.e. if the effective UID/GID is different from the "real" UID/GID, it sets the first to the second.) The wrapper would have to do something like setregid(getegid(), getegid()) to fix that. But as I said, there's also the issue of cleaning up potentially harmful environment variables. If the shell script is started with PATH pointing to the calling user's ~/bin, they can do anything with the scripts rights.
    – ilkkachu
    Commented Jun 17, 2017 at 8:05
  • Of course this isn't nearly as bad as if you had a program setuid to root, but the same idea applies. I glossed over the specifics about the wrapper on purpose, I don't think its a really good idea to start doing that manually, if not really necessary. You mentioned you have Ubuntu, so you should have sudo, and it does most of the sanity-checking already (and can be configured), so my recommendation would be to use it.
    – ilkkachu
    Commented Jun 17, 2017 at 8:08

Most operating systems ignore setgid on scripts. The directory /var/opt/program should be group writable as well as setgid. ls -ld /var/opt/program should output something like drwxrwsr-x 159 root mygroup 5406 Jun 15 10:25 /var/opt/program. Any regular (non-root) user that needs to execute the program should have mygroup as a supplemental group. Add them using usermod with a command similar to usermod -a -G mygroup LOGIN for each user replacing LOGIN with their username. Or edit /etc/group and append the line with mygroup with a comma separated list of those users. Ex: mygroup:x:5000:joe,frank,ellen,mark where the users joe, frank, ellen, and mark will be executing that script.

  • Thanks for the answer. The problem is that users being included in the group will have the same permissions as the program, so the 4-th condition is not fulfilled - The cache content should not be accessible directly, only through the program Commented Jun 17, 2017 at 6:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .