1 /* $NetBSD: master_wakeup.c,v 1.2 2017/02/14 01:16:45 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 53 /* System library. */ 54 55 #include <sys_defs.h> 56 #include <unistd.h> 57 #include <string.h> 58 59 /* Utility library. */ 60 61 #include <msg.h> 62 #include <trigger.h> 63 #include <events.h> 64 #include <set_eugid.h> 65 #include <set_ugid.h> 66 67 /* Global library. */ 68 69 #include <mail_proto.h> /* triggers */ 70 #include <mail_params.h> 71 72 /* Application-specific. */ 73 74 #include "mail_server.h" 75 #include "master.h" 76 77 /* master_wakeup_timer_event - wakeup event handler */ 78 79 static void master_wakeup_timer_event(int unused_event, void *context) 80 { 81 const char *myname = "master_wakeup_timer_event"; 82 MASTER_SERV *serv = (MASTER_SERV *) context; 83 int status; 84 static char wakeup = TRIGGER_REQ_WAKEUP; 85 86 /* 87 * Don't wakeup services whose automatic wakeup feature was turned off in 88 * the mean time. 89 */ 90 if (serv->wakeup_time == 0) 91 return; 92 93 /* 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. 96 */ 97 #define BRIEFLY 1 98 99 if (MASTER_THROTTLED(serv) == 0) { 100 if (msg_verbose) 101 msg_info("%s: service %s", myname, serv->name); 102 103 switch (serv->type) { 104 case MASTER_SERV_TYPE_INET: 105 status = inet_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 106 break; 107 case MASTER_SERV_TYPE_UNIX: 108 status = LOCAL_TRIGGER(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 109 break; 110 #ifdef MASTER_SERV_TYPE_PASS 111 case MASTER_SERV_TYPE_PASS: 112 status = pass_trigger(serv->name, &wakeup, sizeof(wakeup), BRIEFLY); 113 break; 114 #endif 115 116 /* 117 * If someone compromises the postfix account then this must not 118 * overwrite files outside the chroot jail. Countermeasures: 119 * 120 * - Limit the damage by accessing the FIFO as postfix not root. 121 * 122 * - Have fifo_trigger() call safe_open() so we won't follow 123 * arbitrary hard/symlinks to files in/outside the chroot jail. 124 * 125 * - All non-chroot postfix-related files must be root owned (or 126 * postfix check complains). 127 * 128 * - The postfix user and group ID must not be shared with other 129 * applications (says the INSTALL documentation). 130 * 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. 134 */ 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()); 139 break; 140 default: 141 msg_panic("%s: unknown service type: %d", myname, serv->type); 142 } 143 if (status < 0) 144 msg_warn("%s: service %s(%s): %m", 145 myname, serv->ext_name, serv->name); 146 } 147 148 /* 149 * Schedule another wakeup event. 150 */ 151 event_request_timer(master_wakeup_timer_event, (void *) serv, 152 serv->wakeup_time); 153 } 154 155 /* master_wakeup_init - start automatic service wakeup */ 156 157 void master_wakeup_init(MASTER_SERV *serv) 158 { 159 const char *myname = "master_wakeup_init"; 160 161 if (serv->wakeup_time == 0 || (serv->flags & MASTER_FLAG_CONDWAKE)) 162 return; 163 if (msg_verbose) 164 msg_info("%s: service %s time %d", 165 myname, serv->name, serv->wakeup_time); 166 master_wakeup_timer_event(0, (void *) serv); 167 } 168 169 /* master_wakeup_cleanup - cancel wakeup timer */ 170 171 void master_wakeup_cleanup(MASTER_SERV *serv) 172 { 173 const char *myname = "master_wakeup_cleanup"; 174 175 /* 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. 179 */ 180 if (msg_verbose) 181 msg_info("%s: service %s", myname, serv->name); 182 183 event_cancel_timer(master_wakeup_timer_event, (void *) serv); 184 } 185