32

Two setuid programs, /usr/bin/bar and /usr/bin/baz, share a single configuration file foo. The configuration file's mode is 0640, for it holds sensitive information. The one program runs as bar:bar (that is, as user bar, group bar); the other as baz:baz. Changing users is not an option, and even changing groups would not be preferable.

I wish to hard link the single configuration file as /etc/bar/foo and /etc/baz/foo. However, this fails because the file must, as far as I know, belong either to root:bar or to root:baz.

Potential solution: Create a new group barbaz whose members are bar and baz. Let foo belong to root:barbaz.

That looks like a pretty heavy-handed solution to me. Is there no neater, simpler way to share the configuration file foo between the two programs?

For now, I am maintaining two, identical copies of the file. This works, but is obviously wrong. What would be right?

For information: I have little experience with Unix groups and none with setgid(2).

  • The question is generally phased. In my specific case, the two programs happen to be Exim4 and Dovecot, mail-handling programs that can share passwords and TLS certificates. – thb Aug 17 '16 at 16:31
  • 8
    the Ubuntu (& I think Debian) solution for this is the ssl-cert group, which is pretty much your barbaz group. The standard is to set all private keys to be owned by the ssl-cert group, and put the UIDs associated with the programs that need to access them into that group. – abligh Aug 17 '16 at 20:22
  • 1
    @abligh: Interesting. My system is Debian 8 jessie. Apparently, there exists a package ssl-cert whose postinst script, at installation, creates the group of which you speak. I had been unaware of ssl-cert. Apache2 (installed on my host) recommends ssl-cert. The various Exim and Dovecot packages do not, but Postfix (not installed on my host) depends on ssl-cert. Due to Apache, my host does have an ssl-cert group, but this group has no members yet. Thanks for the advice. – thb Aug 17 '16 at 21:22
  • 5
    Make the programs setgid, not setuid. Setuid programs are a bad idea because if they're compromised, the binary can be replaced, creating a trojan horse. (Exception: setuid root, because there you don't have a choice.) – Gilles Aug 17 '16 at 22:13
  • 1
    Does wiki.dovecot.org/HowTo/EximAndDovecotSASL solve your specific situation? – MvG Aug 18 '16 at 7:05
50

You can use ACLs so the file can be read by people in both groups.

chgrp bar file
chmod 640 file
setfacl -m g:baz:r-- file

Now both bar and baz groups can read the file.

For example, here's a file owned by bin:bin with mode 640.

$ ls -l foo
-rw-r-----+ 1 bin bin 5 Aug 17 12:19 foo

The + means there's an ACL set, so let's take a look at it.

$ getfacl foo
# file: foo
# owner: bin
# group: bin
user::rw-
group::r--
group:sweh:r--
mask::r--
other::---

We can see the line group:sweh:r-- : that means people in the group sweh can read it.

Hey, that's me!

$ id
uid=500(sweh) gid=500(sweh) groups=500(sweh)

And yes, I can read the file.

$ cat foo
data
23

You may want to reconsider these statements:

Potential solution: Create a new group barbaz whose members are bar and baz. Let foo belong to root:barbaz.

That looks like a pretty heavy-handed solution to me. Is there no neater, simpler way to share the configuration file foo between the two programs?

Why is it heavy-handed to create a new group? Doing so has the following advantages over ACLs:

  • Although you have phrased this as a hypothetical with commands /usr/bin/bar and /usr/bin/baz, it's relevant that these two programs can share a configuration file. This suggests that the programs are naturally related. Creating a new group for them would seem to describe a relationship that actually exists and should trigger behavior (such as permissions to read the common configuration file).
  • Solving this problem via groups is portable to every Unix, meaning that you can rely on the same mechanism, working exactly the same way, on any Unix or Unix-like system. ACLs are far more complex and portability can be a problem.

Personally I see ACLs as the heavy-handed solution here, and groups as the simpler, traditional Unix way.

16

I would think this would be a typical use for Access Control Lists (ACLs). Add both users (or groups) to the config-file's ACL:

/etc/foo  root:root rw-------  # Traditional Unix ownership and permission for foo
$ setfacl -m user:bar:rw- /etc/foo  # Allows user bar to read and write foo
$ setfacl -m user:baz:rw- /etc/foo  # Allows also user baz to read and write foo

You may have to install the acl-package first.

3

Make the file's mode 0660 (or even 0440 if writing is not required) and ownership bar:baz. Then one process can access the file thanks to user permissions, the other thanks to group permissions. This works even on file systems where ACLs don't.

2

I'll submit this since it's not yet mentioned. Even though this is probably not what you want, it may be the answer for other people with a similar question.

The "new" "cloud" way is to have all configuration handled by a configuration management system (such as chef, puppet, or ansible). It does not then matter that you have two distinct but identical files on the server, since both are a copy of the single file from the configuration management system.

The main advantages of doing it like this is that your configuration is versioned (along with all the rest of your configurations), and that deploying a new identical or almost-identical server becomes so easy that ot can be automated.

(For the record, since you are not using configuration management, I would go with the group system as in @drg's answer).

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.