D-Bus  1.13.16
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_BACKTRACE
72 #include <execinfo.h>
73 #endif
74 #ifdef HAVE_GETPEERUCRED
75 #include <ucred.h>
76 #endif
77 #ifdef HAVE_ALLOCA_H
78 #include <alloca.h>
79 #endif
80 #ifdef HAVE_SYS_RANDOM_H
81 #include <sys/random.h>
82 #endif
83 
84 #ifdef HAVE_ADT
85 #include <bsm/adt.h>
86 #endif
87 
88 #ifdef HAVE_SYSTEMD
89 #include <systemd/sd-daemon.h>
90 #endif
91 
92 #if !DBUS_USE_SYNC
93 #include <pthread.h>
94 #endif
95 
96 #ifndef O_BINARY
97 #define O_BINARY 0
98 #endif
99 
100 #ifndef AI_ADDRCONFIG
101 #define AI_ADDRCONFIG 0
102 #endif
103 
104 #ifndef HAVE_SOCKLEN_T
105 #define socklen_t int
106 #endif
107 
108 #if defined (__sun) || defined (__sun__)
109 /*
110  * CMS_SPACE etc. definitions for Solaris < 10, based on
111  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
112  * via
113  * http://wiki.opencsw.org/porting-faq#toc10
114  *
115  * These are only redefined for Solaris, for now: if your OS needs these too,
116  * please file a bug. (Or preferably, improve your OS so they're not needed.)
117  */
118 
119 # ifndef CMSG_ALIGN
120 # ifdef __sun__
121 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
122 # else
123  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
124 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
125  ~(sizeof (long) - 1))
126 # endif
127 # endif
128 
129 # ifndef CMSG_SPACE
130 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
131  CMSG_ALIGN (len))
132 # endif
133 
134 # ifndef CMSG_LEN
135 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
136 # endif
137 
138 #endif /* Solaris */
139 
155 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
156  const char **error_str_p)
157 {
158  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
159  DBUS_FORCE_STDOUT_NULL,
160  DBUS_FORCE_STDERR_NULL };
161  /* Should always get replaced with the real error before use */
162  const char *error_str = "Failed mysteriously";
163  int devnull = -1;
164  int saved_errno;
165  /* This function relies on the standard fds having their POSIX values. */
166  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
167  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
168  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
169  int i;
170 
171  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
172  {
173  /* Because we rely on being single-threaded, and we want the
174  * standard fds to not be close-on-exec, we don't set it
175  * close-on-exec. */
176  if (devnull < i)
177  devnull = open ("/dev/null", O_RDWR);
178 
179  if (devnull < 0)
180  {
181  error_str = "Failed to open /dev/null";
182  goto out;
183  }
184 
185  /* We already opened all fds < i, so the only way this assertion
186  * could fail is if another thread closed one, and we document
187  * this function as not safe for multi-threading. */
188  _dbus_assert (devnull >= i);
189 
190  if (devnull != i && (flags & relevant_flag[i]) != 0)
191  {
192  if (dup2 (devnull, i) < 0)
193  {
194  error_str = "Failed to dup2 /dev/null onto a standard fd";
195  goto out;
196  }
197  }
198  }
199 
200  error_str = NULL;
201 
202 out:
203  saved_errno = errno;
204 
205  if (devnull > STDERR_FILENO)
206  close (devnull);
207 
208  if (error_str_p != NULL)
209  *error_str_p = error_str;
210 
211  errno = saved_errno;
212  return (error_str == NULL);
213 }
214 
215 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
216  DBusError *error);
217 
218 static dbus_bool_t
219 _dbus_open_socket (int *fd_p,
220  int domain,
221  int type,
222  int protocol,
223  DBusError *error)
224 {
225 #ifdef SOCK_CLOEXEC
226  dbus_bool_t cloexec_done;
227 
228  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
229  cloexec_done = *fd_p >= 0;
230 
231  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
232  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
233 #endif
234  {
235  *fd_p = socket (domain, type, protocol);
236  }
237 
238  if (*fd_p >= 0)
239  {
240 #ifdef SOCK_CLOEXEC
241  if (!cloexec_done)
242 #endif
243  {
245  }
246 
247  _dbus_verbose ("socket fd %d opened\n", *fd_p);
248  return TRUE;
249  }
250  else
251  {
252  dbus_set_error(error,
253  _dbus_error_from_errno (errno),
254  "Failed to open socket: %s",
255  _dbus_strerror (errno));
256  return FALSE;
257  }
258 }
259 
270 static dbus_bool_t
271 _dbus_open_unix_socket (int *fd,
272  DBusError *error)
273 {
274  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
275 }
276 
287  DBusError *error)
288 {
289  return _dbus_close (fd.fd, error);
290 }
291 
301 int
303  DBusString *buffer,
304  int count)
305 {
306  return _dbus_read (fd.fd, buffer, count);
307 }
308 
319 int
321  const DBusString *buffer,
322  int start,
323  int len)
324 {
325 #if HAVE_DECL_MSG_NOSIGNAL
326  const char *data;
327  int bytes_written;
328 
329  data = _dbus_string_get_const_data_len (buffer, start, len);
330 
331  again:
332 
333  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
334 
335  if (bytes_written < 0 && errno == EINTR)
336  goto again;
337 
338  return bytes_written;
339 
340 #else
341  return _dbus_write (fd.fd, buffer, start, len);
342 #endif
343 }
344 
357 int
359  DBusString *buffer,
360  int count,
361  int *fds,
362  unsigned int *n_fds) {
363 #ifndef HAVE_UNIX_FD_PASSING
364  int r;
365 
366  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
367  return r;
368 
369  *n_fds = 0;
370  return r;
371 
372 #else
373  int bytes_read;
374  int start;
375  struct msghdr m;
376  struct iovec iov;
377 
378  _dbus_assert (count >= 0);
380 
381  start = _dbus_string_get_length (buffer);
382 
383  if (!_dbus_string_lengthen (buffer, count))
384  {
385  errno = ENOMEM;
386  return -1;
387  }
388 
389  _DBUS_ZERO(iov);
390  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
391  iov.iov_len = count;
392 
393  _DBUS_ZERO(m);
394  m.msg_iov = &iov;
395  m.msg_iovlen = 1;
396 
397  /* Hmm, we have no clue how long the control data will actually be
398  that is queued for us. The least we can do is assume that the
399  caller knows. Hence let's make space for the number of fds that
400  we shall read at max plus the cmsg header. */
401  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
402 
403  /* It's probably safe to assume that systems with SCM_RIGHTS also
404  know alloca() */
405  m.msg_control = alloca(m.msg_controllen);
406  memset(m.msg_control, 0, m.msg_controllen);
407 
408  /* Do not include the padding at the end when we tell the kernel
409  * how much we're willing to receive. This avoids getting
410  * the padding filled with additional fds that we weren't expecting,
411  * if a (potentially malicious) sender included them. (fd.o #83622) */
412  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
413 
414  again:
415 
416  bytes_read = recvmsg (fd.fd, &m, 0
417 #ifdef MSG_CMSG_CLOEXEC
418  |MSG_CMSG_CLOEXEC
419 #endif
420  );
421 
422  if (bytes_read < 0)
423  {
424  if (errno == EINTR)
425  goto again;
426  else
427  {
428  /* put length back (note that this doesn't actually realloc anything) */
429  _dbus_string_set_length (buffer, start);
430  return -1;
431  }
432  }
433  else
434  {
435  struct cmsghdr *cm;
436  dbus_bool_t found = FALSE;
437 
438  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
439  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
440  {
441  size_t i;
442  int *payload = (int *) CMSG_DATA (cm);
443  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
444  size_t payload_len_fds = payload_len_bytes / sizeof (int);
445  size_t fds_to_use;
446 
447  /* Every unsigned int fits in a size_t without truncation, so
448  * casting (size_t) *n_fds is OK */
449  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
450 
451  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
452  {
453  /* The fds in the payload will fit in our buffer */
454  fds_to_use = payload_len_fds;
455  }
456  else
457  {
458  /* Too many fds in the payload. This shouldn't happen
459  * any more because we're setting m.msg_controllen to
460  * the exact number we can accept, but be safe and
461  * truncate. */
462  fds_to_use = (size_t) *n_fds;
463 
464  /* Close the excess fds to avoid DoS: if they stayed open,
465  * someone could send us an extra fd per message
466  * and we'd eventually run out. */
467  for (i = fds_to_use; i < payload_len_fds; i++)
468  {
469  close (payload[i]);
470  }
471  }
472 
473  memcpy (fds, payload, fds_to_use * sizeof (int));
474  found = TRUE;
475  /* This narrowing cast from size_t to unsigned int cannot
476  * overflow because we have chosen fds_to_use
477  * to be <= *n_fds */
478  *n_fds = (unsigned int) fds_to_use;
479 
480  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
481  worked, hence we need to go through this list and set
482  CLOEXEC everywhere in any case */
483  for (i = 0; i < fds_to_use; i++)
485 
486  break;
487  }
488 
489  if (!found)
490  *n_fds = 0;
491 
492  if (m.msg_flags & MSG_CTRUNC)
493  {
494  unsigned int i;
495 
496  /* Hmm, apparently the control data was truncated. The bad
497  thing is that we might have completely lost a couple of fds
498  without chance to recover them. Hence let's treat this as a
499  serious error. */
500 
501  /* We still need to close whatever fds we *did* receive,
502  * otherwise they'll never get closed. (CVE-2020-12049) */
503  for (i = 0; i < *n_fds; i++)
504  close (fds[i]);
505 
506  *n_fds = 0;
507  errno = ENOSPC;
508  _dbus_string_set_length (buffer, start);
509  return -1;
510  }
511 
512  /* put length back (doesn't actually realloc) */
513  _dbus_string_set_length (buffer, start + bytes_read);
514 
515 #if 0
516  if (bytes_read > 0)
517  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
518 #endif
519 
520  return bytes_read;
521  }
522 #endif
523 }
524 
525 int
526 _dbus_write_socket_with_unix_fds(DBusSocket fd,
527  const DBusString *buffer,
528  int start,
529  int len,
530  const int *fds,
531  int n_fds) {
532 
533 #ifndef HAVE_UNIX_FD_PASSING
534 
535  if (n_fds > 0) {
536  errno = ENOTSUP;
537  return -1;
538  }
539 
540  return _dbus_write_socket(fd, buffer, start, len);
541 #else
542  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
543 #endif
544 }
545 
546 int
547 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
548  const DBusString *buffer1,
549  int start1,
550  int len1,
551  const DBusString *buffer2,
552  int start2,
553  int len2,
554  const int *fds,
555  int n_fds) {
556 
557 #ifndef HAVE_UNIX_FD_PASSING
558 
559  if (n_fds > 0) {
560  errno = ENOTSUP;
561  return -1;
562  }
563 
564  return _dbus_write_socket_two(fd,
565  buffer1, start1, len1,
566  buffer2, start2, len2);
567 #else
568 
569  struct msghdr m;
570  struct cmsghdr *cm;
571  struct iovec iov[2];
572  int bytes_written;
573 
574  _dbus_assert (len1 >= 0);
575  _dbus_assert (len2 >= 0);
576  _dbus_assert (n_fds >= 0);
577 
578  _DBUS_ZERO(iov);
579  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
580  iov[0].iov_len = len1;
581 
582  if (buffer2)
583  {
584  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
585  iov[1].iov_len = len2;
586  }
587 
588  _DBUS_ZERO(m);
589  m.msg_iov = iov;
590  m.msg_iovlen = buffer2 ? 2 : 1;
591 
592  if (n_fds > 0)
593  {
594  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
595  m.msg_control = alloca(m.msg_controllen);
596  memset(m.msg_control, 0, m.msg_controllen);
597 
598  cm = CMSG_FIRSTHDR(&m);
599  cm->cmsg_level = SOL_SOCKET;
600  cm->cmsg_type = SCM_RIGHTS;
601  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
602  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
603  }
604 
605  again:
606 
607  bytes_written = sendmsg (fd.fd, &m, 0
608 #if HAVE_DECL_MSG_NOSIGNAL
609  |MSG_NOSIGNAL
610 #endif
611  );
612 
613  if (bytes_written < 0 && errno == EINTR)
614  goto again;
615 
616 #if 0
617  if (bytes_written > 0)
618  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
619 #endif
620 
621  return bytes_written;
622 #endif
623 }
624 
638 int
640  const DBusString *buffer1,
641  int start1,
642  int len1,
643  const DBusString *buffer2,
644  int start2,
645  int len2)
646 {
647 #if HAVE_DECL_MSG_NOSIGNAL
648  struct iovec vectors[2];
649  const char *data1;
650  const char *data2;
651  int bytes_written;
652  struct msghdr m;
653 
654  _dbus_assert (buffer1 != NULL);
655  _dbus_assert (start1 >= 0);
656  _dbus_assert (start2 >= 0);
657  _dbus_assert (len1 >= 0);
658  _dbus_assert (len2 >= 0);
659 
660  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
661 
662  if (buffer2 != NULL)
663  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
664  else
665  {
666  data2 = NULL;
667  start2 = 0;
668  len2 = 0;
669  }
670 
671  vectors[0].iov_base = (char*) data1;
672  vectors[0].iov_len = len1;
673  vectors[1].iov_base = (char*) data2;
674  vectors[1].iov_len = len2;
675 
676  _DBUS_ZERO(m);
677  m.msg_iov = vectors;
678  m.msg_iovlen = data2 ? 2 : 1;
679 
680  again:
681 
682  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
683 
684  if (bytes_written < 0 && errno == EINTR)
685  goto again;
686 
687  return bytes_written;
688 
689 #else
690  return _dbus_write_two (fd.fd, buffer1, start1, len1,
691  buffer2, start2, len2);
692 #endif
693 }
694 
711 int
712 _dbus_read (int fd,
713  DBusString *buffer,
714  int count)
715 {
716  int bytes_read;
717  int start;
718  char *data;
719 
720  _dbus_assert (count >= 0);
721 
722  start = _dbus_string_get_length (buffer);
723 
724  if (!_dbus_string_lengthen (buffer, count))
725  {
726  errno = ENOMEM;
727  return -1;
728  }
729 
730  data = _dbus_string_get_data_len (buffer, start, count);
731 
732  again:
733 
734  bytes_read = read (fd, data, count);
735 
736  if (bytes_read < 0)
737  {
738  if (errno == EINTR)
739  goto again;
740  else
741  {
742  /* put length back (note that this doesn't actually realloc anything) */
743  _dbus_string_set_length (buffer, start);
744  return -1;
745  }
746  }
747  else
748  {
749  /* put length back (doesn't actually realloc) */
750  _dbus_string_set_length (buffer, start + bytes_read);
751 
752 #if 0
753  if (bytes_read > 0)
754  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
755 #endif
756 
757  return bytes_read;
758  }
759 }
760 
771 int
772 _dbus_write (int fd,
773  const DBusString *buffer,
774  int start,
775  int len)
776 {
777  const char *data;
778  int bytes_written;
779 
780  data = _dbus_string_get_const_data_len (buffer, start, len);
781 
782  again:
783 
784  bytes_written = write (fd, data, len);
785 
786  if (bytes_written < 0 && errno == EINTR)
787  goto again;
788 
789 #if 0
790  if (bytes_written > 0)
791  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
792 #endif
793 
794  return bytes_written;
795 }
796 
817 int
819  const DBusString *buffer1,
820  int start1,
821  int len1,
822  const DBusString *buffer2,
823  int start2,
824  int len2)
825 {
826  _dbus_assert (buffer1 != NULL);
827  _dbus_assert (start1 >= 0);
828  _dbus_assert (start2 >= 0);
829  _dbus_assert (len1 >= 0);
830  _dbus_assert (len2 >= 0);
831 
832 #ifdef HAVE_WRITEV
833  {
834  struct iovec vectors[2];
835  const char *data1;
836  const char *data2;
837  int bytes_written;
838 
839  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
840 
841  if (buffer2 != NULL)
842  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
843  else
844  {
845  data2 = NULL;
846  start2 = 0;
847  len2 = 0;
848  }
849 
850  vectors[0].iov_base = (char*) data1;
851  vectors[0].iov_len = len1;
852  vectors[1].iov_base = (char*) data2;
853  vectors[1].iov_len = len2;
854 
855  again:
856 
857  bytes_written = writev (fd,
858  vectors,
859  data2 ? 2 : 1);
860 
861  if (bytes_written < 0 && errno == EINTR)
862  goto again;
863 
864  return bytes_written;
865  }
866 #else /* HAVE_WRITEV */
867  {
868  int ret1, ret2;
869 
870  ret1 = _dbus_write (fd, buffer1, start1, len1);
871  if (ret1 == len1 && buffer2 != NULL)
872  {
873  ret2 = _dbus_write (fd, buffer2, start2, len2);
874  if (ret2 < 0)
875  ret2 = 0; /* we can't report an error as the first write was OK */
876 
877  return ret1 + ret2;
878  }
879  else
880  return ret1;
881  }
882 #endif /* !HAVE_WRITEV */
883 }
884 
885 #define _DBUS_MAX_SUN_PATH_LENGTH 99
886 
916 int
917 _dbus_connect_unix_socket (const char *path,
918  dbus_bool_t abstract,
919  DBusError *error)
920 {
921  int fd;
922  size_t path_len;
923  struct sockaddr_un addr;
924  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
925 
926  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
927 
928  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
929  path, abstract);
930 
931 
932  if (!_dbus_open_unix_socket (&fd, error))
933  {
934  _DBUS_ASSERT_ERROR_IS_SET(error);
935  return -1;
936  }
937  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
938 
939  _DBUS_ZERO (addr);
940  addr.sun_family = AF_UNIX;
941  path_len = strlen (path);
942 
943  if (abstract)
944  {
945 #ifdef __linux__
946  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
947  path_len++; /* Account for the extra nul byte added to the start of sun_path */
948 
949  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
950  {
952  "Abstract socket name too long\n");
953  _dbus_close (fd, NULL);
954  return -1;
955  }
956 
957  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
958  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
959 #else /* !__linux__ */
961  "Operating system does not support abstract socket namespace\n");
962  _dbus_close (fd, NULL);
963  return -1;
964 #endif /* !__linux__ */
965  }
966  else
967  {
968  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
969  {
971  "Socket name too long\n");
972  _dbus_close (fd, NULL);
973  return -1;
974  }
975 
976  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
977  }
978 
979  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
980  {
981  dbus_set_error (error,
982  _dbus_error_from_errno (errno),
983  "Failed to connect to socket %s: %s",
984  path, _dbus_strerror (errno));
985 
986  _dbus_close (fd, NULL);
987  return -1;
988  }
989 
990  if (!_dbus_set_fd_nonblocking (fd, error))
991  {
992  _DBUS_ASSERT_ERROR_IS_SET (error);
993 
994  _dbus_close (fd, NULL);
995  return -1;
996  }
997 
998  return fd;
999 }
1000 
1013 int
1014 _dbus_connect_exec (const char *path,
1015  char *const argv[],
1016  DBusError *error)
1017 {
1018  int fds[2];
1019  pid_t pid;
1020  int retval;
1021  dbus_bool_t cloexec_done = 0;
1022 
1023  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1024 
1025  _dbus_verbose ("connecting to process %s\n", path);
1026 
1027 #ifdef SOCK_CLOEXEC
1028  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1029  cloexec_done = (retval >= 0);
1030 
1031  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1032 #endif
1033  {
1034  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1035  }
1036 
1037  if (retval < 0)
1038  {
1039  dbus_set_error (error,
1040  _dbus_error_from_errno (errno),
1041  "Failed to create socket pair: %s",
1042  _dbus_strerror (errno));
1043  return -1;
1044  }
1045 
1046  if (!cloexec_done)
1047  {
1048  _dbus_fd_set_close_on_exec (fds[0]);
1049  _dbus_fd_set_close_on_exec (fds[1]);
1050  }
1051 
1052  /* Make sure our output buffers aren't redundantly printed by both the
1053  * parent and the child */
1054  fflush (stdout);
1055  fflush (stderr);
1056 
1057  pid = fork ();
1058  if (pid < 0)
1059  {
1060  dbus_set_error (error,
1061  _dbus_error_from_errno (errno),
1062  "Failed to fork() to call %s: %s",
1063  path, _dbus_strerror (errno));
1064  close (fds[0]);
1065  close (fds[1]);
1066  return -1;
1067  }
1068 
1069  if (pid == 0)
1070  {
1071  /* child */
1072  close (fds[0]);
1073 
1074  dup2 (fds[1], STDIN_FILENO);
1075  dup2 (fds[1], STDOUT_FILENO);
1076 
1077  if (fds[1] != STDIN_FILENO &&
1078  fds[1] != STDOUT_FILENO)
1079  close (fds[1]);
1080 
1081  /* Inherit STDERR and the controlling terminal from the
1082  parent */
1083 
1084  _dbus_close_all ();
1085 
1086  execvp (path, (char * const *) argv);
1087 
1088  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1089 
1090  _exit(1);
1091  }
1092 
1093  /* parent */
1094  close (fds[1]);
1095 
1096  if (!_dbus_set_fd_nonblocking (fds[0], error))
1097  {
1098  _DBUS_ASSERT_ERROR_IS_SET (error);
1099 
1100  close (fds[0]);
1101  return -1;
1102  }
1103 
1104  return fds[0];
1105 }
1106 
1124 int
1125 _dbus_listen_unix_socket (const char *path,
1126  dbus_bool_t abstract,
1127  DBusError *error)
1128 {
1129  int listen_fd;
1130  struct sockaddr_un addr;
1131  size_t path_len;
1132  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1133 
1134  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1135 
1136  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1137  path, abstract);
1138 
1139  if (!_dbus_open_unix_socket (&listen_fd, error))
1140  {
1141  _DBUS_ASSERT_ERROR_IS_SET(error);
1142  return -1;
1143  }
1144  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1145 
1146  _DBUS_ZERO (addr);
1147  addr.sun_family = AF_UNIX;
1148  path_len = strlen (path);
1149 
1150  if (abstract)
1151  {
1152 #ifdef __linux__
1153  /* remember that abstract names aren't nul-terminated so we rely
1154  * on sun_path being filled in with zeroes above.
1155  */
1156  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1157  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1158 
1159  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1160  {
1162  "Abstract socket name too long\n");
1163  _dbus_close (listen_fd, NULL);
1164  return -1;
1165  }
1166 
1167  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1168  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1169 #else /* !__linux__ */
1171  "Operating system does not support abstract socket namespace\n");
1172  _dbus_close (listen_fd, NULL);
1173  return -1;
1174 #endif /* !__linux__ */
1175  }
1176  else
1177  {
1178  /* Discussed security implications of this with Nalin,
1179  * and we couldn't think of where it would kick our ass, but
1180  * it still seems a bit sucky. It also has non-security suckage;
1181  * really we'd prefer to exit if the socket is already in use.
1182  * But there doesn't seem to be a good way to do this.
1183  *
1184  * Just to be extra careful, I threw in the stat() - clearly
1185  * the stat() can't *fix* any security issue, but it at least
1186  * avoids inadvertent/accidental data loss.
1187  */
1188  {
1189  struct stat sb;
1190 
1191  if (stat (path, &sb) == 0 &&
1192  S_ISSOCK (sb.st_mode))
1193  unlink (path);
1194  }
1195 
1196  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1197  {
1199  "Socket name too long\n");
1200  _dbus_close (listen_fd, NULL);
1201  return -1;
1202  }
1203 
1204  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1205  }
1206 
1207  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1208  {
1209  dbus_set_error (error, _dbus_error_from_errno (errno),
1210  "Failed to bind socket \"%s\": %s",
1211  path, _dbus_strerror (errno));
1212  _dbus_close (listen_fd, NULL);
1213  return -1;
1214  }
1215 
1216  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1217  {
1218  dbus_set_error (error, _dbus_error_from_errno (errno),
1219  "Failed to listen on socket \"%s\": %s",
1220  path, _dbus_strerror (errno));
1221  _dbus_close (listen_fd, NULL);
1222  return -1;
1223  }
1224 
1225  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1226  {
1227  _DBUS_ASSERT_ERROR_IS_SET (error);
1228  _dbus_close (listen_fd, NULL);
1229  return -1;
1230  }
1231 
1232  /* Try opening up the permissions, but if we can't, just go ahead
1233  * and continue, maybe it will be good enough.
1234  */
1235  if (!abstract && chmod (path, 0777) < 0)
1236  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1237 
1238  return listen_fd;
1239 }
1240 
1251 int
1253  DBusError *error)
1254 {
1255 #ifdef HAVE_SYSTEMD
1256  int r, n;
1257  int fd;
1258  DBusSocket *new_fds;
1259 
1260  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1261 
1262  n = sd_listen_fds (TRUE);
1263  if (n < 0)
1264  {
1266  "Failed to acquire systemd socket: %s",
1267  _dbus_strerror (-n));
1268  return -1;
1269  }
1270 
1271  if (n <= 0)
1272  {
1274  "No socket received.");
1275  return -1;
1276  }
1277 
1278  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1279  {
1280  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1281  if (r < 0)
1282  {
1284  "Failed to verify systemd socket type: %s",
1285  _dbus_strerror (-r));
1286  return -1;
1287  }
1288 
1289  if (!r)
1290  {
1292  "Passed socket has wrong type.");
1293  return -1;
1294  }
1295  }
1296 
1297  /* OK, the file descriptors are all good, so let's take posession of
1298  them then. */
1299 
1300  new_fds = dbus_new (DBusSocket, n);
1301  if (!new_fds)
1302  {
1304  "Failed to allocate file handle array.");
1305  goto fail;
1306  }
1307 
1308  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1309  {
1310  if (!_dbus_set_fd_nonblocking (fd, error))
1311  {
1312  _DBUS_ASSERT_ERROR_IS_SET (error);
1313  goto fail;
1314  }
1315 
1316  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1317  }
1318 
1319  *fds = new_fds;
1320  return n;
1321 
1322  fail:
1323 
1324  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1325  {
1326  _dbus_close (fd, NULL);
1327  }
1328 
1329  dbus_free (new_fds);
1330  return -1;
1331 #else
1333  "dbus was compiled without systemd support");
1334  return -1;
1335 #endif
1336 }
1337 
1338 /* Convert an error code from getaddrinfo() or getnameinfo() into
1339  * a D-Bus error name. */
1340 static const char *
1341 _dbus_error_from_gai (int gai_res,
1342  int saved_errno)
1343 {
1344  switch (gai_res)
1345  {
1346 #ifdef EAI_FAMILY
1347  case EAI_FAMILY:
1348  /* ai_family not supported (at all) */
1349  return DBUS_ERROR_NOT_SUPPORTED;
1350 #endif
1351 
1352 #ifdef EAI_SOCKTYPE
1353  case EAI_SOCKTYPE:
1354  /* ai_socktype not supported (at all) */
1355  return DBUS_ERROR_NOT_SUPPORTED;
1356 #endif
1357 
1358 #ifdef EAI_MEMORY
1359  case EAI_MEMORY:
1360  /* Out of memory */
1361  return DBUS_ERROR_NO_MEMORY;
1362 #endif
1363 
1364 #ifdef EAI_SYSTEM
1365  case EAI_SYSTEM:
1366  /* Unspecified system error, details in errno */
1367  return _dbus_error_from_errno (saved_errno);
1368 #endif
1369 
1370  case 0:
1371  /* It succeeded, but we didn't get any addresses? */
1372  return DBUS_ERROR_FAILED;
1373 
1374  /* EAI_AGAIN: Transient failure */
1375  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1376  /* EAI_FAIL: Non-recoverable failure */
1377  /* EAI_NODATA: host exists but has no addresses */
1378  /* EAI_NONAME: host does not exist */
1379  /* EAI_OVERFLOW: argument buffer overflow */
1380  /* EAI_SERVICE: service not available for specified socket
1381  * type (we should never see this because we use numeric
1382  * ports) */
1383  default:
1384  return DBUS_ERROR_FAILED;
1385  }
1386 }
1387 
1401 DBusSocket
1402 _dbus_connect_tcp_socket (const char *host,
1403  const char *port,
1404  const char *family,
1405  DBusError *error)
1406 {
1407  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1408 }
1409 
1410 DBusSocket
1411 _dbus_connect_tcp_socket_with_nonce (const char *host,
1412  const char *port,
1413  const char *family,
1414  const char *noncefile,
1415  DBusError *error)
1416 {
1417  int saved_errno = 0;
1418  DBusList *connect_errors = NULL;
1419  DBusSocket fd = DBUS_SOCKET_INIT;
1420  int res;
1421  struct addrinfo hints;
1422  struct addrinfo *ai = NULL;
1423  const struct addrinfo *tmp;
1424  DBusError *connect_error;
1425 
1426  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1427 
1428  _DBUS_ZERO (hints);
1429 
1430  if (!family)
1431  hints.ai_family = AF_UNSPEC;
1432  else if (!strcmp(family, "ipv4"))
1433  hints.ai_family = AF_INET;
1434  else if (!strcmp(family, "ipv6"))
1435  hints.ai_family = AF_INET6;
1436  else
1437  {
1438  dbus_set_error (error,
1440  "Unknown address family %s", family);
1441  return _dbus_socket_get_invalid ();
1442  }
1443  hints.ai_protocol = IPPROTO_TCP;
1444  hints.ai_socktype = SOCK_STREAM;
1445  hints.ai_flags = AI_ADDRCONFIG;
1446 
1447  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1448  {
1449  dbus_set_error (error,
1450  _dbus_error_from_gai (res, errno),
1451  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1452  host, port, gai_strerror(res), res);
1453  _dbus_socket_invalidate (&fd);
1454  goto out;
1455  }
1456 
1457  tmp = ai;
1458  while (tmp)
1459  {
1460  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1461  {
1462  _DBUS_ASSERT_ERROR_IS_SET(error);
1463  _dbus_socket_invalidate (&fd);
1464  goto out;
1465  }
1466  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1467 
1468  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1469  {
1470  saved_errno = errno;
1471  _dbus_close (fd.fd, NULL);
1472  _dbus_socket_invalidate (&fd);
1473 
1474  connect_error = dbus_new0 (DBusError, 1);
1475 
1476  if (connect_error == NULL)
1477  {
1478  _DBUS_SET_OOM (error);
1479  goto out;
1480  }
1481 
1482  dbus_error_init (connect_error);
1483  _dbus_set_error_with_inet_sockaddr (connect_error,
1484  tmp->ai_addr, tmp->ai_addrlen,
1485  "Failed to connect to socket",
1486  saved_errno);
1487 
1488  if (!_dbus_list_append (&connect_errors, connect_error))
1489  {
1490  dbus_error_free (connect_error);
1491  dbus_free (connect_error);
1492  _DBUS_SET_OOM (error);
1493  goto out;
1494  }
1495 
1496  tmp = tmp->ai_next;
1497  continue;
1498  }
1499 
1500  break;
1501  }
1502 
1503  if (!_dbus_socket_is_valid (fd))
1504  {
1505  _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1506  host, port, error);
1507  goto out;
1508  }
1509 
1510  if (noncefile != NULL)
1511  {
1512  DBusString noncefileStr;
1513  dbus_bool_t ret;
1514  _dbus_string_init_const (&noncefileStr, noncefile);
1515  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1516 
1517  if (!ret)
1518  {
1519  _dbus_close (fd.fd, NULL);
1520  _dbus_socket_invalidate (&fd);
1521  goto out;
1522  }
1523  }
1524 
1525  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1526  {
1527  _dbus_close (fd.fd, NULL);
1528  _dbus_socket_invalidate (&fd);
1529  goto out;
1530  }
1531 
1532 out:
1533  if (ai != NULL)
1534  freeaddrinfo (ai);
1535 
1536  while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1537  {
1538  dbus_error_free (connect_error);
1539  dbus_free (connect_error);
1540  }
1541 
1542  return fd;
1543 }
1544 
1562 int
1563 _dbus_listen_tcp_socket (const char *host,
1564  const char *port,
1565  const char *family,
1566  DBusString *retport,
1567  const char **retfamily,
1568  DBusSocket **fds_p,
1569  DBusError *error)
1570 {
1571  int saved_errno;
1572  int nlisten_fd = 0, res, i;
1573  DBusList *bind_errors = NULL;
1574  DBusError *bind_error = NULL;
1575  DBusSocket *listen_fd = NULL;
1576  struct addrinfo hints;
1577  struct addrinfo *ai, *tmp;
1578  unsigned int reuseaddr;
1579  dbus_bool_t have_ipv4 = FALSE;
1580  dbus_bool_t have_ipv6 = FALSE;
1581 
1582  *fds_p = NULL;
1583  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1584 
1585  _DBUS_ZERO (hints);
1586 
1587  if (!family)
1588  hints.ai_family = AF_UNSPEC;
1589  else if (!strcmp(family, "ipv4"))
1590  hints.ai_family = AF_INET;
1591  else if (!strcmp(family, "ipv6"))
1592  hints.ai_family = AF_INET6;
1593  else
1594  {
1595  dbus_set_error (error,
1597  "Unknown address family %s", family);
1598  return -1;
1599  }
1600 
1601  hints.ai_protocol = IPPROTO_TCP;
1602  hints.ai_socktype = SOCK_STREAM;
1603  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1604 
1605  redo_lookup_with_port:
1606  ai = NULL;
1607  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1608  {
1609  dbus_set_error (error,
1610  _dbus_error_from_gai (res, errno),
1611  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1612  host ? host : "*", port, gai_strerror(res), res);
1613  goto failed;
1614  }
1615 
1616  tmp = ai;
1617  while (tmp)
1618  {
1619  int fd = -1, tcp_nodelay_on;
1620  DBusSocket *newlisten_fd;
1621 
1622  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1623  {
1624  _DBUS_ASSERT_ERROR_IS_SET(error);
1625  goto failed;
1626  }
1627  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1628 
1629  reuseaddr = 1;
1630  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1631  {
1632  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1633  host ? host : "*", port, _dbus_strerror (errno));
1634  }
1635 
1636  /* Nagle's algorithm imposes a huge delay on the initial messages
1637  going over TCP. */
1638  tcp_nodelay_on = 1;
1639  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1640  {
1641  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1642  host ? host : "*", port, _dbus_strerror (errno));
1643  }
1644 
1645  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1646  {
1647  saved_errno = errno;
1648  _dbus_close(fd, NULL);
1649 
1650  /*
1651  * We don't treat this as a fatal error, because there might be
1652  * other addresses that we can listen on. In particular:
1653  *
1654  * - If saved_errno is EADDRINUSE after we
1655  * "goto redo_lookup_with_port" after binding a port on one of the
1656  * possible addresses, we will try to bind that same port on
1657  * every address, including the same address again for a second
1658  * time, which will fail with EADDRINUSE.
1659  *
1660  * - If saved_errno is EADDRINUSE, it might be because binding to
1661  * an IPv6 address implicitly binds to a corresponding IPv4
1662  * address or vice versa (e.g. Linux with bindv6only=0).
1663  *
1664  * - If saved_errno is EADDRNOTAVAIL when we asked for family
1665  * AF_UNSPEC, it might be because IPv6 is disabled for this
1666  * particular interface (e.g. Linux with
1667  * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1668  */
1669  bind_error = dbus_new0 (DBusError, 1);
1670 
1671  if (bind_error == NULL)
1672  {
1673  _DBUS_SET_OOM (error);
1674  goto failed;
1675  }
1676 
1677  dbus_error_init (bind_error);
1678  _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1679  "Failed to bind socket",
1680  saved_errno);
1681 
1682  if (!_dbus_list_append (&bind_errors, bind_error))
1683  {
1684  dbus_error_free (bind_error);
1685  dbus_free (bind_error);
1686  _DBUS_SET_OOM (error);
1687  goto failed;
1688  }
1689 
1690  /* Try the next address, maybe it will work better */
1691  tmp = tmp->ai_next;
1692  continue;
1693  }
1694 
1695  if (listen (fd, 30 /* backlog */) < 0)
1696  {
1697  saved_errno = errno;
1698  _dbus_close (fd, NULL);
1699  _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1700  "Failed to listen on socket",
1701  saved_errno);
1702  goto failed;
1703  }
1704 
1705  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1706  if (!newlisten_fd)
1707  {
1708  _dbus_close (fd, NULL);
1710  "Failed to allocate file handle array");
1711  goto failed;
1712  }
1713  listen_fd = newlisten_fd;
1714  listen_fd[nlisten_fd].fd = fd;
1715  nlisten_fd++;
1716 
1717  if (tmp->ai_addr->sa_family == AF_INET)
1718  have_ipv4 = TRUE;
1719  else if (tmp->ai_addr->sa_family == AF_INET6)
1720  have_ipv6 = TRUE;
1721 
1722  if (!_dbus_string_get_length(retport))
1723  {
1724  /* If the user didn't specify a port, or used 0, then
1725  the kernel chooses a port. After the first address
1726  is bound to, we need to force all remaining addresses
1727  to use the same port */
1728  if (!port || !strcmp(port, "0"))
1729  {
1730  int result;
1731  struct sockaddr_storage addr;
1732  socklen_t addrlen;
1733  char portbuf[50];
1734 
1735  addrlen = sizeof(addr);
1736  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1737 
1738  if (result == -1)
1739  {
1740  saved_errno = errno;
1741  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1742  "Failed to retrieve socket name for \"%s:%s\": %s",
1743  host ? host : "*", port, _dbus_strerror (saved_errno));
1744  goto failed;
1745  }
1746 
1747  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1748  portbuf, sizeof(portbuf),
1749  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1750  {
1751  saved_errno = errno;
1752  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1753  "Failed to resolve port \"%s:%s\": %s (%d)",
1754  host ? host : "*", port, gai_strerror(res), res);
1755  goto failed;
1756  }
1757 
1758  if (!_dbus_string_append(retport, portbuf))
1759  {
1761  goto failed;
1762  }
1763 
1764  /* Release current address list & redo lookup */
1765  port = _dbus_string_get_const_data(retport);
1766  freeaddrinfo(ai);
1767  goto redo_lookup_with_port;
1768  }
1769  else
1770  {
1771  if (!_dbus_string_append(retport, port))
1772  {
1774  goto failed;
1775  }
1776  }
1777  }
1778 
1779  tmp = tmp->ai_next;
1780  }
1781  freeaddrinfo(ai);
1782  ai = NULL;
1783 
1784  if (!nlisten_fd)
1785  {
1786  _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1787  port, error);
1788  goto failed;
1789  }
1790 
1791  if (have_ipv4 && !have_ipv6)
1792  *retfamily = "ipv4";
1793  else if (!have_ipv4 && have_ipv6)
1794  *retfamily = "ipv6";
1795 
1796  for (i = 0 ; i < nlisten_fd ; i++)
1797  {
1798  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1799  {
1800  goto failed;
1801  }
1802  }
1803 
1804  *fds_p = listen_fd;
1805 
1806  /* This list might be non-empty even on success, because we might be
1807  * ignoring EADDRINUSE or EADDRNOTAVAIL */
1808  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1809  {
1810  dbus_error_free (bind_error);
1811  dbus_free (bind_error);
1812  }
1813 
1814  return nlisten_fd;
1815 
1816  failed:
1817  if (ai)
1818  freeaddrinfo(ai);
1819  for (i = 0 ; i < nlisten_fd ; i++)
1820  _dbus_close(listen_fd[i].fd, NULL);
1821 
1822  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1823  {
1824  dbus_error_free (bind_error);
1825  dbus_free (bind_error);
1826  }
1827 
1828  dbus_free(listen_fd);
1829  return -1;
1830 }
1831 
1832 static dbus_bool_t
1833 write_credentials_byte (int server_fd,
1834  DBusError *error)
1835 {
1836  int bytes_written;
1837  char buf[1] = { '\0' };
1838 #if defined(HAVE_CMSGCRED)
1839  union {
1840  struct cmsghdr hdr;
1841  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1842  } cmsg;
1843  struct iovec iov;
1844  struct msghdr msg;
1845  iov.iov_base = buf;
1846  iov.iov_len = 1;
1847 
1848  _DBUS_ZERO(msg);
1849  msg.msg_iov = &iov;
1850  msg.msg_iovlen = 1;
1851 
1852  msg.msg_control = (caddr_t) &cmsg;
1853  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1854  _DBUS_ZERO(cmsg);
1855  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1856  cmsg.hdr.cmsg_level = SOL_SOCKET;
1857  cmsg.hdr.cmsg_type = SCM_CREDS;
1858 #endif
1859 
1860  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1861 
1862  again:
1863 
1864 #if defined(HAVE_CMSGCRED)
1865  bytes_written = sendmsg (server_fd, &msg, 0
1866 #if HAVE_DECL_MSG_NOSIGNAL
1867  |MSG_NOSIGNAL
1868 #endif
1869  );
1870 
1871  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1872  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1873  * only allows that on AF_UNIX. Try just doing a send() instead. */
1874  if (bytes_written < 0 && errno == EINVAL)
1875 #endif
1876  {
1877  bytes_written = send (server_fd, buf, 1, 0
1878 #if HAVE_DECL_MSG_NOSIGNAL
1879  |MSG_NOSIGNAL
1880 #endif
1881  );
1882  }
1883 
1884  if (bytes_written < 0 && errno == EINTR)
1885  goto again;
1886 
1887  if (bytes_written < 0)
1888  {
1889  dbus_set_error (error, _dbus_error_from_errno (errno),
1890  "Failed to write credentials byte: %s",
1891  _dbus_strerror (errno));
1892  return FALSE;
1893  }
1894  else if (bytes_written == 0)
1895  {
1897  "wrote zero bytes writing credentials byte");
1898  return FALSE;
1899  }
1900  else
1901  {
1902  _dbus_assert (bytes_written == 1);
1903  _dbus_verbose ("wrote credentials byte\n");
1904  return TRUE;
1905  }
1906 }
1907 
1908 /* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1909 static dbus_bool_t
1910 add_groups_to_credentials (int client_fd,
1911  DBusCredentials *credentials,
1912  dbus_gid_t primary)
1913 {
1914 #if defined(__linux__) && defined(SO_PEERGROUPS)
1915  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1916  gid_t *buf = NULL;
1917  socklen_t len = 1024;
1918  dbus_bool_t oom = FALSE;
1919  /* libdbus has a different representation of group IDs just to annoy you */
1920  dbus_gid_t *converted_gids = NULL;
1921  dbus_bool_t need_primary = TRUE;
1922  size_t n_gids;
1923  size_t i;
1924 
1925  n_gids = ((size_t) len) / sizeof (gid_t);
1926  buf = dbus_new (gid_t, n_gids);
1927 
1928  if (buf == NULL)
1929  return FALSE;
1930 
1931  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1932  {
1933  int e = errno;
1934  gid_t *replacement;
1935 
1936  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1937  _dbus_strerror (e), (unsigned long) len);
1938 
1939  if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1940  {
1941  _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1942  _dbus_strerror (e));
1943  goto out;
1944  }
1945 
1946  /* If not enough space, len is updated to be enough.
1947  * Try again with a large enough buffer. */
1948  n_gids = ((size_t) len) / sizeof (gid_t);
1949  replacement = dbus_realloc (buf, len);
1950 
1951  if (replacement == NULL)
1952  {
1953  oom = TRUE;
1954  goto out;
1955  }
1956 
1957  buf = replacement;
1958  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1959  }
1960 
1961  if (len <= 0)
1962  {
1963  _dbus_verbose ("getsockopt(SO_PEERGROUPS) yielded <= 0 bytes: %ld\n",
1964  (long) len);
1965  goto out;
1966  }
1967 
1968  if (len > n_gids * sizeof (gid_t))
1969  {
1970  _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
1971  _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
1972  }
1973 
1974  if (len % sizeof (gid_t) != 0)
1975  {
1976  _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
1977  "integer multiple of sizeof(gid_t): %lu should be "
1978  "divisible by %zu",
1979  (unsigned long) len, sizeof (gid_t));
1980  goto out;
1981  }
1982 
1983  /* Allocate an extra space for the primary group ID */
1984  n_gids = ((size_t) len) / sizeof (gid_t);
1985 
1986  /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
1987  * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
1988  * This is using _DBUS_INT32_MAX as a conservative lower bound for
1989  * the maximum size_t. */
1990  if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
1991  {
1992  _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
1993  "of groups (%lu bytes), ignoring",
1994  (unsigned long) len);
1995  goto out;
1996  }
1997 
1998  converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
1999 
2000  if (converted_gids == NULL)
2001  {
2002  oom = TRUE;
2003  goto out;
2004  }
2005 
2006  for (i = 0; i < n_gids; i++)
2007  {
2008  converted_gids[i] = (dbus_gid_t) buf[i];
2009 
2010  if (converted_gids[i] == primary)
2011  need_primary = FALSE;
2012  }
2013 
2014  if (need_primary && primary != DBUS_GID_UNSET)
2015  {
2016  converted_gids[n_gids] = primary;
2017  n_gids++;
2018  }
2019 
2020  _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2021 
2022 out:
2023  dbus_free (buf);
2024  return !oom;
2025 #else
2026  /* no error */
2027  return TRUE;
2028 #endif
2029 }
2030 
2031 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2032 static dbus_bool_t
2033 add_linux_security_label_to_credentials (int client_fd,
2034  DBusCredentials *credentials)
2035 {
2036 #if defined(__linux__) && defined(SO_PEERSEC)
2037  DBusString buf;
2038  socklen_t len = 1024;
2039  dbus_bool_t oom = FALSE;
2040 
2041  if (!_dbus_string_init_preallocated (&buf, len) ||
2042  !_dbus_string_set_length (&buf, len))
2043  return FALSE;
2044 
2045  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2046  _dbus_string_get_data (&buf), &len) < 0)
2047  {
2048  int e = errno;
2049 
2050  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2051  _dbus_strerror (e), (unsigned long) len);
2052 
2053  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2054  {
2055  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2056  _dbus_strerror (e));
2057  goto out;
2058  }
2059 
2060  /* If not enough space, len is updated to be enough.
2061  * Try again with a large enough buffer. */
2062  if (!_dbus_string_set_length (&buf, len))
2063  {
2064  oom = TRUE;
2065  goto out;
2066  }
2067 
2068  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2069  }
2070 
2071  if (len <= 0)
2072  {
2073  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2074  (unsigned long) len);
2075  goto out;
2076  }
2077 
2078  if (len > _dbus_string_get_length_uint (&buf))
2079  {
2080  _dbus_verbose ("%lu > %u", (unsigned long) len,
2081  _dbus_string_get_length_uint (&buf));
2082  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2083  }
2084 
2085  if (_dbus_string_get_byte (&buf, len - 1) == 0)
2086  {
2087  /* the kernel included the trailing \0 in its count,
2088  * but DBusString always has an extra \0 after the data anyway */
2089  _dbus_verbose ("subtracting trailing \\0\n");
2090  len--;
2091  }
2092 
2093  if (!_dbus_string_set_length (&buf, len))
2094  {
2095  _dbus_assert_not_reached ("shortening string should not lead to OOM");
2096  oom = TRUE;
2097  goto out;
2098  }
2099 
2100  if (strlen (_dbus_string_get_const_data (&buf)) != len)
2101  {
2102  /* LSM people on the linux-security-module@ mailing list say this
2103  * should never happen: the label should be a bytestring with
2104  * an optional trailing \0 */
2105  _dbus_verbose ("security label from kernel had an embedded \\0, "
2106  "ignoring it\n");
2107  goto out;
2108  }
2109 
2110  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2111  (unsigned long) len,
2112  _dbus_string_get_const_data (&buf));
2113 
2115  _dbus_string_get_const_data (&buf)))
2116  {
2117  oom = TRUE;
2118  goto out;
2119  }
2120 
2121 out:
2122  _dbus_string_free (&buf);
2123  return !oom;
2124 #else
2125  /* no error */
2126  return TRUE;
2127 #endif
2128 }
2129 
2172  DBusCredentials *credentials,
2173  DBusError *error)
2174 {
2175  struct msghdr msg;
2176  struct iovec iov;
2177  char buf;
2178  dbus_uid_t uid_read;
2179  dbus_gid_t primary_gid_read;
2180  dbus_pid_t pid_read;
2181  int bytes_read;
2182 
2183 #ifdef HAVE_CMSGCRED
2184  union {
2185  struct cmsghdr hdr;
2186  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2187  } cmsg;
2188 #endif
2189 
2190  /* The POSIX spec certainly doesn't promise this, but
2191  * we need these assertions to fail as soon as we're wrong about
2192  * it so we can do the porting fixups
2193  */
2194  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2195  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2196  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2197 
2198  uid_read = DBUS_UID_UNSET;
2199  primary_gid_read = DBUS_GID_UNSET;
2200  pid_read = DBUS_PID_UNSET;
2201 
2202  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2203 
2204  _dbus_credentials_clear (credentials);
2205 
2206  iov.iov_base = &buf;
2207  iov.iov_len = 1;
2208 
2209  _DBUS_ZERO(msg);
2210  msg.msg_iov = &iov;
2211  msg.msg_iovlen = 1;
2212 
2213 #if defined(HAVE_CMSGCRED)
2214  _DBUS_ZERO(cmsg);
2215  msg.msg_control = (caddr_t) &cmsg;
2216  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2217 #endif
2218 
2219  again:
2220  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2221 
2222  if (bytes_read < 0)
2223  {
2224  if (errno == EINTR)
2225  goto again;
2226 
2227  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2228  * normally only call read_credentials if the socket was ready
2229  * for reading
2230  */
2231 
2232  dbus_set_error (error, _dbus_error_from_errno (errno),
2233  "Failed to read credentials byte: %s",
2234  _dbus_strerror (errno));
2235  return FALSE;
2236  }
2237  else if (bytes_read == 0)
2238  {
2239  /* this should not happen unless we are using recvmsg wrong,
2240  * so is essentially here for paranoia
2241  */
2243  "Failed to read credentials byte (zero-length read)");
2244  return FALSE;
2245  }
2246  else if (buf != '\0')
2247  {
2249  "Credentials byte was not nul");
2250  return FALSE;
2251  }
2252 
2253  _dbus_verbose ("read credentials byte\n");
2254 
2255  {
2256 #ifdef SO_PEERCRED
2257  /* Supported by at least Linux and OpenBSD, with minor differences.
2258  *
2259  * This mechanism passes the process ID through and does not require
2260  * the peer's cooperation, so we prefer it over all others. Notably,
2261  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2262  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2263  * because this is much less fragile.
2264  */
2265 #ifdef __OpenBSD__
2266  struct sockpeercred cr;
2267 #else
2268  struct ucred cr;
2269 #endif
2270  socklen_t cr_len = sizeof (cr);
2271 
2272  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2273  {
2274  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2275  _dbus_strerror (errno));
2276  }
2277  else if (cr_len != sizeof (cr))
2278  {
2279  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2280  cr_len, (int) sizeof (cr));
2281  }
2282  else
2283  {
2284  pid_read = cr.pid;
2285  uid_read = cr.uid;
2286 #ifdef __linux__
2287  /* Do other platforms have cr.gid? (Not that it really matters,
2288  * because the gid is useless to us unless we know the complete
2289  * group vector, which we only know on Linux.) */
2290  primary_gid_read = cr.gid;
2291 #endif
2292  }
2293 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2294  /* Another variant of the above - used on NetBSD
2295  */
2296  struct unpcbid cr;
2297  socklen_t cr_len = sizeof (cr);
2298 
2299  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2300  {
2301  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2302  _dbus_strerror (errno));
2303  }
2304  else if (cr_len != sizeof (cr))
2305  {
2306  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2307  cr_len, (int) sizeof (cr));
2308  }
2309  else
2310  {
2311  pid_read = cr.unp_pid;
2312  uid_read = cr.unp_euid;
2313  }
2314 #elif defined(HAVE_CMSGCRED)
2315  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2316  * presence of that struct implies SCM_CREDS. Supported by at least
2317  * FreeBSD and DragonflyBSD.
2318  *
2319  * This mechanism requires the peer to help us (it has to send us a
2320  * SCM_CREDS message) but it does pass the process ID through,
2321  * which makes it better than getpeereid().
2322  */
2323  struct cmsgcred *cred;
2324  struct cmsghdr *cmsgp;
2325 
2326  for (cmsgp = CMSG_FIRSTHDR (&msg);
2327  cmsgp != NULL;
2328  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2329  {
2330  if (cmsgp->cmsg_type == SCM_CREDS &&
2331  cmsgp->cmsg_level == SOL_SOCKET &&
2332  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2333  {
2334  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2335  pid_read = cred->cmcred_pid;
2336  uid_read = cred->cmcred_euid;
2337  break;
2338  }
2339  }
2340 
2341 #elif defined(HAVE_GETPEERUCRED)
2342  /* Supported in at least Solaris >= 10. It should probably be higher
2343  * up this list, because it carries the pid and we use this code path
2344  * for audit data. */
2345  ucred_t * ucred = NULL;
2346  if (getpeerucred (client_fd.fd, &ucred) == 0)
2347  {
2348 #ifdef HAVE_ADT
2349  adt_session_data_t *adth = NULL;
2350 #endif
2351  pid_read = ucred_getpid (ucred);
2352  uid_read = ucred_geteuid (ucred);
2353 #ifdef HAVE_ADT
2354  /* generate audit session data based on socket ucred */
2355  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2356  {
2357  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2358  }
2359  else
2360  {
2361  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2362  {
2363  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2364  }
2365  else
2366  {
2367  adt_export_data_t *data = NULL;
2368  size_t size = adt_export_session_data (adth, &data);
2369  if (size <= 0)
2370  {
2371  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2372  }
2373  else
2374  {
2375  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2376  free (data);
2377  }
2378  }
2379  (void) adt_end_session (adth);
2380  }
2381 #endif /* HAVE_ADT */
2382  }
2383  else
2384  {
2385  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2386  }
2387  if (ucred != NULL)
2388  ucred_free (ucred);
2389 
2390  /* ----------------------------------------------------------------
2391  * When adding new mechanisms, please add them above this point
2392  * if they support passing the process ID through, or below if not.
2393  * ---------------------------------------------------------------- */
2394 
2395 #elif defined(HAVE_GETPEEREID)
2396  /* getpeereid() originates from D.J. Bernstein and is fairly
2397  * widely-supported. According to a web search, it might be present in
2398  * any/all of:
2399  *
2400  * - AIX?
2401  * - Blackberry?
2402  * - Cygwin
2403  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2404  * - Mac OS X
2405  * - Minix 3.1.8+
2406  * - MirBSD?
2407  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2408  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2409  * - QNX?
2410  */
2411  uid_t euid;
2412  gid_t egid;
2413  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2414  {
2415  uid_read = euid;
2416  }
2417  else
2418  {
2419  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2420  }
2421 #else /* no supported mechanism */
2422 
2423 #warning Socket credentials not supported on this Unix OS
2424 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2425 
2426  /* Please add other operating systems known to support at least one of
2427  * the mechanisms above to this list, keeping alphabetical order.
2428  * Everything not in this list is best-effort.
2429  */
2430 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2431  defined(__linux__) || \
2432  defined(__OpenBSD__) || \
2433  defined(__NetBSD__)
2434 # error Credentials passing not working on this OS is a regression!
2435 #endif
2436 
2437  _dbus_verbose ("Socket credentials not supported on this OS\n");
2438 #endif
2439  }
2440 
2441  _dbus_verbose ("Credentials:"
2442  " pid "DBUS_PID_FORMAT
2443  " uid "DBUS_UID_FORMAT
2444  "\n",
2445  pid_read,
2446  uid_read);
2447 
2448  if (pid_read != DBUS_PID_UNSET)
2449  {
2450  if (!_dbus_credentials_add_pid (credentials, pid_read))
2451  {
2452  _DBUS_SET_OOM (error);
2453  return FALSE;
2454  }
2455  }
2456 
2457  if (uid_read != DBUS_UID_UNSET)
2458  {
2459  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2460  {
2461  _DBUS_SET_OOM (error);
2462  return FALSE;
2463  }
2464  }
2465 
2466  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2467  {
2468  _DBUS_SET_OOM (error);
2469  return FALSE;
2470  }
2471 
2472  /* We don't put any groups in the credentials unless we can put them
2473  * all there. */
2474  if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2475  {
2476  _DBUS_SET_OOM (error);
2477  return FALSE;
2478  }
2479 
2480  return TRUE;
2481 }
2482 
2502  DBusError *error)
2503 {
2504  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2505 
2506  if (write_credentials_byte (server_fd.fd, error))
2507  return TRUE;
2508  else
2509  return FALSE;
2510 }
2511 
2521 DBusSocket
2523 {
2524  DBusSocket client_fd;
2525  struct sockaddr addr;
2526  socklen_t addrlen;
2527 #ifdef HAVE_ACCEPT4
2528  dbus_bool_t cloexec_done;
2529 #endif
2530 
2531  addrlen = sizeof (addr);
2532 
2533  retry:
2534 
2535 #ifdef HAVE_ACCEPT4
2536  /*
2537  * At compile-time, we assume that if accept4() is available in
2538  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2539  * not necessarily true that either is supported by the running kernel.
2540  */
2541  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2542  cloexec_done = client_fd.fd >= 0;
2543 
2544  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2545 #endif
2546  {
2547  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2548  }
2549 
2550  if (client_fd.fd < 0)
2551  {
2552  if (errno == EINTR)
2553  goto retry;
2554  }
2555 
2556  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2557 
2558 #ifdef HAVE_ACCEPT4
2559  if (!cloexec_done)
2560 #endif
2561  {
2562  _dbus_fd_set_close_on_exec(client_fd.fd);
2563  }
2564 
2565  return client_fd;
2566 }
2567 
2578 {
2579  const char *directory;
2580  struct stat sb;
2581 
2582  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2583 
2584  directory = _dbus_string_get_const_data (dir);
2585 
2586  if (stat (directory, &sb) < 0)
2587  {
2588  dbus_set_error (error, _dbus_error_from_errno (errno),
2589  "%s", _dbus_strerror (errno));
2590 
2591  return FALSE;
2592  }
2593 
2594  if (sb.st_uid != geteuid ())
2595  {
2597  "%s directory is owned by user %lu, not %lu",
2598  directory,
2599  (unsigned long) sb.st_uid,
2600  (unsigned long) geteuid ());
2601  return FALSE;
2602  }
2603 
2604  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2605  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2606  {
2608  "%s directory is not private to the user", directory);
2609  return FALSE;
2610  }
2611 
2612  return TRUE;
2613 }
2614 
2615 static dbus_bool_t
2616 fill_user_info_from_passwd (struct passwd *p,
2617  DBusUserInfo *info,
2618  DBusError *error)
2619 {
2620  _dbus_assert (p->pw_name != NULL);
2621  _dbus_assert (p->pw_dir != NULL);
2622 
2623  info->uid = p->pw_uid;
2624  info->primary_gid = p->pw_gid;
2625  info->username = _dbus_strdup (p->pw_name);
2626  info->homedir = _dbus_strdup (p->pw_dir);
2627 
2628  if (info->username == NULL ||
2629  info->homedir == NULL)
2630  {
2632  return FALSE;
2633  }
2634 
2635  return TRUE;
2636 }
2637 
2638 static dbus_bool_t
2639 fill_user_info (DBusUserInfo *info,
2640  dbus_uid_t uid,
2641  const DBusString *username,
2642  DBusError *error)
2643 {
2644  const char *username_c;
2645 
2646  /* exactly one of username/uid provided */
2647  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2648  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2649 
2650  info->uid = DBUS_UID_UNSET;
2651  info->primary_gid = DBUS_GID_UNSET;
2652  info->group_ids = NULL;
2653  info->n_group_ids = 0;
2654  info->username = NULL;
2655  info->homedir = NULL;
2656 
2657  if (username != NULL)
2658  username_c = _dbus_string_get_const_data (username);
2659  else
2660  username_c = NULL;
2661 
2662  /* For now assuming that the getpwnam() and getpwuid() flavors
2663  * are always symmetrical, if not we have to add more configure
2664  * checks
2665  */
2666 
2667 #ifdef HAVE_GETPWNAM_R
2668  {
2669  struct passwd *p;
2670  int result;
2671  size_t buflen;
2672  char *buf;
2673  struct passwd p_str;
2674 
2675  /* retrieve maximum needed size for buf */
2676  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2677 
2678  /* sysconf actually returns a long, but everything else expects size_t,
2679  * so just recast here.
2680  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2681  */
2682  if ((long) buflen <= 0)
2683  buflen = 1024;
2684 
2685  result = -1;
2686  while (1)
2687  {
2688  buf = dbus_malloc (buflen);
2689  if (buf == NULL)
2690  {
2692  return FALSE;
2693  }
2694 
2695  p = NULL;
2696  if (uid != DBUS_UID_UNSET)
2697  result = getpwuid_r (uid, &p_str, buf, buflen,
2698  &p);
2699  else
2700  result = getpwnam_r (username_c, &p_str, buf, buflen,
2701  &p);
2702  //Try a bigger buffer if ERANGE was returned
2703  if (result == ERANGE && buflen < 512 * 1024)
2704  {
2705  dbus_free (buf);
2706  buflen *= 2;
2707  }
2708  else
2709  {
2710  break;
2711  }
2712  }
2713  if (result == 0 && p == &p_str)
2714  {
2715  if (!fill_user_info_from_passwd (p, info, error))
2716  {
2717  dbus_free (buf);
2718  return FALSE;
2719  }
2720  dbus_free (buf);
2721  }
2722  else
2723  {
2724  dbus_set_error (error, _dbus_error_from_errno (errno),
2725  "User \"%s\" unknown or no memory to allocate password entry\n",
2726  username_c ? username_c : "???");
2727  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2728  dbus_free (buf);
2729  return FALSE;
2730  }
2731  }
2732 #else /* ! HAVE_GETPWNAM_R */
2733  {
2734  /* I guess we're screwed on thread safety here */
2735  struct passwd *p;
2736 
2737 #warning getpwnam_r() not available, please report this to the dbus maintainers with details of your OS
2738 
2739  if (uid != DBUS_UID_UNSET)
2740  p = getpwuid (uid);
2741  else
2742  p = getpwnam (username_c);
2743 
2744  if (p != NULL)
2745  {
2746  if (!fill_user_info_from_passwd (p, info, error))
2747  {
2748  return FALSE;
2749  }
2750  }
2751  else
2752  {
2753  dbus_set_error (error, _dbus_error_from_errno (errno),
2754  "User \"%s\" unknown or no memory to allocate password entry\n",
2755  username_c ? username_c : "???");
2756  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2757  return FALSE;
2758  }
2759  }
2760 #endif /* ! HAVE_GETPWNAM_R */
2761 
2762  /* Fill this in so we can use it to get groups */
2763  username_c = info->username;
2764 
2765 #ifdef HAVE_GETGROUPLIST
2766  {
2767  gid_t *buf;
2768  int buf_count;
2769  int i;
2770  int initial_buf_count;
2771 
2772  initial_buf_count = 17;
2773  buf_count = initial_buf_count;
2774  buf = dbus_new (gid_t, buf_count);
2775  if (buf == NULL)
2776  {
2778  goto failed;
2779  }
2780 
2781  if (getgrouplist (username_c,
2782  info->primary_gid,
2783  buf, &buf_count) < 0)
2784  {
2785  gid_t *new;
2786  /* Presumed cause of negative return code: buf has insufficient
2787  entries to hold the entire group list. The Linux behavior in this
2788  case is to pass back the actual number of groups in buf_count, but
2789  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2790  So as a hack, try to help out a bit by guessing a larger
2791  number of groups, within reason.. might still fail, of course,
2792  but we can at least print a more informative message. I looked up
2793  the "right way" to do this by downloading Apple's own source code
2794  for the "id" command, and it turns out that they use an
2795  undocumented library function getgrouplist_2 (!) which is not
2796  declared in any header in /usr/include (!!). That did not seem
2797  like the way to go here.
2798  */
2799  if (buf_count == initial_buf_count)
2800  {
2801  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2802  }
2803  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2804  if (new == NULL)
2805  {
2807  dbus_free (buf);
2808  goto failed;
2809  }
2810 
2811  buf = new;
2812 
2813  errno = 0;
2814  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2815  {
2816  if (errno == 0)
2817  {
2818  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2819  username_c, buf_count, buf_count);
2820  }
2821  else
2822  {
2823  dbus_set_error (error,
2824  _dbus_error_from_errno (errno),
2825  "Failed to get groups for username \"%s\" primary GID "
2826  DBUS_GID_FORMAT ": %s\n",
2827  username_c, info->primary_gid,
2828  _dbus_strerror (errno));
2829  dbus_free (buf);
2830  goto failed;
2831  }
2832  }
2833  }
2834 
2835  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2836  if (info->group_ids == NULL)
2837  {
2839  dbus_free (buf);
2840  goto failed;
2841  }
2842 
2843  for (i = 0; i < buf_count; ++i)
2844  info->group_ids[i] = buf[i];
2845 
2846  info->n_group_ids = buf_count;
2847 
2848  dbus_free (buf);
2849  }
2850 #else /* HAVE_GETGROUPLIST */
2851  {
2852  /* We just get the one group ID */
2853  info->group_ids = dbus_new (dbus_gid_t, 1);
2854  if (info->group_ids == NULL)
2855  {
2857  goto failed;
2858  }
2859 
2860  info->n_group_ids = 1;
2861 
2862  (info->group_ids)[0] = info->primary_gid;
2863  }
2864 #endif /* HAVE_GETGROUPLIST */
2865 
2866  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2867 
2868  return TRUE;
2869 
2870  failed:
2871  _DBUS_ASSERT_ERROR_IS_SET (error);
2872  return FALSE;
2873 }
2874 
2885  const DBusString *username,
2886  DBusError *error)
2887 {
2888  return fill_user_info (info, DBUS_UID_UNSET,
2889  username, error);
2890 }
2891 
2902  dbus_uid_t uid,
2903  DBusError *error)
2904 {
2905  return fill_user_info (info, uid,
2906  NULL, error);
2907 }
2908 
2924 {
2925  /* The POSIX spec certainly doesn't promise this, but
2926  * we need these assertions to fail as soon as we're wrong about
2927  * it so we can do the porting fixups
2928  */
2929  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2930  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2931  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2932 
2933  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2934  return FALSE;
2935  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2936  return FALSE;
2937 
2938  return TRUE;
2939 }
2940 
2954 {
2955  return _dbus_string_append_uint (str,
2956  _dbus_geteuid ());
2957 }
2958 
2963 dbus_pid_t
2965 {
2966  return getpid ();
2967 }
2968 
2972 dbus_uid_t
2974 {
2975  return getuid ();
2976 }
2977 
2981 dbus_uid_t
2983 {
2984  return geteuid ();
2985 }
2986 
2993 unsigned long
2995 {
2996  return getpid ();
2997 }
2998 
2999 #if !DBUS_USE_SYNC
3000 /* To be thread-safe by default on platforms that don't necessarily have
3001  * atomic operations (notably Debian armel, which is armv4t), we must
3002  * use a mutex that can be initialized statically, like this.
3003  * GLib >= 2.32 uses a similar system.
3004  */
3005 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3006 #endif
3007 
3014 dbus_int32_t
3016 {
3017 #if DBUS_USE_SYNC
3018  return __sync_add_and_fetch(&atomic->value, 1)-1;
3019 #else
3020  dbus_int32_t res;
3021 
3022  pthread_mutex_lock (&atomic_mutex);
3023  res = atomic->value;
3024  atomic->value += 1;
3025  pthread_mutex_unlock (&atomic_mutex);
3026 
3027  return res;
3028 #endif
3029 }
3030 
3037 dbus_int32_t
3039 {
3040 #if DBUS_USE_SYNC
3041  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3042 #else
3043  dbus_int32_t res;
3044 
3045  pthread_mutex_lock (&atomic_mutex);
3046  res = atomic->value;
3047  atomic->value -= 1;
3048  pthread_mutex_unlock (&atomic_mutex);
3049 
3050  return res;
3051 #endif
3052 }
3053 
3061 dbus_int32_t
3063 {
3064 #if DBUS_USE_SYNC
3065  __sync_synchronize ();
3066  return atomic->value;
3067 #else
3068  dbus_int32_t res;
3069 
3070  pthread_mutex_lock (&atomic_mutex);
3071  res = atomic->value;
3072  pthread_mutex_unlock (&atomic_mutex);
3073 
3074  return res;
3075 #endif
3076 }
3077 
3083 void
3085 {
3086 #if DBUS_USE_SYNC
3087  /* Atomic version of "*atomic &= 0; return *atomic" */
3088  __sync_and_and_fetch (&atomic->value, 0);
3089 #else
3090  pthread_mutex_lock (&atomic_mutex);
3091  atomic->value = 0;
3092  pthread_mutex_unlock (&atomic_mutex);
3093 #endif
3094 }
3095 
3101 void
3103 {
3104 #if DBUS_USE_SYNC
3105  /* Atomic version of "*atomic |= 1; return *atomic" */
3106  __sync_or_and_fetch (&atomic->value, 1);
3107 #else
3108  pthread_mutex_lock (&atomic_mutex);
3109  atomic->value = 1;
3110  pthread_mutex_unlock (&atomic_mutex);
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 = _dbus_string_get_length (str);
3397  int fd;
3398  int result;
3399 #ifdef HAVE_GETRANDOM
3400  char *buffer;
3401 
3402  if (!_dbus_string_lengthen (str, n_bytes))
3403  {
3404  _DBUS_SET_OOM (error);
3405  return FALSE;
3406  }
3407 
3408  buffer = _dbus_string_get_data_len (str, old_len, n_bytes);
3409  result = getrandom (buffer, n_bytes, GRND_NONBLOCK);
3410 
3411  if (result == n_bytes)
3412  return TRUE;
3413 
3414  _dbus_string_set_length (str, old_len);
3415 #endif
3416 
3417  /* note, urandom on linux will fall back to pseudorandom */
3418  fd = open ("/dev/urandom", O_RDONLY);
3419 
3420  if (fd < 0)
3421  {
3422  dbus_set_error (error, _dbus_error_from_errno (errno),
3423  "Could not open /dev/urandom: %s",
3424  _dbus_strerror (errno));
3425  return FALSE;
3426  }
3427 
3428  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3429 
3430  result = _dbus_read (fd, str, n_bytes);
3431 
3432  if (result != n_bytes)
3433  {
3434  if (result < 0)
3435  dbus_set_error (error, _dbus_error_from_errno (errno),
3436  "Could not read /dev/urandom: %s",
3437  _dbus_strerror (errno));
3438  else
3440  "Short read from /dev/urandom");
3441 
3442  _dbus_close (fd, NULL);
3443  _dbus_string_set_length (str, old_len);
3444  return FALSE;
3445  }
3446 
3447  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3448  n_bytes);
3449 
3450  _dbus_close (fd, NULL);
3451 
3452  return TRUE;
3453 }
3454 
3460 void
3461 _dbus_exit (int code)
3462 {
3463  _exit (code);
3464 }
3465 
3474 const char*
3475 _dbus_strerror (int error_number)
3476 {
3477  const char *msg;
3478 
3479  msg = strerror (error_number);
3480  if (msg == NULL)
3481  msg = "unknown";
3482 
3483  return msg;
3484 }
3485 
3489 void
3491 {
3492  signal (SIGPIPE, SIG_IGN);
3493 }
3494 
3502 void
3504 {
3505  int val;
3506 
3507  val = fcntl (fd, F_GETFD, 0);
3508 
3509  if (val < 0)
3510  return;
3511 
3512  val |= FD_CLOEXEC;
3513 
3514  fcntl (fd, F_SETFD, val);
3515 }
3516 
3524 void
3526 {
3527  int val;
3528 
3529  val = fcntl (fd, F_GETFD, 0);
3530 
3531  if (val < 0)
3532  return;
3533 
3534  val &= ~FD_CLOEXEC;
3535 
3536  fcntl (fd, F_SETFD, val);
3537 }
3538 
3547 _dbus_close (int fd,
3548  DBusError *error)
3549 {
3550  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3551 
3552  again:
3553  if (close (fd) < 0)
3554  {
3555  if (errno == EINTR)
3556  goto again;
3557 
3558  dbus_set_error (error, _dbus_error_from_errno (errno),
3559  "Could not close fd %d", fd);
3560  return FALSE;
3561  }
3562 
3563  return TRUE;
3564 }
3565 
3574 int
3575 _dbus_dup(int fd,
3576  DBusError *error)
3577 {
3578  int new_fd;
3579 
3580 #ifdef F_DUPFD_CLOEXEC
3581  dbus_bool_t cloexec_done;
3582 
3583  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3584  cloexec_done = new_fd >= 0;
3585 
3586  if (new_fd < 0 && errno == EINVAL)
3587 #endif
3588  {
3589  new_fd = fcntl(fd, F_DUPFD, 3);
3590  }
3591 
3592  if (new_fd < 0) {
3593 
3594  dbus_set_error (error, _dbus_error_from_errno (errno),
3595  "Could not duplicate fd %d", fd);
3596  return -1;
3597  }
3598 
3599 #ifdef F_DUPFD_CLOEXEC
3600  if (!cloexec_done)
3601 #endif
3602  {
3604  }
3605 
3606  return new_fd;
3607 }
3608 
3618  DBusError *error)
3619 {
3620  return _dbus_set_fd_nonblocking (fd.fd, error);
3621 }
3622 
3623 static dbus_bool_t
3624 _dbus_set_fd_nonblocking (int fd,
3625  DBusError *error)
3626 {
3627  int val;
3628 
3629  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3630 
3631  val = fcntl (fd, F_GETFL, 0);
3632  if (val < 0)
3633  {
3634  dbus_set_error (error, _dbus_error_from_errno (errno),
3635  "Failed to get flags from file descriptor %d: %s",
3636  fd, _dbus_strerror (errno));
3637  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3638  _dbus_strerror (errno));
3639  return FALSE;
3640  }
3641 
3642  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3643  {
3644  dbus_set_error (error, _dbus_error_from_errno (errno),
3645  "Failed to set nonblocking flag of file descriptor %d: %s",
3646  fd, _dbus_strerror (errno));
3647  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3648  fd, _dbus_strerror (errno));
3649 
3650  return FALSE;
3651  }
3652 
3653  return TRUE;
3654 }
3655 
3661 void
3663 {
3664 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3665  void *bt[500];
3666  int bt_size;
3667  int i;
3668  char **syms;
3669 
3670  bt_size = backtrace (bt, 500);
3671 
3672  syms = backtrace_symbols (bt, bt_size);
3673 
3674  i = 0;
3675  while (i < bt_size)
3676  {
3677  /* don't use dbus_warn since it can _dbus_abort() */
3678  fprintf (stderr, " %s\n", syms[i]);
3679  ++i;
3680  }
3681  fflush (stderr);
3682 
3683  free (syms);
3684 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3685  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3686 #else
3687  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3688 #endif
3689 }
3690 
3705  DBusSocket *fd2,
3706  dbus_bool_t blocking,
3707  DBusError *error)
3708 {
3709 #ifdef HAVE_SOCKETPAIR
3710  int fds[2];
3711  int retval;
3712 
3713 #ifdef SOCK_CLOEXEC
3714  dbus_bool_t cloexec_done;
3715 
3716  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3717  cloexec_done = retval >= 0;
3718 
3719  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3720 #endif
3721  {
3722  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3723  }
3724 
3725  if (retval < 0)
3726  {
3727  dbus_set_error (error, _dbus_error_from_errno (errno),
3728  "Could not create full-duplex pipe");
3729  return FALSE;
3730  }
3731 
3732  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3733 
3734 #ifdef SOCK_CLOEXEC
3735  if (!cloexec_done)
3736 #endif
3737  {
3738  _dbus_fd_set_close_on_exec (fds[0]);
3739  _dbus_fd_set_close_on_exec (fds[1]);
3740  }
3741 
3742  if (!blocking &&
3743  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3744  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3745  {
3746  dbus_set_error (error, _dbus_error_from_errno (errno),
3747  "Could not set full-duplex pipe nonblocking");
3748 
3749  _dbus_close (fds[0], NULL);
3750  _dbus_close (fds[1], NULL);
3751 
3752  return FALSE;
3753  }
3754 
3755  fd1->fd = fds[0];
3756  fd2->fd = fds[1];
3757 
3758  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3759  fd1->fd, fd2->fd);
3760 
3761  return TRUE;
3762 #else
3763  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3765  "_dbus_socketpair() not implemented on this OS");
3766  return FALSE;
3767 #endif
3768 }
3769 
3778 int
3780  va_list args)
3781 {
3782  char static_buf[1024];
3783  int bufsize = sizeof (static_buf);
3784  int len;
3785  va_list args_copy;
3786 
3787  DBUS_VA_COPY (args_copy, args);
3788  len = vsnprintf (static_buf, bufsize, format, args_copy);
3789  va_end (args_copy);
3790 
3791  /* If vsnprintf() returned non-negative, then either the string fits in
3792  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3793  * returns the number of characters that were needed, or this OS returns the
3794  * truncated length.
3795  *
3796  * We ignore the possibility that snprintf might just ignore the length and
3797  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3798  * If your libc is really that bad, come back when you have a better one. */
3799  if (len == bufsize)
3800  {
3801  /* This could be the truncated length (Tru64 and IRIX have this bug),
3802  * or the real length could be coincidentally the same. Which is it?
3803  * If vsnprintf returns the truncated length, we'll go to the slow
3804  * path. */
3805  DBUS_VA_COPY (args_copy, args);
3806 
3807  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3808  len = -1;
3809 
3810  va_end (args_copy);
3811  }
3812 
3813  /* If vsnprintf() returned negative, we have to do more work.
3814  * HP-UX returns negative. */
3815  while (len < 0)
3816  {
3817  char *buf;
3818 
3819  bufsize *= 2;
3820 
3821  buf = dbus_malloc (bufsize);
3822 
3823  if (buf == NULL)
3824  return -1;
3825 
3826  DBUS_VA_COPY (args_copy, args);
3827  len = vsnprintf (buf, bufsize, format, args_copy);
3828  va_end (args_copy);
3829 
3830  dbus_free (buf);
3831 
3832  /* If the reported length is exactly the buffer size, round up to the
3833  * next size, in case vsnprintf has been returning the truncated
3834  * length */
3835  if (len == bufsize)
3836  len = -1;
3837  }
3838 
3839  return len;
3840 }
3841 
3848 const char*
3850 {
3851  /* Protected by _DBUS_LOCK_sysdeps */
3852  static const char* tmpdir = NULL;
3853 
3854  if (!_DBUS_LOCK (sysdeps))
3855  return NULL;
3856 
3857  if (tmpdir == NULL)
3858  {
3859  /* TMPDIR is what glibc uses, then
3860  * glibc falls back to the P_tmpdir macro which
3861  * just expands to "/tmp"
3862  */
3863  if (tmpdir == NULL)
3864  tmpdir = getenv("TMPDIR");
3865 
3866  /* These two env variables are probably
3867  * broken, but maybe some OS uses them?
3868  */
3869  if (tmpdir == NULL)
3870  tmpdir = getenv("TMP");
3871  if (tmpdir == NULL)
3872  tmpdir = getenv("TEMP");
3873 
3874  /* And this is the sane fallback. */
3875  if (tmpdir == NULL)
3876  tmpdir = "/tmp";
3877  }
3878 
3879  _DBUS_UNLOCK (sysdeps);
3880 
3881  _dbus_assert(tmpdir != NULL);
3882 
3883  return tmpdir;
3884 }
3885 
3886 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3887 
3906 static dbus_bool_t
3907 _read_subprocess_line_argv (const char *progpath,
3908  dbus_bool_t path_fallback,
3909  const char * const *argv,
3910  DBusString *result,
3911  DBusError *error)
3912 {
3913  int result_pipe[2] = { -1, -1 };
3914  int errors_pipe[2] = { -1, -1 };
3915  pid_t pid;
3916  int ret;
3917  int status;
3918  int orig_len;
3919 
3920  dbus_bool_t retval;
3921  sigset_t new_set, old_set;
3922 
3923  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3924  retval = FALSE;
3925 
3926  /* We need to block any existing handlers for SIGCHLD temporarily; they
3927  * will cause waitpid() below to fail.
3928  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3929  */
3930  sigemptyset (&new_set);
3931  sigaddset (&new_set, SIGCHLD);
3932  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3933 
3934  orig_len = _dbus_string_get_length (result);
3935 
3936 #define READ_END 0
3937 #define WRITE_END 1
3938  if (pipe (result_pipe) < 0)
3939  {
3940  dbus_set_error (error, _dbus_error_from_errno (errno),
3941  "Failed to create a pipe to call %s: %s",
3942  progpath, _dbus_strerror (errno));
3943  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3944  progpath, _dbus_strerror (errno));
3945  goto out;
3946  }
3947  if (pipe (errors_pipe) < 0)
3948  {
3949  dbus_set_error (error, _dbus_error_from_errno (errno),
3950  "Failed to create a pipe to call %s: %s",
3951  progpath, _dbus_strerror (errno));
3952  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3953  progpath, _dbus_strerror (errno));
3954  goto out;
3955  }
3956 
3957  /* Make sure our output buffers aren't redundantly printed by both the
3958  * parent and the child */
3959  fflush (stdout);
3960  fflush (stderr);
3961 
3962  pid = fork ();
3963  if (pid < 0)
3964  {
3965  dbus_set_error (error, _dbus_error_from_errno (errno),
3966  "Failed to fork() to call %s: %s",
3967  progpath, _dbus_strerror (errno));
3968  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3969  progpath, _dbus_strerror (errno));
3970  goto out;
3971  }
3972 
3973  if (pid == 0)
3974  {
3975  /* child process */
3976  const char *error_str;
3977 
3978  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3979  {
3980  int saved_errno = errno;
3981 
3982  /* Try to write details into the pipe, but don't bother
3983  * trying too hard (no retry loop). */
3984 
3985  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3986  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3987  {
3988  /* ignore, not much we can do */
3989  }
3990 
3991  error_str = _dbus_strerror (saved_errno);
3992 
3993  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3994  {
3995  /* ignore, not much we can do */
3996  }
3997 
3998  _exit (1);
3999  }
4000 
4001  /* set-up stdXXX */
4002  close (result_pipe[READ_END]);
4003  close (errors_pipe[READ_END]);
4004 
4005  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
4006  _exit (1);
4007  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
4008  _exit (1);
4009 
4010  _dbus_close_all ();
4011 
4012  sigprocmask (SIG_SETMASK, &old_set, NULL);
4013 
4014  /* If it looks fully-qualified, try execv first */
4015  if (progpath[0] == '/')
4016  {
4017  execv (progpath, (char * const *) argv);
4018  /* Ok, that failed. Now if path_fallback is given, let's
4019  * try unqualified. This is mostly a hack to work
4020  * around systems which ship dbus-launch in /usr/bin
4021  * but everything else in /bin (because dbus-launch
4022  * depends on X11).
4023  */
4024  if (path_fallback)
4025  /* We must have a slash, because we checked above */
4026  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4027  }
4028  else
4029  execvp (progpath, (char * const *) argv);
4030 
4031  /* still nothing, we failed */
4032  _exit (1);
4033  }
4034 
4035  /* parent process */
4036  close (result_pipe[WRITE_END]);
4037  close (errors_pipe[WRITE_END]);
4038  result_pipe[WRITE_END] = -1;
4039  errors_pipe[WRITE_END] = -1;
4040 
4041  ret = 0;
4042  do
4043  {
4044  ret = _dbus_read (result_pipe[READ_END], result, 1024);
4045  }
4046  while (ret > 0);
4047 
4048  /* reap the child process to avoid it lingering as zombie */
4049  do
4050  {
4051  ret = waitpid (pid, &status, 0);
4052  }
4053  while (ret == -1 && errno == EINTR);
4054 
4055  /* We succeeded if the process exited with status 0 and
4056  anything was read */
4057  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4058  {
4059  /* The process ended with error */
4060  DBusString error_message;
4061  if (!_dbus_string_init (&error_message))
4062  {
4063  _DBUS_SET_OOM (error);
4064  goto out;
4065  }
4066 
4067  ret = 0;
4068  do
4069  {
4070  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4071  }
4072  while (ret > 0);
4073 
4074  _dbus_string_set_length (result, orig_len);
4075  if (_dbus_string_get_length (&error_message) > 0)
4077  "%s terminated abnormally with the following error: %s",
4078  progpath, _dbus_string_get_data (&error_message));
4079  else
4081  "%s terminated abnormally without any error message",
4082  progpath);
4083  goto out;
4084  }
4085 
4086  retval = TRUE;
4087 
4088  out:
4089  sigprocmask (SIG_SETMASK, &old_set, NULL);
4090 
4091  _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4092 
4093  if (result_pipe[0] != -1)
4094  close (result_pipe[0]);
4095  if (result_pipe[1] != -1)
4096  close (result_pipe[1]);
4097  if (errors_pipe[0] != -1)
4098  close (errors_pipe[0]);
4099  if (errors_pipe[1] != -1)
4100  close (errors_pipe[1]);
4101 
4102  return retval;
4103 }
4104 #endif
4105 
4119 _dbus_get_autolaunch_address (const char *scope,
4120  DBusString *address,
4121  DBusError *error)
4122 {
4123 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4124  static const char arg_dbus_launch[] = "dbus-launch";
4125  static const char arg_autolaunch[] = "--autolaunch";
4126  static const char arg_binary_syntax[] = "--binary-syntax";
4127  static const char arg_close_stderr[] = "--close-stderr";
4128 
4129  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4130  * but that's done elsewhere, and if it worked, this function wouldn't
4131  * be called.) */
4132  const char *display;
4133  const char *progpath;
4134  const char *argv[6];
4135  int i;
4136  DBusString uuid;
4137  dbus_bool_t retval;
4138 
4139  if (_dbus_check_setuid ())
4140  {
4142  "Unable to autolaunch when setuid");
4143  return FALSE;
4144  }
4145 
4146  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4147  retval = FALSE;
4148 
4149  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4150  * dbus-launch-x11 is just going to fail. Rather than trying to
4151  * run it, we might as well bail out early with a nice error.
4152  *
4153  * This is not strictly true in a world where the user bus exists,
4154  * because dbus-launch --autolaunch knows how to connect to that -
4155  * but if we were going to connect to the user bus, we'd have done
4156  * so before trying autolaunch: in any case. */
4157  display = _dbus_getenv ("DISPLAY");
4158 
4159  if (display == NULL || display[0] == '\0')
4160  {
4162  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4163  return FALSE;
4164  }
4165 
4166  if (!_dbus_string_init (&uuid))
4167  {
4168  _DBUS_SET_OOM (error);
4169  return FALSE;
4170  }
4171 
4172  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4173  {
4174  goto out;
4175  }
4176 
4177 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4178  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4179 
4180  if (progpath == NULL)
4181 #endif
4182  progpath = DBUS_BINDIR "/dbus-launch";
4183  /*
4184  * argv[0] is always dbus-launch, that's the name what we'll
4185  * get from /proc, or ps(1), regardless what the progpath is,
4186  * see fd.o#69716
4187  */
4188  i = 0;
4189  argv[i] = arg_dbus_launch;
4190  ++i;
4191  argv[i] = arg_autolaunch;
4192  ++i;
4193  argv[i] = _dbus_string_get_data (&uuid);
4194  ++i;
4195  argv[i] = arg_binary_syntax;
4196  ++i;
4197  argv[i] = arg_close_stderr;
4198  ++i;
4199  argv[i] = NULL;
4200  ++i;
4201 
4202  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4203 
4204  retval = _read_subprocess_line_argv (progpath,
4205  TRUE,
4206  argv, address, error);
4207 
4208  out:
4209  _dbus_string_free (&uuid);
4210  return retval;
4211 #else
4213  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4214  "set your DBUS_SESSION_BUS_ADDRESS instead");
4215  return FALSE;
4216 #endif
4217 }
4218 
4239  dbus_bool_t create_if_not_found,
4240  DBusError *error)
4241 {
4242  DBusError our_error = DBUS_ERROR_INIT;
4243  DBusError etc_error = DBUS_ERROR_INIT;
4244  DBusString filename;
4245  dbus_bool_t b;
4246 
4247  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4248 
4249  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4250  if (b)
4251  return TRUE;
4252 
4253  /* Fallback to the system machine ID */
4254  _dbus_string_init_const (&filename, "/etc/machine-id");
4255  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4256 
4257  if (b)
4258  {
4259  if (create_if_not_found)
4260  {
4261  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4262  * complain if that isn't possible for whatever reason */
4263  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4264  _dbus_write_uuid_file (&filename, machine_id, NULL);
4265  }
4266 
4267  dbus_error_free (&our_error);
4268  return TRUE;
4269  }
4270 
4271  if (!create_if_not_found)
4272  {
4273  dbus_set_error (error, etc_error.name,
4274  "D-Bus library appears to be incorrectly set up: "
4275  "see the manual page for dbus-uuidgen to correct "
4276  "this issue. (%s; %s)",
4277  our_error.message, etc_error.message);
4278  dbus_error_free (&our_error);
4279  dbus_error_free (&etc_error);
4280  return FALSE;
4281  }
4282 
4283  dbus_error_free (&our_error);
4284  dbus_error_free (&etc_error);
4285 
4286  /* if none found, try to make a new one */
4287  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4288 
4289  if (!_dbus_generate_uuid (machine_id, error))
4290  return FALSE;
4291 
4292  return _dbus_write_uuid_file (&filename, machine_id, error);
4293 }
4294 
4304  const char *launchd_env_var,
4305  DBusError *error)
4306 {
4307 #ifdef DBUS_ENABLE_LAUNCHD
4308  char *argv[4];
4309  int i;
4310 
4311  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4312 
4313  if (_dbus_check_setuid ())
4314  {
4316  "Unable to find launchd socket when setuid");
4317  return FALSE;
4318  }
4319 
4320  i = 0;
4321  argv[i] = "launchctl";
4322  ++i;
4323  argv[i] = "getenv";
4324  ++i;
4325  argv[i] = (char*)launchd_env_var;
4326  ++i;
4327  argv[i] = NULL;
4328  ++i;
4329 
4330  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4331 
4332  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4333  {
4334  return FALSE;
4335  }
4336 
4337  /* no error, but no result either */
4338  if (_dbus_string_get_length(socket_path) == 0)
4339  {
4340  return FALSE;
4341  }
4342 
4343  /* strip the carriage-return */
4344  _dbus_string_shorten(socket_path, 1);
4345  return TRUE;
4346 #else /* DBUS_ENABLE_LAUNCHD */
4348  "can't lookup socket from launchd; launchd support not compiled in");
4349  return FALSE;
4350 #endif
4351 }
4352 
4353 #ifdef DBUS_ENABLE_LAUNCHD
4354 static dbus_bool_t
4355 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4356 {
4357  dbus_bool_t valid_socket;
4358  DBusString socket_path;
4359 
4360  if (_dbus_check_setuid ())
4361  {
4363  "Unable to find launchd socket when setuid");
4364  return FALSE;
4365  }
4366 
4367  if (!_dbus_string_init (&socket_path))
4368  {
4369  _DBUS_SET_OOM (error);
4370  return FALSE;
4371  }
4372 
4373  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4374 
4375  if (dbus_error_is_set(error))
4376  {
4377  _dbus_string_free(&socket_path);
4378  return FALSE;
4379  }
4380 
4381  if (!valid_socket)
4382  {
4383  dbus_set_error(error, "no socket path",
4384  "launchd did not provide a socket path, "
4385  "verify that org.freedesktop.dbus-session.plist is loaded!");
4386  _dbus_string_free(&socket_path);
4387  return FALSE;
4388  }
4389  if (!_dbus_string_append (address, "unix:path="))
4390  {
4391  _DBUS_SET_OOM (error);
4392  _dbus_string_free(&socket_path);
4393  return FALSE;
4394  }
4395  if (!_dbus_string_copy (&socket_path, 0, address,
4396  _dbus_string_get_length (address)))
4397  {
4398  _DBUS_SET_OOM (error);
4399  _dbus_string_free(&socket_path);
4400  return FALSE;
4401  }
4402 
4403  _dbus_string_free(&socket_path);
4404  return TRUE;
4405 }
4406 #endif
4407 
4409 _dbus_lookup_user_bus (dbus_bool_t *supported,
4410  DBusString *address,
4411  DBusError *error)
4412 {
4413  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4414  dbus_bool_t ret = FALSE;
4415  struct stat stbuf;
4416  DBusString user_bus_path;
4417 
4418  if (runtime_dir == NULL)
4419  {
4420  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4421  *supported = FALSE;
4422  return TRUE; /* Cannot use it, but not an error */
4423  }
4424 
4425  if (!_dbus_string_init (&user_bus_path))
4426  {
4427  _DBUS_SET_OOM (error);
4428  return FALSE;
4429  }
4430 
4431  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4432  {
4433  _DBUS_SET_OOM (error);
4434  goto out;
4435  }
4436 
4437  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4438  {
4439  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4440  _dbus_strerror (errno));
4441  *supported = FALSE;
4442  ret = TRUE; /* Cannot use it, but not an error */
4443  goto out;
4444  }
4445 
4446  if (stbuf.st_uid != getuid ())
4447  {
4448  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4449  (long) stbuf.st_uid, (long) getuid ());
4450  *supported = FALSE;
4451  ret = TRUE; /* Cannot use it, but not an error */
4452  goto out;
4453  }
4454 
4455  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4456  {
4457  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4458  (long) stbuf.st_mode);
4459  *supported = FALSE;
4460  ret = TRUE; /* Cannot use it, but not an error */
4461  goto out;
4462  }
4463 
4464  if (!_dbus_string_append (address, "unix:path=") ||
4465  !_dbus_address_append_escaped (address, &user_bus_path))
4466  {
4467  _DBUS_SET_OOM (error);
4468  goto out;
4469  }
4470 
4471  *supported = TRUE;
4472  ret = TRUE;
4473 
4474 out:
4475  _dbus_string_free (&user_bus_path);
4476  return ret;
4477 }
4478 
4500  DBusString *address,
4501  DBusError *error)
4502 {
4503 #ifdef DBUS_ENABLE_LAUNCHD
4504  *supported = TRUE;
4505  return _dbus_lookup_session_address_launchd (address, error);
4506 #else
4507  *supported = FALSE;
4508 
4509  if (!_dbus_lookup_user_bus (supported, address, error))
4510  return FALSE;
4511  else if (*supported)
4512  return TRUE;
4513 
4514  /* On non-Mac Unix platforms, if the session address isn't already
4515  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4516  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4517  * autolaunch: global default; see init_session_address in
4518  * dbus/dbus-bus.c. */
4519  return TRUE;
4520 #endif
4521 }
4522 
4530 void
4532 {
4534 }
4535 
4551  DBusCredentials *credentials)
4552 {
4553  DBusString homedir;
4554  DBusString dotdir;
4555  dbus_uid_t uid;
4556 
4557  _dbus_assert (credentials != NULL);
4559 
4560  if (!_dbus_string_init (&homedir))
4561  return FALSE;
4562 
4563  uid = _dbus_credentials_get_unix_uid (credentials);
4564  _dbus_assert (uid != DBUS_UID_UNSET);
4565 
4566  if (!_dbus_homedir_from_uid (uid, &homedir))
4567  goto failed;
4568 
4569 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4570  {
4571  const char *override;
4572 
4573  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4574  if (override != NULL && *override != '\0')
4575  {
4576  _dbus_string_set_length (&homedir, 0);
4577  if (!_dbus_string_append (&homedir, override))
4578  goto failed;
4579 
4580  _dbus_verbose ("Using fake homedir for testing: %s\n",
4581  _dbus_string_get_const_data (&homedir));
4582  }
4583  else
4584  {
4585  /* Not strictly thread-safe, but if we fail at thread-safety here,
4586  * the worst that will happen is some extra warnings. */
4587  static dbus_bool_t already_warned = FALSE;
4588  if (!already_warned)
4589  {
4590  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4591  _dbus_string_get_const_data (&homedir));
4592  already_warned = TRUE;
4593  }
4594  }
4595  }
4596 #endif
4597 
4598  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4599  if (!_dbus_concat_dir_and_file (&homedir,
4600  &dotdir))
4601  goto failed;
4602 
4603  if (!_dbus_string_copy (&homedir, 0,
4604  directory, _dbus_string_get_length (directory))) {
4605  goto failed;
4606  }
4607 
4608  _dbus_string_free (&homedir);
4609  return TRUE;
4610 
4611  failed:
4612  _dbus_string_free (&homedir);
4613  return FALSE;
4614 }
4615 
4616 //PENDING(kdab) docs
4618 _dbus_daemon_publish_session_bus_address (const char* addr,
4619  const char *scope)
4620 {
4621  return TRUE;
4622 }
4623 
4624 //PENDING(kdab) docs
4625 void
4626 _dbus_daemon_unpublish_session_bus_address (void)
4627 {
4628 
4629 }
4630 
4639 {
4640  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4641  * EWOULDBLOCK are numerically equal, which is permitted as described by
4642  * errno(3).
4643  */
4644 #if EAGAIN == EWOULDBLOCK
4645  return e == EAGAIN;
4646 #else
4647  return e == EAGAIN || e == EWOULDBLOCK;
4648 #endif
4649 }
4650 
4660  DBusError *error)
4661 {
4662  const char *filename_c;
4663 
4664  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4665 
4666  filename_c = _dbus_string_get_const_data (filename);
4667 
4668  if (rmdir (filename_c) != 0)
4669  {
4671  "Failed to remove directory %s: %s\n",
4672  filename_c, _dbus_strerror (errno));
4673  return FALSE;
4674  }
4675 
4676  return TRUE;
4677 }
4678 
4688 {
4689 #ifdef SCM_RIGHTS
4690  union {
4691  struct sockaddr sa;
4692  struct sockaddr_storage storage;
4693  struct sockaddr_un un;
4694  } sa_buf;
4695 
4696  socklen_t sa_len = sizeof(sa_buf);
4697 
4698  _DBUS_ZERO(sa_buf);
4699 
4700  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4701  return FALSE;
4702 
4703  return sa_buf.sa.sa_family == AF_UNIX;
4704 
4705 #else
4706  return FALSE;
4707 
4708 #endif
4709 }
4710 
4711 static void
4712 close_ignore_error (int fd)
4713 {
4714  close (fd);
4715 }
4716 
4717 /*
4718  * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4719  * and may call func for integers that are not actually valid fds.
4720  */
4721 static void
4722 act_on_fds_3_and_up (void (*func) (int fd))
4723 {
4724  int maxfds, i;
4725 
4726 #ifdef __linux__
4727  DIR *d;
4728 
4729  /* On Linux we can optimize this a bit if /proc is available. If it
4730  isn't available, fall back to the brute force way. */
4731 
4732  d = opendir ("/proc/self/fd");
4733  if (d)
4734  {
4735  for (;;)
4736  {
4737  struct dirent *de;
4738  int fd;
4739  long l;
4740  char *e = NULL;
4741 
4742  de = readdir (d);
4743  if (!de)
4744  break;
4745 
4746  if (de->d_name[0] == '.')
4747  continue;
4748 
4749  errno = 0;
4750  l = strtol (de->d_name, &e, 10);
4751  if (errno != 0 || e == NULL || *e != '\0')
4752  continue;
4753 
4754  fd = (int) l;
4755  if (fd < 3)
4756  continue;
4757 
4758  if (fd == dirfd (d))
4759  continue;
4760 
4761  func (fd);
4762  }
4763 
4764  closedir (d);
4765  return;
4766  }
4767 #endif
4768 
4769  maxfds = sysconf (_SC_OPEN_MAX);
4770 
4771  /* Pick something reasonable if for some reason sysconf says
4772  * unlimited.
4773  */
4774  if (maxfds < 0)
4775  maxfds = 1024;
4776 
4777  /* close all inherited fds */
4778  for (i = 3; i < maxfds; i++)
4779  func (i);
4780 }
4781 
4786 void
4788 {
4789  act_on_fds_3_and_up (close_ignore_error);
4790 }
4791 
4796 void
4798 {
4799  act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4800 }
4801 
4813 {
4814  /* TODO: get __libc_enable_secure exported from glibc.
4815  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4816  */
4817 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4818  {
4819  /* See glibc/include/unistd.h */
4820  extern int __libc_enable_secure;
4821  return __libc_enable_secure;
4822  }
4823 #elif defined(HAVE_ISSETUGID)
4824  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4825  return issetugid ();
4826 #else
4827  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4828  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4829 
4830  /* We call into this function from _dbus_threads_init_platform_specific()
4831  * to make sure these are initialized before we start threading. */
4832  static dbus_bool_t check_setuid_initialised;
4833  static dbus_bool_t is_setuid;
4834 
4835  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4836  {
4837 #ifdef HAVE_GETRESUID
4838  if (getresuid (&ruid, &euid, &suid) != 0 ||
4839  getresgid (&rgid, &egid, &sgid) != 0)
4840 #endif /* HAVE_GETRESUID */
4841  {
4842  suid = ruid = getuid ();
4843  sgid = rgid = getgid ();
4844  euid = geteuid ();
4845  egid = getegid ();
4846  }
4847 
4848  check_setuid_initialised = TRUE;
4849  is_setuid = (ruid != euid || ruid != suid ||
4850  rgid != egid || rgid != sgid);
4851 
4852  }
4853  return is_setuid;
4854 #endif
4855 }
4856 
4866  DBusString *address,
4867  DBusError *error)
4868 {
4869  union {
4870  struct sockaddr sa;
4871  struct sockaddr_storage storage;
4872  struct sockaddr_un un;
4873  struct sockaddr_in ipv4;
4874  struct sockaddr_in6 ipv6;
4875  } socket;
4876  char hostip[INET6_ADDRSTRLEN];
4877  socklen_t size = sizeof (socket);
4878  DBusString path_str;
4879  const char *family_name = NULL;
4880  dbus_uint16_t port;
4881 
4882  if (getsockname (fd.fd, &socket.sa, &size))
4883  goto err;
4884 
4885  switch (socket.sa.sa_family)
4886  {
4887  case AF_UNIX:
4888  if (socket.un.sun_path[0]=='\0')
4889  {
4890  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4891  if (_dbus_string_append (address, "unix:abstract=") &&
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  else
4903  {
4904  _dbus_string_init_const (&path_str, socket.un.sun_path);
4905  if (_dbus_string_append (address, "unix:path=") &&
4906  _dbus_address_append_escaped (address, &path_str))
4907  {
4908  return TRUE;
4909  }
4910  else
4911  {
4912  _DBUS_SET_OOM (error);
4913  return FALSE;
4914  }
4915  }
4916  /* not reached */
4917  break;
4918 
4919  case AF_INET:
4920 #ifdef AF_INET6
4921  case AF_INET6:
4922 #endif
4923  _dbus_string_init_const (&path_str, hostip);
4924 
4925  if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
4926  &family_name, &port, error))
4927  {
4928  if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
4929  family_name, port) &&
4930  _dbus_address_append_escaped (address, &path_str))
4931  {
4932  return TRUE;
4933  }
4934  else
4935  {
4936  _DBUS_SET_OOM (error);
4937  return FALSE;
4938  }
4939  }
4940  else
4941  {
4942  return FALSE;
4943  }
4944  /* not reached */
4945  break;
4946 
4947  default:
4948  dbus_set_error (error,
4949  _dbus_error_from_errno (EINVAL),
4950  "Failed to read address from socket: Unknown socket type.");
4951  return FALSE;
4952  }
4953  err:
4954  dbus_set_error (error,
4955  _dbus_error_from_errno (errno),
4956  "Failed to read address from socket: %s",
4957  _dbus_strerror (errno));
4958  return FALSE;
4959 }
4960 
4961 int
4962 _dbus_save_socket_errno (void)
4963 {
4964  return errno;
4965 }
4966 
4967 void
4968 _dbus_restore_socket_errno (int saved_errno)
4969 {
4970  errno = saved_errno;
4971 }
4972 
4973 static const char *syslog_tag = "dbus";
4974 #ifdef HAVE_SYSLOG_H
4975 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4976 #endif
4977 
4992 void
4993 _dbus_init_system_log (const char *tag,
4994  DBusLogFlags flags)
4995 {
4996  /* We never want to turn off logging completely */
4997  _dbus_assert (
4998  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4999 
5000  syslog_tag = tag;
5001 
5002 #ifdef HAVE_SYSLOG_H
5003  log_flags = flags;
5004 
5005  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5006  openlog (tag, LOG_PID, LOG_DAEMON);
5007 #endif
5008 }
5009 
5017 void
5018 _dbus_logv (DBusSystemLogSeverity severity,
5019  const char *msg,
5020  va_list args)
5021 {
5022  va_list tmp;
5023 #ifdef HAVE_SYSLOG_H
5024  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5025  {
5026  int flags;
5027  switch (severity)
5028  {
5029  case DBUS_SYSTEM_LOG_INFO:
5030  flags = LOG_DAEMON | LOG_INFO;
5031  break;
5032  case DBUS_SYSTEM_LOG_WARNING:
5033  flags = LOG_DAEMON | LOG_WARNING;
5034  break;
5035  case DBUS_SYSTEM_LOG_SECURITY:
5036  flags = LOG_AUTH | LOG_NOTICE;
5037  break;
5038  case DBUS_SYSTEM_LOG_ERROR:
5039  flags = LOG_DAEMON|LOG_CRIT;
5040  break;
5041  default:
5042  _dbus_assert_not_reached ("invalid log severity");
5043  }
5044 
5045  DBUS_VA_COPY (tmp, args);
5046  vsyslog (flags, msg, tmp);
5047  va_end (tmp);
5048  }
5049 
5050  /* If we don't have syslog.h, we always behave as though stderr was in
5051  * the flags */
5052  if (log_flags & DBUS_LOG_FLAGS_STDERR)
5053 #endif
5054  {
5055  DBUS_VA_COPY (tmp, args);
5056  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5057  vfprintf (stderr, msg, tmp);
5058  fputc ('\n', stderr);
5059  va_end (tmp);
5060  }
5061 }
5062 
5063 /*
5064  * Return the low-level representation of a socket error, as used by
5065  * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5066  * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5067  *
5068  * Some libdbus internal functions copy this into errno, but with
5069  * hindsight that was probably a design flaw.
5070  */
5071 int
5072 _dbus_get_low_level_socket_errno (void)
5073 {
5074  return errno;
5075 }
5076 
5077 /* tests in dbus-sysdeps-util.c */
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:3038
_dbus_user_info_fill
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
Definition: dbus-sysdeps-unix.c:2884
_dbus_create_directory
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
Definition: dbus-sysdeps-unix.c:3286
DBusUserInfo::group_ids
dbus_gid_t * group_ids
Groups IDs, including above primary group.
Definition: dbus-sysdeps-unix.h:110
_DBUS_N_ELEMENTS
#define _DBUS_N_ELEMENTS(array)
Definition: dbus-internals.h:189
_dbus_user_info_fill_uid
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
Definition: dbus-sysdeps-unix.c:2901
DBusUserInfo::n_group_ids
int n_group_ids
Size of group IDs array.
Definition: dbus-sysdeps-unix.h:111
_dbus_getuid
dbus_uid_t _dbus_getuid(void)
Gets our UID.
Definition: dbus-sysdeps-unix.c:2973
dbus_realloc
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:604
_dbus_ensure_standard_fds
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 ...
Definition: dbus-sysdeps-unix.c:155
_dbus_append_address_from_socket
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.
Definition: dbus-sysdeps-unix.c:4865
_dbus_concat_dir_and_file
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
Definition: dbus-sysdeps-unix.c:3317
_dbus_read_socket_with_unix_fds
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.
Definition: dbus-sysdeps-unix.c:358
DBusAtomic::value
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:331
_dbus_verbose_bytes_of_string
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.
Definition: dbus-marshal-basic.c:1421
DBusPollFD::revents
short revents
Events that occurred.
Definition: dbus-sysdeps.h:425
_dbus_accept
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
Definition: dbus-sysdeps-unix.c:2522
_dbus_credentials_add_from_current_process
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...
Definition: dbus-sysdeps-unix.c:2923
_dbus_string_free
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:271
_dbus_atomic_set_nonzero
void _dbus_atomic_set_nonzero(DBusAtomic *atomic)
Atomically set the value of an integer to something nonzero.
Definition: dbus-sysdeps-unix.c:3102
_dbus_lookup_launchd_socket
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.
Definition: dbus-sysdeps-unix.c:4303
_dbus_generate_uuid
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
Definition: dbus-internals.c:720
_dbus_listen_systemd_sockets
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
Definition: dbus-sysdeps-unix.c:1252
_dbus_get_autolaunch_address
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
Definition: dbus-sysdeps-unix.c:4119
_dbus_error_from_errno
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_set_socket_nonblocking
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
Definition: dbus-sysdeps-unix.c:3617
dbus_set_error_const
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_write
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 ...
Definition: dbus-sysdeps-unix.c:772
_dbus_disable_sigpipe
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
Definition: dbus-sysdeps-unix.c:3490
_dbus_string_append_uint
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:401
DBUS_UID_FORMAT
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:151
_dbus_flush_caches
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked.
Definition: dbus-sysdeps-unix.c:4531
_dbus_logv
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
Definition: dbus-sysdeps-unix.c:5018
_dbus_connect_unix_socket
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.
Definition: dbus-sysdeps-unix.c:917
DBusPollFD::events
short events
Events to poll for.
Definition: dbus-sysdeps.h:424
_dbus_lookup_session_address
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.
Definition: dbus-sysdeps-unix.c:4499
_dbus_atomic_set_zero
void _dbus_atomic_set_zero(DBusAtomic *atomic)
Atomically set the value of an integer to 0.
Definition: dbus-sysdeps-unix.c:3084
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1307
_dbus_string_lengthen
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:784
_dbus_append_keyring_directory_for_credentials
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.
Definition: dbus-sysdeps-unix.c:4550
_dbus_get_monotonic_time
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Definition: dbus-sysdeps-unix.c:3201
DBusGUID
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
Definition: dbus-internals.h:432
DBusUserInfo::uid
dbus_uid_t uid
UID.
Definition: dbus-sysdeps-unix.h:108
dbus_error_init
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
_dbus_generate_random_bytes
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.
Definition: dbus-sysdeps-unix.c:3392
_dbus_connect_tcp_socket
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.
Definition: dbus-sysdeps-unix.c:1402
_dbus_listen_unix_socket
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.
Definition: dbus-sysdeps-unix.c:1125
_dbus_string_append_byte
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:1181
dbus_gid_t
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:139
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:3062
_dbus_connect_exec
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.
Definition: dbus-sysdeps-unix.c:1014
_DBUS_LOCK
#define _DBUS_LOCK(name)
Definition: dbus-internals.h:412
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:3575
TRUE
#define TRUE
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
WRITE_END
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn-unix.c:895
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-protocol.h:359
DBUS_ERROR_SPAWN_EXEC_FAILED
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
Definition: dbus-protocol.h:420
_dbus_init_system_log
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
Definition: dbus-sysdeps-unix.c:4993
_dbus_write_socket
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
Definition: dbus-sysdeps-unix.c:320
DBusUserInfo::username
char * username
Username.
Definition: dbus-sysdeps-unix.h:112
_dbus_listen_tcp_socket
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.
Definition: dbus-sysdeps-unix.c:1563
_dbus_read
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.
Definition: dbus-sysdeps-unix.c:712
_dbus_credentials_get_unix_uid
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
Definition: dbus-credentials.c:362
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:704
_dbus_socket_can_pass_unix_fd
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
Definition: dbus-sysdeps-unix.c:4687
_DBUS_POLLERR
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:435
dbus_malloc
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:464
_dbus_sleep_milliseconds
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
Definition: dbus-sysdeps-unix.c:3362
_dbus_exit
void _dbus_exit(int code)
Exit the process, returning the given value.
Definition: dbus-sysdeps-unix.c:3461
DBUS_ERROR_BAD_ADDRESS
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
Definition: dbus-protocol.h:371
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:139
DBusString
Definition: dbus-string.h:42
_dbus_check_setuid
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib.
Definition: dbus-sysdeps-unix.c:4812
_dbus_string_append_printf
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:1138
DBusPollFD::fd
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:423
DBusUserInfo::homedir
char * homedir
Home directory.
Definition: dbus-sysdeps-unix.h:113
_dbus_credentials_add_pid
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
Definition: dbus-credentials.c:158
DBusSocket
Socket interface.
Definition: dbus-sysdeps.h:181
DBusError::name
const char * name
public error name field
Definition: dbus-errors.h:50
_dbus_list_pop_first
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
_dbus_read_uuid_file
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.
Definition: dbus-internals.c:899
_dbus_credentials_clear
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
Definition: dbus-credentials.c:593
_dbus_printf_string_upper_bound
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.
Definition: dbus-sysdeps-unix.c:3779
DBusCredentials
Definition: dbus-credentials.c:49
DBUS_MAXIMUM_MESSAGE_UNIX_FDS
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
Definition: dbus-protocol.h:218
dbus_pid_t
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:135
dbus_uid_t
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:137
DBUS_GID_FORMAT
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:153
FALSE
#define FALSE
DBusPollFD
Definition: dbus-sysdeps.h:421
DBUS_ERROR_NO_MEMORY
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
Definition: dbus-protocol.h:361
_dbus_string_get_data_len
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:514
DBUS_ERROR_INIT
#define DBUS_ERROR_INIT
Definition: dbus-errors.h:62
_dbus_write_two
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.
Definition: dbus-sysdeps-unix.c:818
_dbus_check_dir_is_private_to_user
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.
Definition: dbus-sysdeps-unix.c:2577
_dbus_get_tmpdir
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR,...
Definition: dbus-sysdeps-unix.c:3849
DBUS_UID_UNSET
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:144
DBUS_PID_UNSET
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:142
_dbus_send_credentials_socket
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
Definition: dbus-sysdeps-unix.c:2501
_dbus_fd_set_close_on_exec
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
Definition: dbus-sysdeps-unix.c:3503
dbus_error_is_set
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
_dbus_poll
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
Definition: dbus-sysdeps-unix.c:3123
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Definition: dbus-internals.h:164
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:826
_dbus_read_socket
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Definition: dbus-sysdeps-unix.c:302
DBusAtomic
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:326
dbus_new
#define dbus_new(type, count)
Definition: dbus-memory.h:57
_dbus_close_socket
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
Definition: dbus-sysdeps-unix.c:286
READ_END
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn-unix.c:893
_dbus_address_append_escaped
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:107
_dbus_credentials_take_unix_gids
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.
Definition: dbus-credentials.c:205
_dbus_get_real_time
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Definition: dbus-sysdeps-unix.c:3232
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:153
dbus_error_free
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
DBusUserInfo
Information about a UNIX user.
Definition: dbus-sysdeps-unix.h:106
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:3547
_dbus_socketpair
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
Definition: dbus-sysdeps-unix.c:3704
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:238
_dbus_geteuid
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
Definition: dbus-sysdeps-unix.c:2982
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:589
_dbus_user_database_flush_system
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:357
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
_dbus_fd_clear_close_on_exec
void _dbus_fd_clear_close_on_exec(int fd)
Sets the file descriptor to not be close-on-exec.
Definition: dbus-sysdeps-unix.c:3525
_dbus_getpid
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
Definition: dbus-sysdeps-unix.c:2964
_dbus_credentials_are_anonymous
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
Definition: dbus-credentials.c:479
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
_dbus_print_backtrace
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
Definition: dbus-sysdeps-unix.c:3662
_dbus_credentials_add_adt_audit_data
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.
Definition: dbus-credentials.c:294
DBusList
Definition: dbus-list.h:34
_dbus_append_user_from_current_process
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...
Definition: dbus-sysdeps-unix.c:2953
_dbus_ensure_directory
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
Definition: dbus-sysdeps-unix.c:3254
dbus_set_error
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_PID_FORMAT
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:149
_DBUS_POLLIN
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:429
DBusUserInfo::primary_gid
dbus_gid_t primary_gid
GID.
Definition: dbus-sysdeps-unix.h:109
_dbus_write_uuid_file
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
Definition: dbus-internals.c:850
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:3015
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Definition: dbus-internals.h:413
_dbus_read_local_machine_uuid
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
Definition: dbus-sysdeps-unix.c:4238
_dbus_credentials_add_linux_security_label
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.
Definition: dbus-credentials.c:270
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
_DBUS_ZERO
#define _DBUS_ZERO(object)
Definition: dbus-internals.h:194
_dbus_homedir_from_uid
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:427
_dbus_get_local_machine_uuid_encoded
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.
Definition: dbus-internals.c:951
DBUS_GID_UNSET
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:146
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
dbus_new0
#define dbus_new0(type, count)
Definition: dbus-memory.h:58
_dbus_delete_directory
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Definition: dbus-sysdeps-unix.c:4659
_dbus_fd_set_all_close_on_exec
void _dbus_fd_set_all_close_on_exec(void)
Sets all file descriptors except the first three (i.e.
Definition: dbus-sysdeps-unix.c:4797
_dbus_get_is_errno_eagain_or_ewouldblock
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)
Definition: dbus-sysdeps-unix.c:4638
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:373
_dbus_string_shorten
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:804
_dbus_close_all
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
Definition: dbus-sysdeps-unix.c:4787
_dbus_string_append
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:959
_dbus_write_socket_two
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.
Definition: dbus-sysdeps-unix.c:639
_dbus_pid_for_log
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...
Definition: dbus-sysdeps-unix.c:2994
_DBUS_POLLOUT
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:433
_DBUS_INT32_MAX
#define _DBUS_INT32_MAX
Definition: dbus-internals.h:298
DBUS_ERROR_IO_ERROR
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
Definition: dbus-protocol.h:369
_dbus_read_credentials_socket
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...
Definition: dbus-sysdeps-unix.c:2171
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
NULL
#define NULL
_dbus_credentials_add_unix_uid
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
Definition: dbus-credentials.c:173