D-Bus  1.14.99
dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-file.h"
33 #include "dbus-transport.h"
34 #include "dbus-string.h"
35 #include "dbus-userdb.h"
36 #include "dbus-list.h"
37 #include "dbus-credentials.h"
38 #include "dbus-nonce.h"
39 
40 #include <limits.h>
41 #include <sys/types.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <signal.h>
45 #include <unistd.h>
46 #include <stdio.h>
47 #include <fcntl.h>
48 #include <sys/socket.h>
49 #include <dirent.h>
50 #include <sys/un.h>
51 #include <pwd.h>
52 #include <time.h>
53 #include <locale.h>
54 #include <sys/time.h>
55 #include <sys/stat.h>
56 #include <sys/wait.h>
57 #include <netinet/in.h>
58 #include <netinet/tcp.h>
59 #include <netdb.h>
60 #include <grp.h>
61 #include <arpa/inet.h>
62 
63 #ifdef HAVE_ERRNO_H
64 #include <errno.h>
65 #endif
66 #ifdef HAVE_LINUX_CLOSE_RANGE_H
67 #include <linux/close_range.h>
68 #endif
69 #ifdef HAVE_SYSLOG_H
70 #include <syslog.h>
71 #endif
72 #ifdef HAVE_WRITEV
73 #include <sys/uio.h>
74 #endif
75 #ifdef HAVE_BACKTRACE
76 #include <execinfo.h>
77 #endif
78 #ifdef HAVE_GETPEERUCRED
79 #include <ucred.h>
80 #endif
81 #ifdef HAVE_ALLOCA_H
82 #include <alloca.h>
83 #endif
84 #ifdef HAVE_SYS_RANDOM_H
85 #include <sys/random.h>
86 #endif
87 #ifdef HAVE_SYS_SYSCALL_H
88 #include <sys/syscall.h>
89 #endif
90 
91 #ifdef HAVE_ADT
92 #include <bsm/adt.h>
93 #endif
94 
95 #ifdef HAVE_SYSTEMD
96 #include <systemd/sd-daemon.h>
97 #endif
98 
99 #if !DBUS_USE_SYNC
100 #include <pthread.h>
101 #endif
102 
103 #ifndef O_BINARY
104 #define O_BINARY 0
105 #endif
106 
107 #ifndef AI_ADDRCONFIG
108 #define AI_ADDRCONFIG 0
109 #endif
110 
111 #ifndef HAVE_SOCKLEN_T
112 #define socklen_t int
113 #endif
114 
115 #if defined (__sun) || defined (__sun__)
116 /*
117  * CMS_SPACE etc. definitions for Solaris < 10, based on
118  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
119  * via
120  * http://wiki.opencsw.org/porting-faq#toc10
121  *
122  * These are only redefined for Solaris, for now: if your OS needs these too,
123  * please file a bug. (Or preferably, improve your OS so they're not needed.)
124  */
125 
126 # ifndef CMSG_ALIGN
127 # ifdef __sun__
128 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
129 # else
130  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
131 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
132  ~(sizeof (long) - 1))
133 # endif
134 # endif
135 
136 # ifndef CMSG_SPACE
137 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
138  CMSG_ALIGN (len))
139 # endif
140 
141 # ifndef CMSG_LEN
142 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
143 # endif
144 
145 #endif /* Solaris */
146 
147 #if defined(__linux__) && defined(__NR_close_range) && !defined(HAVE_CLOSE_RANGE)
148 /* The kernel headers are new enough to have the close_range syscall,
149  * but glibc isn't new enough to have the syscall wrapper, so call the
150  * syscall directly. */
151 static inline int
152 close_range (unsigned int first,
153  unsigned int last,
154  unsigned int flags)
155 {
156  return syscall (__NR_close_range, first, last, flags);
157 }
158 /* Now we can call that inline wrapper as though it was provided by glibc. */
159 #define HAVE_CLOSE_RANGE
160 #endif
161 
177 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
178  const char **error_str_p)
179 {
180  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
181  DBUS_FORCE_STDOUT_NULL,
182  DBUS_FORCE_STDERR_NULL };
183  /* Should always get replaced with the real error before use */
184  const char *error_str = "Failed mysteriously";
185  int devnull = -1;
186  int saved_errno;
187  /* This function relies on the standard fds having their POSIX values. */
188  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
189  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
190  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
191  int i;
192 
193  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
194  {
195  /* Because we rely on being single-threaded, and we want the
196  * standard fds to not be close-on-exec, we don't set it
197  * close-on-exec. */
198  if (devnull < i)
199  devnull = open ("/dev/null", O_RDWR);
200 
201  if (devnull < 0)
202  {
203  error_str = "Failed to open /dev/null";
204  goto out;
205  }
206 
207  /* We already opened all fds < i, so the only way this assertion
208  * could fail is if another thread closed one, and we document
209  * this function as not safe for multi-threading. */
210  _dbus_assert (devnull >= i);
211 
212  if (devnull != i && (flags & relevant_flag[i]) != 0)
213  {
214  if (dup2 (devnull, i) < 0)
215  {
216  error_str = "Failed to dup2 /dev/null onto a standard fd";
217  goto out;
218  }
219  }
220  }
221 
222  error_str = NULL;
223 
224 out:
225  saved_errno = errno;
226 
227  if (devnull > STDERR_FILENO)
228  close (devnull);
229 
230  if (error_str_p != NULL)
231  *error_str_p = error_str;
232 
233  errno = saved_errno;
234  return (error_str == NULL);
235 }
236 
237 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
238  DBusError *error);
239 
240 static dbus_bool_t
241 _dbus_open_socket (int *fd_p,
242  int domain,
243  int type,
244  int protocol,
245  DBusError *error)
246 {
247 #ifdef SOCK_CLOEXEC
248  dbus_bool_t cloexec_done;
249 
250  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
251  cloexec_done = *fd_p >= 0;
252 
253  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
254  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
255 #endif
256  {
257  *fd_p = socket (domain, type, protocol);
258  }
259 
260  if (*fd_p >= 0)
261  {
262 #ifdef SOCK_CLOEXEC
263  if (!cloexec_done)
264 #endif
265  {
267  }
268 
269  _dbus_verbose ("socket fd %d opened\n", *fd_p);
270  return TRUE;
271  }
272  else
273  {
274  dbus_set_error(error,
275  _dbus_error_from_errno (errno),
276  "Failed to open socket: %s",
277  _dbus_strerror (errno));
278  return FALSE;
279  }
280 }
281 
292 static dbus_bool_t
293 _dbus_open_unix_socket (int *fd,
294  DBusError *error)
295 {
296  return _dbus_open_socket(fd, AF_UNIX, SOCK_STREAM, 0, error);
297 }
298 
313  DBusError *error)
314 {
315  dbus_bool_t rv;
316 
317  _dbus_assert (fd != NULL);
318  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
319 
320  rv = _dbus_close (fd->fd, error);
321  _dbus_socket_invalidate (fd);
322 
323  return rv;
324 }
325 
335 int
337  DBusString *buffer,
338  int count)
339 {
340  return _dbus_read (fd.fd, buffer, count);
341 }
342 
353 int
355  const DBusString *buffer,
356  int start,
357  int len)
358 {
359 #if HAVE_DECL_MSG_NOSIGNAL
360  const char *data;
361  int bytes_written;
362 
363  data = _dbus_string_get_const_data_len (buffer, start, len);
364 
365  again:
366 
367  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
368 
369  if (bytes_written < 0 && errno == EINTR)
370  goto again;
371 
372  return bytes_written;
373 
374 #else
375  return _dbus_write (fd.fd, buffer, start, len);
376 #endif
377 }
378 
391 int
393  DBusString *buffer,
394  int count,
395  int *fds,
396  unsigned int *n_fds) {
397 #ifndef HAVE_UNIX_FD_PASSING
398  int r;
399 
400  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
401  return r;
402 
403  *n_fds = 0;
404  return r;
405 
406 #else
407  int bytes_read;
408  int start;
409  struct msghdr m;
410  struct iovec iov;
411 
412  _dbus_assert (count >= 0);
414 
415  start = _dbus_string_get_length (buffer);
416 
417  if (!_dbus_string_lengthen (buffer, count))
418  {
419  errno = ENOMEM;
420  return -1;
421  }
422 
423  _DBUS_ZERO(iov);
424  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
425  iov.iov_len = count;
426 
427  _DBUS_ZERO(m);
428  m.msg_iov = &iov;
429  m.msg_iovlen = 1;
430 
431  /* Hmm, we have no clue how long the control data will actually be
432  that is queued for us. The least we can do is assume that the
433  caller knows. Hence let's make space for the number of fds that
434  we shall read at max plus the cmsg header. */
435  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
436 
437  /* It's probably safe to assume that systems with SCM_RIGHTS also
438  know alloca() */
439  m.msg_control = alloca(m.msg_controllen);
440  memset(m.msg_control, 0, m.msg_controllen);
441 
442  /* Do not include the padding at the end when we tell the kernel
443  * how much we're willing to receive. This avoids getting
444  * the padding filled with additional fds that we weren't expecting,
445  * if a (potentially malicious) sender included them. (fd.o #83622) */
446  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
447 
448  again:
449 
450  bytes_read = recvmsg (fd.fd, &m, 0
451 #ifdef MSG_CMSG_CLOEXEC
452  |MSG_CMSG_CLOEXEC
453 #endif
454  );
455 
456  if (bytes_read < 0)
457  {
458  if (errno == EINTR)
459  goto again;
460  else
461  {
462  /* put length back (note that this doesn't actually realloc anything) */
463  _dbus_string_set_length (buffer, start);
464  return -1;
465  }
466  }
467  else
468  {
469  struct cmsghdr *cm;
470  dbus_bool_t found = FALSE;
471 
472  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
473  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
474  {
475  size_t i;
476  int *payload = (int *) (void *) CMSG_DATA (cm);
477  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
478  size_t payload_len_fds;
479  size_t fds_to_use;
480 
481  /* Every unsigned int fits in a size_t without truncation, so
482  * casting (size_t) *n_fds is OK */
483  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
484 
485  if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
486  (char *) payload + payload_len_bytes >
487  (char *) m.msg_control + m.msg_controllen)
488  {
489  /* This is the last cmsg in a truncated message and using
490  * cmsg_len would apparently overrun the allocated buffer.
491  * Some operating systems (illumos and Solaris are known) do
492  * not adjust cmsg_len in the last cmsg when truncation occurs.
493  * Adjust the payload length here. The calculation for
494  * payload_len_fds below will discard any trailing bytes that
495  * belong to an incomplete file descriptor - the kernel will
496  * have already closed that (at least for illumos and Solaris)
497  */
498  payload_len_bytes = m.msg_controllen -
499  ((char *) payload - (char *) m.msg_control);
500  }
501 
502  payload_len_fds = payload_len_bytes / sizeof (int);
503 
504  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
505  {
506  /* The fds in the payload will fit in our buffer */
507  fds_to_use = payload_len_fds;
508  }
509  else
510  {
511  /* Too many fds in the payload. This shouldn't happen
512  * any more because we're setting m.msg_controllen to
513  * the exact number we can accept, but be safe and
514  * truncate. */
515  fds_to_use = (size_t) *n_fds;
516 
517  /* Close the excess fds to avoid DoS: if they stayed open,
518  * someone could send us an extra fd per message
519  * and we'd eventually run out. */
520  for (i = fds_to_use; i < payload_len_fds; i++)
521  {
522  close (payload[i]);
523  }
524  }
525 
526  memcpy (fds, payload, fds_to_use * sizeof (int));
527  found = TRUE;
528  /* This narrowing cast from size_t to unsigned int cannot
529  * overflow because we have chosen fds_to_use
530  * to be <= *n_fds */
531  *n_fds = (unsigned int) fds_to_use;
532 
533  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
534  worked, hence we need to go through this list and set
535  CLOEXEC everywhere in any case */
536  for (i = 0; i < fds_to_use; i++)
538 
539  break;
540  }
541 
542  if (!found)
543  *n_fds = 0;
544 
545  if (m.msg_flags & MSG_CTRUNC)
546  {
547  unsigned int i;
548 
549  /* Hmm, apparently the control data was truncated. The bad
550  thing is that we might have completely lost a couple of fds
551  without chance to recover them. Hence let's treat this as a
552  serious error. */
553 
554  /* We still need to close whatever fds we *did* receive,
555  * otherwise they'll never get closed. (CVE-2020-12049) */
556  for (i = 0; i < *n_fds; i++)
557  close (fds[i]);
558 
559  *n_fds = 0;
560  errno = ENOSPC;
561  _dbus_string_set_length (buffer, start);
562  return -1;
563  }
564 
565  /* put length back (doesn't actually realloc) */
566  _dbus_string_set_length (buffer, start + bytes_read);
567 
568 #if 0
569  if (bytes_read > 0)
570  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
571 #endif
572 
573  return bytes_read;
574  }
575 #endif
576 }
577 
578 int
579 _dbus_write_socket_with_unix_fds(DBusSocket fd,
580  const DBusString *buffer,
581  int start,
582  int len,
583  const int *fds,
584  int n_fds) {
585 
586 #ifndef HAVE_UNIX_FD_PASSING
587 
588  if (n_fds > 0) {
589  errno = ENOTSUP;
590  return -1;
591  }
592 
593  return _dbus_write_socket(fd, buffer, start, len);
594 #else
595  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
596 #endif
597 }
598 
599 int
600 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
601  const DBusString *buffer1,
602  int start1,
603  int len1,
604  const DBusString *buffer2,
605  int start2,
606  int len2,
607  const int *fds,
608  int n_fds) {
609 
610 #ifndef HAVE_UNIX_FD_PASSING
611 
612  if (n_fds > 0) {
613  errno = ENOTSUP;
614  return -1;
615  }
616 
617  return _dbus_write_socket_two(fd,
618  buffer1, start1, len1,
619  buffer2, start2, len2);
620 #else
621 
622  struct msghdr m;
623  struct cmsghdr *cm;
624  struct iovec iov[2];
625  int bytes_written;
626 
627  _dbus_assert (len1 >= 0);
628  _dbus_assert (len2 >= 0);
629  _dbus_assert (n_fds >= 0);
630 
631  _DBUS_ZERO(iov);
632  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
633  iov[0].iov_len = len1;
634 
635  if (buffer2)
636  {
637  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
638  iov[1].iov_len = len2;
639  }
640 
641  _DBUS_ZERO(m);
642  m.msg_iov = iov;
643  m.msg_iovlen = buffer2 ? 2 : 1;
644 
645  if (n_fds > 0)
646  {
647  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
648  m.msg_control = alloca(m.msg_controllen);
649  memset(m.msg_control, 0, m.msg_controllen);
650 
651  cm = CMSG_FIRSTHDR(&m);
652  cm->cmsg_level = SOL_SOCKET;
653  cm->cmsg_type = SCM_RIGHTS;
654  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
655  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
656  }
657 
658  again:
659 
660  bytes_written = sendmsg (fd.fd, &m, 0
661 #if HAVE_DECL_MSG_NOSIGNAL
662  |MSG_NOSIGNAL
663 #endif
664  );
665 
666  if (bytes_written < 0 && errno == EINTR)
667  goto again;
668 
669 #if 0
670  if (bytes_written > 0)
671  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
672 #endif
673 
674  return bytes_written;
675 #endif
676 }
677 
691 int
693  const DBusString *buffer1,
694  int start1,
695  int len1,
696  const DBusString *buffer2,
697  int start2,
698  int len2)
699 {
700 #if HAVE_DECL_MSG_NOSIGNAL
701  struct iovec vectors[2];
702  const char *data1;
703  const char *data2;
704  int bytes_written;
705  struct msghdr m;
706 
707  _dbus_assert (buffer1 != NULL);
708  _dbus_assert (start1 >= 0);
709  _dbus_assert (start2 >= 0);
710  _dbus_assert (len1 >= 0);
711  _dbus_assert (len2 >= 0);
712 
713  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
714 
715  if (buffer2 != NULL)
716  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
717  else
718  {
719  data2 = NULL;
720  start2 = 0;
721  len2 = 0;
722  }
723 
724  vectors[0].iov_base = (char*) data1;
725  vectors[0].iov_len = len1;
726  vectors[1].iov_base = (char*) data2;
727  vectors[1].iov_len = len2;
728 
729  _DBUS_ZERO(m);
730  m.msg_iov = vectors;
731  m.msg_iovlen = data2 ? 2 : 1;
732 
733  again:
734 
735  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
736 
737  if (bytes_written < 0 && errno == EINTR)
738  goto again;
739 
740  return bytes_written;
741 
742 #else
743  return _dbus_write_two (fd.fd, buffer1, start1, len1,
744  buffer2, start2, len2);
745 #endif
746 }
747 
764 int
765 _dbus_read (int fd,
766  DBusString *buffer,
767  int count)
768 {
769  int bytes_read;
770  int start;
771  char *data;
772 
773  _dbus_assert (count >= 0);
774 
775  start = _dbus_string_get_length (buffer);
776 
777  if (!_dbus_string_lengthen (buffer, count))
778  {
779  errno = ENOMEM;
780  return -1;
781  }
782 
783  data = _dbus_string_get_data_len (buffer, start, count);
784 
785  again:
786 
787  bytes_read = read (fd, data, count);
788 
789  if (bytes_read < 0)
790  {
791  if (errno == EINTR)
792  goto again;
793  else
794  {
795  /* put length back (note that this doesn't actually realloc anything) */
796  _dbus_string_set_length (buffer, start);
797  return -1;
798  }
799  }
800  else
801  {
802  /* put length back (doesn't actually realloc) */
803  _dbus_string_set_length (buffer, start + bytes_read);
804 
805 #if 0
806  if (bytes_read > 0)
807  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
808 #endif
809 
810  return bytes_read;
811  }
812 }
813 
824 int
825 _dbus_write (int fd,
826  const DBusString *buffer,
827  int start,
828  int len)
829 {
830  const char *data;
831  int bytes_written;
832 
833  data = _dbus_string_get_const_data_len (buffer, start, len);
834 
835  again:
836 
837  bytes_written = write (fd, data, len);
838 
839  if (bytes_written < 0 && errno == EINTR)
840  goto again;
841 
842 #if 0
843  if (bytes_written > 0)
844  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
845 #endif
846 
847  return bytes_written;
848 }
849 
870 int
872  const DBusString *buffer1,
873  int start1,
874  int len1,
875  const DBusString *buffer2,
876  int start2,
877  int len2)
878 {
879  _dbus_assert (buffer1 != NULL);
880  _dbus_assert (start1 >= 0);
881  _dbus_assert (start2 >= 0);
882  _dbus_assert (len1 >= 0);
883  _dbus_assert (len2 >= 0);
884 
885 #ifdef HAVE_WRITEV
886  {
887  struct iovec vectors[2];
888  const char *data1;
889  const char *data2;
890  int bytes_written;
891 
892  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
893 
894  if (buffer2 != NULL)
895  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
896  else
897  {
898  data2 = NULL;
899  start2 = 0;
900  len2 = 0;
901  }
902 
903  vectors[0].iov_base = (char*) data1;
904  vectors[0].iov_len = len1;
905  vectors[1].iov_base = (char*) data2;
906  vectors[1].iov_len = len2;
907 
908  again:
909 
910  bytes_written = writev (fd,
911  vectors,
912  data2 ? 2 : 1);
913 
914  if (bytes_written < 0 && errno == EINTR)
915  goto again;
916 
917  return bytes_written;
918  }
919 #else /* HAVE_WRITEV */
920  {
921  int ret1, ret2;
922 
923  ret1 = _dbus_write (fd, buffer1, start1, len1);
924  if (ret1 == len1 && buffer2 != NULL)
925  {
926  ret2 = _dbus_write (fd, buffer2, start2, len2);
927  if (ret2 < 0)
928  ret2 = 0; /* we can't report an error as the first write was OK */
929 
930  return ret1 + ret2;
931  }
932  else
933  return ret1;
934  }
935 #endif /* !HAVE_WRITEV */
936 }
937 
955 _dbus_connect_unix_socket (const char *path,
956  dbus_bool_t abstract,
957  DBusError *error)
958 {
959  DBusSocket fd = DBUS_SOCKET_INIT;
960  size_t path_len;
961  struct sockaddr_un addr;
962  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
963 
964  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
965 
966  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
967  path, abstract);
968 
969 
970  if (!_dbus_open_unix_socket (&fd.fd, error))
971  {
972  _DBUS_ASSERT_ERROR_IS_SET(error);
973  return fd;
974  }
975  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
976 
977  _DBUS_ZERO (addr);
978  addr.sun_family = AF_UNIX;
979  path_len = strlen (path);
980 
981  if (abstract)
982  {
983 #ifdef __linux__
984  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
985  path_len++; /* Account for the extra nul byte added to the start of sun_path */
986 
987  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
988  {
990  "Abstract socket name too long\n");
991  _dbus_close_socket (&fd, NULL);
992  return fd;
993  }
994 
995  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
996  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
997 #else /* !__linux__ */
999  "Operating system does not support abstract socket namespace\n");
1000  _dbus_close_socket (&fd, NULL);
1001  return fd;
1002 #endif /* !__linux__ */
1003  }
1004  else
1005  {
1006  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1007  {
1009  "Socket name too long\n");
1010  _dbus_close_socket (&fd, NULL);
1011  return fd;
1012  }
1013 
1014  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1015  }
1016 
1017  if (connect (fd.fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1018  {
1019  dbus_set_error (error,
1020  _dbus_error_from_errno (errno),
1021  "Failed to connect to socket %s: %s",
1022  path, _dbus_strerror (errno));
1023 
1024  _dbus_close_socket (&fd, NULL);
1025  return fd;
1026  }
1027 
1028  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1029  {
1030  _DBUS_ASSERT_ERROR_IS_SET (error);
1031 
1032  _dbus_close_socket (&fd, NULL);
1033  return fd;
1034  }
1035 
1036  return fd;
1037 }
1038 
1051 DBusSocket
1052 _dbus_connect_exec (const char *path,
1053  char *const argv[],
1054  DBusError *error)
1055 {
1056  DBusSocket s = DBUS_SOCKET_INIT;
1057  int fds[2];
1058  pid_t pid;
1059  int retval;
1060  dbus_bool_t cloexec_done = 0;
1061 
1062  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1063 
1064  _dbus_verbose ("connecting to process %s\n", path);
1065 
1066 #ifdef SOCK_CLOEXEC
1067  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1068  cloexec_done = (retval >= 0);
1069 
1070  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1071 #endif
1072  {
1073  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1074  }
1075 
1076  if (retval < 0)
1077  {
1078  dbus_set_error (error,
1079  _dbus_error_from_errno (errno),
1080  "Failed to create socket pair: %s",
1081  _dbus_strerror (errno));
1082  _dbus_assert (!_dbus_socket_is_valid (s));
1083  return s;
1084  }
1085 
1086  if (!cloexec_done)
1087  {
1088  _dbus_fd_set_close_on_exec (fds[0]);
1089  _dbus_fd_set_close_on_exec (fds[1]);
1090  }
1091 
1092  /* Make sure our output buffers aren't redundantly printed by both the
1093  * parent and the child */
1094  fflush (stdout);
1095  fflush (stderr);
1096 
1097  pid = fork ();
1098  if (pid < 0)
1099  {
1100  dbus_set_error (error,
1101  _dbus_error_from_errno (errno),
1102  "Failed to fork() to call %s: %s",
1103  path, _dbus_strerror (errno));
1104  close (fds[0]);
1105  close (fds[1]);
1106  _dbus_assert (!_dbus_socket_is_valid (s));
1107  return s;
1108  }
1109 
1110  if (pid == 0)
1111  {
1112  /* child */
1113  close (fds[0]);
1114 
1115  dup2 (fds[1], STDIN_FILENO);
1116  dup2 (fds[1], STDOUT_FILENO);
1117 
1118  if (fds[1] != STDIN_FILENO &&
1119  fds[1] != STDOUT_FILENO)
1120  close (fds[1]);
1121 
1122  /* Inherit STDERR and the controlling terminal from the
1123  parent */
1124 
1125  _dbus_close_all ();
1126 
1127  execvp (path, (char * const *) argv);
1128 
1129  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1130 
1131  _exit(1);
1132  }
1133 
1134  /* parent */
1135  close (fds[1]);
1136 
1137  if (!_dbus_set_fd_nonblocking (fds[0], error))
1138  {
1139  _DBUS_ASSERT_ERROR_IS_SET (error);
1140 
1141  close (fds[0]);
1142  _dbus_assert (!_dbus_socket_is_valid (s));
1143  return s;
1144  }
1145 
1146  s.fd = fds[0];
1147  return s;
1148 }
1149 
1167 DBusSocket
1168 _dbus_listen_unix_socket (const char *path,
1169  dbus_bool_t abstract,
1170  DBusError *error)
1171 {
1172  DBusSocket s = DBUS_SOCKET_INIT;
1173  int listen_fd;
1174  struct sockaddr_un addr;
1175  size_t path_len;
1176  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1177 
1178  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1179 
1180  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1181  path, abstract);
1182 
1183  if (!_dbus_open_unix_socket (&listen_fd, error))
1184  {
1185  _DBUS_ASSERT_ERROR_IS_SET(error);
1186  return s;
1187  }
1188  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1189 
1190  _DBUS_ZERO (addr);
1191  addr.sun_family = AF_UNIX;
1192  path_len = strlen (path);
1193 
1194  if (abstract)
1195  {
1196 #ifdef __linux__
1197  /* remember that abstract names aren't nul-terminated so we rely
1198  * on sun_path being filled in with zeroes above.
1199  */
1200  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1201  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1202 
1203  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1204  {
1206  "Abstract socket name too long\n");
1207  _dbus_close (listen_fd, NULL);
1208  return s;
1209  }
1210 
1211  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1212  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1213 #else /* !__linux__ */
1215  "Operating system does not support abstract socket namespace\n");
1216  _dbus_close (listen_fd, NULL);
1217  return s;
1218 #endif /* !__linux__ */
1219  }
1220  else
1221  {
1222  /* Discussed security implications of this with Nalin,
1223  * and we couldn't think of where it would kick our ass, but
1224  * it still seems a bit sucky. It also has non-security suckage;
1225  * really we'd prefer to exit if the socket is already in use.
1226  * But there doesn't seem to be a good way to do this.
1227  *
1228  * Just to be extra careful, I threw in the stat() - clearly
1229  * the stat() can't *fix* any security issue, but it at least
1230  * avoids inadvertent/accidental data loss.
1231  */
1232  {
1233  struct stat sb;
1234 
1235  if (stat (path, &sb) == 0 &&
1236  S_ISSOCK (sb.st_mode))
1237  unlink (path);
1238  }
1239 
1240  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1241  {
1243  "Socket name too long\n");
1244  _dbus_close (listen_fd, NULL);
1245  return s;
1246  }
1247 
1248  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1249  }
1250 
1251  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1252  {
1253  dbus_set_error (error, _dbus_error_from_errno (errno),
1254  "Failed to bind socket \"%s\": %s",
1255  path, _dbus_strerror (errno));
1256  _dbus_close (listen_fd, NULL);
1257  return s;
1258  }
1259 
1260  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1261  {
1262  dbus_set_error (error, _dbus_error_from_errno (errno),
1263  "Failed to listen on socket \"%s\": %s",
1264  path, _dbus_strerror (errno));
1265  _dbus_close (listen_fd, NULL);
1266  return s;
1267  }
1268 
1269  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1270  {
1271  _DBUS_ASSERT_ERROR_IS_SET (error);
1272  _dbus_close (listen_fd, NULL);
1273  return s;
1274  }
1275 
1276  /* Try opening up the permissions, but if we can't, just go ahead
1277  * and continue, maybe it will be good enough.
1278  */
1279  if (!abstract && chmod (path, 0777) < 0)
1280  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1281 
1282  s.fd = listen_fd;
1283  return s;
1284 }
1285 
1296 int
1298  DBusError *error)
1299 {
1300 #ifdef HAVE_SYSTEMD
1301  int r, n;
1302  int fd;
1303  DBusSocket *new_fds;
1304 
1305  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1306 
1307  n = sd_listen_fds (TRUE);
1308  if (n < 0)
1309  {
1311  "Failed to acquire systemd socket: %s",
1312  _dbus_strerror (-n));
1313  return -1;
1314  }
1315 
1316  if (n <= 0)
1317  {
1319  "No socket received.");
1320  return -1;
1321  }
1322 
1323  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1324  {
1325  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1326  if (r < 0)
1327  {
1329  "Failed to verify systemd socket type: %s",
1330  _dbus_strerror (-r));
1331  return -1;
1332  }
1333 
1334  if (!r)
1335  {
1337  "Passed socket has wrong type.");
1338  return -1;
1339  }
1340  }
1341 
1342  /* OK, the file descriptors are all good, so let's take posession of
1343  them then. */
1344 
1345  new_fds = dbus_new (DBusSocket, n);
1346  if (!new_fds)
1347  {
1349  "Failed to allocate file handle array.");
1350  goto fail;
1351  }
1352 
1353  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1354  {
1355  if (!_dbus_set_fd_nonblocking (fd, error))
1356  {
1357  _DBUS_ASSERT_ERROR_IS_SET (error);
1358  goto fail;
1359  }
1360 
1361  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1362  }
1363 
1364  *fds = new_fds;
1365  return n;
1366 
1367  fail:
1368 
1369  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1370  {
1371  _dbus_close (fd, NULL);
1372  }
1373 
1374  dbus_free (new_fds);
1375  return -1;
1376 #else
1378  "dbus was compiled without systemd support");
1379  return -1;
1380 #endif
1381 }
1382 
1383 /* Convert an error code from getaddrinfo() or getnameinfo() into
1384  * a D-Bus error name. */
1385 static const char *
1386 _dbus_error_from_gai (int gai_res,
1387  int saved_errno)
1388 {
1389  switch (gai_res)
1390  {
1391 #ifdef EAI_FAMILY
1392  case EAI_FAMILY:
1393  /* ai_family not supported (at all) */
1394  return DBUS_ERROR_NOT_SUPPORTED;
1395 #endif
1396 
1397 #ifdef EAI_SOCKTYPE
1398  case EAI_SOCKTYPE:
1399  /* ai_socktype not supported (at all) */
1400  return DBUS_ERROR_NOT_SUPPORTED;
1401 #endif
1402 
1403 #ifdef EAI_MEMORY
1404  case EAI_MEMORY:
1405  /* Out of memory */
1406  return DBUS_ERROR_NO_MEMORY;
1407 #endif
1408 
1409 #ifdef EAI_SYSTEM
1410  case EAI_SYSTEM:
1411  /* Unspecified system error, details in errno */
1412  return _dbus_error_from_errno (saved_errno);
1413 #endif
1414 
1415  case 0:
1416  /* It succeeded, but we didn't get any addresses? */
1417  return DBUS_ERROR_FAILED;
1418 
1419  /* EAI_AGAIN: Transient failure */
1420  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1421  /* EAI_FAIL: Non-recoverable failure */
1422  /* EAI_NODATA: host exists but has no addresses */
1423  /* EAI_NONAME: host does not exist */
1424  /* EAI_OVERFLOW: argument buffer overflow */
1425  /* EAI_SERVICE: service not available for specified socket
1426  * type (we should never see this because we use numeric
1427  * ports) */
1428  default:
1429  return DBUS_ERROR_FAILED;
1430  }
1431 }
1432 
1446 DBusSocket
1447 _dbus_connect_tcp_socket (const char *host,
1448  const char *port,
1449  const char *family,
1450  DBusError *error)
1451 {
1452  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1453 }
1454 
1455 DBusSocket
1456 _dbus_connect_tcp_socket_with_nonce (const char *host,
1457  const char *port,
1458  const char *family,
1459  const char *noncefile,
1460  DBusError *error)
1461 {
1462  int saved_errno = 0;
1463  DBusList *connect_errors = NULL;
1464  DBusSocket fd = DBUS_SOCKET_INIT;
1465  int res;
1466  struct addrinfo hints;
1467  struct addrinfo *ai = NULL;
1468  const struct addrinfo *tmp;
1469  DBusError *connect_error;
1470 
1471  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1472 
1473  _DBUS_ZERO (hints);
1474 
1475  if (!family)
1476  hints.ai_family = AF_UNSPEC;
1477  else if (!strcmp(family, "ipv4"))
1478  hints.ai_family = AF_INET;
1479  else if (!strcmp(family, "ipv6"))
1480  hints.ai_family = AF_INET6;
1481  else
1482  {
1483  dbus_set_error (error,
1485  "Unknown address family %s", family);
1486  return _dbus_socket_get_invalid ();
1487  }
1488  hints.ai_protocol = IPPROTO_TCP;
1489  hints.ai_socktype = SOCK_STREAM;
1490  hints.ai_flags = AI_ADDRCONFIG;
1491 
1492  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1493  {
1494  dbus_set_error (error,
1495  _dbus_error_from_gai (res, errno),
1496  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1497  host, port, gai_strerror(res), res);
1498  goto out;
1499  }
1500 
1501  tmp = ai;
1502  while (tmp)
1503  {
1504  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1505  {
1506  _DBUS_ASSERT_ERROR_IS_SET(error);
1507  _dbus_socket_invalidate (&fd);
1508  goto out;
1509  }
1510  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1511 
1512  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1513  {
1514  saved_errno = errno;
1515  _dbus_close_socket (&fd, NULL);
1516 
1517  connect_error = dbus_new0 (DBusError, 1);
1518 
1519  if (connect_error == NULL)
1520  {
1521  _DBUS_SET_OOM (error);
1522  goto out;
1523  }
1524 
1525  dbus_error_init (connect_error);
1526  _dbus_set_error_with_inet_sockaddr (connect_error,
1527  tmp->ai_addr, tmp->ai_addrlen,
1528  "Failed to connect to socket",
1529  saved_errno);
1530 
1531  if (!_dbus_list_append (&connect_errors, connect_error))
1532  {
1533  dbus_error_free (connect_error);
1534  dbus_free (connect_error);
1535  _DBUS_SET_OOM (error);
1536  goto out;
1537  }
1538 
1539  tmp = tmp->ai_next;
1540  continue;
1541  }
1542 
1543  break;
1544  }
1545 
1546  if (!_dbus_socket_is_valid (fd))
1547  {
1548  _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1549  host, port, error);
1550  goto out;
1551  }
1552 
1553  if (noncefile != NULL)
1554  {
1555  DBusString noncefileStr;
1556  dbus_bool_t ret;
1557  _dbus_string_init_const (&noncefileStr, noncefile);
1558  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1559 
1560  if (!ret)
1561  {
1562  _dbus_close_socket (&fd, NULL);
1563  goto out;
1564  }
1565  }
1566 
1567  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1568  {
1569  _dbus_close_socket (&fd, NULL);
1570  goto out;
1571  }
1572 
1573 out:
1574  if (ai != NULL)
1575  freeaddrinfo (ai);
1576 
1577  while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1578  {
1579  dbus_error_free (connect_error);
1580  dbus_free (connect_error);
1581  }
1582 
1583  return fd;
1584 }
1585 
1603 int
1604 _dbus_listen_tcp_socket (const char *host,
1605  const char *port,
1606  const char *family,
1607  DBusString *retport,
1608  const char **retfamily,
1609  DBusSocket **fds_p,
1610  DBusError *error)
1611 {
1612  int saved_errno;
1613  int nlisten_fd = 0, res, i;
1614  DBusList *bind_errors = NULL;
1615  DBusError *bind_error = NULL;
1616  DBusSocket *listen_fd = NULL;
1617  struct addrinfo hints;
1618  struct addrinfo *ai, *tmp;
1619  unsigned int reuseaddr;
1620  dbus_bool_t have_ipv4 = FALSE;
1621  dbus_bool_t have_ipv6 = FALSE;
1622 
1623  *fds_p = NULL;
1624  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1625 
1626  _DBUS_ZERO (hints);
1627 
1628  if (!family)
1629  hints.ai_family = AF_UNSPEC;
1630  else if (!strcmp(family, "ipv4"))
1631  hints.ai_family = AF_INET;
1632  else if (!strcmp(family, "ipv6"))
1633  hints.ai_family = AF_INET6;
1634  else
1635  {
1636  dbus_set_error (error,
1638  "Unknown address family %s", family);
1639  return -1;
1640  }
1641 
1642  hints.ai_protocol = IPPROTO_TCP;
1643  hints.ai_socktype = SOCK_STREAM;
1644  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1645 
1646  redo_lookup_with_port:
1647  ai = NULL;
1648  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1649  {
1650  dbus_set_error (error,
1651  _dbus_error_from_gai (res, errno),
1652  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1653  host ? host : "*", port, gai_strerror(res), res);
1654  goto failed;
1655  }
1656 
1657  tmp = ai;
1658  while (tmp)
1659  {
1660  int fd = -1, tcp_nodelay_on;
1661  DBusSocket *newlisten_fd;
1662 
1663  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1664  {
1665  _DBUS_ASSERT_ERROR_IS_SET(error);
1666  goto failed;
1667  }
1668  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1669 
1670  reuseaddr = 1;
1671  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1672  {
1673  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1674  host ? host : "*", port, _dbus_strerror (errno));
1675  }
1676 
1677  /* Nagle's algorithm imposes a huge delay on the initial messages
1678  going over TCP. */
1679  tcp_nodelay_on = 1;
1680  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1681  {
1682  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1683  host ? host : "*", port, _dbus_strerror (errno));
1684  }
1685 
1686  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1687  {
1688  saved_errno = errno;
1689  _dbus_close(fd, NULL);
1690 
1691  /*
1692  * We don't treat this as a fatal error, because there might be
1693  * other addresses that we can listen on. In particular:
1694  *
1695  * - If saved_errno is EADDRINUSE after we
1696  * "goto redo_lookup_with_port" after binding a port on one of the
1697  * possible addresses, we will try to bind that same port on
1698  * every address, including the same address again for a second
1699  * time, which will fail with EADDRINUSE.
1700  *
1701  * - If saved_errno is EADDRINUSE, it might be because binding to
1702  * an IPv6 address implicitly binds to a corresponding IPv4
1703  * address or vice versa (e.g. Linux with bindv6only=0).
1704  *
1705  * - If saved_errno is EADDRNOTAVAIL when we asked for family
1706  * AF_UNSPEC, it might be because IPv6 is disabled for this
1707  * particular interface (e.g. Linux with
1708  * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1709  */
1710  bind_error = dbus_new0 (DBusError, 1);
1711 
1712  if (bind_error == NULL)
1713  {
1714  _DBUS_SET_OOM (error);
1715  goto failed;
1716  }
1717 
1718  dbus_error_init (bind_error);
1719  _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1720  "Failed to bind socket",
1721  saved_errno);
1722 
1723  if (!_dbus_list_append (&bind_errors, bind_error))
1724  {
1725  dbus_error_free (bind_error);
1726  dbus_free (bind_error);
1727  _DBUS_SET_OOM (error);
1728  goto failed;
1729  }
1730 
1731  /* Try the next address, maybe it will work better */
1732  tmp = tmp->ai_next;
1733  continue;
1734  }
1735 
1736  if (listen (fd, 30 /* backlog */) < 0)
1737  {
1738  saved_errno = errno;
1739  _dbus_close (fd, NULL);
1740  _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1741  "Failed to listen on socket",
1742  saved_errno);
1743  goto failed;
1744  }
1745 
1746  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1747  if (!newlisten_fd)
1748  {
1749  _dbus_close (fd, NULL);
1751  "Failed to allocate file handle array");
1752  goto failed;
1753  }
1754  listen_fd = newlisten_fd;
1755  listen_fd[nlisten_fd].fd = fd;
1756  nlisten_fd++;
1757 
1758  if (tmp->ai_addr->sa_family == AF_INET)
1759  have_ipv4 = TRUE;
1760  else if (tmp->ai_addr->sa_family == AF_INET6)
1761  have_ipv6 = TRUE;
1762 
1763  if (!_dbus_string_get_length(retport))
1764  {
1765  /* If the user didn't specify a port, or used 0, then
1766  the kernel chooses a port. After the first address
1767  is bound to, we need to force all remaining addresses
1768  to use the same port */
1769  if (!port || !strcmp(port, "0"))
1770  {
1771  int result;
1772  struct sockaddr_storage addr;
1773  socklen_t addrlen;
1774  char portbuf[50];
1775 
1776  addrlen = sizeof(addr);
1777  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1778 
1779  if (result == -1)
1780  {
1781  saved_errno = errno;
1782  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1783  "Failed to retrieve socket name for \"%s:%s\": %s",
1784  host ? host : "*", port, _dbus_strerror (saved_errno));
1785  goto failed;
1786  }
1787 
1788  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1789  portbuf, sizeof(portbuf),
1790  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1791  {
1792  saved_errno = errno;
1793  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1794  "Failed to resolve port \"%s:%s\": %s (%d)",
1795  host ? host : "*", port, gai_strerror(res), res);
1796  goto failed;
1797  }
1798 
1799  if (!_dbus_string_append(retport, portbuf))
1800  {
1802  goto failed;
1803  }
1804 
1805  /* Release current address list & redo lookup */
1806  port = _dbus_string_get_const_data(retport);
1807  freeaddrinfo(ai);
1808  goto redo_lookup_with_port;
1809  }
1810  else
1811  {
1812  if (!_dbus_string_append(retport, port))
1813  {
1815  goto failed;
1816  }
1817  }
1818  }
1819 
1820  tmp = tmp->ai_next;
1821  }
1822  freeaddrinfo(ai);
1823  ai = NULL;
1824 
1825  if (!nlisten_fd)
1826  {
1827  _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1828  port, error);
1829  goto failed;
1830  }
1831 
1832  if (have_ipv4 && !have_ipv6)
1833  *retfamily = "ipv4";
1834  else if (!have_ipv4 && have_ipv6)
1835  *retfamily = "ipv6";
1836 
1837  for (i = 0 ; i < nlisten_fd ; i++)
1838  {
1839  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1840  {
1841  goto failed;
1842  }
1843  }
1844 
1845  *fds_p = listen_fd;
1846 
1847  /* This list might be non-empty even on success, because we might be
1848  * ignoring EADDRINUSE or EADDRNOTAVAIL */
1849  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1850  {
1851  dbus_error_free (bind_error);
1852  dbus_free (bind_error);
1853  }
1854 
1855  return nlisten_fd;
1856 
1857  failed:
1858  if (ai)
1859  freeaddrinfo(ai);
1860  for (i = 0 ; i < nlisten_fd ; i++)
1861  _dbus_close(listen_fd[i].fd, NULL);
1862 
1863  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1864  {
1865  dbus_error_free (bind_error);
1866  dbus_free (bind_error);
1867  }
1868 
1869  dbus_free(listen_fd);
1870  return -1;
1871 }
1872 
1873 static dbus_bool_t
1874 write_credentials_byte (int server_fd,
1875  DBusError *error)
1876 {
1877  int bytes_written;
1878  char buf[1] = { '\0' };
1879 #if defined(HAVE_CMSGCRED)
1880  union {
1881  struct cmsghdr hdr;
1882  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1883  } cmsg;
1884  struct iovec iov;
1885  struct msghdr msg;
1886  iov.iov_base = buf;
1887  iov.iov_len = 1;
1888 
1889  _DBUS_ZERO(msg);
1890  msg.msg_iov = &iov;
1891  msg.msg_iovlen = 1;
1892 
1893  msg.msg_control = (caddr_t) &cmsg;
1894  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1895  _DBUS_ZERO(cmsg);
1896  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1897  cmsg.hdr.cmsg_level = SOL_SOCKET;
1898  cmsg.hdr.cmsg_type = SCM_CREDS;
1899 #endif
1900 
1901  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1902 
1903  again:
1904 
1905 #if defined(HAVE_CMSGCRED)
1906  bytes_written = sendmsg (server_fd, &msg, 0
1907 #if HAVE_DECL_MSG_NOSIGNAL
1908  |MSG_NOSIGNAL
1909 #endif
1910  );
1911 
1912  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1913  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1914  * only allows that on AF_UNIX. Try just doing a send() instead. */
1915  if (bytes_written < 0 && errno == EINVAL)
1916 #endif
1917  {
1918  bytes_written = send (server_fd, buf, 1, 0
1919 #if HAVE_DECL_MSG_NOSIGNAL
1920  |MSG_NOSIGNAL
1921 #endif
1922  );
1923  }
1924 
1925  if (bytes_written < 0 && errno == EINTR)
1926  goto again;
1927 
1928  if (bytes_written < 0)
1929  {
1930  dbus_set_error (error, _dbus_error_from_errno (errno),
1931  "Failed to write credentials byte: %s",
1932  _dbus_strerror (errno));
1933  return FALSE;
1934  }
1935  else if (bytes_written == 0)
1936  {
1938  "wrote zero bytes writing credentials byte");
1939  return FALSE;
1940  }
1941  else
1942  {
1943  _dbus_assert (bytes_written == 1);
1944  _dbus_verbose ("wrote credentials byte\n");
1945  return TRUE;
1946  }
1947 }
1948 
1949 /* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1950 static dbus_bool_t
1951 add_groups_to_credentials (int client_fd,
1952  DBusCredentials *credentials,
1953  dbus_gid_t primary)
1954 {
1955 #if defined(__linux__) && defined(SO_PEERGROUPS)
1956  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1957  gid_t *buf = NULL;
1958  socklen_t len = 1024;
1959  dbus_bool_t oom = FALSE;
1960  /* libdbus has a different representation of group IDs just to annoy you */
1961  dbus_gid_t *converted_gids = NULL;
1962  dbus_bool_t need_primary = TRUE;
1963  size_t n_gids;
1964  size_t i;
1965 
1966  n_gids = ((size_t) len) / sizeof (gid_t);
1967  buf = dbus_new (gid_t, n_gids);
1968 
1969  if (buf == NULL)
1970  return FALSE;
1971 
1972  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1973  {
1974  int e = errno;
1975  gid_t *replacement;
1976 
1977  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1978  _dbus_strerror (e), (unsigned long) len);
1979 
1980  if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1981  {
1982  _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1983  _dbus_strerror (e));
1984  goto out;
1985  }
1986 
1987  /* If not enough space, len is updated to be enough.
1988  * Try again with a large enough buffer. */
1989  n_gids = ((size_t) len) / sizeof (gid_t);
1990  replacement = dbus_realloc (buf, len);
1991 
1992  if (replacement == NULL)
1993  {
1994  oom = TRUE;
1995  goto out;
1996  }
1997 
1998  buf = replacement;
1999  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2000  }
2001 
2002  if (len <= 0)
2003  {
2004  _dbus_verbose ("getsockopt(SO_PEERGROUPS) yielded <= 0 bytes: %ld\n",
2005  (long) len);
2006  goto out;
2007  }
2008 
2009  if (len > n_gids * sizeof (gid_t))
2010  {
2011  _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
2012  _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
2013  }
2014 
2015  if (len % sizeof (gid_t) != 0)
2016  {
2017  _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
2018  "integer multiple of sizeof(gid_t): %lu should be "
2019  "divisible by %zu",
2020  (unsigned long) len, sizeof (gid_t));
2021  goto out;
2022  }
2023 
2024  /* Allocate an extra space for the primary group ID */
2025  n_gids = ((size_t) len) / sizeof (gid_t);
2026 
2027  /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
2028  * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
2029  * This is using _DBUS_INT32_MAX as a conservative lower bound for
2030  * the maximum size_t. */
2031  if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
2032  {
2033  _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
2034  "of groups (%lu bytes), ignoring",
2035  (unsigned long) len);
2036  goto out;
2037  }
2038 
2039  converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
2040 
2041  if (converted_gids == NULL)
2042  {
2043  oom = TRUE;
2044  goto out;
2045  }
2046 
2047  for (i = 0; i < n_gids; i++)
2048  {
2049  converted_gids[i] = (dbus_gid_t) buf[i];
2050 
2051  if (converted_gids[i] == primary)
2052  need_primary = FALSE;
2053  }
2054 
2055  if (need_primary && primary != DBUS_GID_UNSET)
2056  {
2057  converted_gids[n_gids] = primary;
2058  n_gids++;
2059  }
2060 
2061  _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2062 
2063 out:
2064  dbus_free (buf);
2065  return !oom;
2066 #else
2067  /* no error */
2068  return TRUE;
2069 #endif
2070 }
2071 
2072 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2073 static dbus_bool_t
2074 add_linux_security_label_to_credentials (int client_fd,
2075  DBusCredentials *credentials)
2076 {
2077 #if defined(__linux__) && defined(SO_PEERSEC)
2078  DBusString buf;
2079  socklen_t len = 1024;
2080  dbus_bool_t oom = FALSE;
2081 
2082  if (!_dbus_string_init_preallocated (&buf, len) ||
2083  !_dbus_string_set_length (&buf, len))
2084  return FALSE;
2085 
2086  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2087  _dbus_string_get_data (&buf), &len) < 0)
2088  {
2089  int e = errno;
2090 
2091  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2092  _dbus_strerror (e), (unsigned long) len);
2093 
2094  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2095  {
2096  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2097  _dbus_strerror (e));
2098  goto out;
2099  }
2100 
2101  /* If not enough space, len is updated to be enough.
2102  * Try again with a large enough buffer. */
2103  if (!_dbus_string_set_length (&buf, len))
2104  {
2105  oom = TRUE;
2106  goto out;
2107  }
2108 
2109  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2110  }
2111 
2112  if (len <= 0)
2113  {
2114  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2115  (unsigned long) len);
2116  goto out;
2117  }
2118 
2119  if (len > _dbus_string_get_length_uint (&buf))
2120  {
2121  _dbus_verbose ("%lu > %u", (unsigned long) len,
2122  _dbus_string_get_length_uint (&buf));
2123  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2124  }
2125 
2126  if (_dbus_string_get_byte (&buf, len - 1) == 0)
2127  {
2128  /* the kernel included the trailing \0 in its count,
2129  * but DBusString always has an extra \0 after the data anyway */
2130  _dbus_verbose ("subtracting trailing \\0\n");
2131  len--;
2132  }
2133 
2134  if (!_dbus_string_set_length (&buf, len))
2135  {
2136  _dbus_assert_not_reached ("shortening string should not lead to OOM");
2137  oom = TRUE;
2138  goto out;
2139  }
2140 
2141  if (strlen (_dbus_string_get_const_data (&buf)) != len)
2142  {
2143  /* LSM people on the linux-security-module@ mailing list say this
2144  * should never happen: the label should be a bytestring with
2145  * an optional trailing \0 */
2146  _dbus_verbose ("security label from kernel had an embedded \\0, "
2147  "ignoring it\n");
2148  goto out;
2149  }
2150 
2151  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2152  (unsigned long) len,
2153  _dbus_string_get_const_data (&buf));
2154 
2156  _dbus_string_get_const_data (&buf)))
2157  {
2158  oom = TRUE;
2159  goto out;
2160  }
2161 
2162 out:
2163  _dbus_string_free (&buf);
2164  return !oom;
2165 #else
2166  /* no error */
2167  return TRUE;
2168 #endif
2169 }
2170 
2213  DBusCredentials *credentials,
2214  DBusError *error)
2215 {
2216  struct msghdr msg;
2217  struct iovec iov;
2218  char buf;
2219  dbus_uid_t uid_read;
2220  dbus_gid_t primary_gid_read;
2221  dbus_pid_t pid_read;
2222  int bytes_read;
2223 
2224 #ifdef HAVE_CMSGCRED
2225  union {
2226  struct cmsghdr hdr;
2227  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2228  } cmsg;
2229 #endif
2230 
2231  /* The POSIX spec certainly doesn't promise this, but
2232  * we need these assertions to fail as soon as we're wrong about
2233  * it so we can do the porting fixups
2234  */
2235  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2236  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2237  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2238 
2239  uid_read = DBUS_UID_UNSET;
2240  primary_gid_read = DBUS_GID_UNSET;
2241  pid_read = DBUS_PID_UNSET;
2242 
2243  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2244 
2245  _dbus_credentials_clear (credentials);
2246 
2247  iov.iov_base = &buf;
2248  iov.iov_len = 1;
2249 
2250  _DBUS_ZERO(msg);
2251  msg.msg_iov = &iov;
2252  msg.msg_iovlen = 1;
2253 
2254 #if defined(HAVE_CMSGCRED)
2255  _DBUS_ZERO(cmsg);
2256  msg.msg_control = (caddr_t) &cmsg;
2257  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2258 #endif
2259 
2260  again:
2261  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2262 
2263  if (bytes_read < 0)
2264  {
2265  if (errno == EINTR)
2266  goto again;
2267 
2268  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2269  * normally only call read_credentials if the socket was ready
2270  * for reading
2271  */
2272 
2273  dbus_set_error (error, _dbus_error_from_errno (errno),
2274  "Failed to read credentials byte: %s",
2275  _dbus_strerror (errno));
2276  return FALSE;
2277  }
2278  else if (bytes_read == 0)
2279  {
2280  /* this should not happen unless we are using recvmsg wrong,
2281  * so is essentially here for paranoia
2282  */
2284  "Failed to read credentials byte (zero-length read)");
2285  return FALSE;
2286  }
2287  else if (buf != '\0')
2288  {
2290  "Credentials byte was not nul");
2291  return FALSE;
2292  }
2293 
2294  _dbus_verbose ("read credentials byte\n");
2295 
2296  {
2297 #ifdef SO_PEERCRED
2298  /* Supported by at least Linux and OpenBSD, with minor differences.
2299  *
2300  * This mechanism passes the process ID through and does not require
2301  * the peer's cooperation, so we prefer it over all others. Notably,
2302  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2303  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2304  * because this is much less fragile.
2305  */
2306 #ifdef __OpenBSD__
2307  struct sockpeercred cr;
2308 #else
2309  struct ucred cr;
2310 #endif
2311  socklen_t cr_len = sizeof (cr);
2312 
2313  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2314  {
2315  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2316  _dbus_strerror (errno));
2317  }
2318  else if (cr_len != sizeof (cr))
2319  {
2320  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2321  cr_len, (int) sizeof (cr));
2322  }
2323  else
2324  {
2325  pid_read = cr.pid;
2326  uid_read = cr.uid;
2327 #ifdef __linux__
2328  /* Do other platforms have cr.gid? (Not that it really matters,
2329  * because the gid is useless to us unless we know the complete
2330  * group vector, which we only know on Linux.) */
2331  primary_gid_read = cr.gid;
2332 #endif
2333  }
2334 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2335  /* Another variant of the above - used on NetBSD
2336  */
2337  struct unpcbid cr;
2338  socklen_t cr_len = sizeof (cr);
2339 
2340  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2341  {
2342  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2343  _dbus_strerror (errno));
2344  }
2345  else if (cr_len != sizeof (cr))
2346  {
2347  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2348  cr_len, (int) sizeof (cr));
2349  }
2350  else
2351  {
2352  pid_read = cr.unp_pid;
2353  uid_read = cr.unp_euid;
2354  }
2355 #elif defined(HAVE_CMSGCRED)
2356  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2357  * presence of that struct implies SCM_CREDS. Supported by at least
2358  * FreeBSD and DragonflyBSD.
2359  *
2360  * This mechanism requires the peer to help us (it has to send us a
2361  * SCM_CREDS message) but it does pass the process ID through,
2362  * which makes it better than getpeereid().
2363  */
2364  struct cmsgcred *cred;
2365  struct cmsghdr *cmsgp;
2366 
2367  for (cmsgp = CMSG_FIRSTHDR (&msg);
2368  cmsgp != NULL;
2369  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2370  {
2371  if (cmsgp->cmsg_type == SCM_CREDS &&
2372  cmsgp->cmsg_level == SOL_SOCKET &&
2373  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2374  {
2375  cred = (struct cmsgcred *) (void *) CMSG_DATA (cmsgp);
2376  pid_read = cred->cmcred_pid;
2377  uid_read = cred->cmcred_euid;
2378  break;
2379  }
2380  }
2381 
2382 #elif defined(HAVE_GETPEERUCRED)
2383  /* Supported in at least Solaris >= 10. It should probably be higher
2384  * up this list, because it carries the pid and we use this code path
2385  * for audit data. */
2386  ucred_t * ucred = NULL;
2387  if (getpeerucred (client_fd.fd, &ucred) == 0)
2388  {
2389 #ifdef HAVE_ADT
2390  adt_session_data_t *adth = NULL;
2391 #endif
2392  pid_read = ucred_getpid (ucred);
2393  uid_read = ucred_geteuid (ucred);
2394 #ifdef HAVE_ADT
2395  /* generate audit session data based on socket ucred */
2396  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2397  {
2398  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2399  }
2400  else
2401  {
2402  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2403  {
2404  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2405  }
2406  else
2407  {
2408  adt_export_data_t *data = NULL;
2409  size_t size = adt_export_session_data (adth, &data);
2410  if (size <= 0)
2411  {
2412  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2413  }
2414  else
2415  {
2416  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2417  free (data);
2418  }
2419  }
2420  (void) adt_end_session (adth);
2421  }
2422 #endif /* HAVE_ADT */
2423  }
2424  else
2425  {
2426  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2427  }
2428  if (ucred != NULL)
2429  ucred_free (ucred);
2430 
2431  /* ----------------------------------------------------------------
2432  * When adding new mechanisms, please add them above this point
2433  * if they support passing the process ID through, or below if not.
2434  * ---------------------------------------------------------------- */
2435 
2436 #elif defined(HAVE_GETPEEREID)
2437  /* getpeereid() originates from D.J. Bernstein and is fairly
2438  * widely-supported. According to a web search, it might be present in
2439  * any/all of:
2440  *
2441  * - AIX?
2442  * - Blackberry?
2443  * - Cygwin
2444  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2445  * - Mac OS X
2446  * - Minix 3.1.8+
2447  * - MirBSD?
2448  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2449  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2450  * - QNX?
2451  */
2452  uid_t euid;
2453  gid_t egid;
2454  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2455  {
2456  uid_read = euid;
2457  }
2458  else
2459  {
2460  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2461  }
2462 #else /* no supported mechanism */
2463 
2464 #warning Socket credentials not supported on this Unix OS
2465 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2466 
2467  /* Please add other operating systems known to support at least one of
2468  * the mechanisms above to this list, keeping alphabetical order.
2469  * Everything not in this list is best-effort.
2470  */
2471 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2472  defined(__linux__) || \
2473  defined(__OpenBSD__) || \
2474  defined(__NetBSD__)
2475 # error Credentials passing not working on this OS is a regression!
2476 #endif
2477 
2478  _dbus_verbose ("Socket credentials not supported on this OS\n");
2479 #endif
2480  }
2481 
2482  _dbus_verbose ("Credentials:"
2483  " pid "DBUS_PID_FORMAT
2484  " uid "DBUS_UID_FORMAT
2485  "\n",
2486  pid_read,
2487  uid_read);
2488 
2489  if (pid_read != DBUS_PID_UNSET)
2490  {
2491  if (!_dbus_credentials_add_pid (credentials, pid_read))
2492  {
2493  _DBUS_SET_OOM (error);
2494  return FALSE;
2495  }
2496  }
2497 
2498  if (uid_read != DBUS_UID_UNSET)
2499  {
2500  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2501  {
2502  _DBUS_SET_OOM (error);
2503  return FALSE;
2504  }
2505  }
2506 
2507  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2508  {
2509  _DBUS_SET_OOM (error);
2510  return FALSE;
2511  }
2512 
2513  /* We don't put any groups in the credentials unless we can put them
2514  * all there. */
2515  if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2516  {
2517  _DBUS_SET_OOM (error);
2518  return FALSE;
2519  }
2520 
2521  return TRUE;
2522 }
2523 
2543  DBusError *error)
2544 {
2545  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2546 
2547  if (write_credentials_byte (server_fd.fd, error))
2548  return TRUE;
2549  else
2550  return FALSE;
2551 }
2552 
2562 DBusSocket
2564 {
2565  DBusSocket client_fd;
2566  struct sockaddr addr;
2567  socklen_t addrlen;
2568 #ifdef HAVE_ACCEPT4
2569  dbus_bool_t cloexec_done;
2570 #endif
2571 
2572  addrlen = sizeof (addr);
2573 
2574  retry:
2575 
2576 #ifdef HAVE_ACCEPT4
2577  /*
2578  * At compile-time, we assume that if accept4() is available in
2579  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2580  * not necessarily true that either is supported by the running kernel.
2581  */
2582  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2583  cloexec_done = client_fd.fd >= 0;
2584 
2585  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2586 #endif
2587  {
2588  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2589  }
2590 
2591  if (client_fd.fd < 0)
2592  {
2593  if (errno == EINTR)
2594  goto retry;
2595  }
2596 
2597  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2598 
2599 #ifdef HAVE_ACCEPT4
2600  if (!cloexec_done)
2601 #endif
2602  {
2603  _dbus_fd_set_close_on_exec(client_fd.fd);
2604  }
2605 
2606  return client_fd;
2607 }
2608 
2619 {
2620  const char *directory;
2621  struct stat sb;
2622 
2623  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2624 
2625  directory = _dbus_string_get_const_data (dir);
2626 
2627  if (stat (directory, &sb) < 0)
2628  {
2629  dbus_set_error (error, _dbus_error_from_errno (errno),
2630  "%s", _dbus_strerror (errno));
2631 
2632  return FALSE;
2633  }
2634 
2635  if (sb.st_uid != geteuid ())
2636  {
2638  "%s directory is owned by user %lu, not %lu",
2639  directory,
2640  (unsigned long) sb.st_uid,
2641  (unsigned long) geteuid ());
2642  return FALSE;
2643  }
2644 
2645  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2646  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2647  {
2649  "%s directory is not private to the user", directory);
2650  return FALSE;
2651  }
2652 
2653  return TRUE;
2654 }
2655 
2656 static dbus_bool_t
2657 fill_user_info_from_passwd (struct passwd *p,
2658  DBusUserInfo *info,
2659  DBusError *error)
2660 {
2661  _dbus_assert (p->pw_name != NULL);
2662  _dbus_assert (p->pw_dir != NULL);
2663 
2664  info->uid = p->pw_uid;
2665  info->primary_gid = p->pw_gid;
2666  info->username = _dbus_strdup (p->pw_name);
2667  info->homedir = _dbus_strdup (p->pw_dir);
2668 
2669  if (info->username == NULL ||
2670  info->homedir == NULL)
2671  {
2673  return FALSE;
2674  }
2675 
2676  return TRUE;
2677 }
2678 
2679 static dbus_bool_t
2680 fill_user_info (DBusUserInfo *info,
2681  dbus_uid_t uid,
2682  const DBusString *username,
2683  DBusError *error)
2684 {
2685  const char *username_c;
2686 
2687  /* exactly one of username/uid provided */
2688  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2689  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2690 
2691  info->uid = DBUS_UID_UNSET;
2692  info->primary_gid = DBUS_GID_UNSET;
2693  info->group_ids = NULL;
2694  info->n_group_ids = 0;
2695  info->username = NULL;
2696  info->homedir = NULL;
2697 
2698  if (username != NULL)
2699  username_c = _dbus_string_get_const_data (username);
2700  else
2701  username_c = NULL;
2702 
2703  /* For now assuming that the getpwnam() and getpwuid() flavors
2704  * are always symmetrical, if not we have to add more configure
2705  * checks
2706  */
2707 
2708 #ifdef HAVE_GETPWNAM_R
2709  {
2710  struct passwd *p;
2711  int result;
2712  size_t buflen;
2713  char *buf;
2714  struct passwd p_str;
2715 
2716  /* retrieve maximum needed size for buf */
2717  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2718 
2719  /* sysconf actually returns a long, but everything else expects size_t,
2720  * so just recast here.
2721  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2722  */
2723  if ((long) buflen <= 0)
2724  buflen = 1024;
2725 
2726  result = -1;
2727  while (1)
2728  {
2729  buf = dbus_malloc (buflen);
2730  if (buf == NULL)
2731  {
2733  return FALSE;
2734  }
2735 
2736  p = NULL;
2737  if (uid != DBUS_UID_UNSET)
2738  result = getpwuid_r (uid, &p_str, buf, buflen,
2739  &p);
2740  else
2741  result = getpwnam_r (username_c, &p_str, buf, buflen,
2742  &p);
2743  //Try a bigger buffer if ERANGE was returned
2744  if (result == ERANGE && buflen < 512 * 1024)
2745  {
2746  dbus_free (buf);
2747  buflen *= 2;
2748  }
2749  else
2750  {
2751  break;
2752  }
2753  }
2754  if (result == 0 && p == &p_str)
2755  {
2756  if (!fill_user_info_from_passwd (p, info, error))
2757  {
2758  dbus_free (buf);
2759  return FALSE;
2760  }
2761  dbus_free (buf);
2762  }
2763  else
2764  {
2765  dbus_set_error (error, _dbus_error_from_errno (errno),
2766  "User \"%s\" unknown or no memory to allocate password entry\n",
2767  username_c ? username_c : "???");
2768  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2769  dbus_free (buf);
2770  return FALSE;
2771  }
2772  }
2773 #else /* ! HAVE_GETPWNAM_R */
2774  {
2775  /* I guess we're screwed on thread safety here */
2776  struct passwd *p;
2777 
2778 #warning getpwnam_r() not available, please report this to the dbus maintainers with details of your OS
2779 
2780  if (uid != DBUS_UID_UNSET)
2781  p = getpwuid (uid);
2782  else
2783  p = getpwnam (username_c);
2784 
2785  if (p != NULL)
2786  {
2787  if (!fill_user_info_from_passwd (p, info, error))
2788  {
2789  return FALSE;
2790  }
2791  }
2792  else
2793  {
2794  dbus_set_error (error, _dbus_error_from_errno (errno),
2795  "User \"%s\" unknown or no memory to allocate password entry\n",
2796  username_c ? username_c : "???");
2797  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2798  return FALSE;
2799  }
2800  }
2801 #endif /* ! HAVE_GETPWNAM_R */
2802 
2803  /* Fill this in so we can use it to get groups */
2804  username_c = info->username;
2805 
2806 #ifdef HAVE_GETGROUPLIST
2807  {
2808  gid_t *buf;
2809  int buf_count;
2810  int i;
2811  int initial_buf_count;
2812 
2813  initial_buf_count = 17;
2814  buf_count = initial_buf_count;
2815  buf = dbus_new (gid_t, buf_count);
2816  if (buf == NULL)
2817  {
2819  goto failed;
2820  }
2821 
2822  if (getgrouplist (username_c,
2823  info->primary_gid,
2824  buf, &buf_count) < 0)
2825  {
2826  gid_t *new;
2827  /* Presumed cause of negative return code: buf has insufficient
2828  entries to hold the entire group list. The Linux behavior in this
2829  case is to pass back the actual number of groups in buf_count, but
2830  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2831  So as a hack, try to help out a bit by guessing a larger
2832  number of groups, within reason.. might still fail, of course,
2833  but we can at least print a more informative message. I looked up
2834  the "right way" to do this by downloading Apple's own source code
2835  for the "id" command, and it turns out that they use an
2836  undocumented library function getgrouplist_2 (!) which is not
2837  declared in any header in /usr/include (!!). That did not seem
2838  like the way to go here.
2839  */
2840  if (buf_count == initial_buf_count)
2841  {
2842  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2843  }
2844  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2845  if (new == NULL)
2846  {
2848  dbus_free (buf);
2849  goto failed;
2850  }
2851 
2852  buf = new;
2853 
2854  errno = 0;
2855  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2856  {
2857  if (errno == 0)
2858  {
2859  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2860  username_c, buf_count, buf_count);
2861  }
2862  else
2863  {
2864  dbus_set_error (error,
2865  _dbus_error_from_errno (errno),
2866  "Failed to get groups for username \"%s\" primary GID "
2867  DBUS_GID_FORMAT ": %s\n",
2868  username_c, info->primary_gid,
2869  _dbus_strerror (errno));
2870  dbus_free (buf);
2871  goto failed;
2872  }
2873  }
2874  }
2875 
2876  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2877  if (info->group_ids == NULL)
2878  {
2880  dbus_free (buf);
2881  goto failed;
2882  }
2883 
2884  for (i = 0; i < buf_count; ++i)
2885  info->group_ids[i] = buf[i];
2886 
2887  info->n_group_ids = buf_count;
2888 
2889  dbus_free (buf);
2890  }
2891 #else /* HAVE_GETGROUPLIST */
2892  {
2893  /* We just get the one group ID */
2894  info->group_ids = dbus_new (dbus_gid_t, 1);
2895  if (info->group_ids == NULL)
2896  {
2898  goto failed;
2899  }
2900 
2901  info->n_group_ids = 1;
2902 
2903  (info->group_ids)[0] = info->primary_gid;
2904  }
2905 #endif /* HAVE_GETGROUPLIST */
2906 
2907  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2908 
2909  return TRUE;
2910 
2911  failed:
2912  _DBUS_ASSERT_ERROR_IS_SET (error);
2913  return FALSE;
2914 }
2915 
2926  const DBusString *username,
2927  DBusError *error)
2928 {
2929  return fill_user_info (info, DBUS_UID_UNSET,
2930  username, error);
2931 }
2932 
2943  dbus_uid_t uid,
2944  DBusError *error)
2945 {
2946  return fill_user_info (info, uid,
2947  NULL, error);
2948 }
2949 
2965 {
2966  /* The POSIX spec certainly doesn't promise this, but
2967  * we need these assertions to fail as soon as we're wrong about
2968  * it so we can do the porting fixups
2969  */
2970  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2971  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2972  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2973 
2974  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2975  return FALSE;
2976  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2977  return FALSE;
2978 
2979  return TRUE;
2980 }
2981 
2995 {
2996  return _dbus_string_append_uint (str,
2997  _dbus_geteuid ());
2998 }
2999 
3004 dbus_pid_t
3006 {
3007  return getpid ();
3008 }
3009 
3013 dbus_uid_t
3015 {
3016  return getuid ();
3017 }
3018 
3022 dbus_uid_t
3024 {
3025  return geteuid ();
3026 }
3027 
3034 unsigned long
3036 {
3037  return getpid ();
3038 }
3039 
3040 #if !DBUS_USE_SYNC
3041 /* To be thread-safe by default on platforms that don't necessarily have
3042  * atomic operations (notably Debian armel, which is armv4t), we must
3043  * use a mutex that can be initialized statically, like this.
3044  * GLib >= 2.32 uses a similar system.
3045  */
3046 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3047 #endif
3048 
3057 {
3058 #if DBUS_USE_SYNC
3059  return __sync_add_and_fetch(&atomic->value, 1)-1;
3060 #else
3061  dbus_int32_t res;
3062 
3063  pthread_mutex_lock (&atomic_mutex);
3064  res = atomic->value;
3065  atomic->value += 1;
3066  pthread_mutex_unlock (&atomic_mutex);
3067 
3068  return res;
3069 #endif
3070 }
3071 
3080 {
3081 #if DBUS_USE_SYNC
3082  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3083 #else
3084  dbus_int32_t res;
3085 
3086  pthread_mutex_lock (&atomic_mutex);
3087  res = atomic->value;
3088  atomic->value -= 1;
3089  pthread_mutex_unlock (&atomic_mutex);
3090 
3091  return res;
3092 #endif
3093 }
3094 
3104 {
3105 #if DBUS_USE_SYNC
3106  __sync_synchronize ();
3107  return atomic->value;
3108 #else
3109  dbus_int32_t res;
3110 
3111  pthread_mutex_lock (&atomic_mutex);
3112  res = atomic->value;
3113  pthread_mutex_unlock (&atomic_mutex);
3114 
3115  return res;
3116 #endif
3117 }
3118 
3124 void
3126 {
3127 #if DBUS_USE_SYNC
3128  /* Atomic version of "*atomic &= 0; return *atomic" */
3129  __sync_and_and_fetch (&atomic->value, 0);
3130 #else
3131  pthread_mutex_lock (&atomic_mutex);
3132  atomic->value = 0;
3133  pthread_mutex_unlock (&atomic_mutex);
3134 #endif
3135 }
3136 
3142 void
3144 {
3145 #if DBUS_USE_SYNC
3146  /* Atomic version of "*atomic |= 1; return *atomic" */
3147  __sync_or_and_fetch (&atomic->value, 1);
3148 #else
3149  pthread_mutex_lock (&atomic_mutex);
3150  atomic->value = 1;
3151  pthread_mutex_unlock (&atomic_mutex);
3152 #endif
3153 }
3154 
3163 int
3165  int n_fds,
3166  int timeout_milliseconds)
3167 {
3168 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3169  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3170  if (timeout_milliseconds < -1)
3171  {
3172  timeout_milliseconds = -1;
3173  }
3174 
3175  return poll (fds,
3176  n_fds,
3177  timeout_milliseconds);
3178 #else /* ! HAVE_POLL */
3179  /* Emulate poll() in terms of select() */
3180  fd_set read_set, write_set, err_set;
3181  int max_fd = 0;
3182  int i;
3183  struct timeval tv;
3184  int ready;
3185 
3186  FD_ZERO (&read_set);
3187  FD_ZERO (&write_set);
3188  FD_ZERO (&err_set);
3189 
3190  for (i = 0; i < n_fds; i++)
3191  {
3192  DBusPollFD *fdp = &fds[i];
3193 
3194  if (fdp->events & _DBUS_POLLIN)
3195  FD_SET (fdp->fd, &read_set);
3196 
3197  if (fdp->events & _DBUS_POLLOUT)
3198  FD_SET (fdp->fd, &write_set);
3199 
3200  FD_SET (fdp->fd, &err_set);
3201 
3202  max_fd = MAX (max_fd, fdp->fd);
3203  }
3204 
3205  tv.tv_sec = timeout_milliseconds / 1000;
3206  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3207 
3208  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3209  timeout_milliseconds < 0 ? NULL : &tv);
3210 
3211  if (ready > 0)
3212  {
3213  for (i = 0; i < n_fds; i++)
3214  {
3215  DBusPollFD *fdp = &fds[i];
3216 
3217  fdp->revents = 0;
3218 
3219  if (FD_ISSET (fdp->fd, &read_set))
3220  fdp->revents |= _DBUS_POLLIN;
3221 
3222  if (FD_ISSET (fdp->fd, &write_set))
3223  fdp->revents |= _DBUS_POLLOUT;
3224 
3225  if (FD_ISSET (fdp->fd, &err_set))
3226  fdp->revents |= _DBUS_POLLERR;
3227  }
3228  }
3229 
3230  return ready;
3231 #endif
3232 }
3233 
3241 void
3243  long *tv_usec)
3244 {
3245 #ifdef HAVE_MONOTONIC_CLOCK
3246  struct timespec ts;
3247  clock_gettime (CLOCK_MONOTONIC, &ts);
3248 
3249  if (tv_sec)
3250  *tv_sec = ts.tv_sec;
3251  if (tv_usec)
3252  *tv_usec = ts.tv_nsec / 1000;
3253 #else
3254  struct timeval t;
3255 
3256  gettimeofday (&t, NULL);
3257 
3258  if (tv_sec)
3259  *tv_sec = t.tv_sec;
3260  if (tv_usec)
3261  *tv_usec = t.tv_usec;
3262 #endif
3263 }
3264 
3272 void
3273 _dbus_get_real_time (long *tv_sec,
3274  long *tv_usec)
3275 {
3276  struct timeval t;
3277 
3278  gettimeofday (&t, NULL);
3279 
3280  if (tv_sec)
3281  *tv_sec = t.tv_sec;
3282  if (tv_usec)
3283  *tv_usec = t.tv_usec;
3284 }
3285 
3296  DBusError *error)
3297 {
3298  const char *filename_c;
3299 
3300  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3301 
3302  filename_c = _dbus_string_get_const_data (filename);
3303 
3304  if (mkdir (filename_c, 0700) < 0)
3305  {
3306  if (errno == EEXIST)
3307  return TRUE;
3308 
3310  "Failed to create directory %s: %s\n",
3311  filename_c, _dbus_strerror (errno));
3312  return FALSE;
3313  }
3314  else
3315  return TRUE;
3316 }
3317 
3328  DBusError *error)
3329 {
3330  const char *filename_c;
3331 
3332  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3333 
3334  filename_c = _dbus_string_get_const_data (filename);
3335 
3336  if (mkdir (filename_c, 0700) < 0)
3337  {
3339  "Failed to create directory %s: %s\n",
3340  filename_c, _dbus_strerror (errno));
3341  return FALSE;
3342  }
3343  else
3344  return TRUE;
3345 }
3346 
3359  const DBusString *next_component)
3360 {
3361  dbus_bool_t dir_ends_in_slash;
3362  dbus_bool_t file_starts_with_slash;
3363 
3364  if (_dbus_string_get_length (dir) == 0 ||
3365  _dbus_string_get_length (next_component) == 0)
3366  return TRUE;
3367 
3368  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3369  _dbus_string_get_length (dir) - 1);
3370 
3371  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3372 
3373  if (dir_ends_in_slash && file_starts_with_slash)
3374  {
3375  _dbus_string_shorten (dir, 1);
3376  }
3377  else if (!(dir_ends_in_slash || file_starts_with_slash))
3378  {
3379  if (!_dbus_string_append_byte (dir, '/'))
3380  return FALSE;
3381  }
3382 
3383  return _dbus_string_copy (next_component, 0, dir,
3384  _dbus_string_get_length (dir));
3385 }
3386 
3388 #define NANOSECONDS_PER_SECOND 1000000000
3390 #define MICROSECONDS_PER_SECOND 1000000
3392 #define MILLISECONDS_PER_SECOND 1000
3394 #define NANOSECONDS_PER_MILLISECOND 1000000
3396 #define MICROSECONDS_PER_MILLISECOND 1000
3397 
3402 void
3403 _dbus_sleep_milliseconds (int milliseconds)
3404 {
3405 #ifdef HAVE_NANOSLEEP
3406  struct timespec req;
3407  struct timespec rem;
3408 
3409  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3410  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3411  rem.tv_sec = 0;
3412  rem.tv_nsec = 0;
3413 
3414  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3415  req = rem;
3416 #elif defined (HAVE_USLEEP)
3417  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3418 #else /* ! HAVE_USLEEP */
3419  sleep (MAX (milliseconds / 1000, 1));
3420 #endif
3421 }
3422 
3434  int n_bytes,
3435  DBusError *error)
3436 {
3437  int old_len = _dbus_string_get_length (str);
3438  int fd;
3439  int result;
3440 #ifdef HAVE_GETRANDOM
3441  char *buffer;
3442 
3443  if (!_dbus_string_lengthen (str, n_bytes))
3444  {
3445  _DBUS_SET_OOM (error);
3446  return FALSE;
3447  }
3448 
3449  buffer = _dbus_string_get_data_len (str, old_len, n_bytes);
3450  result = getrandom (buffer, n_bytes, GRND_NONBLOCK);
3451 
3452  if (result == n_bytes)
3453  return TRUE;
3454 
3455  _dbus_string_set_length (str, old_len);
3456 #endif
3457 
3458  /* note, urandom on linux will fall back to pseudorandom */
3459  fd = open ("/dev/urandom", O_RDONLY);
3460 
3461  if (fd < 0)
3462  {
3463  dbus_set_error (error, _dbus_error_from_errno (errno),
3464  "Could not open /dev/urandom: %s",
3465  _dbus_strerror (errno));
3466  return FALSE;
3467  }
3468 
3469  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3470 
3471  result = _dbus_read (fd, str, n_bytes);
3472 
3473  if (result != n_bytes)
3474  {
3475  if (result < 0)
3476  dbus_set_error (error, _dbus_error_from_errno (errno),
3477  "Could not read /dev/urandom: %s",
3478  _dbus_strerror (errno));
3479  else
3481  "Short read from /dev/urandom");
3482 
3483  _dbus_close (fd, NULL);
3484  _dbus_string_set_length (str, old_len);
3485  return FALSE;
3486  }
3487 
3488  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3489  n_bytes);
3490 
3491  _dbus_close (fd, NULL);
3492 
3493  return TRUE;
3494 }
3495 
3501 void
3502 _dbus_exit (int code)
3503 {
3504  _exit (code);
3505 }
3506 
3515 const char*
3516 _dbus_strerror (int error_number)
3517 {
3518  const char *msg;
3519 
3520  msg = strerror (error_number);
3521  if (msg == NULL)
3522  msg = "unknown";
3523 
3524  return msg;
3525 }
3526 
3530 void
3532 {
3533  signal (SIGPIPE, SIG_IGN);
3534 }
3535 
3543 void
3545 {
3546  int val;
3547 
3548  val = fcntl (fd, F_GETFD, 0);
3549 
3550  if (val < 0)
3551  return;
3552 
3553  val |= FD_CLOEXEC;
3554 
3555  fcntl (fd, F_SETFD, val);
3556 }
3557 
3565 void
3567 {
3568  int val;
3569 
3570  val = fcntl (fd, F_GETFD, 0);
3571 
3572  if (val < 0)
3573  return;
3574 
3575  val &= ~FD_CLOEXEC;
3576 
3577  fcntl (fd, F_SETFD, val);
3578 }
3579 
3588 _dbus_close (int fd,
3589  DBusError *error)
3590 {
3591  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3592 
3593  again:
3594  if (close (fd) < 0)
3595  {
3596  if (errno == EINTR)
3597  goto again;
3598 
3599  dbus_set_error (error, _dbus_error_from_errno (errno),
3600  "Could not close fd %d", fd);
3601  return FALSE;
3602  }
3603 
3604  return TRUE;
3605 }
3606 
3615 int
3616 _dbus_dup(int fd,
3617  DBusError *error)
3618 {
3619  int new_fd;
3620 
3621 #ifdef F_DUPFD_CLOEXEC
3622  dbus_bool_t cloexec_done;
3623 
3624  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3625  cloexec_done = new_fd >= 0;
3626 
3627  if (new_fd < 0 && errno == EINVAL)
3628 #endif
3629  {
3630  new_fd = fcntl(fd, F_DUPFD, 3);
3631  }
3632 
3633  if (new_fd < 0) {
3634 
3635  dbus_set_error (error, _dbus_error_from_errno (errno),
3636  "Could not duplicate fd %d", fd);
3637  return -1;
3638  }
3639 
3640 #ifdef F_DUPFD_CLOEXEC
3641  if (!cloexec_done)
3642 #endif
3643  {
3645  }
3646 
3647  return new_fd;
3648 }
3649 
3659  DBusError *error)
3660 {
3661  return _dbus_set_fd_nonblocking (fd.fd, error);
3662 }
3663 
3664 static dbus_bool_t
3665 _dbus_set_fd_nonblocking (int fd,
3666  DBusError *error)
3667 {
3668  int val;
3669 
3670  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3671 
3672  val = fcntl (fd, F_GETFL, 0);
3673  if (val < 0)
3674  {
3675  dbus_set_error (error, _dbus_error_from_errno (errno),
3676  "Failed to get flags from file descriptor %d: %s",
3677  fd, _dbus_strerror (errno));
3678  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3679  _dbus_strerror (errno));
3680  return FALSE;
3681  }
3682 
3683  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3684  {
3685  dbus_set_error (error, _dbus_error_from_errno (errno),
3686  "Failed to set nonblocking flag of file descriptor %d: %s",
3687  fd, _dbus_strerror (errno));
3688  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3689  fd, _dbus_strerror (errno));
3690 
3691  return FALSE;
3692  }
3693 
3694  return TRUE;
3695 }
3696 
3702 void
3704 {
3705 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3706  void *bt[500];
3707  int bt_size;
3708  int i;
3709  char **syms;
3710 
3711  bt_size = backtrace (bt, 500);
3712 
3713  syms = backtrace_symbols (bt, bt_size);
3714 
3715  i = 0;
3716  while (i < bt_size)
3717  {
3718  /* don't use dbus_warn since it can _dbus_abort() */
3719  fprintf (stderr, " %s\n", syms[i]);
3720  ++i;
3721  }
3722  fflush (stderr);
3723 
3724  free (syms);
3725 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3726  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3727 #else
3728  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3729 #endif
3730 }
3731 
3746  DBusSocket *fd2,
3747  dbus_bool_t blocking,
3748  DBusError *error)
3749 {
3750 #ifdef HAVE_SOCKETPAIR
3751  int fds[2];
3752  int retval;
3753 
3754 #ifdef SOCK_CLOEXEC
3755  dbus_bool_t cloexec_done;
3756 
3757  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3758  cloexec_done = retval >= 0;
3759 
3760  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3761 #endif
3762  {
3763  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3764  }
3765 
3766  if (retval < 0)
3767  {
3768  dbus_set_error (error, _dbus_error_from_errno (errno),
3769  "Could not create full-duplex pipe");
3770  return FALSE;
3771  }
3772 
3773  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3774 
3775 #ifdef SOCK_CLOEXEC
3776  if (!cloexec_done)
3777 #endif
3778  {
3779  _dbus_fd_set_close_on_exec (fds[0]);
3780  _dbus_fd_set_close_on_exec (fds[1]);
3781  }
3782 
3783  if (!blocking &&
3784  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3785  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3786  {
3787  dbus_set_error (error, _dbus_error_from_errno (errno),
3788  "Could not set full-duplex pipe nonblocking");
3789 
3790  _dbus_close (fds[0], NULL);
3791  _dbus_close (fds[1], NULL);
3792 
3793  return FALSE;
3794  }
3795 
3796  fd1->fd = fds[0];
3797  fd2->fd = fds[1];
3798 
3799  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3800  fd1->fd, fd2->fd);
3801 
3802  return TRUE;
3803 #else
3804  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3806  "_dbus_socketpair() not implemented on this OS");
3807  return FALSE;
3808 #endif
3809 }
3810 
3819 int
3821  va_list args)
3822 {
3823  char static_buf[1024];
3824  int bufsize = sizeof (static_buf);
3825  int len;
3826  va_list args_copy;
3827 
3828  DBUS_VA_COPY (args_copy, args);
3829  len = vsnprintf (static_buf, bufsize, format, args_copy);
3830  va_end (args_copy);
3831 
3832  /* If vsnprintf() returned non-negative, then either the string fits in
3833  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3834  * returns the number of characters that were needed, or this OS returns the
3835  * truncated length.
3836  *
3837  * We ignore the possibility that snprintf might just ignore the length and
3838  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3839  * If your libc is really that bad, come back when you have a better one. */
3840  if (len == bufsize)
3841  {
3842  /* This could be the truncated length (Tru64 and IRIX have this bug),
3843  * or the real length could be coincidentally the same. Which is it?
3844  * If vsnprintf returns the truncated length, we'll go to the slow
3845  * path. */
3846  DBUS_VA_COPY (args_copy, args);
3847 
3848  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3849  len = -1;
3850 
3851  va_end (args_copy);
3852  }
3853 
3854  /* If vsnprintf() returned negative, we have to do more work.
3855  * HP-UX returns negative. */
3856  while (len < 0)
3857  {
3858  char *buf;
3859 
3860  bufsize *= 2;
3861 
3862  buf = dbus_malloc (bufsize);
3863 
3864  if (buf == NULL)
3865  return -1;
3866 
3867  DBUS_VA_COPY (args_copy, args);
3868  len = vsnprintf (buf, bufsize, format, args_copy);
3869  va_end (args_copy);
3870 
3871  dbus_free (buf);
3872 
3873  /* If the reported length is exactly the buffer size, round up to the
3874  * next size, in case vsnprintf has been returning the truncated
3875  * length */
3876  if (len == bufsize)
3877  len = -1;
3878  }
3879 
3880  return len;
3881 }
3882 
3889 const char*
3891 {
3892  /* Protected by _DBUS_LOCK_sysdeps */
3893  static const char* tmpdir = NULL;
3894 
3895  if (!_DBUS_LOCK (sysdeps))
3896  return NULL;
3897 
3898  if (tmpdir == NULL)
3899  {
3900  /* TMPDIR is what glibc uses, then
3901  * glibc falls back to the P_tmpdir macro which
3902  * just expands to "/tmp"
3903  */
3904  if (tmpdir == NULL)
3905  tmpdir = getenv("TMPDIR");
3906 
3907  /* These two env variables are probably
3908  * broken, but maybe some OS uses them?
3909  */
3910  if (tmpdir == NULL)
3911  tmpdir = getenv("TMP");
3912  if (tmpdir == NULL)
3913  tmpdir = getenv("TEMP");
3914 
3915  /* And this is the sane fallback. */
3916  if (tmpdir == NULL)
3917  tmpdir = "/tmp";
3918  }
3919 
3920  _DBUS_UNLOCK (sysdeps);
3921 
3922  _dbus_assert(tmpdir != NULL);
3923 
3924  return tmpdir;
3925 }
3926 
3927 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3947 static dbus_bool_t
3948 _read_subprocess_line_argv (const char *progpath,
3949  dbus_bool_t path_fallback,
3950  const char * const *argv,
3951  DBusString *result,
3952  DBusError *error)
3953 {
3954  int result_pipe[2] = { -1, -1 };
3955  int errors_pipe[2] = { -1, -1 };
3956  pid_t pid;
3957  int ret;
3958  int status;
3959  int orig_len;
3960 
3961  dbus_bool_t retval;
3962  sigset_t new_set, old_set;
3963 
3964  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3965  retval = FALSE;
3966 
3967  /* We need to block any existing handlers for SIGCHLD temporarily; they
3968  * will cause waitpid() below to fail.
3969  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3970  */
3971  sigemptyset (&new_set);
3972  sigaddset (&new_set, SIGCHLD);
3973  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3974 
3975  orig_len = _dbus_string_get_length (result);
3976 
3977 #define READ_END 0
3978 #define WRITE_END 1
3979  if (pipe (result_pipe) < 0)
3980  {
3981  dbus_set_error (error, _dbus_error_from_errno (errno),
3982  "Failed to create a pipe to call %s: %s",
3983  progpath, _dbus_strerror (errno));
3984  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3985  progpath, _dbus_strerror (errno));
3986  goto out;
3987  }
3988  if (pipe (errors_pipe) < 0)
3989  {
3990  dbus_set_error (error, _dbus_error_from_errno (errno),
3991  "Failed to create a pipe to call %s: %s",
3992  progpath, _dbus_strerror (errno));
3993  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3994  progpath, _dbus_strerror (errno));
3995  goto out;
3996  }
3997 
3998  /* Make sure our output buffers aren't redundantly printed by both the
3999  * parent and the child */
4000  fflush (stdout);
4001  fflush (stderr);
4002 
4003  pid = fork ();
4004  if (pid < 0)
4005  {
4006  dbus_set_error (error, _dbus_error_from_errno (errno),
4007  "Failed to fork() to call %s: %s",
4008  progpath, _dbus_strerror (errno));
4009  _dbus_verbose ("Failed to fork() to call %s: %s\n",
4010  progpath, _dbus_strerror (errno));
4011  goto out;
4012  }
4013 
4014  if (pid == 0)
4015  {
4016  /* child process */
4017  const char *error_str;
4018 
4019  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
4020  {
4021  int saved_errno = errno;
4022 
4023  /* Try to write details into the pipe, but don't bother
4024  * trying too hard (no retry loop). */
4025 
4026  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
4027  write (errors_pipe[WRITE_END], ": ", 2) < 0)
4028  {
4029  /* ignore, not much we can do */
4030  }
4031 
4032  error_str = _dbus_strerror (saved_errno);
4033 
4034  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
4035  {
4036  /* ignore, not much we can do */
4037  }
4038 
4039  _exit (1);
4040  }
4041 
4042  /* set-up stdXXX */
4043  close (result_pipe[READ_END]);
4044  close (errors_pipe[READ_END]);
4045 
4046  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
4047  _exit (1);
4048  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
4049  _exit (1);
4050 
4051  _dbus_close_all ();
4052 
4053  sigprocmask (SIG_SETMASK, &old_set, NULL);
4054 
4055  /* If it looks fully-qualified, try execv first */
4056  if (progpath[0] == '/')
4057  {
4058  execv (progpath, (char * const *) argv);
4059  /* Ok, that failed. Now if path_fallback is given, let's
4060  * try unqualified. This is mostly a hack to work
4061  * around systems which ship dbus-launch in /usr/bin
4062  * but everything else in /bin (because dbus-launch
4063  * depends on X11).
4064  */
4065  if (path_fallback)
4066  /* We must have a slash, because we checked above */
4067  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4068  }
4069  else
4070  execvp (progpath, (char * const *) argv);
4071 
4072  /* still nothing, we failed */
4073  _exit (1);
4074  }
4075 
4076  /* parent process */
4077  close (result_pipe[WRITE_END]);
4078  close (errors_pipe[WRITE_END]);
4079  result_pipe[WRITE_END] = -1;
4080  errors_pipe[WRITE_END] = -1;
4081 
4082  ret = 0;
4083  do
4084  {
4085  ret = _dbus_read (result_pipe[READ_END], result, 1024);
4086  }
4087  while (ret > 0);
4088 
4089  /* reap the child process to avoid it lingering as zombie */
4090  do
4091  {
4092  ret = waitpid (pid, &status, 0);
4093  }
4094  while (ret == -1 && errno == EINTR);
4095 
4096  /* We succeeded if the process exited with status 0 and
4097  anything was read */
4098  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4099  {
4100  /* The process ended with error */
4101  DBusString error_message;
4102  if (!_dbus_string_init (&error_message))
4103  {
4104  _DBUS_SET_OOM (error);
4105  goto out;
4106  }
4107 
4108  ret = 0;
4109  do
4110  {
4111  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4112  }
4113  while (ret > 0);
4114 
4115  _dbus_string_set_length (result, orig_len);
4116  if (_dbus_string_get_length (&error_message) > 0)
4118  "%s terminated abnormally with the following error: %s",
4119  progpath, _dbus_string_get_data (&error_message));
4120  else
4122  "%s terminated abnormally without any error message",
4123  progpath);
4124  goto out;
4125  }
4126 
4127  retval = TRUE;
4128 
4129  out:
4130  sigprocmask (SIG_SETMASK, &old_set, NULL);
4131 
4132  _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4133 
4134  if (result_pipe[0] != -1)
4135  close (result_pipe[0]);
4136  if (result_pipe[1] != -1)
4137  close (result_pipe[1]);
4138  if (errors_pipe[0] != -1)
4139  close (errors_pipe[0]);
4140  if (errors_pipe[1] != -1)
4141  close (errors_pipe[1]);
4142 
4143  return retval;
4144 }
4145 #endif
4146 
4160 _dbus_get_autolaunch_address (const char *scope,
4161  DBusString *address,
4162  DBusError *error)
4163 {
4164 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4165  static const char arg_dbus_launch[] = "dbus-launch";
4166  static const char arg_autolaunch[] = "--autolaunch";
4167  static const char arg_binary_syntax[] = "--binary-syntax";
4168  static const char arg_close_stderr[] = "--close-stderr";
4169 
4170  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4171  * but that's done elsewhere, and if it worked, this function wouldn't
4172  * be called.) */
4173  const char *display;
4174  const char *progpath;
4175  const char *argv[6];
4176  int i;
4177  DBusString uuid;
4178  dbus_bool_t retval;
4179 
4180  if (_dbus_check_setuid ())
4181  {
4183  "Unable to autolaunch when setuid");
4184  return FALSE;
4185  }
4186 
4187  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4188  retval = FALSE;
4189 
4190  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4191  * dbus-launch-x11 is just going to fail. Rather than trying to
4192  * run it, we might as well bail out early with a nice error.
4193  *
4194  * This is not strictly true in a world where the user bus exists,
4195  * because dbus-launch --autolaunch knows how to connect to that -
4196  * but if we were going to connect to the user bus, we'd have done
4197  * so before trying autolaunch: in any case. */
4198  display = _dbus_getenv ("DISPLAY");
4199 
4200  if (display == NULL || display[0] == '\0')
4201  {
4203  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4204  return FALSE;
4205  }
4206 
4207  if (!_dbus_string_init (&uuid))
4208  {
4209  _DBUS_SET_OOM (error);
4210  return FALSE;
4211  }
4212 
4213  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4214  {
4215  goto out;
4216  }
4217 
4218 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4219  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4220 
4221  if (progpath == NULL)
4222 #endif
4223  progpath = DBUS_BINDIR "/dbus-launch";
4224  /*
4225  * argv[0] is always dbus-launch, that's the name what we'll
4226  * get from /proc, or ps(1), regardless what the progpath is,
4227  * see fd.o#69716
4228  */
4229  i = 0;
4230  argv[i] = arg_dbus_launch;
4231  ++i;
4232  argv[i] = arg_autolaunch;
4233  ++i;
4234  argv[i] = _dbus_string_get_data (&uuid);
4235  ++i;
4236  argv[i] = arg_binary_syntax;
4237  ++i;
4238  argv[i] = arg_close_stderr;
4239  ++i;
4240  argv[i] = NULL;
4241  ++i;
4242 
4243  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4244 
4245  retval = _read_subprocess_line_argv (progpath,
4246  TRUE,
4247  argv, address, error);
4248 
4249  out:
4250  _dbus_string_free (&uuid);
4251  return retval;
4252 #else
4254  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4255  "set your DBUS_SESSION_BUS_ADDRESS instead");
4256  return FALSE;
4257 #endif
4258 }
4259 
4280  dbus_bool_t create_if_not_found,
4281  DBusError *error)
4282 {
4283  DBusError our_error = DBUS_ERROR_INIT;
4284  DBusError etc_error = DBUS_ERROR_INIT;
4285  DBusString filename;
4286  dbus_bool_t b;
4287 
4288  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4289 
4290  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4291  if (b)
4292  return TRUE;
4293 
4294  /* Fallback to the system machine ID */
4295  _dbus_string_init_const (&filename, "/etc/machine-id");
4296  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4297 
4298  if (b)
4299  {
4300  if (create_if_not_found)
4301  {
4302  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4303  * complain if that isn't possible for whatever reason */
4304  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4305  _dbus_write_uuid_file (&filename, machine_id, NULL);
4306  }
4307 
4308  dbus_error_free (&our_error);
4309  return TRUE;
4310  }
4311 
4312  if (!create_if_not_found)
4313  {
4314  dbus_set_error (error, etc_error.name,
4315  "D-Bus library appears to be incorrectly set up: "
4316  "see the manual page for dbus-uuidgen to correct "
4317  "this issue. (%s; %s)",
4318  our_error.message, etc_error.message);
4319  dbus_error_free (&our_error);
4320  dbus_error_free (&etc_error);
4321  return FALSE;
4322  }
4323 
4324  dbus_error_free (&our_error);
4325  dbus_error_free (&etc_error);
4326 
4327  /* if none found, try to make a new one */
4328  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4329 
4330  if (!_dbus_generate_uuid (machine_id, error))
4331  return FALSE;
4332 
4333  return _dbus_write_uuid_file (&filename, machine_id, error);
4334 }
4335 
4345  const char *launchd_env_var,
4346  DBusError *error)
4347 {
4348 #ifdef DBUS_ENABLE_LAUNCHD
4349  char *argv[4];
4350  int i;
4351 
4352  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4353 
4354  if (_dbus_check_setuid ())
4355  {
4357  "Unable to find launchd socket when setuid");
4358  return FALSE;
4359  }
4360 
4361  i = 0;
4362  argv[i] = "launchctl";
4363  ++i;
4364  argv[i] = "getenv";
4365  ++i;
4366  argv[i] = (char*)launchd_env_var;
4367  ++i;
4368  argv[i] = NULL;
4369  ++i;
4370 
4371  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4372 
4373  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4374  {
4375  return FALSE;
4376  }
4377 
4378  /* no error, but no result either */
4379  if (_dbus_string_get_length(socket_path) == 0)
4380  {
4381  return FALSE;
4382  }
4383 
4384  /* strip the carriage-return */
4385  _dbus_string_shorten(socket_path, 1);
4386  return TRUE;
4387 #else /* DBUS_ENABLE_LAUNCHD */
4389  "can't lookup socket from launchd; launchd support not compiled in");
4390  return FALSE;
4391 #endif
4392 }
4393 
4394 #ifdef DBUS_ENABLE_LAUNCHD
4395 static dbus_bool_t
4396 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4397 {
4398  dbus_bool_t valid_socket;
4399  DBusString socket_path;
4400 
4401  if (_dbus_check_setuid ())
4402  {
4404  "Unable to find launchd socket when setuid");
4405  return FALSE;
4406  }
4407 
4408  if (!_dbus_string_init (&socket_path))
4409  {
4410  _DBUS_SET_OOM (error);
4411  return FALSE;
4412  }
4413 
4414  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4415 
4416  if (dbus_error_is_set(error))
4417  {
4418  _dbus_string_free(&socket_path);
4419  return FALSE;
4420  }
4421 
4422  if (!valid_socket)
4423  {
4424  dbus_set_error(error, "no socket path",
4425  "launchd did not provide a socket path, "
4426  "verify that org.freedesktop.dbus-session.plist is loaded!");
4427  _dbus_string_free(&socket_path);
4428  return FALSE;
4429  }
4430  if (!_dbus_string_append (address, "unix:path="))
4431  {
4432  _DBUS_SET_OOM (error);
4433  _dbus_string_free(&socket_path);
4434  return FALSE;
4435  }
4436  if (!_dbus_string_copy (&socket_path, 0, address,
4437  _dbus_string_get_length (address)))
4438  {
4439  _DBUS_SET_OOM (error);
4440  _dbus_string_free(&socket_path);
4441  return FALSE;
4442  }
4443 
4444  _dbus_string_free(&socket_path);
4445  return TRUE;
4446 }
4447 #endif
4448 
4449 static dbus_bool_t
4450 _dbus_lookup_user_bus (dbus_bool_t *supported,
4451  DBusString *address,
4452  DBusError *error)
4453 {
4454  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4455  dbus_bool_t ret = FALSE;
4456  struct stat stbuf;
4457  DBusString user_bus_path;
4458 
4459  if (runtime_dir == NULL)
4460  {
4461  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4462  *supported = FALSE;
4463  return TRUE; /* Cannot use it, but not an error */
4464  }
4465 
4466  if (!_dbus_string_init (&user_bus_path))
4467  {
4468  _DBUS_SET_OOM (error);
4469  return FALSE;
4470  }
4471 
4472  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4473  {
4474  _DBUS_SET_OOM (error);
4475  goto out;
4476  }
4477 
4478  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4479  {
4480  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4481  _dbus_strerror (errno));
4482  *supported = FALSE;
4483  ret = TRUE; /* Cannot use it, but not an error */
4484  goto out;
4485  }
4486 
4487  if (stbuf.st_uid != getuid ())
4488  {
4489  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4490  (long) stbuf.st_uid, (long) getuid ());
4491  *supported = FALSE;
4492  ret = TRUE; /* Cannot use it, but not an error */
4493  goto out;
4494  }
4495 
4496  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4497  {
4498  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4499  (long) stbuf.st_mode);
4500  *supported = FALSE;
4501  ret = TRUE; /* Cannot use it, but not an error */
4502  goto out;
4503  }
4504 
4505  if (!_dbus_string_append (address, "unix:path=") ||
4506  !_dbus_address_append_escaped (address, &user_bus_path))
4507  {
4508  _DBUS_SET_OOM (error);
4509  goto out;
4510  }
4511 
4512  *supported = TRUE;
4513  ret = TRUE;
4514 
4515 out:
4516  _dbus_string_free (&user_bus_path);
4517  return ret;
4518 }
4519 
4541  DBusString *address,
4542  DBusError *error)
4543 {
4544 #ifdef DBUS_ENABLE_LAUNCHD
4545  *supported = TRUE;
4546  return _dbus_lookup_session_address_launchd (address, error);
4547 #else
4548  *supported = FALSE;
4549 
4550  if (!_dbus_lookup_user_bus (supported, address, error))
4551  return FALSE;
4552  else if (*supported)
4553  return TRUE;
4554 
4555  /* On non-Mac Unix platforms, if the session address isn't already
4556  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4557  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4558  * autolaunch: global default; see init_session_address in
4559  * dbus/dbus-bus.c. */
4560  return TRUE;
4561 #endif
4562 }
4563 
4571 void
4573 {
4575 }
4576 
4592  DBusCredentials *credentials)
4593 {
4594  DBusString homedir;
4595  DBusString dotdir;
4596  dbus_uid_t uid;
4597 
4598  _dbus_assert (credentials != NULL);
4600 
4601  if (!_dbus_string_init (&homedir))
4602  return FALSE;
4603 
4604  uid = _dbus_credentials_get_unix_uid (credentials);
4605  _dbus_assert (uid != DBUS_UID_UNSET);
4606 
4607  if (!_dbus_homedir_from_uid (uid, &homedir))
4608  goto failed;
4609 
4610 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4611  {
4612  const char *override;
4613 
4614  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4615  if (override != NULL && *override != '\0')
4616  {
4617  _dbus_string_set_length (&homedir, 0);
4618  if (!_dbus_string_append (&homedir, override))
4619  goto failed;
4620 
4621  _dbus_verbose ("Using fake homedir for testing: %s\n",
4622  _dbus_string_get_const_data (&homedir));
4623  }
4624  else
4625  {
4626  /* Not strictly thread-safe, but if we fail at thread-safety here,
4627  * the worst that will happen is some extra warnings. */
4628  static dbus_bool_t already_warned = FALSE;
4629  if (!already_warned)
4630  {
4631  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4632  _dbus_string_get_const_data (&homedir));
4633  already_warned = TRUE;
4634  }
4635  }
4636  }
4637 #endif
4638 
4639  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4640  if (!_dbus_concat_dir_and_file (&homedir,
4641  &dotdir))
4642  goto failed;
4643 
4644  if (!_dbus_string_copy (&homedir, 0,
4645  directory, _dbus_string_get_length (directory))) {
4646  goto failed;
4647  }
4648 
4649  _dbus_string_free (&homedir);
4650  return TRUE;
4651 
4652  failed:
4653  _dbus_string_free (&homedir);
4654  return FALSE;
4655 }
4656 
4657 /* Documented in dbus-sysdeps-win.c, does nothing on Unix */
4659 _dbus_daemon_unpublish_session_bus_address (void)
4660 {
4661  return TRUE;
4662 }
4663 
4672 {
4673  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4674  * EWOULDBLOCK are numerically equal, which is permitted as described by
4675  * errno(3).
4676  */
4677 #if EAGAIN == EWOULDBLOCK
4678  return e == EAGAIN;
4679 #else
4680  return e == EAGAIN || e == EWOULDBLOCK;
4681 #endif
4682 }
4683 
4693  DBusError *error)
4694 {
4695  const char *filename_c;
4696 
4697  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4698 
4699  filename_c = _dbus_string_get_const_data (filename);
4700 
4701  if (rmdir (filename_c) != 0)
4702  {
4704  "Failed to remove directory %s: %s\n",
4705  filename_c, _dbus_strerror (errno));
4706  return FALSE;
4707  }
4708 
4709  return TRUE;
4710 }
4711 
4721 {
4722 #ifdef SCM_RIGHTS
4723  union {
4724  struct sockaddr sa;
4725  struct sockaddr_storage storage;
4726  struct sockaddr_un un;
4727  } sa_buf;
4728 
4729  socklen_t sa_len = sizeof(sa_buf);
4730 
4731  _DBUS_ZERO(sa_buf);
4732 
4733  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4734  return FALSE;
4735 
4736  return sa_buf.sa.sa_family == AF_UNIX;
4737 
4738 #else
4739  return FALSE;
4740 
4741 #endif
4742 }
4743 
4744 static void
4745 close_ignore_error (int fd)
4746 {
4747  close (fd);
4748 }
4749 
4750 /*
4751  * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4752  * and may call func for integers that are not actually valid fds.
4753  */
4754 static void
4755 act_on_fds_3_and_up (void (*func) (int fd))
4756 {
4757  int maxfds, i;
4758 
4759 #if defined(__linux__) && defined(__GLIBC__)
4760  DIR *d;
4761 
4762  /* On Linux we can optimize this a bit if /proc is available. If it
4763  isn't available, fall back to the brute force way. */
4764 
4765  d = opendir ("/proc/self/fd");
4766  if (d)
4767  {
4768  for (;;)
4769  {
4770  struct dirent *de;
4771  int fd;
4772  long l;
4773  char *e = NULL;
4774 
4775  de = readdir (d);
4776  if (!de)
4777  break;
4778 
4779  if (de->d_name[0] == '.')
4780  continue;
4781 
4782  errno = 0;
4783  l = strtol (de->d_name, &e, 10);
4784  if (errno != 0 || e == NULL || *e != '\0')
4785  continue;
4786 
4787  fd = (int) l;
4788  if (fd < 3)
4789  continue;
4790 
4791  if (fd == dirfd (d))
4792  continue;
4793 
4794  func (fd);
4795  }
4796 
4797  closedir (d);
4798  return;
4799  }
4800 #endif
4801 
4802  maxfds = sysconf (_SC_OPEN_MAX);
4803 
4804  /* Pick something reasonable if for some reason sysconf says
4805  * unlimited.
4806  */
4807  if (maxfds < 0)
4808  maxfds = 1024;
4809 
4810  /* close all inherited fds */
4811  for (i = 3; i < maxfds; i++)
4812  func (i);
4813 }
4814 
4819 void
4821 {
4822 #ifdef HAVE_CLOSE_RANGE
4823  if (close_range (3, INT_MAX, 0) == 0)
4824  return;
4825 #endif
4826 
4827  /* Some library implementations of closefrom() are not async-signal-safe,
4828  * and we call _dbus_close_all() after forking, so we only do this on
4829  * operating systems where we know that closefrom() is a system call */
4830 #if defined(HAVE_CLOSEFROM) && ( \
4831  defined(__FreeBSD__) || \
4832  defined(__NetBSD__) || \
4833  defined(__OpenBSD__) || \
4834  defined(__sun__) && defined(F_CLOSEFROM) \
4835 )
4836  closefrom (3);
4837 #else
4838  act_on_fds_3_and_up (close_ignore_error);
4839 #endif
4840 }
4841 
4846 void
4848 {
4849 #if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC)
4850  if (close_range (3, INT_MAX, CLOSE_RANGE_CLOEXEC) == 0)
4851  return;
4852 #endif
4853 
4854  act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4855 }
4856 
4868 {
4869  /* TODO: get __libc_enable_secure exported from glibc.
4870  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4871  */
4872 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4873  {
4874  /* See glibc/include/unistd.h */
4875  extern int __libc_enable_secure;
4876  return __libc_enable_secure;
4877  }
4878 #elif defined(HAVE_ISSETUGID)
4879  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4880  return issetugid ();
4881 #else
4882  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4883  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4884 
4885  /* We call into this function from _dbus_threads_init_platform_specific()
4886  * to make sure these are initialized before we start threading. */
4887  static dbus_bool_t check_setuid_initialised;
4888  static dbus_bool_t is_setuid;
4889 
4890  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4891  {
4892 #ifdef HAVE_GETRESUID
4893  if (getresuid (&ruid, &euid, &suid) != 0 ||
4894  getresgid (&rgid, &egid, &sgid) != 0)
4895 #endif /* HAVE_GETRESUID */
4896  {
4897  suid = ruid = getuid ();
4898  sgid = rgid = getgid ();
4899  euid = geteuid ();
4900  egid = getegid ();
4901  }
4902 
4903  check_setuid_initialised = TRUE;
4904  is_setuid = (ruid != euid || ruid != suid ||
4905  rgid != egid || rgid != sgid);
4906 
4907  }
4908  return is_setuid;
4909 #endif
4910 }
4911 
4921  DBusString *address,
4922  DBusError *error)
4923 {
4924  union {
4925  struct sockaddr sa;
4926  struct sockaddr_storage storage;
4927  struct sockaddr_un un;
4928  struct sockaddr_in ipv4;
4929  struct sockaddr_in6 ipv6;
4930  } socket;
4931  char hostip[INET6_ADDRSTRLEN];
4932  socklen_t size = sizeof (socket);
4933  DBusString path_str;
4934  const char *family_name = NULL;
4935  dbus_uint16_t port;
4936 
4937  if (getsockname (fd.fd, &socket.sa, &size))
4938  goto err;
4939 
4940  switch (socket.sa.sa_family)
4941  {
4942  case AF_UNIX:
4943  if (socket.un.sun_path[0]=='\0')
4944  {
4945  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4946  if (_dbus_string_append (address, "unix:abstract=") &&
4947  _dbus_address_append_escaped (address, &path_str))
4948  {
4949  return TRUE;
4950  }
4951  else
4952  {
4953  _DBUS_SET_OOM (error);
4954  return FALSE;
4955  }
4956  }
4957  else
4958  {
4959  _dbus_string_init_const (&path_str, socket.un.sun_path);
4960  if (_dbus_string_append (address, "unix:path=") &&
4961  _dbus_address_append_escaped (address, &path_str))
4962  {
4963  return TRUE;
4964  }
4965  else
4966  {
4967  _DBUS_SET_OOM (error);
4968  return FALSE;
4969  }
4970  }
4971  /* not reached */
4972  break;
4973 
4974  case AF_INET:
4975 #ifdef AF_INET6
4976  case AF_INET6:
4977 #endif
4978  _dbus_string_init_const (&path_str, hostip);
4979 
4980  if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
4981  &family_name, &port, error))
4982  {
4983  if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
4984  family_name, port) &&
4985  _dbus_address_append_escaped (address, &path_str))
4986  {
4987  return TRUE;
4988  }
4989  else
4990  {
4991  _DBUS_SET_OOM (error);
4992  return FALSE;
4993  }
4994  }
4995  else
4996  {
4997  return FALSE;
4998  }
4999  /* not reached */
5000  break;
5001 
5002  default:
5003  dbus_set_error (error,
5004  _dbus_error_from_errno (EINVAL),
5005  "Failed to read address from socket: Unknown socket type.");
5006  return FALSE;
5007  }
5008  err:
5009  dbus_set_error (error,
5010  _dbus_error_from_errno (errno),
5011  "Failed to read address from socket: %s",
5012  _dbus_strerror (errno));
5013  return FALSE;
5014 }
5015 
5016 int
5017 _dbus_save_socket_errno (void)
5018 {
5019  return errno;
5020 }
5021 
5022 void
5023 _dbus_restore_socket_errno (int saved_errno)
5024 {
5025  errno = saved_errno;
5026 }
5027 
5028 static const char *syslog_tag = "dbus";
5029 #ifdef HAVE_SYSLOG_H
5030 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
5031 #endif
5032 
5047 void
5048 _dbus_init_system_log (const char *tag,
5049  DBusLogFlags flags)
5050 {
5051  /* We never want to turn off logging completely */
5052  _dbus_assert (
5053  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
5054 
5055  syslog_tag = tag;
5056 
5057 #ifdef HAVE_SYSLOG_H
5058  log_flags = flags;
5059 
5060  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5061  openlog (tag, LOG_PID, LOG_DAEMON);
5062 #endif
5063 }
5064 
5072 void
5073 _dbus_logv (DBusSystemLogSeverity severity,
5074  const char *msg,
5075  va_list args)
5076 {
5077  va_list tmp;
5078 #ifdef HAVE_SYSLOG_H
5079  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5080  {
5081  int flags;
5082  switch (severity)
5083  {
5084  case DBUS_SYSTEM_LOG_INFO:
5085  flags = LOG_DAEMON | LOG_INFO;
5086  break;
5087  case DBUS_SYSTEM_LOG_WARNING:
5088  flags = LOG_DAEMON | LOG_WARNING;
5089  break;
5090  case DBUS_SYSTEM_LOG_SECURITY:
5091  flags = LOG_AUTH | LOG_NOTICE;
5092  break;
5093  case DBUS_SYSTEM_LOG_ERROR:
5094  flags = LOG_DAEMON|LOG_CRIT;
5095  break;
5096  default:
5097  _dbus_assert_not_reached ("invalid log severity");
5098  }
5099 
5100  DBUS_VA_COPY (tmp, args);
5101  vsyslog (flags, msg, tmp);
5102  va_end (tmp);
5103  }
5104 
5105  /* If we don't have syslog.h, we always behave as though stderr was in
5106  * the flags */
5107  if (log_flags & DBUS_LOG_FLAGS_STDERR)
5108 #endif
5109  {
5110  DBUS_VA_COPY (tmp, args);
5111  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5112  vfprintf (stderr, msg, tmp);
5113  fputc ('\n', stderr);
5114  va_end (tmp);
5115  }
5116 }
5117 
5118 /*
5119  * Return the low-level representation of a socket error, as used by
5120  * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5121  * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5122  *
5123  * Some libdbus internal functions copy this into errno, but with
5124  * hindsight that was probably a design flaw.
5125  */
5126 int
5127 _dbus_get_low_level_socket_errno (void)
5128 {
5129  return errno;
5130 }
5131 
5132 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:107
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials.
void _dbus_credentials_take_unix_gids(DBusCredentials *credentials, dbus_gid_t *gids, size_t n_gids)
Add UNIX group IDs to the credentials, replacing any group IDs that might already have been present.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:599
#define READ_END
Helps remember which end of the pipe is which.
#define WRITE_END
Helps remember which end of the pipe is which.
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:394
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:464
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
#define _DBUS_INT32_MAX
Maximum value of type "int32".
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:692
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:592
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:452
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:847
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:980
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1345
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:139
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:278
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:535
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:825
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:805
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:401
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1190
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1147
void _dbus_fd_clear_close_on_exec(int fd)
Sets the file descriptor to not be close-on-exec.
void _dbus_fd_set_all_close_on_exec(void)
Sets all file descriptors except the first three (i.e.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer.
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:429
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:137
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted)
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:135
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
void _dbus_exit(int code)
Exit the process, returning the given value.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:431
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
void _dbus_atomic_set_nonzero(DBusAtomic *atomic)
Atomically set the value of an integer to something nonzero.
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:139
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, unsigned int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:144
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
dbus_bool_t _dbus_read_credentials_socket(DBusSocket client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:142
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
DBusSocket _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR,...
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:146
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:425
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, const char **retfamily, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the most important credentials of the current process (the uid and pid) to the passed-in credent...
dbus_bool_t _dbus_close_socket(DBusSocket *fd, DBusError *error)
Closes a socket and invalidates it.
DBusSocket _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
void _dbus_atomic_set_zero(DBusAtomic *atomic)
Atomically set the value of an integer to 0.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with.
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:153
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul.
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:151
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
DBusSocket _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
#define _DBUS_MAX_SUN_PATH_LENGTH
Maximum length of the path to a UNIX domain socket, sockaddr_un::sun_path member.
Definition: dbus-sysdeps.h:745
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked.
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:149
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
unsigned short dbus_uint16_t
A 16-bit unsigned integer on all platforms.
int dbus_int32_t
A 32-bit signed integer on all platforms.
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:323
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:327
Object representing an exception.
Definition: dbus-errors.h:49
const char * name
public error name field
Definition: dbus-errors.h:50
const char * message
public error message field
Definition: dbus-errors.h:51
A node in a linked list.
Definition: dbus-list.h:35
short events
Events to poll for.
Definition: dbus-sysdeps.h:420
short revents
Events that occurred.
Definition: dbus-sysdeps.h:421
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:419
Socket interface.
Definition: dbus-sysdeps.h:181
Information about a UNIX user.
int n_group_ids
Size of group IDs array.
dbus_uid_t uid
UID.
char * homedir
Home directory.
dbus_gid_t * group_ids
Groups IDs, including above primary group.
char * username
Username.
dbus_gid_t primary_gid
GID.
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...