Home | History | Annotate | Line # | Download | only in conf
postmulti-script revision 1.1
      1  1.1  tron #! /bin/sh
      2  1.1  tron #	$NetBSD: postmulti-script,v 1.1 2009/06/23 10:08:23 tron Exp $
      3  1.1  tron #
      4  1.1  tron 
      5  1.1  tron umask 022
      6  1.1  tron 
      7  1.1  tron # postmulti(1) contract:
      8  1.1  tron #
      9  1.1  tron # Arguments:
     10  1.1  tron #  postmulti-script -e <edit_command>
     11  1.1  tron #
     12  1.1  tron # Environment:
     13  1.1  tron #
     14  1.1  tron # All actions:
     15  1.1  tron #
     16  1.1  tron #  MAIL_CONFIG			- config_directory of primary instance
     17  1.1  tron #  command_directory		- From primary instance
     18  1.1  tron #  daemon_directory		- From primary instance
     19  1.1  tron #  config_directroy		- config_directory of target instance
     20  1.1  tron #  queue_directory		- queue_directory of target instance
     21  1.1  tron #  data_directory		- data_directory of target instance
     22  1.1  tron #
     23  1.1  tron # Create, destroy, import and deport:
     24  1.1  tron #
     25  1.1  tron #  multi_instance_directories	- New value for primary instance
     26  1.1  tron #
     27  1.1  tron # Create, import and assign (unset == nochange, "-" == clear):
     28  1.1  tron #
     29  1.1  tron #  multi_instance_group		- New value for target instance
     30  1.1  tron #  multi_instance_name		- New value for target instance
     31  1.1  tron 
     32  1.1  tron : ${MAIL_CONFIG:?"do not invoke this command directly"}
     33  1.1  tron : ${command_directory:?"do not invoke this command directly"}
     34  1.1  tron : ${daemon_directory:?"do not invoke this command directly"}
     35  1.1  tron 
     36  1.1  tron USAGE="$0 -e create|destroy|import|deport|enable|disable|assign|init"
     37  1.1  tron usage() { echo "$0: Error: Usage: $USAGE" >&2; exit 1; }
     38  1.1  tron 
     39  1.1  tron TAG="$MAIL_LOGTAG/postmulti-script"
     40  1.1  tron fatal() { postlog -p fatal -t "$TAG" "$1"; exit 1; }
     41  1.1  tron 
     42  1.1  tron # args: add|del $dir
     43  1.1  tron #
     44  1.1  tron update_cfdirs() {
     45  1.1  tron     op=$1
     46  1.1  tron     dir=$2
     47  1.1  tron 
     48  1.1  tron     alt=`postconf -h alternate_config_directories` || return 1
     49  1.1  tron 
     50  1.1  tron     shift $#	# Needed on SunOS where bare "set --" is NOP!
     51  1.1  tron     IFS="$IFS,"; set -- $alt; IFS="$BACKUP_IFS"
     52  1.1  tron     keep=
     53  1.1  tron     found=
     54  1.1  tron     # Portability: SunOS "sh" needs 'in "$@"' for one-line for-loop.
     55  1.1  tron     for d in "$@"; do [ "$d" = "$dir" ] && found=1 || keep="$keep $d"; done
     56  1.1  tron 
     57  1.1  tron     set -- "multi_instance_directories = $multi_instance_directories"
     58  1.1  tron 
     59  1.1  tron     case $op in
     60  1.1  tron     add) test -n "$found" ||
     61  1.1  tron 	 set -- "$@" "alternate_config_directories =$keep $dir";;
     62  1.1  tron     del) test -n "$found" &&
     63  1.1  tron 	 set -- "$@" "alternate_config_directories =$keep";;
     64  1.1  tron       *) return 1;;		# XXX: Internal error
     65  1.1  tron     esac
     66  1.1  tron     postconf -e "$@" || return 1
     67  1.1  tron }
     68  1.1  tron 
     69  1.1  tron assign_names() {
     70  1.1  tron     # Set the instance name and group
     71  1.1  tron     #
     72  1.1  tron     test -n "$multi_instance_name" && {
     73  1.1  tron 	test "$multi_instance_name" = "-" && multi_instance_name=
     74  1.1  tron 	set -- "$@" "multi_instance_name = $multi_instance_name"
     75  1.1  tron     }
     76  1.1  tron     test -n "$multi_instance_group" && {
     77  1.1  tron 	test "$multi_instance_group" = "-" && multi_instance_group=
     78  1.1  tron 	set -- "$@" "multi_instance_group = $multi_instance_group"
     79  1.1  tron     }
     80  1.1  tron     test $# -eq 0 || postconf -c "$config_directory" -e "$@" || return 1
     81  1.1  tron }
     82  1.1  tron 
     83  1.1  tron # Process command-line options and parameter settings. Work around
     84  1.1  tron # brain damaged shells. "IFS=value command" should not make the
     85  1.1  tron # IFS=value setting permanent. But some broken standard allows it.
     86  1.1  tron 
     87  1.1  tron BACKUP_IFS="$IFS"
     88  1.1  tron action=
     89  1.1  tron 
     90  1.1  tron while getopts ":e:" opt
     91  1.1  tron do
     92  1.1  tron     case $opt in
     93  1.1  tron     e) action="$OPTARG";;
     94  1.1  tron     *) usage;;
     95  1.1  tron     esac
     96  1.1  tron done
     97  1.1  tron shift `expr $OPTIND - 1`
     98  1.1  tron 
     99  1.1  tron # Check for valid action and required instance name
    100  1.1  tron case "$action" in
    101  1.1  tron  create|import|destroy|deport|enable|disable|assign|init) ;;
    102  1.1  tron 						       *) usage;;
    103  1.1  tron esac
    104  1.1  tron test $# -eq 0 || usage
    105  1.1  tron 
    106  1.1  tron case $action in
    107  1.1  tron init)
    108  1.1  tron     postconf -e \
    109  1.1  tron     	'multi_instance_wrapper = ${command_directory}/postmulti -p --' \
    110  1.1  tron     	'multi_instance_enable = yes'
    111  1.1  tron     exit $? ;;
    112  1.1  tron esac
    113  1.1  tron 
    114  1.1  tron : ${config_directory:?"Invalid empty target instance config_directory"}
    115  1.1  tron 
    116  1.1  tron case $action in
    117  1.1  tron create|import)
    118  1.1  tron 
    119  1.1  tron     # Atomically install stock main.cf/master.cf files. We install the
    120  1.1  tron     # master.cf file last. Once it is present the instance is complete.
    121  1.1  tron     #
    122  1.1  tron     test -f $config_directory/main.cf -a \
    123  1.1  tron 	 -f $config_directory/master.cf || {
    124  1.1  tron 
    125  1.1  tron 	test "$action" = "create" || {
    126  1.1  tron 	    test -f $config_directory/main.cf ||
    127  1.1  tron 		fatal "'$config_directory' lacks a main.cf file"
    128  1.1  tron 	    test -f $config_directory/master.cf ||
    129  1.1  tron 		fatal "'$config_directory' lacks a master.cf file"
    130  1.1  tron 	}
    131  1.1  tron 
    132  1.1  tron 	# Create instance-specific directories
    133  1.1  tron 	#
    134  1.1  tron 	test -d $config_directory ||
    135  1.1  tron 	    { (umask 022; mkdir -p $config_directory) || exit 1; }
    136  1.1  tron 	test -d $queue_directory ||
    137  1.1  tron 	    { (umask 022; mkdir -p $queue_directory) || exit 1; }
    138  1.1  tron 	test -d $data_directory ||
    139  1.1  tron 	    { (umask 077; mkdir -p $data_directory) || exit 1; }
    140  1.1  tron 
    141  1.1  tron 	tmpdir=$config_directory/.tmp
    142  1.1  tron 	(umask 077; mkdir -p $tmpdir) || exit 1
    143  1.1  tron 	cp -p $daemon_directory/main.cf $tmpdir/main.cf || exit 1
    144  1.1  tron 
    145  1.1  tron 	# Shared install parameters are cloned from user-specified values in
    146  1.1  tron 	# the default instance, but only if explicitly set there. Otherwise,
    147  1.1  tron 	# they are commented out in the new main.cf file.
    148  1.1  tron 	#
    149  1.1  tron 	SHARED_PARAMETERS="
    150  1.1  tron 	    command_directory
    151  1.1  tron 	    daemon_directory
    152  1.1  tron 	    mail_owner
    153  1.1  tron 	    setgid_group
    154  1.1  tron 	    sendmail_path
    155  1.1  tron 	    mailq_path
    156  1.1  tron 	    newaliases_path
    157  1.1  tron 	    html_directory
    158  1.1  tron 	    manpage_directory
    159  1.1  tron 	    sample_directory
    160  1.1  tron 	    readme_directory
    161  1.1  tron 	"
    162  1.1  tron 
    163  1.1  tron 	shift $#	# Needed on SunOS where bare "set --" is NOP!
    164  1.1  tron 	comment_out=
    165  1.1  tron 	for p in $SHARED_PARAMETERS; do
    166  1.1  tron 	    val=`postconf -nh $p` || exit 1
    167  1.1  tron 	    test -n "$val" && { set -- "$@" "$p = $val"; continue; }
    168  1.1  tron 	    comment_out="$comment_out $p"
    169  1.1  tron 	done
    170  1.1  tron 
    171  1.1  tron 	# First comment-out any parameters that take default values
    172  1.1  tron 	test -n "$comment_out" && {
    173  1.1  tron 	    postconf -c $tmpdir -# $comment_out || exit 1
    174  1.1  tron 	}
    175  1.1  tron 
    176  1.1  tron 	# Now add instance-specific and non-default values.
    177  1.1  tron 	# By default, disable inet services and local submission
    178  1.1  tron 	# in new instances
    179  1.1  tron 	#
    180  1.1  tron 	postconf -c $tmpdir -e \
    181  1.1  tron 	    "queue_directory = $queue_directory" \
    182  1.1  tron 	    "data_directory = $data_directory" \
    183  1.1  tron 	    "authorized_submit_users =" \
    184  1.1  tron 	    "master_service_disable = inet" \
    185  1.1  tron 	    "$@" || exit 1
    186  1.1  tron 
    187  1.1  tron 
    188  1.1  tron 	cp -p $daemon_directory/master.cf $tmpdir/master.cf || exit 1
    189  1.1  tron 	mv $tmpdir/main.cf $config_directory/main.cf || exit 1
    190  1.1  tron 	mv $tmpdir/master.cf $config_directory/master.cf || exit 1
    191  1.1  tron 	rmdir $tmpdir 2>/dev/null
    192  1.1  tron     }
    193  1.1  tron 
    194  1.1  tron     # Set instance name and group
    195  1.1  tron     #
    196  1.1  tron     assign_names || exit 1
    197  1.1  tron 
    198  1.1  tron     # Update multi_instance_directories
    199  1.1  tron     # and drop from alternate_config_directories
    200  1.1  tron     #
    201  1.1  tron     # XXX: Must happen before set-permissions below, otherwise instance
    202  1.1  tron     # is treated as a non-slave instance by post-install via postfix(1).
    203  1.1  tron     #
    204  1.1  tron     update_cfdirs del $config_directory || exit 1
    205  1.1  tron 
    206  1.1  tron     # Update permissions of private files. Verifies existence of
    207  1.1  tron     # queue_directory and data_directory, ...
    208  1.1  tron     #
    209  1.1  tron     # XXX: Must happen after instance list updates above, otherwise instance
    210  1.1  tron     # is treated as a non-slave instance by post-install via postfix(1).
    211  1.1  tron     #
    212  1.1  tron     postfix -c $config_directory set-permissions || exit 1
    213  1.1  tron     ;;
    214  1.1  tron 
    215  1.1  tron deport)
    216  1.1  tron     # Deporting an already deleted instance?
    217  1.1  tron     #
    218  1.1  tron     [ -f "$config_directory/main.cf" ] || {
    219  1.1  tron 	update_cfdirs del $config_directory
    220  1.1  tron 	exit $?
    221  1.1  tron     }
    222  1.1  tron 
    223  1.1  tron     postfix -c "$config_directory" status >/dev/null 2>&1 &&
    224  1.1  tron     	fatal "Instance '$config_directory' is not stopped"
    225  1.1  tron 
    226  1.1  tron     # Update multi_instance_directories
    227  1.1  tron     # and add to alternate_config_directories
    228  1.1  tron     #
    229  1.1  tron     update_cfdirs add $config_directory || exit 1
    230  1.1  tron     ;;
    231  1.1  tron 
    232  1.1  tron destroy)
    233  1.1  tron     # Locate the target instance
    234  1.1  tron     #
    235  1.1  tron     [ -f "$config_directory/main.cf" ] ||
    236  1.1  tron 	fatal "$config_directory/main.cf file not found"
    237  1.1  tron 
    238  1.1  tron     postfix -c "$config_directory" status >/dev/null 2>&1 &&
    239  1.1  tron     	fatal "Instance '$config_directory' is not stopped"
    240  1.1  tron 
    241  1.1  tron     # XXX: Internal "postfix /some/cmd" interface via /bin/env for execvp().
    242  1.1  tron     #
    243  1.1  tron     for q in maildrop incoming active deferred hold
    244  1.1  tron     do
    245  1.1  tron 	postfix -c "$config_directory" /bin/env \
    246  1.1  tron 	    find "$q" ! -name "$q" ! -name "?" -perm 0700 -print |
    247  1.1  tron 	    grep "^" >/dev/null &&
    248  1.1  tron 	    fatal "Instance '$config_directory' $q queue is not empty"
    249  1.1  tron     done
    250  1.1  tron 
    251  1.1  tron     # Update multi_instance directories
    252  1.1  tron     # and also (just in case) drop from alternate_config_directories
    253  1.1  tron     #
    254  1.1  tron     update_cfdirs del $config_directory || exit 1
    255  1.1  tron 
    256  1.1  tron     # Change default personalities:
    257  1.1  tron     MAIL_CONFIG="$config_directory"; export MAIL_CONFIG
    258  1.1  tron 
    259  1.1  tron     # Full steam ahead, instance will be at least partly destroyed!
    260  1.1  tron 
    261  1.1  tron     # Try to remove data_directory, but not sub-directories.
    262  1.1  tron     # Note: care with "$TAG" insertion into sh -c 'script'.
    263  1.1  tron     #
    264  1.1  tron     postfix /bin/sh -c \
    265  1.1  tron     	'cd $data_directory; rm -f -- *; cd ..; rmdir $data_directory; \
    266  1.1  tron          PATH=$command_directory:$PATH; export PATH; \
    267  1.1  tron 	 test -d $data_directory && \
    268  1.1  tron 	     postlog -p warn -t "'"$TAG"'" \
    269  1.1  tron 	     	"$data_directory partly removed" 2>&1' 2>/dev/null
    270  1.1  tron 
    271  1.1  tron     # Remove Postfix-owned files in the queue directory.
    272  1.1  tron     # Remove all files in the "pid" sub-directory.
    273  1.1  tron     # Remove empty directories.
    274  1.1  tron     # Note: care with "$TAG" insertion into sh -c 'script'.
    275  1.1  tron     postfix /bin/sh -c \
    276  1.1  tron     	'find . -user $mail_owner ! -type d -exec rm -f -- "{}" ";"; \
    277  1.1  tron     	 find . -depth -user $mail_owner -type d -exec rmdir -- "{}" ";"; \
    278  1.1  tron 	 rm -f -- pid/*; rmdir *; cd ..; rmdir $queue_directory; \
    279  1.1  tron          PATH=$command_directory:$PATH; export PATH; \
    280  1.1  tron 	 test -d $queue_directory && \
    281  1.1  tron 	     postlog -p warn -t "'"$TAG"'" \
    282  1.1  tron 	     	"$queue_directory partly removed" 2>&1' 2>/dev/null
    283  1.1  tron 
    284  1.1  tron     # In the configuration directory remove just the main.cf and master.cf
    285  1.1  tron     # files.
    286  1.1  tron     rm -f -- "$MAIL_CONFIG/master.cf" "$MAIL_CONFIG/main.cf" 2>/dev/null
    287  1.1  tron     rmdir -- "$MAIL_CONFIG" 2>/dev/null
    288  1.1  tron     test -d "$MAIL_CONFIG" && \
    289  1.1  tron 	 postlog -p warn -t "$TAG" \
    290  1.1  tron 	    "$MAIL_CONFIG partly removed" 2>&1
    291  1.1  tron     ;;
    292  1.1  tron enable)
    293  1.1  tron     postconf -c "$config_directory" -e \
    294  1.1  tron     	"multi_instance_enable = yes" || exit 1;;
    295  1.1  tron disable)
    296  1.1  tron     postconf -c "$config_directory" -e \
    297  1.1  tron     	"multi_instance_enable = no" || exit 1;;
    298  1.1  tron assign)
    299  1.1  tron     assign_names || exit 1;;
    300  1.1  tron esac
    301  1.1  tron 
    302  1.1  tron exit 0
    303