1c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth/* Copyright (c) 2006 Trusted Computer Solutions, Inc. */ 2c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/types.h> 3c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/socket.h> 4c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/poll.h> 5c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/stat.h> 6c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/un.h> 7c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <errno.h> 8c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <stdint.h> 9c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <stdio.h> 10c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <unistd.h> 11c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <stdlib.h> 12c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <signal.h> 13c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <string.h> 14c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <syslog.h> 158ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh#include <unistd.h> 16c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <selinux/selinux.h> 17c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/types.h> 18c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/capability.h> 19c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include <sys/resource.h> 20c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#include "mcstrans.h" 21c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 22c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#ifdef UNUSED 23c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#elif defined(__GNUC__) 24c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth# define UNUSED(x) UNUSED_ ## x __attribute__((unused)) 25c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#elif defined(__LCLINT__) 26c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth# define UNUSED(x) /*@unused@*/ x 27c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#else 28c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth# define UNUSED(x) x 29c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#endif 30c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 31c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define SETRANS_UNIX_SOCKET "/var/run/setrans/.setrans-unix" 32c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 33c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define SETRANS_INIT 1 34c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define RAW_TO_TRANS_CONTEXT 2 35c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define TRANS_TO_RAW_CONTEXT 3 36c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define RAW_CONTEXT_TO_COLOR 4 37c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define MAX_DATA_BUF 4096 38c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define MAX_DESCRIPTORS 8192 39c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 40c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#ifdef DEBUG 41c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth//#define log_debug(fmt, ...) syslog(LOG_DEBUG, fmt, __VA_ARGS__) 42c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define log_debug(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) 43c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#else 44c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define log_debug(fmt, ...) ; 45c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#endif 46c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 47c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern int init_translations(void); 48c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern void finish_context_translations(void); 49c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern int trans_context(const security_context_t, security_context_t *); 50c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern int untrans_context(const security_context_t, security_context_t *); 51c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 52c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern int init_colors(void); 53c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern void finish_context_colors(void); 54c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothextern int raw_color(const security_context_t, char **); 55c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 56c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define SETRANSD_PATHNAME "/sbin/mcstransd" 57c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 58c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth/* name of program (for error messages) */ 59c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#define SETRANSD_PROGNAME "mcstransd" 60c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 61c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int sockfd = -1; /* socket we are listening on */ 62c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 63c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic volatile int restart_daemon = 0; 64c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void cleanup_exit(int ret) __attribute__ ((noreturn)); 65c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 66c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothcleanup_exit(int ret) 67c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 68c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth finish_context_colors(); 69c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth finish_context_translations(); 70c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (sockfd >=0) 71c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (void)unlink(SETRANS_UNIX_SOCKET); 72c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 73c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("%s\n", "cleanup_exit"); 74c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 75c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth exit(ret); 76c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 77c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 78c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void clean_exit(void); 79c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic __attribute__((noreturn)) void clean_exit(void) 80c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 81c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("%s\n", "clean_exit"); 82c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(0); 83c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 84c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 85c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 86c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothsend_response(int fd, uint32_t function, char *data, int32_t ret_val) 87c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 88c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct iovec resp_hdr[3]; 89c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth uint32_t data_size; 90c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct iovec resp_data; 91c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ssize_t count; 92c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 93c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!data) 94c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data = ""; 95c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 96c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data_size = strlen(data) + 1; 97c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 98c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[0].iov_base = &function; 99c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[0].iov_len = sizeof(function); 100c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[1].iov_base = &data_size; 101c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[1].iov_len = sizeof(data_size); 102c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[2].iov_base = &ret_val; 103c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_hdr[2].iov_len = sizeof(ret_val); 104c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 105c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth while (((count = writev(fd, resp_hdr, 3)) < 0) && (errno == EINTR)); 106c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (count != (sizeof(function) + sizeof(data_size) + sizeof(ret_val))) { 107c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to write response header"); 108c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 109c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 110c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 111c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_data.iov_base = data; 112c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth resp_data.iov_len = data_size; 113c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 114c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth while (((count = writev(fd, &resp_data, 1)) < 0) && (errno == EINTR)); 115c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (count < 0 || (size_t)count != data_size) { 116c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to write response data"); 117c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 118c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 119c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 120c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return ret_val; 121c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 122c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 123c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 124c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothget_peer_pid(int fd, pid_t *pid) 125c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 126c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret; 127c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth socklen_t size = sizeof(struct ucred); 128c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct ucred peercred; 129c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 130c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* get the context of the requesting process */ 131c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &size); 132c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret < 0) { 133c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to get PID of client process"); 134c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 135c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 136c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth *pid = peercred.pid; 137c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return ret; 138c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 139c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 140c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 141c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 142c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothget_peer_con(int fd, char **peercon) 143c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 144c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret; 145c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth pid_t pid; 146c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = get_peer_pid(fd, &pid); 147c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret) 148c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 149c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = getpidcon_raw(pid, peercon); 150c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret) { 151c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, 152c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth "Failed to get context of client process (pid=%u)", 153c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth pid); 154c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 155c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 156c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 0; 157c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 158c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 159c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 160c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothprocess_request(int fd, uint32_t function, char *data1, char *UNUSED(data2)) 161c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 162c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int32_t result; 163c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth char *out = NULL; 164c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth char *peercon = NULL; 165c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret; 166c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 167c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = get_peer_con(fd, &peercon); 168c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret) 169c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return ret; 170c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 171c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* TODO: Check if MLS clearance (in peercon) dominates the MLS label 172c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth * (in the request input). 173c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth */ 174c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 175c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth switch (function) { 176c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth case SETRANS_INIT: 177c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth result = 0; 178c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = send_response(fd, function, NULL, result); 179c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 180c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth case RAW_TO_TRANS_CONTEXT: 181c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth result = trans_context(data1, &out); 182c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = send_response(fd, function, out, result); 183c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 184c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth case TRANS_TO_RAW_CONTEXT: 185c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth result = untrans_context(data1, &out); 186c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = send_response(fd, function, out, result); 187c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 188c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth case RAW_CONTEXT_TO_COLOR: 189c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth result = raw_color(data1, &out); 190c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = send_response(fd, function, out, result); 191c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 192c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth default: 193c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth result = -1; 194c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = -1; 195c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 196c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 197c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 198c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (result) { 199c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth pid_t pid = 0; 200c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth get_peer_pid(fd, &pid); 201c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Invalid request func=%d from=%u", 202c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth function, pid); 203c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 204c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 205c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(out); 206c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth freecon(peercon); 207c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 208c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return ret; 209c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 210c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 211c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 212c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothservice_request(int fd) 213c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 214c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct iovec req_hdr[3]; 215c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth uint32_t function; 216c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth uint32_t data1_size; 217c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth uint32_t data2_size; 218c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct iovec req_data[2]; 219c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth char *data1; 220c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth char *data2; 221c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret; 222c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ssize_t count; 223c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 224c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[0].iov_base = &function; 225c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[0].iov_len = sizeof(function); 226c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[1].iov_base = &data1_size; 227c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[1].iov_len = sizeof(data1_size); 228c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[2].iov_base = &data2_size; 229c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_hdr[2].iov_len = sizeof(data2_size); 230c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 231c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth while (((count = readv(fd, req_hdr, 3)) < 0) && (errno == EINTR)); 232c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (count <= 0) { 233c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 1; 234c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 235c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (count != (sizeof(function) + sizeof(data1_size) + 236c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sizeof(data2_size) )) { 237c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("Failed to read request header %d != %u\n",(int)count, 238c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (unsigned)(sizeof(function) + sizeof(data1_size) + 239c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sizeof(data2_size) )); 240c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 241c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 242c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 243c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!data1_size || !data2_size || data1_size > MAX_DATA_BUF || 244c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data2_size > MAX_DATA_BUF ) { 245c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("Header invalid data1_size=%u data2_size=%u\n", 246c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data1_size, data2_size); 247c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 248c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 249c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 250c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data1 = malloc(data1_size); 251c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!data1) { 252c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("Could not allocate %d bytes\n", data1_size); 253c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 254c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 255c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data2 = malloc(data2_size); 256c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!data2) { 257c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(data1); 258c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("Could not allocate %d bytes\n", data2_size); 259c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 260c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 261c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 262c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_data[0].iov_base = data1; 263c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_data[0].iov_len = data1_size; 264c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_data[1].iov_base = data2; 265c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth req_data[1].iov_len = data2_size; 266c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 267c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth while (((count = readv(fd, req_data, 2)) < 0) && (errno == EINTR)); 268c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (count <= 0 || (size_t)count != (data1_size + data2_size) || 269c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth data1[data1_size - 1] != '\0' || data2[data2_size - 1] != '\0') { 270c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(data1); 271c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(data2); 272c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("Failed to read request data (%d)\n", (int)count); 273c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 274c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 275c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 276c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = process_request(fd, function, data1, data2); 277c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 278c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(data1); 279c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth free(data2); 280c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 281c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return ret; 282c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 283c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 284c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 285c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothadd_pollfd(struct pollfd **ufds, int *nfds, int connfd) 286c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 287c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ii = 0; 288c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 289c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* First see if we can find an already invalidated ufd */ 290c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth for (ii = 0; ii < *nfds; ii++) { 291c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if ((*ufds)[ii].fd == -1) 292c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth break; 293c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 294c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 295c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ii == *nfds) { 296c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct pollfd *tmp = (struct pollfd *)realloc(*ufds, 297c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*nfds+1)*sizeof(struct pollfd)); 298c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!tmp) { 299c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "realloc failed for %d fds", *nfds+1); 300c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 301c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 302c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 303c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth *ufds = tmp; 304c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*nfds)++; 305c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 306c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 307c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].fd = connfd; 308c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].events = POLLIN|POLLPRI; 309c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].revents = 0; 310c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 311c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 0; 312c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 313c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 314c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 315c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothadj_pollfds(struct pollfd **ufds, int *nfds) 316c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 317c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ii, jj; 318c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 319c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth jj = 0; 320c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth for (ii = 0; ii < *nfds; ii++) { 321c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if ((*ufds)[ii].fd != -1) { 322c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (jj < ii) 323c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[jj] = (*ufds)[ii]; 324c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth jj++; 325c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 326c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 327c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth *nfds = jj; 328c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 329c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 330c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic int 331c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothprocess_events(struct pollfd **ufds, int *nfds) 332c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 333c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ii = 0; 334c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret = 0; 335c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 336c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth for (ii = 0; ii < *nfds; ii++) { 337c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth short revents = (*ufds)[ii].revents; 338c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int connfd = (*ufds)[ii].fd; 339c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 340c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (revents & (POLLIN | POLLPRI)) { 341c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (connfd == sockfd) { 342c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 343c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Probably received a connection */ 344c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if ((connfd = accept(sockfd, NULL, NULL)) < 0) { 345c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "accept() failed: %m"); 346c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 347c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 348c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 349c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (add_pollfd(ufds, nfds, connfd)) { 350c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, 351c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth "Failed to add fd (%d) to poll list\n", 352c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth connfd); 353c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return -1; 354c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 355c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } else { 356c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = service_request(connfd); 357c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret) { 358c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret < 0) { 359c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, 360c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth "Servicing of request " 361c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth "failed for fd (%d)\n", 362c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth connfd); 363c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 364c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Setup pollfd for deletion later. */ 365c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].fd = -1; 366c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth close(connfd); 367c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* So we don't get bothered later */ 368c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth revents = revents & ~(POLLHUP); 369c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 370c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 371c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth revents = revents & ~(POLLIN | POLLPRI); 372c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 373c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (revents & POLLHUP) { 374c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth log_debug("The connection with fd (%d) hung up\n", 375c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth connfd); 376c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 377c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Set the pollfd up for deletion later. */ 378c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].fd = -1; 379c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth close(connfd); 380c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 381c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth revents = revents & ~(POLLHUP); 382c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 383c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (revents) { 384c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Unknown/error events (%x) encountered" 385c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth " for fd (%d)\n", revents, connfd); 386c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 387c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Set the pollfd up for deletion later. */ 388c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].fd = -1; 389c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth close(connfd); 390c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 391c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 392c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (*ufds)[ii].revents = 0; 393c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 394c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 395c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Delete any invalidated ufds */ 396c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth adj_pollfds(ufds, nfds); 397c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 398c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 0; 399c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 400c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 401c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 402c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothprocess_connections(void) __attribute__ ((noreturn)); 403c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 404c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 405c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothprocess_connections(void) 406c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 407c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int ret = 0; 408c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth int nfds = 1; 409c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 410c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct pollfd *ufds = (struct pollfd *)malloc(sizeof(struct pollfd)); 411c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (!ufds) { 412c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to allocate a pollfd"); 413c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 414c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 415c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ufds[0].fd = sockfd; 416c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ufds[0].events = POLLIN|POLLPRI; 417c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ufds[0].revents = 0; 418c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 419c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth while (1) { 420c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (restart_daemon) { 421c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_NOTICE, "Reload Translations"); 422c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth finish_context_colors(); 423c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth finish_context_translations(); 424c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (init_translations()) { 425c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to initialize label translations"); 426c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 427c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 428c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (init_colors()) { 429c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to initialize color translations"); 430c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "No color information will be available"); 431c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 432c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth restart_daemon = 0; 433c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 434c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 435c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = poll(ufds, nfds, -1); 436c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret < 0) { 437c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (errno == EINTR) { 438c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth continue; 439c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 440c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "poll() failed: %m"); 441c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 442c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 443c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 444c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth ret = process_events(&ufds, &nfds); 445c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (ret) { 446c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Error processing events"); 447c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 448c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 449c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 450c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 451c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 452c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 453c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothsigterm_handler(int sig) __attribute__ ((noreturn)); 454c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 455c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 456c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothsigterm_handler(int UNUSED(sig)) 457c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 458c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(0); 459c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 460c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 461c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 462c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothsighup_handler(int UNUSED(sig)) 463c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 464c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth restart_daemon = 1; 465c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 466c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 467c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothstatic void 468c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothinitialize(void) 469c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 470c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct sigaction act; 471c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct sockaddr_un addr; 472c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth struct rlimit rl ; 473c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 474c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (init_translations()) { 475c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to initialize label translations"); 476c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 477c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 478c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (init_colors()) { 479c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Failed to initialize color translations"); 480c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "No color information will be available"); 481c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 482c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 483c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* the socket will be unlinked when the daemon terminates */ 484c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_handler = sigterm_handler; 485c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigemptyset(&act.sa_mask); 486c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGINT); 487c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGQUIT); 488c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGTERM); 489c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGHUP); 490c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_flags = 0; 491c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaction(SIGINT, &act, NULL); 492c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaction(SIGQUIT, &act, NULL); 493c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaction(SIGTERM, &act, NULL); 494c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 495c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* restart the daemon on SIGHUP */ 496c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_handler = sighup_handler; 497c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigemptyset(&act.sa_mask); 498c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGINT); 499c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGQUIT); 500c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaddset(&act.sa_mask, SIGTERM); 501c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_flags = 0; 502c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaction(SIGHUP, &act, NULL); 503c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 504c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* ignore SIGPIPE (in case a client terminates after sending request) */ 505c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_handler = SIG_IGN; 506c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigemptyset(&act.sa_mask); 507c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth act.sa_flags = 0; 508c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sigaction(SIGPIPE, &act, NULL); 509c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 510c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth atexit(clean_exit); 511c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 512c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth sockfd = socket(PF_UNIX, SOCK_STREAM, 0); 513c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (sockfd < 0) { 514c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "socket() failed: %m"); 515c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 516c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 517c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 518c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth memset(&addr, 0, sizeof(addr)); 519c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth addr.sun_family = AF_UNIX; 520c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth strncpy(addr.sun_path, SETRANS_UNIX_SOCKET, sizeof(addr.sun_path) - 1); 521c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 522c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth (void)unlink(SETRANS_UNIX_SOCKET); 523c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 524c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 525c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "bind() failed: %m"); 526c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 527c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 528c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 529c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (listen(sockfd, SOMAXCONN) < 0) { 530c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "listen() failed: %m"); 531c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 532c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 533c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 534c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (chmod(SETRANS_UNIX_SOCKET, S_IRWXU | S_IRWXG | S_IRWXO)) { 535c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "chmod() failed: %m"); 536c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cleanup_exit(1); 537c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 538c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 539c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Raise the rlimit for file descriptors... */ 540c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth rl.rlim_max = MAX_DESCRIPTORS; 541c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth rl.rlim_cur = MAX_DESCRIPTORS; 542c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth setrlimit(RLIMIT_NOFILE, &rl); 543c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 544c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 545c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 546c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothvoid dropprivs(void) 547c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 548c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cap_t new_caps; 549c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 550c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth new_caps = cap_init(); 551c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (cap_set_proc(new_caps)) { 552c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "Error dropping capabilities, aborting: %s\n", 553c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth strerror(errno)); 5547e0f0124743d241354afa888f3bfe23355679bc9Steve Lawrence cleanup_exit(-1); 555c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 556c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth cap_free(new_caps); 557c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 558c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 5598ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walshstatic void usage(char *program) 5608ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh{ 5618ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh printf("%s [-f] [-h] \n", program); 5628ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh} 5638ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh 564c89625db93f63f29a57451e692ae33ab24d49291Xavier Tothint 5658ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walshmain(int argc, char *argv[]) 566c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth{ 5678ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh int opt; 5688ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh int do_fork = 1; 5698ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh while ((opt = getopt(argc, argv, "hf")) > 0) { 5708ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh switch (opt) { 5718ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh case 'f': 5728ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh do_fork = 0; 5738ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh break; 5748ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh case 'h': 5758ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh usage(argv[0]); 5768ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh exit(0); 5778ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh break; 5788ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh case '?': 5798ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh usage(argv[0]); 5808ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh exit(-1); 5818ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh } 5828ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh } 5838ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh 584c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#ifndef DEBUG 585c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* Make sure we are root */ 586c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth if (getuid() != 0) { 587c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "You must be root to run this program.\n"); 588c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 4; 589c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 590c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#endif 591c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 592c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth openlog(SETRANSD_PROGNAME, 0, LOG_DAEMON); 593c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_NOTICE, "%s starting", argv[0]); 594c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 595c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth initialize(); 596c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 597c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#ifndef DEBUG 598c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth dropprivs(); 599c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 600c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* run in the background as a daemon */ 6018ca93d6b9d5b18bf37dccea4aa25ac81b93f0ba9Dan Walsh if (do_fork && daemon(0, 0)) { 602c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_ERR, "daemon() failed: %m"); 6037e0f0124743d241354afa888f3bfe23355679bc9Steve Lawrence cleanup_exit(1); 604c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth } 605c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth#endif 606c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 607c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth syslog(LOG_NOTICE, "%s initialized", argv[0]); 608c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth process_connections(); 609c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 610c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth /* we should never get here */ 611c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth return 1; 612c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth} 613c89625db93f63f29a57451e692ae33ab24d49291Xavier Toth 614