7 /* Postfix master - start/stop service wakeup timers
11 /* void master_wakeup_init(serv)
14 /* void master_wakeup_cleanup(serv)
17 /* This module implements automatic service wakeup. In order to
18 /* wakeup a service, a wakeup trigger is sent to the corresponding
19 /* service port or FIFO, and a timer is started to repeat this sequence
20 /* after a configurable amount of time.
22 /* master_wakeup_init() wakes up the named service. No wakeup
23 /* is done or scheduled when a zero wakeup time is given, or when
24 /* the service has been throttled in the mean time.
25 /* It is OK to call master_wakeup_init() while a timer is already
26 /* running for the named service. The effect is to restart the
29 /* master_wakeup_cleanup() cancels the wakeup timer for the named
30 /* service. It is an error to disable a service while it still has
31 /* an active wakeup timer (doing so would cause a dangling reference
32 /* to a non-existent service).
33 /* It is OK to call master_wakeup_cleanup() even when no timer is
34 /* active for the named service.
38 /* inet_trigger(3), internet-domain client
39 /* unix_trigger(3), unix-domain client
40 /* fifo_trigger(3), fifo client
41 /* upass_trigger(3), file descriptor passing client
45 /* The Secure Mailer license must be distributed with this software.
48 /* IBM T.J. Watson Research
50 /* Yorktown Heights, NY 10598, USA
59 /* Utility library. */
64 #include <set_eugid.h>
69 #include <mail_proto.h> /* triggers */
70 #include <mail_params.h>
72 /* Application-specific. */
74 #include "mail_server.h"
77 /* master_wakeup_timer_event - wakeup event handler */
79 static void master_wakeup_timer_event(int unused_event
, char *context
)
81 const char *myname
= "master_wakeup_timer_event";
82 MASTER_SERV
*serv
= (MASTER_SERV
*) context
;
84 static char wakeup
= TRIGGER_REQ_WAKEUP
;
87 * Don't wakeup services whose automatic wakeup feature was turned off in
90 if (serv
->wakeup_time
== 0)
94 * Don't wake up services that are throttled. Find out what transport to
95 * use. We can't block here so we choose a short timeout.
99 if (MASTER_THROTTLED(serv
) == 0) {
101 msg_info("%s: service %s", myname
, serv
->name
);
103 switch (serv
->type
) {
104 case MASTER_SERV_TYPE_INET
:
105 status
= inet_trigger(serv
->name
, &wakeup
, sizeof(wakeup
), BRIEFLY
);
107 case MASTER_SERV_TYPE_UNIX
:
108 status
= LOCAL_TRIGGER(serv
->name
, &wakeup
, sizeof(wakeup
), BRIEFLY
);
110 #ifdef MASTER_SERV_TYPE_PASS
111 case MASTER_SERV_TYPE_PASS
:
112 status
= PASS_TRIGGER(serv
->name
, &wakeup
, sizeof(wakeup
), BRIEFLY
);
117 * If someone compromises the postfix account then this must not
118 * overwrite files outside the chroot jail. Countermeasures:
120 * - Limit the damage by accessing the FIFO as postfix not root.
122 * - Have fifo_trigger() call safe_open() so we won't follow
123 * arbitrary hard/symlinks to files in/outside the chroot jail.
125 * - All non-chroot postfix-related files must be root owned (or
126 * postfix check complains).
128 * - The postfix user and group ID must not be shared with other
129 * applications (says the INSTALL documentation).
131 * Result of a discussion with Michael Tokarev, who received his
132 * insights from Solar Designer, who tested Postfix with a kernel
133 * module that is paranoid about open() calls.
135 case MASTER_SERV_TYPE_FIFO
:
136 set_eugid(var_owner_uid
, var_owner_gid
);
137 status
= fifo_trigger(serv
->name
, &wakeup
, sizeof(wakeup
), BRIEFLY
);
138 set_ugid(getuid(), getgid());
141 msg_panic("%s: unknown service type: %d", myname
, serv
->type
);
144 msg_warn("%s: service %s(%s): %m",
145 myname
, serv
->ext_name
, serv
->name
);
149 * Schedule another wakeup event.
151 event_request_timer(master_wakeup_timer_event
, (char *) serv
,
155 /* master_wakeup_init - start automatic service wakeup */
157 void master_wakeup_init(MASTER_SERV
*serv
)
159 const char *myname
= "master_wakeup_init";
161 if (serv
->wakeup_time
== 0 || (serv
->flags
& MASTER_FLAG_CONDWAKE
))
164 msg_info("%s: service %s time %d",
165 myname
, serv
->name
, serv
->wakeup_time
);
166 master_wakeup_timer_event(0, (char *) serv
);
169 /* master_wakeup_cleanup - cancel wakeup timer */
171 void master_wakeup_cleanup(MASTER_SERV
*serv
)
173 const char *myname
= "master_wakeup_cleanup";
176 * Cleanup, even when the wakeup feature has been turned off. There might
177 * still be a pending timer. Don't depend on the code that reloads the
178 * config file to reset the wakeup timer when things change.
181 msg_info("%s: service %s", myname
, serv
->name
);
183 event_cancel_timer(master_wakeup_timer_event
, (char *) serv
);