D-Bus  1.12.20
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 <sys/types.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <fcntl.h>
47 #include <sys/socket.h>
48 #include <dirent.h>
49 #include <sys/un.h>
50 #include <pwd.h>
51 #include <time.h>
52 #include <locale.h>
53 #include <sys/time.h>
54 #include <sys/stat.h>
55 #include <sys/wait.h>
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
58 #include <netdb.h>
59 #include <grp.h>
60 #include <arpa/inet.h>
61 
62 #ifdef HAVE_ERRNO_H
63 #include <errno.h>
64 #endif
65 #ifdef HAVE_SYSLOG_H
66 #include <syslog.h>
67 #endif
68 #ifdef HAVE_WRITEV
69 #include <sys/uio.h>
70 #endif
71 #ifdef HAVE_POLL
72 #include <sys/poll.h>
73 #endif
74 #ifdef HAVE_BACKTRACE
75 #include <execinfo.h>
76 #endif
77 #ifdef HAVE_GETPEERUCRED
78 #include <ucred.h>
79 #endif
80 #ifdef HAVE_ALLOCA_H
81 #include <alloca.h>
82 #endif
83 
84 #ifdef HAVE_ADT
85 #include <bsm/adt.h>
86 #endif
87 
88 #ifdef HAVE_SYSTEMD
89 #include <systemd/sd-daemon.h>
90 #endif
91 
92 #if !DBUS_USE_SYNC
93 #include <pthread.h>
94 #endif
95 
96 #ifndef O_BINARY
97 #define O_BINARY 0
98 #endif
99 
100 #ifndef AI_ADDRCONFIG
101 #define AI_ADDRCONFIG 0
102 #endif
103 
104 #ifndef HAVE_SOCKLEN_T
105 #define socklen_t int
106 #endif
107 
108 #if defined (__sun) || defined (__sun__)
109 /*
110  * CMS_SPACE etc. definitions for Solaris < 10, based on
111  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
112  * via
113  * http://wiki.opencsw.org/porting-faq#toc10
114  *
115  * These are only redefined for Solaris, for now: if your OS needs these too,
116  * please file a bug. (Or preferably, improve your OS so they're not needed.)
117  */
118 
119 # ifndef CMSG_ALIGN
120 # ifdef __sun__
121 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
122 # else
123  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
124 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
125  ~(sizeof (long) - 1))
126 # endif
127 # endif
128 
129 # ifndef CMSG_SPACE
130 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
131  CMSG_ALIGN (len))
132 # endif
133 
134 # ifndef CMSG_LEN
135 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
136 # endif
137 
138 #endif /* Solaris */
139 
155 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
156  const char **error_str_p)
157 {
158  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
159  DBUS_FORCE_STDOUT_NULL,
160  DBUS_FORCE_STDERR_NULL };
161  /* Should always get replaced with the real error before use */
162  const char *error_str = "Failed mysteriously";
163  int devnull = -1;
164  int saved_errno;
165  /* This function relies on the standard fds having their POSIX values. */
166  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
167  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
168  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
169  int i;
170 
171  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
172  {
173  /* Because we rely on being single-threaded, and we want the
174  * standard fds to not be close-on-exec, we don't set it
175  * close-on-exec. */
176  if (devnull < i)
177  devnull = open ("/dev/null", O_RDWR);
178 
179  if (devnull < 0)
180  {
181  error_str = "Failed to open /dev/null";
182  goto out;
183  }
184 
185  /* We already opened all fds < i, so the only way this assertion
186  * could fail is if another thread closed one, and we document
187  * this function as not safe for multi-threading. */
188  _dbus_assert (devnull >= i);
189 
190  if (devnull != i && (flags & relevant_flag[i]) != 0)
191  {
192  if (dup2 (devnull, i) < 0)
193  {
194  error_str = "Failed to dup2 /dev/null onto a standard fd";
195  goto out;
196  }
197  }
198  }
199 
200  error_str = NULL;
201 
202 out:
203  saved_errno = errno;
204 
205  if (devnull > STDERR_FILENO)
206  close (devnull);
207 
208  if (error_str_p != NULL)
209  *error_str_p = error_str;
210 
211  errno = saved_errno;
212  return (error_str == NULL);
213 }
214 
215 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
216  DBusError *error);
217 
218 static dbus_bool_t
219 _dbus_open_socket (int *fd_p,
220  int domain,
221  int type,
222  int protocol,
223  DBusError *error)
224 {
225 #ifdef SOCK_CLOEXEC
226  dbus_bool_t cloexec_done;
227 
228  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
229  cloexec_done = *fd_p >= 0;
230 
231  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
232  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
233 #endif
234  {
235  *fd_p = socket (domain, type, protocol);
236  }
237 
238  if (*fd_p >= 0)
239  {
240 #ifdef SOCK_CLOEXEC
241  if (!cloexec_done)
242 #endif
243  {
245  }
246 
247  _dbus_verbose ("socket fd %d opened\n", *fd_p);
248  return TRUE;
249  }
250  else
251  {
252  dbus_set_error(error,
253  _dbus_error_from_errno (errno),
254  "Failed to open socket: %s",
255  _dbus_strerror (errno));
256  return FALSE;
257  }
258 }
259 
270 static dbus_bool_t
271 _dbus_open_unix_socket (int *fd,
272  DBusError *error)
273 {
274  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
275 }
276 
287  DBusError *error)
288 {
289  return _dbus_close (fd.fd, error);
290 }
291 
301 int
303  DBusString *buffer,
304  int count)
305 {
306  return _dbus_read (fd.fd, buffer, count);
307 }
308 
319 int
321  const DBusString *buffer,
322  int start,
323  int len)
324 {
325 #if HAVE_DECL_MSG_NOSIGNAL
326  const char *data;
327  int bytes_written;
328 
329  data = _dbus_string_get_const_data_len (buffer, start, len);
330 
331  again:
332 
333  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
334 
335  if (bytes_written < 0 && errno == EINTR)
336  goto again;
337 
338  return bytes_written;
339 
340 #else
341  return _dbus_write (fd.fd, buffer, start, len);
342 #endif
343 }
344 
357 int
359  DBusString *buffer,
360  int count,
361  int *fds,
362  unsigned int *n_fds) {
363 #ifndef HAVE_UNIX_FD_PASSING
364  int r;
365 
366  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
367  return r;
368 
369  *n_fds = 0;
370  return r;
371 
372 #else
373  int bytes_read;
374  int start;
375  struct msghdr m;
376  struct iovec iov;
377 
378  _dbus_assert (count >= 0);
380 
381  start = _dbus_string_get_length (buffer);
382 
383  if (!_dbus_string_lengthen (buffer, count))
384  {
385  errno = ENOMEM;
386  return -1;
387  }
388 
389  _DBUS_ZERO(iov);
390  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
391  iov.iov_len = count;
392 
393  _DBUS_ZERO(m);
394  m.msg_iov = &iov;
395  m.msg_iovlen = 1;
396 
397  /* Hmm, we have no clue how long the control data will actually be
398  that is queued for us. The least we can do is assume that the
399  caller knows. Hence let's make space for the number of fds that
400  we shall read at max plus the cmsg header. */
401  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
402 
403  /* It's probably safe to assume that systems with SCM_RIGHTS also
404  know alloca() */
405  m.msg_control = alloca(m.msg_controllen);
406  memset(m.msg_control, 0, m.msg_controllen);
407 
408  /* Do not include the padding at the end when we tell the kernel
409  * how much we're willing to receive. This avoids getting
410  * the padding filled with additional fds that we weren't expecting,
411  * if a (potentially malicious) sender included them. (fd.o #83622) */
412  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
413 
414  again:
415 
416  bytes_read = recvmsg (fd.fd, &m, 0
417 #ifdef MSG_CMSG_CLOEXEC
418  |MSG_CMSG_CLOEXEC
419 #endif
420  );
421 
422  if (bytes_read < 0)
423  {
424  if (errno == EINTR)
425  goto again;
426  else
427  {
428  /* put length back (note that this doesn't actually realloc anything) */
429  _dbus_string_set_length (buffer, start);
430  return -1;
431  }
432  }
433  else
434  {
435  struct cmsghdr *cm;
436  dbus_bool_t found = FALSE;
437 
438  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
439  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
440  {
441  size_t i;
442  int *payload = (int *) CMSG_DATA (cm);
443  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
444  size_t payload_len_fds;
445  size_t fds_to_use;
446 
447  /* Every unsigned int fits in a size_t without truncation, so
448  * casting (size_t) *n_fds is OK */
449  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
450 
451  if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
452  (char *) payload + payload_len_bytes >
453  (char *) m.msg_control + m.msg_controllen)
454  {
455  /* This is the last cmsg in a truncated message and using
456  * cmsg_len would apparently overrun the allocated buffer.
457  * Some operating systems (illumos and Solaris are known) do
458  * not adjust cmsg_len in the last cmsg when truncation occurs.
459  * Adjust the payload length here. The calculation for
460  * payload_len_fds below will discard any trailing bytes that
461  * belong to an incomplete file descriptor - the kernel will
462  * have already closed that (at least for illumos and Solaris)
463  */
464  payload_len_bytes = m.msg_controllen -
465  ((char *) payload - (char *) m.msg_control);
466  }
467 
468  payload_len_fds = payload_len_bytes / sizeof (int);
469 
470  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
471  {
472  /* The fds in the payload will fit in our buffer */
473  fds_to_use = payload_len_fds;
474  }
475  else
476  {
477  /* Too many fds in the payload. This shouldn't happen
478  * any more because we're setting m.msg_controllen to
479  * the exact number we can accept, but be safe and
480  * truncate. */
481  fds_to_use = (size_t) *n_fds;
482 
483  /* Close the excess fds to avoid DoS: if they stayed open,
484  * someone could send us an extra fd per message
485  * and we'd eventually run out. */
486  for (i = fds_to_use; i < payload_len_fds; i++)
487  {
488  close (payload[i]);
489  }
490  }
491 
492  memcpy (fds, payload, fds_to_use * sizeof (int));
493  found = TRUE;
494  /* This narrowing cast from size_t to unsigned int cannot
495  * overflow because we have chosen fds_to_use
496  * to be <= *n_fds */
497  *n_fds = (unsigned int) fds_to_use;
498 
499  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
500  worked, hence we need to go through this list and set
501  CLOEXEC everywhere in any case */
502  for (i = 0; i < fds_to_use; i++)
504 
505  break;
506  }
507 
508  if (!found)
509  *n_fds = 0;
510 
511  if (m.msg_flags & MSG_CTRUNC)
512  {
513  unsigned int i;
514 
515  /* Hmm, apparently the control data was truncated. The bad
516  thing is that we might have completely lost a couple of fds
517  without chance to recover them. Hence let's treat this as a
518  serious error. */
519 
520  /* We still need to close whatever fds we *did* receive,
521  * otherwise they'll never get closed. (CVE-2020-12049) */
522  for (i = 0; i < *n_fds; i++)
523  close (fds[i]);
524 
525  *n_fds = 0;
526  errno = ENOSPC;
527  _dbus_string_set_length (buffer, start);
528  return -1;
529  }
530 
531  /* put length back (doesn't actually realloc) */
532  _dbus_string_set_length (buffer, start + bytes_read);
533 
534 #if 0
535  if (bytes_read > 0)
536  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
537 #endif
538 
539  return bytes_read;
540  }
541 #endif
542 }
543 
544 int
545 _dbus_write_socket_with_unix_fds(DBusSocket fd,
546  const DBusString *buffer,
547  int start,
548  int len,
549  const int *fds,
550  int n_fds) {
551 
552 #ifndef HAVE_UNIX_FD_PASSING
553 
554  if (n_fds > 0) {
555  errno = ENOTSUP;
556  return -1;
557  }
558 
559  return _dbus_write_socket(fd, buffer, start, len);
560 #else
561  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
562 #endif
563 }
564 
565 int
566 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
567  const DBusString *buffer1,
568  int start1,
569  int len1,
570  const DBusString *buffer2,
571  int start2,
572  int len2,
573  const int *fds,
574  int n_fds) {
575 
576 #ifndef HAVE_UNIX_FD_PASSING
577 
578  if (n_fds > 0) {
579  errno = ENOTSUP;
580  return -1;
581  }
582 
583  return _dbus_write_socket_two(fd,
584  buffer1, start1, len1,
585  buffer2, start2, len2);
586 #else
587 
588  struct msghdr m;
589  struct cmsghdr *cm;
590  struct iovec iov[2];
591  int bytes_written;
592 
593  _dbus_assert (len1 >= 0);
594  _dbus_assert (len2 >= 0);
595  _dbus_assert (n_fds >= 0);
596 
597  _DBUS_ZERO(iov);
598  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
599  iov[0].iov_len = len1;
600 
601  if (buffer2)
602  {
603  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
604  iov[1].iov_len = len2;
605  }
606 
607  _DBUS_ZERO(m);
608  m.msg_iov = iov;
609  m.msg_iovlen = buffer2 ? 2 : 1;
610 
611  if (n_fds > 0)
612  {
613  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
614  m.msg_control = alloca(m.msg_controllen);
615  memset(m.msg_control, 0, m.msg_controllen);
616 
617  cm = CMSG_FIRSTHDR(&m);
618  cm->cmsg_level = SOL_SOCKET;
619  cm->cmsg_type = SCM_RIGHTS;
620  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
621  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
622  }
623 
624  again:
625 
626  bytes_written = sendmsg (fd.fd, &m, 0
627 #if HAVE_DECL_MSG_NOSIGNAL
628  |MSG_NOSIGNAL
629 #endif
630  );
631 
632  if (bytes_written < 0 && errno == EINTR)
633  goto again;
634 
635 #if 0
636  if (bytes_written > 0)
637  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
638 #endif
639 
640  return bytes_written;
641 #endif
642 }
643 
657 int
659  const DBusString *buffer1,
660  int start1,
661  int len1,
662  const DBusString *buffer2,
663  int start2,
664  int len2)
665 {
666 #if HAVE_DECL_MSG_NOSIGNAL
667  struct iovec vectors[2];
668  const char *data1;
669  const char *data2;
670  int bytes_written;
671  struct msghdr m;
672 
673  _dbus_assert (buffer1 != NULL);
674  _dbus_assert (start1 >= 0);
675  _dbus_assert (start2 >= 0);
676  _dbus_assert (len1 >= 0);
677  _dbus_assert (len2 >= 0);
678 
679  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
680 
681  if (buffer2 != NULL)
682  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
683  else
684  {
685  data2 = NULL;
686  start2 = 0;
687  len2 = 0;
688  }
689 
690  vectors[0].iov_base = (char*) data1;
691  vectors[0].iov_len = len1;
692  vectors[1].iov_base = (char*) data2;
693  vectors[1].iov_len = len2;
694 
695  _DBUS_ZERO(m);
696  m.msg_iov = vectors;
697  m.msg_iovlen = data2 ? 2 : 1;
698 
699  again:
700 
701  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
702 
703  if (bytes_written < 0 && errno == EINTR)
704  goto again;
705 
706  return bytes_written;
707 
708 #else
709  return _dbus_write_two (fd.fd, buffer1, start1, len1,
710  buffer2, start2, len2);
711 #endif
712 }
713 
730 int
731 _dbus_read (int fd,
732  DBusString *buffer,
733  int count)
734 {
735  int bytes_read;
736  int start;
737  char *data;
738 
739  _dbus_assert (count >= 0);
740 
741  start = _dbus_string_get_length (buffer);
742 
743  if (!_dbus_string_lengthen (buffer, count))
744  {
745  errno = ENOMEM;
746  return -1;
747  }
748 
749  data = _dbus_string_get_data_len (buffer, start, count);
750 
751  again:
752 
753  bytes_read = read (fd, data, count);
754 
755  if (bytes_read < 0)
756  {
757  if (errno == EINTR)
758  goto again;
759  else
760  {
761  /* put length back (note that this doesn't actually realloc anything) */
762  _dbus_string_set_length (buffer, start);
763  return -1;
764  }
765  }
766  else
767  {
768  /* put length back (doesn't actually realloc) */
769  _dbus_string_set_length (buffer, start + bytes_read);
770 
771 #if 0
772  if (bytes_read > 0)
773  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
774 #endif
775 
776  return bytes_read;
777  }
778 }
779 
790 int
791 _dbus_write (int fd,
792  const DBusString *buffer,
793  int start,
794  int len)
795 {
796  const char *data;
797  int bytes_written;
798 
799  data = _dbus_string_get_const_data_len (buffer, start, len);
800 
801  again:
802 
803  bytes_written = write (fd, data, len);
804 
805  if (bytes_written < 0 && errno == EINTR)
806  goto again;
807 
808 #if 0
809  if (bytes_written > 0)
810  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
811 #endif
812 
813  return bytes_written;
814 }
815 
836 int
838  const DBusString *buffer1,
839  int start1,
840  int len1,
841  const DBusString *buffer2,
842  int start2,
843  int len2)
844 {
845  _dbus_assert (buffer1 != NULL);
846  _dbus_assert (start1 >= 0);
847  _dbus_assert (start2 >= 0);
848  _dbus_assert (len1 >= 0);
849  _dbus_assert (len2 >= 0);
850 
851 #ifdef HAVE_WRITEV
852  {
853  struct iovec vectors[2];
854  const char *data1;
855  const char *data2;
856  int bytes_written;
857 
858  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
859 
860  if (buffer2 != NULL)
861  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
862  else
863  {
864  data2 = NULL;
865  start2 = 0;
866  len2 = 0;
867  }
868 
869  vectors[0].iov_base = (char*) data1;
870  vectors[0].iov_len = len1;
871  vectors[1].iov_base = (char*) data2;
872  vectors[1].iov_len = len2;
873 
874  again:
875 
876  bytes_written = writev (fd,
877  vectors,
878  data2 ? 2 : 1);
879 
880  if (bytes_written < 0 && errno == EINTR)
881  goto again;
882 
883  return bytes_written;
884  }
885 #else /* HAVE_WRITEV */
886  {
887  int ret1, ret2;
888 
889  ret1 = _dbus_write (fd, buffer1, start1, len1);
890  if (ret1 == len1 && buffer2 != NULL)
891  {
892  ret2 = _dbus_write (fd, buffer2, start2, len2);
893  if (ret2 < 0)
894  ret2 = 0; /* we can't report an error as the first write was OK */
895 
896  return ret1 + ret2;
897  }
898  else
899  return ret1;
900  }
901 #endif /* !HAVE_WRITEV */
902 }
903 
904 #define _DBUS_MAX_SUN_PATH_LENGTH 99
905 
935 int
936 _dbus_connect_unix_socket (const char *path,
937  dbus_bool_t abstract,
938  DBusError *error)
939 {
940  int fd;
941  size_t path_len;
942  struct sockaddr_un addr;
943  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
944 
945  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
946 
947  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
948  path, abstract);
949 
950 
951  if (!_dbus_open_unix_socket (&fd, error))
952  {
953  _DBUS_ASSERT_ERROR_IS_SET(error);
954  return -1;
955  }
956  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
957 
958  _DBUS_ZERO (addr);
959  addr.sun_family = AF_UNIX;
960  path_len = strlen (path);
961 
962  if (abstract)
963  {
964 #ifdef __linux__
965  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
966  path_len++; /* Account for the extra nul byte added to the start of sun_path */
967 
968  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
969  {
971  "Abstract socket name too long\n");
972  _dbus_close (fd, NULL);
973  return -1;
974  }
975 
976  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
977  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
978 #else /* !__linux__ */
980  "Operating system does not support abstract socket namespace\n");
981  _dbus_close (fd, NULL);
982  return -1;
983 #endif /* !__linux__ */
984  }
985  else
986  {
987  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
988  {
990  "Socket name too long\n");
991  _dbus_close (fd, NULL);
992  return -1;
993  }
994 
995  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
996  }
997 
998  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
999  {
1000  dbus_set_error (error,
1001  _dbus_error_from_errno (errno),
1002  "Failed to connect to socket %s: %s",
1003  path, _dbus_strerror (errno));
1004 
1005  _dbus_close (fd, NULL);
1006  return -1;
1007  }
1008 
1009  if (!_dbus_set_fd_nonblocking (fd, error))
1010  {
1011  _DBUS_ASSERT_ERROR_IS_SET (error);
1012 
1013  _dbus_close (fd, NULL);
1014  return -1;
1015  }
1016 
1017  return fd;
1018 }
1019 
1032 int
1033 _dbus_connect_exec (const char *path,
1034  char *const argv[],
1035  DBusError *error)
1036 {
1037  int fds[2];
1038  pid_t pid;
1039  int retval;
1040  dbus_bool_t cloexec_done = 0;
1041 
1042  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1043 
1044  _dbus_verbose ("connecting to process %s\n", path);
1045 
1046 #ifdef SOCK_CLOEXEC
1047  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1048  cloexec_done = (retval >= 0);
1049 
1050  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1051 #endif
1052  {
1053  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1054  }
1055 
1056  if (retval < 0)
1057  {
1058  dbus_set_error (error,
1059  _dbus_error_from_errno (errno),
1060  "Failed to create socket pair: %s",
1061  _dbus_strerror (errno));
1062  return -1;
1063  }
1064 
1065  if (!cloexec_done)
1066  {
1067  _dbus_fd_set_close_on_exec (fds[0]);
1068  _dbus_fd_set_close_on_exec (fds[1]);
1069  }
1070 
1071  pid = fork ();
1072  if (pid < 0)
1073  {
1074  dbus_set_error (error,
1075  _dbus_error_from_errno (errno),
1076  "Failed to fork() to call %s: %s",
1077  path, _dbus_strerror (errno));
1078  close (fds[0]);
1079  close (fds[1]);
1080  return -1;
1081  }
1082 
1083  if (pid == 0)
1084  {
1085  /* child */
1086  close (fds[0]);
1087 
1088  dup2 (fds[1], STDIN_FILENO);
1089  dup2 (fds[1], STDOUT_FILENO);
1090 
1091  if (fds[1] != STDIN_FILENO &&
1092  fds[1] != STDOUT_FILENO)
1093  close (fds[1]);
1094 
1095  /* Inherit STDERR and the controlling terminal from the
1096  parent */
1097 
1098  _dbus_close_all ();
1099 
1100  execvp (path, (char * const *) argv);
1101 
1102  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1103 
1104  _exit(1);
1105  }
1106 
1107  /* parent */
1108  close (fds[1]);
1109 
1110  if (!_dbus_set_fd_nonblocking (fds[0], error))
1111  {
1112  _DBUS_ASSERT_ERROR_IS_SET (error);
1113 
1114  close (fds[0]);
1115  return -1;
1116  }
1117 
1118  return fds[0];
1119 }
1120 
1138 int
1139 _dbus_listen_unix_socket (const char *path,
1140  dbus_bool_t abstract,
1141  DBusError *error)
1142 {
1143  int listen_fd;
1144  struct sockaddr_un addr;
1145  size_t path_len;
1146  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1147 
1148  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1149 
1150  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1151  path, abstract);
1152 
1153  if (!_dbus_open_unix_socket (&listen_fd, error))
1154  {
1155  _DBUS_ASSERT_ERROR_IS_SET(error);
1156  return -1;
1157  }
1158  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1159 
1160  _DBUS_ZERO (addr);
1161  addr.sun_family = AF_UNIX;
1162  path_len = strlen (path);
1163 
1164  if (abstract)
1165  {
1166 #ifdef __linux__
1167  /* remember that abstract names aren't nul-terminated so we rely
1168  * on sun_path being filled in with zeroes above.
1169  */
1170  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1171  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1172 
1173  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1174  {
1176  "Abstract socket name too long\n");
1177  _dbus_close (listen_fd, NULL);
1178  return -1;
1179  }
1180 
1181  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1182  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1183 #else /* !__linux__ */
1185  "Operating system does not support abstract socket namespace\n");
1186  _dbus_close (listen_fd, NULL);
1187  return -1;
1188 #endif /* !__linux__ */
1189  }
1190  else
1191  {
1192  /* Discussed security implications of this with Nalin,
1193  * and we couldn't think of where it would kick our ass, but
1194  * it still seems a bit sucky. It also has non-security suckage;
1195  * really we'd prefer to exit if the socket is already in use.
1196  * But there doesn't seem to be a good way to do this.
1197  *
1198  * Just to be extra careful, I threw in the stat() - clearly
1199  * the stat() can't *fix* any security issue, but it at least
1200  * avoids inadvertent/accidental data loss.
1201  */
1202  {
1203  struct stat sb;
1204 
1205  if (stat (path, &sb) == 0 &&
1206  S_ISSOCK (sb.st_mode))
1207  unlink (path);
1208  }
1209 
1210  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1211  {
1213  "Socket name too long\n");
1214  _dbus_close (listen_fd, NULL);
1215  return -1;
1216  }
1217 
1218  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1219  }
1220 
1221  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1222  {
1223  dbus_set_error (error, _dbus_error_from_errno (errno),
1224  "Failed to bind socket \"%s\": %s",
1225  path, _dbus_strerror (errno));
1226  _dbus_close (listen_fd, NULL);
1227  return -1;
1228  }
1229 
1230  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1231  {
1232  dbus_set_error (error, _dbus_error_from_errno (errno),
1233  "Failed to listen on socket \"%s\": %s",
1234  path, _dbus_strerror (errno));
1235  _dbus_close (listen_fd, NULL);
1236  return -1;
1237  }
1238 
1239  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1240  {
1241  _DBUS_ASSERT_ERROR_IS_SET (error);
1242  _dbus_close (listen_fd, NULL);
1243  return -1;
1244  }
1245 
1246  /* Try opening up the permissions, but if we can't, just go ahead
1247  * and continue, maybe it will be good enough.
1248  */
1249  if (!abstract && chmod (path, 0777) < 0)
1250  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1251 
1252  return listen_fd;
1253 }
1254 
1265 int
1267  DBusError *error)
1268 {
1269 #ifdef HAVE_SYSTEMD
1270  int r, n;
1271  int fd;
1272  DBusSocket *new_fds;
1273 
1274  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1275 
1276  n = sd_listen_fds (TRUE);
1277  if (n < 0)
1278  {
1280  "Failed to acquire systemd socket: %s",
1281  _dbus_strerror (-n));
1282  return -1;
1283  }
1284 
1285  if (n <= 0)
1286  {
1288  "No socket received.");
1289  return -1;
1290  }
1291 
1292  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1293  {
1294  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1295  if (r < 0)
1296  {
1298  "Failed to verify systemd socket type: %s",
1299  _dbus_strerror (-r));
1300  return -1;
1301  }
1302 
1303  if (!r)
1304  {
1306  "Passed socket has wrong type.");
1307  return -1;
1308  }
1309  }
1310 
1311  /* OK, the file descriptors are all good, so let's take posession of
1312  them then. */
1313 
1314  new_fds = dbus_new (DBusSocket, n);
1315  if (!new_fds)
1316  {
1318  "Failed to allocate file handle array.");
1319  goto fail;
1320  }
1321 
1322  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1323  {
1324  if (!_dbus_set_fd_nonblocking (fd, error))
1325  {
1326  _DBUS_ASSERT_ERROR_IS_SET (error);
1327  goto fail;
1328  }
1329 
1330  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1331  }
1332 
1333  *fds = new_fds;
1334  return n;
1335 
1336  fail:
1337 
1338  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1339  {
1340  _dbus_close (fd, NULL);
1341  }
1342 
1343  dbus_free (new_fds);
1344  return -1;
1345 #else
1347  "dbus was compiled without systemd support");
1348  return -1;
1349 #endif
1350 }
1351 
1352 /* Convert an error code from getaddrinfo() or getnameinfo() into
1353  * a D-Bus error name. */
1354 static const char *
1355 _dbus_error_from_gai (int gai_res,
1356  int saved_errno)
1357 {
1358  switch (gai_res)
1359  {
1360 #ifdef EAI_FAMILY
1361  case EAI_FAMILY:
1362  /* ai_family not supported (at all) */
1363  return DBUS_ERROR_NOT_SUPPORTED;
1364 #endif
1365 
1366 #ifdef EAI_SOCKTYPE
1367  case EAI_SOCKTYPE:
1368  /* ai_socktype not supported (at all) */
1369  return DBUS_ERROR_NOT_SUPPORTED;
1370 #endif
1371 
1372 #ifdef EAI_MEMORY
1373  case EAI_MEMORY:
1374  /* Out of memory */
1375  return DBUS_ERROR_NO_MEMORY;
1376 #endif
1377 
1378 #ifdef EAI_SYSTEM
1379  case EAI_SYSTEM:
1380  /* Unspecified system error, details in errno */
1381  return _dbus_error_from_errno (saved_errno);
1382 #endif
1383 
1384  case 0:
1385  /* It succeeded, but we didn't get any addresses? */
1386  return DBUS_ERROR_FAILED;
1387 
1388  /* EAI_AGAIN: Transient failure */
1389  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1390  /* EAI_FAIL: Non-recoverable failure */
1391  /* EAI_NODATA: host exists but has no addresses */
1392  /* EAI_NONAME: host does not exist */
1393  /* EAI_OVERFLOW: argument buffer overflow */
1394  /* EAI_SERVICE: service not available for specified socket
1395  * type (we should never see this because we use numeric
1396  * ports) */
1397  default:
1398  return DBUS_ERROR_FAILED;
1399  }
1400 }
1401 
1415 DBusSocket
1416 _dbus_connect_tcp_socket (const char *host,
1417  const char *port,
1418  const char *family,
1419  DBusError *error)
1420 {
1421  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1422 }
1423 
1424 DBusSocket
1425 _dbus_connect_tcp_socket_with_nonce (const char *host,
1426  const char *port,
1427  const char *family,
1428  const char *noncefile,
1429  DBusError *error)
1430 {
1431  int saved_errno = 0;
1432  DBusSocket fd = DBUS_SOCKET_INIT;
1433  int res;
1434  struct addrinfo hints;
1435  struct addrinfo *ai, *tmp;
1436 
1437  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1438 
1439  _DBUS_ZERO (hints);
1440 
1441  if (!family)
1442  hints.ai_family = AF_UNSPEC;
1443  else if (!strcmp(family, "ipv4"))
1444  hints.ai_family = AF_INET;
1445  else if (!strcmp(family, "ipv6"))
1446  hints.ai_family = AF_INET6;
1447  else
1448  {
1449  dbus_set_error (error,
1451  "Unknown address family %s", family);
1452  return _dbus_socket_get_invalid ();
1453  }
1454  hints.ai_protocol = IPPROTO_TCP;
1455  hints.ai_socktype = SOCK_STREAM;
1456  hints.ai_flags = AI_ADDRCONFIG;
1457 
1458  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1459  {
1460  dbus_set_error (error,
1461  _dbus_error_from_gai (res, errno),
1462  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1463  host, port, gai_strerror(res), res);
1464  return _dbus_socket_get_invalid ();
1465  }
1466 
1467  tmp = ai;
1468  while (tmp)
1469  {
1470  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1471  {
1472  freeaddrinfo(ai);
1473  _DBUS_ASSERT_ERROR_IS_SET(error);
1474  return _dbus_socket_get_invalid ();
1475  }
1476  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1477 
1478  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1479  {
1480  saved_errno = errno;
1481  _dbus_close (fd.fd, NULL);
1482  fd.fd = -1;
1483  tmp = tmp->ai_next;
1484  continue;
1485  }
1486 
1487  break;
1488  }
1489  freeaddrinfo(ai);
1490 
1491  if (fd.fd == -1)
1492  {
1493  dbus_set_error (error,
1494  _dbus_error_from_errno (saved_errno),
1495  "Failed to connect to socket \"%s:%s\" %s",
1496  host, port, _dbus_strerror(saved_errno));
1497  return _dbus_socket_get_invalid ();
1498  }
1499 
1500  if (noncefile != NULL)
1501  {
1502  DBusString noncefileStr;
1503  dbus_bool_t ret;
1504  _dbus_string_init_const (&noncefileStr, noncefile);
1505  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1506  _dbus_string_free (&noncefileStr);
1507 
1508  if (!ret)
1509  {
1510  _dbus_close (fd.fd, NULL);
1511  return _dbus_socket_get_invalid ();
1512  }
1513  }
1514 
1515  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1516  {
1517  _dbus_close (fd.fd, NULL);
1518  return _dbus_socket_get_invalid ();
1519  }
1520 
1521  return fd;
1522 }
1523 
1540 int
1541 _dbus_listen_tcp_socket (const char *host,
1542  const char *port,
1543  const char *family,
1544  DBusString *retport,
1545  DBusSocket **fds_p,
1546  DBusError *error)
1547 {
1548  int saved_errno;
1549  int nlisten_fd = 0, res, i;
1550  DBusSocket *listen_fd = NULL;
1551  struct addrinfo hints;
1552  struct addrinfo *ai, *tmp;
1553  unsigned int reuseaddr;
1554 
1555  *fds_p = NULL;
1556  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1557 
1558  _DBUS_ZERO (hints);
1559 
1560  if (!family)
1561  hints.ai_family = AF_UNSPEC;
1562  else if (!strcmp(family, "ipv4"))
1563  hints.ai_family = AF_INET;
1564  else if (!strcmp(family, "ipv6"))
1565  hints.ai_family = AF_INET6;
1566  else
1567  {
1568  dbus_set_error (error,
1570  "Unknown address family %s", family);
1571  return -1;
1572  }
1573 
1574  hints.ai_protocol = IPPROTO_TCP;
1575  hints.ai_socktype = SOCK_STREAM;
1576  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1577 
1578  redo_lookup_with_port:
1579  ai = NULL;
1580  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1581  {
1582  dbus_set_error (error,
1583  _dbus_error_from_gai (res, errno),
1584  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1585  host ? host : "*", port, gai_strerror(res), res);
1586  goto failed;
1587  }
1588 
1589  tmp = ai;
1590  while (tmp)
1591  {
1592  int fd = -1, tcp_nodelay_on;
1593  DBusSocket *newlisten_fd;
1594 
1595  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1596  {
1597  _DBUS_ASSERT_ERROR_IS_SET(error);
1598  goto failed;
1599  }
1600  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1601 
1602  reuseaddr = 1;
1603  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1604  {
1605  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1606  host ? host : "*", port, _dbus_strerror (errno));
1607  }
1608 
1609  /* Nagle's algorithm imposes a huge delay on the initial messages
1610  going over TCP. */
1611  tcp_nodelay_on = 1;
1612  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1613  {
1614  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1615  host ? host : "*", port, _dbus_strerror (errno));
1616  }
1617 
1618  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1619  {
1620  saved_errno = errno;
1621  _dbus_close(fd, NULL);
1622  if (saved_errno == EADDRINUSE)
1623  {
1624  /* Depending on kernel policy, binding to an IPv6 address
1625  might implicitly bind to a corresponding IPv4
1626  address or vice versa, resulting in EADDRINUSE for the
1627  other one (e.g. bindv6only=0 on Linux).
1628 
1629  Also, after we "goto redo_lookup_with_port" after binding
1630  a port on one of the possible addresses, we will
1631  try to bind that same port on every address, including the
1632  same address again for a second time; that one will
1633  also fail with EADDRINUSE.
1634 
1635  For both those reasons, ignore EADDRINUSE here */
1636  tmp = tmp->ai_next;
1637  continue;
1638  }
1639  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1640  "Failed to bind socket \"%s:%s\": %s",
1641  host ? host : "*", port, _dbus_strerror (saved_errno));
1642  goto failed;
1643  }
1644 
1645  if (listen (fd, 30 /* backlog */) < 0)
1646  {
1647  saved_errno = errno;
1648  _dbus_close (fd, NULL);
1649  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1650  "Failed to listen on socket \"%s:%s\": %s",
1651  host ? host : "*", port, _dbus_strerror (saved_errno));
1652  goto failed;
1653  }
1654 
1655  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1656  if (!newlisten_fd)
1657  {
1658  _dbus_close (fd, NULL);
1660  "Failed to allocate file handle array");
1661  goto failed;
1662  }
1663  listen_fd = newlisten_fd;
1664  listen_fd[nlisten_fd].fd = fd;
1665  nlisten_fd++;
1666 
1667  if (!_dbus_string_get_length(retport))
1668  {
1669  /* If the user didn't specify a port, or used 0, then
1670  the kernel chooses a port. After the first address
1671  is bound to, we need to force all remaining addresses
1672  to use the same port */
1673  if (!port || !strcmp(port, "0"))
1674  {
1675  int result;
1676  struct sockaddr_storage addr;
1677  socklen_t addrlen;
1678  char portbuf[50];
1679 
1680  addrlen = sizeof(addr);
1681  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1682 
1683  if (result == -1)
1684  {
1685  saved_errno = errno;
1686  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1687  "Failed to retrieve socket name for \"%s:%s\": %s",
1688  host ? host : "*", port, _dbus_strerror (saved_errno));
1689  goto failed;
1690  }
1691 
1692  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1693  portbuf, sizeof(portbuf),
1694  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1695  {
1696  saved_errno = errno;
1697  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1698  "Failed to resolve port \"%s:%s\": %s (%d)",
1699  host ? host : "*", port, gai_strerror(res), res);
1700  goto failed;
1701  }
1702 
1703  if (!_dbus_string_append(retport, portbuf))
1704  {
1706  goto failed;
1707  }
1708 
1709  /* Release current address list & redo lookup */
1710  port = _dbus_string_get_const_data(retport);
1711  freeaddrinfo(ai);
1712  goto redo_lookup_with_port;
1713  }
1714  else
1715  {
1716  if (!_dbus_string_append(retport, port))
1717  {
1719  goto failed;
1720  }
1721  }
1722  }
1723 
1724  tmp = tmp->ai_next;
1725  }
1726  freeaddrinfo(ai);
1727  ai = NULL;
1728 
1729  if (!nlisten_fd)
1730  {
1731  errno = EADDRINUSE;
1732  dbus_set_error (error, _dbus_error_from_errno (errno),
1733  "Failed to bind socket \"%s:%s\": %s",
1734  host ? host : "*", port, _dbus_strerror (errno));
1735  goto failed;
1736  }
1737 
1738  for (i = 0 ; i < nlisten_fd ; i++)
1739  {
1740  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1741  {
1742  goto failed;
1743  }
1744  }
1745 
1746  *fds_p = listen_fd;
1747 
1748  return nlisten_fd;
1749 
1750  failed:
1751  if (ai)
1752  freeaddrinfo(ai);
1753  for (i = 0 ; i < nlisten_fd ; i++)
1754  _dbus_close(listen_fd[i].fd, NULL);
1755  dbus_free(listen_fd);
1756  return -1;
1757 }
1758 
1759 static dbus_bool_t
1760 write_credentials_byte (int server_fd,
1761  DBusError *error)
1762 {
1763  int bytes_written;
1764  char buf[1] = { '\0' };
1765 #if defined(HAVE_CMSGCRED)
1766  union {
1767  struct cmsghdr hdr;
1768  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1769  } cmsg;
1770  struct iovec iov;
1771  struct msghdr msg;
1772  iov.iov_base = buf;
1773  iov.iov_len = 1;
1774 
1775  _DBUS_ZERO(msg);
1776  msg.msg_iov = &iov;
1777  msg.msg_iovlen = 1;
1778 
1779  msg.msg_control = (caddr_t) &cmsg;
1780  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1781  _DBUS_ZERO(cmsg);
1782  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1783  cmsg.hdr.cmsg_level = SOL_SOCKET;
1784  cmsg.hdr.cmsg_type = SCM_CREDS;
1785 #endif
1786 
1787  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1788 
1789  again:
1790 
1791 #if defined(HAVE_CMSGCRED)
1792  bytes_written = sendmsg (server_fd, &msg, 0
1793 #if HAVE_DECL_MSG_NOSIGNAL
1794  |MSG_NOSIGNAL
1795 #endif
1796  );
1797 
1798  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1799  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1800  * only allows that on AF_UNIX. Try just doing a send() instead. */
1801  if (bytes_written < 0 && errno == EINVAL)
1802 #endif
1803  {
1804  bytes_written = send (server_fd, buf, 1, 0
1805 #if HAVE_DECL_MSG_NOSIGNAL
1806  |MSG_NOSIGNAL
1807 #endif
1808  );
1809  }
1810 
1811  if (bytes_written < 0 && errno == EINTR)
1812  goto again;
1813 
1814  if (bytes_written < 0)
1815  {
1816  dbus_set_error (error, _dbus_error_from_errno (errno),
1817  "Failed to write credentials byte: %s",
1818  _dbus_strerror (errno));
1819  return FALSE;
1820  }
1821  else if (bytes_written == 0)
1822  {
1824  "wrote zero bytes writing credentials byte");
1825  return FALSE;
1826  }
1827  else
1828  {
1829  _dbus_assert (bytes_written == 1);
1830  _dbus_verbose ("wrote credentials byte\n");
1831  return TRUE;
1832  }
1833 }
1834 
1835 /* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1836 static dbus_bool_t
1837 add_groups_to_credentials (int client_fd,
1838  DBusCredentials *credentials,
1839  dbus_gid_t primary)
1840 {
1841 #if defined(__linux__) && defined(SO_PEERGROUPS)
1842  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1843  /* This function assumes socklen_t is unsigned, which is true on Linux */
1844  _DBUS_STATIC_ASSERT (((socklen_t) -1) > 0);
1845  gid_t *buf = NULL;
1846  socklen_t len = 1024;
1847  dbus_bool_t oom = FALSE;
1848  /* libdbus has a different representation of group IDs just to annoy you */
1849  dbus_gid_t *converted_gids = NULL;
1850  dbus_bool_t need_primary = TRUE;
1851  size_t n_gids;
1852  size_t i;
1853 
1854  n_gids = ((size_t) len) / sizeof (gid_t);
1855  buf = dbus_new (gid_t, n_gids);
1856 
1857  if (buf == NULL)
1858  return FALSE;
1859 
1860  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1861  {
1862  int e = errno;
1863  gid_t *replacement;
1864 
1865  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1866  _dbus_strerror (e), (unsigned long) len);
1867 
1868  if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1869  {
1870  _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1871  _dbus_strerror (e));
1872  goto out;
1873  }
1874 
1875  /* If not enough space, len is updated to be enough.
1876  * Try again with a large enough buffer. */
1877  n_gids = ((size_t) len) / sizeof (gid_t);
1878  replacement = dbus_realloc (buf, len);
1879 
1880  if (replacement == NULL)
1881  {
1882  oom = TRUE;
1883  goto out;
1884  }
1885 
1886  buf = replacement;
1887  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1888  }
1889 
1890  if (len > n_gids * sizeof (gid_t))
1891  {
1892  _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
1893  _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
1894  }
1895 
1896  if (len % sizeof (gid_t) != 0)
1897  {
1898  _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
1899  "integer multiple of sizeof(gid_t): %lu should be "
1900  "divisible by %zu",
1901  (unsigned long) len, sizeof (gid_t));
1902  goto out;
1903  }
1904 
1905  /* Allocate an extra space for the primary group ID */
1906  n_gids = ((size_t) len) / sizeof (gid_t);
1907 
1908  /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
1909  * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
1910  * This is using _DBUS_INT32_MAX as a conservative lower bound for
1911  * the maximum size_t. */
1912  if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
1913  {
1914  _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
1915  "of groups (%lu bytes), ignoring",
1916  (unsigned long) len);
1917  goto out;
1918  }
1919 
1920  converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
1921 
1922  if (converted_gids == NULL)
1923  {
1924  oom = TRUE;
1925  goto out;
1926  }
1927 
1928  for (i = 0; i < n_gids; i++)
1929  {
1930  converted_gids[i] = (dbus_gid_t) buf[i];
1931 
1932  if (converted_gids[i] == primary)
1933  need_primary = FALSE;
1934  }
1935 
1936  if (need_primary && primary != DBUS_GID_UNSET)
1937  {
1938  converted_gids[n_gids] = primary;
1939  n_gids++;
1940  }
1941 
1942  _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
1943 
1944 out:
1945  dbus_free (buf);
1946  return !oom;
1947 #else
1948  /* no error */
1949  return TRUE;
1950 #endif
1951 }
1952 
1953 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1954 static dbus_bool_t
1955 add_linux_security_label_to_credentials (int client_fd,
1956  DBusCredentials *credentials)
1957 {
1958 #if defined(__linux__) && defined(SO_PEERSEC)
1959  DBusString buf;
1960  socklen_t len = 1024;
1961  dbus_bool_t oom = FALSE;
1962 
1963  if (!_dbus_string_init_preallocated (&buf, len) ||
1964  !_dbus_string_set_length (&buf, len))
1965  return FALSE;
1966 
1967  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1968  _dbus_string_get_data (&buf), &len) < 0)
1969  {
1970  int e = errno;
1971 
1972  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1973  _dbus_strerror (e), (unsigned long) len);
1974 
1975  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1976  {
1977  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1978  _dbus_strerror (e));
1979  goto out;
1980  }
1981 
1982  /* If not enough space, len is updated to be enough.
1983  * Try again with a large enough buffer. */
1984  if (!_dbus_string_set_length (&buf, len))
1985  {
1986  oom = TRUE;
1987  goto out;
1988  }
1989 
1990  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1991  }
1992 
1993  if (len <= 0)
1994  {
1995  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1996  (unsigned long) len);
1997  goto out;
1998  }
1999 
2000  if (len > _dbus_string_get_length_uint (&buf))
2001  {
2002  _dbus_verbose ("%lu > %u", (unsigned long) len,
2003  _dbus_string_get_length_uint (&buf));
2004  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2005  }
2006 
2007  if (_dbus_string_get_byte (&buf, len - 1) == 0)
2008  {
2009  /* the kernel included the trailing \0 in its count,
2010  * but DBusString always has an extra \0 after the data anyway */
2011  _dbus_verbose ("subtracting trailing \\0\n");
2012  len--;
2013  }
2014 
2015  if (!_dbus_string_set_length (&buf, len))
2016  {
2017  _dbus_assert_not_reached ("shortening string should not lead to OOM");
2018  oom = TRUE;
2019  goto out;
2020  }
2021 
2022  if (strlen (_dbus_string_get_const_data (&buf)) != len)
2023  {
2024  /* LSM people on the linux-security-module@ mailing list say this
2025  * should never happen: the label should be a bytestring with
2026  * an optional trailing \0 */
2027  _dbus_verbose ("security label from kernel had an embedded \\0, "
2028  "ignoring it\n");
2029  goto out;
2030  }
2031 
2032  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2033  (unsigned long) len,
2034  _dbus_string_get_const_data (&buf));
2035 
2037  _dbus_string_get_const_data (&buf)))
2038  {
2039  oom = TRUE;
2040  goto out;
2041  }
2042 
2043 out:
2044  _dbus_string_free (&buf);
2045  return !oom;
2046 #else
2047  /* no error */
2048  return TRUE;
2049 #endif
2050 }
2051 
2094  DBusCredentials *credentials,
2095  DBusError *error)
2096 {
2097  struct msghdr msg;
2098  struct iovec iov;
2099  char buf;
2100  dbus_uid_t uid_read;
2101  dbus_gid_t primary_gid_read;
2102  dbus_pid_t pid_read;
2103  int bytes_read;
2104 
2105 #ifdef HAVE_CMSGCRED
2106  union {
2107  struct cmsghdr hdr;
2108  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2109  } cmsg;
2110 #endif
2111 
2112  /* The POSIX spec certainly doesn't promise this, but
2113  * we need these assertions to fail as soon as we're wrong about
2114  * it so we can do the porting fixups
2115  */
2116  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2117  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2118  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2119 
2120  uid_read = DBUS_UID_UNSET;
2121  primary_gid_read = DBUS_GID_UNSET;
2122  pid_read = DBUS_PID_UNSET;
2123 
2124  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2125 
2126  _dbus_credentials_clear (credentials);
2127 
2128  iov.iov_base = &buf;
2129  iov.iov_len = 1;
2130 
2131  _DBUS_ZERO(msg);
2132  msg.msg_iov = &iov;
2133  msg.msg_iovlen = 1;
2134 
2135 #if defined(HAVE_CMSGCRED)
2136  _DBUS_ZERO(cmsg);
2137  msg.msg_control = (caddr_t) &cmsg;
2138  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2139 #endif
2140 
2141  again:
2142  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2143 
2144  if (bytes_read < 0)
2145  {
2146  if (errno == EINTR)
2147  goto again;
2148 
2149  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2150  * normally only call read_credentials if the socket was ready
2151  * for reading
2152  */
2153 
2154  dbus_set_error (error, _dbus_error_from_errno (errno),
2155  "Failed to read credentials byte: %s",
2156  _dbus_strerror (errno));
2157  return FALSE;
2158  }
2159  else if (bytes_read == 0)
2160  {
2161  /* this should not happen unless we are using recvmsg wrong,
2162  * so is essentially here for paranoia
2163  */
2165  "Failed to read credentials byte (zero-length read)");
2166  return FALSE;
2167  }
2168  else if (buf != '\0')
2169  {
2171  "Credentials byte was not nul");
2172  return FALSE;
2173  }
2174 
2175  _dbus_verbose ("read credentials byte\n");
2176 
2177  {
2178 #ifdef SO_PEERCRED
2179  /* Supported by at least Linux and OpenBSD, with minor differences.
2180  *
2181  * This mechanism passes the process ID through and does not require
2182  * the peer's cooperation, so we prefer it over all others. Notably,
2183  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2184  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2185  * because this is much less fragile.
2186  */
2187 #ifdef __OpenBSD__
2188  struct sockpeercred cr;
2189 #else
2190  struct ucred cr;
2191 #endif
2192  socklen_t cr_len = sizeof (cr);
2193 
2194  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2195  {
2196  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2197  _dbus_strerror (errno));
2198  }
2199  else if (cr_len != sizeof (cr))
2200  {
2201  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2202  cr_len, (int) sizeof (cr));
2203  }
2204  else
2205  {
2206  pid_read = cr.pid;
2207  uid_read = cr.uid;
2208 #ifdef __linux__
2209  /* Do other platforms have cr.gid? (Not that it really matters,
2210  * because the gid is useless to us unless we know the complete
2211  * group vector, which we only know on Linux.) */
2212  primary_gid_read = cr.gid;
2213 #endif
2214  }
2215 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2216  /* Another variant of the above - used on NetBSD
2217  */
2218  struct unpcbid cr;
2219  socklen_t cr_len = sizeof (cr);
2220 
2221  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2222  {
2223  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2224  _dbus_strerror (errno));
2225  }
2226  else if (cr_len != sizeof (cr))
2227  {
2228  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2229  cr_len, (int) sizeof (cr));
2230  }
2231  else
2232  {
2233  pid_read = cr.unp_pid;
2234  uid_read = cr.unp_euid;
2235  }
2236 #elif defined(HAVE_CMSGCRED)
2237  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2238  * presence of that struct implies SCM_CREDS. Supported by at least
2239  * FreeBSD and DragonflyBSD.
2240  *
2241  * This mechanism requires the peer to help us (it has to send us a
2242  * SCM_CREDS message) but it does pass the process ID through,
2243  * which makes it better than getpeereid().
2244  */
2245  struct cmsgcred *cred;
2246  struct cmsghdr *cmsgp;
2247 
2248  for (cmsgp = CMSG_FIRSTHDR (&msg);
2249  cmsgp != NULL;
2250  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2251  {
2252  if (cmsgp->cmsg_type == SCM_CREDS &&
2253  cmsgp->cmsg_level == SOL_SOCKET &&
2254  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2255  {
2256  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2257  pid_read = cred->cmcred_pid;
2258  uid_read = cred->cmcred_euid;
2259  break;
2260  }
2261  }
2262 
2263 #elif defined(HAVE_GETPEERUCRED)
2264  /* Supported in at least Solaris >= 10. It should probably be higher
2265  * up this list, because it carries the pid and we use this code path
2266  * for audit data. */
2267  ucred_t * ucred = NULL;
2268  if (getpeerucred (client_fd.fd, &ucred) == 0)
2269  {
2270 #ifdef HAVE_ADT
2271  adt_session_data_t *adth = NULL;
2272 #endif
2273  pid_read = ucred_getpid (ucred);
2274  uid_read = ucred_geteuid (ucred);
2275 #ifdef HAVE_ADT
2276  /* generate audit session data based on socket ucred */
2277  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2278  {
2279  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2280  }
2281  else
2282  {
2283  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2284  {
2285  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2286  }
2287  else
2288  {
2289  adt_export_data_t *data = NULL;
2290  size_t size = adt_export_session_data (adth, &data);
2291  if (size <= 0)
2292  {
2293  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2294  }
2295  else
2296  {
2297  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2298  free (data);
2299  }
2300  }
2301  (void) adt_end_session (adth);
2302  }
2303 #endif /* HAVE_ADT */
2304  }
2305  else
2306  {
2307  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2308  }
2309  if (ucred != NULL)
2310  ucred_free (ucred);
2311 
2312  /* ----------------------------------------------------------------
2313  * When adding new mechanisms, please add them above this point
2314  * if they support passing the process ID through, or below if not.
2315  * ---------------------------------------------------------------- */
2316 
2317 #elif defined(HAVE_GETPEEREID)
2318  /* getpeereid() originates from D.J. Bernstein and is fairly
2319  * widely-supported. According to a web search, it might be present in
2320  * any/all of:
2321  *
2322  * - AIX?
2323  * - Blackberry?
2324  * - Cygwin
2325  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2326  * - Mac OS X
2327  * - Minix 3.1.8+
2328  * - MirBSD?
2329  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2330  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2331  * - QNX?
2332  */
2333  uid_t euid;
2334  gid_t egid;
2335  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2336  {
2337  uid_read = euid;
2338  }
2339  else
2340  {
2341  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2342  }
2343 #else /* no supported mechanism */
2344 
2345 #warning Socket credentials not supported on this Unix OS
2346 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2347 
2348  /* Please add other operating systems known to support at least one of
2349  * the mechanisms above to this list, keeping alphabetical order.
2350  * Everything not in this list is best-effort.
2351  */
2352 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2353  defined(__linux__) || \
2354  defined(__OpenBSD__) || \
2355  defined(__NetBSD__)
2356 # error Credentials passing not working on this OS is a regression!
2357 #endif
2358 
2359  _dbus_verbose ("Socket credentials not supported on this OS\n");
2360 #endif
2361  }
2362 
2363  _dbus_verbose ("Credentials:"
2364  " pid "DBUS_PID_FORMAT
2365  " uid "DBUS_UID_FORMAT
2366  "\n",
2367  pid_read,
2368  uid_read);
2369 
2370  if (pid_read != DBUS_PID_UNSET)
2371  {
2372  if (!_dbus_credentials_add_pid (credentials, pid_read))
2373  {
2374  _DBUS_SET_OOM (error);
2375  return FALSE;
2376  }
2377  }
2378 
2379  if (uid_read != DBUS_UID_UNSET)
2380  {
2381  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2382  {
2383  _DBUS_SET_OOM (error);
2384  return FALSE;
2385  }
2386  }
2387 
2388  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2389  {
2390  _DBUS_SET_OOM (error);
2391  return FALSE;
2392  }
2393 
2394  /* We don't put any groups in the credentials unless we can put them
2395  * all there. */
2396  if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2397  {
2398  _DBUS_SET_OOM (error);
2399  return FALSE;
2400  }
2401 
2402  return TRUE;
2403 }
2404 
2424  DBusError *error)
2425 {
2426  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2427 
2428  if (write_credentials_byte (server_fd.fd, error))
2429  return TRUE;
2430  else
2431  return FALSE;
2432 }
2433 
2443 DBusSocket
2445 {
2446  DBusSocket client_fd;
2447  struct sockaddr addr;
2448  socklen_t addrlen;
2449 #ifdef HAVE_ACCEPT4
2450  dbus_bool_t cloexec_done;
2451 #endif
2452 
2453  addrlen = sizeof (addr);
2454 
2455  retry:
2456 
2457 #ifdef HAVE_ACCEPT4
2458  /*
2459  * At compile-time, we assume that if accept4() is available in
2460  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2461  * not necessarily true that either is supported by the running kernel.
2462  */
2463  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2464  cloexec_done = client_fd.fd >= 0;
2465 
2466  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2467 #endif
2468  {
2469  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2470  }
2471 
2472  if (client_fd.fd < 0)
2473  {
2474  if (errno == EINTR)
2475  goto retry;
2476  }
2477 
2478  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2479 
2480 #ifdef HAVE_ACCEPT4
2481  if (!cloexec_done)
2482 #endif
2483  {
2484  _dbus_fd_set_close_on_exec(client_fd.fd);
2485  }
2486 
2487  return client_fd;
2488 }
2489 
2500 {
2501  const char *directory;
2502  struct stat sb;
2503 
2504  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2505 
2506  directory = _dbus_string_get_const_data (dir);
2507 
2508  if (stat (directory, &sb) < 0)
2509  {
2510  dbus_set_error (error, _dbus_error_from_errno (errno),
2511  "%s", _dbus_strerror (errno));
2512 
2513  return FALSE;
2514  }
2515 
2516  if (sb.st_uid != geteuid ())
2517  {
2519  "%s directory is owned by user %lu, not %lu",
2520  directory,
2521  (unsigned long) sb.st_uid,
2522  (unsigned long) geteuid ());
2523  return FALSE;
2524  }
2525 
2526  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2527  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2528  {
2530  "%s directory is not private to the user", directory);
2531  return FALSE;
2532  }
2533 
2534  return TRUE;
2535 }
2536 
2537 static dbus_bool_t
2538 fill_user_info_from_passwd (struct passwd *p,
2539  DBusUserInfo *info,
2540  DBusError *error)
2541 {
2542  _dbus_assert (p->pw_name != NULL);
2543  _dbus_assert (p->pw_dir != NULL);
2544 
2545  info->uid = p->pw_uid;
2546  info->primary_gid = p->pw_gid;
2547  info->username = _dbus_strdup (p->pw_name);
2548  info->homedir = _dbus_strdup (p->pw_dir);
2549 
2550  if (info->username == NULL ||
2551  info->homedir == NULL)
2552  {
2554  return FALSE;
2555  }
2556 
2557  return TRUE;
2558 }
2559 
2560 static dbus_bool_t
2561 fill_user_info (DBusUserInfo *info,
2562  dbus_uid_t uid,
2563  const DBusString *username,
2564  DBusError *error)
2565 {
2566  const char *username_c;
2567 
2568  /* exactly one of username/uid provided */
2569  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2570  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2571 
2572  info->uid = DBUS_UID_UNSET;
2573  info->primary_gid = DBUS_GID_UNSET;
2574  info->group_ids = NULL;
2575  info->n_group_ids = 0;
2576  info->username = NULL;
2577  info->homedir = NULL;
2578 
2579  if (username != NULL)
2580  username_c = _dbus_string_get_const_data (username);
2581  else
2582  username_c = NULL;
2583 
2584  /* For now assuming that the getpwnam() and getpwuid() flavors
2585  * are always symmetrical, if not we have to add more configure
2586  * checks
2587  */
2588 
2589 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2590  {
2591  struct passwd *p;
2592  int result;
2593  size_t buflen;
2594  char *buf;
2595  struct passwd p_str;
2596 
2597  /* retrieve maximum needed size for buf */
2598  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2599 
2600  /* sysconf actually returns a long, but everything else expects size_t,
2601  * so just recast here.
2602  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2603  */
2604  if ((long) buflen <= 0)
2605  buflen = 1024;
2606 
2607  result = -1;
2608  while (1)
2609  {
2610  buf = dbus_malloc (buflen);
2611  if (buf == NULL)
2612  {
2614  return FALSE;
2615  }
2616 
2617  p = NULL;
2618 #ifdef HAVE_POSIX_GETPWNAM_R
2619  if (uid != DBUS_UID_UNSET)
2620  result = getpwuid_r (uid, &p_str, buf, buflen,
2621  &p);
2622  else
2623  result = getpwnam_r (username_c, &p_str, buf, buflen,
2624  &p);
2625 #else
2626  if (uid != DBUS_UID_UNSET)
2627  p = getpwuid_r (uid, &p_str, buf, buflen);
2628  else
2629  p = getpwnam_r (username_c, &p_str, buf, buflen);
2630  result = 0;
2631 #endif /* !HAVE_POSIX_GETPWNAM_R */
2632  //Try a bigger buffer if ERANGE was returned
2633  if (result == ERANGE && buflen < 512 * 1024)
2634  {
2635  dbus_free (buf);
2636  buflen *= 2;
2637  }
2638  else
2639  {
2640  break;
2641  }
2642  }
2643  if (result == 0 && p == &p_str)
2644  {
2645  if (!fill_user_info_from_passwd (p, info, error))
2646  {
2647  dbus_free (buf);
2648  return FALSE;
2649  }
2650  dbus_free (buf);
2651  }
2652  else
2653  {
2654  dbus_set_error (error, _dbus_error_from_errno (errno),
2655  "User \"%s\" unknown or no memory to allocate password entry\n",
2656  username_c ? username_c : "???");
2657  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2658  dbus_free (buf);
2659  return FALSE;
2660  }
2661  }
2662 #else /* ! HAVE_GETPWNAM_R */
2663  {
2664  /* I guess we're screwed on thread safety here */
2665  struct passwd *p;
2666 
2667  if (uid != DBUS_UID_UNSET)
2668  p = getpwuid (uid);
2669  else
2670  p = getpwnam (username_c);
2671 
2672  if (p != NULL)
2673  {
2674  if (!fill_user_info_from_passwd (p, info, error))
2675  {
2676  return FALSE;
2677  }
2678  }
2679  else
2680  {
2681  dbus_set_error (error, _dbus_error_from_errno (errno),
2682  "User \"%s\" unknown or no memory to allocate password entry\n",
2683  username_c ? username_c : "???");
2684  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2685  return FALSE;
2686  }
2687  }
2688 #endif /* ! HAVE_GETPWNAM_R */
2689 
2690  /* Fill this in so we can use it to get groups */
2691  username_c = info->username;
2692 
2693 #ifdef HAVE_GETGROUPLIST
2694  {
2695  gid_t *buf;
2696  int buf_count;
2697  int i;
2698  int initial_buf_count;
2699 
2700  initial_buf_count = 17;
2701  buf_count = initial_buf_count;
2702  buf = dbus_new (gid_t, buf_count);
2703  if (buf == NULL)
2704  {
2706  goto failed;
2707  }
2708 
2709  if (getgrouplist (username_c,
2710  info->primary_gid,
2711  buf, &buf_count) < 0)
2712  {
2713  gid_t *new;
2714  /* Presumed cause of negative return code: buf has insufficient
2715  entries to hold the entire group list. The Linux behavior in this
2716  case is to pass back the actual number of groups in buf_count, but
2717  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2718  So as a hack, try to help out a bit by guessing a larger
2719  number of groups, within reason.. might still fail, of course,
2720  but we can at least print a more informative message. I looked up
2721  the "right way" to do this by downloading Apple's own source code
2722  for the "id" command, and it turns out that they use an
2723  undocumented library function getgrouplist_2 (!) which is not
2724  declared in any header in /usr/include (!!). That did not seem
2725  like the way to go here.
2726  */
2727  if (buf_count == initial_buf_count)
2728  {
2729  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2730  }
2731  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2732  if (new == NULL)
2733  {
2735  dbus_free (buf);
2736  goto failed;
2737  }
2738 
2739  buf = new;
2740 
2741  errno = 0;
2742  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2743  {
2744  if (errno == 0)
2745  {
2746  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2747  username_c, buf_count, buf_count);
2748  }
2749  else
2750  {
2751  dbus_set_error (error,
2752  _dbus_error_from_errno (errno),
2753  "Failed to get groups for username \"%s\" primary GID "
2754  DBUS_GID_FORMAT ": %s\n",
2755  username_c, info->primary_gid,
2756  _dbus_strerror (errno));
2757  dbus_free (buf);
2758  goto failed;
2759  }
2760  }
2761  }
2762 
2763  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2764  if (info->group_ids == NULL)
2765  {
2767  dbus_free (buf);
2768  goto failed;
2769  }
2770 
2771  for (i = 0; i < buf_count; ++i)
2772  info->group_ids[i] = buf[i];
2773 
2774  info->n_group_ids = buf_count;
2775 
2776  dbus_free (buf);
2777  }
2778 #else /* HAVE_GETGROUPLIST */
2779  {
2780  /* We just get the one group ID */
2781  info->group_ids = dbus_new (dbus_gid_t, 1);
2782  if (info->group_ids == NULL)
2783  {
2785  goto failed;
2786  }
2787 
2788  info->n_group_ids = 1;
2789 
2790  (info->group_ids)[0] = info->primary_gid;
2791  }
2792 #endif /* HAVE_GETGROUPLIST */
2793 
2794  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2795 
2796  return TRUE;
2797 
2798  failed:
2799  _DBUS_ASSERT_ERROR_IS_SET (error);
2800  return FALSE;
2801 }
2802 
2813  const DBusString *username,
2814  DBusError *error)
2815 {
2816  return fill_user_info (info, DBUS_UID_UNSET,
2817  username, error);
2818 }
2819 
2830  dbus_uid_t uid,
2831  DBusError *error)
2832 {
2833  return fill_user_info (info, uid,
2834  NULL, error);
2835 }
2836 
2846 {
2847  /* The POSIX spec certainly doesn't promise this, but
2848  * we need these assertions to fail as soon as we're wrong about
2849  * it so we can do the porting fixups
2850  */
2851  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2852  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2853  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2854 
2855  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2856  return FALSE;
2857  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2858  return FALSE;
2859 
2860  return TRUE;
2861 }
2862 
2876 {
2877  return _dbus_string_append_uint (str,
2878  _dbus_geteuid ());
2879 }
2880 
2885 dbus_pid_t
2887 {
2888  return getpid ();
2889 }
2890 
2894 dbus_uid_t
2896 {
2897  return getuid ();
2898 }
2899 
2903 dbus_uid_t
2905 {
2906  return geteuid ();
2907 }
2908 
2915 unsigned long
2917 {
2918  return getpid ();
2919 }
2920 
2929 _dbus_parse_uid (const DBusString *uid_str,
2930  dbus_uid_t *uid)
2931 {
2932  int end;
2933  long val;
2934 
2935  if (_dbus_string_get_length (uid_str) == 0)
2936  {
2937  _dbus_verbose ("UID string was zero length\n");
2938  return FALSE;
2939  }
2940 
2941  val = -1;
2942  end = 0;
2943  if (!_dbus_string_parse_int (uid_str, 0, &val,
2944  &end))
2945  {
2946  _dbus_verbose ("could not parse string as a UID\n");
2947  return FALSE;
2948  }
2949 
2950  if (end != _dbus_string_get_length (uid_str))
2951  {
2952  _dbus_verbose ("string contained trailing stuff after UID\n");
2953  return FALSE;
2954  }
2955 
2956  *uid = val;
2957 
2958  return TRUE;
2959 }
2960 
2961 #if !DBUS_USE_SYNC
2962 /* To be thread-safe by default on platforms that don't necessarily have
2963  * atomic operations (notably Debian armel, which is armv4t), we must
2964  * use a mutex that can be initialized statically, like this.
2965  * GLib >= 2.32 uses a similar system.
2966  */
2967 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2968 #endif
2969 
2976 dbus_int32_t
2978 {
2979 #if DBUS_USE_SYNC
2980  return __sync_add_and_fetch(&atomic->value, 1)-1;
2981 #else
2982  dbus_int32_t res;
2983 
2984  pthread_mutex_lock (&atomic_mutex);
2985  res = atomic->value;
2986  atomic->value += 1;
2987  pthread_mutex_unlock (&atomic_mutex);
2988 
2989  return res;
2990 #endif
2991 }
2992 
2999 dbus_int32_t
3001 {
3002 #if DBUS_USE_SYNC
3003  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3004 #else
3005  dbus_int32_t res;
3006 
3007  pthread_mutex_lock (&atomic_mutex);
3008  res = atomic->value;
3009  atomic->value -= 1;
3010  pthread_mutex_unlock (&atomic_mutex);
3011 
3012  return res;
3013 #endif
3014 }
3015 
3023 dbus_int32_t
3025 {
3026 #if DBUS_USE_SYNC
3027  __sync_synchronize ();
3028  return atomic->value;
3029 #else
3030  dbus_int32_t res;
3031 
3032  pthread_mutex_lock (&atomic_mutex);
3033  res = atomic->value;
3034  pthread_mutex_unlock (&atomic_mutex);
3035 
3036  return res;
3037 #endif
3038 }
3039 
3048 int
3050  int n_fds,
3051  int timeout_milliseconds)
3052 {
3053 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3054  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3055  if (timeout_milliseconds < -1)
3056  {
3057  timeout_milliseconds = -1;
3058  }
3059 
3060  return poll (fds,
3061  n_fds,
3062  timeout_milliseconds);
3063 #else /* ! HAVE_POLL */
3064  /* Emulate poll() in terms of select() */
3065  fd_set read_set, write_set, err_set;
3066  int max_fd = 0;
3067  int i;
3068  struct timeval tv;
3069  int ready;
3070 
3071  FD_ZERO (&read_set);
3072  FD_ZERO (&write_set);
3073  FD_ZERO (&err_set);
3074 
3075  for (i = 0; i < n_fds; i++)
3076  {
3077  DBusPollFD *fdp = &fds[i];
3078 
3079  if (fdp->events & _DBUS_POLLIN)
3080  FD_SET (fdp->fd, &read_set);
3081 
3082  if (fdp->events & _DBUS_POLLOUT)
3083  FD_SET (fdp->fd, &write_set);
3084 
3085  FD_SET (fdp->fd, &err_set);
3086 
3087  max_fd = MAX (max_fd, fdp->fd);
3088  }
3089 
3090  tv.tv_sec = timeout_milliseconds / 1000;
3091  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3092 
3093  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3094  timeout_milliseconds < 0 ? NULL : &tv);
3095 
3096  if (ready > 0)
3097  {
3098  for (i = 0; i < n_fds; i++)
3099  {
3100  DBusPollFD *fdp = &fds[i];
3101 
3102  fdp->revents = 0;
3103 
3104  if (FD_ISSET (fdp->fd, &read_set))
3105  fdp->revents |= _DBUS_POLLIN;
3106 
3107  if (FD_ISSET (fdp->fd, &write_set))
3108  fdp->revents |= _DBUS_POLLOUT;
3109 
3110  if (FD_ISSET (fdp->fd, &err_set))
3111  fdp->revents |= _DBUS_POLLERR;
3112  }
3113  }
3114 
3115  return ready;
3116 #endif
3117 }
3118 
3126 void
3128  long *tv_usec)
3129 {
3130 #ifdef HAVE_MONOTONIC_CLOCK
3131  struct timespec ts;
3132  clock_gettime (CLOCK_MONOTONIC, &ts);
3133 
3134  if (tv_sec)
3135  *tv_sec = ts.tv_sec;
3136  if (tv_usec)
3137  *tv_usec = ts.tv_nsec / 1000;
3138 #else
3139  struct timeval t;
3140 
3141  gettimeofday (&t, NULL);
3142 
3143  if (tv_sec)
3144  *tv_sec = t.tv_sec;
3145  if (tv_usec)
3146  *tv_usec = t.tv_usec;
3147 #endif
3148 }
3149 
3157 void
3158 _dbus_get_real_time (long *tv_sec,
3159  long *tv_usec)
3160 {
3161  struct timeval t;
3162 
3163  gettimeofday (&t, NULL);
3164 
3165  if (tv_sec)
3166  *tv_sec = t.tv_sec;
3167  if (tv_usec)
3168  *tv_usec = t.tv_usec;
3169 }
3170 
3181  DBusError *error)
3182 {
3183  const char *filename_c;
3184 
3185  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3186 
3187  filename_c = _dbus_string_get_const_data (filename);
3188 
3189  if (mkdir (filename_c, 0700) < 0)
3190  {
3191  if (errno == EEXIST)
3192  return TRUE;
3193 
3195  "Failed to create directory %s: %s\n",
3196  filename_c, _dbus_strerror (errno));
3197  return FALSE;
3198  }
3199  else
3200  return TRUE;
3201 }
3202 
3213  DBusError *error)
3214 {
3215  const char *filename_c;
3216 
3217  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3218 
3219  filename_c = _dbus_string_get_const_data (filename);
3220 
3221  if (mkdir (filename_c, 0700) < 0)
3222  {
3224  "Failed to create directory %s: %s\n",
3225  filename_c, _dbus_strerror (errno));
3226  return FALSE;
3227  }
3228  else
3229  return TRUE;
3230 }
3231 
3244  const DBusString *next_component)
3245 {
3246  dbus_bool_t dir_ends_in_slash;
3247  dbus_bool_t file_starts_with_slash;
3248 
3249  if (_dbus_string_get_length (dir) == 0 ||
3250  _dbus_string_get_length (next_component) == 0)
3251  return TRUE;
3252 
3253  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3254  _dbus_string_get_length (dir) - 1);
3255 
3256  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3257 
3258  if (dir_ends_in_slash && file_starts_with_slash)
3259  {
3260  _dbus_string_shorten (dir, 1);
3261  }
3262  else if (!(dir_ends_in_slash || file_starts_with_slash))
3263  {
3264  if (!_dbus_string_append_byte (dir, '/'))
3265  return FALSE;
3266  }
3267 
3268  return _dbus_string_copy (next_component, 0, dir,
3269  _dbus_string_get_length (dir));
3270 }
3271 
3273 #define NANOSECONDS_PER_SECOND 1000000000
3274 
3275 #define MICROSECONDS_PER_SECOND 1000000
3276 
3277 #define MILLISECONDS_PER_SECOND 1000
3278 
3279 #define NANOSECONDS_PER_MILLISECOND 1000000
3280 
3281 #define MICROSECONDS_PER_MILLISECOND 1000
3282 
3287 void
3288 _dbus_sleep_milliseconds (int milliseconds)
3289 {
3290 #ifdef HAVE_NANOSLEEP
3291  struct timespec req;
3292  struct timespec rem;
3293 
3294  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3295  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3296  rem.tv_sec = 0;
3297  rem.tv_nsec = 0;
3298 
3299  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3300  req = rem;
3301 #elif defined (HAVE_USLEEP)
3302  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3303 #else /* ! HAVE_USLEEP */
3304  sleep (MAX (milliseconds / 1000, 1));
3305 #endif
3306 }
3307 
3319  int n_bytes,
3320  DBusError *error)
3321 {
3322  int old_len;
3323  int fd;
3324  int result;
3325 
3326  old_len = _dbus_string_get_length (str);
3327  fd = -1;
3328 
3329  /* note, urandom on linux will fall back to pseudorandom */
3330  fd = open ("/dev/urandom", O_RDONLY);
3331 
3332  if (fd < 0)
3333  {
3334  dbus_set_error (error, _dbus_error_from_errno (errno),
3335  "Could not open /dev/urandom: %s",
3336  _dbus_strerror (errno));
3337  return FALSE;
3338  }
3339 
3340  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3341 
3342  result = _dbus_read (fd, str, n_bytes);
3343 
3344  if (result != n_bytes)
3345  {
3346  if (result < 0)
3347  dbus_set_error (error, _dbus_error_from_errno (errno),
3348  "Could not read /dev/urandom: %s",
3349  _dbus_strerror (errno));
3350  else
3352  "Short read from /dev/urandom");
3353 
3354  _dbus_close (fd, NULL);
3355  _dbus_string_set_length (str, old_len);
3356  return FALSE;
3357  }
3358 
3359  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3360  n_bytes);
3361 
3362  _dbus_close (fd, NULL);
3363 
3364  return TRUE;
3365 }
3366 
3372 void
3373 _dbus_exit (int code)
3374 {
3375  _exit (code);
3376 }
3377 
3386 const char*
3387 _dbus_strerror (int error_number)
3388 {
3389  const char *msg;
3390 
3391  msg = strerror (error_number);
3392  if (msg == NULL)
3393  msg = "unknown";
3394 
3395  return msg;
3396 }
3397 
3401 void
3403 {
3404  signal (SIGPIPE, SIG_IGN);
3405 }
3406 
3414 void
3416 {
3417  int val;
3418 
3419  val = fcntl (fd, F_GETFD, 0);
3420 
3421  if (val < 0)
3422  return;
3423 
3424  val |= FD_CLOEXEC;
3425 
3426  fcntl (fd, F_SETFD, val);
3427 }
3428 
3437 _dbus_close (int fd,
3438  DBusError *error)
3439 {
3440  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3441 
3442  again:
3443  if (close (fd) < 0)
3444  {
3445  if (errno == EINTR)
3446  goto again;
3447 
3448  dbus_set_error (error, _dbus_error_from_errno (errno),
3449  "Could not close fd %d", fd);
3450  return FALSE;
3451  }
3452 
3453  return TRUE;
3454 }
3455 
3464 int
3465 _dbus_dup(int fd,
3466  DBusError *error)
3467 {
3468  int new_fd;
3469 
3470 #ifdef F_DUPFD_CLOEXEC
3471  dbus_bool_t cloexec_done;
3472 
3473  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3474  cloexec_done = new_fd >= 0;
3475 
3476  if (new_fd < 0 && errno == EINVAL)
3477 #endif
3478  {
3479  new_fd = fcntl(fd, F_DUPFD, 3);
3480  }
3481 
3482  if (new_fd < 0) {
3483 
3484  dbus_set_error (error, _dbus_error_from_errno (errno),
3485  "Could not duplicate fd %d", fd);
3486  return -1;
3487  }
3488 
3489 #ifdef F_DUPFD_CLOEXEC
3490  if (!cloexec_done)
3491 #endif
3492  {
3494  }
3495 
3496  return new_fd;
3497 }
3498 
3508  DBusError *error)
3509 {
3510  return _dbus_set_fd_nonblocking (fd.fd, error);
3511 }
3512 
3513 static dbus_bool_t
3514 _dbus_set_fd_nonblocking (int fd,
3515  DBusError *error)
3516 {
3517  int val;
3518 
3519  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3520 
3521  val = fcntl (fd, F_GETFL, 0);
3522  if (val < 0)
3523  {
3524  dbus_set_error (error, _dbus_error_from_errno (errno),
3525  "Failed to get flags from file descriptor %d: %s",
3526  fd, _dbus_strerror (errno));
3527  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3528  _dbus_strerror (errno));
3529  return FALSE;
3530  }
3531 
3532  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3533  {
3534  dbus_set_error (error, _dbus_error_from_errno (errno),
3535  "Failed to set nonblocking flag of file descriptor %d: %s",
3536  fd, _dbus_strerror (errno));
3537  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3538  fd, _dbus_strerror (errno));
3539 
3540  return FALSE;
3541  }
3542 
3543  return TRUE;
3544 }
3545 
3551 void
3553 {
3554 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3555  void *bt[500];
3556  int bt_size;
3557  int i;
3558  char **syms;
3559 
3560  bt_size = backtrace (bt, 500);
3561 
3562  syms = backtrace_symbols (bt, bt_size);
3563 
3564  i = 0;
3565  while (i < bt_size)
3566  {
3567  /* don't use dbus_warn since it can _dbus_abort() */
3568  fprintf (stderr, " %s\n", syms[i]);
3569  ++i;
3570  }
3571  fflush (stderr);
3572 
3573  free (syms);
3574 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3575  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3576 #else
3577  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3578 #endif
3579 }
3580 
3595  DBusSocket *fd2,
3596  dbus_bool_t blocking,
3597  DBusError *error)
3598 {
3599 #ifdef HAVE_SOCKETPAIR
3600  int fds[2];
3601  int retval;
3602 
3603 #ifdef SOCK_CLOEXEC
3604  dbus_bool_t cloexec_done;
3605 
3606  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3607  cloexec_done = retval >= 0;
3608 
3609  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3610 #endif
3611  {
3612  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3613  }
3614 
3615  if (retval < 0)
3616  {
3617  dbus_set_error (error, _dbus_error_from_errno (errno),
3618  "Could not create full-duplex pipe");
3619  return FALSE;
3620  }
3621 
3622  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3623 
3624 #ifdef SOCK_CLOEXEC
3625  if (!cloexec_done)
3626 #endif
3627  {
3628  _dbus_fd_set_close_on_exec (fds[0]);
3629  _dbus_fd_set_close_on_exec (fds[1]);
3630  }
3631 
3632  if (!blocking &&
3633  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3634  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3635  {
3636  dbus_set_error (error, _dbus_error_from_errno (errno),
3637  "Could not set full-duplex pipe nonblocking");
3638 
3639  _dbus_close (fds[0], NULL);
3640  _dbus_close (fds[1], NULL);
3641 
3642  return FALSE;
3643  }
3644 
3645  fd1->fd = fds[0];
3646  fd2->fd = fds[1];
3647 
3648  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3649  fd1->fd, fd2->fd);
3650 
3651  return TRUE;
3652 #else
3653  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3655  "_dbus_socketpair() not implemented on this OS");
3656  return FALSE;
3657 #endif
3658 }
3659 
3668 int
3670  va_list args)
3671 {
3672  char static_buf[1024];
3673  int bufsize = sizeof (static_buf);
3674  int len;
3675  va_list args_copy;
3676 
3677  DBUS_VA_COPY (args_copy, args);
3678  len = vsnprintf (static_buf, bufsize, format, args_copy);
3679  va_end (args_copy);
3680 
3681  /* If vsnprintf() returned non-negative, then either the string fits in
3682  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3683  * returns the number of characters that were needed, or this OS returns the
3684  * truncated length.
3685  *
3686  * We ignore the possibility that snprintf might just ignore the length and
3687  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3688  * If your libc is really that bad, come back when you have a better one. */
3689  if (len == bufsize)
3690  {
3691  /* This could be the truncated length (Tru64 and IRIX have this bug),
3692  * or the real length could be coincidentally the same. Which is it?
3693  * If vsnprintf returns the truncated length, we'll go to the slow
3694  * path. */
3695  DBUS_VA_COPY (args_copy, args);
3696 
3697  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3698  len = -1;
3699 
3700  va_end (args_copy);
3701  }
3702 
3703  /* If vsnprintf() returned negative, we have to do more work.
3704  * HP-UX returns negative. */
3705  while (len < 0)
3706  {
3707  char *buf;
3708 
3709  bufsize *= 2;
3710 
3711  buf = dbus_malloc (bufsize);
3712 
3713  if (buf == NULL)
3714  return -1;
3715 
3716  DBUS_VA_COPY (args_copy, args);
3717  len = vsnprintf (buf, bufsize, format, args_copy);
3718  va_end (args_copy);
3719 
3720  dbus_free (buf);
3721 
3722  /* If the reported length is exactly the buffer size, round up to the
3723  * next size, in case vsnprintf has been returning the truncated
3724  * length */
3725  if (len == bufsize)
3726  len = -1;
3727  }
3728 
3729  return len;
3730 }
3731 
3738 const char*
3740 {
3741  /* Protected by _DBUS_LOCK_sysdeps */
3742  static const char* tmpdir = NULL;
3743 
3744  if (!_DBUS_LOCK (sysdeps))
3745  return NULL;
3746 
3747  if (tmpdir == NULL)
3748  {
3749  /* TMPDIR is what glibc uses, then
3750  * glibc falls back to the P_tmpdir macro which
3751  * just expands to "/tmp"
3752  */
3753  if (tmpdir == NULL)
3754  tmpdir = getenv("TMPDIR");
3755 
3756  /* These two env variables are probably
3757  * broken, but maybe some OS uses them?
3758  */
3759  if (tmpdir == NULL)
3760  tmpdir = getenv("TMP");
3761  if (tmpdir == NULL)
3762  tmpdir = getenv("TEMP");
3763 
3764  /* And this is the sane fallback. */
3765  if (tmpdir == NULL)
3766  tmpdir = "/tmp";
3767  }
3768 
3769  _DBUS_UNLOCK (sysdeps);
3770 
3771  _dbus_assert(tmpdir != NULL);
3772 
3773  return tmpdir;
3774 }
3775 
3776 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3777 
3796 static dbus_bool_t
3797 _read_subprocess_line_argv (const char *progpath,
3798  dbus_bool_t path_fallback,
3799  const char * const *argv,
3800  DBusString *result,
3801  DBusError *error)
3802 {
3803  int result_pipe[2] = { -1, -1 };
3804  int errors_pipe[2] = { -1, -1 };
3805  pid_t pid;
3806  int ret;
3807  int status;
3808  int orig_len;
3809 
3810  dbus_bool_t retval;
3811  sigset_t new_set, old_set;
3812 
3813  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3814  retval = FALSE;
3815 
3816  /* We need to block any existing handlers for SIGCHLD temporarily; they
3817  * will cause waitpid() below to fail.
3818  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3819  */
3820  sigemptyset (&new_set);
3821  sigaddset (&new_set, SIGCHLD);
3822  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3823 
3824  orig_len = _dbus_string_get_length (result);
3825 
3826 #define READ_END 0
3827 #define WRITE_END 1
3828  if (pipe (result_pipe) < 0)
3829  {
3830  dbus_set_error (error, _dbus_error_from_errno (errno),
3831  "Failed to create a pipe to call %s: %s",
3832  progpath, _dbus_strerror (errno));
3833  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3834  progpath, _dbus_strerror (errno));
3835  goto out;
3836  }
3837  if (pipe (errors_pipe) < 0)
3838  {
3839  dbus_set_error (error, _dbus_error_from_errno (errno),
3840  "Failed to create a pipe to call %s: %s",
3841  progpath, _dbus_strerror (errno));
3842  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3843  progpath, _dbus_strerror (errno));
3844  goto out;
3845  }
3846 
3847  pid = fork ();
3848  if (pid < 0)
3849  {
3850  dbus_set_error (error, _dbus_error_from_errno (errno),
3851  "Failed to fork() to call %s: %s",
3852  progpath, _dbus_strerror (errno));
3853  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3854  progpath, _dbus_strerror (errno));
3855  goto out;
3856  }
3857 
3858  if (pid == 0)
3859  {
3860  /* child process */
3861  const char *error_str;
3862 
3863  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3864  {
3865  int saved_errno = errno;
3866 
3867  /* Try to write details into the pipe, but don't bother
3868  * trying too hard (no retry loop). */
3869 
3870  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3871  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3872  {
3873  /* ignore, not much we can do */
3874  }
3875 
3876  error_str = _dbus_strerror (saved_errno);
3877 
3878  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3879  {
3880  /* ignore, not much we can do */
3881  }
3882 
3883  _exit (1);
3884  }
3885 
3886  /* set-up stdXXX */
3887  close (result_pipe[READ_END]);
3888  close (errors_pipe[READ_END]);
3889 
3890  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3891  _exit (1);
3892  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3893  _exit (1);
3894 
3895  _dbus_close_all ();
3896 
3897  sigprocmask (SIG_SETMASK, &old_set, NULL);
3898 
3899  /* If it looks fully-qualified, try execv first */
3900  if (progpath[0] == '/')
3901  {
3902  execv (progpath, (char * const *) argv);
3903  /* Ok, that failed. Now if path_fallback is given, let's
3904  * try unqualified. This is mostly a hack to work
3905  * around systems which ship dbus-launch in /usr/bin
3906  * but everything else in /bin (because dbus-launch
3907  * depends on X11).
3908  */
3909  if (path_fallback)
3910  /* We must have a slash, because we checked above */
3911  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3912  }
3913  else
3914  execvp (progpath, (char * const *) argv);
3915 
3916  /* still nothing, we failed */
3917  _exit (1);
3918  }
3919 
3920  /* parent process */
3921  close (result_pipe[WRITE_END]);
3922  close (errors_pipe[WRITE_END]);
3923  result_pipe[WRITE_END] = -1;
3924  errors_pipe[WRITE_END] = -1;
3925 
3926  ret = 0;
3927  do
3928  {
3929  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3930  }
3931  while (ret > 0);
3932 
3933  /* reap the child process to avoid it lingering as zombie */
3934  do
3935  {
3936  ret = waitpid (pid, &status, 0);
3937  }
3938  while (ret == -1 && errno == EINTR);
3939 
3940  /* We succeeded if the process exited with status 0 and
3941  anything was read */
3942  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3943  {
3944  /* The process ended with error */
3945  DBusString error_message;
3946  if (!_dbus_string_init (&error_message))
3947  {
3948  _DBUS_SET_OOM (error);
3949  goto out;
3950  }
3951 
3952  ret = 0;
3953  do
3954  {
3955  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3956  }
3957  while (ret > 0);
3958 
3959  _dbus_string_set_length (result, orig_len);
3960  if (_dbus_string_get_length (&error_message) > 0)
3962  "%s terminated abnormally with the following error: %s",
3963  progpath, _dbus_string_get_data (&error_message));
3964  else
3966  "%s terminated abnormally without any error message",
3967  progpath);
3968  goto out;
3969  }
3970 
3971  retval = TRUE;
3972 
3973  out:
3974  sigprocmask (SIG_SETMASK, &old_set, NULL);
3975 
3976  if (retval)
3977  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3978  else
3979  _DBUS_ASSERT_ERROR_IS_SET (error);
3980 
3981  if (result_pipe[0] != -1)
3982  close (result_pipe[0]);
3983  if (result_pipe[1] != -1)
3984  close (result_pipe[1]);
3985  if (errors_pipe[0] != -1)
3986  close (errors_pipe[0]);
3987  if (errors_pipe[1] != -1)
3988  close (errors_pipe[1]);
3989 
3990  return retval;
3991 }
3992 #endif
3993 
4007 _dbus_get_autolaunch_address (const char *scope,
4008  DBusString *address,
4009  DBusError *error)
4010 {
4011 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4012  static const char arg_dbus_launch[] = "dbus-launch";
4013  static const char arg_autolaunch[] = "--autolaunch";
4014  static const char arg_binary_syntax[] = "--binary-syntax";
4015  static const char arg_close_stderr[] = "--close-stderr";
4016 
4017  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4018  * but that's done elsewhere, and if it worked, this function wouldn't
4019  * be called.) */
4020  const char *display;
4021  const char *progpath;
4022  const char *argv[6];
4023  int i;
4024  DBusString uuid;
4025  dbus_bool_t retval;
4026 
4027  if (_dbus_check_setuid ())
4028  {
4030  "Unable to autolaunch when setuid");
4031  return FALSE;
4032  }
4033 
4034  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4035  retval = FALSE;
4036 
4037  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4038  * dbus-launch-x11 is just going to fail. Rather than trying to
4039  * run it, we might as well bail out early with a nice error.
4040  *
4041  * This is not strictly true in a world where the user bus exists,
4042  * because dbus-launch --autolaunch knows how to connect to that -
4043  * but if we were going to connect to the user bus, we'd have done
4044  * so before trying autolaunch: in any case. */
4045  display = _dbus_getenv ("DISPLAY");
4046 
4047  if (display == NULL || display[0] == '\0')
4048  {
4050  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4051  return FALSE;
4052  }
4053 
4054  if (!_dbus_string_init (&uuid))
4055  {
4056  _DBUS_SET_OOM (error);
4057  return FALSE;
4058  }
4059 
4060  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4061  {
4062  goto out;
4063  }
4064 
4065 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4066  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4067 
4068  if (progpath == NULL)
4069 #endif
4070  progpath = DBUS_BINDIR "/dbus-launch";
4071  /*
4072  * argv[0] is always dbus-launch, that's the name what we'll
4073  * get from /proc, or ps(1), regardless what the progpath is,
4074  * see fd.o#69716
4075  */
4076  i = 0;
4077  argv[i] = arg_dbus_launch;
4078  ++i;
4079  argv[i] = arg_autolaunch;
4080  ++i;
4081  argv[i] = _dbus_string_get_data (&uuid);
4082  ++i;
4083  argv[i] = arg_binary_syntax;
4084  ++i;
4085  argv[i] = arg_close_stderr;
4086  ++i;
4087  argv[i] = NULL;
4088  ++i;
4089 
4090  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4091 
4092  retval = _read_subprocess_line_argv (progpath,
4093  TRUE,
4094  argv, address, error);
4095 
4096  out:
4097  _dbus_string_free (&uuid);
4098  return retval;
4099 #else
4101  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4102  "set your DBUS_SESSION_BUS_ADDRESS instead");
4103  return FALSE;
4104 #endif
4105 }
4106 
4127  dbus_bool_t create_if_not_found,
4128  DBusError *error)
4129 {
4130  DBusError our_error = DBUS_ERROR_INIT;
4131  DBusError etc_error = DBUS_ERROR_INIT;
4132  DBusString filename;
4133  dbus_bool_t b;
4134 
4135  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4136 
4137  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4138  if (b)
4139  return TRUE;
4140 
4141  /* Fallback to the system machine ID */
4142  _dbus_string_init_const (&filename, "/etc/machine-id");
4143  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4144 
4145  if (b)
4146  {
4147  if (create_if_not_found)
4148  {
4149  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4150  * complain if that isn't possible for whatever reason */
4151  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4152  _dbus_write_uuid_file (&filename, machine_id, NULL);
4153  }
4154 
4155  dbus_error_free (&our_error);
4156  return TRUE;
4157  }
4158 
4159  if (!create_if_not_found)
4160  {
4161  dbus_set_error (error, etc_error.name,
4162  "D-Bus library appears to be incorrectly set up: "
4163  "see the manual page for dbus-uuidgen to correct "
4164  "this issue. (%s; %s)",
4165  our_error.message, etc_error.message);
4166  dbus_error_free (&our_error);
4167  dbus_error_free (&etc_error);
4168  return FALSE;
4169  }
4170 
4171  dbus_error_free (&our_error);
4172  dbus_error_free (&etc_error);
4173 
4174  /* if none found, try to make a new one */
4175  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4176 
4177  if (!_dbus_generate_uuid (machine_id, error))
4178  return FALSE;
4179 
4180  return _dbus_write_uuid_file (&filename, machine_id, error);
4181 }
4182 
4192  const char *launchd_env_var,
4193  DBusError *error)
4194 {
4195 #ifdef DBUS_ENABLE_LAUNCHD
4196  char *argv[4];
4197  int i;
4198 
4199  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4200 
4201  if (_dbus_check_setuid ())
4202  {
4204  "Unable to find launchd socket when setuid");
4205  return FALSE;
4206  }
4207 
4208  i = 0;
4209  argv[i] = "launchctl";
4210  ++i;
4211  argv[i] = "getenv";
4212  ++i;
4213  argv[i] = (char*)launchd_env_var;
4214  ++i;
4215  argv[i] = NULL;
4216  ++i;
4217 
4218  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4219 
4220  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4221  {
4222  return FALSE;
4223  }
4224 
4225  /* no error, but no result either */
4226  if (_dbus_string_get_length(socket_path) == 0)
4227  {
4228  return FALSE;
4229  }
4230 
4231  /* strip the carriage-return */
4232  _dbus_string_shorten(socket_path, 1);
4233  return TRUE;
4234 #else /* DBUS_ENABLE_LAUNCHD */
4236  "can't lookup socket from launchd; launchd support not compiled in");
4237  return FALSE;
4238 #endif
4239 }
4240 
4241 #ifdef DBUS_ENABLE_LAUNCHD
4242 static dbus_bool_t
4243 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4244 {
4245  dbus_bool_t valid_socket;
4246  DBusString socket_path;
4247 
4248  if (_dbus_check_setuid ())
4249  {
4251  "Unable to find launchd socket when setuid");
4252  return FALSE;
4253  }
4254 
4255  if (!_dbus_string_init (&socket_path))
4256  {
4257  _DBUS_SET_OOM (error);
4258  return FALSE;
4259  }
4260 
4261  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4262 
4263  if (dbus_error_is_set(error))
4264  {
4265  _dbus_string_free(&socket_path);
4266  return FALSE;
4267  }
4268 
4269  if (!valid_socket)
4270  {
4271  dbus_set_error(error, "no socket path",
4272  "launchd did not provide a socket path, "
4273  "verify that org.freedesktop.dbus-session.plist is loaded!");
4274  _dbus_string_free(&socket_path);
4275  return FALSE;
4276  }
4277  if (!_dbus_string_append (address, "unix:path="))
4278  {
4279  _DBUS_SET_OOM (error);
4280  _dbus_string_free(&socket_path);
4281  return FALSE;
4282  }
4283  if (!_dbus_string_copy (&socket_path, 0, address,
4284  _dbus_string_get_length (address)))
4285  {
4286  _DBUS_SET_OOM (error);
4287  _dbus_string_free(&socket_path);
4288  return FALSE;
4289  }
4290 
4291  _dbus_string_free(&socket_path);
4292  return TRUE;
4293 }
4294 #endif
4295 
4297 _dbus_lookup_user_bus (dbus_bool_t *supported,
4298  DBusString *address,
4299  DBusError *error)
4300 {
4301  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4302  dbus_bool_t ret = FALSE;
4303  struct stat stbuf;
4304  DBusString user_bus_path;
4305 
4306  if (runtime_dir == NULL)
4307  {
4308  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4309  *supported = FALSE;
4310  return TRUE; /* Cannot use it, but not an error */
4311  }
4312 
4313  if (!_dbus_string_init (&user_bus_path))
4314  {
4315  _DBUS_SET_OOM (error);
4316  return FALSE;
4317  }
4318 
4319  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4320  {
4321  _DBUS_SET_OOM (error);
4322  goto out;
4323  }
4324 
4325  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4326  {
4327  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4328  _dbus_strerror (errno));
4329  *supported = FALSE;
4330  ret = TRUE; /* Cannot use it, but not an error */
4331  goto out;
4332  }
4333 
4334  if (stbuf.st_uid != getuid ())
4335  {
4336  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4337  (long) stbuf.st_uid, (long) getuid ());
4338  *supported = FALSE;
4339  ret = TRUE; /* Cannot use it, but not an error */
4340  goto out;
4341  }
4342 
4343  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4344  {
4345  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4346  (long) stbuf.st_mode);
4347  *supported = FALSE;
4348  ret = TRUE; /* Cannot use it, but not an error */
4349  goto out;
4350  }
4351 
4352  if (!_dbus_string_append (address, "unix:path=") ||
4353  !_dbus_address_append_escaped (address, &user_bus_path))
4354  {
4355  _DBUS_SET_OOM (error);
4356  goto out;
4357  }
4358 
4359  *supported = TRUE;
4360  ret = TRUE;
4361 
4362 out:
4363  _dbus_string_free (&user_bus_path);
4364  return ret;
4365 }
4366 
4388  DBusString *address,
4389  DBusError *error)
4390 {
4391 #ifdef DBUS_ENABLE_LAUNCHD
4392  *supported = TRUE;
4393  return _dbus_lookup_session_address_launchd (address, error);
4394 #else
4395  *supported = FALSE;
4396 
4397  if (!_dbus_lookup_user_bus (supported, address, error))
4398  return FALSE;
4399  else if (*supported)
4400  return TRUE;
4401 
4402  /* On non-Mac Unix platforms, if the session address isn't already
4403  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4404  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4405  * autolaunch: global default; see init_session_address in
4406  * dbus/dbus-bus.c. */
4407  return TRUE;
4408 #endif
4409 }
4410 
4418 void
4420 {
4422 }
4423 
4439  DBusCredentials *credentials)
4440 {
4441  DBusString homedir;
4442  DBusString dotdir;
4443  dbus_uid_t uid;
4444 
4445  _dbus_assert (credentials != NULL);
4447 
4448  if (!_dbus_string_init (&homedir))
4449  return FALSE;
4450 
4451  uid = _dbus_credentials_get_unix_uid (credentials);
4452  _dbus_assert (uid != DBUS_UID_UNSET);
4453 
4454  if (!_dbus_homedir_from_uid (uid, &homedir))
4455  goto failed;
4456 
4457 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4458  {
4459  const char *override;
4460 
4461  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4462  if (override != NULL && *override != '\0')
4463  {
4464  _dbus_string_set_length (&homedir, 0);
4465  if (!_dbus_string_append (&homedir, override))
4466  goto failed;
4467 
4468  _dbus_verbose ("Using fake homedir for testing: %s\n",
4469  _dbus_string_get_const_data (&homedir));
4470  }
4471  else
4472  {
4473  /* Not strictly thread-safe, but if we fail at thread-safety here,
4474  * the worst that will happen is some extra warnings. */
4475  static dbus_bool_t already_warned = FALSE;
4476  if (!already_warned)
4477  {
4478  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4479  _dbus_string_get_const_data (&homedir));
4480  already_warned = TRUE;
4481  }
4482  }
4483  }
4484 #endif
4485 
4486  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4487  if (!_dbus_concat_dir_and_file (&homedir,
4488  &dotdir))
4489  goto failed;
4490 
4491  if (!_dbus_string_copy (&homedir, 0,
4492  directory, _dbus_string_get_length (directory))) {
4493  goto failed;
4494  }
4495 
4496  _dbus_string_free (&homedir);
4497  return TRUE;
4498 
4499  failed:
4500  _dbus_string_free (&homedir);
4501  return FALSE;
4502 }
4503 
4504 //PENDING(kdab) docs
4506 _dbus_daemon_publish_session_bus_address (const char* addr,
4507  const char *scope)
4508 {
4509  return TRUE;
4510 }
4511 
4512 //PENDING(kdab) docs
4513 void
4514 _dbus_daemon_unpublish_session_bus_address (void)
4515 {
4516 
4517 }
4518 
4527 {
4528  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4529  * EWOULDBLOCK are numerically equal, which is permitted as described by
4530  * errno(3).
4531  */
4532 #if EAGAIN == EWOULDBLOCK
4533  return e == EAGAIN;
4534 #else
4535  return e == EAGAIN || e == EWOULDBLOCK;
4536 #endif
4537 }
4538 
4548  DBusError *error)
4549 {
4550  const char *filename_c;
4551 
4552  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4553 
4554  filename_c = _dbus_string_get_const_data (filename);
4555 
4556  if (rmdir (filename_c) != 0)
4557  {
4559  "Failed to remove directory %s: %s\n",
4560  filename_c, _dbus_strerror (errno));
4561  return FALSE;
4562  }
4563 
4564  return TRUE;
4565 }
4566 
4576 {
4577 #ifdef SCM_RIGHTS
4578  union {
4579  struct sockaddr sa;
4580  struct sockaddr_storage storage;
4581  struct sockaddr_un un;
4582  } sa_buf;
4583 
4584  socklen_t sa_len = sizeof(sa_buf);
4585 
4586  _DBUS_ZERO(sa_buf);
4587 
4588  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4589  return FALSE;
4590 
4591  return sa_buf.sa.sa_family == AF_UNIX;
4592 
4593 #else
4594  return FALSE;
4595 
4596 #endif
4597 }
4598 
4603 void
4605 {
4606  int maxfds, i;
4607 
4608 #ifdef __linux__
4609  DIR *d;
4610 
4611  /* On Linux we can optimize this a bit if /proc is available. If it
4612  isn't available, fall back to the brute force way. */
4613 
4614  d = opendir ("/proc/self/fd");
4615  if (d)
4616  {
4617  for (;;)
4618  {
4619  struct dirent *de;
4620  int fd;
4621  long l;
4622  char *e = NULL;
4623 
4624  de = readdir (d);
4625  if (!de)
4626  break;
4627 
4628  if (de->d_name[0] == '.')
4629  continue;
4630 
4631  errno = 0;
4632  l = strtol (de->d_name, &e, 10);
4633  if (errno != 0 || e == NULL || *e != '\0')
4634  continue;
4635 
4636  fd = (int) l;
4637  if (fd < 3)
4638  continue;
4639 
4640  if (fd == dirfd (d))
4641  continue;
4642 
4643  close (fd);
4644  }
4645 
4646  closedir (d);
4647  return;
4648  }
4649 #endif
4650 
4651  maxfds = sysconf (_SC_OPEN_MAX);
4652 
4653  /* Pick something reasonable if for some reason sysconf says
4654  * unlimited.
4655  */
4656  if (maxfds < 0)
4657  maxfds = 1024;
4658 
4659  /* close all inherited fds */
4660  for (i = 3; i < maxfds; i++)
4661  close (i);
4662 }
4663 
4675 {
4676  /* TODO: get __libc_enable_secure exported from glibc.
4677  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4678  */
4679 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4680  {
4681  /* See glibc/include/unistd.h */
4682  extern int __libc_enable_secure;
4683  return __libc_enable_secure;
4684  }
4685 #elif defined(HAVE_ISSETUGID)
4686  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4687  return issetugid ();
4688 #else
4689  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4690  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4691 
4692  /* We call into this function from _dbus_threads_init_platform_specific()
4693  * to make sure these are initialized before we start threading. */
4694  static dbus_bool_t check_setuid_initialised;
4695  static dbus_bool_t is_setuid;
4696 
4697  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4698  {
4699 #ifdef HAVE_GETRESUID
4700  if (getresuid (&ruid, &euid, &suid) != 0 ||
4701  getresgid (&rgid, &egid, &sgid) != 0)
4702 #endif /* HAVE_GETRESUID */
4703  {
4704  suid = ruid = getuid ();
4705  sgid = rgid = getgid ();
4706  euid = geteuid ();
4707  egid = getegid ();
4708  }
4709 
4710  check_setuid_initialised = TRUE;
4711  is_setuid = (ruid != euid || ruid != suid ||
4712  rgid != egid || rgid != sgid);
4713 
4714  }
4715  return is_setuid;
4716 #endif
4717 }
4718 
4728  DBusString *address,
4729  DBusError *error)
4730 {
4731  union {
4732  struct sockaddr sa;
4733  struct sockaddr_storage storage;
4734  struct sockaddr_un un;
4735  struct sockaddr_in ipv4;
4736  struct sockaddr_in6 ipv6;
4737  } socket;
4738  char hostip[INET6_ADDRSTRLEN];
4739  socklen_t size = sizeof (socket);
4740  DBusString path_str;
4741 
4742  if (getsockname (fd.fd, &socket.sa, &size))
4743  goto err;
4744 
4745  switch (socket.sa.sa_family)
4746  {
4747  case AF_UNIX:
4748  if (socket.un.sun_path[0]=='\0')
4749  {
4750  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4751  if (_dbus_string_append (address, "unix:abstract=") &&
4752  _dbus_address_append_escaped (address, &path_str))
4753  return TRUE;
4754  }
4755  else
4756  {
4757  _dbus_string_init_const (&path_str, socket.un.sun_path);
4758  if (_dbus_string_append (address, "unix:path=") &&
4759  _dbus_address_append_escaped (address, &path_str))
4760  return TRUE;
4761  }
4762  break;
4763  case AF_INET:
4764  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4765  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4766  hostip, ntohs (socket.ipv4.sin_port)))
4767  return TRUE;
4768  break;
4769 #ifdef AF_INET6
4770  case AF_INET6:
4771  _dbus_string_init_const (&path_str, hostip);
4772  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4773  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4774  ntohs (socket.ipv6.sin6_port)) &&
4775  _dbus_address_append_escaped (address, &path_str))
4776  return TRUE;
4777  break;
4778 #endif
4779  default:
4780  dbus_set_error (error,
4781  _dbus_error_from_errno (EINVAL),
4782  "Failed to read address from socket: Unknown socket type.");
4783  return FALSE;
4784  }
4785  err:
4786  dbus_set_error (error,
4787  _dbus_error_from_errno (errno),
4788  "Failed to open socket: %s",
4789  _dbus_strerror (errno));
4790  return FALSE;
4791 }
4792 
4793 int
4794 _dbus_save_socket_errno (void)
4795 {
4796  return errno;
4797 }
4798 
4799 void
4800 _dbus_restore_socket_errno (int saved_errno)
4801 {
4802  errno = saved_errno;
4803 }
4804 
4805 static const char *syslog_tag = "dbus";
4806 #ifdef HAVE_SYSLOG_H
4807 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4808 #endif
4809 
4824 void
4825 _dbus_init_system_log (const char *tag,
4826  DBusLogFlags flags)
4827 {
4828  /* We never want to turn off logging completely */
4829  _dbus_assert (
4830  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4831 
4832  syslog_tag = tag;
4833 
4834 #ifdef HAVE_SYSLOG_H
4835  log_flags = flags;
4836 
4837  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4838  openlog (tag, LOG_PID, LOG_DAEMON);
4839 #endif
4840 }
4841 
4849 void
4850 _dbus_logv (DBusSystemLogSeverity severity,
4851  const char *msg,
4852  va_list args)
4853 {
4854  va_list tmp;
4855 #ifdef HAVE_SYSLOG_H
4856  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4857  {
4858  int flags;
4859  switch (severity)
4860  {
4861  case DBUS_SYSTEM_LOG_INFO:
4862  flags = LOG_DAEMON | LOG_INFO;
4863  break;
4864  case DBUS_SYSTEM_LOG_WARNING:
4865  flags = LOG_DAEMON | LOG_WARNING;
4866  break;
4867  case DBUS_SYSTEM_LOG_SECURITY:
4868  flags = LOG_AUTH | LOG_NOTICE;
4869  break;
4870  case DBUS_SYSTEM_LOG_ERROR:
4871  flags = LOG_DAEMON|LOG_CRIT;
4872  break;
4873  default:
4874  _dbus_assert_not_reached ("invalid log severity");
4875  }
4876 
4877  DBUS_VA_COPY (tmp, args);
4878  vsyslog (flags, msg, tmp);
4879  va_end (tmp);
4880  }
4881 
4882  /* If we don't have syslog.h, we always behave as though stderr was in
4883  * the flags */
4884  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4885 #endif
4886  {
4887  DBUS_VA_COPY (tmp, args);
4888  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4889  vfprintf (stderr, msg, tmp);
4890  fputc ('\n', stderr);
4891  va_end (tmp);
4892  }
4893 }
4894 
4895 /* tests in dbus-sysdeps-util.c */
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:935
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:437
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:306
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&#39;t contain...
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:394
const char * message
public error message field
Definition: dbus-errors.h:51
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:311
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.
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&#39;re running on from the dbus configuration.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
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:760
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:702
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
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 ...
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 ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:150
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:146
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
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.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
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.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:386
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_gid_t primary_gid
GID.
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...
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:405
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
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:490
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
short events
Events to poll for.
Definition: dbus-sysdeps.h:400
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&#39;s copied to the d...
Definition: dbus-string.c:1283
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:139
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_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:141
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
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:592
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
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:498
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:132
Socket interface.
Definition: dbus-sysdeps.h:175
dbus_gid_t * group_ids
Groups IDs, including above primary group.
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.
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:462
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...
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
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) ...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
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...
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:409
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
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.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
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:132
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_uid_t uid
UID.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
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_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
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.
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...
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Object representing an exception.
Definition: dbus-errors.h:48
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:104
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
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
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.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
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.
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
int _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. ...
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
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:1157
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:143
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:399
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
const char * name
public error name field
Definition: dbus-errors.h:50
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:888
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:148
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.
char * homedir
Home directory.
void _dbus_exit(int code)
Exit the process, returning the given value.
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...
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
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.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
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...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
#define _DBUS_INT32_MAX
Maximum value of type "int32".
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. ...
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
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
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
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.
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_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
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.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:890
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:136
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:602
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...
char * _dbus_strdup(const char *str)
Duplicates a string.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
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_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:187
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:134
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:401
int _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.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _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.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:411