10.9. Permissions and owners

The rules in this section are guidelines for general use. If necessary you may deviate from the details below. However, if you do so you must make sure that what is done is secure and you should try to be as consistent as possible with the rest of the system. You should probably also discuss it on debian-devel first.

Files should be owned by root:root, and made writable only by the owner and universally readable (and executable, if appropriate), that is mode 644 or 755.

Directories should be mode 755 or (for group-writability) mode 2775. The ownership of the directory should be consistent with its mode: if a directory is mode 2775, it should be owned by the group that needs write access to it. 14

Control information files should be owned by root:root and either mode 644 (for most files) or mode 755 (for executables such as maintainer scripts).

Setuid and setgid executables should be mode 4755 or 2755 respectively, and owned by the appropriate user or group. They should not be made unreadable (modes like 4711 or 2711 or even 4111); doing so achieves no extra security, because anyone can find the binary in the freely available Debian package; it is merely inconvenient. For the same reason you should not restrict read or execute permissions on non-set-id executables.

Some setuid programs need to be restricted to particular sets of users, using file permissions. In this case they should be owned by the uid to which they are set-id, and by the group which should be allowed to execute them. They should have mode 4754; again there is no point in making them unreadable to those users who must not be allowed to execute them.

It is possible to arrange that the system administrator can reconfigure the package to correspond to their local security policy by changing the permissions on a binary: they can do this by using dpkg-statoverride, as described below. 15 Another method you should consider is to create a group for people allowed to use the program(s) and make any setuid executables executable only by that group.

If you need to create a new user or group for your package there are two possibilities. Firstly, you may need to make some files in the binary package be owned by this user or group, or you may need to compile the user or group id (rather than just the name) into the binary (though this latter should be avoided if possible, as in this case you need a statically allocated id).

If you need a statically allocated id, you must ask for a user or group id from the base-passwd maintainer, and must not release the package until you have been allocated one. Once you have been allocated one you must either make the package depend on a version of the base-passwd package with the id present in /etc/passwd or /etc/group, or arrange for your package to create the user or group itself with the correct id (using adduser) in its preinst or postinst. (Doing it in the postinst is to be preferred if it is possible, otherwise a pre-dependency will be needed on the adduser package.)

On the other hand, the program might be able to determine the uid or gid from the user or group name at runtime, so that a dynamically allocated id can be used. In this case you should choose an appropriate user or group name, discussing this on debian-devel and checking that it is unique. When this has been checked you must arrange for your package to create the user or group if necessary using adduser in the preinst or postinst script (again, the latter is to be preferred if it is possible).

Note that changing the numeric value of an id associated with a name is very difficult, and involves searching the file system for all appropriate files. You need to think carefully whether a static or dynamic id is required, since changing your mind later will cause problems.

10.9.1. The use of dpkg-statoverride

This section is not intended as policy, but as a description of the use of dpkg-statoverride.

If a system administrator wishes to have a file (or directory or other such thing) installed with owner and permissions different from those in the distributed Debian package, they can use the dpkg-statoverride program to instruct dpkg to use the different settings every time the file is installed. Thus the package maintainer should distribute the files with their normal permissions, and leave it for the system administrator to make any desired changes. For example, a daemon which is normally required to be setuid root, but in certain situations could be used without being setuid, should be installed setuid in the .deb. Then the local system administrator can change this if they wish. If there are two standard ways of doing it, the package maintainer can use debconf to find out the preference, and call dpkg-statoverride in the maintainer script if necessary to accommodate the system administrator’s choice. Care must be taken during upgrades to not override an existing setting.

Given the above, dpkg-statoverride is essentially a tool for system administrators and would not normally be needed in the maintainer scripts. There is one type of situation, though, where calls to dpkg-statoverride would be needed in the maintainer scripts, and that involves packages which use dynamically allocated user or group ids. In such a situation, something like the following idiom can be very helpful in the package’s postinst, where sysuser is a dynamically allocated id:

  1. for i in /usr/bin/foo /usr/sbin/bar; do
  2. # only do something when no setting exists
  3. if ! dpkg-statoverride --list $i >/dev/null 2>&1; then
  4. #include: debconf processing, question about foo and bar
  5. if [ "$RET" = "true" ] ; then
  6. dpkg-statoverride --update --add sysuser root 4755 $i
  7. fi
  8. fi
  9. done

The corresponding code to remove the override when the package is purged would be:

  1. for i in /usr/bin/foo /usr/sbin/bar; do
  2. if dpkg-statoverride --list $i >/dev/null 2>&1; then
  3. dpkg-statoverride --remove $i
  4. fi
  5. done