Two different packages must not install programs with different functionality but with the same filenames. (The case of two programs having the same functionality but different implementations is handled via `alternatives' or the `Conflicts' mechanism. See Maintainer scripts, Section 2.3.8 and Conflicting binary packages - Conflicts, Section 7.3 respectively.) If this case happens, one of the programs must be renamed. The maintainers should report this to the debian-devel mailing list and try to find a consensus about which program will have to be renamed. If a consensus cannot be reached, both programs must be renamed.
Generally the following compilation parameters should be used:
CC = gcc CFLAGS = -O2 -Wall # sane warning options vary between programs LDFLAGS = # none install -s # (or use strip on the files in debian/tmp)
Note that by default all installed binaries should be stripped, either by using
the -s flag to install
, or by calling
strip
on the binaries after they have been copied into
debian/tmp but before the tree is made into a package.
The -N flag should not be used. On a.out systems it may have been useful for some very small binaries, but for ELF it has no good effect.
Debugging symbols are useful for error diagnosis, investigation of core dumps (which may be submitted by users in bug reports), or testing and developing the software. Therefore it is recommended to support building the package with debugging information through the following interface: If the environment variable DEB_BUILD_OPTIONS contains the string debug, compile the software with debugging information (usually this involves adding the -g flag to CFLAGS). This allows the generation of a build tree with debugging information. If the environment variable DEB_BUILD_OPTIONS contains the string nostrip, do not strip the files at installation time. This allows one to generate a package with debugging information included.[35] The following makefile snippet is an example of how one may test for either condition; you will probably have to massage this example in order to make it work for your package.
CFLAGS = -O2 -Wall INSTALL = install INSTALL_FILE = $(INSTALL) -p -o root -g root -m 644 INSTALL_PROGRAM = $(INSTALL) -p -o root -g root -m 755 INSTALL_SCRIPT = $(INSTALL) -p -o root -g root -m 755 INSTALL_DIR = $(INSTALL) -p -d -o root -g root -m 755 ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CFLAGS += -g endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif
It is up to the package maintainer to decide what compilation options are best for the package. Certain binaries (such as computationally-intensive programs) will function better with certain flags (-O3, for example); feel free to use them. Please use good judgment here. Don't use flags for the sake of it; only use them if there is good reason to do so. Feel free to override the upstream author's ideas about which compilation options are best: they are often inappropriate for our environment.
All libraries must have a shared version in the lib* package and a static version in the lib*-dev package. The shared version must be compiled with -fPIC, and the static version must not be. In other words, each *.c file will need to be compiled twice.
You must specify the gcc option -D_REENTRANT when building a library (either static or shared) to make the library compatible with LinuxThreads.
Note that all installed shared libraries should be stripped with
strip --strip-unneeded your-lib
(The option --strip-unneeded makes strip
remove only
the symbols which aren't needed for relocation processing.) Shared libraries
can function perfectly well when stripped, since the symbols for dynamic
linking are in a separate part of the ELF object file.[36]
Note that under some circumstances it may be useful to install a shared library unstripped, for example when building a separate package to support debugging.
Shared object files (often .so files) that are not public libraries, that is, they are not meant to be linked to by third party executables (binaries of other packages), should be installed in subdirectories of the /usr/lib directory. Such files are exempt from the rules that govern ordinary shared libraries, except that they must not be installed executable and should be stripped.[37]
Packages containing shared libraries that may be linked to by other packages' binaries, but which for some compelling reason can not be installed in /usr/lib directory, may install the shared library files in subdirectories of the /usr/lib directory, in which case they should arrange to add that directory in /etc/ld.so.conf in the package's post-installation script, and remove it in the package's post-removal script.
An ever increasing number of packages are using libtool
to do
their linking. The latest GNU libtools (>= 1.3a) can take advantage of the
metadata in the installed libtool
archive files (*.la
files). The main advantage of libtool
's .la files is
that it allows libtool
to store and subsequently access metadata
with respect to the libraries it builds. libtool
will search for
those files, which contain a lot of useful information about a library (such as
library dependency information for static linking). Also, they're
essential for programs using libltdl.[38]
Packages that use libtool
to create shared libraries should
include the .la files in the -dev package, unless the
package relies on libtool's libltdl library, in which
case the .la files must go in the run-time library package.
You must make sure that you use only released versions of shared libraries to build your packages; otherwise other users will not be able to run your binaries properly. Producing source packages that depend on unreleased compilers is also usually a bad idea.
Packages involving shared libraries should be split up into several binary packages.
For a straightforward library which has a development environment and a runtime kit including just shared libraries you need to create two packages: librarynamesoversion, where soversion is the version number in the soname of the shared library[39] and librarynamesoversion-dev.
If you prefer only to support one development version at a time you may name
the development package libraryname-dev; otherwise you
may need to use dpkg
's Conflicts mechanism (see Conflicting binary packages -
Conflicts, Section 7.3) to ensure that the user only installs
one development version at a time (as different development versions are likely
to have the same header files in them, which would cause a filename clash if
both were installed). Typically the development version should also have an
exact version dependency on the runtime library, to make sure that compilation
and linking happens correctly. The ${Source-Version} substitution
variable can be useful for this purpose.
Packages which use the shared library should have a dependency on the name of the shared library package, librarynamesoversion. When the soname changes you can have both versions of the library installed while migrating from the old library to the new.
If your package has some run-time support programs which use the shared library you must not put them in the shared library package. If you do that then you won't be able to install several versions of the shared library without getting filename clashes. Instead, either create a third package for the runtime binaries (this package might typically be named libraryname-runtime; note the absence of the soversion in the package name), or if the development package is small you may include them in there.
If you have several shared libraries built from the same source tree you may lump them all together into a single shared library package, provided that you change all of their sonames at once (so that you don't get filename clashes if you try to install different versions of the combined shared libraries package).
Shared libraries should not be installed executable, since the dynamic linker does not require this and trying to execute a shared library usually results in a core dump.
All command scripts, including the package maintainer scripts inside the
package and used by dpkg
, should have a #! line
naming the shell to be used to interpret them.
In the case of Perl scripts this should be #!/usr/bin/perl.
Shell scripts (sh
and bash
) should almost certainly
start with set -e so that errors are detected. Every script
should use set -e or check the exit status of every
command.
The standard shell interpreter /bin/sh can be a symbolic link to
any POSIX compatible shell, if echo -n does not generate a
newline.[40] Thus, shell scripts
specifying /bin/sh as interpreter should only use POSIX features.
If a script requires non-POSIX features from the shell interpreter, the
appropriate shell must be specified in the first line of the script (e.g.,
#!/bin/bash) and the package must depend on the package providing
the shell (unless the shell package is marked `Essential', as in the case of
bash
).
You may wish to restrict your script to POSIX features when possible so that it
may use /bin/sh as its interpreter. If your script works with
ash
, it's probably POSIX compliant, but if you are in doubt, use
/bin/bash.
Perl scripts should check for errors when making any system calls, including open, print, close, rename and system.
csh
and tcsh
should be avoided as scripting
languages. See Csh Programming Considered Harmful, one of the
comp.unix.* FAQs, which can be found at http://language.perl.com/versus/csh.whynot
.[41] If an upstream package comes with
csh
scripts then you must make sure that they start with
#!/bin/csh and make your package depend on the
c-shell
virtual package.
Any scripts which create files in world-writeable directories (e.g., in /tmp) must use a mechanism which will fail if a file with the same name already exists.
The Debian base system provides the tempfile
and
mktemp
utilities for use by scripts for this purpose.
In general, symbolic links within a top-level directory should be relative, and symbolic links pointing from one top-level directory into another should be absolute. (A top-level directory is a sub-directory of the root directory /.)
In addition, symbolic links should be specified as short as possible, i.e., link targets like foo/../bar are deprecated.
Note that when creating a relative link using ln
it is not
necessary for the target of the link to exist relative to the working directory
you're running ln
from, nor is it necessary to change directory to
the directory where the link is to be made. Simply include the string that
should appear as the target of the link (this will be a pathname relative to
the directory in which the link resides) as the first argument to
ln
.
For example, in your Makefile
or debian/rules, you
can do things like:
ln -fs gcc $(prefix)/bin/cc ln -fs gcc debian/tmp/usr/bin/cc ln -fs ../sbin/sendmail $(prefix)/bin/runq ln -fs ../sbin/sendmail debian/tmp/usr/bin/runq
A symbolic link pointing to a compressed file should always have the same file extension as the referenced file. (For example, if a file foo.gz is referenced by a symbolic link, the filename of the link has to end with `.gz' too, as in bar.gz.)
Packages must not include device files in the package file tree.
If a package needs any special device files that are not included in the base
system, it must call MAKEDEV
in the postinst
script,
after asking the user for permission to do so.
Packages must not remove any device files in the postrm
or any
other script. This is left to the system administrator.
Debian uses the serial devices /dev/ttyS*. Programs using the old /dev/cu* devices should be changed to use /dev/ttyS*.
dpkg
(see Details of configuration,
Section 6.6).
The distinction between these two is important; they are not interchangeable concepts. Almost all conffiles are configuration files, but many configuration files are not conffiles.
Note that a script that embeds configuration information (such as most of the files in /etc/default and /etc/cron.{daily,weekly,monthly}) is de-facto a configuration file and should be treated as such.
Any configuration files created or used by your package must reside in /etc. If there are several you should consider creating a subdirectory of /etc named after your package.
If your package creates or uses configuration files outside of /etc, and it is not feasible to modify the package to use the /etc, you should still put the files in /etc and create symbolic links to those files from the location that the package requires.
Configuration file handling must conform to the following behavior:
The easy way to achieve this behavior is to make the configuration file a conffile. This is appropriate only if it is possible to distribute a default version that will work for most installations, although some system administrators may choose to modify it. This implies that the default version will be part of the package distribution, and must not be modified by the maintainer scripts during installation (or at any other time).
In order to ensure that local changes are preserved correctly, no package may contain or make hard links to conffiles.[42]
The other way to do it is via the maintainer scripts. In this case, the
configuration file must not be listed as a conffile and must not
be part of the package distribution. If the existence of a file is required
for the package to be sensibly configured it is the responsibility of the
package maintainer to provide maintainer scripts which correctly create, update
and maintain the file and remove it on purge. (See Package maintainer scripts and installation
procedure, Chapter 6 for more information.) These scripts must be
idempotent (i.e., must work correctly if dpkg
needs to re-run them
due to errors during installation or removal), must cope with all the variety
of ways dpkg
can call maintainer scripts, must not overwrite or
otherwise mangle the user's configuration without asking, must not ask
unnecessary questions (particularly during upgrades), and otherwise be good
citizens.
The scripts are not required to configure every possible option for the
package, but only those necessary to get the package running on a given system.
Ideally the sysadmin should not have to do any configuration other than that
done (semi-)automatically by the postinst
script.
A common practice is to create a script called
package-configure and have the package's
postinst
call it if and only if the configuration file does not
already exist. In certain cases it is useful for there to be an example or
template file which the maintainer scripts use. Such files should be in
/usr/share/package or
/usr/lib/package (depending on whether they are
architecture-independent or not). There should be symbolic links to them from
/usr/share/doc/package/examples if they are examples,
and should be perfectly ordinary dpkg
-handled files (not
configuration files).
These two styles of configuration file handling must not be mixed, for that way
lies madness: dpkg
will ask about overwriting the file every time
the package is upgraded.
Packages which specify the same file as a conffile must be tagged
as conflicting with each other. (This is an instance of the general
rule about not sharing files. Note that neither alternatives nor diversions
are likely to be appropriate in this case; in particular, dpkg
does not handle diverted conffiles well.)
The maintainer scripts must not alter a conffile of any package, including the one the scripts belong to.
If two or more packages use the same configuration file and it is reasonable for both to be installed at the same time, one of these packages must be defined as owner of the configuration file, i.e., it will be the package which handles that file as a configuration file. Other packages that use the configuration file must depend on the owning package if they require the configuration file to operate. If the other package will use the configuration file if present, but is capable of operating without it, no dependency need be declared.
If it is desirable for two or more related packages to share a configuration file and for all of the related packages to be able to modify that configuration file, then the following should be done:
Sometimes it's appropriate to create a new package which provides the basic infrastructure for the other packages and which manages the shared configuration files. (The sgml-base package is a good example.)
The files in /etc/skel will automatically be copied into new user
accounts by adduser
. No other program should reference the files
in /etc/skel.
Therefore, if a program needs a dotfile to exist in advance in $HOME to work sensibly, that dotfile should be installed in /etc/skel and treated as a configuration file.
However, programs that require dotfiles in order to operate sensibly (dotfiles that they do not create themselves automatically, that is) are a bad thing. Furthermore, programs should be configured by the Debian default installation to behave as closely to the upstream default behaviour as possible.
Therefore, if a program in a Debian package needs to be configured in some way in order to operate sensibly, that should be done using a site-wide configuration file placed in /etc. Only if the program doesn't support a site-wide default configuration and the package maintainer doesn't have time to add it may a default per-user file be placed in /etc/skel.
/etc/skel should be as empty as we can make it. This is particularly true because there is no easy (or necessarily desirable) mechanism for ensuring that the appropriate dotfiles are copied into the accounts of existing users when a package is installed.
Log files should usually be named /var/log/package.log. If you have many log files, or need a separate directory for permission reasons (/var/log is writable only by root), you should usually create a directory named /var/log/package and place your log files there.
Log files must be rotated occasionally so that they don't grow indefinitely;
the best way to do this is to drop a log rotation configuration file into the
directory /etc/logrotate.d and use the facilities provided by
logrotate.[43] Here is a good
example for a logrotate config file (for more information see
logrotate(8)
):
/var/log/foo/* { rotate 12 weekly compress postrotate /etc/init.d/foo force-reload endscript }
This rotates all files under /var/log/foo, saves 12 compressed generations, and forces the daemon to reload its configuration information after the log rotation.
Log files should be removed when the package is purged (but not when it is only
removed). This should be done by the postrm
script when it is
called with the argument purge (see Details of removal and/or
configuration purging, Section 6.7).
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.
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.[44] 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 with the base system
maintainer that it is unique and that they do not wish you to use a statically
allocated id instead. 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.
dpkg-statoverride
This section is not intended as policy, but as a description of the use of
dpkg-statoverride
.
dpkg-statoverride
is a replacement for the deprecated
suidmanager package. Packages which previously used
suidmanager should have a Conflicts: suidmanager (<<
0.50) entry (or even (<< 0.52)), and calls to
suidregister and suidunregister should now be simply
removed from the maintainer scripts.
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, he 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.
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:
for i in /usr/bin/foo /usr/sbin/bar do if ! dpkg-statoverride --list $i >/dev/null then dpkg-statoverride --update --add sysuser root 4755 $i fi done
The corresponding dpkg-statoverride --remove calls can then be made unconditionally when the package is purged.
Debian Policy Manual
version 3.5.6.1, 2002-03-14ijackson@gnu.ai.mit.edu
schwarz@debian.org
bweaver@debian.org
debian-policy@lists.debian.org