1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker * uuidd.c --- UUID-generation daemon
3*6a54128fSAndroid Build Coastguard Worker *
4*6a54128fSAndroid Build Coastguard Worker * Copyright (C) 2007 Theodore Ts'o
5*6a54128fSAndroid Build Coastguard Worker *
6*6a54128fSAndroid Build Coastguard Worker * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker * This file may be redistributed under the terms of the GNU Public
8*6a54128fSAndroid Build Coastguard Worker * License.
9*6a54128fSAndroid Build Coastguard Worker * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker */
11*6a54128fSAndroid Build Coastguard Worker
12*6a54128fSAndroid Build Coastguard Worker #define _GNU_SOURCE /* for setres[ug]id() */
13*6a54128fSAndroid Build Coastguard Worker
14*6a54128fSAndroid Build Coastguard Worker #include "config.h"
15*6a54128fSAndroid Build Coastguard Worker #include <stdio.h>
16*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_STDLIB_H
17*6a54128fSAndroid Build Coastguard Worker #include <stdlib.h>
18*6a54128fSAndroid Build Coastguard Worker #endif
19*6a54128fSAndroid Build Coastguard Worker #include <unistd.h>
20*6a54128fSAndroid Build Coastguard Worker #include <inttypes.h>
21*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
22*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
23*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
24*6a54128fSAndroid Build Coastguard Worker #include <sys/socket.h>
25*6a54128fSAndroid Build Coastguard Worker #include <sys/un.h>
26*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
27*6a54128fSAndroid Build Coastguard Worker #include <signal.h>
28*6a54128fSAndroid Build Coastguard Worker #include <string.h>
29*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_GETOPT_H
30*6a54128fSAndroid Build Coastguard Worker #include <getopt.h>
31*6a54128fSAndroid Build Coastguard Worker #else
32*6a54128fSAndroid Build Coastguard Worker extern int getopt(int argc, char * const argv[], const char *optstring);
33*6a54128fSAndroid Build Coastguard Worker extern char *optarg;
34*6a54128fSAndroid Build Coastguard Worker extern int optind;
35*6a54128fSAndroid Build Coastguard Worker #endif
36*6a54128fSAndroid Build Coastguard Worker #include "uuid/uuid.h"
37*6a54128fSAndroid Build Coastguard Worker #include "uuid/uuidd.h"
38*6a54128fSAndroid Build Coastguard Worker #include "support/nls-enable.h"
39*6a54128fSAndroid Build Coastguard Worker #include "ext2fs/ext2fs.h"
40*6a54128fSAndroid Build Coastguard Worker
41*6a54128fSAndroid Build Coastguard Worker #ifdef __GNUC__
42*6a54128fSAndroid Build Coastguard Worker #define CODE_ATTR(x) __attribute__(x)
43*6a54128fSAndroid Build Coastguard Worker #else
44*6a54128fSAndroid Build Coastguard Worker #define CODE_ATTR(x)
45*6a54128fSAndroid Build Coastguard Worker #endif
46*6a54128fSAndroid Build Coastguard Worker
usage(const char * progname)47*6a54128fSAndroid Build Coastguard Worker static void usage(const char *progname)
48*6a54128fSAndroid Build Coastguard Worker {
49*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _("Usage: %s [-d] [-p pidfile] [-s socketpath] "
50*6a54128fSAndroid Build Coastguard Worker "[-T timeout]\n"), progname);
51*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _(" %s [-r|t] [-n num] [-s socketpath]\n"),
52*6a54128fSAndroid Build Coastguard Worker progname);
53*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _(" %s -k\n"), progname);
54*6a54128fSAndroid Build Coastguard Worker exit(1);
55*6a54128fSAndroid Build Coastguard Worker }
56*6a54128fSAndroid Build Coastguard Worker
die(const char * msg)57*6a54128fSAndroid Build Coastguard Worker static void die(const char *msg)
58*6a54128fSAndroid Build Coastguard Worker {
59*6a54128fSAndroid Build Coastguard Worker perror(msg);
60*6a54128fSAndroid Build Coastguard Worker exit(1);
61*6a54128fSAndroid Build Coastguard Worker }
62*6a54128fSAndroid Build Coastguard Worker
create_daemon(void)63*6a54128fSAndroid Build Coastguard Worker static void create_daemon(void)
64*6a54128fSAndroid Build Coastguard Worker {
65*6a54128fSAndroid Build Coastguard Worker pid_t pid;
66*6a54128fSAndroid Build Coastguard Worker uid_t euid;
67*6a54128fSAndroid Build Coastguard Worker
68*6a54128fSAndroid Build Coastguard Worker pid = fork();
69*6a54128fSAndroid Build Coastguard Worker if (pid == -1) {
70*6a54128fSAndroid Build Coastguard Worker perror("fork");
71*6a54128fSAndroid Build Coastguard Worker exit(1);
72*6a54128fSAndroid Build Coastguard Worker } else if (pid != 0) {
73*6a54128fSAndroid Build Coastguard Worker exit(0);
74*6a54128fSAndroid Build Coastguard Worker }
75*6a54128fSAndroid Build Coastguard Worker
76*6a54128fSAndroid Build Coastguard Worker close(0);
77*6a54128fSAndroid Build Coastguard Worker close(1);
78*6a54128fSAndroid Build Coastguard Worker close(2);
79*6a54128fSAndroid Build Coastguard Worker open("/dev/null", O_RDWR);
80*6a54128fSAndroid Build Coastguard Worker open("/dev/null", O_RDWR);
81*6a54128fSAndroid Build Coastguard Worker open("/dev/null", O_RDWR);
82*6a54128fSAndroid Build Coastguard Worker
83*6a54128fSAndroid Build Coastguard Worker if (chdir("/")) {} /* Silence warn_unused_result warning */
84*6a54128fSAndroid Build Coastguard Worker (void) setsid();
85*6a54128fSAndroid Build Coastguard Worker euid = geteuid();
86*6a54128fSAndroid Build Coastguard Worker if (setreuid(euid, euid) < 0)
87*6a54128fSAndroid Build Coastguard Worker die("setreuid");
88*6a54128fSAndroid Build Coastguard Worker }
89*6a54128fSAndroid Build Coastguard Worker
read_all(int fd,char * buf,size_t count)90*6a54128fSAndroid Build Coastguard Worker static ssize_t read_all(int fd, char *buf, size_t count)
91*6a54128fSAndroid Build Coastguard Worker {
92*6a54128fSAndroid Build Coastguard Worker ssize_t ret;
93*6a54128fSAndroid Build Coastguard Worker ssize_t c = 0;
94*6a54128fSAndroid Build Coastguard Worker int tries = 0;
95*6a54128fSAndroid Build Coastguard Worker
96*6a54128fSAndroid Build Coastguard Worker memset(buf, 0, count);
97*6a54128fSAndroid Build Coastguard Worker while (count > 0) {
98*6a54128fSAndroid Build Coastguard Worker ret = read(fd, buf, count);
99*6a54128fSAndroid Build Coastguard Worker if (ret <= 0) {
100*6a54128fSAndroid Build Coastguard Worker if ((errno == EAGAIN || errno == EINTR || ret == 0) &&
101*6a54128fSAndroid Build Coastguard Worker (tries++ < 5))
102*6a54128fSAndroid Build Coastguard Worker continue;
103*6a54128fSAndroid Build Coastguard Worker return c ? c : -1;
104*6a54128fSAndroid Build Coastguard Worker }
105*6a54128fSAndroid Build Coastguard Worker if (ret > 0)
106*6a54128fSAndroid Build Coastguard Worker tries = 0;
107*6a54128fSAndroid Build Coastguard Worker count -= ret;
108*6a54128fSAndroid Build Coastguard Worker buf += ret;
109*6a54128fSAndroid Build Coastguard Worker c += ret;
110*6a54128fSAndroid Build Coastguard Worker }
111*6a54128fSAndroid Build Coastguard Worker return c;
112*6a54128fSAndroid Build Coastguard Worker }
113*6a54128fSAndroid Build Coastguard Worker
write_all(int fd,char * buf,size_t count)114*6a54128fSAndroid Build Coastguard Worker static int write_all(int fd, char *buf, size_t count)
115*6a54128fSAndroid Build Coastguard Worker {
116*6a54128fSAndroid Build Coastguard Worker ssize_t ret;
117*6a54128fSAndroid Build Coastguard Worker int c = 0;
118*6a54128fSAndroid Build Coastguard Worker
119*6a54128fSAndroid Build Coastguard Worker while (count > 0) {
120*6a54128fSAndroid Build Coastguard Worker ret = write(fd, buf, count);
121*6a54128fSAndroid Build Coastguard Worker if (ret < 0) {
122*6a54128fSAndroid Build Coastguard Worker if ((errno == EAGAIN) || (errno == EINTR))
123*6a54128fSAndroid Build Coastguard Worker continue;
124*6a54128fSAndroid Build Coastguard Worker return -1;
125*6a54128fSAndroid Build Coastguard Worker }
126*6a54128fSAndroid Build Coastguard Worker count -= ret;
127*6a54128fSAndroid Build Coastguard Worker buf += ret;
128*6a54128fSAndroid Build Coastguard Worker c += ret;
129*6a54128fSAndroid Build Coastguard Worker }
130*6a54128fSAndroid Build Coastguard Worker return c;
131*6a54128fSAndroid Build Coastguard Worker }
132*6a54128fSAndroid Build Coastguard Worker
133*6a54128fSAndroid Build Coastguard Worker static const char *cleanup_pidfile, *cleanup_socket;
134*6a54128fSAndroid Build Coastguard Worker
terminate_intr(int signo CODE_ATTR ((unused)))135*6a54128fSAndroid Build Coastguard Worker static void terminate_intr(int signo CODE_ATTR((unused)))
136*6a54128fSAndroid Build Coastguard Worker {
137*6a54128fSAndroid Build Coastguard Worker (void) unlink(cleanup_pidfile);
138*6a54128fSAndroid Build Coastguard Worker if (cleanup_socket)
139*6a54128fSAndroid Build Coastguard Worker (void) unlink(cleanup_socket);
140*6a54128fSAndroid Build Coastguard Worker exit(0);
141*6a54128fSAndroid Build Coastguard Worker }
142*6a54128fSAndroid Build Coastguard Worker
call_daemon(const char * socket_path,int op,char * buf,int buflen,int * num,const char ** err_context)143*6a54128fSAndroid Build Coastguard Worker static int call_daemon(const char *socket_path, int op, char *buf,
144*6a54128fSAndroid Build Coastguard Worker int buflen, int *num, const char **err_context)
145*6a54128fSAndroid Build Coastguard Worker {
146*6a54128fSAndroid Build Coastguard Worker char op_buf[8];
147*6a54128fSAndroid Build Coastguard Worker int op_len;
148*6a54128fSAndroid Build Coastguard Worker int s;
149*6a54128fSAndroid Build Coastguard Worker ssize_t ret;
150*6a54128fSAndroid Build Coastguard Worker int32_t reply_len = 0;
151*6a54128fSAndroid Build Coastguard Worker struct sockaddr_un srv_addr;
152*6a54128fSAndroid Build Coastguard Worker
153*6a54128fSAndroid Build Coastguard Worker if (((op == 4) || (op == 5)) && !num) {
154*6a54128fSAndroid Build Coastguard Worker if (err_context)
155*6a54128fSAndroid Build Coastguard Worker *err_context = _("bad arguments");
156*6a54128fSAndroid Build Coastguard Worker errno = EINVAL;
157*6a54128fSAndroid Build Coastguard Worker return -1;
158*6a54128fSAndroid Build Coastguard Worker }
159*6a54128fSAndroid Build Coastguard Worker
160*6a54128fSAndroid Build Coastguard Worker if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
161*6a54128fSAndroid Build Coastguard Worker if (err_context)
162*6a54128fSAndroid Build Coastguard Worker *err_context = _("socket");
163*6a54128fSAndroid Build Coastguard Worker return -1;
164*6a54128fSAndroid Build Coastguard Worker }
165*6a54128fSAndroid Build Coastguard Worker
166*6a54128fSAndroid Build Coastguard Worker srv_addr.sun_family = AF_UNIX;
167*6a54128fSAndroid Build Coastguard Worker strncpy(srv_addr.sun_path, socket_path, sizeof(srv_addr.sun_path));
168*6a54128fSAndroid Build Coastguard Worker srv_addr.sun_path[sizeof(srv_addr.sun_path)-1] = '\0';
169*6a54128fSAndroid Build Coastguard Worker
170*6a54128fSAndroid Build Coastguard Worker if (connect(s, (const struct sockaddr *) &srv_addr,
171*6a54128fSAndroid Build Coastguard Worker sizeof(struct sockaddr_un)) < 0) {
172*6a54128fSAndroid Build Coastguard Worker if (err_context)
173*6a54128fSAndroid Build Coastguard Worker *err_context = _("connect");
174*6a54128fSAndroid Build Coastguard Worker close(s);
175*6a54128fSAndroid Build Coastguard Worker return -1;
176*6a54128fSAndroid Build Coastguard Worker }
177*6a54128fSAndroid Build Coastguard Worker
178*6a54128fSAndroid Build Coastguard Worker if (op == 5) {
179*6a54128fSAndroid Build Coastguard Worker if ((*num)*16 > buflen-4)
180*6a54128fSAndroid Build Coastguard Worker *num = (buflen-4) / 16;
181*6a54128fSAndroid Build Coastguard Worker }
182*6a54128fSAndroid Build Coastguard Worker op_buf[0] = op;
183*6a54128fSAndroid Build Coastguard Worker op_len = 1;
184*6a54128fSAndroid Build Coastguard Worker if ((op == 4) || (op == 5)) {
185*6a54128fSAndroid Build Coastguard Worker memcpy(op_buf+1, num, sizeof(int));
186*6a54128fSAndroid Build Coastguard Worker op_len += sizeof(int);
187*6a54128fSAndroid Build Coastguard Worker }
188*6a54128fSAndroid Build Coastguard Worker
189*6a54128fSAndroid Build Coastguard Worker ret = write_all(s, op_buf, op_len);
190*6a54128fSAndroid Build Coastguard Worker if (ret < op_len) {
191*6a54128fSAndroid Build Coastguard Worker if (err_context)
192*6a54128fSAndroid Build Coastguard Worker *err_context = _("write");
193*6a54128fSAndroid Build Coastguard Worker close(s);
194*6a54128fSAndroid Build Coastguard Worker return -1;
195*6a54128fSAndroid Build Coastguard Worker }
196*6a54128fSAndroid Build Coastguard Worker
197*6a54128fSAndroid Build Coastguard Worker ret = read_all(s, (char *) &reply_len, sizeof(reply_len));
198*6a54128fSAndroid Build Coastguard Worker if (ret < 0) {
199*6a54128fSAndroid Build Coastguard Worker if (err_context)
200*6a54128fSAndroid Build Coastguard Worker *err_context = _("read count");
201*6a54128fSAndroid Build Coastguard Worker close(s);
202*6a54128fSAndroid Build Coastguard Worker return -1;
203*6a54128fSAndroid Build Coastguard Worker }
204*6a54128fSAndroid Build Coastguard Worker if (reply_len < 0 || reply_len > buflen) {
205*6a54128fSAndroid Build Coastguard Worker if (err_context)
206*6a54128fSAndroid Build Coastguard Worker *err_context = _("bad response length");
207*6a54128fSAndroid Build Coastguard Worker close(s);
208*6a54128fSAndroid Build Coastguard Worker return -1;
209*6a54128fSAndroid Build Coastguard Worker }
210*6a54128fSAndroid Build Coastguard Worker ret = read_all(s, (char *) buf, reply_len);
211*6a54128fSAndroid Build Coastguard Worker
212*6a54128fSAndroid Build Coastguard Worker if ((ret > 0) && (op == 4)) {
213*6a54128fSAndroid Build Coastguard Worker if (reply_len >= (int) (16+sizeof(int)))
214*6a54128fSAndroid Build Coastguard Worker memcpy(buf+16, num, sizeof(int));
215*6a54128fSAndroid Build Coastguard Worker else
216*6a54128fSAndroid Build Coastguard Worker *num = -1;
217*6a54128fSAndroid Build Coastguard Worker }
218*6a54128fSAndroid Build Coastguard Worker if ((ret > 0) && (op == 5)) {
219*6a54128fSAndroid Build Coastguard Worker if (*num >= (int) sizeof(int))
220*6a54128fSAndroid Build Coastguard Worker memcpy(buf, num, sizeof(int));
221*6a54128fSAndroid Build Coastguard Worker else
222*6a54128fSAndroid Build Coastguard Worker *num = -1;
223*6a54128fSAndroid Build Coastguard Worker }
224*6a54128fSAndroid Build Coastguard Worker
225*6a54128fSAndroid Build Coastguard Worker close(s);
226*6a54128fSAndroid Build Coastguard Worker
227*6a54128fSAndroid Build Coastguard Worker return ret;
228*6a54128fSAndroid Build Coastguard Worker }
229*6a54128fSAndroid Build Coastguard Worker
server_loop(const char * socket_path,const char * pidfile_path,int debug,int timeout,int quiet)230*6a54128fSAndroid Build Coastguard Worker static void server_loop(const char *socket_path, const char *pidfile_path,
231*6a54128fSAndroid Build Coastguard Worker int debug, int timeout, int quiet)
232*6a54128fSAndroid Build Coastguard Worker {
233*6a54128fSAndroid Build Coastguard Worker struct sockaddr_un my_addr, from_addr;
234*6a54128fSAndroid Build Coastguard Worker struct flock fl;
235*6a54128fSAndroid Build Coastguard Worker socklen_t fromlen;
236*6a54128fSAndroid Build Coastguard Worker int32_t reply_len = 0;
237*6a54128fSAndroid Build Coastguard Worker uuid_t uu;
238*6a54128fSAndroid Build Coastguard Worker mode_t save_umask;
239*6a54128fSAndroid Build Coastguard Worker char reply_buf[1024], *cp;
240*6a54128fSAndroid Build Coastguard Worker char op, str[UUID_STR_SIZE];
241*6a54128fSAndroid Build Coastguard Worker int i, s, ns, len, num;
242*6a54128fSAndroid Build Coastguard Worker int fd_pidfile, ret;
243*6a54128fSAndroid Build Coastguard Worker
244*6a54128fSAndroid Build Coastguard Worker fd_pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0664);
245*6a54128fSAndroid Build Coastguard Worker if (fd_pidfile < 0) {
246*6a54128fSAndroid Build Coastguard Worker if (!quiet)
247*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, "Failed to open/create %s: %s\n",
248*6a54128fSAndroid Build Coastguard Worker pidfile_path, strerror(errno));
249*6a54128fSAndroid Build Coastguard Worker exit(1);
250*6a54128fSAndroid Build Coastguard Worker }
251*6a54128fSAndroid Build Coastguard Worker cleanup_pidfile = pidfile_path;
252*6a54128fSAndroid Build Coastguard Worker cleanup_socket = 0;
253*6a54128fSAndroid Build Coastguard Worker signal(SIGALRM, terminate_intr);
254*6a54128fSAndroid Build Coastguard Worker alarm(30);
255*6a54128fSAndroid Build Coastguard Worker fl.l_type = F_WRLCK;
256*6a54128fSAndroid Build Coastguard Worker fl.l_whence = SEEK_SET;
257*6a54128fSAndroid Build Coastguard Worker fl.l_start = 0;
258*6a54128fSAndroid Build Coastguard Worker fl.l_len = 0;
259*6a54128fSAndroid Build Coastguard Worker fl.l_pid = 0;
260*6a54128fSAndroid Build Coastguard Worker while (fcntl(fd_pidfile, F_SETLKW, &fl) < 0) {
261*6a54128fSAndroid Build Coastguard Worker if ((errno == EAGAIN) || (errno == EINTR))
262*6a54128fSAndroid Build Coastguard Worker continue;
263*6a54128fSAndroid Build Coastguard Worker if (!quiet)
264*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, "Failed to lock %s: %s\n",
265*6a54128fSAndroid Build Coastguard Worker pidfile_path, strerror(errno));
266*6a54128fSAndroid Build Coastguard Worker exit(1);
267*6a54128fSAndroid Build Coastguard Worker }
268*6a54128fSAndroid Build Coastguard Worker ret = call_daemon(socket_path, 0, reply_buf, sizeof(reply_buf), 0, 0);
269*6a54128fSAndroid Build Coastguard Worker if (ret > 0) {
270*6a54128fSAndroid Build Coastguard Worker if (!quiet)
271*6a54128fSAndroid Build Coastguard Worker printf(_("uuidd daemon already running at pid %s\n"),
272*6a54128fSAndroid Build Coastguard Worker reply_buf);
273*6a54128fSAndroid Build Coastguard Worker exit(1);
274*6a54128fSAndroid Build Coastguard Worker }
275*6a54128fSAndroid Build Coastguard Worker alarm(0);
276*6a54128fSAndroid Build Coastguard Worker
277*6a54128fSAndroid Build Coastguard Worker if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
278*6a54128fSAndroid Build Coastguard Worker if (!quiet)
279*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _("Couldn't create unix stream "
280*6a54128fSAndroid Build Coastguard Worker "socket: %s"), strerror(errno));
281*6a54128fSAndroid Build Coastguard Worker exit(1);
282*6a54128fSAndroid Build Coastguard Worker }
283*6a54128fSAndroid Build Coastguard Worker
284*6a54128fSAndroid Build Coastguard Worker /*
285*6a54128fSAndroid Build Coastguard Worker * Make sure the socket isn't using fd numbers 0-2 to avoid it
286*6a54128fSAndroid Build Coastguard Worker * getting closed by create_daemon()
287*6a54128fSAndroid Build Coastguard Worker */
288*6a54128fSAndroid Build Coastguard Worker while (!debug && s <= 2) {
289*6a54128fSAndroid Build Coastguard Worker s = dup(s);
290*6a54128fSAndroid Build Coastguard Worker if (s < 0) {
291*6a54128fSAndroid Build Coastguard Worker perror("dup");
292*6a54128fSAndroid Build Coastguard Worker exit(1);
293*6a54128fSAndroid Build Coastguard Worker }
294*6a54128fSAndroid Build Coastguard Worker }
295*6a54128fSAndroid Build Coastguard Worker
296*6a54128fSAndroid Build Coastguard Worker /*
297*6a54128fSAndroid Build Coastguard Worker * Create the address we will be binding to.
298*6a54128fSAndroid Build Coastguard Worker */
299*6a54128fSAndroid Build Coastguard Worker my_addr.sun_family = AF_UNIX;
300*6a54128fSAndroid Build Coastguard Worker strncpy(my_addr.sun_path, socket_path, sizeof(my_addr.sun_path));
301*6a54128fSAndroid Build Coastguard Worker my_addr.sun_path[sizeof(my_addr.sun_path)-1] = '\0';
302*6a54128fSAndroid Build Coastguard Worker (void) unlink(socket_path);
303*6a54128fSAndroid Build Coastguard Worker save_umask = umask(0);
304*6a54128fSAndroid Build Coastguard Worker if (bind(s, (const struct sockaddr *) &my_addr,
305*6a54128fSAndroid Build Coastguard Worker sizeof(struct sockaddr_un)) < 0) {
306*6a54128fSAndroid Build Coastguard Worker if (!quiet)
307*6a54128fSAndroid Build Coastguard Worker fprintf(stderr,
308*6a54128fSAndroid Build Coastguard Worker _("Couldn't bind unix socket %s: %s\n"),
309*6a54128fSAndroid Build Coastguard Worker socket_path, strerror(errno));
310*6a54128fSAndroid Build Coastguard Worker exit(1);
311*6a54128fSAndroid Build Coastguard Worker }
312*6a54128fSAndroid Build Coastguard Worker (void) umask(save_umask);
313*6a54128fSAndroid Build Coastguard Worker
314*6a54128fSAndroid Build Coastguard Worker if (listen(s, 5) < 0) {
315*6a54128fSAndroid Build Coastguard Worker if (!quiet)
316*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _("Couldn't listen on unix "
317*6a54128fSAndroid Build Coastguard Worker "socket %s: %s\n"), socket_path,
318*6a54128fSAndroid Build Coastguard Worker strerror(errno));
319*6a54128fSAndroid Build Coastguard Worker exit(1);
320*6a54128fSAndroid Build Coastguard Worker }
321*6a54128fSAndroid Build Coastguard Worker
322*6a54128fSAndroid Build Coastguard Worker cleanup_socket = socket_path;
323*6a54128fSAndroid Build Coastguard Worker if (!debug)
324*6a54128fSAndroid Build Coastguard Worker create_daemon();
325*6a54128fSAndroid Build Coastguard Worker signal(SIGHUP, terminate_intr);
326*6a54128fSAndroid Build Coastguard Worker signal(SIGINT, terminate_intr);
327*6a54128fSAndroid Build Coastguard Worker signal(SIGTERM, terminate_intr);
328*6a54128fSAndroid Build Coastguard Worker signal(SIGALRM, terminate_intr);
329*6a54128fSAndroid Build Coastguard Worker signal(SIGPIPE, SIG_IGN);
330*6a54128fSAndroid Build Coastguard Worker
331*6a54128fSAndroid Build Coastguard Worker sprintf(reply_buf, "%8d\n", getpid());
332*6a54128fSAndroid Build Coastguard Worker if (ftruncate(fd_pidfile, 0)) {} /* Silence warn_unused_result */
333*6a54128fSAndroid Build Coastguard Worker write_all(fd_pidfile, reply_buf, strlen(reply_buf));
334*6a54128fSAndroid Build Coastguard Worker if (fd_pidfile > 1)
335*6a54128fSAndroid Build Coastguard Worker close(fd_pidfile); /* Unlock the pid file */
336*6a54128fSAndroid Build Coastguard Worker
337*6a54128fSAndroid Build Coastguard Worker while (1) {
338*6a54128fSAndroid Build Coastguard Worker fromlen = sizeof(from_addr);
339*6a54128fSAndroid Build Coastguard Worker if (timeout > 0)
340*6a54128fSAndroid Build Coastguard Worker alarm(timeout);
341*6a54128fSAndroid Build Coastguard Worker ns = accept(s, (struct sockaddr *) &from_addr, &fromlen);
342*6a54128fSAndroid Build Coastguard Worker alarm(0);
343*6a54128fSAndroid Build Coastguard Worker if (ns < 0) {
344*6a54128fSAndroid Build Coastguard Worker if ((errno == EAGAIN) || (errno == EINTR))
345*6a54128fSAndroid Build Coastguard Worker continue;
346*6a54128fSAndroid Build Coastguard Worker perror("accept");
347*6a54128fSAndroid Build Coastguard Worker exit(1);
348*6a54128fSAndroid Build Coastguard Worker }
349*6a54128fSAndroid Build Coastguard Worker len = read(ns, &op, 1);
350*6a54128fSAndroid Build Coastguard Worker if (len != 1) {
351*6a54128fSAndroid Build Coastguard Worker if (len < 0)
352*6a54128fSAndroid Build Coastguard Worker perror("read");
353*6a54128fSAndroid Build Coastguard Worker else
354*6a54128fSAndroid Build Coastguard Worker printf(_("Error reading from client, "
355*6a54128fSAndroid Build Coastguard Worker "len = %d\n"), len);
356*6a54128fSAndroid Build Coastguard Worker goto shutdown_socket;
357*6a54128fSAndroid Build Coastguard Worker }
358*6a54128fSAndroid Build Coastguard Worker if ((op == 4) || (op == 5)) {
359*6a54128fSAndroid Build Coastguard Worker if (read_all(ns, (char *) &num, sizeof(num)) != 4)
360*6a54128fSAndroid Build Coastguard Worker goto shutdown_socket;
361*6a54128fSAndroid Build Coastguard Worker if (debug)
362*6a54128fSAndroid Build Coastguard Worker printf(_("operation %d, incoming num = %d\n"),
363*6a54128fSAndroid Build Coastguard Worker op, num);
364*6a54128fSAndroid Build Coastguard Worker } else if (debug)
365*6a54128fSAndroid Build Coastguard Worker printf("operation %d\n", op);
366*6a54128fSAndroid Build Coastguard Worker
367*6a54128fSAndroid Build Coastguard Worker switch(op) {
368*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_GETPID:
369*6a54128fSAndroid Build Coastguard Worker sprintf(reply_buf, "%d", getpid());
370*6a54128fSAndroid Build Coastguard Worker reply_len = strlen(reply_buf)+1;
371*6a54128fSAndroid Build Coastguard Worker break;
372*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_GET_MAXOP:
373*6a54128fSAndroid Build Coastguard Worker sprintf(reply_buf, "%d", UUIDD_MAX_OP);
374*6a54128fSAndroid Build Coastguard Worker reply_len = strlen(reply_buf)+1;
375*6a54128fSAndroid Build Coastguard Worker break;
376*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_TIME_UUID:
377*6a54128fSAndroid Build Coastguard Worker num = 1;
378*6a54128fSAndroid Build Coastguard Worker uuid__generate_time(uu, &num);
379*6a54128fSAndroid Build Coastguard Worker if (debug) {
380*6a54128fSAndroid Build Coastguard Worker uuid_unparse(uu, str);
381*6a54128fSAndroid Build Coastguard Worker printf(_("Generated time UUID: %s\n"), str);
382*6a54128fSAndroid Build Coastguard Worker }
383*6a54128fSAndroid Build Coastguard Worker memcpy(reply_buf, uu, sizeof(uu));
384*6a54128fSAndroid Build Coastguard Worker reply_len = sizeof(uu);
385*6a54128fSAndroid Build Coastguard Worker break;
386*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_RANDOM_UUID:
387*6a54128fSAndroid Build Coastguard Worker num = 1;
388*6a54128fSAndroid Build Coastguard Worker uuid__generate_random(uu, &num);
389*6a54128fSAndroid Build Coastguard Worker if (debug) {
390*6a54128fSAndroid Build Coastguard Worker uuid_unparse(uu, str);
391*6a54128fSAndroid Build Coastguard Worker printf(_("Generated random UUID: %s\n"), str);
392*6a54128fSAndroid Build Coastguard Worker }
393*6a54128fSAndroid Build Coastguard Worker memcpy(reply_buf, uu, sizeof(uu));
394*6a54128fSAndroid Build Coastguard Worker reply_len = sizeof(uu);
395*6a54128fSAndroid Build Coastguard Worker break;
396*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_BULK_TIME_UUID:
397*6a54128fSAndroid Build Coastguard Worker uuid__generate_time(uu, &num);
398*6a54128fSAndroid Build Coastguard Worker if (debug) {
399*6a54128fSAndroid Build Coastguard Worker uuid_unparse(uu, str);
400*6a54128fSAndroid Build Coastguard Worker printf(P_("Generated time UUID %s and "
401*6a54128fSAndroid Build Coastguard Worker "subsequent UUID\n",
402*6a54128fSAndroid Build Coastguard Worker "Generated time UUID %s and %d "
403*6a54128fSAndroid Build Coastguard Worker "subsequent UUIDs\n", num),
404*6a54128fSAndroid Build Coastguard Worker str, num);
405*6a54128fSAndroid Build Coastguard Worker }
406*6a54128fSAndroid Build Coastguard Worker memcpy(reply_buf, uu, sizeof(uu));
407*6a54128fSAndroid Build Coastguard Worker reply_len = sizeof(uu);
408*6a54128fSAndroid Build Coastguard Worker memcpy(reply_buf+reply_len, &num, sizeof(num));
409*6a54128fSAndroid Build Coastguard Worker reply_len += sizeof(num);
410*6a54128fSAndroid Build Coastguard Worker break;
411*6a54128fSAndroid Build Coastguard Worker case UUIDD_OP_BULK_RANDOM_UUID:
412*6a54128fSAndroid Build Coastguard Worker if (num < 0)
413*6a54128fSAndroid Build Coastguard Worker num = 1;
414*6a54128fSAndroid Build Coastguard Worker if (num > 1000)
415*6a54128fSAndroid Build Coastguard Worker num = 1000;
416*6a54128fSAndroid Build Coastguard Worker if (num*16 > (int) (sizeof(reply_buf)-sizeof(num)))
417*6a54128fSAndroid Build Coastguard Worker num = (sizeof(reply_buf)-sizeof(num)) / 16;
418*6a54128fSAndroid Build Coastguard Worker uuid__generate_random((unsigned char *) reply_buf +
419*6a54128fSAndroid Build Coastguard Worker sizeof(num), &num);
420*6a54128fSAndroid Build Coastguard Worker if (debug) {
421*6a54128fSAndroid Build Coastguard Worker printf(_("Generated %d UUID's:\n"), num);
422*6a54128fSAndroid Build Coastguard Worker for (i=0, cp=reply_buf+sizeof(num);
423*6a54128fSAndroid Build Coastguard Worker i < num; i++, cp+=16) {
424*6a54128fSAndroid Build Coastguard Worker uuid_unparse((unsigned char *)cp, str);
425*6a54128fSAndroid Build Coastguard Worker printf("\t%s\n", str);
426*6a54128fSAndroid Build Coastguard Worker }
427*6a54128fSAndroid Build Coastguard Worker }
428*6a54128fSAndroid Build Coastguard Worker reply_len = (num*16) + sizeof(num);
429*6a54128fSAndroid Build Coastguard Worker memcpy(reply_buf, &num, sizeof(num));
430*6a54128fSAndroid Build Coastguard Worker break;
431*6a54128fSAndroid Build Coastguard Worker default:
432*6a54128fSAndroid Build Coastguard Worker if (debug)
433*6a54128fSAndroid Build Coastguard Worker printf(_("Invalid operation %d\n"), op);
434*6a54128fSAndroid Build Coastguard Worker goto shutdown_socket;
435*6a54128fSAndroid Build Coastguard Worker }
436*6a54128fSAndroid Build Coastguard Worker write_all(ns, (char *) &reply_len, sizeof(reply_len));
437*6a54128fSAndroid Build Coastguard Worker write_all(ns, reply_buf, reply_len);
438*6a54128fSAndroid Build Coastguard Worker shutdown_socket:
439*6a54128fSAndroid Build Coastguard Worker close(ns);
440*6a54128fSAndroid Build Coastguard Worker }
441*6a54128fSAndroid Build Coastguard Worker }
442*6a54128fSAndroid Build Coastguard Worker
main(int argc,char ** argv)443*6a54128fSAndroid Build Coastguard Worker int main(int argc, char **argv)
444*6a54128fSAndroid Build Coastguard Worker {
445*6a54128fSAndroid Build Coastguard Worker const char *socket_path = UUIDD_SOCKET_PATH;
446*6a54128fSAndroid Build Coastguard Worker const char *pidfile_path = UUIDD_PIDFILE_PATH;
447*6a54128fSAndroid Build Coastguard Worker const char *err_context;
448*6a54128fSAndroid Build Coastguard Worker char buf[1024], *cp;
449*6a54128fSAndroid Build Coastguard Worker char str[37], *tmp;
450*6a54128fSAndroid Build Coastguard Worker uuid_t uu;
451*6a54128fSAndroid Build Coastguard Worker uid_t uid;
452*6a54128fSAndroid Build Coastguard Worker gid_t gid;
453*6a54128fSAndroid Build Coastguard Worker int i, c, ret;
454*6a54128fSAndroid Build Coastguard Worker int debug = 0, do_type = 0, do_kill = 0, num = 0;
455*6a54128fSAndroid Build Coastguard Worker int timeout = 0, quiet = 0, drop_privs = 0;
456*6a54128fSAndroid Build Coastguard Worker
457*6a54128fSAndroid Build Coastguard Worker #ifdef ENABLE_NLS
458*6a54128fSAndroid Build Coastguard Worker setlocale(LC_MESSAGES, "");
459*6a54128fSAndroid Build Coastguard Worker setlocale(LC_CTYPE, "");
460*6a54128fSAndroid Build Coastguard Worker bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
461*6a54128fSAndroid Build Coastguard Worker textdomain(NLS_CAT_NAME);
462*6a54128fSAndroid Build Coastguard Worker #endif
463*6a54128fSAndroid Build Coastguard Worker
464*6a54128fSAndroid Build Coastguard Worker while ((c = getopt (argc, argv, "dkn:qp:s:tT:r")) != EOF) {
465*6a54128fSAndroid Build Coastguard Worker switch (c) {
466*6a54128fSAndroid Build Coastguard Worker case 'd':
467*6a54128fSAndroid Build Coastguard Worker debug++;
468*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
469*6a54128fSAndroid Build Coastguard Worker break;
470*6a54128fSAndroid Build Coastguard Worker case 'k':
471*6a54128fSAndroid Build Coastguard Worker do_kill++;
472*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
473*6a54128fSAndroid Build Coastguard Worker break;
474*6a54128fSAndroid Build Coastguard Worker case 'n':
475*6a54128fSAndroid Build Coastguard Worker num = strtol(optarg, &tmp, 0);
476*6a54128fSAndroid Build Coastguard Worker if ((num < 0) || *tmp) {
477*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _("Bad number: %s\n"), optarg);
478*6a54128fSAndroid Build Coastguard Worker exit(1);
479*6a54128fSAndroid Build Coastguard Worker }
480*6a54128fSAndroid Build Coastguard Worker break;
481*6a54128fSAndroid Build Coastguard Worker case 'p':
482*6a54128fSAndroid Build Coastguard Worker pidfile_path = optarg;
483*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
484*6a54128fSAndroid Build Coastguard Worker break;
485*6a54128fSAndroid Build Coastguard Worker case 'q':
486*6a54128fSAndroid Build Coastguard Worker quiet++;
487*6a54128fSAndroid Build Coastguard Worker break;
488*6a54128fSAndroid Build Coastguard Worker case 's':
489*6a54128fSAndroid Build Coastguard Worker socket_path = optarg;
490*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
491*6a54128fSAndroid Build Coastguard Worker break;
492*6a54128fSAndroid Build Coastguard Worker case 't':
493*6a54128fSAndroid Build Coastguard Worker do_type = UUIDD_OP_TIME_UUID;
494*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
495*6a54128fSAndroid Build Coastguard Worker break;
496*6a54128fSAndroid Build Coastguard Worker case 'T':
497*6a54128fSAndroid Build Coastguard Worker timeout = strtol(optarg, &tmp, 0);
498*6a54128fSAndroid Build Coastguard Worker if ((timeout < 0) || *tmp) {
499*6a54128fSAndroid Build Coastguard Worker fprintf(stderr, _("Bad number: %s\n"), optarg);
500*6a54128fSAndroid Build Coastguard Worker exit(1);
501*6a54128fSAndroid Build Coastguard Worker }
502*6a54128fSAndroid Build Coastguard Worker break;
503*6a54128fSAndroid Build Coastguard Worker case 'r':
504*6a54128fSAndroid Build Coastguard Worker do_type = UUIDD_OP_RANDOM_UUID;
505*6a54128fSAndroid Build Coastguard Worker drop_privs = 1;
506*6a54128fSAndroid Build Coastguard Worker break;
507*6a54128fSAndroid Build Coastguard Worker default:
508*6a54128fSAndroid Build Coastguard Worker usage(argv[0]);
509*6a54128fSAndroid Build Coastguard Worker }
510*6a54128fSAndroid Build Coastguard Worker }
511*6a54128fSAndroid Build Coastguard Worker uid = getuid();
512*6a54128fSAndroid Build Coastguard Worker if (uid && drop_privs) {
513*6a54128fSAndroid Build Coastguard Worker gid = getgid();
514*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SETRESGID
515*6a54128fSAndroid Build Coastguard Worker if (setresgid(gid, gid, gid) < 0)
516*6a54128fSAndroid Build Coastguard Worker die("setresgid");
517*6a54128fSAndroid Build Coastguard Worker #else
518*6a54128fSAndroid Build Coastguard Worker if (setregid(gid, gid) < 0)
519*6a54128fSAndroid Build Coastguard Worker die("setregid");
520*6a54128fSAndroid Build Coastguard Worker #endif
521*6a54128fSAndroid Build Coastguard Worker
522*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_SETRESUID
523*6a54128fSAndroid Build Coastguard Worker if (setresuid(uid, uid, uid) < 0)
524*6a54128fSAndroid Build Coastguard Worker die("setresuid");
525*6a54128fSAndroid Build Coastguard Worker #else
526*6a54128fSAndroid Build Coastguard Worker if (setreuid(uid, uid) < 0)
527*6a54128fSAndroid Build Coastguard Worker die("setreuid");
528*6a54128fSAndroid Build Coastguard Worker #endif
529*6a54128fSAndroid Build Coastguard Worker }
530*6a54128fSAndroid Build Coastguard Worker if (num && do_type) {
531*6a54128fSAndroid Build Coastguard Worker ret = call_daemon(socket_path, do_type+2, buf,
532*6a54128fSAndroid Build Coastguard Worker sizeof(buf), &num, &err_context);
533*6a54128fSAndroid Build Coastguard Worker if (ret < 0) {
534*6a54128fSAndroid Build Coastguard Worker printf(_("Error calling uuidd daemon (%s): %s\n"),
535*6a54128fSAndroid Build Coastguard Worker err_context, strerror(errno));
536*6a54128fSAndroid Build Coastguard Worker exit(1);
537*6a54128fSAndroid Build Coastguard Worker }
538*6a54128fSAndroid Build Coastguard Worker if (do_type == UUIDD_OP_TIME_UUID) {
539*6a54128fSAndroid Build Coastguard Worker if (ret != sizeof(uu) + sizeof(num))
540*6a54128fSAndroid Build Coastguard Worker goto unexpected_size;
541*6a54128fSAndroid Build Coastguard Worker
542*6a54128fSAndroid Build Coastguard Worker uuid_unparse((unsigned char *) buf, str);
543*6a54128fSAndroid Build Coastguard Worker
544*6a54128fSAndroid Build Coastguard Worker printf(P_("%s and subsequent UUID\n",
545*6a54128fSAndroid Build Coastguard Worker "%s and subsequent %d UUIDs\n", num),
546*6a54128fSAndroid Build Coastguard Worker str, num);
547*6a54128fSAndroid Build Coastguard Worker } else {
548*6a54128fSAndroid Build Coastguard Worker printf("%s", _("List of UUID's:\n"));
549*6a54128fSAndroid Build Coastguard Worker cp = buf + 4;
550*6a54128fSAndroid Build Coastguard Worker if (ret != (int) (sizeof(num) + num*sizeof(uu)))
551*6a54128fSAndroid Build Coastguard Worker goto unexpected_size;
552*6a54128fSAndroid Build Coastguard Worker for (i=0; i < num; i++, cp+=16) {
553*6a54128fSAndroid Build Coastguard Worker uuid_unparse((unsigned char *) cp, str);
554*6a54128fSAndroid Build Coastguard Worker printf("\t%s\n", str);
555*6a54128fSAndroid Build Coastguard Worker }
556*6a54128fSAndroid Build Coastguard Worker }
557*6a54128fSAndroid Build Coastguard Worker exit(0);
558*6a54128fSAndroid Build Coastguard Worker }
559*6a54128fSAndroid Build Coastguard Worker if (do_type) {
560*6a54128fSAndroid Build Coastguard Worker ret = call_daemon(socket_path, do_type, (char *) &uu,
561*6a54128fSAndroid Build Coastguard Worker sizeof(uu), 0, &err_context);
562*6a54128fSAndroid Build Coastguard Worker if (ret < 0) {
563*6a54128fSAndroid Build Coastguard Worker printf(_("Error calling uuidd daemon (%s): %s\n"),
564*6a54128fSAndroid Build Coastguard Worker err_context, strerror(errno));
565*6a54128fSAndroid Build Coastguard Worker exit(1);
566*6a54128fSAndroid Build Coastguard Worker }
567*6a54128fSAndroid Build Coastguard Worker if (ret != sizeof(uu)) {
568*6a54128fSAndroid Build Coastguard Worker unexpected_size:
569*6a54128fSAndroid Build Coastguard Worker printf(_("Unexpected reply length from server %d\n"),
570*6a54128fSAndroid Build Coastguard Worker ret);
571*6a54128fSAndroid Build Coastguard Worker exit(1);
572*6a54128fSAndroid Build Coastguard Worker }
573*6a54128fSAndroid Build Coastguard Worker uuid_unparse(uu, str);
574*6a54128fSAndroid Build Coastguard Worker
575*6a54128fSAndroid Build Coastguard Worker printf("%s\n", str);
576*6a54128fSAndroid Build Coastguard Worker exit(0);
577*6a54128fSAndroid Build Coastguard Worker }
578*6a54128fSAndroid Build Coastguard Worker
579*6a54128fSAndroid Build Coastguard Worker if (do_kill) {
580*6a54128fSAndroid Build Coastguard Worker ret = call_daemon(socket_path, 0, buf, sizeof(buf), 0, 0);
581*6a54128fSAndroid Build Coastguard Worker if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) {
582*6a54128fSAndroid Build Coastguard Worker ret = kill(do_kill, SIGTERM);
583*6a54128fSAndroid Build Coastguard Worker if (ret < 0) {
584*6a54128fSAndroid Build Coastguard Worker if (!quiet)
585*6a54128fSAndroid Build Coastguard Worker fprintf(stderr,
586*6a54128fSAndroid Build Coastguard Worker _("Couldn't kill uuidd running "
587*6a54128fSAndroid Build Coastguard Worker "at pid %d: %s\n"), do_kill,
588*6a54128fSAndroid Build Coastguard Worker strerror(errno));
589*6a54128fSAndroid Build Coastguard Worker exit(1);
590*6a54128fSAndroid Build Coastguard Worker }
591*6a54128fSAndroid Build Coastguard Worker if (!quiet)
592*6a54128fSAndroid Build Coastguard Worker printf(_("Killed uuidd running at pid %d\n"),
593*6a54128fSAndroid Build Coastguard Worker do_kill);
594*6a54128fSAndroid Build Coastguard Worker }
595*6a54128fSAndroid Build Coastguard Worker exit(0);
596*6a54128fSAndroid Build Coastguard Worker }
597*6a54128fSAndroid Build Coastguard Worker
598*6a54128fSAndroid Build Coastguard Worker server_loop(socket_path, pidfile_path, debug, timeout, quiet);
599*6a54128fSAndroid Build Coastguard Worker return 0;
600*6a54128fSAndroid Build Coastguard Worker }
601