Postfix3.3.1
master_wakeup.c
[詳解]
1 /*++
2 /* NAME
3 /* master_wakeup 3
4 /* SUMMARY
5 /* Postfix master - start/stop service wakeup timers
6 /* SYNOPSIS
7 /* #include "master.h"
8 /*
9 /* void master_wakeup_init(serv)
10 /* MASTER_SERV *serv;
11 /*
12 /* void master_wakeup_cleanup(serv)
13 /* MASTER_SERV *serv;
14 /* DESCRIPTION
15 /* This module implements automatic service wakeup. In order to
16 /* wakeup a service, a wakeup trigger is sent to the corresponding
17 /* service port or FIFO, and a timer is started to repeat this sequence
18 /* after a configurable amount of time.
19 /*
20 /* master_wakeup_init() wakes up the named service. No wakeup
21 /* is done or scheduled when a zero wakeup time is given, or when
22 /* the service has been throttled in the mean time.
23 /* It is OK to call master_wakeup_init() while a timer is already
24 /* running for the named service. The effect is to restart the
25 /* wakeup timer.
26 /*
27 /* master_wakeup_cleanup() cancels the wakeup timer for the named
28 /* service. It is an error to disable a service while it still has
29 /* an active wakeup timer (doing so would cause a dangling reference
30 /* to a non-existent service).
31 /* It is OK to call master_wakeup_cleanup() even when no timer is
32 /* active for the named service.
33 /* DIAGNOSTICS
34 /* BUGS
35 /* SEE ALSO
36 /* inet_trigger(3), internet-domain client
37 /* unix_trigger(3), unix-domain client
38 /* fifo_trigger(3), fifo client
39 /* upass_trigger(3), file descriptor passing client
40 /* LICENSE
41 /* .ad
42 /* .fi
43 /* The Secure Mailer license must be distributed with this software.
44 /* AUTHOR(S)
45 /* Wietse Venema
46 /* IBM T.J. Watson Research
47 /* P.O. Box 704
48 /* Yorktown Heights, NY 10598, USA
49 /*--*/
50 
51 /* System library. */
52 
53 #include <sys_defs.h>
54 #include <unistd.h>
55 #include <string.h>
56 
57 /* Utility library. */
58 
59 #include <msg.h>
60 #include <trigger.h>
61 #include <events.h>
62 #include <set_eugid.h>
63 #include <set_ugid.h>
64 
65 /* Global library. */
66 
67 #include <mail_proto.h> /* triggers */
68 #include <mail_params.h>
69 
70 /* Application-specific. */
71 
72 #include "mail_server.h"
73 #include "master.h"
74 
75 /* master_wakeup_timer_event - wakeup event handler */
76 
77 static void master_wakeup_timer_event(int unused_event, void *context)
78 {
79  const char *myname = "master_wakeup_timer_event";
80  MASTER_SERV *serv = (MASTER_SERV *) context;
81  int status;
82  static char wakeup = TRIGGER_REQ_WAKEUP;
83 
84  /*
85  * Don't wakeup services whose automatic wakeup feature was turned off in
86  * the mean time.
87  */
88  if (serv->wakeup_time == 0)
89  return;
90 
91  /*
92  * Don't wake up services that are throttled. Find out what transport to
93  * use. We can't block here so we choose a short timeout.
94  */
95 #define BRIEFLY 1
96 
97  if (MASTER_THROTTLED(serv) == 0) {
98  if (msg_verbose)
99  msg_info("%s: service %s", myname, serv->name);
100 
101  switch (serv->type) {
103  status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
104  break;
106  status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
107  break;
108 #ifdef MASTER_SERV_TYPE_PASS
110  status = pass_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
111  break;
112 #endif
113 
114  /*
115  * If someone compromises the postfix account then this must not
116  * overwrite files outside the chroot jail. Countermeasures:
117  *
118  * - Limit the damage by accessing the FIFO as postfix not root.
119  *
120  * - Have fifo_trigger() call safe_open() so we won't follow
121  * arbitrary hard/symlinks to files in/outside the chroot jail.
122  *
123  * - All non-chroot postfix-related files must be root owned (or
124  * postfix check complains).
125  *
126  * - The postfix user and group ID must not be shared with other
127  * applications (says the INSTALL documentation).
128  *
129  * Result of a discussion with Michael Tokarev, who received his
130  * insights from Solar Designer, who tested Postfix with a kernel
131  * module that is paranoid about open() calls.
132  */
135  status = fifo_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY);
136  set_ugid(getuid(), getgid());
137  break;
138  default:
139  msg_panic("%s: unknown service type: %d", myname, serv->type);
140  }
141  if (status < 0)
142  msg_warn("%s: service %s(%s): %m",
143  myname, serv->ext_name, serv->name);
144  }
145 
146  /*
147  * Schedule another wakeup event.
148  */
149  event_request_timer(master_wakeup_timer_event, (void *) serv,
150  serv->wakeup_time);
151 }
152 
153 /* master_wakeup_init - start automatic service wakeup */
154 
156 {
157  const char *myname = "master_wakeup_init";
158 
159  if (serv->wakeup_time == 0 || (serv->flags & MASTER_FLAG_CONDWAKE))
160  return;
161  if (msg_verbose)
162  msg_info("%s: service %s time %d",
163  myname, serv->name, serv->wakeup_time);
164  master_wakeup_timer_event(0, (void *) serv);
165 }
166 
167 /* master_wakeup_cleanup - cancel wakeup timer */
168 
170 {
171  const char *myname = "master_wakeup_cleanup";
172 
173  /*
174  * Cleanup, even when the wakeup feature has been turned off. There might
175  * still be a pending timer. Don't depend on the code that reloads the
176  * config file to reset the wakeup timer when things change.
177  */
178  if (msg_verbose)
179  msg_info("%s: service %s", myname, serv->name);
180 
181  event_cancel_timer(master_wakeup_timer_event, (void *) serv);
182 }
int msg_verbose
Definition: msg.c:177
NORETURN msg_panic(const char *fmt,...)
Definition: msg.c:295
#define MASTER_SERV_TYPE_PASS
Definition: master.h:81
char * ext_name
Definition: master.h:29
void master_wakeup_init(MASTER_SERV *serv)
int wakeup_time
Definition: master.h:33
char * name
Definition: master.h:30
#define MASTER_THROTTLED(f)
Definition: master.h:69
int inet_trigger(const char *service, const char *buf, ssize_t len, int timeout)
Definition: inet_trigger.c:93
int type
Definition: master.h:31
gid_t var_owner_gid
Definition: mail_params.c:235
uid_t var_owner_uid
Definition: mail_params.c:234
int flags
Definition: master.h:28
void msg_warn(const char *fmt,...)
Definition: msg.c:215
#define MASTER_SERV_TYPE_UNIX
Definition: master.h:78
#define MASTER_SERV_TYPE_INET
Definition: master.h:79
void set_eugid(uid_t euid, gid_t egid)
Definition: set_eugid.c:54
void set_ugid(uid_t uid, gid_t gid)
Definition: set_ugid.c:45
#define TRIGGER_REQ_WAKEUP
Definition: mail_proto.h:101
#define BRIEFLY
time_t event_request_timer(EVENT_NOTIFY_TIME_FN callback, void *context, int delay)
Definition: events.c:894
int fifo_trigger(const char *service, const char *buf, ssize_t len, int timeout)
Definition: fifo_trigger.c:58
int pass_trigger(const char *service, const char *buf, ssize_t len, int timeout)
Definition: pass_trigger.c:97
#define MASTER_SERV_TYPE_FIFO
Definition: master.h:80
int event_cancel_timer(EVENT_NOTIFY_TIME_FN callback, void *context)
Definition: events.c:965
#define LOCAL_TRIGGER
Definition: sys_defs.h:1425
#define MASTER_FLAG_CONDWAKE
Definition: master.h:64
void msg_info(const char *fmt,...)
Definition: msg.c:199
void master_wakeup_cleanup(MASTER_SERV *serv)