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