D-Bus  1.12.8
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  if (m.msg_flags & MSG_CTRUNC)
439  {
440  /* Hmm, apparently the control data was truncated. The bad
441  thing is that we might have completely lost a couple of fds
442  without chance to recover them. Hence let's treat this as a
443  serious error. */
444 
445  errno = ENOSPC;
446  _dbus_string_set_length (buffer, start);
447  return -1;
448  }
449 
450  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
451  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
452  {
453  size_t i;
454  int *payload = (int *) CMSG_DATA (cm);
455  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
456  size_t payload_len_fds = payload_len_bytes / sizeof (int);
457  size_t fds_to_use;
458 
459  /* Every unsigned int fits in a size_t without truncation, so
460  * casting (size_t) *n_fds is OK */
461  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
462 
463  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
464  {
465  /* The fds in the payload will fit in our buffer */
466  fds_to_use = payload_len_fds;
467  }
468  else
469  {
470  /* Too many fds in the payload. This shouldn't happen
471  * any more because we're setting m.msg_controllen to
472  * the exact number we can accept, but be safe and
473  * truncate. */
474  fds_to_use = (size_t) *n_fds;
475 
476  /* Close the excess fds to avoid DoS: if they stayed open,
477  * someone could send us an extra fd per message
478  * and we'd eventually run out. */
479  for (i = fds_to_use; i < payload_len_fds; i++)
480  {
481  close (payload[i]);
482  }
483  }
484 
485  memcpy (fds, payload, fds_to_use * sizeof (int));
486  found = TRUE;
487  /* This narrowing cast from size_t to unsigned int cannot
488  * overflow because we have chosen fds_to_use
489  * to be <= *n_fds */
490  *n_fds = (unsigned int) fds_to_use;
491 
492  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
493  worked, hence we need to go through this list and set
494  CLOEXEC everywhere in any case */
495  for (i = 0; i < fds_to_use; i++)
497 
498  break;
499  }
500 
501  if (!found)
502  *n_fds = 0;
503 
504  /* put length back (doesn't actually realloc) */
505  _dbus_string_set_length (buffer, start + bytes_read);
506 
507 #if 0
508  if (bytes_read > 0)
509  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
510 #endif
511 
512  return bytes_read;
513  }
514 #endif
515 }
516 
517 int
518 _dbus_write_socket_with_unix_fds(DBusSocket fd,
519  const DBusString *buffer,
520  int start,
521  int len,
522  const int *fds,
523  int n_fds) {
524 
525 #ifndef HAVE_UNIX_FD_PASSING
526 
527  if (n_fds > 0) {
528  errno = ENOTSUP;
529  return -1;
530  }
531 
532  return _dbus_write_socket(fd, buffer, start, len);
533 #else
534  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
535 #endif
536 }
537 
538 int
539 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
540  const DBusString *buffer1,
541  int start1,
542  int len1,
543  const DBusString *buffer2,
544  int start2,
545  int len2,
546  const int *fds,
547  int n_fds) {
548 
549 #ifndef HAVE_UNIX_FD_PASSING
550 
551  if (n_fds > 0) {
552  errno = ENOTSUP;
553  return -1;
554  }
555 
556  return _dbus_write_socket_two(fd,
557  buffer1, start1, len1,
558  buffer2, start2, len2);
559 #else
560 
561  struct msghdr m;
562  struct cmsghdr *cm;
563  struct iovec iov[2];
564  int bytes_written;
565 
566  _dbus_assert (len1 >= 0);
567  _dbus_assert (len2 >= 0);
568  _dbus_assert (n_fds >= 0);
569 
570  _DBUS_ZERO(iov);
571  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
572  iov[0].iov_len = len1;
573 
574  if (buffer2)
575  {
576  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
577  iov[1].iov_len = len2;
578  }
579 
580  _DBUS_ZERO(m);
581  m.msg_iov = iov;
582  m.msg_iovlen = buffer2 ? 2 : 1;
583 
584  if (n_fds > 0)
585  {
586  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
587  m.msg_control = alloca(m.msg_controllen);
588  memset(m.msg_control, 0, m.msg_controllen);
589 
590  cm = CMSG_FIRSTHDR(&m);
591  cm->cmsg_level = SOL_SOCKET;
592  cm->cmsg_type = SCM_RIGHTS;
593  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
594  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
595  }
596 
597  again:
598 
599  bytes_written = sendmsg (fd.fd, &m, 0
600 #if HAVE_DECL_MSG_NOSIGNAL
601  |MSG_NOSIGNAL
602 #endif
603  );
604 
605  if (bytes_written < 0 && errno == EINTR)
606  goto again;
607 
608 #if 0
609  if (bytes_written > 0)
610  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
611 #endif
612 
613  return bytes_written;
614 #endif
615 }
616 
630 int
632  const DBusString *buffer1,
633  int start1,
634  int len1,
635  const DBusString *buffer2,
636  int start2,
637  int len2)
638 {
639 #if HAVE_DECL_MSG_NOSIGNAL
640  struct iovec vectors[2];
641  const char *data1;
642  const char *data2;
643  int bytes_written;
644  struct msghdr m;
645 
646  _dbus_assert (buffer1 != NULL);
647  _dbus_assert (start1 >= 0);
648  _dbus_assert (start2 >= 0);
649  _dbus_assert (len1 >= 0);
650  _dbus_assert (len2 >= 0);
651 
652  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
653 
654  if (buffer2 != NULL)
655  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
656  else
657  {
658  data2 = NULL;
659  start2 = 0;
660  len2 = 0;
661  }
662 
663  vectors[0].iov_base = (char*) data1;
664  vectors[0].iov_len = len1;
665  vectors[1].iov_base = (char*) data2;
666  vectors[1].iov_len = len2;
667 
668  _DBUS_ZERO(m);
669  m.msg_iov = vectors;
670  m.msg_iovlen = data2 ? 2 : 1;
671 
672  again:
673 
674  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
675 
676  if (bytes_written < 0 && errno == EINTR)
677  goto again;
678 
679  return bytes_written;
680 
681 #else
682  return _dbus_write_two (fd.fd, buffer1, start1, len1,
683  buffer2, start2, len2);
684 #endif
685 }
686 
703 int
704 _dbus_read (int fd,
705  DBusString *buffer,
706  int count)
707 {
708  int bytes_read;
709  int start;
710  char *data;
711 
712  _dbus_assert (count >= 0);
713 
714  start = _dbus_string_get_length (buffer);
715 
716  if (!_dbus_string_lengthen (buffer, count))
717  {
718  errno = ENOMEM;
719  return -1;
720  }
721 
722  data = _dbus_string_get_data_len (buffer, start, count);
723 
724  again:
725 
726  bytes_read = read (fd, data, count);
727 
728  if (bytes_read < 0)
729  {
730  if (errno == EINTR)
731  goto again;
732  else
733  {
734  /* put length back (note that this doesn't actually realloc anything) */
735  _dbus_string_set_length (buffer, start);
736  return -1;
737  }
738  }
739  else
740  {
741  /* put length back (doesn't actually realloc) */
742  _dbus_string_set_length (buffer, start + bytes_read);
743 
744 #if 0
745  if (bytes_read > 0)
746  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
747 #endif
748 
749  return bytes_read;
750  }
751 }
752 
763 int
764 _dbus_write (int fd,
765  const DBusString *buffer,
766  int start,
767  int len)
768 {
769  const char *data;
770  int bytes_written;
771 
772  data = _dbus_string_get_const_data_len (buffer, start, len);
773 
774  again:
775 
776  bytes_written = write (fd, data, len);
777 
778  if (bytes_written < 0 && errno == EINTR)
779  goto again;
780 
781 #if 0
782  if (bytes_written > 0)
783  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
784 #endif
785 
786  return bytes_written;
787 }
788 
809 int
811  const DBusString *buffer1,
812  int start1,
813  int len1,
814  const DBusString *buffer2,
815  int start2,
816  int len2)
817 {
818  _dbus_assert (buffer1 != NULL);
819  _dbus_assert (start1 >= 0);
820  _dbus_assert (start2 >= 0);
821  _dbus_assert (len1 >= 0);
822  _dbus_assert (len2 >= 0);
823 
824 #ifdef HAVE_WRITEV
825  {
826  struct iovec vectors[2];
827  const char *data1;
828  const char *data2;
829  int bytes_written;
830 
831  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
832 
833  if (buffer2 != NULL)
834  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
835  else
836  {
837  data2 = NULL;
838  start2 = 0;
839  len2 = 0;
840  }
841 
842  vectors[0].iov_base = (char*) data1;
843  vectors[0].iov_len = len1;
844  vectors[1].iov_base = (char*) data2;
845  vectors[1].iov_len = len2;
846 
847  again:
848 
849  bytes_written = writev (fd,
850  vectors,
851  data2 ? 2 : 1);
852 
853  if (bytes_written < 0 && errno == EINTR)
854  goto again;
855 
856  return bytes_written;
857  }
858 #else /* HAVE_WRITEV */
859  {
860  int ret1, ret2;
861 
862  ret1 = _dbus_write (fd, buffer1, start1, len1);
863  if (ret1 == len1 && buffer2 != NULL)
864  {
865  ret2 = _dbus_write (fd, buffer2, start2, len2);
866  if (ret2 < 0)
867  ret2 = 0; /* we can't report an error as the first write was OK */
868 
869  return ret1 + ret2;
870  }
871  else
872  return ret1;
873  }
874 #endif /* !HAVE_WRITEV */
875 }
876 
877 #define _DBUS_MAX_SUN_PATH_LENGTH 99
878 
908 int
909 _dbus_connect_unix_socket (const char *path,
910  dbus_bool_t abstract,
911  DBusError *error)
912 {
913  int fd;
914  size_t path_len;
915  struct sockaddr_un addr;
916 
917  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
918 
919  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
920  path, abstract);
921 
922 
923  if (!_dbus_open_unix_socket (&fd, error))
924  {
925  _DBUS_ASSERT_ERROR_IS_SET(error);
926  return -1;
927  }
928  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
929 
930  _DBUS_ZERO (addr);
931  addr.sun_family = AF_UNIX;
932  path_len = strlen (path);
933 
934  if (abstract)
935  {
936 #ifdef __linux__
937  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
938  path_len++; /* Account for the extra nul byte added to the start of sun_path */
939 
940  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
941  {
943  "Abstract socket name too long\n");
944  _dbus_close (fd, NULL);
945  return -1;
946  }
947 
948  strncpy (&addr.sun_path[1], path, path_len);
949  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
950 #else /* !__linux__ */
952  "Operating system does not support abstract socket namespace\n");
953  _dbus_close (fd, NULL);
954  return -1;
955 #endif /* !__linux__ */
956  }
957  else
958  {
959  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
960  {
962  "Socket name too long\n");
963  _dbus_close (fd, NULL);
964  return -1;
965  }
966 
967  strncpy (addr.sun_path, path, path_len);
968  }
969 
970  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
971  {
972  dbus_set_error (error,
973  _dbus_error_from_errno (errno),
974  "Failed to connect to socket %s: %s",
975  path, _dbus_strerror (errno));
976 
977  _dbus_close (fd, NULL);
978  return -1;
979  }
980 
981  if (!_dbus_set_fd_nonblocking (fd, error))
982  {
983  _DBUS_ASSERT_ERROR_IS_SET (error);
984 
985  _dbus_close (fd, NULL);
986  return -1;
987  }
988 
989  return fd;
990 }
991 
1004 int
1005 _dbus_connect_exec (const char *path,
1006  char *const argv[],
1007  DBusError *error)
1008 {
1009  int fds[2];
1010  pid_t pid;
1011  int retval;
1012  dbus_bool_t cloexec_done = 0;
1013 
1014  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1015 
1016  _dbus_verbose ("connecting to process %s\n", path);
1017 
1018 #ifdef SOCK_CLOEXEC
1019  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1020  cloexec_done = (retval >= 0);
1021 
1022  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1023 #endif
1024  {
1025  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1026  }
1027 
1028  if (retval < 0)
1029  {
1030  dbus_set_error (error,
1031  _dbus_error_from_errno (errno),
1032  "Failed to create socket pair: %s",
1033  _dbus_strerror (errno));
1034  return -1;
1035  }
1036 
1037  if (!cloexec_done)
1038  {
1039  _dbus_fd_set_close_on_exec (fds[0]);
1040  _dbus_fd_set_close_on_exec (fds[1]);
1041  }
1042 
1043  pid = fork ();
1044  if (pid < 0)
1045  {
1046  dbus_set_error (error,
1047  _dbus_error_from_errno (errno),
1048  "Failed to fork() to call %s: %s",
1049  path, _dbus_strerror (errno));
1050  close (fds[0]);
1051  close (fds[1]);
1052  return -1;
1053  }
1054 
1055  if (pid == 0)
1056  {
1057  /* child */
1058  close (fds[0]);
1059 
1060  dup2 (fds[1], STDIN_FILENO);
1061  dup2 (fds[1], STDOUT_FILENO);
1062 
1063  if (fds[1] != STDIN_FILENO &&
1064  fds[1] != STDOUT_FILENO)
1065  close (fds[1]);
1066 
1067  /* Inherit STDERR and the controlling terminal from the
1068  parent */
1069 
1070  _dbus_close_all ();
1071 
1072  execvp (path, (char * const *) argv);
1073 
1074  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1075 
1076  _exit(1);
1077  }
1078 
1079  /* parent */
1080  close (fds[1]);
1081 
1082  if (!_dbus_set_fd_nonblocking (fds[0], error))
1083  {
1084  _DBUS_ASSERT_ERROR_IS_SET (error);
1085 
1086  close (fds[0]);
1087  return -1;
1088  }
1089 
1090  return fds[0];
1091 }
1092 
1110 int
1111 _dbus_listen_unix_socket (const char *path,
1112  dbus_bool_t abstract,
1113  DBusError *error)
1114 {
1115  int listen_fd;
1116  struct sockaddr_un addr;
1117  size_t path_len;
1118 
1119  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1120 
1121  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1122  path, abstract);
1123 
1124  if (!_dbus_open_unix_socket (&listen_fd, error))
1125  {
1126  _DBUS_ASSERT_ERROR_IS_SET(error);
1127  return -1;
1128  }
1129  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1130 
1131  _DBUS_ZERO (addr);
1132  addr.sun_family = AF_UNIX;
1133  path_len = strlen (path);
1134 
1135  if (abstract)
1136  {
1137 #ifdef __linux__
1138  /* remember that abstract names aren't nul-terminated so we rely
1139  * on sun_path being filled in with zeroes above.
1140  */
1141  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1142  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1143 
1144  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1145  {
1147  "Abstract socket name too long\n");
1148  _dbus_close (listen_fd, NULL);
1149  return -1;
1150  }
1151 
1152  strncpy (&addr.sun_path[1], path, path_len);
1153  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1154 #else /* !__linux__ */
1156  "Operating system does not support abstract socket namespace\n");
1157  _dbus_close (listen_fd, NULL);
1158  return -1;
1159 #endif /* !__linux__ */
1160  }
1161  else
1162  {
1163  /* Discussed security implications of this with Nalin,
1164  * and we couldn't think of where it would kick our ass, but
1165  * it still seems a bit sucky. It also has non-security suckage;
1166  * really we'd prefer to exit if the socket is already in use.
1167  * But there doesn't seem to be a good way to do this.
1168  *
1169  * Just to be extra careful, I threw in the stat() - clearly
1170  * the stat() can't *fix* any security issue, but it at least
1171  * avoids inadvertent/accidental data loss.
1172  */
1173  {
1174  struct stat sb;
1175 
1176  if (stat (path, &sb) == 0 &&
1177  S_ISSOCK (sb.st_mode))
1178  unlink (path);
1179  }
1180 
1181  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1182  {
1184  "Socket name too long\n");
1185  _dbus_close (listen_fd, NULL);
1186  return -1;
1187  }
1188 
1189  strncpy (addr.sun_path, path, path_len);
1190  }
1191 
1192  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1193  {
1194  dbus_set_error (error, _dbus_error_from_errno (errno),
1195  "Failed to bind socket \"%s\": %s",
1196  path, _dbus_strerror (errno));
1197  _dbus_close (listen_fd, NULL);
1198  return -1;
1199  }
1200 
1201  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1202  {
1203  dbus_set_error (error, _dbus_error_from_errno (errno),
1204  "Failed to listen on socket \"%s\": %s",
1205  path, _dbus_strerror (errno));
1206  _dbus_close (listen_fd, NULL);
1207  return -1;
1208  }
1209 
1210  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1211  {
1212  _DBUS_ASSERT_ERROR_IS_SET (error);
1213  _dbus_close (listen_fd, NULL);
1214  return -1;
1215  }
1216 
1217  /* Try opening up the permissions, but if we can't, just go ahead
1218  * and continue, maybe it will be good enough.
1219  */
1220  if (!abstract && chmod (path, 0777) < 0)
1221  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1222 
1223  return listen_fd;
1224 }
1225 
1236 int
1238  DBusError *error)
1239 {
1240 #ifdef HAVE_SYSTEMD
1241  int r, n;
1242  int fd;
1243  DBusSocket *new_fds;
1244 
1245  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1246 
1247  n = sd_listen_fds (TRUE);
1248  if (n < 0)
1249  {
1251  "Failed to acquire systemd socket: %s",
1252  _dbus_strerror (-n));
1253  return -1;
1254  }
1255 
1256  if (n <= 0)
1257  {
1259  "No socket received.");
1260  return -1;
1261  }
1262 
1263  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1264  {
1265  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1266  if (r < 0)
1267  {
1269  "Failed to verify systemd socket type: %s",
1270  _dbus_strerror (-r));
1271  return -1;
1272  }
1273 
1274  if (!r)
1275  {
1277  "Passed socket has wrong type.");
1278  return -1;
1279  }
1280  }
1281 
1282  /* OK, the file descriptors are all good, so let's take posession of
1283  them then. */
1284 
1285  new_fds = dbus_new (DBusSocket, n);
1286  if (!new_fds)
1287  {
1289  "Failed to allocate file handle array.");
1290  goto fail;
1291  }
1292 
1293  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1294  {
1295  if (!_dbus_set_fd_nonblocking (fd, error))
1296  {
1297  _DBUS_ASSERT_ERROR_IS_SET (error);
1298  goto fail;
1299  }
1300 
1301  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1302  }
1303 
1304  *fds = new_fds;
1305  return n;
1306 
1307  fail:
1308 
1309  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1310  {
1311  _dbus_close (fd, NULL);
1312  }
1313 
1314  dbus_free (new_fds);
1315  return -1;
1316 #else
1318  "dbus was compiled without systemd support");
1319  return -1;
1320 #endif
1321 }
1322 
1323 /* Convert an error code from getaddrinfo() or getnameinfo() into
1324  * a D-Bus error name. */
1325 static const char *
1326 _dbus_error_from_gai (int gai_res,
1327  int saved_errno)
1328 {
1329  switch (gai_res)
1330  {
1331 #ifdef EAI_FAMILY
1332  case EAI_FAMILY:
1333  /* ai_family not supported (at all) */
1334  return DBUS_ERROR_NOT_SUPPORTED;
1335 #endif
1336 
1337 #ifdef EAI_SOCKTYPE
1338  case EAI_SOCKTYPE:
1339  /* ai_socktype not supported (at all) */
1340  return DBUS_ERROR_NOT_SUPPORTED;
1341 #endif
1342 
1343 #ifdef EAI_MEMORY
1344  case EAI_MEMORY:
1345  /* Out of memory */
1346  return DBUS_ERROR_NO_MEMORY;
1347 #endif
1348 
1349 #ifdef EAI_SYSTEM
1350  case EAI_SYSTEM:
1351  /* Unspecified system error, details in errno */
1352  return _dbus_error_from_errno (saved_errno);
1353 #endif
1354 
1355  case 0:
1356  /* It succeeded, but we didn't get any addresses? */
1357  return DBUS_ERROR_FAILED;
1358 
1359  /* EAI_AGAIN: Transient failure */
1360  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1361  /* EAI_FAIL: Non-recoverable failure */
1362  /* EAI_NODATA: host exists but has no addresses */
1363  /* EAI_NONAME: host does not exist */
1364  /* EAI_OVERFLOW: argument buffer overflow */
1365  /* EAI_SERVICE: service not available for specified socket
1366  * type (we should never see this because we use numeric
1367  * ports) */
1368  default:
1369  return DBUS_ERROR_FAILED;
1370  }
1371 }
1372 
1386 DBusSocket
1387 _dbus_connect_tcp_socket (const char *host,
1388  const char *port,
1389  const char *family,
1390  DBusError *error)
1391 {
1392  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1393 }
1394 
1395 DBusSocket
1396 _dbus_connect_tcp_socket_with_nonce (const char *host,
1397  const char *port,
1398  const char *family,
1399  const char *noncefile,
1400  DBusError *error)
1401 {
1402  int saved_errno = 0;
1403  DBusSocket fd = DBUS_SOCKET_INIT;
1404  int res;
1405  struct addrinfo hints;
1406  struct addrinfo *ai, *tmp;
1407 
1408  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1409 
1410  _DBUS_ZERO (hints);
1411 
1412  if (!family)
1413  hints.ai_family = AF_UNSPEC;
1414  else if (!strcmp(family, "ipv4"))
1415  hints.ai_family = AF_INET;
1416  else if (!strcmp(family, "ipv6"))
1417  hints.ai_family = AF_INET6;
1418  else
1419  {
1420  dbus_set_error (error,
1422  "Unknown address family %s", family);
1423  return _dbus_socket_get_invalid ();
1424  }
1425  hints.ai_protocol = IPPROTO_TCP;
1426  hints.ai_socktype = SOCK_STREAM;
1427  hints.ai_flags = AI_ADDRCONFIG;
1428 
1429  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1430  {
1431  dbus_set_error (error,
1432  _dbus_error_from_gai (res, errno),
1433  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1434  host, port, gai_strerror(res), res);
1435  return _dbus_socket_get_invalid ();
1436  }
1437 
1438  tmp = ai;
1439  while (tmp)
1440  {
1441  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1442  {
1443  freeaddrinfo(ai);
1444  _DBUS_ASSERT_ERROR_IS_SET(error);
1445  return _dbus_socket_get_invalid ();
1446  }
1447  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1448 
1449  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1450  {
1451  saved_errno = errno;
1452  _dbus_close (fd.fd, NULL);
1453  fd.fd = -1;
1454  tmp = tmp->ai_next;
1455  continue;
1456  }
1457 
1458  break;
1459  }
1460  freeaddrinfo(ai);
1461 
1462  if (fd.fd == -1)
1463  {
1464  dbus_set_error (error,
1465  _dbus_error_from_errno (saved_errno),
1466  "Failed to connect to socket \"%s:%s\" %s",
1467  host, port, _dbus_strerror(saved_errno));
1468  return _dbus_socket_get_invalid ();
1469  }
1470 
1471  if (noncefile != NULL)
1472  {
1473  DBusString noncefileStr;
1474  dbus_bool_t ret;
1475  _dbus_string_init_const (&noncefileStr, noncefile);
1476  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1477  _dbus_string_free (&noncefileStr);
1478 
1479  if (!ret)
1480  {
1481  _dbus_close (fd.fd, NULL);
1482  return _dbus_socket_get_invalid ();
1483  }
1484  }
1485 
1486  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1487  {
1488  _dbus_close (fd.fd, NULL);
1489  return _dbus_socket_get_invalid ();
1490  }
1491 
1492  return fd;
1493 }
1494 
1511 int
1512 _dbus_listen_tcp_socket (const char *host,
1513  const char *port,
1514  const char *family,
1515  DBusString *retport,
1516  DBusSocket **fds_p,
1517  DBusError *error)
1518 {
1519  int saved_errno;
1520  int nlisten_fd = 0, res, i;
1521  DBusSocket *listen_fd = NULL;
1522  struct addrinfo hints;
1523  struct addrinfo *ai, *tmp;
1524  unsigned int reuseaddr;
1525 
1526  *fds_p = NULL;
1527  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1528 
1529  _DBUS_ZERO (hints);
1530 
1531  if (!family)
1532  hints.ai_family = AF_UNSPEC;
1533  else if (!strcmp(family, "ipv4"))
1534  hints.ai_family = AF_INET;
1535  else if (!strcmp(family, "ipv6"))
1536  hints.ai_family = AF_INET6;
1537  else
1538  {
1539  dbus_set_error (error,
1541  "Unknown address family %s", family);
1542  return -1;
1543  }
1544 
1545  hints.ai_protocol = IPPROTO_TCP;
1546  hints.ai_socktype = SOCK_STREAM;
1547  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1548 
1549  redo_lookup_with_port:
1550  ai = NULL;
1551  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1552  {
1553  dbus_set_error (error,
1554  _dbus_error_from_gai (res, errno),
1555  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1556  host ? host : "*", port, gai_strerror(res), res);
1557  goto failed;
1558  }
1559 
1560  tmp = ai;
1561  while (tmp)
1562  {
1563  int fd = -1, tcp_nodelay_on;
1564  DBusSocket *newlisten_fd;
1565 
1566  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1567  {
1568  _DBUS_ASSERT_ERROR_IS_SET(error);
1569  goto failed;
1570  }
1571  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1572 
1573  reuseaddr = 1;
1574  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1575  {
1576  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1577  host ? host : "*", port, _dbus_strerror (errno));
1578  }
1579 
1580  /* Nagle's algorithm imposes a huge delay on the initial messages
1581  going over TCP. */
1582  tcp_nodelay_on = 1;
1583  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1584  {
1585  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1586  host ? host : "*", port, _dbus_strerror (errno));
1587  }
1588 
1589  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1590  {
1591  saved_errno = errno;
1592  _dbus_close(fd, NULL);
1593  if (saved_errno == EADDRINUSE)
1594  {
1595  /* Depending on kernel policy, binding to an IPv6 address
1596  might implicitly bind to a corresponding IPv4
1597  address or vice versa, resulting in EADDRINUSE for the
1598  other one (e.g. bindv6only=0 on Linux).
1599 
1600  Also, after we "goto redo_lookup_with_port" after binding
1601  a port on one of the possible addresses, we will
1602  try to bind that same port on every address, including the
1603  same address again for a second time; that one will
1604  also fail with EADDRINUSE.
1605 
1606  For both those reasons, ignore EADDRINUSE here */
1607  tmp = tmp->ai_next;
1608  continue;
1609  }
1610  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1611  "Failed to bind socket \"%s:%s\": %s",
1612  host ? host : "*", port, _dbus_strerror (saved_errno));
1613  goto failed;
1614  }
1615 
1616  if (listen (fd, 30 /* backlog */) < 0)
1617  {
1618  saved_errno = errno;
1619  _dbus_close (fd, NULL);
1620  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1621  "Failed to listen on socket \"%s:%s\": %s",
1622  host ? host : "*", port, _dbus_strerror (saved_errno));
1623  goto failed;
1624  }
1625 
1626  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1627  if (!newlisten_fd)
1628  {
1629  _dbus_close (fd, NULL);
1631  "Failed to allocate file handle array");
1632  goto failed;
1633  }
1634  listen_fd = newlisten_fd;
1635  listen_fd[nlisten_fd].fd = fd;
1636  nlisten_fd++;
1637 
1638  if (!_dbus_string_get_length(retport))
1639  {
1640  /* If the user didn't specify a port, or used 0, then
1641  the kernel chooses a port. After the first address
1642  is bound to, we need to force all remaining addresses
1643  to use the same port */
1644  if (!port || !strcmp(port, "0"))
1645  {
1646  int result;
1647  struct sockaddr_storage addr;
1648  socklen_t addrlen;
1649  char portbuf[50];
1650 
1651  addrlen = sizeof(addr);
1652  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1653 
1654  if (result == -1)
1655  {
1656  saved_errno = errno;
1657  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1658  "Failed to retrieve socket name for \"%s:%s\": %s",
1659  host ? host : "*", port, _dbus_strerror (saved_errno));
1660  goto failed;
1661  }
1662 
1663  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1664  portbuf, sizeof(portbuf),
1665  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1666  {
1667  saved_errno = errno;
1668  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1669  "Failed to resolve port \"%s:%s\": %s (%d)",
1670  host ? host : "*", port, gai_strerror(res), res);
1671  goto failed;
1672  }
1673 
1674  if (!_dbus_string_append(retport, portbuf))
1675  {
1677  goto failed;
1678  }
1679 
1680  /* Release current address list & redo lookup */
1681  port = _dbus_string_get_const_data(retport);
1682  freeaddrinfo(ai);
1683  goto redo_lookup_with_port;
1684  }
1685  else
1686  {
1687  if (!_dbus_string_append(retport, port))
1688  {
1690  goto failed;
1691  }
1692  }
1693  }
1694 
1695  tmp = tmp->ai_next;
1696  }
1697  freeaddrinfo(ai);
1698  ai = NULL;
1699 
1700  if (!nlisten_fd)
1701  {
1702  errno = EADDRINUSE;
1703  dbus_set_error (error, _dbus_error_from_errno (errno),
1704  "Failed to bind socket \"%s:%s\": %s",
1705  host ? host : "*", port, _dbus_strerror (errno));
1706  goto failed;
1707  }
1708 
1709  for (i = 0 ; i < nlisten_fd ; i++)
1710  {
1711  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1712  {
1713  goto failed;
1714  }
1715  }
1716 
1717  *fds_p = listen_fd;
1718 
1719  return nlisten_fd;
1720 
1721  failed:
1722  if (ai)
1723  freeaddrinfo(ai);
1724  for (i = 0 ; i < nlisten_fd ; i++)
1725  _dbus_close(listen_fd[i].fd, NULL);
1726  dbus_free(listen_fd);
1727  return -1;
1728 }
1729 
1730 static dbus_bool_t
1731 write_credentials_byte (int server_fd,
1732  DBusError *error)
1733 {
1734  int bytes_written;
1735  char buf[1] = { '\0' };
1736 #if defined(HAVE_CMSGCRED)
1737  union {
1738  struct cmsghdr hdr;
1739  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1740  } cmsg;
1741  struct iovec iov;
1742  struct msghdr msg;
1743  iov.iov_base = buf;
1744  iov.iov_len = 1;
1745 
1746  _DBUS_ZERO(msg);
1747  msg.msg_iov = &iov;
1748  msg.msg_iovlen = 1;
1749 
1750  msg.msg_control = (caddr_t) &cmsg;
1751  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1752  _DBUS_ZERO(cmsg);
1753  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1754  cmsg.hdr.cmsg_level = SOL_SOCKET;
1755  cmsg.hdr.cmsg_type = SCM_CREDS;
1756 #endif
1757 
1758  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1759 
1760  again:
1761 
1762 #if defined(HAVE_CMSGCRED)
1763  bytes_written = sendmsg (server_fd, &msg, 0
1764 #if HAVE_DECL_MSG_NOSIGNAL
1765  |MSG_NOSIGNAL
1766 #endif
1767  );
1768 
1769  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1770  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1771  * only allows that on AF_UNIX. Try just doing a send() instead. */
1772  if (bytes_written < 0 && errno == EINVAL)
1773 #endif
1774  {
1775  bytes_written = send (server_fd, buf, 1, 0
1776 #if HAVE_DECL_MSG_NOSIGNAL
1777  |MSG_NOSIGNAL
1778 #endif
1779  );
1780  }
1781 
1782  if (bytes_written < 0 && errno == EINTR)
1783  goto again;
1784 
1785  if (bytes_written < 0)
1786  {
1787  dbus_set_error (error, _dbus_error_from_errno (errno),
1788  "Failed to write credentials byte: %s",
1789  _dbus_strerror (errno));
1790  return FALSE;
1791  }
1792  else if (bytes_written == 0)
1793  {
1795  "wrote zero bytes writing credentials byte");
1796  return FALSE;
1797  }
1798  else
1799  {
1800  _dbus_assert (bytes_written == 1);
1801  _dbus_verbose ("wrote credentials byte\n");
1802  return TRUE;
1803  }
1804 }
1805 
1806 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1807 static dbus_bool_t
1808 add_linux_security_label_to_credentials (int client_fd,
1809  DBusCredentials *credentials)
1810 {
1811 #if defined(__linux__) && defined(SO_PEERSEC)
1812  DBusString buf;
1813  socklen_t len = 1024;
1814  dbus_bool_t oom = FALSE;
1815 
1816  if (!_dbus_string_init_preallocated (&buf, len) ||
1817  !_dbus_string_set_length (&buf, len))
1818  return FALSE;
1819 
1820  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1821  _dbus_string_get_data (&buf), &len) < 0)
1822  {
1823  int e = errno;
1824 
1825  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1826  _dbus_strerror (e), (unsigned long) len);
1827 
1828  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1829  {
1830  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1831  _dbus_strerror (e));
1832  goto out;
1833  }
1834 
1835  /* If not enough space, len is updated to be enough.
1836  * Try again with a large enough buffer. */
1837  if (!_dbus_string_set_length (&buf, len))
1838  {
1839  oom = TRUE;
1840  goto out;
1841  }
1842 
1843  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1844  }
1845 
1846  if (len <= 0)
1847  {
1848  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1849  (unsigned long) len);
1850  goto out;
1851  }
1852 
1853  if (len > _dbus_string_get_length_uint (&buf))
1854  {
1855  _dbus_verbose ("%lu > %u", (unsigned long) len,
1856  _dbus_string_get_length_uint (&buf));
1857  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1858  }
1859 
1860  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1861  {
1862  /* the kernel included the trailing \0 in its count,
1863  * but DBusString always has an extra \0 after the data anyway */
1864  _dbus_verbose ("subtracting trailing \\0\n");
1865  len--;
1866  }
1867 
1868  if (!_dbus_string_set_length (&buf, len))
1869  {
1870  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1871  oom = TRUE;
1872  goto out;
1873  }
1874 
1875  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1876  {
1877  /* LSM people on the linux-security-module@ mailing list say this
1878  * should never happen: the label should be a bytestring with
1879  * an optional trailing \0 */
1880  _dbus_verbose ("security label from kernel had an embedded \\0, "
1881  "ignoring it\n");
1882  goto out;
1883  }
1884 
1885  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1886  (unsigned long) len,
1887  _dbus_string_get_const_data (&buf));
1888 
1890  _dbus_string_get_const_data (&buf)))
1891  {
1892  oom = TRUE;
1893  goto out;
1894  }
1895 
1896 out:
1897  _dbus_string_free (&buf);
1898  return !oom;
1899 #else
1900  /* no error */
1901  return TRUE;
1902 #endif
1903 }
1904 
1947  DBusCredentials *credentials,
1948  DBusError *error)
1949 {
1950  struct msghdr msg;
1951  struct iovec iov;
1952  char buf;
1953  dbus_uid_t uid_read;
1954  dbus_pid_t pid_read;
1955  int bytes_read;
1956 
1957 #ifdef HAVE_CMSGCRED
1958  union {
1959  struct cmsghdr hdr;
1960  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1961  } cmsg;
1962 #endif
1963 
1964  /* The POSIX spec certainly doesn't promise this, but
1965  * we need these assertions to fail as soon as we're wrong about
1966  * it so we can do the porting fixups
1967  */
1968  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1969  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1970  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1971 
1972  uid_read = DBUS_UID_UNSET;
1973  pid_read = DBUS_PID_UNSET;
1974 
1975  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1976 
1977  _dbus_credentials_clear (credentials);
1978 
1979  iov.iov_base = &buf;
1980  iov.iov_len = 1;
1981 
1982  _DBUS_ZERO(msg);
1983  msg.msg_iov = &iov;
1984  msg.msg_iovlen = 1;
1985 
1986 #if defined(HAVE_CMSGCRED)
1987  _DBUS_ZERO(cmsg);
1988  msg.msg_control = (caddr_t) &cmsg;
1989  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1990 #endif
1991 
1992  again:
1993  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1994 
1995  if (bytes_read < 0)
1996  {
1997  if (errno == EINTR)
1998  goto again;
1999 
2000  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2001  * normally only call read_credentials if the socket was ready
2002  * for reading
2003  */
2004 
2005  dbus_set_error (error, _dbus_error_from_errno (errno),
2006  "Failed to read credentials byte: %s",
2007  _dbus_strerror (errno));
2008  return FALSE;
2009  }
2010  else if (bytes_read == 0)
2011  {
2012  /* this should not happen unless we are using recvmsg wrong,
2013  * so is essentially here for paranoia
2014  */
2016  "Failed to read credentials byte (zero-length read)");
2017  return FALSE;
2018  }
2019  else if (buf != '\0')
2020  {
2022  "Credentials byte was not nul");
2023  return FALSE;
2024  }
2025 
2026  _dbus_verbose ("read credentials byte\n");
2027 
2028  {
2029 #ifdef SO_PEERCRED
2030  /* Supported by at least Linux and OpenBSD, with minor differences.
2031  *
2032  * This mechanism passes the process ID through and does not require
2033  * the peer's cooperation, so we prefer it over all others. Notably,
2034  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2035  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2036  * because this is much less fragile.
2037  */
2038 #ifdef __OpenBSD__
2039  struct sockpeercred cr;
2040 #else
2041  struct ucred cr;
2042 #endif
2043  socklen_t cr_len = sizeof (cr);
2044 
2045  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2046  {
2047  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2048  _dbus_strerror (errno));
2049  }
2050  else if (cr_len != sizeof (cr))
2051  {
2052  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2053  cr_len, (int) sizeof (cr));
2054  }
2055  else
2056  {
2057  pid_read = cr.pid;
2058  uid_read = cr.uid;
2059  }
2060 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2061  /* Another variant of the above - used on NetBSD
2062  */
2063  struct unpcbid cr;
2064  socklen_t cr_len = sizeof (cr);
2065 
2066  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2067  {
2068  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2069  _dbus_strerror (errno));
2070  }
2071  else if (cr_len != sizeof (cr))
2072  {
2073  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2074  cr_len, (int) sizeof (cr));
2075  }
2076  else
2077  {
2078  pid_read = cr.unp_pid;
2079  uid_read = cr.unp_euid;
2080  }
2081 #elif defined(HAVE_CMSGCRED)
2082  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2083  * presence of that struct implies SCM_CREDS. Supported by at least
2084  * FreeBSD and DragonflyBSD.
2085  *
2086  * This mechanism requires the peer to help us (it has to send us a
2087  * SCM_CREDS message) but it does pass the process ID through,
2088  * which makes it better than getpeereid().
2089  */
2090  struct cmsgcred *cred;
2091  struct cmsghdr *cmsgp;
2092 
2093  for (cmsgp = CMSG_FIRSTHDR (&msg);
2094  cmsgp != NULL;
2095  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2096  {
2097  if (cmsgp->cmsg_type == SCM_CREDS &&
2098  cmsgp->cmsg_level == SOL_SOCKET &&
2099  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2100  {
2101  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2102  pid_read = cred->cmcred_pid;
2103  uid_read = cred->cmcred_euid;
2104  break;
2105  }
2106  }
2107 
2108 #elif defined(HAVE_GETPEERUCRED)
2109  /* Supported in at least Solaris >= 10. It should probably be higher
2110  * up this list, because it carries the pid and we use this code path
2111  * for audit data. */
2112  ucred_t * ucred = NULL;
2113  if (getpeerucred (client_fd.fd, &ucred) == 0)
2114  {
2115 #ifdef HAVE_ADT
2116  adt_session_data_t *adth = NULL;
2117 #endif
2118  pid_read = ucred_getpid (ucred);
2119  uid_read = ucred_geteuid (ucred);
2120 #ifdef HAVE_ADT
2121  /* generate audit session data based on socket ucred */
2122  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2123  {
2124  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2125  }
2126  else
2127  {
2128  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2129  {
2130  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2131  }
2132  else
2133  {
2134  adt_export_data_t *data = NULL;
2135  size_t size = adt_export_session_data (adth, &data);
2136  if (size <= 0)
2137  {
2138  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2139  }
2140  else
2141  {
2142  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2143  free (data);
2144  }
2145  }
2146  (void) adt_end_session (adth);
2147  }
2148 #endif /* HAVE_ADT */
2149  }
2150  else
2151  {
2152  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2153  }
2154  if (ucred != NULL)
2155  ucred_free (ucred);
2156 
2157  /* ----------------------------------------------------------------
2158  * When adding new mechanisms, please add them above this point
2159  * if they support passing the process ID through, or below if not.
2160  * ---------------------------------------------------------------- */
2161 
2162 #elif defined(HAVE_GETPEEREID)
2163  /* getpeereid() originates from D.J. Bernstein and is fairly
2164  * widely-supported. According to a web search, it might be present in
2165  * any/all of:
2166  *
2167  * - AIX?
2168  * - Blackberry?
2169  * - Cygwin
2170  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2171  * - Mac OS X
2172  * - Minix 3.1.8+
2173  * - MirBSD?
2174  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2175  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2176  * - QNX?
2177  */
2178  uid_t euid;
2179  gid_t egid;
2180  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2181  {
2182  uid_read = euid;
2183  }
2184  else
2185  {
2186  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2187  }
2188 #else /* no supported mechanism */
2189 
2190 #warning Socket credentials not supported on this Unix OS
2191 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2192 
2193  /* Please add other operating systems known to support at least one of
2194  * the mechanisms above to this list, keeping alphabetical order.
2195  * Everything not in this list is best-effort.
2196  */
2197 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2198  defined(__linux__) || \
2199  defined(__OpenBSD__) || \
2200  defined(__NetBSD__)
2201 # error Credentials passing not working on this OS is a regression!
2202 #endif
2203 
2204  _dbus_verbose ("Socket credentials not supported on this OS\n");
2205 #endif
2206  }
2207 
2208  _dbus_verbose ("Credentials:"
2209  " pid "DBUS_PID_FORMAT
2210  " uid "DBUS_UID_FORMAT
2211  "\n",
2212  pid_read,
2213  uid_read);
2214 
2215  if (pid_read != DBUS_PID_UNSET)
2216  {
2217  if (!_dbus_credentials_add_pid (credentials, pid_read))
2218  {
2219  _DBUS_SET_OOM (error);
2220  return FALSE;
2221  }
2222  }
2223 
2224  if (uid_read != DBUS_UID_UNSET)
2225  {
2226  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2227  {
2228  _DBUS_SET_OOM (error);
2229  return FALSE;
2230  }
2231  }
2232 
2233  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2234  {
2235  _DBUS_SET_OOM (error);
2236  return FALSE;
2237  }
2238 
2239  return TRUE;
2240 }
2241 
2261  DBusError *error)
2262 {
2263  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2264 
2265  if (write_credentials_byte (server_fd.fd, error))
2266  return TRUE;
2267  else
2268  return FALSE;
2269 }
2270 
2280 DBusSocket
2282 {
2283  DBusSocket client_fd;
2284  struct sockaddr addr;
2285  socklen_t addrlen;
2286 #ifdef HAVE_ACCEPT4
2287  dbus_bool_t cloexec_done;
2288 #endif
2289 
2290  addrlen = sizeof (addr);
2291 
2292  retry:
2293 
2294 #ifdef HAVE_ACCEPT4
2295  /*
2296  * At compile-time, we assume that if accept4() is available in
2297  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2298  * not necessarily true that either is supported by the running kernel.
2299  */
2300  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2301  cloexec_done = client_fd.fd >= 0;
2302 
2303  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2304 #endif
2305  {
2306  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2307  }
2308 
2309  if (client_fd.fd < 0)
2310  {
2311  if (errno == EINTR)
2312  goto retry;
2313  }
2314 
2315  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2316 
2317 #ifdef HAVE_ACCEPT4
2318  if (!cloexec_done)
2319 #endif
2320  {
2321  _dbus_fd_set_close_on_exec(client_fd.fd);
2322  }
2323 
2324  return client_fd;
2325 }
2326 
2337 {
2338  const char *directory;
2339  struct stat sb;
2340 
2341  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2342 
2343  directory = _dbus_string_get_const_data (dir);
2344 
2345  if (stat (directory, &sb) < 0)
2346  {
2347  dbus_set_error (error, _dbus_error_from_errno (errno),
2348  "%s", _dbus_strerror (errno));
2349 
2350  return FALSE;
2351  }
2352 
2353  if (sb.st_uid != geteuid ())
2354  {
2356  "%s directory is owned by user %lu, not %lu",
2357  directory,
2358  (unsigned long) sb.st_uid,
2359  (unsigned long) geteuid ());
2360  return FALSE;
2361  }
2362 
2363  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2364  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2365  {
2367  "%s directory is not private to the user", directory);
2368  return FALSE;
2369  }
2370 
2371  return TRUE;
2372 }
2373 
2374 static dbus_bool_t
2375 fill_user_info_from_passwd (struct passwd *p,
2376  DBusUserInfo *info,
2377  DBusError *error)
2378 {
2379  _dbus_assert (p->pw_name != NULL);
2380  _dbus_assert (p->pw_dir != NULL);
2381 
2382  info->uid = p->pw_uid;
2383  info->primary_gid = p->pw_gid;
2384  info->username = _dbus_strdup (p->pw_name);
2385  info->homedir = _dbus_strdup (p->pw_dir);
2386 
2387  if (info->username == NULL ||
2388  info->homedir == NULL)
2389  {
2391  return FALSE;
2392  }
2393 
2394  return TRUE;
2395 }
2396 
2397 static dbus_bool_t
2398 fill_user_info (DBusUserInfo *info,
2399  dbus_uid_t uid,
2400  const DBusString *username,
2401  DBusError *error)
2402 {
2403  const char *username_c;
2404 
2405  /* exactly one of username/uid provided */
2406  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2407  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2408 
2409  info->uid = DBUS_UID_UNSET;
2410  info->primary_gid = DBUS_GID_UNSET;
2411  info->group_ids = NULL;
2412  info->n_group_ids = 0;
2413  info->username = NULL;
2414  info->homedir = NULL;
2415 
2416  if (username != NULL)
2417  username_c = _dbus_string_get_const_data (username);
2418  else
2419  username_c = NULL;
2420 
2421  /* For now assuming that the getpwnam() and getpwuid() flavors
2422  * are always symmetrical, if not we have to add more configure
2423  * checks
2424  */
2425 
2426 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2427  {
2428  struct passwd *p;
2429  int result;
2430  size_t buflen;
2431  char *buf;
2432  struct passwd p_str;
2433 
2434  /* retrieve maximum needed size for buf */
2435  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2436 
2437  /* sysconf actually returns a long, but everything else expects size_t,
2438  * so just recast here.
2439  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2440  */
2441  if ((long) buflen <= 0)
2442  buflen = 1024;
2443 
2444  result = -1;
2445  while (1)
2446  {
2447  buf = dbus_malloc (buflen);
2448  if (buf == NULL)
2449  {
2451  return FALSE;
2452  }
2453 
2454  p = NULL;
2455 #ifdef HAVE_POSIX_GETPWNAM_R
2456  if (uid != DBUS_UID_UNSET)
2457  result = getpwuid_r (uid, &p_str, buf, buflen,
2458  &p);
2459  else
2460  result = getpwnam_r (username_c, &p_str, buf, buflen,
2461  &p);
2462 #else
2463  if (uid != DBUS_UID_UNSET)
2464  p = getpwuid_r (uid, &p_str, buf, buflen);
2465  else
2466  p = getpwnam_r (username_c, &p_str, buf, buflen);
2467  result = 0;
2468 #endif /* !HAVE_POSIX_GETPWNAM_R */
2469  //Try a bigger buffer if ERANGE was returned
2470  if (result == ERANGE && buflen < 512 * 1024)
2471  {
2472  dbus_free (buf);
2473  buflen *= 2;
2474  }
2475  else
2476  {
2477  break;
2478  }
2479  }
2480  if (result == 0 && p == &p_str)
2481  {
2482  if (!fill_user_info_from_passwd (p, info, error))
2483  {
2484  dbus_free (buf);
2485  return FALSE;
2486  }
2487  dbus_free (buf);
2488  }
2489  else
2490  {
2491  dbus_set_error (error, _dbus_error_from_errno (errno),
2492  "User \"%s\" unknown or no memory to allocate password entry\n",
2493  username_c ? username_c : "???");
2494  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2495  dbus_free (buf);
2496  return FALSE;
2497  }
2498  }
2499 #else /* ! HAVE_GETPWNAM_R */
2500  {
2501  /* I guess we're screwed on thread safety here */
2502  struct passwd *p;
2503 
2504  if (uid != DBUS_UID_UNSET)
2505  p = getpwuid (uid);
2506  else
2507  p = getpwnam (username_c);
2508 
2509  if (p != NULL)
2510  {
2511  if (!fill_user_info_from_passwd (p, info, error))
2512  {
2513  return FALSE;
2514  }
2515  }
2516  else
2517  {
2518  dbus_set_error (error, _dbus_error_from_errno (errno),
2519  "User \"%s\" unknown or no memory to allocate password entry\n",
2520  username_c ? username_c : "???");
2521  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2522  return FALSE;
2523  }
2524  }
2525 #endif /* ! HAVE_GETPWNAM_R */
2526 
2527  /* Fill this in so we can use it to get groups */
2528  username_c = info->username;
2529 
2530 #ifdef HAVE_GETGROUPLIST
2531  {
2532  gid_t *buf;
2533  int buf_count;
2534  int i;
2535  int initial_buf_count;
2536 
2537  initial_buf_count = 17;
2538  buf_count = initial_buf_count;
2539  buf = dbus_new (gid_t, buf_count);
2540  if (buf == NULL)
2541  {
2543  goto failed;
2544  }
2545 
2546  if (getgrouplist (username_c,
2547  info->primary_gid,
2548  buf, &buf_count) < 0)
2549  {
2550  gid_t *new;
2551  /* Presumed cause of negative return code: buf has insufficient
2552  entries to hold the entire group list. The Linux behavior in this
2553  case is to pass back the actual number of groups in buf_count, but
2554  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2555  So as a hack, try to help out a bit by guessing a larger
2556  number of groups, within reason.. might still fail, of course,
2557  but we can at least print a more informative message. I looked up
2558  the "right way" to do this by downloading Apple's own source code
2559  for the "id" command, and it turns out that they use an
2560  undocumented library function getgrouplist_2 (!) which is not
2561  declared in any header in /usr/include (!!). That did not seem
2562  like the way to go here.
2563  */
2564  if (buf_count == initial_buf_count)
2565  {
2566  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2567  }
2568  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2569  if (new == NULL)
2570  {
2572  dbus_free (buf);
2573  goto failed;
2574  }
2575 
2576  buf = new;
2577 
2578  errno = 0;
2579  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2580  {
2581  if (errno == 0)
2582  {
2583  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2584  username_c, buf_count, buf_count);
2585  }
2586  else
2587  {
2588  dbus_set_error (error,
2589  _dbus_error_from_errno (errno),
2590  "Failed to get groups for username \"%s\" primary GID "
2591  DBUS_GID_FORMAT ": %s\n",
2592  username_c, info->primary_gid,
2593  _dbus_strerror (errno));
2594  dbus_free (buf);
2595  goto failed;
2596  }
2597  }
2598  }
2599 
2600  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2601  if (info->group_ids == NULL)
2602  {
2604  dbus_free (buf);
2605  goto failed;
2606  }
2607 
2608  for (i = 0; i < buf_count; ++i)
2609  info->group_ids[i] = buf[i];
2610 
2611  info->n_group_ids = buf_count;
2612 
2613  dbus_free (buf);
2614  }
2615 #else /* HAVE_GETGROUPLIST */
2616  {
2617  /* We just get the one group ID */
2618  info->group_ids = dbus_new (dbus_gid_t, 1);
2619  if (info->group_ids == NULL)
2620  {
2622  goto failed;
2623  }
2624 
2625  info->n_group_ids = 1;
2626 
2627  (info->group_ids)[0] = info->primary_gid;
2628  }
2629 #endif /* HAVE_GETGROUPLIST */
2630 
2631  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2632 
2633  return TRUE;
2634 
2635  failed:
2636  _DBUS_ASSERT_ERROR_IS_SET (error);
2637  return FALSE;
2638 }
2639 
2650  const DBusString *username,
2651  DBusError *error)
2652 {
2653  return fill_user_info (info, DBUS_UID_UNSET,
2654  username, error);
2655 }
2656 
2667  dbus_uid_t uid,
2668  DBusError *error)
2669 {
2670  return fill_user_info (info, uid,
2671  NULL, error);
2672 }
2673 
2683 {
2684  /* The POSIX spec certainly doesn't promise this, but
2685  * we need these assertions to fail as soon as we're wrong about
2686  * it so we can do the porting fixups
2687  */
2688  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2689  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2690  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2691 
2692  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2693  return FALSE;
2694  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2695  return FALSE;
2696 
2697  return TRUE;
2698 }
2699 
2713 {
2714  return _dbus_string_append_uint (str,
2715  _dbus_geteuid ());
2716 }
2717 
2722 dbus_pid_t
2724 {
2725  return getpid ();
2726 }
2727 
2731 dbus_uid_t
2733 {
2734  return getuid ();
2735 }
2736 
2740 dbus_uid_t
2742 {
2743  return geteuid ();
2744 }
2745 
2752 unsigned long
2754 {
2755  return getpid ();
2756 }
2757 
2766 _dbus_parse_uid (const DBusString *uid_str,
2767  dbus_uid_t *uid)
2768 {
2769  int end;
2770  long val;
2771 
2772  if (_dbus_string_get_length (uid_str) == 0)
2773  {
2774  _dbus_verbose ("UID string was zero length\n");
2775  return FALSE;
2776  }
2777 
2778  val = -1;
2779  end = 0;
2780  if (!_dbus_string_parse_int (uid_str, 0, &val,
2781  &end))
2782  {
2783  _dbus_verbose ("could not parse string as a UID\n");
2784  return FALSE;
2785  }
2786 
2787  if (end != _dbus_string_get_length (uid_str))
2788  {
2789  _dbus_verbose ("string contained trailing stuff after UID\n");
2790  return FALSE;
2791  }
2792 
2793  *uid = val;
2794 
2795  return TRUE;
2796 }
2797 
2798 #if !DBUS_USE_SYNC
2799 /* To be thread-safe by default on platforms that don't necessarily have
2800  * atomic operations (notably Debian armel, which is armv4t), we must
2801  * use a mutex that can be initialized statically, like this.
2802  * GLib >= 2.32 uses a similar system.
2803  */
2804 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2805 #endif
2806 
2813 dbus_int32_t
2815 {
2816 #if DBUS_USE_SYNC
2817  return __sync_add_and_fetch(&atomic->value, 1)-1;
2818 #else
2819  dbus_int32_t res;
2820 
2821  pthread_mutex_lock (&atomic_mutex);
2822  res = atomic->value;
2823  atomic->value += 1;
2824  pthread_mutex_unlock (&atomic_mutex);
2825 
2826  return res;
2827 #endif
2828 }
2829 
2836 dbus_int32_t
2838 {
2839 #if DBUS_USE_SYNC
2840  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2841 #else
2842  dbus_int32_t res;
2843 
2844  pthread_mutex_lock (&atomic_mutex);
2845  res = atomic->value;
2846  atomic->value -= 1;
2847  pthread_mutex_unlock (&atomic_mutex);
2848 
2849  return res;
2850 #endif
2851 }
2852 
2860 dbus_int32_t
2862 {
2863 #if DBUS_USE_SYNC
2864  __sync_synchronize ();
2865  return atomic->value;
2866 #else
2867  dbus_int32_t res;
2868 
2869  pthread_mutex_lock (&atomic_mutex);
2870  res = atomic->value;
2871  pthread_mutex_unlock (&atomic_mutex);
2872 
2873  return res;
2874 #endif
2875 }
2876 
2885 int
2887  int n_fds,
2888  int timeout_milliseconds)
2889 {
2890 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2891  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2892  if (timeout_milliseconds < -1)
2893  {
2894  timeout_milliseconds = -1;
2895  }
2896 
2897  return poll (fds,
2898  n_fds,
2899  timeout_milliseconds);
2900 #else /* ! HAVE_POLL */
2901  /* Emulate poll() in terms of select() */
2902  fd_set read_set, write_set, err_set;
2903  int max_fd = 0;
2904  int i;
2905  struct timeval tv;
2906  int ready;
2907 
2908  FD_ZERO (&read_set);
2909  FD_ZERO (&write_set);
2910  FD_ZERO (&err_set);
2911 
2912  for (i = 0; i < n_fds; i++)
2913  {
2914  DBusPollFD *fdp = &fds[i];
2915 
2916  if (fdp->events & _DBUS_POLLIN)
2917  FD_SET (fdp->fd, &read_set);
2918 
2919  if (fdp->events & _DBUS_POLLOUT)
2920  FD_SET (fdp->fd, &write_set);
2921 
2922  FD_SET (fdp->fd, &err_set);
2923 
2924  max_fd = MAX (max_fd, fdp->fd);
2925  }
2926 
2927  tv.tv_sec = timeout_milliseconds / 1000;
2928  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2929 
2930  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2931  timeout_milliseconds < 0 ? NULL : &tv);
2932 
2933  if (ready > 0)
2934  {
2935  for (i = 0; i < n_fds; i++)
2936  {
2937  DBusPollFD *fdp = &fds[i];
2938 
2939  fdp->revents = 0;
2940 
2941  if (FD_ISSET (fdp->fd, &read_set))
2942  fdp->revents |= _DBUS_POLLIN;
2943 
2944  if (FD_ISSET (fdp->fd, &write_set))
2945  fdp->revents |= _DBUS_POLLOUT;
2946 
2947  if (FD_ISSET (fdp->fd, &err_set))
2948  fdp->revents |= _DBUS_POLLERR;
2949  }
2950  }
2951 
2952  return ready;
2953 #endif
2954 }
2955 
2963 void
2965  long *tv_usec)
2966 {
2967 #ifdef HAVE_MONOTONIC_CLOCK
2968  struct timespec ts;
2969  clock_gettime (CLOCK_MONOTONIC, &ts);
2970 
2971  if (tv_sec)
2972  *tv_sec = ts.tv_sec;
2973  if (tv_usec)
2974  *tv_usec = ts.tv_nsec / 1000;
2975 #else
2976  struct timeval t;
2977 
2978  gettimeofday (&t, NULL);
2979 
2980  if (tv_sec)
2981  *tv_sec = t.tv_sec;
2982  if (tv_usec)
2983  *tv_usec = t.tv_usec;
2984 #endif
2985 }
2986 
2994 void
2995 _dbus_get_real_time (long *tv_sec,
2996  long *tv_usec)
2997 {
2998  struct timeval t;
2999 
3000  gettimeofday (&t, NULL);
3001 
3002  if (tv_sec)
3003  *tv_sec = t.tv_sec;
3004  if (tv_usec)
3005  *tv_usec = t.tv_usec;
3006 }
3007 
3018  DBusError *error)
3019 {
3020  const char *filename_c;
3021 
3022  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3023 
3024  filename_c = _dbus_string_get_const_data (filename);
3025 
3026  if (mkdir (filename_c, 0700) < 0)
3027  {
3028  if (errno == EEXIST)
3029  return TRUE;
3030 
3032  "Failed to create directory %s: %s\n",
3033  filename_c, _dbus_strerror (errno));
3034  return FALSE;
3035  }
3036  else
3037  return TRUE;
3038 }
3039 
3050  DBusError *error)
3051 {
3052  const char *filename_c;
3053 
3054  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3055 
3056  filename_c = _dbus_string_get_const_data (filename);
3057 
3058  if (mkdir (filename_c, 0700) < 0)
3059  {
3061  "Failed to create directory %s: %s\n",
3062  filename_c, _dbus_strerror (errno));
3063  return FALSE;
3064  }
3065  else
3066  return TRUE;
3067 }
3068 
3081  const DBusString *next_component)
3082 {
3083  dbus_bool_t dir_ends_in_slash;
3084  dbus_bool_t file_starts_with_slash;
3085 
3086  if (_dbus_string_get_length (dir) == 0 ||
3087  _dbus_string_get_length (next_component) == 0)
3088  return TRUE;
3089 
3090  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3091  _dbus_string_get_length (dir) - 1);
3092 
3093  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3094 
3095  if (dir_ends_in_slash && file_starts_with_slash)
3096  {
3097  _dbus_string_shorten (dir, 1);
3098  }
3099  else if (!(dir_ends_in_slash || file_starts_with_slash))
3100  {
3101  if (!_dbus_string_append_byte (dir, '/'))
3102  return FALSE;
3103  }
3104 
3105  return _dbus_string_copy (next_component, 0, dir,
3106  _dbus_string_get_length (dir));
3107 }
3108 
3110 #define NANOSECONDS_PER_SECOND 1000000000
3111 
3112 #define MICROSECONDS_PER_SECOND 1000000
3113 
3114 #define MILLISECONDS_PER_SECOND 1000
3115 
3116 #define NANOSECONDS_PER_MILLISECOND 1000000
3117 
3118 #define MICROSECONDS_PER_MILLISECOND 1000
3119 
3124 void
3125 _dbus_sleep_milliseconds (int milliseconds)
3126 {
3127 #ifdef HAVE_NANOSLEEP
3128  struct timespec req;
3129  struct timespec rem;
3130 
3131  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3132  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3133  rem.tv_sec = 0;
3134  rem.tv_nsec = 0;
3135 
3136  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3137  req = rem;
3138 #elif defined (HAVE_USLEEP)
3139  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3140 #else /* ! HAVE_USLEEP */
3141  sleep (MAX (milliseconds / 1000, 1));
3142 #endif
3143 }
3144 
3156  int n_bytes,
3157  DBusError *error)
3158 {
3159  int old_len;
3160  int fd;
3161  int result;
3162 
3163  old_len = _dbus_string_get_length (str);
3164  fd = -1;
3165 
3166  /* note, urandom on linux will fall back to pseudorandom */
3167  fd = open ("/dev/urandom", O_RDONLY);
3168 
3169  if (fd < 0)
3170  {
3171  dbus_set_error (error, _dbus_error_from_errno (errno),
3172  "Could not open /dev/urandom: %s",
3173  _dbus_strerror (errno));
3174  return FALSE;
3175  }
3176 
3177  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3178 
3179  result = _dbus_read (fd, str, n_bytes);
3180 
3181  if (result != n_bytes)
3182  {
3183  if (result < 0)
3184  dbus_set_error (error, _dbus_error_from_errno (errno),
3185  "Could not read /dev/urandom: %s",
3186  _dbus_strerror (errno));
3187  else
3189  "Short read from /dev/urandom");
3190 
3191  _dbus_close (fd, NULL);
3192  _dbus_string_set_length (str, old_len);
3193  return FALSE;
3194  }
3195 
3196  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3197  n_bytes);
3198 
3199  _dbus_close (fd, NULL);
3200 
3201  return TRUE;
3202 }
3203 
3209 void
3210 _dbus_exit (int code)
3211 {
3212  _exit (code);
3213 }
3214 
3223 const char*
3224 _dbus_strerror (int error_number)
3225 {
3226  const char *msg;
3227 
3228  msg = strerror (error_number);
3229  if (msg == NULL)
3230  msg = "unknown";
3231 
3232  return msg;
3233 }
3234 
3238 void
3240 {
3241  signal (SIGPIPE, SIG_IGN);
3242 }
3243 
3251 void
3253 {
3254  int val;
3255 
3256  val = fcntl (fd, F_GETFD, 0);
3257 
3258  if (val < 0)
3259  return;
3260 
3261  val |= FD_CLOEXEC;
3262 
3263  fcntl (fd, F_SETFD, val);
3264 }
3265 
3274 _dbus_close (int fd,
3275  DBusError *error)
3276 {
3277  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3278 
3279  again:
3280  if (close (fd) < 0)
3281  {
3282  if (errno == EINTR)
3283  goto again;
3284 
3285  dbus_set_error (error, _dbus_error_from_errno (errno),
3286  "Could not close fd %d", fd);
3287  return FALSE;
3288  }
3289 
3290  return TRUE;
3291 }
3292 
3301 int
3302 _dbus_dup(int fd,
3303  DBusError *error)
3304 {
3305  int new_fd;
3306 
3307 #ifdef F_DUPFD_CLOEXEC
3308  dbus_bool_t cloexec_done;
3309 
3310  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3311  cloexec_done = new_fd >= 0;
3312 
3313  if (new_fd < 0 && errno == EINVAL)
3314 #endif
3315  {
3316  new_fd = fcntl(fd, F_DUPFD, 3);
3317  }
3318 
3319  if (new_fd < 0) {
3320 
3321  dbus_set_error (error, _dbus_error_from_errno (errno),
3322  "Could not duplicate fd %d", fd);
3323  return -1;
3324  }
3325 
3326 #ifdef F_DUPFD_CLOEXEC
3327  if (!cloexec_done)
3328 #endif
3329  {
3331  }
3332 
3333  return new_fd;
3334 }
3335 
3345  DBusError *error)
3346 {
3347  return _dbus_set_fd_nonblocking (fd.fd, error);
3348 }
3349 
3350 static dbus_bool_t
3351 _dbus_set_fd_nonblocking (int fd,
3352  DBusError *error)
3353 {
3354  int val;
3355 
3356  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3357 
3358  val = fcntl (fd, F_GETFL, 0);
3359  if (val < 0)
3360  {
3361  dbus_set_error (error, _dbus_error_from_errno (errno),
3362  "Failed to get flags from file descriptor %d: %s",
3363  fd, _dbus_strerror (errno));
3364  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3365  _dbus_strerror (errno));
3366  return FALSE;
3367  }
3368 
3369  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3370  {
3371  dbus_set_error (error, _dbus_error_from_errno (errno),
3372  "Failed to set nonblocking flag of file descriptor %d: %s",
3373  fd, _dbus_strerror (errno));
3374  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3375  fd, _dbus_strerror (errno));
3376 
3377  return FALSE;
3378  }
3379 
3380  return TRUE;
3381 }
3382 
3388 void
3390 {
3391 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3392  void *bt[500];
3393  int bt_size;
3394  int i;
3395  char **syms;
3396 
3397  bt_size = backtrace (bt, 500);
3398 
3399  syms = backtrace_symbols (bt, bt_size);
3400 
3401  i = 0;
3402  while (i < bt_size)
3403  {
3404  /* don't use dbus_warn since it can _dbus_abort() */
3405  fprintf (stderr, " %s\n", syms[i]);
3406  ++i;
3407  }
3408  fflush (stderr);
3409 
3410  free (syms);
3411 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3412  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3413 #else
3414  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3415 #endif
3416 }
3417 
3432  DBusSocket *fd2,
3433  dbus_bool_t blocking,
3434  DBusError *error)
3435 {
3436 #ifdef HAVE_SOCKETPAIR
3437  int fds[2];
3438  int retval;
3439 
3440 #ifdef SOCK_CLOEXEC
3441  dbus_bool_t cloexec_done;
3442 
3443  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3444  cloexec_done = retval >= 0;
3445 
3446  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3447 #endif
3448  {
3449  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3450  }
3451 
3452  if (retval < 0)
3453  {
3454  dbus_set_error (error, _dbus_error_from_errno (errno),
3455  "Could not create full-duplex pipe");
3456  return FALSE;
3457  }
3458 
3459  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3460 
3461 #ifdef SOCK_CLOEXEC
3462  if (!cloexec_done)
3463 #endif
3464  {
3465  _dbus_fd_set_close_on_exec (fds[0]);
3466  _dbus_fd_set_close_on_exec (fds[1]);
3467  }
3468 
3469  if (!blocking &&
3470  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3471  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3472  {
3473  dbus_set_error (error, _dbus_error_from_errno (errno),
3474  "Could not set full-duplex pipe nonblocking");
3475 
3476  _dbus_close (fds[0], NULL);
3477  _dbus_close (fds[1], NULL);
3478 
3479  return FALSE;
3480  }
3481 
3482  fd1->fd = fds[0];
3483  fd2->fd = fds[1];
3484 
3485  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3486  fd1->fd, fd2->fd);
3487 
3488  return TRUE;
3489 #else
3490  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3492  "_dbus_socketpair() not implemented on this OS");
3493  return FALSE;
3494 #endif
3495 }
3496 
3505 int
3507  va_list args)
3508 {
3509  char static_buf[1024];
3510  int bufsize = sizeof (static_buf);
3511  int len;
3512  va_list args_copy;
3513 
3514  DBUS_VA_COPY (args_copy, args);
3515  len = vsnprintf (static_buf, bufsize, format, args_copy);
3516  va_end (args_copy);
3517 
3518  /* If vsnprintf() returned non-negative, then either the string fits in
3519  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3520  * returns the number of characters that were needed, or this OS returns the
3521  * truncated length.
3522  *
3523  * We ignore the possibility that snprintf might just ignore the length and
3524  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3525  * If your libc is really that bad, come back when you have a better one. */
3526  if (len == bufsize)
3527  {
3528  /* This could be the truncated length (Tru64 and IRIX have this bug),
3529  * or the real length could be coincidentally the same. Which is it?
3530  * If vsnprintf returns the truncated length, we'll go to the slow
3531  * path. */
3532  DBUS_VA_COPY (args_copy, args);
3533 
3534  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3535  len = -1;
3536 
3537  va_end (args_copy);
3538  }
3539 
3540  /* If vsnprintf() returned negative, we have to do more work.
3541  * HP-UX returns negative. */
3542  while (len < 0)
3543  {
3544  char *buf;
3545 
3546  bufsize *= 2;
3547 
3548  buf = dbus_malloc (bufsize);
3549 
3550  if (buf == NULL)
3551  return -1;
3552 
3553  DBUS_VA_COPY (args_copy, args);
3554  len = vsnprintf (buf, bufsize, format, args_copy);
3555  va_end (args_copy);
3556 
3557  dbus_free (buf);
3558 
3559  /* If the reported length is exactly the buffer size, round up to the
3560  * next size, in case vsnprintf has been returning the truncated
3561  * length */
3562  if (len == bufsize)
3563  len = -1;
3564  }
3565 
3566  return len;
3567 }
3568 
3575 const char*
3577 {
3578  /* Protected by _DBUS_LOCK_sysdeps */
3579  static const char* tmpdir = NULL;
3580 
3581  if (!_DBUS_LOCK (sysdeps))
3582  return NULL;
3583 
3584  if (tmpdir == NULL)
3585  {
3586  /* TMPDIR is what glibc uses, then
3587  * glibc falls back to the P_tmpdir macro which
3588  * just expands to "/tmp"
3589  */
3590  if (tmpdir == NULL)
3591  tmpdir = getenv("TMPDIR");
3592 
3593  /* These two env variables are probably
3594  * broken, but maybe some OS uses them?
3595  */
3596  if (tmpdir == NULL)
3597  tmpdir = getenv("TMP");
3598  if (tmpdir == NULL)
3599  tmpdir = getenv("TEMP");
3600 
3601  /* And this is the sane fallback. */
3602  if (tmpdir == NULL)
3603  tmpdir = "/tmp";
3604  }
3605 
3606  _DBUS_UNLOCK (sysdeps);
3607 
3608  _dbus_assert(tmpdir != NULL);
3609 
3610  return tmpdir;
3611 }
3612 
3613 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3614 
3633 static dbus_bool_t
3634 _read_subprocess_line_argv (const char *progpath,
3635  dbus_bool_t path_fallback,
3636  const char * const *argv,
3637  DBusString *result,
3638  DBusError *error)
3639 {
3640  int result_pipe[2] = { -1, -1 };
3641  int errors_pipe[2] = { -1, -1 };
3642  pid_t pid;
3643  int ret;
3644  int status;
3645  int orig_len;
3646 
3647  dbus_bool_t retval;
3648  sigset_t new_set, old_set;
3649 
3650  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3651  retval = FALSE;
3652 
3653  /* We need to block any existing handlers for SIGCHLD temporarily; they
3654  * will cause waitpid() below to fail.
3655  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3656  */
3657  sigemptyset (&new_set);
3658  sigaddset (&new_set, SIGCHLD);
3659  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3660 
3661  orig_len = _dbus_string_get_length (result);
3662 
3663 #define READ_END 0
3664 #define WRITE_END 1
3665  if (pipe (result_pipe) < 0)
3666  {
3667  dbus_set_error (error, _dbus_error_from_errno (errno),
3668  "Failed to create a pipe to call %s: %s",
3669  progpath, _dbus_strerror (errno));
3670  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3671  progpath, _dbus_strerror (errno));
3672  goto out;
3673  }
3674  if (pipe (errors_pipe) < 0)
3675  {
3676  dbus_set_error (error, _dbus_error_from_errno (errno),
3677  "Failed to create a pipe to call %s: %s",
3678  progpath, _dbus_strerror (errno));
3679  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3680  progpath, _dbus_strerror (errno));
3681  goto out;
3682  }
3683 
3684  pid = fork ();
3685  if (pid < 0)
3686  {
3687  dbus_set_error (error, _dbus_error_from_errno (errno),
3688  "Failed to fork() to call %s: %s",
3689  progpath, _dbus_strerror (errno));
3690  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3691  progpath, _dbus_strerror (errno));
3692  goto out;
3693  }
3694 
3695  if (pid == 0)
3696  {
3697  /* child process */
3698  const char *error_str;
3699 
3700  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3701  {
3702  int saved_errno = errno;
3703 
3704  /* Try to write details into the pipe, but don't bother
3705  * trying too hard (no retry loop). */
3706 
3707  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3708  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3709  {
3710  /* ignore, not much we can do */
3711  }
3712 
3713  error_str = _dbus_strerror (saved_errno);
3714 
3715  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3716  {
3717  /* ignore, not much we can do */
3718  }
3719 
3720  _exit (1);
3721  }
3722 
3723  /* set-up stdXXX */
3724  close (result_pipe[READ_END]);
3725  close (errors_pipe[READ_END]);
3726 
3727  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3728  _exit (1);
3729  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3730  _exit (1);
3731 
3732  _dbus_close_all ();
3733 
3734  sigprocmask (SIG_SETMASK, &old_set, NULL);
3735 
3736  /* If it looks fully-qualified, try execv first */
3737  if (progpath[0] == '/')
3738  {
3739  execv (progpath, (char * const *) argv);
3740  /* Ok, that failed. Now if path_fallback is given, let's
3741  * try unqualified. This is mostly a hack to work
3742  * around systems which ship dbus-launch in /usr/bin
3743  * but everything else in /bin (because dbus-launch
3744  * depends on X11).
3745  */
3746  if (path_fallback)
3747  /* We must have a slash, because we checked above */
3748  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3749  }
3750  else
3751  execvp (progpath, (char * const *) argv);
3752 
3753  /* still nothing, we failed */
3754  _exit (1);
3755  }
3756 
3757  /* parent process */
3758  close (result_pipe[WRITE_END]);
3759  close (errors_pipe[WRITE_END]);
3760  result_pipe[WRITE_END] = -1;
3761  errors_pipe[WRITE_END] = -1;
3762 
3763  ret = 0;
3764  do
3765  {
3766  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3767  }
3768  while (ret > 0);
3769 
3770  /* reap the child process to avoid it lingering as zombie */
3771  do
3772  {
3773  ret = waitpid (pid, &status, 0);
3774  }
3775  while (ret == -1 && errno == EINTR);
3776 
3777  /* We succeeded if the process exited with status 0 and
3778  anything was read */
3779  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3780  {
3781  /* The process ended with error */
3782  DBusString error_message;
3783  if (!_dbus_string_init (&error_message))
3784  {
3785  _DBUS_SET_OOM (error);
3786  goto out;
3787  }
3788 
3789  ret = 0;
3790  do
3791  {
3792  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3793  }
3794  while (ret > 0);
3795 
3796  _dbus_string_set_length (result, orig_len);
3797  if (_dbus_string_get_length (&error_message) > 0)
3799  "%s terminated abnormally with the following error: %s",
3800  progpath, _dbus_string_get_data (&error_message));
3801  else
3803  "%s terminated abnormally without any error message",
3804  progpath);
3805  goto out;
3806  }
3807 
3808  retval = TRUE;
3809 
3810  out:
3811  sigprocmask (SIG_SETMASK, &old_set, NULL);
3812 
3813  if (retval)
3814  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3815  else
3816  _DBUS_ASSERT_ERROR_IS_SET (error);
3817 
3818  if (result_pipe[0] != -1)
3819  close (result_pipe[0]);
3820  if (result_pipe[1] != -1)
3821  close (result_pipe[1]);
3822  if (errors_pipe[0] != -1)
3823  close (errors_pipe[0]);
3824  if (errors_pipe[1] != -1)
3825  close (errors_pipe[1]);
3826 
3827  return retval;
3828 }
3829 #endif
3830 
3844 _dbus_get_autolaunch_address (const char *scope,
3845  DBusString *address,
3846  DBusError *error)
3847 {
3848 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3849  static const char arg_dbus_launch[] = "dbus-launch";
3850  static const char arg_autolaunch[] = "--autolaunch";
3851  static const char arg_binary_syntax[] = "--binary-syntax";
3852  static const char arg_close_stderr[] = "--close-stderr";
3853 
3854  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3855  * but that's done elsewhere, and if it worked, this function wouldn't
3856  * be called.) */
3857  const char *display;
3858  const char *progpath;
3859  const char *argv[6];
3860  int i;
3861  DBusString uuid;
3862  dbus_bool_t retval;
3863 
3864  if (_dbus_check_setuid ())
3865  {
3867  "Unable to autolaunch when setuid");
3868  return FALSE;
3869  }
3870 
3871  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3872  retval = FALSE;
3873 
3874  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3875  * dbus-launch-x11 is just going to fail. Rather than trying to
3876  * run it, we might as well bail out early with a nice error.
3877  *
3878  * This is not strictly true in a world where the user bus exists,
3879  * because dbus-launch --autolaunch knows how to connect to that -
3880  * but if we were going to connect to the user bus, we'd have done
3881  * so before trying autolaunch: in any case. */
3882  display = _dbus_getenv ("DISPLAY");
3883 
3884  if (display == NULL || display[0] == '\0')
3885  {
3887  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3888  return FALSE;
3889  }
3890 
3891  if (!_dbus_string_init (&uuid))
3892  {
3893  _DBUS_SET_OOM (error);
3894  return FALSE;
3895  }
3896 
3897  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3898  {
3899  goto out;
3900  }
3901 
3902 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3903  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3904 
3905  if (progpath == NULL)
3906 #endif
3907  progpath = DBUS_BINDIR "/dbus-launch";
3908  /*
3909  * argv[0] is always dbus-launch, that's the name what we'll
3910  * get from /proc, or ps(1), regardless what the progpath is,
3911  * see fd.o#69716
3912  */
3913  i = 0;
3914  argv[i] = arg_dbus_launch;
3915  ++i;
3916  argv[i] = arg_autolaunch;
3917  ++i;
3918  argv[i] = _dbus_string_get_data (&uuid);
3919  ++i;
3920  argv[i] = arg_binary_syntax;
3921  ++i;
3922  argv[i] = arg_close_stderr;
3923  ++i;
3924  argv[i] = NULL;
3925  ++i;
3926 
3927  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3928 
3929  retval = _read_subprocess_line_argv (progpath,
3930  TRUE,
3931  argv, address, error);
3932 
3933  out:
3934  _dbus_string_free (&uuid);
3935  return retval;
3936 #else
3938  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3939  "set your DBUS_SESSION_BUS_ADDRESS instead");
3940  return FALSE;
3941 #endif
3942 }
3943 
3964  dbus_bool_t create_if_not_found,
3965  DBusError *error)
3966 {
3967  DBusError our_error = DBUS_ERROR_INIT;
3968  DBusError etc_error = DBUS_ERROR_INIT;
3969  DBusString filename;
3970  dbus_bool_t b;
3971 
3972  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3973 
3974  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
3975  if (b)
3976  return TRUE;
3977 
3978  /* Fallback to the system machine ID */
3979  _dbus_string_init_const (&filename, "/etc/machine-id");
3980  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
3981 
3982  if (b)
3983  {
3984  if (create_if_not_found)
3985  {
3986  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3987  * complain if that isn't possible for whatever reason */
3988  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3989  _dbus_write_uuid_file (&filename, machine_id, NULL);
3990  }
3991 
3992  dbus_error_free (&our_error);
3993  return TRUE;
3994  }
3995 
3996  if (!create_if_not_found)
3997  {
3998  dbus_set_error (error, etc_error.name,
3999  "D-Bus library appears to be incorrectly set up: "
4000  "see the manual page for dbus-uuidgen to correct "
4001  "this issue. (%s; %s)",
4002  our_error.message, etc_error.message);
4003  dbus_error_free (&our_error);
4004  dbus_error_free (&etc_error);
4005  return FALSE;
4006  }
4007 
4008  dbus_error_free (&our_error);
4009  dbus_error_free (&etc_error);
4010 
4011  /* if none found, try to make a new one */
4012  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4013 
4014  if (!_dbus_generate_uuid (machine_id, error))
4015  return FALSE;
4016 
4017  return _dbus_write_uuid_file (&filename, machine_id, error);
4018 }
4019 
4029  const char *launchd_env_var,
4030  DBusError *error)
4031 {
4032 #ifdef DBUS_ENABLE_LAUNCHD
4033  char *argv[4];
4034  int i;
4035 
4036  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4037 
4038  if (_dbus_check_setuid ())
4039  {
4041  "Unable to find launchd socket when setuid");
4042  return FALSE;
4043  }
4044 
4045  i = 0;
4046  argv[i] = "launchctl";
4047  ++i;
4048  argv[i] = "getenv";
4049  ++i;
4050  argv[i] = (char*)launchd_env_var;
4051  ++i;
4052  argv[i] = NULL;
4053  ++i;
4054 
4055  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4056 
4057  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4058  {
4059  return FALSE;
4060  }
4061 
4062  /* no error, but no result either */
4063  if (_dbus_string_get_length(socket_path) == 0)
4064  {
4065  return FALSE;
4066  }
4067 
4068  /* strip the carriage-return */
4069  _dbus_string_shorten(socket_path, 1);
4070  return TRUE;
4071 #else /* DBUS_ENABLE_LAUNCHD */
4073  "can't lookup socket from launchd; launchd support not compiled in");
4074  return FALSE;
4075 #endif
4076 }
4077 
4078 #ifdef DBUS_ENABLE_LAUNCHD
4079 static dbus_bool_t
4080 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4081 {
4082  dbus_bool_t valid_socket;
4083  DBusString socket_path;
4084 
4085  if (_dbus_check_setuid ())
4086  {
4088  "Unable to find launchd socket when setuid");
4089  return FALSE;
4090  }
4091 
4092  if (!_dbus_string_init (&socket_path))
4093  {
4094  _DBUS_SET_OOM (error);
4095  return FALSE;
4096  }
4097 
4098  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4099 
4100  if (dbus_error_is_set(error))
4101  {
4102  _dbus_string_free(&socket_path);
4103  return FALSE;
4104  }
4105 
4106  if (!valid_socket)
4107  {
4108  dbus_set_error(error, "no socket path",
4109  "launchd did not provide a socket path, "
4110  "verify that org.freedesktop.dbus-session.plist is loaded!");
4111  _dbus_string_free(&socket_path);
4112  return FALSE;
4113  }
4114  if (!_dbus_string_append (address, "unix:path="))
4115  {
4116  _DBUS_SET_OOM (error);
4117  _dbus_string_free(&socket_path);
4118  return FALSE;
4119  }
4120  if (!_dbus_string_copy (&socket_path, 0, address,
4121  _dbus_string_get_length (address)))
4122  {
4123  _DBUS_SET_OOM (error);
4124  _dbus_string_free(&socket_path);
4125  return FALSE;
4126  }
4127 
4128  _dbus_string_free(&socket_path);
4129  return TRUE;
4130 }
4131 #endif
4132 
4134 _dbus_lookup_user_bus (dbus_bool_t *supported,
4135  DBusString *address,
4136  DBusError *error)
4137 {
4138  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4139  dbus_bool_t ret = FALSE;
4140  struct stat stbuf;
4141  DBusString user_bus_path;
4142 
4143  if (runtime_dir == NULL)
4144  {
4145  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4146  *supported = FALSE;
4147  return TRUE; /* Cannot use it, but not an error */
4148  }
4149 
4150  if (!_dbus_string_init (&user_bus_path))
4151  {
4152  _DBUS_SET_OOM (error);
4153  return FALSE;
4154  }
4155 
4156  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4157  {
4158  _DBUS_SET_OOM (error);
4159  goto out;
4160  }
4161 
4162  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4163  {
4164  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4165  _dbus_strerror (errno));
4166  *supported = FALSE;
4167  ret = TRUE; /* Cannot use it, but not an error */
4168  goto out;
4169  }
4170 
4171  if (stbuf.st_uid != getuid ())
4172  {
4173  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4174  (long) stbuf.st_uid, (long) getuid ());
4175  *supported = FALSE;
4176  ret = TRUE; /* Cannot use it, but not an error */
4177  goto out;
4178  }
4179 
4180  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4181  {
4182  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4183  (long) stbuf.st_mode);
4184  *supported = FALSE;
4185  ret = TRUE; /* Cannot use it, but not an error */
4186  goto out;
4187  }
4188 
4189  if (!_dbus_string_append (address, "unix:path=") ||
4190  !_dbus_address_append_escaped (address, &user_bus_path))
4191  {
4192  _DBUS_SET_OOM (error);
4193  goto out;
4194  }
4195 
4196  *supported = TRUE;
4197  ret = TRUE;
4198 
4199 out:
4200  _dbus_string_free (&user_bus_path);
4201  return ret;
4202 }
4203 
4225  DBusString *address,
4226  DBusError *error)
4227 {
4228 #ifdef DBUS_ENABLE_LAUNCHD
4229  *supported = TRUE;
4230  return _dbus_lookup_session_address_launchd (address, error);
4231 #else
4232  *supported = FALSE;
4233 
4234  if (!_dbus_lookup_user_bus (supported, address, error))
4235  return FALSE;
4236  else if (*supported)
4237  return TRUE;
4238 
4239  /* On non-Mac Unix platforms, if the session address isn't already
4240  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4241  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4242  * autolaunch: global default; see init_session_address in
4243  * dbus/dbus-bus.c. */
4244  return TRUE;
4245 #endif
4246 }
4247 
4255 void
4257 {
4259 }
4260 
4276  DBusCredentials *credentials)
4277 {
4278  DBusString homedir;
4279  DBusString dotdir;
4280  dbus_uid_t uid;
4281 
4282  _dbus_assert (credentials != NULL);
4284 
4285  if (!_dbus_string_init (&homedir))
4286  return FALSE;
4287 
4288  uid = _dbus_credentials_get_unix_uid (credentials);
4289  _dbus_assert (uid != DBUS_UID_UNSET);
4290 
4291  if (!_dbus_homedir_from_uid (uid, &homedir))
4292  goto failed;
4293 
4294 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4295  {
4296  const char *override;
4297 
4298  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4299  if (override != NULL && *override != '\0')
4300  {
4301  _dbus_string_set_length (&homedir, 0);
4302  if (!_dbus_string_append (&homedir, override))
4303  goto failed;
4304 
4305  _dbus_verbose ("Using fake homedir for testing: %s\n",
4306  _dbus_string_get_const_data (&homedir));
4307  }
4308  else
4309  {
4310  /* Not strictly thread-safe, but if we fail at thread-safety here,
4311  * the worst that will happen is some extra warnings. */
4312  static dbus_bool_t already_warned = FALSE;
4313  if (!already_warned)
4314  {
4315  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4316  _dbus_string_get_const_data (&homedir));
4317  already_warned = TRUE;
4318  }
4319  }
4320  }
4321 #endif
4322 
4323  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4324  if (!_dbus_concat_dir_and_file (&homedir,
4325  &dotdir))
4326  goto failed;
4327 
4328  if (!_dbus_string_copy (&homedir, 0,
4329  directory, _dbus_string_get_length (directory))) {
4330  goto failed;
4331  }
4332 
4333  _dbus_string_free (&homedir);
4334  return TRUE;
4335 
4336  failed:
4337  _dbus_string_free (&homedir);
4338  return FALSE;
4339 }
4340 
4341 //PENDING(kdab) docs
4343 _dbus_daemon_publish_session_bus_address (const char* addr,
4344  const char *scope)
4345 {
4346  return TRUE;
4347 }
4348 
4349 //PENDING(kdab) docs
4350 void
4351 _dbus_daemon_unpublish_session_bus_address (void)
4352 {
4353 
4354 }
4355 
4364 {
4365  return e == EAGAIN || e == EWOULDBLOCK;
4366 }
4367 
4377  DBusError *error)
4378 {
4379  const char *filename_c;
4380 
4381  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4382 
4383  filename_c = _dbus_string_get_const_data (filename);
4384 
4385  if (rmdir (filename_c) != 0)
4386  {
4388  "Failed to remove directory %s: %s\n",
4389  filename_c, _dbus_strerror (errno));
4390  return FALSE;
4391  }
4392 
4393  return TRUE;
4394 }
4395 
4405 {
4406 #ifdef SCM_RIGHTS
4407  union {
4408  struct sockaddr sa;
4409  struct sockaddr_storage storage;
4410  struct sockaddr_un un;
4411  } sa_buf;
4412 
4413  socklen_t sa_len = sizeof(sa_buf);
4414 
4415  _DBUS_ZERO(sa_buf);
4416 
4417  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4418  return FALSE;
4419 
4420  return sa_buf.sa.sa_family == AF_UNIX;
4421 
4422 #else
4423  return FALSE;
4424 
4425 #endif
4426 }
4427 
4432 void
4434 {
4435  int maxfds, i;
4436 
4437 #ifdef __linux__
4438  DIR *d;
4439 
4440  /* On Linux we can optimize this a bit if /proc is available. If it
4441  isn't available, fall back to the brute force way. */
4442 
4443  d = opendir ("/proc/self/fd");
4444  if (d)
4445  {
4446  for (;;)
4447  {
4448  struct dirent *de;
4449  int fd;
4450  long l;
4451  char *e = NULL;
4452 
4453  de = readdir (d);
4454  if (!de)
4455  break;
4456 
4457  if (de->d_name[0] == '.')
4458  continue;
4459 
4460  errno = 0;
4461  l = strtol (de->d_name, &e, 10);
4462  if (errno != 0 || e == NULL || *e != '\0')
4463  continue;
4464 
4465  fd = (int) l;
4466  if (fd < 3)
4467  continue;
4468 
4469  if (fd == dirfd (d))
4470  continue;
4471 
4472  close (fd);
4473  }
4474 
4475  closedir (d);
4476  return;
4477  }
4478 #endif
4479 
4480  maxfds = sysconf (_SC_OPEN_MAX);
4481 
4482  /* Pick something reasonable if for some reason sysconf says
4483  * unlimited.
4484  */
4485  if (maxfds < 0)
4486  maxfds = 1024;
4487 
4488  /* close all inherited fds */
4489  for (i = 3; i < maxfds; i++)
4490  close (i);
4491 }
4492 
4504 {
4505  /* TODO: get __libc_enable_secure exported from glibc.
4506  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4507  */
4508 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4509  {
4510  /* See glibc/include/unistd.h */
4511  extern int __libc_enable_secure;
4512  return __libc_enable_secure;
4513  }
4514 #elif defined(HAVE_ISSETUGID)
4515  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4516  return issetugid ();
4517 #else
4518  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4519  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4520 
4521  /* We call into this function from _dbus_threads_init_platform_specific()
4522  * to make sure these are initialized before we start threading. */
4523  static dbus_bool_t check_setuid_initialised;
4524  static dbus_bool_t is_setuid;
4525 
4526  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4527  {
4528 #ifdef HAVE_GETRESUID
4529  if (getresuid (&ruid, &euid, &suid) != 0 ||
4530  getresgid (&rgid, &egid, &sgid) != 0)
4531 #endif /* HAVE_GETRESUID */
4532  {
4533  suid = ruid = getuid ();
4534  sgid = rgid = getgid ();
4535  euid = geteuid ();
4536  egid = getegid ();
4537  }
4538 
4539  check_setuid_initialised = TRUE;
4540  is_setuid = (ruid != euid || ruid != suid ||
4541  rgid != egid || rgid != sgid);
4542 
4543  }
4544  return is_setuid;
4545 #endif
4546 }
4547 
4557  DBusString *address,
4558  DBusError *error)
4559 {
4560  union {
4561  struct sockaddr sa;
4562  struct sockaddr_storage storage;
4563  struct sockaddr_un un;
4564  struct sockaddr_in ipv4;
4565  struct sockaddr_in6 ipv6;
4566  } socket;
4567  char hostip[INET6_ADDRSTRLEN];
4568  socklen_t size = sizeof (socket);
4569  DBusString path_str;
4570 
4571  if (getsockname (fd.fd, &socket.sa, &size))
4572  goto err;
4573 
4574  switch (socket.sa.sa_family)
4575  {
4576  case AF_UNIX:
4577  if (socket.un.sun_path[0]=='\0')
4578  {
4579  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4580  if (_dbus_string_append (address, "unix:abstract=") &&
4581  _dbus_address_append_escaped (address, &path_str))
4582  return TRUE;
4583  }
4584  else
4585  {
4586  _dbus_string_init_const (&path_str, socket.un.sun_path);
4587  if (_dbus_string_append (address, "unix:path=") &&
4588  _dbus_address_append_escaped (address, &path_str))
4589  return TRUE;
4590  }
4591  break;
4592  case AF_INET:
4593  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4594  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4595  hostip, ntohs (socket.ipv4.sin_port)))
4596  return TRUE;
4597  break;
4598 #ifdef AF_INET6
4599  case AF_INET6:
4600  _dbus_string_init_const (&path_str, hostip);
4601  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4602  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4603  ntohs (socket.ipv6.sin6_port)) &&
4604  _dbus_address_append_escaped (address, &path_str))
4605  return TRUE;
4606  break;
4607 #endif
4608  default:
4609  dbus_set_error (error,
4610  _dbus_error_from_errno (EINVAL),
4611  "Failed to read address from socket: Unknown socket type.");
4612  return FALSE;
4613  }
4614  err:
4615  dbus_set_error (error,
4616  _dbus_error_from_errno (errno),
4617  "Failed to open socket: %s",
4618  _dbus_strerror (errno));
4619  return FALSE;
4620 }
4621 
4622 int
4623 _dbus_save_socket_errno (void)
4624 {
4625  return errno;
4626 }
4627 
4628 void
4629 _dbus_restore_socket_errno (int saved_errno)
4630 {
4631  errno = saved_errno;
4632 }
4633 
4634 static const char *syslog_tag = "dbus";
4635 #ifdef HAVE_SYSLOG_H
4636 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4637 #endif
4638 
4653 void
4654 _dbus_init_system_log (const char *tag,
4655  DBusLogFlags flags)
4656 {
4657  /* We never want to turn off logging completely */
4658  _dbus_assert (
4659  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4660 
4661  syslog_tag = tag;
4662 
4663 #ifdef HAVE_SYSLOG_H
4664  log_flags = flags;
4665 
4666  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4667  openlog (tag, LOG_PID, LOG_DAEMON);
4668 #endif
4669 }
4670 
4678 void
4679 _dbus_logv (DBusSystemLogSeverity severity,
4680  const char *msg,
4681  va_list args)
4682 {
4683  va_list tmp;
4684 #ifdef HAVE_SYSLOG_H
4685  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4686  {
4687  int flags;
4688  switch (severity)
4689  {
4690  case DBUS_SYSTEM_LOG_INFO:
4691  flags = LOG_DAEMON | LOG_INFO;
4692  break;
4693  case DBUS_SYSTEM_LOG_WARNING:
4694  flags = LOG_DAEMON | LOG_WARNING;
4695  break;
4696  case DBUS_SYSTEM_LOG_SECURITY:
4697  flags = LOG_AUTH | LOG_NOTICE;
4698  break;
4699  case DBUS_SYSTEM_LOG_ERROR:
4700  flags = LOG_DAEMON|LOG_CRIT;
4701  break;
4702  default:
4703  _dbus_assert_not_reached ("invalid log severity");
4704  }
4705 
4706  DBUS_VA_COPY (tmp, args);
4707  vsyslog (flags, msg, tmp);
4708  va_end (tmp);
4709  }
4710 
4711  /* If we don't have syslog.h, we always behave as though stderr was in
4712  * the flags */
4713  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4714 #endif
4715  {
4716  DBUS_VA_COPY (tmp, args);
4717  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4718  vfprintf (stderr, msg, tmp);
4719  fputc ('\n', stderr);
4720  va_end (tmp);
4721  }
4722 }
4723 
4724 /* 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:280
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:285
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.
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
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:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:124
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:120
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:349
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:379
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:374
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:113
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:115
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:461
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:106
Socket interface.
Definition: dbus-sysdeps.h:149
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.
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:383
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:117
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:373
#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:122
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.
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:110
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:108
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:375
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:385