1 /* $NetBSD: master_wakeup.c,v 1.3 2020/03/18 19:05:16 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* master_wakeup 3 6 /* SUMMARY 7 /* Postfix master - start/stop service wakeup timers 8 /* SYNOPSIS 9 /* #include "master.h" 10 /* 11 /* void master_wakeup_init(serv) 12 /* MASTER_SERV *serv; 13 /* 14 /* void master_wakeup_cleanup(serv) 15 /* MASTER_SERV *serv; 16 /* DESCRIPTION 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. 21 /* 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 27 /* wakeup timer. 28 /* 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. 35 /* DIAGNOSTICS 36 /* BUGS 37 /* SEE ALSO 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 42 /* LICENSE 43 /* .ad 44 /* .fi 45 /* The Secure Mailer license must be distributed with this software. 46 /* AUTHOR(S) 47 /* Wietse Venema 48 /* IBM T.J. Watson Research 49 /* P.O. Box 704 50 /* Yorktown Heights, NY 10598, USA 51 /* 52 /* Wietse Venema 53 /* Google, Inc. 54 /* 111 8th Avenue 55 /* New York, NY 10011, USA 56 /*--*/ 57 58 /* System library. */ 59 60 #include <sys_defs.h> 61 #include <unistd.h> 62 #include <string.h> 63 #include <errno.h> 64 65 /* Utility library. */ 66 67 #include <msg.h> 68 #include <trigger.h> 69 #include <events.h> 70 #include <set_eugid.h> 71 #include <set_ugid.h> 72 73 /* Global library. */ 74 75 #include <mail_proto.h> /* triggers */ 76 #include <mail_params.h> 77 78 /* Application-specific. */ 79 80 #include "mail_server.h" 81 #include "master.h" 82 83 /* master_wakeup_timer_event - wakeup event handler */ 84 85 static void master_wakeup_timer_event(int unused_event, void *context) 86 { 87 const char *myname = "master_wakeup_timer_event"; 88 MASTER_SERV *serv = (MASTER_SERV *) context; 89 int status; 90 static char wakeup = TRIGGER_REQ_WAKEUP; 91 92 /* 93 * Don't wakeup services whose automatic wakeup feature was turned off in 94 * the mean time. 95 */ 96 if (serv->wakeup_time == 0) 97 return; 98 99 /* 100 * Don't wake up services that are throttled. Find out what transport to 101 * use. We can't block here so we choose a short timeout. 102 */ 103 #define BRIEFLY 1 104 105 if (MASTER_THROTTLED(serv) == 0) { 106 if (msg_verbose) 107 msg_info("%s: service %s", myname, serv->name); 108 109 switch (serv->type) { 110 case MASTER_SERV_TYPE_INET: 111 status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 112 break; 113 case MASTER_SERV_TYPE_UNIX: 114 status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 115 break; 116 case MASTER_SERV_TYPE_UXDG: 117 status = -1; 118 errno = EOPNOTSUPP; 119 break; 120 #ifdef MASTER_SERV_TYPE_PASS 121 case MASTER_SERV_TYPE_PASS: 122 status = pass_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 123 break; 124 #endif 125 126 /* 127 * If someone compromises the postfix account then this must not 128 * overwrite files outside the chroot jail. Countermeasures: 129 * 130 * - Limit the damage by accessing the FIFO as postfix not root. 131 * 132 * - Have fifo_trigger() call safe_open() so we won't follow 133 * arbitrary hard/symlinks to files in/outside the chroot jail. 134 * 135 * - All non-chroot postfix-related files must be root owned (or 136 * postfix check complains). 137 * 138 * - The postfix user and group ID must not be shared with other 139 * applications (says the INSTALL documentation). 140 * 141 * Result of a discussion with Michael Tokarev, who received his 142 * insights from Solar Designer, who tested Postfix with a kernel 143 * module that is paranoid about open() calls. 144 */ 145 case MASTER_SERV_TYPE_FIFO: 146 set_eugid(var_owner_uid, var_owner_gid); 147 status = fifo_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 148 set_ugid(getuid(), getgid()); 149 break; 150 default: 151 msg_panic("%s: unknown service type: %d", myname, serv->type); 152 } 153 if (status < 0) 154 msg_warn("%s: service %s(%s): %m", 155 myname, serv->ext_name, serv->name); 156 } 157 158 /* 159 * Schedule another wakeup event. 160 */ 161 event_request_timer(master_wakeup_timer_event, (void *) serv, 162 serv->wakeup_time); 163 } 164 165 /* master_wakeup_init - start automatic service wakeup */ 166 167 void master_wakeup_init(MASTER_SERV *serv) 168 { 169 const char *myname = "master_wakeup_init"; 170 171 if (serv->wakeup_time == 0 || (serv->flags & MASTER_FLAG_CONDWAKE)) 172 return; 173 if (msg_verbose) 174 msg_info("%s: service %s time %d", 175 myname, serv->name, serv->wakeup_time); 176 master_wakeup_timer_event(0, (void *) serv); 177 } 178 179 /* master_wakeup_cleanup - cancel wakeup timer */ 180 181 void master_wakeup_cleanup(MASTER_SERV *serv) 182 { 183 const char *myname = "master_wakeup_cleanup"; 184 185 /* 186 * Cleanup, even when the wakeup feature has been turned off. There might 187 * still be a pending timer. Don't depend on the code that reloads the 188 * config file to reset the wakeup timer when things change. 189 */ 190 if (msg_verbose) 191 msg_info("%s: service %s", myname, serv->name); 192 193 event_cancel_timer(master_wakeup_timer_event, (void *) serv); 194 } 195