3 # To view the formatted manual page of this file, type:
4 # POSTFIXSOURCE/mantools/srctoman - postfix-install | nroff -man
10 # Postfix installation procedure
12 # sh postfix-install [options] [name=value] ...
14 # The postfix-install script is to be run from the top-level
15 # Postfix source directory. It implements the following operations:
17 # Install or upgrade Postfix from source code. This requires
18 # super-user privileges.
20 # Build a package that can be distributed to other systems, in order
21 # to install or upgrade Postfix elsewhere. This requires no super-user
22 # privileges. To complete the installation after unpacking the
23 # package, execute as super-user the post-install script in the Postfix
24 # configuration directory.
26 # The postfix-install script is controlled by installation parameters.
27 # Specific parameters are described at the end of this document.
29 # By default, postfix-install asks the user for installation
30 # parameter settings. Most settings are stored in the installed
31 # main.cf file. Stored settings are used as site-specific defaults
32 # when the postfix-install script is run later.
34 # The names of Postfix files and directories, as well as their
35 # ownerships and permissions, are stored in the postfix-files file
36 # in the Postfix configuration directory. This information is used
37 # by the post-install script (also in the configuration directory)
38 # for creating missing queue directories when Postfix is started,
39 # and for setting correct ownership and permissions when Postfix
40 # is installed from a pre-built package or from source code.
43 # .IP -non-interactive
44 # Do not ask the user for parameter settings. Installation parameters
45 # are specified via one of the non-interactive methods described
48 # Build a ready-to-install package. This requires that a
49 # non-default install_root parameter is specified.
50 # INSTALLATION PARAMETER INPUT METHODS
53 # Parameter settings can be specified through a variety of
54 # mechanisms. In order of decreasing precedence these are:
55 # .IP "interactive mode"
56 # By default, postfix-install will ask the user for installation
57 # parameter settings. These settings have the highest precedence.
59 # Parameter settings can be given as name=value arguments on
60 # the postfix-install command line.
61 # .IP "process environment"
62 # Parameter settings can be given as name=value environment
63 # variables. Environment parameters can also be specified on the
64 # make(1) command line as "make install name=value ...".
65 # .IP "installed configuration files"
66 # If a parameter is not specified via the command line or via the
67 # process environment, postfix-install will attempt to extract its
68 # value from an already installed Postfix main.cf configuration file.
69 # .IP "built-in defaults"
70 # These settings have the lowest precedence.
71 # INSTALLATION PARAMETER DESCRIPTION
74 # The description of installation parameters and their built-in
75 # default settings is as follows:
77 # Prefix that is prepended to the pathnames of installed files.
78 # Specify this ONLY when creating pre-built packages for distribution to
79 # other systems. The built-in default is "/", the local root directory.
80 # This parameter setting is not recorded in the installed main.cf file.
82 # Directory for scratch files while installing Postfix.
83 # You must have write permission in this directory.
84 # The built-in default directory name is the current directory.
85 # This parameter setting is not recorded in the installed main.cf file.
86 # .IP config_directory
87 # The final destination directory for Postfix configuration files.
88 # The built-in default directory name is /etc/postfix.
89 # This parameter setting is not recorded in the installed main.cf file
90 # and can be changed only by recompiling Postfix.
92 # The final destination directory for Postfix-writable data files such
93 # as caches. This directory should not be shared with non-Postfix
94 # software. The built-in default directory name is /var/db/postfix.
95 # This parameter setting is recorded in the installed main.cf file.
96 # .IP daemon_directory
97 # The final destination directory for Postfix daemon programs. This
98 # directory should not be in the command search path of any users.
99 # The built-in default directory name is /usr/libexec/postfix.
100 # This parameter setting is recorded in the installed main.cf file.
101 # .IP command_directory
102 # The final destination directory for Postfix administrative commands.
103 # This directory should be in the command search path of adminstrative
104 # users. The built-in default directory name is system dependent.
105 # This parameter setting is recorded in the installed main.cf file.
107 # The destination directory for the Postfix HTML files.
108 # This parameter setting is recorded in the installed main.cf file.
109 # .IP queue_directory
110 # The final destination directory for Postfix queues.
111 # The built-in default directory name is /var/spool/postfix.
112 # This parameter setting is recorded in the installed main.cf file.
114 # The final destination pathname for the Postfix sendmail command.
115 # This is the Sendmail-compatible mail posting interface.
116 # The built-in default pathname is system dependent.
117 # This parameter setting is recorded in the installed main.cf file.
118 # .IP newaliases_path
119 # The final destination pathname for the Postfix newaliases command.
120 # This is the Sendmail-compatible command to build alias databases
121 # for the Postfix local delivery agent.
122 # The built-in default pathname is system dependent.
123 # This parameter setting is recorded in the installed main.cf file.
125 # The final destination pathname for the Postfix mailq command.
126 # This is the Sendmail-compatible command to list the mail queue.
127 # The built-in default pathname is system dependent.
128 # This parameter setting is recorded in the installed main.cf file.
130 # The owner of the Postfix queue. Its numerical user ID and group ID
131 # must not be used by any other accounts on the system.
132 # The built-in default account name is postfix.
133 # This parameter setting is recorded in the installed main.cf file.
135 # The group for mail submission and for queue management commands.
136 # Its numerical group ID must not be used by any other accounts on the
137 # system, not even by the mail_owner account.
138 # The built-in default group name is postdrop.
139 # This parameter setting is recorded in the installed main.cf file.
140 # .IP manpage_directory
141 # The destination directory for the Postfix on-line manual pages.
142 # This parameter setting is recorded in the installed main.cf file.
143 # .IP sample_directory
144 # The destination directory for the Postfix sample configuration files.
145 # This parameter is obsolete as of Postfix version 2.1.
146 # This parameter setting is recorded in the installed main.cf file.
147 # .IP readme_directory
148 # The destination directory for the Postfix README files.
149 # This parameter setting is recorded in the installed main.cf file.
151 # post-install(1) post-installation procedure
153 # $config_directory/main.cf, Postfix installation configuration.
154 # $daemon_directory/postfix-files, installation control file.
155 # $config_directory/install.cf, obsolete configuration file.
159 # The Secure Mailer license must be distributed with this software.
162 # IBM T.J. Watson Research
164 # Yorktown Heights, NY 10598, USA
168 # By now, shells must have functions. Ultrix users must use sh5 or lose.
171 PATH
=/bin
:/usr
/bin
:/usr
/sbin
:/usr
/etc
:/sbin
:/etc
:/usr
/contrib
/bin
:/usr
/gnu
/bin
:/usr
/ucb
:/usr
/bsd
177 USAGE
="Usage: $0 [name=value] [option]
178 -non-interactive Do not ask for installation parameters.
179 -package Build a ready-to-install package.
180 name=value Specify an installation parameter".
182 # Process command-line options and parameter settings. Work around
183 # brain damaged shells. "IFS=value command" should not make the
184 # IFS=value setting permanent. But some broken standard allows it.
189 *=*) IFS
= eval $arg; IFS
="$BACKUP_IFS";;
190 -non-int*) non_interactive
=1;;
191 -package) need_install_root
=install_root
;;
192 *) echo "$0: Error: $USAGE" 1>&2; exit 1;;
199 test -z "$non_interactive" -a ! -t 0 && {
200 echo $0: Error
: for non-interactive use
, run
: \"$0 -non-interactive\" 1>&2
204 test -x bin
/postconf ||
{
205 echo $0: Error
: no bin
/postconf
file. Did you forget to run
\"make\"?
1>&2
216 test -z "$non_interactive" && cat <<EOF | ${FMT}
218 Warning: if you use this script to install Postfix locally,
219 this script will replace existing sendmail or Postfix programs.
220 Make backups if you want to be able to recover.
222 Before installing files, this script prompts you for some
223 definitions. Most definitions will be remembered, so you have
224 to specify them only once. All definitions should have a
225 reasonable default value.
228 # The following shell functions replace files/symlinks while minimizing
229 # the time that a file does not exist, and avoid copying over files
230 # in order to not disturb running programs. That is certainly desirable
231 # when upgrading Postfix on a live machine. It also avoids surprises
232 # when building a Postfix package for distribution to other systems.
234 compare_or_replace
() {
240 (cmp $src $dst >/dev
/null
2>&1 && echo Skipping
$dst...
) ||
{
241 echo Updating
$dst...
242 rm -f $tempdir/junk ||
exit 1
243 cp $src $tempdir/junk ||
exit 1
244 mv -f $tempdir/junk
$dst ||
exit 1
245 test -z "$owner" || chown
$owner $dst ||
exit 1
246 test -z "$group" || chgrp
$group $dst ||
exit 1
247 chmod $mode $dst ||
exit 1
251 compare_or_symlink
() {
252 (cmp $1 $2 >/dev
/null
2>&1 && echo Skipping
$2...
) ||
{
254 rm -f $tempdir/junk ||
exit 1
255 dest
=`echo $1 | sed '
261 link
=`echo $2 | sed '
270 ln -s $link $tempdir/junk ||
exit 1
271 mv -f $tempdir/junk
$2 ||
{
272 echo $0: Error
: your
mv command has trouble renaming symlinks.
1>&2
273 echo If you run Linux
, upgrade to GNU fileutils-4.0 or better
, 1>&2
274 echo or choose a tempdir that is
in the same
file system as
$2.
1>&2
275 echo If you run FreeBSD
, upgrade to version
5 or better.
1>&2
281 compare_or_hardlink
() {
282 (cmp $1 $2 >/dev
/null
2>&1 && echo Skipping
$2...
) ||
{
292 dir
=`echo $path|sed -e 's/[/][/]*[^/]*$//' -e 's/^$/\//'`
293 test -d $dir || mkdir
-p $dir ||
exit 1
297 # How to supress newlines in echo.
306 install_root_prompt
="the prefix for installed file names. Specify
307 this ONLY if you are building ready-to-install packages for
308 distribution to other machines."
310 tempdir_prompt
="a directory for scratch files while installing
311 Postfix. You must have write permission in this directory."
313 config_directory_prompt
="the final destination directory for
314 installed Postfix configuration files."
316 data_directory_prompt
="the final destination directory for
317 Postfix-writable data files such as caches or random numbers. This
318 directory should not be shared with non-Postfix software."
320 daemon_directory_prompt
="the final destination directory for
321 installed Postfix daemon programs. This directory should not be
322 in the command search path of any users."
324 command_directory_prompt
="the final destination directory for
325 installed Postfix administrative commands. This directory should
326 be in the command search path of adminstrative users."
328 queue_directory_prompt
="the final destination directory for Postfix
331 sendmail_path_prompt
="the final destination pathname for the
332 installed Postfix sendmail command. This is the Sendmail-compatible
333 mail posting interface."
335 newaliases_path_prompt
="the final destination pathname for the
336 installed Postfix newaliases command. This is the Sendmail-compatible
337 command to build alias databases for the Postfix local delivery
340 mailq_path_prompt
="the final destination pathname for the installed
341 Postfix mailq command. This is the Sendmail-compatible mail queue
344 mail_owner_prompt
="the owner of the Postfix queue. Specify an
345 account with numerical user ID and group ID values that are not
346 used by any other accounts on the system."
348 setgid_group_prompt
="the group for mail submission and for queue
349 management commands. Specify a group name with a numerical group
350 ID that is not shared with other accounts, not even with the Postfix
351 mail_owner account. You can no longer specify \"no\" here."
353 manpage_directory_prompt
="the destination directory for the Postfix on-line
354 manual pages. You can no longer specify \"no\" here."
356 readme_directory_prompt
="the destination directory for the Postfix
357 README files. Specify \"no\" if you do not want to install these files."
359 html_directory_prompt
="the destination directory for the Postfix
360 HTML files. Specify \"no\" if you do not want to install these files."
362 # Default settings, just to get started.
366 : ${config_directory=`bin/postconf -h -d config_directory`}
368 # Find out the location of installed configuration files.
370 test -z "$non_interactive" && for name
in install_root tempdir config_directory
375 eval echo Please specify \$
${name}_prompt |
${FMT}
376 eval echo \
$n "$name: [\$$name]\ \$c"
381 /*) eval $name=$ans; break;;
382 *) echo; echo $0: Error
: $name should be an absolute path name.
1>&2;;
388 # In case some systems special-case pathnames beginning with //.
390 case $install_root in
394 test -z "$need_install_root" ||
test -n "$install_root" ||
{
395 echo $0: Error
: invalid package root directory
: \"install_root
=/\" 1>&2
399 CONFIG_DIRECTORY
=$install_root$config_directory
401 # If a parameter is not set via the command line or environment,
402 # try to use settings from installed configuration files.
404 # Extract parameter settings from the obsolete install.cf file, as
405 # a transitional aid.
407 grep setgid_group
$CONFIG_DIRECTORY/main.cf
>/dev
/null
2>&1 ||
{
408 test -f $CONFIG_DIRECTORY/install.cf
&& {
409 for name
in sendmail_path newaliases_path mailq_path setgid manpages
413 "") eval unset $name;;
415 eval : \
${$name="\`. $CONFIG_DIRECTORY/install.cf; echo \$$name\`"} \
418 : ${setgid_group=$setgid}
419 : ${manpage_directory=$manpages}
423 CONFIG_PARAMS
="command_directory daemon_directory data_directory \
424 html_directory mail_owner mailq_path manpage_directory newaliases_path \
425 queue_directory readme_directory sendmail_path setgid_group"
427 # Extract parameter settings from the installed main.cf file.
429 test -f $CONFIG_DIRECTORY/main.cf
&& {
430 for name
in $CONFIG_PARAMS sample_directory
434 "") eval unset $name;;
436 eval : \
${$name=\`bin/postconf -c $CONFIG_DIRECTORY -h $name\`} ||
441 # Use built-in defaults as the final source of parameter settings.
443 for name
in $CONFIG_PARAMS sample_directory
447 "") eval unset $name;;
449 eval : \
${$name=\`bin/postconf -d -h $name\`} ||
exit 1
452 # Override settings manually.
454 test -z "$non_interactive" && for name
in $CONFIG_PARAMS
459 eval echo Please specify \$
${name}_prompt |
${FMT}
460 eval echo \
$n "$name: [\$$name]\ \$c"
464 *) eval $name=$ans; break;;
471 case "$setgid_group" in
472 no
) (echo $0: Error
: the setgid_group parameter no longer accepts
473 echo \"no
\" values. Try again with
\"setgid_group
=groupname
\" on the
474 echo command line or execute
\"make install\" and specify setgid_group
475 echo interactively.
) |
${FMT} 1>&2
479 case "$manpage_directory" in
480 no
) (echo $0: Error
: the manpage_directory parameter no longer accepts
481 echo \"no
\" values. Try again with
\"manpage_directory
=/path
/name
\"
482 echo on the
command line or execute
\"make install\" and specify
483 echo manpage_directory interactively.
) |
${FMT} 1>&2
487 for path
in "$html_directory" "$readme_directory"
492 *) echo $0: Error
: \"$path\" should be
\"no
\" or an absolute path name.
1>&2
497 for path
in "$daemon_directory" "$data_directory" "$command_directory" "$queue_directory" \
498 "$sendmail_path" "$newaliases_path" "$mailq_path" "$manpage_directory"
502 *) echo $0: Error
: \"$path\" should be an absolute path name.
1>&2; exit 1;;
506 for path
in mailq_path newaliases_path sendmail_path
508 eval test -d $install_root\$
$path && {
509 echo $0: Error
: \"$path\" specifies a directory.
1>&2
514 for path
in command_directory config_directory daemon_directory data_directory \
515 manpage_directory queue_directory html_directory readme_directory
517 eval test -f $install_root\$
$path && {
518 echo $0: Error
: \"$path\" specifies a regular
file.
1>&2
523 test -d $tempdir || mkdir
-p $tempdir ||
exit 1
525 trap "rm -f $tempdir/junk" 0 1 2 3 15
527 ( rm -f $tempdir/junk
&& touch $tempdir/junk
) ||
{
528 echo $0: Error
: you have no
write permission to
$tempdir.
1>&2
529 echo Specify an alternative directory
for scratch files.
1>&2
533 test -z "$install_root" && {
535 chown root
$tempdir/junk
>/dev
/null
2>&1 ||
{
536 echo Error
: you have no permission to change
file ownership.
1>&2
540 chown
"$mail_owner" $tempdir/junk
>/dev
/null
2>&1 ||
{
541 echo $0: Error
: \"$mail_owner\" needs an entry
in the passwd
file.
1>&2
542 echo Remember
, \"$mail_owner\" needs a dedicated user and group id.
1>&2
546 chgrp
"$setgid_group" $tempdir/junk
>/dev
/null
2>&1 ||
{
547 echo $0: Error
: \"$setgid_group\" needs an entry
in the group
file.
1>&2
548 echo Remember
, \"$setgid_group\" needs a dedicated group id.
1>&2
554 rm -f $tempdir/junk ||
exit 1
560 DAEMON_DIRECTORY
=$install_root$daemon_directory
561 COMMAND_DIRECTORY
=$install_root$command_directory
562 QUEUE_DIRECTORY
=$install_root$queue_directory
563 SENDMAIL_PATH
=$install_root$sendmail_path
564 HTML_DIRECTORY
=$install_root$html_directory
565 MANPAGE_DIRECTORY
=$install_root$manpage_directory
566 README_DIRECTORY
=$install_root$readme_directory
568 # Avoid repeated tests for existence of these; default permissions suffice.
570 test -d $DAEMON_DIRECTORY || mkdir
-p $DAEMON_DIRECTORY ||
exit 1
571 test -d $COMMAND_DIRECTORY || mkdir
-p $COMMAND_DIRECTORY ||
exit 1
572 test -d $COMMAND_DIRECTORY || mkdir
-p $COMMAND_DIRECTORY ||
exit 1
573 test "$html_directory" = "no" -o -d $HTML_DIRECTORY ||
574 mkdir
-p $HTML_DIRECTORY ||
exit 1
575 test "$readme_directory" = "no" -o -d $README_DIRECTORY ||
576 mkdir
-p $README_DIRECTORY ||
exit 1
578 # Upgrade or first-time installation?
580 if [ -f $CONFIG_DIRECTORY/main.cf
]
582 post_install_options
="upgrade-source"
584 post_install_options
="first-install"
587 # Install files, using information from the postfix-files file.
589 exec < libexec
/postfix-files ||
exit 1
590 while IFS
=: read path
type owner group mode flags junk
601 # Skip over files that ought to be removed.
602 # Leave it up to post-install to report them to the user.
608 # Skip over files that must be preserved.
611 *p
*) eval test -f $install_root$path && {
612 eval echo "Skipping $install_root$path..."
617 # Save source path before it is clobbered.
620 [hl
]) eval source=$owner;;
623 # If installing from source code, apply special permissions or ownership.
624 # If building a package, don't apply special permissions or ownership.
626 case $install_root in
628 [$
]*) eval owner
=$owner;;
632 [$
]*) eval group
=$group;;
645 # Create/update directory.
647 d
) eval path
=$install_root$path
648 test "$path" = "${install_root}no" -o -d $path ||
{
649 mkdir
-p $path ||
exit 1
650 test -z "$owner" || chown
$owner $path ||
exit 1
651 test -z "$group" || chgrp
$group $path ||
exit 1
652 chmod $mode $path ||
exit 1
656 # Create/update regular file.
658 f
) echo $path |
(IFS
=/ read prefix
file; IFS
="$BACKUP_IFS"
661 compare_or_replace
$mode "$owner" "$group" libexec
/$file \
662 $DAEMON_DIRECTORY/$file ||
exit 1;;
663 '$command_directory')
664 compare_or_replace
$mode "$owner" "$group" bin
/$file \
665 $COMMAND_DIRECTORY/$file ||
exit 1;;
667 compare_or_replace
$mode "$owner" "$group" conf
/$file \
668 $CONFIG_DIRECTORY/$file ||
exit 1;;
670 check_parent
$SENDMAIL_PATH ||
exit 1
671 compare_or_replace
$mode "$owner" "$group" bin
/sendmail \
672 $SENDMAIL_PATH ||
exit 1;;
674 test "$html_directory" = "no" ||
675 compare_or_replace
$mode "$owner" "$group" html
/$file \
676 $HTML_DIRECTORY/$file ||
exit 1;;
677 '$manpage_directory')
678 check_parent
$MANPAGE_DIRECTORY/$file ||
exit 1
679 compare_or_replace
$mode "$owner" "$group" man
/$file \
680 $MANPAGE_DIRECTORY/$file ||
exit 1;;
682 test "$readme_directory" = "no" ||
683 compare_or_replace
$mode "$owner" "$group" README_FILES
/$file \
684 $README_DIRECTORY/$file ||
exit 1;;
685 *) echo $0: Error
: unknown entry
$path in libexec
/postfix-files
1>&2
690 # Hard link. Skip files that are not installed.
692 h
) eval echo $path |
(
693 IFS
=/ read prefix
file; IFS
="$BACKUP_IFS"
694 test "$prefix" = "no" ||
(
695 eval dest_path
=$install_root$path
696 check_parent
$dest_path ||
exit 1
697 eval source_path
=$install_root$source
698 compare_or_hardlink
$source_path $dest_path ||
exit 1
703 # Symbolic link. Skip files that are not installed.
705 l
) eval echo $path |
(
706 IFS
=/ read prefix
file; IFS
="$BACKUP_IFS"
707 test "$prefix" = "no" ||
(
708 eval dest_path
=$install_root$path
709 check_parent
$dest_path ||
exit 1
710 eval source_path
=$install_root$source
711 compare_or_symlink
$source_path $dest_path ||
exit 1
716 *) echo $0: Error
: unknown
type $type for $path in libexec
/postfix-files
1>&2
722 # Save the installation parameters to main.cf even when they haven't
723 # changed from their current default. Defaults can change between
724 # Postfix releases, and software should not suddenly be installed in
725 # the wrong place when Postfix is being upgraded.
727 bin
/postconf
-c $CONFIG_DIRECTORY -e \
728 "daemon_directory = $daemon_directory" \
729 "data_directory = $data_directory" \
730 "command_directory = $command_directory" \
731 "queue_directory = $queue_directory" \
732 "mail_owner = $mail_owner" \
733 "setgid_group = $setgid_group" \
734 "sendmail_path = $sendmail_path" \
735 "mailq_path = $mailq_path" \
736 "newaliases_path = $newaliases_path" \
737 "html_directory = $html_directory" \
738 "manpage_directory = $manpage_directory" \
739 "sample_directory = $sample_directory" \
740 "readme_directory = $readme_directory" \
743 # If Postfix is being installed locally from source code, do the
744 # post-install processing now.
746 test -n "$install_root" ||
{
747 bin
/postfix post-install
$post_install_options ||
exit 1