1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3 *
4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25 #include "dbus-internals.h"
26 #include "dbus-sysdeps.h"
27 #include "dbus-sysdeps-unix.h"
28 #include "dbus-threads.h"
29 #include "dbus-protocol.h"
30 #include "dbus-transport.h"
31 #include "dbus-string.h"
32 #include "dbus-userdb.h"
33 #include "dbus-list.h"
34 #include <sys/types.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <signal.h>
38 #include <unistd.h>
39 #include <stdio.h>
40 #include <fcntl.h>
41 #include <sys/socket.h>
42 #include <dirent.h>
43 #include <sys/un.h>
44 #include <pwd.h>
45 #include <time.h>
46 #include <locale.h>
47 #include <sys/time.h>
48 #include <sys/stat.h>
49 #include <sys/wait.h>
50 #include <netinet/in.h>
51 #include <netdb.h>
52 #include <grp.h>
53 #include <cutils/sockets.h>
54
55 #ifdef HAVE_ERRNO_H
56 #include <errno.h>
57 #endif
58 #ifdef HAVE_WRITEV
59 #include <sys/uio.h>
60 #endif
61 #ifdef HAVE_POLL
62 #include <sys/poll.h>
63 #endif
64 #ifdef HAVE_BACKTRACE
65 #include <execinfo.h>
66 #endif
67 #ifdef HAVE_GETPEERUCRED
68 #include <ucred.h>
69 #endif
70
71 #ifndef O_BINARY
72 #define O_BINARY 0
73 #endif
74
75 #ifndef HAVE_SOCKLEN_T
76 #define socklen_t int
77 #endif
78
79 static dbus_bool_t
_dbus_open_socket(int * fd,int domain,int type,int protocol,DBusError * error)80 _dbus_open_socket (int *fd,
81 int domain,
82 int type,
83 int protocol,
84 DBusError *error)
85 {
86 *fd = socket (domain, type, protocol);
87 if (*fd >= 0)
88 {
89 return TRUE;
90 }
91 else
92 {
93 dbus_set_error(error,
94 _dbus_error_from_errno (errno),
95 "Failed to open socket: %s",
96 _dbus_strerror (errno));
97 return FALSE;
98 }
99 }
100
101 dbus_bool_t
_dbus_open_tcp_socket(int * fd,DBusError * error)102 _dbus_open_tcp_socket (int *fd,
103 DBusError *error)
104 {
105 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
106 }
107
108 /**
109 * Opens a UNIX domain socket (as in the socket() call).
110 * Does not bind the socket.
111 * @param fd return location for socket descriptor
112 * @param error return location for an error
113 * @returns #FALSE if error is set
114 */
115 dbus_bool_t
_dbus_open_unix_socket(int * fd,DBusError * error)116 _dbus_open_unix_socket (int *fd,
117 DBusError *error)
118 {
119 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
120 }
121
122 /**
123 * Closes a socket. Should not be used on non-socket
124 * file descriptors or handles.
125 *
126 * @param fd the socket
127 * @param error return location for an error
128 * @returns #FALSE if error is set
129 */
130 dbus_bool_t
_dbus_close_socket(int fd,DBusError * error)131 _dbus_close_socket (int fd,
132 DBusError *error)
133 {
134 return _dbus_close (fd, error);
135 }
136
137 /**
138 * Like _dbus_read(), but only works on sockets so is
139 * available on Windows.
140 *
141 * @param fd the socket
142 * @param buffer string to append data to
143 * @param count max amount of data to read
144 * @returns number of bytes appended to the string
145 */
146 int
_dbus_read_socket(int fd,DBusString * buffer,int count)147 _dbus_read_socket (int fd,
148 DBusString *buffer,
149 int count)
150 {
151 return _dbus_read (fd, buffer, count);
152 }
153
154 /**
155 * Like _dbus_write(), but only supports sockets
156 * and is thus available on Windows.
157 *
158 * @param fd the file descriptor to write
159 * @param buffer the buffer to write data from
160 * @param start the first byte in the buffer to write
161 * @param len the number of bytes to try to write
162 * @returns the number of bytes written or -1 on error
163 */
164 int
_dbus_write_socket(int fd,const DBusString * buffer,int start,int len)165 _dbus_write_socket (int fd,
166 const DBusString *buffer,
167 int start,
168 int len)
169 {
170 return _dbus_write (fd, buffer, start, len);
171 }
172
173 /**
174 * Like _dbus_write_two() but only works on sockets and is thus
175 * available on Windows.
176 *
177 * @param fd the file descriptor
178 * @param buffer1 first buffer
179 * @param start1 first byte to write in first buffer
180 * @param len1 number of bytes to write from first buffer
181 * @param buffer2 second buffer, or #NULL
182 * @param start2 first byte to write in second buffer
183 * @param len2 number of bytes to write in second buffer
184 * @returns total bytes written from both buffers, or -1 on error
185 */
186 int
_dbus_write_socket_two(int fd,const DBusString * buffer1,int start1,int len1,const DBusString * buffer2,int start2,int len2)187 _dbus_write_socket_two (int fd,
188 const DBusString *buffer1,
189 int start1,
190 int len1,
191 const DBusString *buffer2,
192 int start2,
193 int len2)
194 {
195 return _dbus_write_two (fd, buffer1, start1, len1,
196 buffer2, start2, len2);
197 }
198
199
200 /**
201 * Thin wrapper around the read() system call that appends
202 * the data it reads to the DBusString buffer. It appends
203 * up to the given count, and returns the same value
204 * and same errno as read(). The only exception is that
205 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
206 * return ENOMEM, even though regular UNIX read doesn't.
207 *
208 * Unlike _dbus_read_socket(), _dbus_read() is not available
209 * on Windows.
210 *
211 * @param fd the file descriptor to read from
212 * @param buffer the buffer to append data to
213 * @param count the amount of data to read
214 * @returns the number of bytes read or -1
215 */
216 int
_dbus_read(int fd,DBusString * buffer,int count)217 _dbus_read (int fd,
218 DBusString *buffer,
219 int count)
220 {
221 int bytes_read;
222 int start;
223 char *data;
224
225 _dbus_assert (count >= 0);
226
227 start = _dbus_string_get_length (buffer);
228
229 if (!_dbus_string_lengthen (buffer, count))
230 {
231 errno = ENOMEM;
232 return -1;
233 }
234
235 data = _dbus_string_get_data_len (buffer, start, count);
236
237 again:
238
239 bytes_read = read (fd, data, count);
240
241 if (bytes_read < 0)
242 {
243 if (errno == EINTR)
244 goto again;
245 else
246 {
247 /* put length back (note that this doesn't actually realloc anything) */
248 _dbus_string_set_length (buffer, start);
249 return -1;
250 }
251 }
252 else
253 {
254 /* put length back (doesn't actually realloc) */
255 _dbus_string_set_length (buffer, start + bytes_read);
256
257 #if 0
258 if (bytes_read > 0)
259 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
260 #endif
261
262 return bytes_read;
263 }
264 }
265
266 /**
267 * Thin wrapper around the write() system call that writes a part of a
268 * DBusString and handles EINTR for you.
269 *
270 * @param fd the file descriptor to write
271 * @param buffer the buffer to write data from
272 * @param start the first byte in the buffer to write
273 * @param len the number of bytes to try to write
274 * @returns the number of bytes written or -1 on error
275 */
276 int
_dbus_write(int fd,const DBusString * buffer,int start,int len)277 _dbus_write (int fd,
278 const DBusString *buffer,
279 int start,
280 int len)
281 {
282 const char *data;
283 int bytes_written;
284
285 data = _dbus_string_get_const_data_len (buffer, start, len);
286
287 again:
288
289 bytes_written = write (fd, data, len);
290
291 if (bytes_written < 0 && errno == EINTR)
292 goto again;
293
294 #if 0
295 if (bytes_written > 0)
296 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
297 #endif
298
299 return bytes_written;
300 }
301
302 /**
303 * Like _dbus_write() but will use writev() if possible
304 * to write both buffers in sequence. The return value
305 * is the number of bytes written in the first buffer,
306 * plus the number written in the second. If the first
307 * buffer is written successfully and an error occurs
308 * writing the second, the number of bytes in the first
309 * is returned (i.e. the error is ignored), on systems that
310 * don't have writev. Handles EINTR for you.
311 * The second buffer may be #NULL.
312 *
313 * @param fd the file descriptor
314 * @param buffer1 first buffer
315 * @param start1 first byte to write in first buffer
316 * @param len1 number of bytes to write from first buffer
317 * @param buffer2 second buffer, or #NULL
318 * @param start2 first byte to write in second buffer
319 * @param len2 number of bytes to write in second buffer
320 * @returns total bytes written from both buffers, or -1 on error
321 */
322 int
_dbus_write_two(int fd,const DBusString * buffer1,int start1,int len1,const DBusString * buffer2,int start2,int len2)323 _dbus_write_two (int fd,
324 const DBusString *buffer1,
325 int start1,
326 int len1,
327 const DBusString *buffer2,
328 int start2,
329 int len2)
330 {
331 _dbus_assert (buffer1 != NULL);
332 _dbus_assert (start1 >= 0);
333 _dbus_assert (start2 >= 0);
334 _dbus_assert (len1 >= 0);
335 _dbus_assert (len2 >= 0);
336
337 #ifdef HAVE_WRITEV
338 {
339 struct iovec vectors[2];
340 const char *data1;
341 const char *data2;
342 int bytes_written;
343
344 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
345
346 if (buffer2 != NULL)
347 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
348 else
349 {
350 data2 = NULL;
351 start2 = 0;
352 len2 = 0;
353 }
354
355 vectors[0].iov_base = (char*) data1;
356 vectors[0].iov_len = len1;
357 vectors[1].iov_base = (char*) data2;
358 vectors[1].iov_len = len2;
359
360 again:
361
362 bytes_written = writev (fd,
363 vectors,
364 data2 ? 2 : 1);
365
366 if (bytes_written < 0 && errno == EINTR)
367 goto again;
368
369 return bytes_written;
370 }
371 #else /* HAVE_WRITEV */
372 {
373 int ret1;
374
375 ret1 = _dbus_write (fd, buffer1, start1, len1);
376 if (ret1 == len1 && buffer2 != NULL)
377 {
378 ret2 = _dbus_write (fd, buffer2, start2, len2);
379 if (ret2 < 0)
380 ret2 = 0; /* we can't report an error as the first write was OK */
381
382 return ret1 + ret2;
383 }
384 else
385 return ret1;
386 }
387 #endif /* !HAVE_WRITEV */
388 }
389
390 #define _DBUS_MAX_SUN_PATH_LENGTH 99
391
392 /**
393 * @def _DBUS_MAX_SUN_PATH_LENGTH
394 *
395 * Maximum length of the path to a UNIX domain socket,
396 * sockaddr_un::sun_path member. POSIX requires that all systems
397 * support at least 100 bytes here, including the nul termination.
398 * We use 99 for the max value to allow for the nul.
399 *
400 * We could probably also do sizeof (addr.sun_path)
401 * but this way we are the same on all platforms
402 * which is probably a good idea.
403 */
404
405 /**
406 * Creates a socket and connects it to the UNIX domain socket at the
407 * given path. The connection fd is returned, and is set up as
408 * nonblocking.
409 *
410 * Uses abstract sockets instead of filesystem-linked sockets if
411 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
412 * On non-Linux abstract socket usage always fails.
413 *
414 * @param path the path to UNIX domain socket
415 * @param abstract #TRUE to use abstract namespace
416 * @param error return location for error code
417 * @returns connection file descriptor or -1 on error
418 */
419 int
_dbus_connect_unix_socket(const char * path,dbus_bool_t abstract,DBusError * error)420 _dbus_connect_unix_socket (const char *path,
421 dbus_bool_t abstract,
422 DBusError *error)
423 {
424 int fd;
425 size_t path_len;
426 struct sockaddr_un addr;
427
428 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
429
430 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
431 path, abstract);
432
433
434 if (!_dbus_open_unix_socket (&fd, error))
435 {
436 _DBUS_ASSERT_ERROR_IS_SET(error);
437 return -1;
438 }
439 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
440
441 _DBUS_ZERO (addr);
442 addr.sun_family = AF_UNIX;
443 path_len = strlen (path);
444
445 if (abstract)
446 {
447 #ifdef HAVE_ABSTRACT_SOCKETS
448 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
449 path_len++; /* Account for the extra nul byte added to the start of sun_path */
450
451 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
452 {
453 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
454 "Abstract socket name too long\n");
455 _dbus_close (fd, NULL);
456 return -1;
457 }
458
459 strncpy (&addr.sun_path[1], path, path_len);
460 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
461 #else /* HAVE_ABSTRACT_SOCKETS */
462 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
463 "Operating system does not support abstract socket namespace\n");
464 _dbus_close (fd, NULL);
465 return -1;
466 #endif /* ! HAVE_ABSTRACT_SOCKETS */
467 }
468 else
469 {
470 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
471 {
472 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
473 "Socket name too long\n");
474 _dbus_close (fd, NULL);
475 return -1;
476 }
477
478 strncpy (addr.sun_path, path, path_len);
479 }
480
481 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
482 {
483 dbus_set_error (error,
484 _dbus_error_from_errno (errno),
485 "Failed to connect to socket %s: %s",
486 path, _dbus_strerror (errno));
487
488 _dbus_close (fd, NULL);
489 fd = -1;
490
491 return -1;
492 }
493
494 if (!_dbus_set_fd_nonblocking (fd, error))
495 {
496 _DBUS_ASSERT_ERROR_IS_SET (error);
497
498 _dbus_close (fd, NULL);
499 fd = -1;
500
501 return -1;
502 }
503
504 return fd;
505 }
506
507 /**
508 * Enables or disables the reception of credentials on the given socket during
509 * the next message transmission. This is only effective if the #LOCAL_CREDS
510 * system feature exists, in which case the other side of the connection does
511 * not have to do anything special to send the credentials.
512 *
513 * @param fd socket on which to change the #LOCAL_CREDS flag.
514 * @param on whether to enable or disable the #LOCAL_CREDS flag.
515 */
516 static dbus_bool_t
_dbus_set_local_creds(int fd,dbus_bool_t on)517 _dbus_set_local_creds (int fd, dbus_bool_t on)
518 {
519 dbus_bool_t retval = TRUE;
520
521 #if defined(HAVE_CMSGCRED)
522 /* NOOP just to make sure only one codepath is used
523 * and to prefer CMSGCRED
524 */
525 #elif defined(LOCAL_CREDS)
526 int val = on ? 1 : 0;
527 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
528 {
529 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
530 retval = FALSE;
531 }
532 else
533 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
534 on ? "enabled" : "disabled", fd);
535 #endif
536
537 return retval;
538 }
539
540 /**
541 * Creates a socket and binds it to the given path,
542 * then listens on the socket. The socket is
543 * set to be nonblocking.
544 *
545 * Uses abstract sockets instead of filesystem-linked
546 * sockets if requested (it's possible only on Linux;
547 * see "man 7 unix" on Linux).
548 * On non-Linux abstract socket usage always fails.
549 *
550 * @param path the socket name
551 * @param abstract #TRUE to use abstract namespace
552 * @param error return location for errors
553 * @returns the listening file descriptor or -1 on error
554 */
555 int
_dbus_listen_unix_socket(const char * path,dbus_bool_t abstract,DBusError * error)556 _dbus_listen_unix_socket (const char *path,
557 dbus_bool_t abstract,
558 DBusError *error)
559 {
560 int listen_fd;
561 struct sockaddr_un addr;
562 size_t path_len;
563
564 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
565
566 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
567 path, abstract);
568 #ifdef ANDROID_MANAGED_SOCKET
569 if (strncmp (path, ANDROID_SOCKET_DIR"/", strlen(ANDROID_SOCKET_DIR"/")) == 0)
570 {
571 const char* suffix;
572 /* init has created a socket for us, pick it up from environ */
573 suffix = &path[strlen (ANDROID_SOCKET_DIR"/")];
574 listen_fd = android_get_control_socket (suffix);
575 if (listen_fd == -1)
576 {
577 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
578 "Could not obtain fd for android socket %s\n", suffix);
579 return -1;
580 }
581
582 _dbus_verbose ("Obtained fd for android socket %s\n", suffix);
583 }
584 else
585 {
586 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
587 "Not an android socket: %s\n", path);
588 return -1;
589 }
590 #else
591
592 if (!_dbus_open_unix_socket (&listen_fd, error))
593 {
594 _DBUS_ASSERT_ERROR_IS_SET(error);
595 return -1;
596 }
597 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
598
599 _DBUS_ZERO (addr);
600 addr.sun_family = AF_UNIX;
601 path_len = strlen (path);
602
603 if (abstract)
604 {
605 #ifdef HAVE_ABSTRACT_SOCKETS
606 /* remember that abstract names aren't nul-terminated so we rely
607 * on sun_path being filled in with zeroes above.
608 */
609 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
610 path_len++; /* Account for the extra nul byte added to the start of sun_path */
611
612 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
613 {
614 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
615 "Abstract socket name too long\n");
616 _dbus_close (listen_fd, NULL);
617 return -1;
618 }
619
620 strncpy (&addr.sun_path[1], path, path_len);
621 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
622 #else /* HAVE_ABSTRACT_SOCKETS */
623 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
624 "Operating system does not support abstract socket namespace\n");
625 _dbus_close (listen_fd, NULL);
626 return -1;
627 #endif /* ! HAVE_ABSTRACT_SOCKETS */
628 }
629 else
630 {
631 /* Discussed security implications of this with Nalin,
632 * and we couldn't think of where it would kick our ass, but
633 * it still seems a bit sucky. It also has non-security suckage;
634 * really we'd prefer to exit if the socket is already in use.
635 * But there doesn't seem to be a good way to do this.
636 *
637 * Just to be extra careful, I threw in the stat() - clearly
638 * the stat() can't *fix* any security issue, but it at least
639 * avoids inadvertent/accidental data loss.
640 */
641 {
642 struct stat sb;
643
644 if (stat (path, &sb) == 0 &&
645 S_ISSOCK (sb.st_mode))
646 unlink (path);
647 }
648
649 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
650 {
651 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
652 "Abstract socket name too long\n");
653 _dbus_close (listen_fd, NULL);
654 return -1;
655 }
656
657 strncpy (addr.sun_path, path, path_len);
658 }
659
660 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
661 {
662 dbus_set_error (error, _dbus_error_from_errno (errno),
663 "Failed to bind socket \"%s\": %s",
664 path, _dbus_strerror (errno));
665 _dbus_close (listen_fd, NULL);
666 return -1;
667 }
668
669 #endif /* android init managed sockets */
670
671 if (listen (listen_fd, 30 /* backlog */) < 0)
672 {
673 dbus_set_error (error, _dbus_error_from_errno (errno),
674 "Failed to listen on socket \"%s\": %s",
675 path, _dbus_strerror (errno));
676 _dbus_close (listen_fd, NULL);
677 return -1;
678 }
679
680 if (!_dbus_set_local_creds (listen_fd, TRUE))
681 {
682 dbus_set_error (error, _dbus_error_from_errno (errno),
683 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
684 path, _dbus_strerror (errno));
685 close (listen_fd);
686 return -1;
687 }
688
689 if (!_dbus_set_fd_nonblocking (listen_fd, error))
690 {
691 _DBUS_ASSERT_ERROR_IS_SET (error);
692 _dbus_close (listen_fd, NULL);
693 return -1;
694 }
695
696 #ifndef ANDROID_MANAGED_SOCKET
697 /* Try opening up the permissions, but if we can't, just go ahead
698 * and continue, maybe it will be good enough.
699 */
700 if (!abstract && chmod (path, 0777) < 0)
701 _dbus_warn ("Could not set mode 0777 on socket %s\n",
702 path);
703 #endif
704
705 return listen_fd;
706 }
707
708 /**
709 * Creates a socket and connects to a socket at the given host
710 * and port. The connection fd is returned, and is set up as
711 * nonblocking.
712 *
713 * @param host the host name to connect to
714 * @param port the prot to connect to
715 * @param error return location for error code
716 * @returns connection file descriptor or -1 on error
717 */
718 int
_dbus_connect_tcp_socket(const char * host,dbus_uint32_t port,DBusError * error)719 _dbus_connect_tcp_socket (const char *host,
720 dbus_uint32_t port,
721 DBusError *error)
722 {
723 int fd;
724 struct sockaddr_in addr;
725 struct hostent *he;
726 struct in_addr *haddr;
727
728 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
729
730
731 if (!_dbus_open_tcp_socket (&fd, error))
732 {
733 _DBUS_ASSERT_ERROR_IS_SET(error);
734
735 return -1;
736 }
737 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
738
739 if (host == NULL)
740 host = "localhost";
741
742 he = gethostbyname (host);
743 if (he == NULL)
744 {
745 dbus_set_error (error,
746 _dbus_error_from_errno (errno),
747 "Failed to lookup hostname: %s",
748 host);
749 _dbus_close (fd, NULL);
750 return -1;
751 }
752
753 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
754
755 _DBUS_ZERO (addr);
756 memcpy (&addr.sin_addr, haddr, sizeof(struct in_addr));
757 addr.sin_family = AF_INET;
758 addr.sin_port = htons (port);
759
760 if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
761 {
762 dbus_set_error (error,
763 _dbus_error_from_errno (errno),
764 "Failed to connect to socket %s:%d %s",
765 host, port, _dbus_strerror (errno));
766
767 _dbus_close (fd, NULL);
768 fd = -1;
769
770 return -1;
771 }
772
773 if (!_dbus_set_fd_nonblocking (fd, error))
774 {
775 _dbus_close (fd, NULL);
776 fd = -1;
777
778 return -1;
779 }
780
781 return fd;
782 }
783
784 /**
785 * Creates a socket and binds it to the given path,
786 * then listens on the socket. The socket is
787 * set to be nonblocking.
788 *
789 * @param host the host name to listen on
790 * @param port the prot to listen on
791 * @param error return location for errors
792 * @returns the listening file descriptor or -1 on error
793 */
794 int
_dbus_listen_tcp_socket(const char * host,dbus_uint32_t port,DBusError * error)795 _dbus_listen_tcp_socket (const char *host,
796 dbus_uint32_t port,
797 DBusError *error)
798 {
799 int listen_fd;
800 struct sockaddr_in addr;
801 struct hostent *he;
802 struct in_addr *haddr;
803
804 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
805
806
807 if (!_dbus_open_tcp_socket (&listen_fd, error))
808 {
809 _DBUS_ASSERT_ERROR_IS_SET(error);
810 return -1;
811 }
812 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
813
814 he = gethostbyname (host);
815 if (he == NULL)
816 {
817 dbus_set_error (error,
818 _dbus_error_from_errno (errno),
819 "Failed to lookup hostname: %s",
820 host);
821 _dbus_close (listen_fd, NULL);
822 return -1;
823 }
824
825 haddr = ((struct in_addr *) (he->h_addr_list)[0]);
826
827 _DBUS_ZERO (addr);
828 memcpy (&addr.sin_addr, haddr, sizeof (struct in_addr));
829 addr.sin_family = AF_INET;
830 addr.sin_port = htons (port);
831
832 if (bind (listen_fd, (struct sockaddr*) &addr, sizeof (struct sockaddr)))
833 {
834 dbus_set_error (error, _dbus_error_from_errno (errno),
835 "Failed to bind socket \"%s:%d\": %s",
836 host, port, _dbus_strerror (errno));
837 _dbus_close (listen_fd, NULL);
838 return -1;
839 }
840
841 if (listen (listen_fd, 30 /* backlog */) < 0)
842 {
843 dbus_set_error (error, _dbus_error_from_errno (errno),
844 "Failed to listen on socket \"%s:%d\": %s",
845 host, port, _dbus_strerror (errno));
846 _dbus_close (listen_fd, NULL);
847 return -1;
848 }
849
850 if (!_dbus_set_fd_nonblocking (listen_fd, error))
851 {
852 _dbus_close (listen_fd, NULL);
853 return -1;
854 }
855
856 return listen_fd;
857 }
858
859 static dbus_bool_t
write_credentials_byte(int server_fd,DBusError * error)860 write_credentials_byte (int server_fd,
861 DBusError *error)
862 {
863 int bytes_written;
864 char buf[1] = { '\0' };
865 #if defined(HAVE_CMSGCRED)
866 struct {
867 struct cmsghdr hdr;
868 struct cmsgcred cred;
869 } cmsg;
870 struct iovec iov;
871 struct msghdr msg;
872 iov.iov_base = buf;
873 iov.iov_len = 1;
874
875 memset (&msg, 0, sizeof (msg));
876 msg.msg_iov = &iov;
877 msg.msg_iovlen = 1;
878
879 msg.msg_control = &cmsg;
880 msg.msg_controllen = sizeof (cmsg);
881 memset (&cmsg, 0, sizeof (cmsg));
882 cmsg.hdr.cmsg_len = sizeof (cmsg);
883 cmsg.hdr.cmsg_level = SOL_SOCKET;
884 cmsg.hdr.cmsg_type = SCM_CREDS;
885 #endif
886
887 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
888
889 again:
890
891 #if defined(HAVE_CMSGCRED)
892 bytes_written = sendmsg (server_fd, &msg, 0);
893 #else
894 bytes_written = write (server_fd, buf, 1);
895 #endif
896
897 if (bytes_written < 0 && errno == EINTR)
898 goto again;
899
900 if (bytes_written < 0)
901 {
902 dbus_set_error (error, _dbus_error_from_errno (errno),
903 "Failed to write credentials byte: %s",
904 _dbus_strerror (errno));
905 return FALSE;
906 }
907 else if (bytes_written == 0)
908 {
909 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
910 "wrote zero bytes writing credentials byte");
911 return FALSE;
912 }
913 else
914 {
915 _dbus_assert (bytes_written == 1);
916 _dbus_verbose ("wrote credentials byte\n");
917 return TRUE;
918 }
919 }
920
921 /**
922 * Reads a single byte which must be nul (an error occurs otherwise),
923 * and reads unix credentials if available. Fills in pid/uid/gid with
924 * -1 if no credentials are available. Return value indicates whether
925 * a byte was read, not whether we got valid credentials. On some
926 * systems, such as Linux, reading/writing the byte isn't actually
927 * required, but we do it anyway just to avoid multiple codepaths.
928 *
929 * Fails if no byte is available, so you must select() first.
930 *
931 * The point of the byte is that on some systems we have to
932 * use sendmsg()/recvmsg() to transmit credentials.
933 *
934 * @param client_fd the client file descriptor
935 * @param credentials struct to fill with credentials of client
936 * @param error location to store error code
937 * @returns #TRUE on success
938 */
939 dbus_bool_t
_dbus_read_credentials_unix_socket(int client_fd,DBusCredentials * credentials,DBusError * error)940 _dbus_read_credentials_unix_socket (int client_fd,
941 DBusCredentials *credentials,
942 DBusError *error)
943 {
944 struct msghdr msg;
945 struct iovec iov;
946 char buf;
947
948 #ifdef HAVE_CMSGCRED
949 struct {
950 struct cmsghdr hdr;
951 struct cmsgcred cred;
952 } cmsg;
953
954 #elif defined(LOCAL_CREDS)
955 struct {
956 struct cmsghdr hdr;
957 struct sockcred cred;
958 } cmsg;
959 #endif
960
961 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
962
963 /* The POSIX spec certainly doesn't promise this, but
964 * we need these assertions to fail as soon as we're wrong about
965 * it so we can do the porting fixups
966 */
967 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
968 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
969 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
970
971 _dbus_credentials_clear (credentials);
972
973 /* Systems supporting LOCAL_CREDS are configured to have this feature
974 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
975 * the connection. Therefore, the received message must carry the
976 * credentials information without doing anything special.
977 */
978
979 iov.iov_base = &buf;
980 iov.iov_len = 1;
981
982 memset (&msg, 0, sizeof (msg));
983 msg.msg_iov = &iov;
984 msg.msg_iovlen = 1;
985
986 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
987 memset (&cmsg, 0, sizeof (cmsg));
988 msg.msg_control = &cmsg;
989 msg.msg_controllen = sizeof (cmsg);
990 #endif
991
992 again:
993 if (recvmsg (client_fd, &msg, 0) < 0)
994 {
995 if (errno == EINTR)
996 goto again;
997
998 dbus_set_error (error, _dbus_error_from_errno (errno),
999 "Failed to read credentials byte: %s",
1000 _dbus_strerror (errno));
1001 return FALSE;
1002 }
1003
1004 if (buf != '\0')
1005 {
1006 dbus_set_error (error, DBUS_ERROR_FAILED,
1007 "Credentials byte was not nul");
1008 return FALSE;
1009 }
1010
1011 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1012 if (cmsg.hdr.cmsg_len < sizeof (cmsg) || cmsg.hdr.cmsg_type != SCM_CREDS)
1013 {
1014 dbus_set_error (error, DBUS_ERROR_FAILED,
1015 "Message from recvmsg() was not SCM_CREDS");
1016 return FALSE;
1017 }
1018 #endif
1019
1020 _dbus_verbose ("read credentials byte\n");
1021
1022 {
1023 #ifdef SO_PEERCRED
1024 struct ucred cr;
1025 int cr_len = sizeof (cr);
1026
1027 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1028 cr_len == sizeof (cr))
1029 {
1030 credentials->pid = cr.pid;
1031 credentials->uid = cr.uid;
1032 credentials->gid = cr.gid;
1033 }
1034 else
1035 {
1036 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1037 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1038 }
1039 #elif defined(HAVE_CMSGCRED)
1040 credentials->pid = cmsg.cred.cmcred_pid;
1041 credentials->uid = cmsg.cred.cmcred_euid;
1042 credentials->gid = cmsg.cred.cmcred_groups[0];
1043 #elif defined(LOCAL_CREDS)
1044 credentials->pid = DBUS_PID_UNSET;
1045 credentials->uid = cmsg.cred.sc_uid;
1046 credentials->gid = cmsg.cred.sc_gid;
1047 /* Since we have already got the credentials from this socket, we can
1048 * disable its LOCAL_CREDS flag if it was ever set. */
1049 _dbus_set_local_creds (client_fd, FALSE);
1050 #elif defined(HAVE_GETPEEREID)
1051 uid_t euid;
1052 gid_t egid;
1053 if (getpeereid (client_fd, &euid, &egid) == 0)
1054 {
1055 credentials->uid = euid;
1056 credentials->gid = egid;
1057 }
1058 else
1059 {
1060 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1061 }
1062 #elif defined(HAVE_GETPEERUCRED)
1063 ucred_t * ucred = NULL;
1064 if (getpeerucred (client_fd, &ucred) == 0)
1065 {
1066 credentials->pid = ucred_getpid (ucred);
1067 credentials->uid = ucred_geteuid (ucred);
1068 credentials->gid = ucred_getegid (ucred);
1069 }
1070 else
1071 {
1072 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1073 }
1074 if (ucred != NULL)
1075 ucred_free (ucred);
1076 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1077 _dbus_verbose ("Socket credentials not supported on this OS\n");
1078 #endif
1079 }
1080
1081 _dbus_verbose ("Credentials:"
1082 " pid "DBUS_PID_FORMAT
1083 " uid "DBUS_UID_FORMAT
1084 " gid "DBUS_GID_FORMAT"\n",
1085 credentials->pid,
1086 credentials->uid,
1087 credentials->gid);
1088
1089 return TRUE;
1090 }
1091
1092 /**
1093 * Sends a single nul byte with our UNIX credentials as ancillary
1094 * data. Returns #TRUE if the data was successfully written. On
1095 * systems that don't support sending credentials, just writes a byte,
1096 * doesn't send any credentials. On some systems, such as Linux,
1097 * reading/writing the byte isn't actually required, but we do it
1098 * anyway just to avoid multiple codepaths.
1099 *
1100 * Fails if no byte can be written, so you must select() first.
1101 *
1102 * The point of the byte is that on some systems we have to
1103 * use sendmsg()/recvmsg() to transmit credentials.
1104 *
1105 * @param server_fd file descriptor for connection to server
1106 * @param error return location for error code
1107 * @returns #TRUE if the byte was sent
1108 */
1109 dbus_bool_t
_dbus_send_credentials_unix_socket(int server_fd,DBusError * error)1110 _dbus_send_credentials_unix_socket (int server_fd,
1111 DBusError *error)
1112 {
1113 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1114
1115 if (write_credentials_byte (server_fd, error))
1116 return TRUE;
1117 else
1118 return FALSE;
1119 }
1120
1121 /**
1122 * Accepts a connection on a listening socket.
1123 * Handles EINTR for you.
1124 *
1125 * @param listen_fd the listen file descriptor
1126 * @returns the connection fd of the client, or -1 on error
1127 */
1128 int
_dbus_accept(int listen_fd)1129 _dbus_accept (int listen_fd)
1130 {
1131 int client_fd;
1132 struct sockaddr addr;
1133 socklen_t addrlen;
1134
1135 addrlen = sizeof (addr);
1136
1137 retry:
1138 client_fd = accept (listen_fd, &addr, &addrlen);
1139
1140 if (client_fd < 0)
1141 {
1142 if (errno == EINTR)
1143 goto retry;
1144 }
1145
1146 return client_fd;
1147 }
1148
1149 /**
1150 * Checks to make sure the given directory is
1151 * private to the user
1152 *
1153 * @param dir the name of the directory
1154 * @param error error return
1155 * @returns #FALSE on failure
1156 **/
1157 dbus_bool_t
_dbus_check_dir_is_private_to_user(DBusString * dir,DBusError * error)1158 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1159 {
1160 const char *directory;
1161 struct stat sb;
1162
1163 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1164
1165 directory = _dbus_string_get_const_data (dir);
1166
1167 if (stat (directory, &sb) < 0)
1168 {
1169 dbus_set_error (error, _dbus_error_from_errno (errno),
1170 "%s", _dbus_strerror (errno));
1171
1172 return FALSE;
1173 }
1174
1175 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1176 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1177 {
1178 dbus_set_error (error, DBUS_ERROR_FAILED,
1179 "%s directory is not private to the user", directory);
1180 return FALSE;
1181 }
1182
1183 return TRUE;
1184 }
1185
1186 static dbus_bool_t
fill_user_info_from_passwd(struct passwd * p,DBusUserInfo * info,DBusError * error)1187 fill_user_info_from_passwd (struct passwd *p,
1188 DBusUserInfo *info,
1189 DBusError *error)
1190 {
1191 _dbus_assert (p->pw_name != NULL);
1192 _dbus_assert (p->pw_dir != NULL);
1193
1194 info->uid = p->pw_uid;
1195 info->primary_gid = p->pw_gid;
1196 info->username = _dbus_strdup (p->pw_name);
1197 info->homedir = _dbus_strdup (p->pw_dir);
1198
1199 if (info->username == NULL ||
1200 info->homedir == NULL)
1201 {
1202 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1203 return FALSE;
1204 }
1205
1206 return TRUE;
1207 }
1208
1209 static dbus_bool_t
fill_user_info(DBusUserInfo * info,dbus_uid_t uid,const DBusString * username,DBusError * error)1210 fill_user_info (DBusUserInfo *info,
1211 dbus_uid_t uid,
1212 const DBusString *username,
1213 DBusError *error)
1214 {
1215 const char *username_c;
1216
1217 /* exactly one of username/uid provided */
1218 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1219 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1220
1221 info->uid = DBUS_UID_UNSET;
1222 info->primary_gid = DBUS_GID_UNSET;
1223 info->group_ids = NULL;
1224 info->n_group_ids = 0;
1225 info->username = NULL;
1226 info->homedir = NULL;
1227
1228 if (username != NULL)
1229 username_c = _dbus_string_get_const_data (username);
1230 else
1231 username_c = NULL;
1232
1233 /* For now assuming that the getpwnam() and getpwuid() flavors
1234 * are always symmetrical, if not we have to add more configure
1235 * checks
1236 */
1237
1238 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1239 {
1240 struct passwd *p;
1241 int result;
1242 char buf[1024];
1243 struct passwd p_str;
1244
1245 p = NULL;
1246 #ifdef HAVE_POSIX_GETPWNAM_R
1247 if (uid != DBUS_UID_UNSET)
1248 result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
1249 &p);
1250 else
1251 result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
1252 &p);
1253 #else
1254 if (uid != DBUS_UID_UNSET)
1255 p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
1256 else
1257 p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
1258 result = 0;
1259 #endif /* !HAVE_POSIX_GETPWNAM_R */
1260 if (result == 0 && p == &p_str)
1261 {
1262 if (!fill_user_info_from_passwd (p, info, error))
1263 return FALSE;
1264 }
1265 else
1266 {
1267 dbus_set_error (error, _dbus_error_from_errno (errno),
1268 "User \"%s\" unknown or no memory to allocate password entry\n",
1269 username_c ? username_c : "???");
1270 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1271 return FALSE;
1272 }
1273 }
1274 #else /* ! HAVE_GETPWNAM_R */
1275 {
1276 /* I guess we're screwed on thread safety here */
1277 struct passwd *p;
1278
1279 if (uid != DBUS_UID_UNSET)
1280 p = getpwuid (uid);
1281 else
1282 p = getpwnam (username_c);
1283
1284 if (p != NULL)
1285 {
1286 if (!fill_user_info_from_passwd (p, info, error))
1287 return FALSE;
1288 }
1289 else
1290 {
1291 dbus_set_error (error, _dbus_error_from_errno (errno),
1292 "User \"%s\" unknown or no memory to allocate password entry\n",
1293 username_c ? username_c : "???");
1294 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
1295 return FALSE;
1296 }
1297 }
1298 #endif /* ! HAVE_GETPWNAM_R */
1299
1300 /* Fill this in so we can use it to get groups */
1301 username_c = info->username;
1302
1303 #ifdef HAVE_GETGROUPLIST
1304 {
1305 gid_t *buf;
1306 int buf_count;
1307 int i;
1308
1309 buf_count = 17;
1310 buf = dbus_new (gid_t, buf_count);
1311 if (buf == NULL)
1312 {
1313 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1314 goto failed;
1315 }
1316
1317 if (getgrouplist (username_c,
1318 info->primary_gid,
1319 buf, &buf_count) < 0)
1320 {
1321 gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
1322 if (new == NULL)
1323 {
1324 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1325 dbus_free (buf);
1326 goto failed;
1327 }
1328
1329 buf = new;
1330
1331 errno = 0;
1332 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
1333 {
1334 dbus_set_error (error,
1335 _dbus_error_from_errno (errno),
1336 "Failed to get groups for username \"%s\" primary GID "
1337 DBUS_GID_FORMAT ": %s\n",
1338 username_c, info->primary_gid,
1339 _dbus_strerror (errno));
1340 dbus_free (buf);
1341 goto failed;
1342 }
1343 }
1344
1345 info->group_ids = dbus_new (dbus_gid_t, buf_count);
1346 if (info->group_ids == NULL)
1347 {
1348 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1349 dbus_free (buf);
1350 goto failed;
1351 }
1352
1353 for (i = 0; i < buf_count; ++i)
1354 info->group_ids[i] = buf[i];
1355
1356 info->n_group_ids = buf_count;
1357
1358 dbus_free (buf);
1359 }
1360 #else /* HAVE_GETGROUPLIST */
1361 {
1362 /* We just get the one group ID */
1363 info->group_ids = dbus_new (dbus_gid_t, 1);
1364 if (info->group_ids == NULL)
1365 {
1366 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1367 goto failed;
1368 }
1369
1370 info->n_group_ids = 1;
1371
1372 (info->group_ids)[0] = info->primary_gid;
1373 }
1374 #endif /* HAVE_GETGROUPLIST */
1375
1376 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1377
1378 return TRUE;
1379
1380 failed:
1381 _DBUS_ASSERT_ERROR_IS_SET (error);
1382 return FALSE;
1383 }
1384
1385 /**
1386 * Gets user info for the given username.
1387 *
1388 * @param info user info object to initialize
1389 * @param username the username
1390 * @param error error return
1391 * @returns #TRUE on success
1392 */
1393 dbus_bool_t
_dbus_user_info_fill(DBusUserInfo * info,const DBusString * username,DBusError * error)1394 _dbus_user_info_fill (DBusUserInfo *info,
1395 const DBusString *username,
1396 DBusError *error)
1397 {
1398 return fill_user_info (info, DBUS_UID_UNSET,
1399 username, error);
1400 }
1401
1402 /**
1403 * Gets user info for the given user ID.
1404 *
1405 * @param info user info object to initialize
1406 * @param uid the user ID
1407 * @param error error return
1408 * @returns #TRUE on success
1409 */
1410 dbus_bool_t
_dbus_user_info_fill_uid(DBusUserInfo * info,dbus_uid_t uid,DBusError * error)1411 _dbus_user_info_fill_uid (DBusUserInfo *info,
1412 dbus_uid_t uid,
1413 DBusError *error)
1414 {
1415 return fill_user_info (info, uid,
1416 NULL, error);
1417 }
1418
1419 /**
1420 * Gets the credentials of the current process.
1421 *
1422 * @param credentials credentials to fill in.
1423 */
1424 void
_dbus_credentials_from_current_process(DBusCredentials * credentials)1425 _dbus_credentials_from_current_process (DBusCredentials *credentials)
1426 {
1427 /* The POSIX spec certainly doesn't promise this, but
1428 * we need these assertions to fail as soon as we're wrong about
1429 * it so we can do the porting fixups
1430 */
1431 _dbus_assert (sizeof (pid_t) <= sizeof (credentials->pid));
1432 _dbus_assert (sizeof (uid_t) <= sizeof (credentials->uid));
1433 _dbus_assert (sizeof (gid_t) <= sizeof (credentials->gid));
1434
1435 credentials->pid = getpid ();
1436 credentials->uid = getuid ();
1437 credentials->gid = getgid ();
1438 }
1439
1440 /**
1441 * Gets our process ID
1442 * @returns process ID
1443 */
1444 unsigned long
_dbus_getpid(void)1445 _dbus_getpid (void)
1446 {
1447 return getpid ();
1448 }
1449
1450 /** Gets our UID
1451 * @returns process UID
1452 */
1453 dbus_uid_t
_dbus_getuid(void)1454 _dbus_getuid (void)
1455 {
1456 return getuid ();
1457 }
1458
1459 #ifdef DBUS_BUILD_TESTS
1460 /** Gets our GID
1461 * @returns process GID
1462 */
1463 dbus_gid_t
_dbus_getgid(void)1464 _dbus_getgid (void)
1465 {
1466 return getgid ();
1467 }
1468 #endif
1469
1470 /**
1471 * Wrapper for poll().
1472 *
1473 * @param fds the file descriptors to poll
1474 * @param n_fds number of descriptors in the array
1475 * @param timeout_milliseconds timeout or -1 for infinite
1476 * @returns numbers of fds with revents, or <0 on error
1477 */
1478 int
_dbus_poll(DBusPollFD * fds,int n_fds,int timeout_milliseconds)1479 _dbus_poll (DBusPollFD *fds,
1480 int n_fds,
1481 int timeout_milliseconds)
1482 {
1483 #ifdef HAVE_POLL
1484 /* This big thing is a constant expression and should get optimized
1485 * out of existence. So it's more robust than a configure check at
1486 * no cost.
1487 */
1488 if (_DBUS_POLLIN == POLLIN &&
1489 _DBUS_POLLPRI == POLLPRI &&
1490 _DBUS_POLLOUT == POLLOUT &&
1491 _DBUS_POLLERR == POLLERR &&
1492 _DBUS_POLLHUP == POLLHUP &&
1493 _DBUS_POLLNVAL == POLLNVAL &&
1494 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
1495 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
1496 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
1497 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
1498 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
1499 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
1500 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
1501 {
1502 return poll ((struct pollfd*) fds,
1503 n_fds,
1504 timeout_milliseconds);
1505 }
1506 else
1507 {
1508 /* We have to convert the DBusPollFD to an array of
1509 * struct pollfd, poll, and convert back.
1510 */
1511 _dbus_warn ("didn't implement poll() properly for this system yet\n");
1512 return -1;
1513 }
1514 #else /* ! HAVE_POLL */
1515
1516 fd_set read_set, write_set, err_set;
1517 int max_fd = 0;
1518 int i;
1519 struct timeval tv;
1520 int ready;
1521
1522 FD_ZERO (&read_set);
1523 FD_ZERO (&write_set);
1524 FD_ZERO (&err_set);
1525
1526 for (i = 0; i < n_fds; i++)
1527 {
1528 DBusPollFD *fdp = &fds[i];
1529
1530 if (fdp->events & _DBUS_POLLIN)
1531 FD_SET (fdp->fd, &read_set);
1532
1533 if (fdp->events & _DBUS_POLLOUT)
1534 FD_SET (fdp->fd, &write_set);
1535
1536 FD_SET (fdp->fd, &err_set);
1537
1538 max_fd = MAX (max_fd, fdp->fd);
1539 }
1540
1541 tv.tv_sec = timeout_milliseconds / 1000;
1542 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
1543
1544 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
1545 timeout_milliseconds < 0 ? NULL : &tv);
1546
1547 if (ready > 0)
1548 {
1549 for (i = 0; i < n_fds; i++)
1550 {
1551 DBusPollFD *fdp = &fds[i];
1552
1553 fdp->revents = 0;
1554
1555 if (FD_ISSET (fdp->fd, &read_set))
1556 fdp->revents |= _DBUS_POLLIN;
1557
1558 if (FD_ISSET (fdp->fd, &write_set))
1559 fdp->revents |= _DBUS_POLLOUT;
1560
1561 if (FD_ISSET (fdp->fd, &err_set))
1562 fdp->revents |= _DBUS_POLLERR;
1563 }
1564 }
1565
1566 return ready;
1567 #endif
1568 }
1569
1570 /**
1571 * Get current time, as in gettimeofday().
1572 *
1573 * @param tv_sec return location for number of seconds
1574 * @param tv_usec return location for number of microseconds (thousandths)
1575 */
1576 void
_dbus_get_current_time(long * tv_sec,long * tv_usec)1577 _dbus_get_current_time (long *tv_sec,
1578 long *tv_usec)
1579 {
1580 struct timeval t;
1581
1582 gettimeofday (&t, NULL);
1583
1584 if (tv_sec)
1585 *tv_sec = t.tv_sec;
1586 if (tv_usec)
1587 *tv_usec = t.tv_usec;
1588 }
1589
1590 /**
1591 * Appends the contents of the given file to the string,
1592 * returning error code. At the moment, won't open a file
1593 * more than a megabyte in size.
1594 *
1595 * @param str the string to append to
1596 * @param filename filename to load
1597 * @param error place to set an error
1598 * @returns #FALSE if error was set
1599 */
1600 dbus_bool_t
_dbus_file_get_contents(DBusString * str,const DBusString * filename,DBusError * error)1601 _dbus_file_get_contents (DBusString *str,
1602 const DBusString *filename,
1603 DBusError *error)
1604 {
1605 int fd;
1606 struct stat sb;
1607 int orig_len;
1608 int total;
1609 const char *filename_c;
1610
1611 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1612
1613 filename_c = _dbus_string_get_const_data (filename);
1614
1615 /* O_BINARY useful on Cygwin */
1616 fd = open (filename_c, O_RDONLY | O_BINARY);
1617 if (fd < 0)
1618 {
1619 dbus_set_error (error, _dbus_error_from_errno (errno),
1620 "Failed to open \"%s\": %s",
1621 filename_c,
1622 _dbus_strerror (errno));
1623 return FALSE;
1624 }
1625
1626 if (fstat (fd, &sb) < 0)
1627 {
1628 dbus_set_error (error, _dbus_error_from_errno (errno),
1629 "Failed to stat \"%s\": %s",
1630 filename_c,
1631 _dbus_strerror (errno));
1632
1633 _dbus_verbose ("fstat() failed: %s",
1634 _dbus_strerror (errno));
1635
1636 _dbus_close (fd, NULL);
1637
1638 return FALSE;
1639 }
1640
1641 if (sb.st_size > _DBUS_ONE_MEGABYTE)
1642 {
1643 dbus_set_error (error, DBUS_ERROR_FAILED,
1644 "File size %lu of \"%s\" is too large.",
1645 (unsigned long) sb.st_size, filename_c);
1646 _dbus_close (fd, NULL);
1647 return FALSE;
1648 }
1649
1650 total = 0;
1651 orig_len = _dbus_string_get_length (str);
1652 if (sb.st_size > 0 && S_ISREG (sb.st_mode))
1653 {
1654 int bytes_read;
1655
1656 while (total < (int) sb.st_size)
1657 {
1658 bytes_read = _dbus_read (fd, str,
1659 sb.st_size - total);
1660 if (bytes_read <= 0)
1661 {
1662 dbus_set_error (error, _dbus_error_from_errno (errno),
1663 "Error reading \"%s\": %s",
1664 filename_c,
1665 _dbus_strerror (errno));
1666
1667 _dbus_verbose ("read() failed: %s",
1668 _dbus_strerror (errno));
1669
1670 _dbus_close (fd, NULL);
1671 _dbus_string_set_length (str, orig_len);
1672 return FALSE;
1673 }
1674 else
1675 total += bytes_read;
1676 }
1677
1678 _dbus_close (fd, NULL);
1679 return TRUE;
1680 }
1681 else if (sb.st_size != 0)
1682 {
1683 _dbus_verbose ("Can only open regular files at the moment.\n");
1684 dbus_set_error (error, DBUS_ERROR_FAILED,
1685 "\"%s\" is not a regular file",
1686 filename_c);
1687 _dbus_close (fd, NULL);
1688 return FALSE;
1689 }
1690 else
1691 {
1692 _dbus_close (fd, NULL);
1693 return TRUE;
1694 }
1695 }
1696
1697 /**
1698 * Writes a string out to a file. If the file exists,
1699 * it will be atomically overwritten by the new data.
1700 *
1701 * @param str the string to write out
1702 * @param filename the file to save string to
1703 * @param error error to be filled in on failure
1704 * @returns #FALSE on failure
1705 */
1706 dbus_bool_t
_dbus_string_save_to_file(const DBusString * str,const DBusString * filename,DBusError * error)1707 _dbus_string_save_to_file (const DBusString *str,
1708 const DBusString *filename,
1709 DBusError *error)
1710 {
1711 int fd;
1712 int bytes_to_write;
1713 const char *filename_c;
1714 DBusString tmp_filename;
1715 const char *tmp_filename_c;
1716 int total;
1717 dbus_bool_t need_unlink;
1718 dbus_bool_t retval;
1719
1720 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1721
1722 fd = -1;
1723 retval = FALSE;
1724 need_unlink = FALSE;
1725
1726 if (!_dbus_string_init (&tmp_filename))
1727 {
1728 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1729 return FALSE;
1730 }
1731
1732 if (!_dbus_string_copy (filename, 0, &tmp_filename, 0))
1733 {
1734 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1735 _dbus_string_free (&tmp_filename);
1736 return FALSE;
1737 }
1738
1739 if (!_dbus_string_append (&tmp_filename, "."))
1740 {
1741 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1742 _dbus_string_free (&tmp_filename);
1743 return FALSE;
1744 }
1745
1746 #define N_TMP_FILENAME_RANDOM_BYTES 8
1747 if (!_dbus_generate_random_ascii (&tmp_filename, N_TMP_FILENAME_RANDOM_BYTES))
1748 {
1749 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1750 _dbus_string_free (&tmp_filename);
1751 return FALSE;
1752 }
1753
1754 filename_c = _dbus_string_get_const_data (filename);
1755 tmp_filename_c = _dbus_string_get_const_data (&tmp_filename);
1756
1757 fd = open (tmp_filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
1758 0600);
1759 if (fd < 0)
1760 {
1761 dbus_set_error (error, _dbus_error_from_errno (errno),
1762 "Could not create %s: %s", tmp_filename_c,
1763 _dbus_strerror (errno));
1764 goto out;
1765 }
1766
1767 need_unlink = TRUE;
1768
1769 total = 0;
1770 bytes_to_write = _dbus_string_get_length (str);
1771
1772 while (total < bytes_to_write)
1773 {
1774 int bytes_written;
1775
1776 bytes_written = _dbus_write (fd, str, total,
1777 bytes_to_write - total);
1778
1779 if (bytes_written <= 0)
1780 {
1781 dbus_set_error (error, _dbus_error_from_errno (errno),
1782 "Could not write to %s: %s", tmp_filename_c,
1783 _dbus_strerror (errno));
1784
1785 goto out;
1786 }
1787
1788 total += bytes_written;
1789 }
1790
1791 if (!_dbus_close (fd, NULL))
1792 {
1793 dbus_set_error (error, _dbus_error_from_errno (errno),
1794 "Could not close file %s: %s",
1795 tmp_filename_c, _dbus_strerror (errno));
1796
1797 goto out;
1798 }
1799
1800 fd = -1;
1801
1802 if (rename (tmp_filename_c, filename_c) < 0)
1803 {
1804 dbus_set_error (error, _dbus_error_from_errno (errno),
1805 "Could not rename %s to %s: %s",
1806 tmp_filename_c, filename_c,
1807 _dbus_strerror (errno));
1808
1809 goto out;
1810 }
1811
1812 need_unlink = FALSE;
1813
1814 retval = TRUE;
1815
1816 out:
1817 /* close first, then unlink, to prevent ".nfs34234235" garbage
1818 * files
1819 */
1820
1821 if (fd >= 0)
1822 _dbus_close (fd, NULL);
1823
1824 if (need_unlink && unlink (tmp_filename_c) < 0)
1825 _dbus_verbose ("Failed to unlink temp file %s: %s\n",
1826 tmp_filename_c, _dbus_strerror (errno));
1827
1828 _dbus_string_free (&tmp_filename);
1829
1830 if (!retval)
1831 _DBUS_ASSERT_ERROR_IS_SET (error);
1832
1833 return retval;
1834 }
1835
1836 /** Makes the file readable by every user in the system.
1837 *
1838 * @param filename the filename
1839 * @param error error location
1840 * @returns #TRUE if the file's permissions could be changed.
1841 */
1842 dbus_bool_t
_dbus_make_file_world_readable(const DBusString * filename,DBusError * error)1843 _dbus_make_file_world_readable(const DBusString *filename,
1844 DBusError *error)
1845 {
1846 const char *filename_c;
1847
1848 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1849
1850 filename_c = _dbus_string_get_const_data (filename);
1851 if (chmod (filename_c, 0644) == -1)
1852 {
1853 dbus_set_error (error,
1854 DBUS_ERROR_FAILED,
1855 "Could not change permissions of file %s: %s\n",
1856 filename_c,
1857 _dbus_strerror (errno));
1858 return FALSE;
1859 }
1860 return TRUE;
1861 }
1862
1863 /** Creates the given file, failing if the file already exists.
1864 *
1865 * @param filename the filename
1866 * @param error error location
1867 * @returns #TRUE if we created the file and it didn't exist
1868 */
1869 dbus_bool_t
_dbus_create_file_exclusively(const DBusString * filename,DBusError * error)1870 _dbus_create_file_exclusively (const DBusString *filename,
1871 DBusError *error)
1872 {
1873 int fd;
1874 const char *filename_c;
1875
1876 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1877
1878 filename_c = _dbus_string_get_const_data (filename);
1879
1880 fd = open (filename_c, O_WRONLY | O_BINARY | O_EXCL | O_CREAT,
1881 0600);
1882 if (fd < 0)
1883 {
1884 dbus_set_error (error,
1885 DBUS_ERROR_FAILED,
1886 "Could not create file %s: %s\n",
1887 filename_c,
1888 _dbus_strerror (errno));
1889 return FALSE;
1890 }
1891
1892 if (!_dbus_close (fd, NULL))
1893 {
1894 dbus_set_error (error,
1895 DBUS_ERROR_FAILED,
1896 "Could not close file %s: %s\n",
1897 filename_c,
1898 _dbus_strerror (errno));
1899 return FALSE;
1900 }
1901
1902 return TRUE;
1903 }
1904
1905 /**
1906 * Deletes the given file.
1907 *
1908 * @param filename the filename
1909 * @param error error location
1910 *
1911 * @returns #TRUE if unlink() succeeded
1912 */
1913 dbus_bool_t
_dbus_delete_file(const DBusString * filename,DBusError * error)1914 _dbus_delete_file (const DBusString *filename,
1915 DBusError *error)
1916 {
1917 const char *filename_c;
1918
1919 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1920
1921 filename_c = _dbus_string_get_const_data (filename);
1922
1923 if (unlink (filename_c) < 0)
1924 {
1925 dbus_set_error (error, DBUS_ERROR_FAILED,
1926 "Failed to delete file %s: %s\n",
1927 filename_c, _dbus_strerror (errno));
1928 return FALSE;
1929 }
1930 else
1931 return TRUE;
1932 }
1933
1934 /**
1935 * Creates a directory; succeeds if the directory
1936 * is created or already existed.
1937 *
1938 * @param filename directory filename
1939 * @param error initialized error object
1940 * @returns #TRUE on success
1941 */
1942 dbus_bool_t
_dbus_create_directory(const DBusString * filename,DBusError * error)1943 _dbus_create_directory (const DBusString *filename,
1944 DBusError *error)
1945 {
1946 const char *filename_c;
1947
1948 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1949
1950 filename_c = _dbus_string_get_const_data (filename);
1951
1952 if (mkdir (filename_c, 0700) < 0)
1953 {
1954 if (errno == EEXIST)
1955 return TRUE;
1956
1957 dbus_set_error (error, DBUS_ERROR_FAILED,
1958 "Failed to create directory %s: %s\n",
1959 filename_c, _dbus_strerror (errno));
1960 return FALSE;
1961 }
1962 else
1963 return TRUE;
1964 }
1965
1966 /**
1967 * Appends the given filename to the given directory.
1968 *
1969 * @todo it might be cute to collapse multiple '/' such as "foo//"
1970 * concat "//bar"
1971 *
1972 * @param dir the directory name
1973 * @param next_component the filename
1974 * @returns #TRUE on success
1975 */
1976 dbus_bool_t
_dbus_concat_dir_and_file(DBusString * dir,const DBusString * next_component)1977 _dbus_concat_dir_and_file (DBusString *dir,
1978 const DBusString *next_component)
1979 {
1980 dbus_bool_t dir_ends_in_slash;
1981 dbus_bool_t file_starts_with_slash;
1982
1983 if (_dbus_string_get_length (dir) == 0 ||
1984 _dbus_string_get_length (next_component) == 0)
1985 return TRUE;
1986
1987 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
1988 _dbus_string_get_length (dir) - 1);
1989
1990 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
1991
1992 if (dir_ends_in_slash && file_starts_with_slash)
1993 {
1994 _dbus_string_shorten (dir, 1);
1995 }
1996 else if (!(dir_ends_in_slash || file_starts_with_slash))
1997 {
1998 if (!_dbus_string_append_byte (dir, '/'))
1999 return FALSE;
2000 }
2001
2002 return _dbus_string_copy (next_component, 0, dir,
2003 _dbus_string_get_length (dir));
2004 }
2005
2006 /** nanoseconds in a second */
2007 #define NANOSECONDS_PER_SECOND 1000000000
2008 /** microseconds in a second */
2009 #define MICROSECONDS_PER_SECOND 1000000
2010 /** milliseconds in a second */
2011 #define MILLISECONDS_PER_SECOND 1000
2012 /** nanoseconds in a millisecond */
2013 #define NANOSECONDS_PER_MILLISECOND 1000000
2014 /** microseconds in a millisecond */
2015 #define MICROSECONDS_PER_MILLISECOND 1000
2016
2017 /**
2018 * Sleeps the given number of milliseconds.
2019 * @param milliseconds number of milliseconds
2020 */
2021 void
_dbus_sleep_milliseconds(int milliseconds)2022 _dbus_sleep_milliseconds (int milliseconds)
2023 {
2024 #ifdef HAVE_NANOSLEEP
2025 struct timespec req;
2026 struct timespec rem;
2027
2028 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2029 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2030 rem.tv_sec = 0;
2031 rem.tv_nsec = 0;
2032
2033 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2034 req = rem;
2035 #elif defined (HAVE_USLEEP)
2036 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2037 #else /* ! HAVE_USLEEP */
2038 sleep (MAX (milliseconds / 1000, 1));
2039 #endif
2040 }
2041
2042 static dbus_bool_t
_dbus_generate_pseudorandom_bytes(DBusString * str,int n_bytes)2043 _dbus_generate_pseudorandom_bytes (DBusString *str,
2044 int n_bytes)
2045 {
2046 int old_len;
2047 char *p;
2048
2049 old_len = _dbus_string_get_length (str);
2050
2051 if (!_dbus_string_lengthen (str, n_bytes))
2052 return FALSE;
2053
2054 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2055
2056 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2057
2058 return TRUE;
2059 }
2060
2061 /**
2062 * Generates the given number of random bytes,
2063 * using the best mechanism we can come up with.
2064 *
2065 * @param str the string
2066 * @param n_bytes the number of random bytes to append to string
2067 * @returns #TRUE on success, #FALSE if no memory
2068 */
2069 dbus_bool_t
_dbus_generate_random_bytes(DBusString * str,int n_bytes)2070 _dbus_generate_random_bytes (DBusString *str,
2071 int n_bytes)
2072 {
2073 int old_len;
2074 int fd;
2075
2076 /* FALSE return means "no memory", if it could
2077 * mean something else then we'd need to return
2078 * a DBusError. So we always fall back to pseudorandom
2079 * if the I/O fails.
2080 */
2081
2082 old_len = _dbus_string_get_length (str);
2083 fd = -1;
2084
2085 /* note, urandom on linux will fall back to pseudorandom */
2086 fd = open ("/dev/urandom", O_RDONLY);
2087 if (fd < 0)
2088 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2089
2090 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2091 {
2092 _dbus_close (fd, NULL);
2093 _dbus_string_set_length (str, old_len);
2094 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2095 }
2096
2097 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2098 n_bytes);
2099
2100 _dbus_close (fd, NULL);
2101
2102 return TRUE;
2103 }
2104
2105 /**
2106 * Exit the process, returning the given value.
2107 *
2108 * @param code the exit code
2109 */
2110 void
_dbus_exit(int code)2111 _dbus_exit (int code)
2112 {
2113 _exit (code);
2114 }
2115
2116 /**
2117 * A wrapper around strerror() because some platforms
2118 * may be lame and not have strerror().
2119 *
2120 * @param error_number errno.
2121 * @returns error description.
2122 */
2123 const char*
_dbus_strerror(int error_number)2124 _dbus_strerror (int error_number)
2125 {
2126 const char *msg;
2127
2128 msg = strerror (error_number);
2129 if (msg == NULL)
2130 msg = "unknown";
2131
2132 return msg;
2133 }
2134
2135 /**
2136 * signal (SIGPIPE, SIG_IGN);
2137 */
2138 void
_dbus_disable_sigpipe(void)2139 _dbus_disable_sigpipe (void)
2140 {
2141 signal (SIGPIPE, SIG_IGN);
2142 }
2143
2144 /**
2145 * Sets the file descriptor to be close
2146 * on exec. Should be called for all file
2147 * descriptors in D-Bus code.
2148 *
2149 * @param fd the file descriptor
2150 */
2151 void
_dbus_fd_set_close_on_exec(int fd)2152 _dbus_fd_set_close_on_exec (int fd)
2153 {
2154 int val;
2155
2156 val = fcntl (fd, F_GETFD, 0);
2157
2158 if (val < 0)
2159 return;
2160
2161 val |= FD_CLOEXEC;
2162
2163 fcntl (fd, F_SETFD, val);
2164 }
2165
2166 /**
2167 * Closes a file descriptor.
2168 *
2169 * @param fd the file descriptor
2170 * @param error error object
2171 * @returns #FALSE if error set
2172 */
2173 dbus_bool_t
_dbus_close(int fd,DBusError * error)2174 _dbus_close (int fd,
2175 DBusError *error)
2176 {
2177 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2178
2179 again:
2180 if (close (fd) < 0)
2181 {
2182 if (errno == EINTR)
2183 goto again;
2184
2185 dbus_set_error (error, _dbus_error_from_errno (errno),
2186 "Could not close fd %d", fd);
2187 return FALSE;
2188 }
2189
2190 return TRUE;
2191 }
2192
2193 /**
2194 * Sets a file descriptor to be nonblocking.
2195 *
2196 * @param fd the file descriptor.
2197 * @param error address of error location.
2198 * @returns #TRUE on success.
2199 */
2200 dbus_bool_t
_dbus_set_fd_nonblocking(int fd,DBusError * error)2201 _dbus_set_fd_nonblocking (int fd,
2202 DBusError *error)
2203 {
2204 int val;
2205
2206 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2207
2208 val = fcntl (fd, F_GETFL, 0);
2209 if (val < 0)
2210 {
2211 dbus_set_error (error, _dbus_error_from_errno (errno),
2212 "Failed to get flags from file descriptor %d: %s",
2213 fd, _dbus_strerror (errno));
2214 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2215 _dbus_strerror (errno));
2216 return FALSE;
2217 }
2218
2219 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2220 {
2221 dbus_set_error (error, _dbus_error_from_errno (errno),
2222 "Failed to set nonblocking flag of file descriptor %d: %s",
2223 fd, _dbus_strerror (errno));
2224 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2225 fd, _dbus_strerror (errno));
2226
2227 return FALSE;
2228 }
2229
2230 return TRUE;
2231 }
2232
2233 /**
2234 * On GNU libc systems, print a crude backtrace to stderr. On other
2235 * systems, print "no backtrace support" and block for possible gdb
2236 * attachment if an appropriate environment variable is set.
2237 */
2238 void
_dbus_print_backtrace(void)2239 _dbus_print_backtrace (void)
2240 {
2241 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2242 void *bt[500];
2243 int bt_size;
2244 int i;
2245 char **syms;
2246
2247 bt_size = backtrace (bt, 500);
2248
2249 syms = backtrace_symbols (bt, bt_size);
2250
2251 i = 0;
2252 while (i < bt_size)
2253 {
2254 /* don't use dbus_warn since it can _dbus_abort() */
2255 fprintf (stderr, " %s\n", syms[i]);
2256 ++i;
2257 }
2258 fflush (stderr);
2259
2260 free (syms);
2261 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2262 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2263 #else
2264 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2265 #endif
2266 }
2267
2268 /**
2269 * Creates a full-duplex pipe (as in socketpair()).
2270 * Sets both ends of the pipe nonblocking.
2271 *
2272 * @todo libdbus only uses this for the debug-pipe server, so in
2273 * principle it could be in dbus-sysdeps-util.c, except that
2274 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2275 * debug-pipe server is used.
2276 *
2277 * @param fd1 return location for one end
2278 * @param fd2 return location for the other end
2279 * @param blocking #TRUE if pipe should be blocking
2280 * @param error error return
2281 * @returns #FALSE on failure (if error is set)
2282 */
2283 dbus_bool_t
_dbus_full_duplex_pipe(int * fd1,int * fd2,dbus_bool_t blocking,DBusError * error)2284 _dbus_full_duplex_pipe (int *fd1,
2285 int *fd2,
2286 dbus_bool_t blocking,
2287 DBusError *error)
2288 {
2289 #ifdef HAVE_SOCKETPAIR
2290 int fds[2];
2291
2292 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2293
2294 if (socketpair (AF_UNIX, SOCK_STREAM, 0, fds) < 0)
2295 {
2296 dbus_set_error (error, _dbus_error_from_errno (errno),
2297 "Could not create full-duplex pipe");
2298 return FALSE;
2299 }
2300
2301 if (!blocking &&
2302 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2303 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2304 {
2305 dbus_set_error (error, _dbus_error_from_errno (errno),
2306 "Could not set full-duplex pipe nonblocking");
2307
2308 _dbus_close (fds[0], NULL);
2309 _dbus_close (fds[1], NULL);
2310
2311 return FALSE;
2312 }
2313
2314 *fd1 = fds[0];
2315 *fd2 = fds[1];
2316
2317 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2318 *fd1, *fd2);
2319
2320 return TRUE;
2321 #else
2322 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2323 dbus_set_error (error, DBUS_ERROR_FAILED,
2324 "_dbus_full_duplex_pipe() not implemented on this OS");
2325 return FALSE;
2326 #endif
2327 }
2328
2329
2330 /**
2331 * Measure the length of the given format string and arguments,
2332 * not including the terminating nul.
2333 *
2334 * @param format a printf-style format string
2335 * @param args arguments for the format string
2336 * @returns length of the given format string and args
2337 */
2338 int
_dbus_printf_string_upper_bound(const char * format,va_list args)2339 _dbus_printf_string_upper_bound (const char *format,
2340 va_list args)
2341 {
2342 char c;
2343 return vsnprintf (&c, 1, format, args);
2344 }
2345
2346 /**
2347 * Gets the temporary files directory by inspecting the environment variables
2348 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2349 *
2350 * @returns location of temp directory
2351 */
2352 const char*
_dbus_get_tmpdir(void)2353 _dbus_get_tmpdir(void)
2354 {
2355 static const char* tmpdir = NULL;
2356
2357 if (tmpdir == NULL)
2358 {
2359 /* TMPDIR is what glibc uses, then
2360 * glibc falls back to the P_tmpdir macro which
2361 * just expands to "/tmp"
2362 */
2363 if (tmpdir == NULL)
2364 tmpdir = getenv("TMPDIR");
2365
2366 /* These two env variables are probably
2367 * broken, but maybe some OS uses them?
2368 */
2369 if (tmpdir == NULL)
2370 tmpdir = getenv("TMP");
2371 if (tmpdir == NULL)
2372 tmpdir = getenv("TEMP");
2373
2374 /* And this is the sane fallback. */
2375 if (tmpdir == NULL)
2376 tmpdir = "/tmp";
2377 }
2378
2379 _dbus_assert(tmpdir != NULL);
2380
2381 return tmpdir;
2382 }
2383
2384 /**
2385 * Determines the address of the session bus by querying a
2386 * platform-specific method.
2387 *
2388 * If successful, returns #TRUE and appends the address to @p
2389 * address. If a failure happens, returns #FALSE and
2390 * sets an error in @p error.
2391 *
2392 * @param address a DBusString where the address can be stored
2393 * @param error a DBusError to store the error in case of failure
2394 * @returns #TRUE on success, #FALSE if an error happened
2395 */
2396 dbus_bool_t
_dbus_get_autolaunch_address(DBusString * address,DBusError * error)2397 _dbus_get_autolaunch_address (DBusString *address,
2398 DBusError *error)
2399 {
2400 static char *argv[5];
2401 int address_pipe[2];
2402 pid_t pid;
2403 int ret;
2404 int status;
2405 int orig_len;
2406 int i;
2407 DBusString uuid;
2408 dbus_bool_t retval;
2409
2410 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2411 retval = FALSE;
2412
2413 _dbus_string_init (&uuid);
2414
2415 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
2416 {
2417 _DBUS_SET_OOM (error);
2418 goto out;
2419 }
2420
2421 i = 0;
2422 argv[i] = "dbus-launch";
2423 ++i;
2424 argv[i] = "--autolaunch";
2425 ++i;
2426 argv[i] = _dbus_string_get_data (&uuid);
2427 ++i;
2428 argv[i] = "--binary-syntax";
2429 ++i;
2430 argv[i] = NULL;
2431 ++i;
2432
2433 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
2434
2435 orig_len = _dbus_string_get_length (address);
2436
2437 #define READ_END 0
2438 #define WRITE_END 1
2439 if (pipe (address_pipe) < 0)
2440 {
2441 dbus_set_error (error, _dbus_error_from_errno (errno),
2442 "Failed to create a pipe: %s",
2443 _dbus_strerror (errno));
2444 _dbus_verbose ("Failed to create a pipe to call dbus-launch: %s\n",
2445 _dbus_strerror (errno));
2446 goto out;
2447 }
2448
2449 pid = fork ();
2450 if (pid < 0)
2451 {
2452 dbus_set_error (error, _dbus_error_from_errno (errno),
2453 "Failed to fork(): %s",
2454 _dbus_strerror (errno));
2455 _dbus_verbose ("Failed to fork() to call dbus-launch: %s\n",
2456 _dbus_strerror (errno));
2457 goto out;
2458 }
2459
2460 if (pid == 0)
2461 {
2462 /* child process */
2463 int fd = open ("/dev/null", O_RDWR);
2464 if (fd == -1)
2465 /* huh?! can't open /dev/null? */
2466 _exit (1);
2467
2468 /* set-up stdXXX */
2469 close (address_pipe[READ_END]);
2470 close (0); /* close stdin */
2471 close (1); /* close stdout */
2472 close (2); /* close stderr */
2473
2474 if (dup2 (fd, 0) == -1)
2475 _exit (1);
2476 if (dup2 (address_pipe[WRITE_END], 1) == -1)
2477 _exit (1);
2478 if (dup2 (fd, 2) == -1)
2479 _exit (1);
2480
2481 close (fd);
2482 close (address_pipe[WRITE_END]);
2483
2484 execv (DBUS_BINDIR "/dbus-launch", argv);
2485
2486 /* failed, try searching PATH */
2487 execvp ("dbus-launch", argv);
2488
2489 /* still nothing, we failed */
2490 _exit (1);
2491 }
2492
2493 /* parent process */
2494 close (address_pipe[WRITE_END]);
2495 ret = 0;
2496 do
2497 {
2498 ret = _dbus_read (address_pipe[READ_END], address, 1024);
2499 }
2500 while (ret > 0);
2501
2502 /* reap the child process to avoid it lingering as zombie */
2503 do
2504 {
2505 ret = waitpid (pid, &status, 0);
2506 }
2507 while (ret == -1 && errno == EINTR);
2508
2509 /* We succeeded if the process exited with status 0 and
2510 anything was read */
2511 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 ||
2512 _dbus_string_get_length (address) == orig_len)
2513 {
2514 /* The process ended with error */
2515 _dbus_string_set_length (address, orig_len);
2516 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
2517 "Failed to execute dbus-launch to autolaunch D-Bus session");
2518 goto out;
2519 }
2520
2521 retval = TRUE;
2522
2523 out:
2524 if (retval)
2525 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2526 else
2527 _DBUS_ASSERT_ERROR_IS_SET (error);
2528
2529 _dbus_string_free (&uuid);
2530 return retval;
2531 }
2532
2533 /**
2534 * Reads the uuid of the machine we're running on from
2535 * the dbus configuration. Optionally try to create it
2536 * (only root can do this usually).
2537 *
2538 * On UNIX, reads a file that gets created by dbus-uuidgen
2539 * in a post-install script. On Windows, if there's a standard
2540 * machine uuid we could just use that, but I can't find one
2541 * with the right properties (the hardware profile guid can change
2542 * without rebooting I believe). If there's no standard one
2543 * we might want to use the registry instead of a file for
2544 * this, and I'm not sure how we'd ensure the uuid gets created.
2545 *
2546 * @param machine_id guid to init with the machine's uuid
2547 * @param create_if_not_found try to create the uuid if it doesn't exist
2548 * @param error the error return
2549 * @returns #FALSE if the error is set
2550 */
2551 dbus_bool_t
_dbus_read_local_machine_uuid(DBusGUID * machine_id,dbus_bool_t create_if_not_found,DBusError * error)2552 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
2553 dbus_bool_t create_if_not_found,
2554 DBusError *error)
2555 {
2556 DBusString filename;
2557 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
2558 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
2559 }
2560
2561 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
2562
2563 static dbus_bool_t
split_paths_and_append(DBusString * dirs,const char * suffix,DBusList ** dir_list)2564 split_paths_and_append (DBusString *dirs,
2565 const char *suffix,
2566 DBusList **dir_list)
2567 {
2568 /* split on colon (:) */
2569 int start;
2570 int i;
2571 int len;
2572 char *cpath;
2573 const DBusString file_suffix;
2574
2575 start = 0;
2576 i = 0;
2577
2578 _dbus_string_init_const (&file_suffix, suffix);
2579
2580 len = _dbus_string_get_length (dirs);
2581
2582 while (_dbus_string_find (dirs, start, ":", &i))
2583 {
2584 DBusString path;
2585
2586 if (!_dbus_string_init (&path))
2587 goto oom;
2588
2589 if (!_dbus_string_copy_len (dirs,
2590 start,
2591 i - start,
2592 &path,
2593 0))
2594 {
2595 _dbus_string_free (&path);
2596 goto oom;
2597 }
2598
2599 _dbus_string_chop_white (&path);
2600
2601 /* check for an empty path */
2602 if (_dbus_string_get_length (&path) == 0)
2603 goto next;
2604
2605 if (!_dbus_concat_dir_and_file (&path,
2606 &file_suffix))
2607 {
2608 _dbus_string_free (&path);
2609 goto oom;
2610 }
2611
2612 if (!_dbus_string_copy_data(&path, &cpath))
2613 {
2614 _dbus_string_free (&path);
2615 goto oom;
2616 }
2617
2618 if (!_dbus_list_append (dir_list, cpath))
2619 {
2620 _dbus_string_free (&path);
2621 dbus_free (cpath);
2622 goto oom;
2623 }
2624
2625 next:
2626 _dbus_string_free (&path);
2627 start = i + 1;
2628 }
2629
2630 if (start != len)
2631 {
2632 DBusString path;
2633
2634 if (!_dbus_string_init (&path))
2635 goto oom;
2636
2637 if (!_dbus_string_copy_len (dirs,
2638 start,
2639 len - start,
2640 &path,
2641 0))
2642 {
2643 _dbus_string_free (&path);
2644 goto oom;
2645 }
2646
2647 if (!_dbus_concat_dir_and_file (&path,
2648 &file_suffix))
2649 {
2650 _dbus_string_free (&path);
2651 goto oom;
2652 }
2653
2654 if (!_dbus_string_copy_data(&path, &cpath))
2655 {
2656 _dbus_string_free (&path);
2657 goto oom;
2658 }
2659
2660 if (!_dbus_list_append (dir_list, cpath))
2661 {
2662 _dbus_string_free (&path);
2663 dbus_free (cpath);
2664 goto oom;
2665 }
2666
2667 _dbus_string_free (&path);
2668 }
2669
2670 return TRUE;
2671
2672 oom:
2673 _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL);
2674 _dbus_list_clear (dir_list);
2675 return FALSE;
2676 }
2677
2678 /**
2679 * Returns the standard directories for a session bus to look for service
2680 * activation files
2681 *
2682 * On UNIX this should be the standard xdg freedesktop.org data directories:
2683 *
2684 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
2685 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
2686 *
2687 * and
2688 *
2689 * DBUS_DATADIR
2690 *
2691 * @param dirs the directory list we are returning
2692 * @returns #FALSE on OOM
2693 */
2694
2695 dbus_bool_t
_dbus_get_standard_session_servicedirs(DBusList ** dirs)2696 _dbus_get_standard_session_servicedirs (DBusList **dirs)
2697 {
2698 const char *xdg_data_home;
2699 const char *xdg_data_dirs;
2700 DBusString servicedir_path;
2701
2702 if (!_dbus_string_init (&servicedir_path))
2703 return FALSE;
2704
2705 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
2706 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
2707
2708 if (xdg_data_dirs != NULL)
2709 {
2710 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
2711 goto oom;
2712
2713 if (!_dbus_string_append (&servicedir_path, ":"))
2714 goto oom;
2715 }
2716 else
2717 {
2718 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
2719 goto oom;
2720 }
2721
2722 /*
2723 * add configured datadir to defaults
2724 * this may be the same as an xdg dir
2725 * however the config parser should take
2726 * care of duplicates
2727 */
2728 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
2729 goto oom;
2730
2731 if (xdg_data_home != NULL)
2732 {
2733 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
2734 goto oom;
2735 }
2736 else
2737 {
2738 const DBusString *homedir;
2739 const DBusString local_share;
2740
2741 if (!_dbus_homedir_from_current_process (&homedir))
2742 goto oom;
2743
2744 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
2745 goto oom;
2746
2747 _dbus_string_init_const (&local_share, "/.local/share");
2748 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
2749 goto oom;
2750 }
2751
2752 if (!split_paths_and_append (&servicedir_path,
2753 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
2754 dirs))
2755 goto oom;
2756
2757 _dbus_string_free (&servicedir_path);
2758 return TRUE;
2759
2760 oom:
2761 _dbus_string_free (&servicedir_path);
2762 return FALSE;
2763 }
2764
2765 /* tests in dbus-sysdeps-util.c */
2766