D-Bus  1.13.7
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  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
917 
918  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
919 
920  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
921  path, abstract);
922 
923 
924  if (!_dbus_open_unix_socket (&fd, error))
925  {
926  _DBUS_ASSERT_ERROR_IS_SET(error);
927  return -1;
928  }
929  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
930 
931  _DBUS_ZERO (addr);
932  addr.sun_family = AF_UNIX;
933  path_len = strlen (path);
934 
935  if (abstract)
936  {
937 #ifdef __linux__
938  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
939  path_len++; /* Account for the extra nul byte added to the start of sun_path */
940 
941  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
942  {
944  "Abstract socket name too long\n");
945  _dbus_close (fd, NULL);
946  return -1;
947  }
948 
949  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
950  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
951 #else /* !__linux__ */
953  "Operating system does not support abstract socket namespace\n");
954  _dbus_close (fd, NULL);
955  return -1;
956 #endif /* !__linux__ */
957  }
958  else
959  {
960  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
961  {
963  "Socket name too long\n");
964  _dbus_close (fd, NULL);
965  return -1;
966  }
967 
968  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
969  }
970 
971  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
972  {
973  dbus_set_error (error,
974  _dbus_error_from_errno (errno),
975  "Failed to connect to socket %s: %s",
976  path, _dbus_strerror (errno));
977 
978  _dbus_close (fd, NULL);
979  return -1;
980  }
981 
982  if (!_dbus_set_fd_nonblocking (fd, error))
983  {
984  _DBUS_ASSERT_ERROR_IS_SET (error);
985 
986  _dbus_close (fd, NULL);
987  return -1;
988  }
989 
990  return fd;
991 }
992 
1005 int
1006 _dbus_connect_exec (const char *path,
1007  char *const argv[],
1008  DBusError *error)
1009 {
1010  int fds[2];
1011  pid_t pid;
1012  int retval;
1013  dbus_bool_t cloexec_done = 0;
1014 
1015  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1016 
1017  _dbus_verbose ("connecting to process %s\n", path);
1018 
1019 #ifdef SOCK_CLOEXEC
1020  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1021  cloexec_done = (retval >= 0);
1022 
1023  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1024 #endif
1025  {
1026  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1027  }
1028 
1029  if (retval < 0)
1030  {
1031  dbus_set_error (error,
1032  _dbus_error_from_errno (errno),
1033  "Failed to create socket pair: %s",
1034  _dbus_strerror (errno));
1035  return -1;
1036  }
1037 
1038  if (!cloexec_done)
1039  {
1040  _dbus_fd_set_close_on_exec (fds[0]);
1041  _dbus_fd_set_close_on_exec (fds[1]);
1042  }
1043 
1044  /* Make sure our output buffers aren't redundantly printed by both the
1045  * parent and the child */
1046  fflush (stdout);
1047  fflush (stderr);
1048 
1049  pid = fork ();
1050  if (pid < 0)
1051  {
1052  dbus_set_error (error,
1053  _dbus_error_from_errno (errno),
1054  "Failed to fork() to call %s: %s",
1055  path, _dbus_strerror (errno));
1056  close (fds[0]);
1057  close (fds[1]);
1058  return -1;
1059  }
1060 
1061  if (pid == 0)
1062  {
1063  /* child */
1064  close (fds[0]);
1065 
1066  dup2 (fds[1], STDIN_FILENO);
1067  dup2 (fds[1], STDOUT_FILENO);
1068 
1069  if (fds[1] != STDIN_FILENO &&
1070  fds[1] != STDOUT_FILENO)
1071  close (fds[1]);
1072 
1073  /* Inherit STDERR and the controlling terminal from the
1074  parent */
1075 
1076  _dbus_close_all ();
1077 
1078  execvp (path, (char * const *) argv);
1079 
1080  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1081 
1082  _exit(1);
1083  }
1084 
1085  /* parent */
1086  close (fds[1]);
1087 
1088  if (!_dbus_set_fd_nonblocking (fds[0], error))
1089  {
1090  _DBUS_ASSERT_ERROR_IS_SET (error);
1091 
1092  close (fds[0]);
1093  return -1;
1094  }
1095 
1096  return fds[0];
1097 }
1098 
1116 int
1117 _dbus_listen_unix_socket (const char *path,
1118  dbus_bool_t abstract,
1119  DBusError *error)
1120 {
1121  int listen_fd;
1122  struct sockaddr_un addr;
1123  size_t path_len;
1124  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1125 
1126  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1127 
1128  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1129  path, abstract);
1130 
1131  if (!_dbus_open_unix_socket (&listen_fd, error))
1132  {
1133  _DBUS_ASSERT_ERROR_IS_SET(error);
1134  return -1;
1135  }
1136  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1137 
1138  _DBUS_ZERO (addr);
1139  addr.sun_family = AF_UNIX;
1140  path_len = strlen (path);
1141 
1142  if (abstract)
1143  {
1144 #ifdef __linux__
1145  /* remember that abstract names aren't nul-terminated so we rely
1146  * on sun_path being filled in with zeroes above.
1147  */
1148  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1149  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1150 
1151  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1152  {
1154  "Abstract socket name too long\n");
1155  _dbus_close (listen_fd, NULL);
1156  return -1;
1157  }
1158 
1159  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1160  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1161 #else /* !__linux__ */
1163  "Operating system does not support abstract socket namespace\n");
1164  _dbus_close (listen_fd, NULL);
1165  return -1;
1166 #endif /* !__linux__ */
1167  }
1168  else
1169  {
1170  /* Discussed security implications of this with Nalin,
1171  * and we couldn't think of where it would kick our ass, but
1172  * it still seems a bit sucky. It also has non-security suckage;
1173  * really we'd prefer to exit if the socket is already in use.
1174  * But there doesn't seem to be a good way to do this.
1175  *
1176  * Just to be extra careful, I threw in the stat() - clearly
1177  * the stat() can't *fix* any security issue, but it at least
1178  * avoids inadvertent/accidental data loss.
1179  */
1180  {
1181  struct stat sb;
1182 
1183  if (stat (path, &sb) == 0 &&
1184  S_ISSOCK (sb.st_mode))
1185  unlink (path);
1186  }
1187 
1188  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1189  {
1191  "Socket name too long\n");
1192  _dbus_close (listen_fd, NULL);
1193  return -1;
1194  }
1195 
1196  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1197  }
1198 
1199  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1200  {
1201  dbus_set_error (error, _dbus_error_from_errno (errno),
1202  "Failed to bind socket \"%s\": %s",
1203  path, _dbus_strerror (errno));
1204  _dbus_close (listen_fd, NULL);
1205  return -1;
1206  }
1207 
1208  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1209  {
1210  dbus_set_error (error, _dbus_error_from_errno (errno),
1211  "Failed to listen on socket \"%s\": %s",
1212  path, _dbus_strerror (errno));
1213  _dbus_close (listen_fd, NULL);
1214  return -1;
1215  }
1216 
1217  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1218  {
1219  _DBUS_ASSERT_ERROR_IS_SET (error);
1220  _dbus_close (listen_fd, NULL);
1221  return -1;
1222  }
1223 
1224  /* Try opening up the permissions, but if we can't, just go ahead
1225  * and continue, maybe it will be good enough.
1226  */
1227  if (!abstract && chmod (path, 0777) < 0)
1228  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1229 
1230  return listen_fd;
1231 }
1232 
1243 int
1245  DBusError *error)
1246 {
1247 #ifdef HAVE_SYSTEMD
1248  int r, n;
1249  int fd;
1250  DBusSocket *new_fds;
1251 
1252  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1253 
1254  n = sd_listen_fds (TRUE);
1255  if (n < 0)
1256  {
1258  "Failed to acquire systemd socket: %s",
1259  _dbus_strerror (-n));
1260  return -1;
1261  }
1262 
1263  if (n <= 0)
1264  {
1266  "No socket received.");
1267  return -1;
1268  }
1269 
1270  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1271  {
1272  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1273  if (r < 0)
1274  {
1276  "Failed to verify systemd socket type: %s",
1277  _dbus_strerror (-r));
1278  return -1;
1279  }
1280 
1281  if (!r)
1282  {
1284  "Passed socket has wrong type.");
1285  return -1;
1286  }
1287  }
1288 
1289  /* OK, the file descriptors are all good, so let's take posession of
1290  them then. */
1291 
1292  new_fds = dbus_new (DBusSocket, n);
1293  if (!new_fds)
1294  {
1296  "Failed to allocate file handle array.");
1297  goto fail;
1298  }
1299 
1300  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1301  {
1302  if (!_dbus_set_fd_nonblocking (fd, error))
1303  {
1304  _DBUS_ASSERT_ERROR_IS_SET (error);
1305  goto fail;
1306  }
1307 
1308  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1309  }
1310 
1311  *fds = new_fds;
1312  return n;
1313 
1314  fail:
1315 
1316  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1317  {
1318  _dbus_close (fd, NULL);
1319  }
1320 
1321  dbus_free (new_fds);
1322  return -1;
1323 #else
1325  "dbus was compiled without systemd support");
1326  return -1;
1327 #endif
1328 }
1329 
1330 /* Convert an error code from getaddrinfo() or getnameinfo() into
1331  * a D-Bus error name. */
1332 static const char *
1333 _dbus_error_from_gai (int gai_res,
1334  int saved_errno)
1335 {
1336  switch (gai_res)
1337  {
1338 #ifdef EAI_FAMILY
1339  case EAI_FAMILY:
1340  /* ai_family not supported (at all) */
1341  return DBUS_ERROR_NOT_SUPPORTED;
1342 #endif
1343 
1344 #ifdef EAI_SOCKTYPE
1345  case EAI_SOCKTYPE:
1346  /* ai_socktype not supported (at all) */
1347  return DBUS_ERROR_NOT_SUPPORTED;
1348 #endif
1349 
1350 #ifdef EAI_MEMORY
1351  case EAI_MEMORY:
1352  /* Out of memory */
1353  return DBUS_ERROR_NO_MEMORY;
1354 #endif
1355 
1356 #ifdef EAI_SYSTEM
1357  case EAI_SYSTEM:
1358  /* Unspecified system error, details in errno */
1359  return _dbus_error_from_errno (saved_errno);
1360 #endif
1361 
1362  case 0:
1363  /* It succeeded, but we didn't get any addresses? */
1364  return DBUS_ERROR_FAILED;
1365 
1366  /* EAI_AGAIN: Transient failure */
1367  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1368  /* EAI_FAIL: Non-recoverable failure */
1369  /* EAI_NODATA: host exists but has no addresses */
1370  /* EAI_NONAME: host does not exist */
1371  /* EAI_OVERFLOW: argument buffer overflow */
1372  /* EAI_SERVICE: service not available for specified socket
1373  * type (we should never see this because we use numeric
1374  * ports) */
1375  default:
1376  return DBUS_ERROR_FAILED;
1377  }
1378 }
1379 
1393 DBusSocket
1394 _dbus_connect_tcp_socket (const char *host,
1395  const char *port,
1396  const char *family,
1397  DBusError *error)
1398 {
1399  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1400 }
1401 
1402 DBusSocket
1403 _dbus_connect_tcp_socket_with_nonce (const char *host,
1404  const char *port,
1405  const char *family,
1406  const char *noncefile,
1407  DBusError *error)
1408 {
1409  int saved_errno = 0;
1410  DBusList *connect_errors = NULL;
1411  DBusSocket fd = DBUS_SOCKET_INIT;
1412  int res;
1413  struct addrinfo hints;
1414  struct addrinfo *ai, *tmp;
1415  DBusError *connect_error;
1416 
1417  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1418 
1419  _DBUS_ZERO (hints);
1420 
1421  if (!family)
1422  hints.ai_family = AF_UNSPEC;
1423  else if (!strcmp(family, "ipv4"))
1424  hints.ai_family = AF_INET;
1425  else if (!strcmp(family, "ipv6"))
1426  hints.ai_family = AF_INET6;
1427  else
1428  {
1429  dbus_set_error (error,
1431  "Unknown address family %s", family);
1432  return _dbus_socket_get_invalid ();
1433  }
1434  hints.ai_protocol = IPPROTO_TCP;
1435  hints.ai_socktype = SOCK_STREAM;
1436  hints.ai_flags = AI_ADDRCONFIG;
1437 
1438  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1439  {
1440  dbus_set_error (error,
1441  _dbus_error_from_gai (res, errno),
1442  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1443  host, port, gai_strerror(res), res);
1444  _dbus_socket_invalidate (&fd);
1445  goto out;
1446  }
1447 
1448  tmp = ai;
1449  while (tmp)
1450  {
1451  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1452  {
1453  freeaddrinfo(ai);
1454  _DBUS_ASSERT_ERROR_IS_SET(error);
1455  _dbus_socket_invalidate (&fd);
1456  goto out;
1457  }
1458  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1459 
1460  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1461  {
1462  saved_errno = errno;
1463  _dbus_close (fd.fd, NULL);
1464  _dbus_socket_invalidate (&fd);
1465 
1466  connect_error = dbus_new0 (DBusError, 1);
1467 
1468  if (connect_error == NULL)
1469  {
1470  _DBUS_SET_OOM (error);
1471  goto out;
1472  }
1473 
1474  dbus_error_init (connect_error);
1475  _dbus_set_error_with_inet_sockaddr (connect_error,
1476  tmp->ai_addr, tmp->ai_addrlen,
1477  "Failed to connect to socket",
1478  saved_errno);
1479 
1480  if (!_dbus_list_append (&connect_errors, connect_error))
1481  {
1482  dbus_error_free (connect_error);
1483  dbus_free (connect_error);
1484  _DBUS_SET_OOM (error);
1485  goto out;
1486  }
1487 
1488  tmp = tmp->ai_next;
1489  continue;
1490  }
1491 
1492  break;
1493  }
1494  freeaddrinfo(ai);
1495 
1496  if (!_dbus_socket_is_valid (fd))
1497  {
1498  _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1499  host, port, error);
1500  goto out;
1501  }
1502 
1503  if (noncefile != NULL)
1504  {
1505  DBusString noncefileStr;
1506  dbus_bool_t ret;
1507  _dbus_string_init_const (&noncefileStr, noncefile);
1508  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1509 
1510  if (!ret)
1511  {
1512  _dbus_close (fd.fd, NULL);
1513  _dbus_socket_invalidate (&fd);
1514  goto out;
1515  }
1516  }
1517 
1518  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1519  {
1520  _dbus_close (fd.fd, NULL);
1521  _dbus_socket_invalidate (&fd);
1522  goto out;
1523  }
1524 
1525 out:
1526  while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1527  {
1528  dbus_error_free (connect_error);
1529  dbus_free (connect_error);
1530  }
1531 
1532  return fd;
1533 }
1534 
1552 int
1553 _dbus_listen_tcp_socket (const char *host,
1554  const char *port,
1555  const char *family,
1556  DBusString *retport,
1557  const char **retfamily,
1558  DBusSocket **fds_p,
1559  DBusError *error)
1560 {
1561  int saved_errno;
1562  int nlisten_fd = 0, res, i;
1563  DBusList *bind_errors = NULL;
1564  DBusError *bind_error = NULL;
1565  DBusSocket *listen_fd = NULL;
1566  struct addrinfo hints;
1567  struct addrinfo *ai, *tmp;
1568  unsigned int reuseaddr;
1569  dbus_bool_t have_ipv4 = FALSE;
1570  dbus_bool_t have_ipv6 = FALSE;
1571 
1572  *fds_p = NULL;
1573  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1574 
1575  _DBUS_ZERO (hints);
1576 
1577  if (!family)
1578  hints.ai_family = AF_UNSPEC;
1579  else if (!strcmp(family, "ipv4"))
1580  hints.ai_family = AF_INET;
1581  else if (!strcmp(family, "ipv6"))
1582  hints.ai_family = AF_INET6;
1583  else
1584  {
1585  dbus_set_error (error,
1587  "Unknown address family %s", family);
1588  return -1;
1589  }
1590 
1591  hints.ai_protocol = IPPROTO_TCP;
1592  hints.ai_socktype = SOCK_STREAM;
1593  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1594 
1595  redo_lookup_with_port:
1596  ai = NULL;
1597  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1598  {
1599  dbus_set_error (error,
1600  _dbus_error_from_gai (res, errno),
1601  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1602  host ? host : "*", port, gai_strerror(res), res);
1603  goto failed;
1604  }
1605 
1606  tmp = ai;
1607  while (tmp)
1608  {
1609  int fd = -1, tcp_nodelay_on;
1610  DBusSocket *newlisten_fd;
1611 
1612  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1613  {
1614  _DBUS_ASSERT_ERROR_IS_SET(error);
1615  goto failed;
1616  }
1617  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1618 
1619  reuseaddr = 1;
1620  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1621  {
1622  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1623  host ? host : "*", port, _dbus_strerror (errno));
1624  }
1625 
1626  /* Nagle's algorithm imposes a huge delay on the initial messages
1627  going over TCP. */
1628  tcp_nodelay_on = 1;
1629  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1630  {
1631  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1632  host ? host : "*", port, _dbus_strerror (errno));
1633  }
1634 
1635  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1636  {
1637  saved_errno = errno;
1638  _dbus_close(fd, NULL);
1639 
1640  /*
1641  * We don't treat this as a fatal error, because there might be
1642  * other addresses that we can listen on. In particular:
1643  *
1644  * - If saved_errno is EADDRINUSE after we
1645  * "goto redo_lookup_with_port" after binding a port on one of the
1646  * possible addresses, we will try to bind that same port on
1647  * every address, including the same address again for a second
1648  * time, which will fail with EADDRINUSE.
1649  *
1650  * - If saved_errno is EADDRINUSE, it might be because binding to
1651  * an IPv6 address implicitly binds to a corresponding IPv4
1652  * address or vice versa (e.g. Linux with bindv6only=0).
1653  *
1654  * - If saved_errno is EADDRNOTAVAIL when we asked for family
1655  * AF_UNSPEC, it might be because IPv6 is disabled for this
1656  * particular interface (e.g. Linux with
1657  * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1658  */
1659  bind_error = dbus_new0 (DBusError, 1);
1660 
1661  if (bind_error == NULL)
1662  {
1663  _DBUS_SET_OOM (error);
1664  goto failed;
1665  }
1666 
1667  dbus_error_init (bind_error);
1668  _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1669  "Failed to bind socket",
1670  saved_errno);
1671 
1672  if (!_dbus_list_append (&bind_errors, bind_error))
1673  {
1674  dbus_error_free (bind_error);
1675  dbus_free (bind_error);
1676  _DBUS_SET_OOM (error);
1677  goto failed;
1678  }
1679 
1680  /* Try the next address, maybe it will work better */
1681  tmp = tmp->ai_next;
1682  continue;
1683  }
1684 
1685  if (listen (fd, 30 /* backlog */) < 0)
1686  {
1687  saved_errno = errno;
1688  _dbus_close (fd, NULL);
1689  _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1690  "Failed to listen on socket",
1691  saved_errno);
1692  goto failed;
1693  }
1694 
1695  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1696  if (!newlisten_fd)
1697  {
1698  _dbus_close (fd, NULL);
1700  "Failed to allocate file handle array");
1701  goto failed;
1702  }
1703  listen_fd = newlisten_fd;
1704  listen_fd[nlisten_fd].fd = fd;
1705  nlisten_fd++;
1706 
1707  if (tmp->ai_addr->sa_family == AF_INET)
1708  have_ipv4 = TRUE;
1709  else if (tmp->ai_addr->sa_family == AF_INET6)
1710  have_ipv6 = TRUE;
1711 
1712  if (!_dbus_string_get_length(retport))
1713  {
1714  /* If the user didn't specify a port, or used 0, then
1715  the kernel chooses a port. After the first address
1716  is bound to, we need to force all remaining addresses
1717  to use the same port */
1718  if (!port || !strcmp(port, "0"))
1719  {
1720  int result;
1721  struct sockaddr_storage addr;
1722  socklen_t addrlen;
1723  char portbuf[50];
1724 
1725  addrlen = sizeof(addr);
1726  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1727 
1728  if (result == -1)
1729  {
1730  saved_errno = errno;
1731  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1732  "Failed to retrieve socket name for \"%s:%s\": %s",
1733  host ? host : "*", port, _dbus_strerror (saved_errno));
1734  goto failed;
1735  }
1736 
1737  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1738  portbuf, sizeof(portbuf),
1739  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1740  {
1741  saved_errno = errno;
1742  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1743  "Failed to resolve port \"%s:%s\": %s (%d)",
1744  host ? host : "*", port, gai_strerror(res), res);
1745  goto failed;
1746  }
1747 
1748  if (!_dbus_string_append(retport, portbuf))
1749  {
1751  goto failed;
1752  }
1753 
1754  /* Release current address list & redo lookup */
1755  port = _dbus_string_get_const_data(retport);
1756  freeaddrinfo(ai);
1757  goto redo_lookup_with_port;
1758  }
1759  else
1760  {
1761  if (!_dbus_string_append(retport, port))
1762  {
1764  goto failed;
1765  }
1766  }
1767  }
1768 
1769  tmp = tmp->ai_next;
1770  }
1771  freeaddrinfo(ai);
1772  ai = NULL;
1773 
1774  if (!nlisten_fd)
1775  {
1776  _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1777  port, error);
1778  goto failed;
1779  }
1780 
1781  if (have_ipv4 && !have_ipv6)
1782  *retfamily = "ipv4";
1783  else if (!have_ipv4 && have_ipv6)
1784  *retfamily = "ipv6";
1785 
1786  for (i = 0 ; i < nlisten_fd ; i++)
1787  {
1788  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1789  {
1790  goto failed;
1791  }
1792  }
1793 
1794  *fds_p = listen_fd;
1795 
1796  /* This list might be non-empty even on success, because we might be
1797  * ignoring EADDRINUSE or EADDRNOTAVAIL */
1798  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1799  {
1800  dbus_error_free (bind_error);
1801  dbus_free (bind_error);
1802  }
1803 
1804  return nlisten_fd;
1805 
1806  failed:
1807  if (ai)
1808  freeaddrinfo(ai);
1809  for (i = 0 ; i < nlisten_fd ; i++)
1810  _dbus_close(listen_fd[i].fd, NULL);
1811 
1812  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1813  {
1814  dbus_error_free (bind_error);
1815  dbus_free (bind_error);
1816  }
1817 
1818  dbus_free(listen_fd);
1819  return -1;
1820 }
1821 
1822 static dbus_bool_t
1823 write_credentials_byte (int server_fd,
1824  DBusError *error)
1825 {
1826  int bytes_written;
1827  char buf[1] = { '\0' };
1828 #if defined(HAVE_CMSGCRED)
1829  union {
1830  struct cmsghdr hdr;
1831  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1832  } cmsg;
1833  struct iovec iov;
1834  struct msghdr msg;
1835  iov.iov_base = buf;
1836  iov.iov_len = 1;
1837 
1838  _DBUS_ZERO(msg);
1839  msg.msg_iov = &iov;
1840  msg.msg_iovlen = 1;
1841 
1842  msg.msg_control = (caddr_t) &cmsg;
1843  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1844  _DBUS_ZERO(cmsg);
1845  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1846  cmsg.hdr.cmsg_level = SOL_SOCKET;
1847  cmsg.hdr.cmsg_type = SCM_CREDS;
1848 #endif
1849 
1850  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1851 
1852  again:
1853 
1854 #if defined(HAVE_CMSGCRED)
1855  bytes_written = sendmsg (server_fd, &msg, 0
1856 #if HAVE_DECL_MSG_NOSIGNAL
1857  |MSG_NOSIGNAL
1858 #endif
1859  );
1860 
1861  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1862  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1863  * only allows that on AF_UNIX. Try just doing a send() instead. */
1864  if (bytes_written < 0 && errno == EINVAL)
1865 #endif
1866  {
1867  bytes_written = send (server_fd, buf, 1, 0
1868 #if HAVE_DECL_MSG_NOSIGNAL
1869  |MSG_NOSIGNAL
1870 #endif
1871  );
1872  }
1873 
1874  if (bytes_written < 0 && errno == EINTR)
1875  goto again;
1876 
1877  if (bytes_written < 0)
1878  {
1879  dbus_set_error (error, _dbus_error_from_errno (errno),
1880  "Failed to write credentials byte: %s",
1881  _dbus_strerror (errno));
1882  return FALSE;
1883  }
1884  else if (bytes_written == 0)
1885  {
1887  "wrote zero bytes writing credentials byte");
1888  return FALSE;
1889  }
1890  else
1891  {
1892  _dbus_assert (bytes_written == 1);
1893  _dbus_verbose ("wrote credentials byte\n");
1894  return TRUE;
1895  }
1896 }
1897 
1898 /* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1899 static dbus_bool_t
1900 add_groups_to_credentials (int client_fd,
1901  DBusCredentials *credentials,
1902  dbus_gid_t primary)
1903 {
1904 #if defined(__linux__) && defined(SO_PEERGROUPS)
1905  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1906  gid_t *buf = NULL;
1907  socklen_t len = 1024;
1908  dbus_bool_t oom = FALSE;
1909  /* libdbus has a different representation of group IDs just to annoy you */
1910  dbus_gid_t *converted_gids = NULL;
1911  dbus_bool_t need_primary = TRUE;
1912  size_t n_gids;
1913  size_t i;
1914 
1915  n_gids = ((size_t) len) / sizeof (gid_t);
1916  buf = dbus_new (gid_t, n_gids);
1917 
1918  if (buf == NULL)
1919  return FALSE;
1920 
1921  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1922  {
1923  int e = errno;
1924  gid_t *replacement;
1925 
1926  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1927  _dbus_strerror (e), (unsigned long) len);
1928 
1929  if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1930  {
1931  _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1932  _dbus_strerror (e));
1933  goto out;
1934  }
1935 
1936  /* If not enough space, len is updated to be enough.
1937  * Try again with a large enough buffer. */
1938  n_gids = ((size_t) len) / sizeof (gid_t);
1939  replacement = dbus_realloc (buf, len);
1940 
1941  if (replacement == NULL)
1942  {
1943  oom = TRUE;
1944  goto out;
1945  }
1946 
1947  buf = replacement;
1948  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1949  }
1950 
1951  if (len <= 0)
1952  {
1953  _dbus_verbose ("getsockopt(SO_PEERGROUPS) yielded <= 0 bytes: %ld\n",
1954  (long) len);
1955  goto out;
1956  }
1957 
1958  if (len > n_gids * sizeof (gid_t))
1959  {
1960  _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
1961  _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
1962  }
1963 
1964  if (len % sizeof (gid_t) != 0)
1965  {
1966  _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
1967  "integer multiple of sizeof(gid_t): %lu should be "
1968  "divisible by %zu",
1969  (unsigned long) len, sizeof (gid_t));
1970  goto out;
1971  }
1972 
1973  /* Allocate an extra space for the primary group ID */
1974  n_gids = ((size_t) len) / sizeof (gid_t);
1975 
1976  /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
1977  * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
1978  * This is using _DBUS_INT32_MAX as a conservative lower bound for
1979  * the maximum size_t. */
1980  if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
1981  {
1982  _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
1983  "of groups (%lu bytes), ignoring",
1984  (unsigned long) len);
1985  goto out;
1986  }
1987 
1988  converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
1989 
1990  if (converted_gids == NULL)
1991  {
1992  oom = TRUE;
1993  goto out;
1994  }
1995 
1996  for (i = 0; i < n_gids; i++)
1997  {
1998  converted_gids[i] = (dbus_gid_t) buf[i];
1999 
2000  if (converted_gids[i] == primary)
2001  need_primary = FALSE;
2002  }
2003 
2004  if (need_primary && primary != DBUS_GID_UNSET)
2005  {
2006  converted_gids[n_gids] = primary;
2007  n_gids++;
2008  }
2009 
2010  _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2011 
2012 out:
2013  dbus_free (buf);
2014  return !oom;
2015 #else
2016  /* no error */
2017  return TRUE;
2018 #endif
2019 }
2020 
2021 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2022 static dbus_bool_t
2023 add_linux_security_label_to_credentials (int client_fd,
2024  DBusCredentials *credentials)
2025 {
2026 #if defined(__linux__) && defined(SO_PEERSEC)
2027  DBusString buf;
2028  socklen_t len = 1024;
2029  dbus_bool_t oom = FALSE;
2030 
2031  if (!_dbus_string_init_preallocated (&buf, len) ||
2032  !_dbus_string_set_length (&buf, len))
2033  return FALSE;
2034 
2035  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2036  _dbus_string_get_data (&buf), &len) < 0)
2037  {
2038  int e = errno;
2039 
2040  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2041  _dbus_strerror (e), (unsigned long) len);
2042 
2043  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2044  {
2045  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2046  _dbus_strerror (e));
2047  goto out;
2048  }
2049 
2050  /* If not enough space, len is updated to be enough.
2051  * Try again with a large enough buffer. */
2052  if (!_dbus_string_set_length (&buf, len))
2053  {
2054  oom = TRUE;
2055  goto out;
2056  }
2057 
2058  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2059  }
2060 
2061  if (len <= 0)
2062  {
2063  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2064  (unsigned long) len);
2065  goto out;
2066  }
2067 
2068  if (len > _dbus_string_get_length_uint (&buf))
2069  {
2070  _dbus_verbose ("%lu > %u", (unsigned long) len,
2071  _dbus_string_get_length_uint (&buf));
2072  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2073  }
2074 
2075  if (_dbus_string_get_byte (&buf, len - 1) == 0)
2076  {
2077  /* the kernel included the trailing \0 in its count,
2078  * but DBusString always has an extra \0 after the data anyway */
2079  _dbus_verbose ("subtracting trailing \\0\n");
2080  len--;
2081  }
2082 
2083  if (!_dbus_string_set_length (&buf, len))
2084  {
2085  _dbus_assert_not_reached ("shortening string should not lead to OOM");
2086  oom = TRUE;
2087  goto out;
2088  }
2089 
2090  if (strlen (_dbus_string_get_const_data (&buf)) != len)
2091  {
2092  /* LSM people on the linux-security-module@ mailing list say this
2093  * should never happen: the label should be a bytestring with
2094  * an optional trailing \0 */
2095  _dbus_verbose ("security label from kernel had an embedded \\0, "
2096  "ignoring it\n");
2097  goto out;
2098  }
2099 
2100  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2101  (unsigned long) len,
2102  _dbus_string_get_const_data (&buf));
2103 
2105  _dbus_string_get_const_data (&buf)))
2106  {
2107  oom = TRUE;
2108  goto out;
2109  }
2110 
2111 out:
2112  _dbus_string_free (&buf);
2113  return !oom;
2114 #else
2115  /* no error */
2116  return TRUE;
2117 #endif
2118 }
2119 
2162  DBusCredentials *credentials,
2163  DBusError *error)
2164 {
2165  struct msghdr msg;
2166  struct iovec iov;
2167  char buf;
2168  dbus_uid_t uid_read;
2169  dbus_gid_t primary_gid_read;
2170  dbus_pid_t pid_read;
2171  int bytes_read;
2172 
2173 #ifdef HAVE_CMSGCRED
2174  union {
2175  struct cmsghdr hdr;
2176  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2177  } cmsg;
2178 #endif
2179 
2180  /* The POSIX spec certainly doesn't promise this, but
2181  * we need these assertions to fail as soon as we're wrong about
2182  * it so we can do the porting fixups
2183  */
2184  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2185  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2186  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2187 
2188  uid_read = DBUS_UID_UNSET;
2189  primary_gid_read = DBUS_GID_UNSET;
2190  pid_read = DBUS_PID_UNSET;
2191 
2192  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2193 
2194  _dbus_credentials_clear (credentials);
2195 
2196  iov.iov_base = &buf;
2197  iov.iov_len = 1;
2198 
2199  _DBUS_ZERO(msg);
2200  msg.msg_iov = &iov;
2201  msg.msg_iovlen = 1;
2202 
2203 #if defined(HAVE_CMSGCRED)
2204  _DBUS_ZERO(cmsg);
2205  msg.msg_control = (caddr_t) &cmsg;
2206  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2207 #endif
2208 
2209  again:
2210  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2211 
2212  if (bytes_read < 0)
2213  {
2214  if (errno == EINTR)
2215  goto again;
2216 
2217  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2218  * normally only call read_credentials if the socket was ready
2219  * for reading
2220  */
2221 
2222  dbus_set_error (error, _dbus_error_from_errno (errno),
2223  "Failed to read credentials byte: %s",
2224  _dbus_strerror (errno));
2225  return FALSE;
2226  }
2227  else if (bytes_read == 0)
2228  {
2229  /* this should not happen unless we are using recvmsg wrong,
2230  * so is essentially here for paranoia
2231  */
2233  "Failed to read credentials byte (zero-length read)");
2234  return FALSE;
2235  }
2236  else if (buf != '\0')
2237  {
2239  "Credentials byte was not nul");
2240  return FALSE;
2241  }
2242 
2243  _dbus_verbose ("read credentials byte\n");
2244 
2245  {
2246 #ifdef SO_PEERCRED
2247  /* Supported by at least Linux and OpenBSD, with minor differences.
2248  *
2249  * This mechanism passes the process ID through and does not require
2250  * the peer's cooperation, so we prefer it over all others. Notably,
2251  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2252  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2253  * because this is much less fragile.
2254  */
2255 #ifdef __OpenBSD__
2256  struct sockpeercred cr;
2257 #else
2258  struct ucred cr;
2259 #endif
2260  socklen_t cr_len = sizeof (cr);
2261 
2262  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2263  {
2264  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2265  _dbus_strerror (errno));
2266  }
2267  else if (cr_len != sizeof (cr))
2268  {
2269  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2270  cr_len, (int) sizeof (cr));
2271  }
2272  else
2273  {
2274  pid_read = cr.pid;
2275  uid_read = cr.uid;
2276 #ifdef __linux__
2277  /* Do other platforms have cr.gid? (Not that it really matters,
2278  * because the gid is useless to us unless we know the complete
2279  * group vector, which we only know on Linux.) */
2280  primary_gid_read = cr.gid;
2281 #endif
2282  }
2283 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2284  /* Another variant of the above - used on NetBSD
2285  */
2286  struct unpcbid cr;
2287  socklen_t cr_len = sizeof (cr);
2288 
2289  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2290  {
2291  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2292  _dbus_strerror (errno));
2293  }
2294  else if (cr_len != sizeof (cr))
2295  {
2296  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2297  cr_len, (int) sizeof (cr));
2298  }
2299  else
2300  {
2301  pid_read = cr.unp_pid;
2302  uid_read = cr.unp_euid;
2303  }
2304 #elif defined(HAVE_CMSGCRED)
2305  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2306  * presence of that struct implies SCM_CREDS. Supported by at least
2307  * FreeBSD and DragonflyBSD.
2308  *
2309  * This mechanism requires the peer to help us (it has to send us a
2310  * SCM_CREDS message) but it does pass the process ID through,
2311  * which makes it better than getpeereid().
2312  */
2313  struct cmsgcred *cred;
2314  struct cmsghdr *cmsgp;
2315 
2316  for (cmsgp = CMSG_FIRSTHDR (&msg);
2317  cmsgp != NULL;
2318  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2319  {
2320  if (cmsgp->cmsg_type == SCM_CREDS &&
2321  cmsgp->cmsg_level == SOL_SOCKET &&
2322  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2323  {
2324  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2325  pid_read = cred->cmcred_pid;
2326  uid_read = cred->cmcred_euid;
2327  break;
2328  }
2329  }
2330 
2331 #elif defined(HAVE_GETPEERUCRED)
2332  /* Supported in at least Solaris >= 10. It should probably be higher
2333  * up this list, because it carries the pid and we use this code path
2334  * for audit data. */
2335  ucred_t * ucred = NULL;
2336  if (getpeerucred (client_fd.fd, &ucred) == 0)
2337  {
2338 #ifdef HAVE_ADT
2339  adt_session_data_t *adth = NULL;
2340 #endif
2341  pid_read = ucred_getpid (ucred);
2342  uid_read = ucred_geteuid (ucred);
2343 #ifdef HAVE_ADT
2344  /* generate audit session data based on socket ucred */
2345  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2346  {
2347  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2348  }
2349  else
2350  {
2351  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2352  {
2353  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2354  }
2355  else
2356  {
2357  adt_export_data_t *data = NULL;
2358  size_t size = adt_export_session_data (adth, &data);
2359  if (size <= 0)
2360  {
2361  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2362  }
2363  else
2364  {
2365  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2366  free (data);
2367  }
2368  }
2369  (void) adt_end_session (adth);
2370  }
2371 #endif /* HAVE_ADT */
2372  }
2373  else
2374  {
2375  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2376  }
2377  if (ucred != NULL)
2378  ucred_free (ucred);
2379 
2380  /* ----------------------------------------------------------------
2381  * When adding new mechanisms, please add them above this point
2382  * if they support passing the process ID through, or below if not.
2383  * ---------------------------------------------------------------- */
2384 
2385 #elif defined(HAVE_GETPEEREID)
2386  /* getpeereid() originates from D.J. Bernstein and is fairly
2387  * widely-supported. According to a web search, it might be present in
2388  * any/all of:
2389  *
2390  * - AIX?
2391  * - Blackberry?
2392  * - Cygwin
2393  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2394  * - Mac OS X
2395  * - Minix 3.1.8+
2396  * - MirBSD?
2397  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2398  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2399  * - QNX?
2400  */
2401  uid_t euid;
2402  gid_t egid;
2403  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2404  {
2405  uid_read = euid;
2406  }
2407  else
2408  {
2409  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2410  }
2411 #else /* no supported mechanism */
2412 
2413 #warning Socket credentials not supported on this Unix OS
2414 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2415 
2416  /* Please add other operating systems known to support at least one of
2417  * the mechanisms above to this list, keeping alphabetical order.
2418  * Everything not in this list is best-effort.
2419  */
2420 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2421  defined(__linux__) || \
2422  defined(__OpenBSD__) || \
2423  defined(__NetBSD__)
2424 # error Credentials passing not working on this OS is a regression!
2425 #endif
2426 
2427  _dbus_verbose ("Socket credentials not supported on this OS\n");
2428 #endif
2429  }
2430 
2431  _dbus_verbose ("Credentials:"
2432  " pid "DBUS_PID_FORMAT
2433  " uid "DBUS_UID_FORMAT
2434  "\n",
2435  pid_read,
2436  uid_read);
2437 
2438  if (pid_read != DBUS_PID_UNSET)
2439  {
2440  if (!_dbus_credentials_add_pid (credentials, pid_read))
2441  {
2442  _DBUS_SET_OOM (error);
2443  return FALSE;
2444  }
2445  }
2446 
2447  if (uid_read != DBUS_UID_UNSET)
2448  {
2449  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2450  {
2451  _DBUS_SET_OOM (error);
2452  return FALSE;
2453  }
2454  }
2455 
2456  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2457  {
2458  _DBUS_SET_OOM (error);
2459  return FALSE;
2460  }
2461 
2462  /* We don't put any groups in the credentials unless we can put them
2463  * all there. */
2464  if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2465  {
2466  _DBUS_SET_OOM (error);
2467  return FALSE;
2468  }
2469 
2470  return TRUE;
2471 }
2472 
2492  DBusError *error)
2493 {
2494  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2495 
2496  if (write_credentials_byte (server_fd.fd, error))
2497  return TRUE;
2498  else
2499  return FALSE;
2500 }
2501 
2511 DBusSocket
2513 {
2514  DBusSocket client_fd;
2515  struct sockaddr addr;
2516  socklen_t addrlen;
2517 #ifdef HAVE_ACCEPT4
2518  dbus_bool_t cloexec_done;
2519 #endif
2520 
2521  addrlen = sizeof (addr);
2522 
2523  retry:
2524 
2525 #ifdef HAVE_ACCEPT4
2526  /*
2527  * At compile-time, we assume that if accept4() is available in
2528  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2529  * not necessarily true that either is supported by the running kernel.
2530  */
2531  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2532  cloexec_done = client_fd.fd >= 0;
2533 
2534  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2535 #endif
2536  {
2537  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2538  }
2539 
2540  if (client_fd.fd < 0)
2541  {
2542  if (errno == EINTR)
2543  goto retry;
2544  }
2545 
2546  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2547 
2548 #ifdef HAVE_ACCEPT4
2549  if (!cloexec_done)
2550 #endif
2551  {
2552  _dbus_fd_set_close_on_exec(client_fd.fd);
2553  }
2554 
2555  return client_fd;
2556 }
2557 
2568 {
2569  const char *directory;
2570  struct stat sb;
2571 
2572  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2573 
2574  directory = _dbus_string_get_const_data (dir);
2575 
2576  if (stat (directory, &sb) < 0)
2577  {
2578  dbus_set_error (error, _dbus_error_from_errno (errno),
2579  "%s", _dbus_strerror (errno));
2580 
2581  return FALSE;
2582  }
2583 
2584  if (sb.st_uid != geteuid ())
2585  {
2587  "%s directory is owned by user %lu, not %lu",
2588  directory,
2589  (unsigned long) sb.st_uid,
2590  (unsigned long) geteuid ());
2591  return FALSE;
2592  }
2593 
2594  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2595  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2596  {
2598  "%s directory is not private to the user", directory);
2599  return FALSE;
2600  }
2601 
2602  return TRUE;
2603 }
2604 
2605 static dbus_bool_t
2606 fill_user_info_from_passwd (struct passwd *p,
2607  DBusUserInfo *info,
2608  DBusError *error)
2609 {
2610  _dbus_assert (p->pw_name != NULL);
2611  _dbus_assert (p->pw_dir != NULL);
2612 
2613  info->uid = p->pw_uid;
2614  info->primary_gid = p->pw_gid;
2615  info->username = _dbus_strdup (p->pw_name);
2616  info->homedir = _dbus_strdup (p->pw_dir);
2617 
2618  if (info->username == NULL ||
2619  info->homedir == NULL)
2620  {
2622  return FALSE;
2623  }
2624 
2625  return TRUE;
2626 }
2627 
2628 static dbus_bool_t
2629 fill_user_info (DBusUserInfo *info,
2630  dbus_uid_t uid,
2631  const DBusString *username,
2632  DBusError *error)
2633 {
2634  const char *username_c;
2635 
2636  /* exactly one of username/uid provided */
2637  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2638  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2639 
2640  info->uid = DBUS_UID_UNSET;
2641  info->primary_gid = DBUS_GID_UNSET;
2642  info->group_ids = NULL;
2643  info->n_group_ids = 0;
2644  info->username = NULL;
2645  info->homedir = NULL;
2646 
2647  if (username != NULL)
2648  username_c = _dbus_string_get_const_data (username);
2649  else
2650  username_c = NULL;
2651 
2652  /* For now assuming that the getpwnam() and getpwuid() flavors
2653  * are always symmetrical, if not we have to add more configure
2654  * checks
2655  */
2656 
2657 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2658  {
2659  struct passwd *p;
2660  int result;
2661  size_t buflen;
2662  char *buf;
2663  struct passwd p_str;
2664 
2665  /* retrieve maximum needed size for buf */
2666  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2667 
2668  /* sysconf actually returns a long, but everything else expects size_t,
2669  * so just recast here.
2670  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2671  */
2672  if ((long) buflen <= 0)
2673  buflen = 1024;
2674 
2675  result = -1;
2676  while (1)
2677  {
2678  buf = dbus_malloc (buflen);
2679  if (buf == NULL)
2680  {
2682  return FALSE;
2683  }
2684 
2685  p = NULL;
2686 #ifdef HAVE_POSIX_GETPWNAM_R
2687  if (uid != DBUS_UID_UNSET)
2688  result = getpwuid_r (uid, &p_str, buf, buflen,
2689  &p);
2690  else
2691  result = getpwnam_r (username_c, &p_str, buf, buflen,
2692  &p);
2693 #else
2694  if (uid != DBUS_UID_UNSET)
2695  p = getpwuid_r (uid, &p_str, buf, buflen);
2696  else
2697  p = getpwnam_r (username_c, &p_str, buf, buflen);
2698  result = 0;
2699 #endif /* !HAVE_POSIX_GETPWNAM_R */
2700  //Try a bigger buffer if ERANGE was returned
2701  if (result == ERANGE && buflen < 512 * 1024)
2702  {
2703  dbus_free (buf);
2704  buflen *= 2;
2705  }
2706  else
2707  {
2708  break;
2709  }
2710  }
2711  if (result == 0 && p == &p_str)
2712  {
2713  if (!fill_user_info_from_passwd (p, info, error))
2714  {
2715  dbus_free (buf);
2716  return FALSE;
2717  }
2718  dbus_free (buf);
2719  }
2720  else
2721  {
2722  dbus_set_error (error, _dbus_error_from_errno (errno),
2723  "User \"%s\" unknown or no memory to allocate password entry\n",
2724  username_c ? username_c : "???");
2725  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2726  dbus_free (buf);
2727  return FALSE;
2728  }
2729  }
2730 #else /* ! HAVE_GETPWNAM_R */
2731  {
2732  /* I guess we're screwed on thread safety here */
2733  struct passwd *p;
2734 
2735  if (uid != DBUS_UID_UNSET)
2736  p = getpwuid (uid);
2737  else
2738  p = getpwnam (username_c);
2739 
2740  if (p != NULL)
2741  {
2742  if (!fill_user_info_from_passwd (p, info, error))
2743  {
2744  return FALSE;
2745  }
2746  }
2747  else
2748  {
2749  dbus_set_error (error, _dbus_error_from_errno (errno),
2750  "User \"%s\" unknown or no memory to allocate password entry\n",
2751  username_c ? username_c : "???");
2752  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2753  return FALSE;
2754  }
2755  }
2756 #endif /* ! HAVE_GETPWNAM_R */
2757 
2758  /* Fill this in so we can use it to get groups */
2759  username_c = info->username;
2760 
2761 #ifdef HAVE_GETGROUPLIST
2762  {
2763  gid_t *buf;
2764  int buf_count;
2765  int i;
2766  int initial_buf_count;
2767 
2768  initial_buf_count = 17;
2769  buf_count = initial_buf_count;
2770  buf = dbus_new (gid_t, buf_count);
2771  if (buf == NULL)
2772  {
2774  goto failed;
2775  }
2776 
2777  if (getgrouplist (username_c,
2778  info->primary_gid,
2779  buf, &buf_count) < 0)
2780  {
2781  gid_t *new;
2782  /* Presumed cause of negative return code: buf has insufficient
2783  entries to hold the entire group list. The Linux behavior in this
2784  case is to pass back the actual number of groups in buf_count, but
2785  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2786  So as a hack, try to help out a bit by guessing a larger
2787  number of groups, within reason.. might still fail, of course,
2788  but we can at least print a more informative message. I looked up
2789  the "right way" to do this by downloading Apple's own source code
2790  for the "id" command, and it turns out that they use an
2791  undocumented library function getgrouplist_2 (!) which is not
2792  declared in any header in /usr/include (!!). That did not seem
2793  like the way to go here.
2794  */
2795  if (buf_count == initial_buf_count)
2796  {
2797  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2798  }
2799  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2800  if (new == NULL)
2801  {
2803  dbus_free (buf);
2804  goto failed;
2805  }
2806 
2807  buf = new;
2808 
2809  errno = 0;
2810  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2811  {
2812  if (errno == 0)
2813  {
2814  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2815  username_c, buf_count, buf_count);
2816  }
2817  else
2818  {
2819  dbus_set_error (error,
2820  _dbus_error_from_errno (errno),
2821  "Failed to get groups for username \"%s\" primary GID "
2822  DBUS_GID_FORMAT ": %s\n",
2823  username_c, info->primary_gid,
2824  _dbus_strerror (errno));
2825  dbus_free (buf);
2826  goto failed;
2827  }
2828  }
2829  }
2830 
2831  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2832  if (info->group_ids == NULL)
2833  {
2835  dbus_free (buf);
2836  goto failed;
2837  }
2838 
2839  for (i = 0; i < buf_count; ++i)
2840  info->group_ids[i] = buf[i];
2841 
2842  info->n_group_ids = buf_count;
2843 
2844  dbus_free (buf);
2845  }
2846 #else /* HAVE_GETGROUPLIST */
2847  {
2848  /* We just get the one group ID */
2849  info->group_ids = dbus_new (dbus_gid_t, 1);
2850  if (info->group_ids == NULL)
2851  {
2853  goto failed;
2854  }
2855 
2856  info->n_group_ids = 1;
2857 
2858  (info->group_ids)[0] = info->primary_gid;
2859  }
2860 #endif /* HAVE_GETGROUPLIST */
2861 
2862  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2863 
2864  return TRUE;
2865 
2866  failed:
2867  _DBUS_ASSERT_ERROR_IS_SET (error);
2868  return FALSE;
2869 }
2870 
2881  const DBusString *username,
2882  DBusError *error)
2883 {
2884  return fill_user_info (info, DBUS_UID_UNSET,
2885  username, error);
2886 }
2887 
2898  dbus_uid_t uid,
2899  DBusError *error)
2900 {
2901  return fill_user_info (info, uid,
2902  NULL, error);
2903 }
2904 
2920 {
2921  /* The POSIX spec certainly doesn't promise this, but
2922  * we need these assertions to fail as soon as we're wrong about
2923  * it so we can do the porting fixups
2924  */
2925  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2926  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2927  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2928 
2929  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2930  return FALSE;
2931  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2932  return FALSE;
2933 
2934  return TRUE;
2935 }
2936 
2950 {
2951  return _dbus_string_append_uint (str,
2952  _dbus_geteuid ());
2953 }
2954 
2959 dbus_pid_t
2961 {
2962  return getpid ();
2963 }
2964 
2968 dbus_uid_t
2970 {
2971  return getuid ();
2972 }
2973 
2977 dbus_uid_t
2979 {
2980  return geteuid ();
2981 }
2982 
2989 unsigned long
2991 {
2992  return getpid ();
2993 }
2994 
3003 _dbus_parse_uid (const DBusString *uid_str,
3004  dbus_uid_t *uid)
3005 {
3006  int end;
3007  long val;
3008 
3009  if (_dbus_string_get_length (uid_str) == 0)
3010  {
3011  _dbus_verbose ("UID string was zero length\n");
3012  return FALSE;
3013  }
3014 
3015  val = -1;
3016  end = 0;
3017  if (!_dbus_string_parse_int (uid_str, 0, &val,
3018  &end))
3019  {
3020  _dbus_verbose ("could not parse string as a UID\n");
3021  return FALSE;
3022  }
3023 
3024  if (end != _dbus_string_get_length (uid_str))
3025  {
3026  _dbus_verbose ("string contained trailing stuff after UID\n");
3027  return FALSE;
3028  }
3029 
3030  *uid = val;
3031 
3032  return TRUE;
3033 }
3034 
3035 #if !DBUS_USE_SYNC
3036 /* To be thread-safe by default on platforms that don't necessarily have
3037  * atomic operations (notably Debian armel, which is armv4t), we must
3038  * use a mutex that can be initialized statically, like this.
3039  * GLib >= 2.32 uses a similar system.
3040  */
3041 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3042 #endif
3043 
3050 dbus_int32_t
3052 {
3053 #if DBUS_USE_SYNC
3054  return __sync_add_and_fetch(&atomic->value, 1)-1;
3055 #else
3056  dbus_int32_t res;
3057 
3058  pthread_mutex_lock (&atomic_mutex);
3059  res = atomic->value;
3060  atomic->value += 1;
3061  pthread_mutex_unlock (&atomic_mutex);
3062 
3063  return res;
3064 #endif
3065 }
3066 
3073 dbus_int32_t
3075 {
3076 #if DBUS_USE_SYNC
3077  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3078 #else
3079  dbus_int32_t res;
3080 
3081  pthread_mutex_lock (&atomic_mutex);
3082  res = atomic->value;
3083  atomic->value -= 1;
3084  pthread_mutex_unlock (&atomic_mutex);
3085 
3086  return res;
3087 #endif
3088 }
3089 
3097 dbus_int32_t
3099 {
3100 #if DBUS_USE_SYNC
3101  __sync_synchronize ();
3102  return atomic->value;
3103 #else
3104  dbus_int32_t res;
3105 
3106  pthread_mutex_lock (&atomic_mutex);
3107  res = atomic->value;
3108  pthread_mutex_unlock (&atomic_mutex);
3109 
3110  return res;
3111 #endif
3112 }
3113 
3122 int
3124  int n_fds,
3125  int timeout_milliseconds)
3126 {
3127 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3128  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3129  if (timeout_milliseconds < -1)
3130  {
3131  timeout_milliseconds = -1;
3132  }
3133 
3134  return poll (fds,
3135  n_fds,
3136  timeout_milliseconds);
3137 #else /* ! HAVE_POLL */
3138  /* Emulate poll() in terms of select() */
3139  fd_set read_set, write_set, err_set;
3140  int max_fd = 0;
3141  int i;
3142  struct timeval tv;
3143  int ready;
3144 
3145  FD_ZERO (&read_set);
3146  FD_ZERO (&write_set);
3147  FD_ZERO (&err_set);
3148 
3149  for (i = 0; i < n_fds; i++)
3150  {
3151  DBusPollFD *fdp = &fds[i];
3152 
3153  if (fdp->events & _DBUS_POLLIN)
3154  FD_SET (fdp->fd, &read_set);
3155 
3156  if (fdp->events & _DBUS_POLLOUT)
3157  FD_SET (fdp->fd, &write_set);
3158 
3159  FD_SET (fdp->fd, &err_set);
3160 
3161  max_fd = MAX (max_fd, fdp->fd);
3162  }
3163 
3164  tv.tv_sec = timeout_milliseconds / 1000;
3165  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3166 
3167  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3168  timeout_milliseconds < 0 ? NULL : &tv);
3169 
3170  if (ready > 0)
3171  {
3172  for (i = 0; i < n_fds; i++)
3173  {
3174  DBusPollFD *fdp = &fds[i];
3175 
3176  fdp->revents = 0;
3177 
3178  if (FD_ISSET (fdp->fd, &read_set))
3179  fdp->revents |= _DBUS_POLLIN;
3180 
3181  if (FD_ISSET (fdp->fd, &write_set))
3182  fdp->revents |= _DBUS_POLLOUT;
3183 
3184  if (FD_ISSET (fdp->fd, &err_set))
3185  fdp->revents |= _DBUS_POLLERR;
3186  }
3187  }
3188 
3189  return ready;
3190 #endif
3191 }
3192 
3200 void
3202  long *tv_usec)
3203 {
3204 #ifdef HAVE_MONOTONIC_CLOCK
3205  struct timespec ts;
3206  clock_gettime (CLOCK_MONOTONIC, &ts);
3207 
3208  if (tv_sec)
3209  *tv_sec = ts.tv_sec;
3210  if (tv_usec)
3211  *tv_usec = ts.tv_nsec / 1000;
3212 #else
3213  struct timeval t;
3214 
3215  gettimeofday (&t, NULL);
3216 
3217  if (tv_sec)
3218  *tv_sec = t.tv_sec;
3219  if (tv_usec)
3220  *tv_usec = t.tv_usec;
3221 #endif
3222 }
3223 
3231 void
3232 _dbus_get_real_time (long *tv_sec,
3233  long *tv_usec)
3234 {
3235  struct timeval t;
3236 
3237  gettimeofday (&t, NULL);
3238 
3239  if (tv_sec)
3240  *tv_sec = t.tv_sec;
3241  if (tv_usec)
3242  *tv_usec = t.tv_usec;
3243 }
3244 
3255  DBusError *error)
3256 {
3257  const char *filename_c;
3258 
3259  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3260 
3261  filename_c = _dbus_string_get_const_data (filename);
3262 
3263  if (mkdir (filename_c, 0700) < 0)
3264  {
3265  if (errno == EEXIST)
3266  return TRUE;
3267 
3269  "Failed to create directory %s: %s\n",
3270  filename_c, _dbus_strerror (errno));
3271  return FALSE;
3272  }
3273  else
3274  return TRUE;
3275 }
3276 
3287  DBusError *error)
3288 {
3289  const char *filename_c;
3290 
3291  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3292 
3293  filename_c = _dbus_string_get_const_data (filename);
3294 
3295  if (mkdir (filename_c, 0700) < 0)
3296  {
3298  "Failed to create directory %s: %s\n",
3299  filename_c, _dbus_strerror (errno));
3300  return FALSE;
3301  }
3302  else
3303  return TRUE;
3304 }
3305 
3318  const DBusString *next_component)
3319 {
3320  dbus_bool_t dir_ends_in_slash;
3321  dbus_bool_t file_starts_with_slash;
3322 
3323  if (_dbus_string_get_length (dir) == 0 ||
3324  _dbus_string_get_length (next_component) == 0)
3325  return TRUE;
3326 
3327  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3328  _dbus_string_get_length (dir) - 1);
3329 
3330  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3331 
3332  if (dir_ends_in_slash && file_starts_with_slash)
3333  {
3334  _dbus_string_shorten (dir, 1);
3335  }
3336  else if (!(dir_ends_in_slash || file_starts_with_slash))
3337  {
3338  if (!_dbus_string_append_byte (dir, '/'))
3339  return FALSE;
3340  }
3341 
3342  return _dbus_string_copy (next_component, 0, dir,
3343  _dbus_string_get_length (dir));
3344 }
3345 
3347 #define NANOSECONDS_PER_SECOND 1000000000
3348 
3349 #define MICROSECONDS_PER_SECOND 1000000
3350 
3351 #define MILLISECONDS_PER_SECOND 1000
3352 
3353 #define NANOSECONDS_PER_MILLISECOND 1000000
3354 
3355 #define MICROSECONDS_PER_MILLISECOND 1000
3356 
3361 void
3362 _dbus_sleep_milliseconds (int milliseconds)
3363 {
3364 #ifdef HAVE_NANOSLEEP
3365  struct timespec req;
3366  struct timespec rem;
3367 
3368  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3369  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3370  rem.tv_sec = 0;
3371  rem.tv_nsec = 0;
3372 
3373  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3374  req = rem;
3375 #elif defined (HAVE_USLEEP)
3376  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3377 #else /* ! HAVE_USLEEP */
3378  sleep (MAX (milliseconds / 1000, 1));
3379 #endif
3380 }
3381 
3393  int n_bytes,
3394  DBusError *error)
3395 {
3396  int old_len;
3397  int fd;
3398  int result;
3399 
3400  old_len = _dbus_string_get_length (str);
3401  fd = -1;
3402 
3403  /* note, urandom on linux will fall back to pseudorandom */
3404  fd = open ("/dev/urandom", O_RDONLY);
3405 
3406  if (fd < 0)
3407  {
3408  dbus_set_error (error, _dbus_error_from_errno (errno),
3409  "Could not open /dev/urandom: %s",
3410  _dbus_strerror (errno));
3411  return FALSE;
3412  }
3413 
3414  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3415 
3416  result = _dbus_read (fd, str, n_bytes);
3417 
3418  if (result != n_bytes)
3419  {
3420  if (result < 0)
3421  dbus_set_error (error, _dbus_error_from_errno (errno),
3422  "Could not read /dev/urandom: %s",
3423  _dbus_strerror (errno));
3424  else
3426  "Short read from /dev/urandom");
3427 
3428  _dbus_close (fd, NULL);
3429  _dbus_string_set_length (str, old_len);
3430  return FALSE;
3431  }
3432 
3433  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3434  n_bytes);
3435 
3436  _dbus_close (fd, NULL);
3437 
3438  return TRUE;
3439 }
3440 
3446 void
3447 _dbus_exit (int code)
3448 {
3449  _exit (code);
3450 }
3451 
3460 const char*
3461 _dbus_strerror (int error_number)
3462 {
3463  const char *msg;
3464 
3465  msg = strerror (error_number);
3466  if (msg == NULL)
3467  msg = "unknown";
3468 
3469  return msg;
3470 }
3471 
3475 void
3477 {
3478  signal (SIGPIPE, SIG_IGN);
3479 }
3480 
3488 void
3490 {
3491  int val;
3492 
3493  val = fcntl (fd, F_GETFD, 0);
3494 
3495  if (val < 0)
3496  return;
3497 
3498  val |= FD_CLOEXEC;
3499 
3500  fcntl (fd, F_SETFD, val);
3501 }
3502 
3510 void
3512 {
3513  int val;
3514 
3515  val = fcntl (fd, F_GETFD, 0);
3516 
3517  if (val < 0)
3518  return;
3519 
3520  val &= ~FD_CLOEXEC;
3521 
3522  fcntl (fd, F_SETFD, val);
3523 }
3524 
3533 _dbus_close (int fd,
3534  DBusError *error)
3535 {
3536  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3537 
3538  again:
3539  if (close (fd) < 0)
3540  {
3541  if (errno == EINTR)
3542  goto again;
3543 
3544  dbus_set_error (error, _dbus_error_from_errno (errno),
3545  "Could not close fd %d", fd);
3546  return FALSE;
3547  }
3548 
3549  return TRUE;
3550 }
3551 
3560 int
3561 _dbus_dup(int fd,
3562  DBusError *error)
3563 {
3564  int new_fd;
3565 
3566 #ifdef F_DUPFD_CLOEXEC
3567  dbus_bool_t cloexec_done;
3568 
3569  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3570  cloexec_done = new_fd >= 0;
3571 
3572  if (new_fd < 0 && errno == EINVAL)
3573 #endif
3574  {
3575  new_fd = fcntl(fd, F_DUPFD, 3);
3576  }
3577 
3578  if (new_fd < 0) {
3579 
3580  dbus_set_error (error, _dbus_error_from_errno (errno),
3581  "Could not duplicate fd %d", fd);
3582  return -1;
3583  }
3584 
3585 #ifdef F_DUPFD_CLOEXEC
3586  if (!cloexec_done)
3587 #endif
3588  {
3590  }
3591 
3592  return new_fd;
3593 }
3594 
3604  DBusError *error)
3605 {
3606  return _dbus_set_fd_nonblocking (fd.fd, error);
3607 }
3608 
3609 static dbus_bool_t
3610 _dbus_set_fd_nonblocking (int fd,
3611  DBusError *error)
3612 {
3613  int val;
3614 
3615  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3616 
3617  val = fcntl (fd, F_GETFL, 0);
3618  if (val < 0)
3619  {
3620  dbus_set_error (error, _dbus_error_from_errno (errno),
3621  "Failed to get flags from file descriptor %d: %s",
3622  fd, _dbus_strerror (errno));
3623  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3624  _dbus_strerror (errno));
3625  return FALSE;
3626  }
3627 
3628  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3629  {
3630  dbus_set_error (error, _dbus_error_from_errno (errno),
3631  "Failed to set nonblocking flag of file descriptor %d: %s",
3632  fd, _dbus_strerror (errno));
3633  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3634  fd, _dbus_strerror (errno));
3635 
3636  return FALSE;
3637  }
3638 
3639  return TRUE;
3640 }
3641 
3647 void
3649 {
3650 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3651  void *bt[500];
3652  int bt_size;
3653  int i;
3654  char **syms;
3655 
3656  bt_size = backtrace (bt, 500);
3657 
3658  syms = backtrace_symbols (bt, bt_size);
3659 
3660  i = 0;
3661  while (i < bt_size)
3662  {
3663  /* don't use dbus_warn since it can _dbus_abort() */
3664  fprintf (stderr, " %s\n", syms[i]);
3665  ++i;
3666  }
3667  fflush (stderr);
3668 
3669  free (syms);
3670 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3671  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3672 #else
3673  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3674 #endif
3675 }
3676 
3691  DBusSocket *fd2,
3692  dbus_bool_t blocking,
3693  DBusError *error)
3694 {
3695 #ifdef HAVE_SOCKETPAIR
3696  int fds[2];
3697  int retval;
3698 
3699 #ifdef SOCK_CLOEXEC
3700  dbus_bool_t cloexec_done;
3701 
3702  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3703  cloexec_done = retval >= 0;
3704 
3705  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3706 #endif
3707  {
3708  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3709  }
3710 
3711  if (retval < 0)
3712  {
3713  dbus_set_error (error, _dbus_error_from_errno (errno),
3714  "Could not create full-duplex pipe");
3715  return FALSE;
3716  }
3717 
3718  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3719 
3720 #ifdef SOCK_CLOEXEC
3721  if (!cloexec_done)
3722 #endif
3723  {
3724  _dbus_fd_set_close_on_exec (fds[0]);
3725  _dbus_fd_set_close_on_exec (fds[1]);
3726  }
3727 
3728  if (!blocking &&
3729  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3730  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3731  {
3732  dbus_set_error (error, _dbus_error_from_errno (errno),
3733  "Could not set full-duplex pipe nonblocking");
3734 
3735  _dbus_close (fds[0], NULL);
3736  _dbus_close (fds[1], NULL);
3737 
3738  return FALSE;
3739  }
3740 
3741  fd1->fd = fds[0];
3742  fd2->fd = fds[1];
3743 
3744  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3745  fd1->fd, fd2->fd);
3746 
3747  return TRUE;
3748 #else
3749  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3751  "_dbus_socketpair() not implemented on this OS");
3752  return FALSE;
3753 #endif
3754 }
3755 
3764 int
3766  va_list args)
3767 {
3768  char static_buf[1024];
3769  int bufsize = sizeof (static_buf);
3770  int len;
3771  va_list args_copy;
3772 
3773  DBUS_VA_COPY (args_copy, args);
3774  len = vsnprintf (static_buf, bufsize, format, args_copy);
3775  va_end (args_copy);
3776 
3777  /* If vsnprintf() returned non-negative, then either the string fits in
3778  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3779  * returns the number of characters that were needed, or this OS returns the
3780  * truncated length.
3781  *
3782  * We ignore the possibility that snprintf might just ignore the length and
3783  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3784  * If your libc is really that bad, come back when you have a better one. */
3785  if (len == bufsize)
3786  {
3787  /* This could be the truncated length (Tru64 and IRIX have this bug),
3788  * or the real length could be coincidentally the same. Which is it?
3789  * If vsnprintf returns the truncated length, we'll go to the slow
3790  * path. */
3791  DBUS_VA_COPY (args_copy, args);
3792 
3793  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3794  len = -1;
3795 
3796  va_end (args_copy);
3797  }
3798 
3799  /* If vsnprintf() returned negative, we have to do more work.
3800  * HP-UX returns negative. */
3801  while (len < 0)
3802  {
3803  char *buf;
3804 
3805  bufsize *= 2;
3806 
3807  buf = dbus_malloc (bufsize);
3808 
3809  if (buf == NULL)
3810  return -1;
3811 
3812  DBUS_VA_COPY (args_copy, args);
3813  len = vsnprintf (buf, bufsize, format, args_copy);
3814  va_end (args_copy);
3815 
3816  dbus_free (buf);
3817 
3818  /* If the reported length is exactly the buffer size, round up to the
3819  * next size, in case vsnprintf has been returning the truncated
3820  * length */
3821  if (len == bufsize)
3822  len = -1;
3823  }
3824 
3825  return len;
3826 }
3827 
3834 const char*
3836 {
3837  /* Protected by _DBUS_LOCK_sysdeps */
3838  static const char* tmpdir = NULL;
3839 
3840  if (!_DBUS_LOCK (sysdeps))
3841  return NULL;
3842 
3843  if (tmpdir == NULL)
3844  {
3845  /* TMPDIR is what glibc uses, then
3846  * glibc falls back to the P_tmpdir macro which
3847  * just expands to "/tmp"
3848  */
3849  if (tmpdir == NULL)
3850  tmpdir = getenv("TMPDIR");
3851 
3852  /* These two env variables are probably
3853  * broken, but maybe some OS uses them?
3854  */
3855  if (tmpdir == NULL)
3856  tmpdir = getenv("TMP");
3857  if (tmpdir == NULL)
3858  tmpdir = getenv("TEMP");
3859 
3860  /* And this is the sane fallback. */
3861  if (tmpdir == NULL)
3862  tmpdir = "/tmp";
3863  }
3864 
3865  _DBUS_UNLOCK (sysdeps);
3866 
3867  _dbus_assert(tmpdir != NULL);
3868 
3869  return tmpdir;
3870 }
3871 
3872 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3873 
3892 static dbus_bool_t
3893 _read_subprocess_line_argv (const char *progpath,
3894  dbus_bool_t path_fallback,
3895  const char * const *argv,
3896  DBusString *result,
3897  DBusError *error)
3898 {
3899  int result_pipe[2] = { -1, -1 };
3900  int errors_pipe[2] = { -1, -1 };
3901  pid_t pid;
3902  int ret;
3903  int status;
3904  int orig_len;
3905 
3906  dbus_bool_t retval;
3907  sigset_t new_set, old_set;
3908 
3909  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3910  retval = FALSE;
3911 
3912  /* We need to block any existing handlers for SIGCHLD temporarily; they
3913  * will cause waitpid() below to fail.
3914  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3915  */
3916  sigemptyset (&new_set);
3917  sigaddset (&new_set, SIGCHLD);
3918  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3919 
3920  orig_len = _dbus_string_get_length (result);
3921 
3922 #define READ_END 0
3923 #define WRITE_END 1
3924  if (pipe (result_pipe) < 0)
3925  {
3926  dbus_set_error (error, _dbus_error_from_errno (errno),
3927  "Failed to create a pipe to call %s: %s",
3928  progpath, _dbus_strerror (errno));
3929  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3930  progpath, _dbus_strerror (errno));
3931  goto out;
3932  }
3933  if (pipe (errors_pipe) < 0)
3934  {
3935  dbus_set_error (error, _dbus_error_from_errno (errno),
3936  "Failed to create a pipe to call %s: %s",
3937  progpath, _dbus_strerror (errno));
3938  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3939  progpath, _dbus_strerror (errno));
3940  goto out;
3941  }
3942 
3943  /* Make sure our output buffers aren't redundantly printed by both the
3944  * parent and the child */
3945  fflush (stdout);
3946  fflush (stderr);
3947 
3948  pid = fork ();
3949  if (pid < 0)
3950  {
3951  dbus_set_error (error, _dbus_error_from_errno (errno),
3952  "Failed to fork() to call %s: %s",
3953  progpath, _dbus_strerror (errno));
3954  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3955  progpath, _dbus_strerror (errno));
3956  goto out;
3957  }
3958 
3959  if (pid == 0)
3960  {
3961  /* child process */
3962  const char *error_str;
3963 
3964  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3965  {
3966  int saved_errno = errno;
3967 
3968  /* Try to write details into the pipe, but don't bother
3969  * trying too hard (no retry loop). */
3970 
3971  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3972  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3973  {
3974  /* ignore, not much we can do */
3975  }
3976 
3977  error_str = _dbus_strerror (saved_errno);
3978 
3979  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3980  {
3981  /* ignore, not much we can do */
3982  }
3983 
3984  _exit (1);
3985  }
3986 
3987  /* set-up stdXXX */
3988  close (result_pipe[READ_END]);
3989  close (errors_pipe[READ_END]);
3990 
3991  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3992  _exit (1);
3993  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3994  _exit (1);
3995 
3996  _dbus_close_all ();
3997 
3998  sigprocmask (SIG_SETMASK, &old_set, NULL);
3999 
4000  /* If it looks fully-qualified, try execv first */
4001  if (progpath[0] == '/')
4002  {
4003  execv (progpath, (char * const *) argv);
4004  /* Ok, that failed. Now if path_fallback is given, let's
4005  * try unqualified. This is mostly a hack to work
4006  * around systems which ship dbus-launch in /usr/bin
4007  * but everything else in /bin (because dbus-launch
4008  * depends on X11).
4009  */
4010  if (path_fallback)
4011  /* We must have a slash, because we checked above */
4012  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4013  }
4014  else
4015  execvp (progpath, (char * const *) argv);
4016 
4017  /* still nothing, we failed */
4018  _exit (1);
4019  }
4020 
4021  /* parent process */
4022  close (result_pipe[WRITE_END]);
4023  close (errors_pipe[WRITE_END]);
4024  result_pipe[WRITE_END] = -1;
4025  errors_pipe[WRITE_END] = -1;
4026 
4027  ret = 0;
4028  do
4029  {
4030  ret = _dbus_read (result_pipe[READ_END], result, 1024);
4031  }
4032  while (ret > 0);
4033 
4034  /* reap the child process to avoid it lingering as zombie */
4035  do
4036  {
4037  ret = waitpid (pid, &status, 0);
4038  }
4039  while (ret == -1 && errno == EINTR);
4040 
4041  /* We succeeded if the process exited with status 0 and
4042  anything was read */
4043  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4044  {
4045  /* The process ended with error */
4046  DBusString error_message;
4047  if (!_dbus_string_init (&error_message))
4048  {
4049  _DBUS_SET_OOM (error);
4050  goto out;
4051  }
4052 
4053  ret = 0;
4054  do
4055  {
4056  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4057  }
4058  while (ret > 0);
4059 
4060  _dbus_string_set_length (result, orig_len);
4061  if (_dbus_string_get_length (&error_message) > 0)
4063  "%s terminated abnormally with the following error: %s",
4064  progpath, _dbus_string_get_data (&error_message));
4065  else
4067  "%s terminated abnormally without any error message",
4068  progpath);
4069  goto out;
4070  }
4071 
4072  retval = TRUE;
4073 
4074  out:
4075  sigprocmask (SIG_SETMASK, &old_set, NULL);
4076 
4077  _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4078 
4079  if (result_pipe[0] != -1)
4080  close (result_pipe[0]);
4081  if (result_pipe[1] != -1)
4082  close (result_pipe[1]);
4083  if (errors_pipe[0] != -1)
4084  close (errors_pipe[0]);
4085  if (errors_pipe[1] != -1)
4086  close (errors_pipe[1]);
4087 
4088  return retval;
4089 }
4090 #endif
4091 
4105 _dbus_get_autolaunch_address (const char *scope,
4106  DBusString *address,
4107  DBusError *error)
4108 {
4109 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4110  static const char arg_dbus_launch[] = "dbus-launch";
4111  static const char arg_autolaunch[] = "--autolaunch";
4112  static const char arg_binary_syntax[] = "--binary-syntax";
4113  static const char arg_close_stderr[] = "--close-stderr";
4114 
4115  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4116  * but that's done elsewhere, and if it worked, this function wouldn't
4117  * be called.) */
4118  const char *display;
4119  const char *progpath;
4120  const char *argv[6];
4121  int i;
4122  DBusString uuid;
4123  dbus_bool_t retval;
4124 
4125  if (_dbus_check_setuid ())
4126  {
4128  "Unable to autolaunch when setuid");
4129  return FALSE;
4130  }
4131 
4132  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4133  retval = FALSE;
4134 
4135  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4136  * dbus-launch-x11 is just going to fail. Rather than trying to
4137  * run it, we might as well bail out early with a nice error.
4138  *
4139  * This is not strictly true in a world where the user bus exists,
4140  * because dbus-launch --autolaunch knows how to connect to that -
4141  * but if we were going to connect to the user bus, we'd have done
4142  * so before trying autolaunch: in any case. */
4143  display = _dbus_getenv ("DISPLAY");
4144 
4145  if (display == NULL || display[0] == '\0')
4146  {
4148  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4149  return FALSE;
4150  }
4151 
4152  if (!_dbus_string_init (&uuid))
4153  {
4154  _DBUS_SET_OOM (error);
4155  return FALSE;
4156  }
4157 
4158  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4159  {
4160  goto out;
4161  }
4162 
4163 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4164  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4165 
4166  if (progpath == NULL)
4167 #endif
4168  progpath = DBUS_BINDIR "/dbus-launch";
4169  /*
4170  * argv[0] is always dbus-launch, that's the name what we'll
4171  * get from /proc, or ps(1), regardless what the progpath is,
4172  * see fd.o#69716
4173  */
4174  i = 0;
4175  argv[i] = arg_dbus_launch;
4176  ++i;
4177  argv[i] = arg_autolaunch;
4178  ++i;
4179  argv[i] = _dbus_string_get_data (&uuid);
4180  ++i;
4181  argv[i] = arg_binary_syntax;
4182  ++i;
4183  argv[i] = arg_close_stderr;
4184  ++i;
4185  argv[i] = NULL;
4186  ++i;
4187 
4188  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4189 
4190  retval = _read_subprocess_line_argv (progpath,
4191  TRUE,
4192  argv, address, error);
4193 
4194  out:
4195  _dbus_string_free (&uuid);
4196  return retval;
4197 #else
4199  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4200  "set your DBUS_SESSION_BUS_ADDRESS instead");
4201  return FALSE;
4202 #endif
4203 }
4204 
4225  dbus_bool_t create_if_not_found,
4226  DBusError *error)
4227 {
4228  DBusError our_error = DBUS_ERROR_INIT;
4229  DBusError etc_error = DBUS_ERROR_INIT;
4230  DBusString filename;
4231  dbus_bool_t b;
4232 
4233  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4234 
4235  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4236  if (b)
4237  return TRUE;
4238 
4239  /* Fallback to the system machine ID */
4240  _dbus_string_init_const (&filename, "/etc/machine-id");
4241  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4242 
4243  if (b)
4244  {
4245  if (create_if_not_found)
4246  {
4247  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4248  * complain if that isn't possible for whatever reason */
4249  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4250  _dbus_write_uuid_file (&filename, machine_id, NULL);
4251  }
4252 
4253  dbus_error_free (&our_error);
4254  return TRUE;
4255  }
4256 
4257  if (!create_if_not_found)
4258  {
4259  dbus_set_error (error, etc_error.name,
4260  "D-Bus library appears to be incorrectly set up: "
4261  "see the manual page for dbus-uuidgen to correct "
4262  "this issue. (%s; %s)",
4263  our_error.message, etc_error.message);
4264  dbus_error_free (&our_error);
4265  dbus_error_free (&etc_error);
4266  return FALSE;
4267  }
4268 
4269  dbus_error_free (&our_error);
4270  dbus_error_free (&etc_error);
4271 
4272  /* if none found, try to make a new one */
4273  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4274 
4275  if (!_dbus_generate_uuid (machine_id, error))
4276  return FALSE;
4277 
4278  return _dbus_write_uuid_file (&filename, machine_id, error);
4279 }
4280 
4290  const char *launchd_env_var,
4291  DBusError *error)
4292 {
4293 #ifdef DBUS_ENABLE_LAUNCHD
4294  char *argv[4];
4295  int i;
4296 
4297  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4298 
4299  if (_dbus_check_setuid ())
4300  {
4302  "Unable to find launchd socket when setuid");
4303  return FALSE;
4304  }
4305 
4306  i = 0;
4307  argv[i] = "launchctl";
4308  ++i;
4309  argv[i] = "getenv";
4310  ++i;
4311  argv[i] = (char*)launchd_env_var;
4312  ++i;
4313  argv[i] = NULL;
4314  ++i;
4315 
4316  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4317 
4318  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4319  {
4320  return FALSE;
4321  }
4322 
4323  /* no error, but no result either */
4324  if (_dbus_string_get_length(socket_path) == 0)
4325  {
4326  return FALSE;
4327  }
4328 
4329  /* strip the carriage-return */
4330  _dbus_string_shorten(socket_path, 1);
4331  return TRUE;
4332 #else /* DBUS_ENABLE_LAUNCHD */
4334  "can't lookup socket from launchd; launchd support not compiled in");
4335  return FALSE;
4336 #endif
4337 }
4338 
4339 #ifdef DBUS_ENABLE_LAUNCHD
4340 static dbus_bool_t
4341 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4342 {
4343  dbus_bool_t valid_socket;
4344  DBusString socket_path;
4345 
4346  if (_dbus_check_setuid ())
4347  {
4349  "Unable to find launchd socket when setuid");
4350  return FALSE;
4351  }
4352 
4353  if (!_dbus_string_init (&socket_path))
4354  {
4355  _DBUS_SET_OOM (error);
4356  return FALSE;
4357  }
4358 
4359  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4360 
4361  if (dbus_error_is_set(error))
4362  {
4363  _dbus_string_free(&socket_path);
4364  return FALSE;
4365  }
4366 
4367  if (!valid_socket)
4368  {
4369  dbus_set_error(error, "no socket path",
4370  "launchd did not provide a socket path, "
4371  "verify that org.freedesktop.dbus-session.plist is loaded!");
4372  _dbus_string_free(&socket_path);
4373  return FALSE;
4374  }
4375  if (!_dbus_string_append (address, "unix:path="))
4376  {
4377  _DBUS_SET_OOM (error);
4378  _dbus_string_free(&socket_path);
4379  return FALSE;
4380  }
4381  if (!_dbus_string_copy (&socket_path, 0, address,
4382  _dbus_string_get_length (address)))
4383  {
4384  _DBUS_SET_OOM (error);
4385  _dbus_string_free(&socket_path);
4386  return FALSE;
4387  }
4388 
4389  _dbus_string_free(&socket_path);
4390  return TRUE;
4391 }
4392 #endif
4393 
4395 _dbus_lookup_user_bus (dbus_bool_t *supported,
4396  DBusString *address,
4397  DBusError *error)
4398 {
4399  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4400  dbus_bool_t ret = FALSE;
4401  struct stat stbuf;
4402  DBusString user_bus_path;
4403 
4404  if (runtime_dir == NULL)
4405  {
4406  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4407  *supported = FALSE;
4408  return TRUE; /* Cannot use it, but not an error */
4409  }
4410 
4411  if (!_dbus_string_init (&user_bus_path))
4412  {
4413  _DBUS_SET_OOM (error);
4414  return FALSE;
4415  }
4416 
4417  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4418  {
4419  _DBUS_SET_OOM (error);
4420  goto out;
4421  }
4422 
4423  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4424  {
4425  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4426  _dbus_strerror (errno));
4427  *supported = FALSE;
4428  ret = TRUE; /* Cannot use it, but not an error */
4429  goto out;
4430  }
4431 
4432  if (stbuf.st_uid != getuid ())
4433  {
4434  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4435  (long) stbuf.st_uid, (long) getuid ());
4436  *supported = FALSE;
4437  ret = TRUE; /* Cannot use it, but not an error */
4438  goto out;
4439  }
4440 
4441  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4442  {
4443  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4444  (long) stbuf.st_mode);
4445  *supported = FALSE;
4446  ret = TRUE; /* Cannot use it, but not an error */
4447  goto out;
4448  }
4449 
4450  if (!_dbus_string_append (address, "unix:path=") ||
4451  !_dbus_address_append_escaped (address, &user_bus_path))
4452  {
4453  _DBUS_SET_OOM (error);
4454  goto out;
4455  }
4456 
4457  *supported = TRUE;
4458  ret = TRUE;
4459 
4460 out:
4461  _dbus_string_free (&user_bus_path);
4462  return ret;
4463 }
4464 
4486  DBusString *address,
4487  DBusError *error)
4488 {
4489 #ifdef DBUS_ENABLE_LAUNCHD
4490  *supported = TRUE;
4491  return _dbus_lookup_session_address_launchd (address, error);
4492 #else
4493  *supported = FALSE;
4494 
4495  if (!_dbus_lookup_user_bus (supported, address, error))
4496  return FALSE;
4497  else if (*supported)
4498  return TRUE;
4499 
4500  /* On non-Mac Unix platforms, if the session address isn't already
4501  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4502  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4503  * autolaunch: global default; see init_session_address in
4504  * dbus/dbus-bus.c. */
4505  return TRUE;
4506 #endif
4507 }
4508 
4516 void
4518 {
4520 }
4521 
4537  DBusCredentials *credentials)
4538 {
4539  DBusString homedir;
4540  DBusString dotdir;
4541  dbus_uid_t uid;
4542 
4543  _dbus_assert (credentials != NULL);
4545 
4546  if (!_dbus_string_init (&homedir))
4547  return FALSE;
4548 
4549  uid = _dbus_credentials_get_unix_uid (credentials);
4550  _dbus_assert (uid != DBUS_UID_UNSET);
4551 
4552  if (!_dbus_homedir_from_uid (uid, &homedir))
4553  goto failed;
4554 
4555 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4556  {
4557  const char *override;
4558 
4559  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4560  if (override != NULL && *override != '\0')
4561  {
4562  _dbus_string_set_length (&homedir, 0);
4563  if (!_dbus_string_append (&homedir, override))
4564  goto failed;
4565 
4566  _dbus_verbose ("Using fake homedir for testing: %s\n",
4567  _dbus_string_get_const_data (&homedir));
4568  }
4569  else
4570  {
4571  /* Not strictly thread-safe, but if we fail at thread-safety here,
4572  * the worst that will happen is some extra warnings. */
4573  static dbus_bool_t already_warned = FALSE;
4574  if (!already_warned)
4575  {
4576  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4577  _dbus_string_get_const_data (&homedir));
4578  already_warned = TRUE;
4579  }
4580  }
4581  }
4582 #endif
4583 
4584  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4585  if (!_dbus_concat_dir_and_file (&homedir,
4586  &dotdir))
4587  goto failed;
4588 
4589  if (!_dbus_string_copy (&homedir, 0,
4590  directory, _dbus_string_get_length (directory))) {
4591  goto failed;
4592  }
4593 
4594  _dbus_string_free (&homedir);
4595  return TRUE;
4596 
4597  failed:
4598  _dbus_string_free (&homedir);
4599  return FALSE;
4600 }
4601 
4602 //PENDING(kdab) docs
4604 _dbus_daemon_publish_session_bus_address (const char* addr,
4605  const char *scope)
4606 {
4607  return TRUE;
4608 }
4609 
4610 //PENDING(kdab) docs
4611 void
4612 _dbus_daemon_unpublish_session_bus_address (void)
4613 {
4614 
4615 }
4616 
4625 {
4626  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4627  * EWOULDBLOCK are numerically equal, which is permitted as described by
4628  * errno(3).
4629  */
4630 #if EAGAIN == EWOULDBLOCK
4631  return e == EAGAIN;
4632 #else
4633  return e == EAGAIN || e == EWOULDBLOCK;
4634 #endif
4635 }
4636 
4646  DBusError *error)
4647 {
4648  const char *filename_c;
4649 
4650  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4651 
4652  filename_c = _dbus_string_get_const_data (filename);
4653 
4654  if (rmdir (filename_c) != 0)
4655  {
4657  "Failed to remove directory %s: %s\n",
4658  filename_c, _dbus_strerror (errno));
4659  return FALSE;
4660  }
4661 
4662  return TRUE;
4663 }
4664 
4674 {
4675 #ifdef SCM_RIGHTS
4676  union {
4677  struct sockaddr sa;
4678  struct sockaddr_storage storage;
4679  struct sockaddr_un un;
4680  } sa_buf;
4681 
4682  socklen_t sa_len = sizeof(sa_buf);
4683 
4684  _DBUS_ZERO(sa_buf);
4685 
4686  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4687  return FALSE;
4688 
4689  return sa_buf.sa.sa_family == AF_UNIX;
4690 
4691 #else
4692  return FALSE;
4693 
4694 #endif
4695 }
4696 
4697 static void
4698 close_ignore_error (int fd)
4699 {
4700  close (fd);
4701 }
4702 
4703 /*
4704  * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4705  * and may call func for integers that are not actually valid fds.
4706  */
4707 static void
4708 act_on_fds_3_and_up (void (*func) (int fd))
4709 {
4710  int maxfds, i;
4711 
4712 #ifdef __linux__
4713  DIR *d;
4714 
4715  /* On Linux we can optimize this a bit if /proc is available. If it
4716  isn't available, fall back to the brute force way. */
4717 
4718  d = opendir ("/proc/self/fd");
4719  if (d)
4720  {
4721  for (;;)
4722  {
4723  struct dirent *de;
4724  int fd;
4725  long l;
4726  char *e = NULL;
4727 
4728  de = readdir (d);
4729  if (!de)
4730  break;
4731 
4732  if (de->d_name[0] == '.')
4733  continue;
4734 
4735  errno = 0;
4736  l = strtol (de->d_name, &e, 10);
4737  if (errno != 0 || e == NULL || *e != '\0')
4738  continue;
4739 
4740  fd = (int) l;
4741  if (fd < 3)
4742  continue;
4743 
4744  if (fd == dirfd (d))
4745  continue;
4746 
4747  func (fd);
4748  }
4749 
4750  closedir (d);
4751  return;
4752  }
4753 #endif
4754 
4755  maxfds = sysconf (_SC_OPEN_MAX);
4756 
4757  /* Pick something reasonable if for some reason sysconf says
4758  * unlimited.
4759  */
4760  if (maxfds < 0)
4761  maxfds = 1024;
4762 
4763  /* close all inherited fds */
4764  for (i = 3; i < maxfds; i++)
4765  func (i);
4766 }
4767 
4772 void
4774 {
4775  act_on_fds_3_and_up (close_ignore_error);
4776 }
4777 
4782 void
4784 {
4785  act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4786 }
4787 
4799 {
4800  /* TODO: get __libc_enable_secure exported from glibc.
4801  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4802  */
4803 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4804  {
4805  /* See glibc/include/unistd.h */
4806  extern int __libc_enable_secure;
4807  return __libc_enable_secure;
4808  }
4809 #elif defined(HAVE_ISSETUGID)
4810  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4811  return issetugid ();
4812 #else
4813  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4814  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4815 
4816  /* We call into this function from _dbus_threads_init_platform_specific()
4817  * to make sure these are initialized before we start threading. */
4818  static dbus_bool_t check_setuid_initialised;
4819  static dbus_bool_t is_setuid;
4820 
4821  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4822  {
4823 #ifdef HAVE_GETRESUID
4824  if (getresuid (&ruid, &euid, &suid) != 0 ||
4825  getresgid (&rgid, &egid, &sgid) != 0)
4826 #endif /* HAVE_GETRESUID */
4827  {
4828  suid = ruid = getuid ();
4829  sgid = rgid = getgid ();
4830  euid = geteuid ();
4831  egid = getegid ();
4832  }
4833 
4834  check_setuid_initialised = TRUE;
4835  is_setuid = (ruid != euid || ruid != suid ||
4836  rgid != egid || rgid != sgid);
4837 
4838  }
4839  return is_setuid;
4840 #endif
4841 }
4842 
4852  DBusString *address,
4853  DBusError *error)
4854 {
4855  union {
4856  struct sockaddr sa;
4857  struct sockaddr_storage storage;
4858  struct sockaddr_un un;
4859  struct sockaddr_in ipv4;
4860  struct sockaddr_in6 ipv6;
4861  } socket;
4862  char hostip[INET6_ADDRSTRLEN];
4863  socklen_t size = sizeof (socket);
4864  DBusString path_str;
4865  const char *family_name = NULL;
4866  dbus_uint16_t port;
4867 
4868  if (getsockname (fd.fd, &socket.sa, &size))
4869  goto err;
4870 
4871  switch (socket.sa.sa_family)
4872  {
4873  case AF_UNIX:
4874  if (socket.un.sun_path[0]=='\0')
4875  {
4876  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4877  if (_dbus_string_append (address, "unix:abstract=") &&
4878  _dbus_address_append_escaped (address, &path_str))
4879  {
4880  return TRUE;
4881  }
4882  else
4883  {
4884  _DBUS_SET_OOM (error);
4885  return FALSE;
4886  }
4887  }
4888  else
4889  {
4890  _dbus_string_init_const (&path_str, socket.un.sun_path);
4891  if (_dbus_string_append (address, "unix:path=") &&
4892  _dbus_address_append_escaped (address, &path_str))
4893  {
4894  return TRUE;
4895  }
4896  else
4897  {
4898  _DBUS_SET_OOM (error);
4899  return FALSE;
4900  }
4901  }
4902  /* not reached */
4903  break;
4904 
4905  case AF_INET:
4906 #ifdef AF_INET6
4907  case AF_INET6:
4908 #endif
4909  _dbus_string_init_const (&path_str, hostip);
4910 
4911  if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
4912  &family_name, &port, error))
4913  {
4914  if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
4915  family_name, port) &&
4916  _dbus_address_append_escaped (address, &path_str))
4917  {
4918  return TRUE;
4919  }
4920  else
4921  {
4922  _DBUS_SET_OOM (error);
4923  return FALSE;
4924  }
4925  }
4926  else
4927  {
4928  return FALSE;
4929  }
4930  /* not reached */
4931  break;
4932 
4933  default:
4934  dbus_set_error (error,
4935  _dbus_error_from_errno (EINVAL),
4936  "Failed to read address from socket: Unknown socket type.");
4937  return FALSE;
4938  }
4939  err:
4940  dbus_set_error (error,
4941  _dbus_error_from_errno (errno),
4942  "Failed to read address from socket: %s",
4943  _dbus_strerror (errno));
4944  return FALSE;
4945 }
4946 
4947 int
4948 _dbus_save_socket_errno (void)
4949 {
4950  return errno;
4951 }
4952 
4953 void
4954 _dbus_restore_socket_errno (int saved_errno)
4955 {
4956  errno = saved_errno;
4957 }
4958 
4959 static const char *syslog_tag = "dbus";
4960 #ifdef HAVE_SYSLOG_H
4961 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4962 #endif
4963 
4978 void
4979 _dbus_init_system_log (const char *tag,
4980  DBusLogFlags flags)
4981 {
4982  /* We never want to turn off logging completely */
4983  _dbus_assert (
4984  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4985 
4986  syslog_tag = tag;
4987 
4988 #ifdef HAVE_SYSLOG_H
4989  log_flags = flags;
4990 
4991  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4992  openlog (tag, LOG_PID, LOG_DAEMON);
4993 #endif
4994 }
4995 
5003 void
5004 _dbus_logv (DBusSystemLogSeverity severity,
5005  const char *msg,
5006  va_list args)
5007 {
5008  va_list tmp;
5009 #ifdef HAVE_SYSLOG_H
5010  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5011  {
5012  int flags;
5013  switch (severity)
5014  {
5015  case DBUS_SYSTEM_LOG_INFO:
5016  flags = LOG_DAEMON | LOG_INFO;
5017  break;
5018  case DBUS_SYSTEM_LOG_WARNING:
5019  flags = LOG_DAEMON | LOG_WARNING;
5020  break;
5021  case DBUS_SYSTEM_LOG_SECURITY:
5022  flags = LOG_AUTH | LOG_NOTICE;
5023  break;
5024  case DBUS_SYSTEM_LOG_ERROR:
5025  flags = LOG_DAEMON|LOG_CRIT;
5026  break;
5027  default:
5028  _dbus_assert_not_reached ("invalid log severity");
5029  }
5030 
5031  DBUS_VA_COPY (tmp, args);
5032  vsyslog (flags, msg, tmp);
5033  va_end (tmp);
5034  }
5035 
5036  /* If we don't have syslog.h, we always behave as though stderr was in
5037  * the flags */
5038  if (log_flags & DBUS_LOG_FLAGS_STDERR)
5039 #endif
5040  {
5041  DBUS_VA_COPY (tmp, args);
5042  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5043  vfprintf (stderr, msg, tmp);
5044  fputc ('\n', stderr);
5045  va_end (tmp);
5046  }
5047 }
5048 
5049 /*
5050  * Return the low-level representation of a socket error, as used by
5051  * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5052  * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5053  *
5054  * Some libdbus internal functions copy this into errno, but with
5055  * hindsight that was probably a design flaw.
5056  */
5057 int
5058 _dbus_get_low_level_socket_errno (void)
5059 {
5060  return errno;
5061 }
5062 
5063 /* 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:952
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:444
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:323
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:401
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:328
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:777
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:703
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:150
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:146
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:356
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:422
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:507
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:797
short events
Events to poll for.
Definition: dbus-sysdeps.h:417
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:1300
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:139
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:141
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:599
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:468
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:132
Socket interface.
Definition: dbus-sysdeps.h:178
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:463
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...
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
void _dbus_fd_clear_close_on_exec(int fd)
Sets the file descriptor to not be close-on-exec.
void _dbus_credentials_take_unix_gids(DBusCredentials *credentials, dbus_gid_t *gids, size_t n_gids)
Add UNIX group IDs to the credentials, replacing any group IDs that might already have been present...
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:426
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_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
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:1131
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:105
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
#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:1174
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:143
void _dbus_fd_set_all_close_on_exec(void)
Sets all file descriptors except the first three (i.e.
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the most important credentials of the current process (the uid and pid) to the passed-in credent...
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:416
#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.
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:148
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
void _dbus_exit(int code)
Exit the process, returning the given value.
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
A node in a linked list.
Definition: dbus-list.h:34
dbus_uid_t _dbus_getuid(void)
Gets our UID.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
#define _DBUS_INT32_MAX
Maximum value of type "int32".
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:819
#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.
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:136
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:603
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.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, const char **retfamily, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
#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:195
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:134
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:418
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:428