How to perform file / directory manipulations based on user rights?

I have a server application that will run under the system account, because at any given time it will process requests on behalf of any user in the system. These queries consist of file system management instructions.

Here's the catch: the program should consider these special user rights when performing actions. For example, joe cannot modify /home/larry if its permissions are 755 .

My current strategy is this:

  • Get owner / file group
  • Compare it to the user / group ID of the user trying to complete the action.
  • If any of the matches (or if they do not match), use the appropriate part of the permission field in the file to allow or deny the action

Is it wise? Is there an easier way to do this?

At first I thought about having multiple instances of the application under user accounts, but this is not an option, because only one of the instances can listen on this TCP port.

+8
unix privileges
source share
3 answers

Take a look at samba , an example of this can be done. The samba daemon runs as root, but forks and accepts the credentials of a regular user as soon as possible.

Unix systems have two different sets of credentials: real user / group identifiers and effective user and group identifiers. A real set determines who you really are, and an effective set determines what you can access. You can change the effective uid / gid as you wish if you are root & mdash, including a regular user and vice versa again, as your real users / groups remain at the root during the transition. So an alternative way to do this in one process is to use seteuid/gid to apply different users permissions back and forth as needed. If your server daemon is running as root or has CAP_SETUID , then this will be allowed.

However, please note that if you have the ability to switch the effective uid / gid on your own whim and your application is distorted, then this subversive activity can, for example, switch the effective uid / gid to 0, and you could have a serious security vulnerability, This is why it is wise to drop all privileges as soon as possible, including your real user uid / gid.

For this reason, it is normal and safer to have one listening socket working as root, then disconnect and change both real and effective user identifiers by calling setuid . Then he cannot go back. Your forked process will have a socket, which was accept() ed, since it is a fork. Each process simply closes file descriptors that they do not need; sockets remain alive because they are referenced by file descriptors in opposite processes.

You can also try and enforce the rights by studying them yourself, but I hope that it is obvious that this is potentially error-prone, has many extreme cases, and most likely is wrong (for example, it will not work with the POSIX ACL if you do not specifically implement this either).

So, you have three options:

  • Fork and setgid() / setuid() user you want. If communication is required, use pipe(2) or socketpair(2) before starting work.
  • Do not use fork and seteuid() / setegid() around as needed (less secure: most likely, this will lead to a compromise of your server by accident).
  • Do not contact system credentials; manually enforce (less secure: get authorization soon)

If you need to get in touch with a daemon, then although it can be harder to do with a socket or channel, the first option is indeed a proper safe way. See how ssh does privilege sharing , for example. You might also consider whether you can change your architecture so that instead of making any connection, the process can simply share some memory or disk space.

You mentioned that you think that a separate process is performed for each user, but you need one TCP listening port. You can still do it. Just ask the main daemon to listen on the TCP port and send requests to each user daemon and report as needed (for example, through Unix domain sockets). It will actually be almost the same as having a forking master daemon; I think the latter would be easier to implement.

Further reading: credentials(7) manpage. Also note that Linux has the uid / gids file system; it's pretty much the same as effective uid / gids, with the exception of other things like sending signals. If your users do not have access to the shell and cannot run arbitrary code, you do not need to worry about the differences.

+3
source share

I would get my fork () server and setuid(uid) right away to give up root privileges. Then any file manipulation will be on behalf of the user you become. Since you are a child server, you should still have an accept () ed child socket which will request the request (and I accept the response). This (obviously) requires root privileges for the daemon.

Transferring file descriptors between processes seems unnecessarily complicated in this case, since the child already has a request descriptor.

+3
source share

Allow one server to work on a server with a prefix server and run child processes for users who log on to the system. The processes of child processes must discard privileges and mislead the user. Now children can no longer do harm.

+2
source share

All Articles