D-Bus  1.13.20
dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-file.h"
33 #include "dbus-transport.h"
34 #include "dbus-string.h"
35 #include "dbus-userdb.h"
36 #include "dbus-list.h"
37 #include "dbus-credentials.h"
38 #include "dbus-nonce.h"
39 
40 #include <sys/types.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <fcntl.h>
47 #include <sys/socket.h>
48 #include <dirent.h>
49 #include <sys/un.h>
50 #include <pwd.h>
51 #include <time.h>
52 #include <locale.h>
53 #include <sys/time.h>
54 #include <sys/stat.h>
55 #include <sys/wait.h>
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
58 #include <netdb.h>
59 #include <grp.h>
60 #include <arpa/inet.h>
61 
62 #ifdef HAVE_ERRNO_H
63 #include <errno.h>
64 #endif
65 #ifdef HAVE_SYSLOG_H
66 #include <syslog.h>
67 #endif
68 #ifdef HAVE_WRITEV
69 #include <sys/uio.h>
70 #endif
71 #ifdef HAVE_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;
445  size_t fds_to_use;
446 
447  /* Every unsigned int fits in a size_t without truncation, so
448  * casting (size_t) *n_fds is OK */
449  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
450 
451  if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
452  (char *) payload + payload_len_bytes >
453  (char *) m.msg_control + m.msg_controllen)
454  {
455  /* This is the last cmsg in a truncated message and using
456  * cmsg_len would apparently overrun the allocated buffer.
457  * Some operating systems (illumos and Solaris are known) do
458  * not adjust cmsg_len in the last cmsg when truncation occurs.
459  * Adjust the payload length here. The calculation for
460  * payload_len_fds below will discard any trailing bytes that
461  * belong to an incomplete file descriptor - the kernel will
462  * have already closed that (at least for illumos and Solaris)
463  */
464  payload_len_bytes = m.msg_controllen -
465  ((char *) payload - (char *) m.msg_control);
466  }
467 
468  payload_len_fds = payload_len_bytes / sizeof (int);
469 
470  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
471  {
472  /* The fds in the payload will fit in our buffer */
473  fds_to_use = payload_len_fds;
474  }
475  else
476  {
477  /* Too many fds in the payload. This shouldn't happen
478  * any more because we're setting m.msg_controllen to
479  * the exact number we can accept, but be safe and
480  * truncate. */
481  fds_to_use = (size_t) *n_fds;
482 
483  /* Close the excess fds to avoid DoS: if they stayed open,
484  * someone could send us an extra fd per message
485  * and we'd eventually run out. */
486  for (i = fds_to_use; i < payload_len_fds; i++)
487  {
488  close (payload[i]);
489  }
490  }
491 
492  memcpy (fds, payload, fds_to_use * sizeof (int));
493  found = TRUE;
494  /* This narrowing cast from size_t to unsigned int cannot
495  * overflow because we have chosen fds_to_use
496  * to be <= *n_fds */
497  *n_fds = (unsigned int) fds_to_use;
498 
499  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
500  worked, hence we need to go through this list and set
501  CLOEXEC everywhere in any case */
502  for (i = 0; i < fds_to_use; i++)
504 
505  break;
506  }
507 
508  if (!found)
509  *n_fds = 0;
510 
511  if (m.msg_flags & MSG_CTRUNC)
512  {
513  unsigned int i;
514 
515  /* Hmm, apparently the control data was truncated. The bad
516  thing is that we might have completely lost a couple of fds
517  without chance to recover them. Hence let's treat this as a
518  serious error. */
519 
520  /* We still need to close whatever fds we *did* receive,
521  * otherwise they'll never get closed. (CVE-2020-12049) */
522  for (i = 0; i < *n_fds; i++)
523  close (fds[i]);
524 
525  *n_fds = 0;
526  errno = ENOSPC;
527  _dbus_string_set_length (buffer, start);
528  return -1;
529  }
530 
531  /* put length back (doesn't actually realloc) */
532  _dbus_string_set_length (buffer, start + bytes_read);
533 
534 #if 0
535  if (bytes_read > 0)
536  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
537 #endif
538 
539  return bytes_read;
540  }
541 #endif
542 }
543 
544 int
545 _dbus_write_socket_with_unix_fds(DBusSocket fd,
546  const DBusString *buffer,
547  int start,
548  int len,
549  const int *fds,
550  int n_fds) {
551 
552 #ifndef HAVE_UNIX_FD_PASSING
553 
554  if (n_fds > 0) {
555  errno = ENOTSUP;
556  return -1;
557  }
558 
559  return _dbus_write_socket(fd, buffer, start, len);
560 #else
561  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
562 #endif
563 }
564 
565 int
566 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
567  const DBusString *buffer1,
568  int start1,
569  int len1,
570  const DBusString *buffer2,
571  int start2,
572  int len2,
573  const int *fds,
574  int n_fds) {
575 
576 #ifndef HAVE_UNIX_FD_PASSING
577 
578  if (n_fds > 0) {
579  errno = ENOTSUP;
580  return -1;
581  }
582 
583  return _dbus_write_socket_two(fd,
584  buffer1, start1, len1,
585  buffer2, start2, len2);
586 #else
587 
588  struct msghdr m;
589  struct cmsghdr *cm;
590  struct iovec iov[2];
591  int bytes_written;
592 
593  _dbus_assert (len1 >= 0);
594  _dbus_assert (len2 >= 0);
595  _dbus_assert (n_fds >= 0);
596 
597  _DBUS_ZERO(iov);
598  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
599  iov[0].iov_len = len1;
600 
601  if (buffer2)
602  {
603  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
604  iov[1].iov_len = len2;
605  }
606 
607  _DBUS_ZERO(m);
608  m.msg_iov = iov;
609  m.msg_iovlen = buffer2 ? 2 : 1;
610 
611  if (n_fds > 0)
612  {
613  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
614  m.msg_control = alloca(m.msg_controllen);
615  memset(m.msg_control, 0, m.msg_controllen);
616 
617  cm = CMSG_FIRSTHDR(&m);
618  cm->cmsg_level = SOL_SOCKET;
619  cm->cmsg_type = SCM_RIGHTS;
620  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
621  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
622  }
623 
624  again:
625 
626  bytes_written = sendmsg (fd.fd, &m, 0
627 #if HAVE_DECL_MSG_NOSIGNAL
628  |MSG_NOSIGNAL
629 #endif
630  );
631 
632  if (bytes_written < 0 && errno == EINTR)
633  goto again;
634 
635 #if 0
636  if (bytes_written > 0)
637  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
638 #endif
639 
640  return bytes_written;
641 #endif
642 }
643 
657 int
659  const DBusString *buffer1,
660  int start1,
661  int len1,
662  const DBusString *buffer2,
663  int start2,
664  int len2)
665 {
666 #if HAVE_DECL_MSG_NOSIGNAL
667  struct iovec vectors[2];
668  const char *data1;
669  const char *data2;
670  int bytes_written;
671  struct msghdr m;
672 
673  _dbus_assert (buffer1 != NULL);
674  _dbus_assert (start1 >= 0);
675  _dbus_assert (start2 >= 0);
676  _dbus_assert (len1 >= 0);
677  _dbus_assert (len2 >= 0);
678 
679  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
680 
681  if (buffer2 != NULL)
682  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
683  else
684  {
685  data2 = NULL;
686  start2 = 0;
687  len2 = 0;
688  }
689 
690  vectors[0].iov_base = (char*) data1;
691  vectors[0].iov_len = len1;
692  vectors[1].iov_base = (char*) data2;
693  vectors[1].iov_len = len2;
694 
695  _DBUS_ZERO(m);
696  m.msg_iov = vectors;
697  m.msg_iovlen = data2 ? 2 : 1;
698 
699  again:
700 
701  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
702 
703  if (bytes_written < 0 && errno == EINTR)
704  goto again;
705 
706  return bytes_written;
707 
708 #else
709  return _dbus_write_two (fd.fd, buffer1, start1, len1,
710  buffer2, start2, len2);
711 #endif
712 }
713 
730 int
731 _dbus_read (int fd,
732  DBusString *buffer,
733  int count)
734 {
735  int bytes_read;
736  int start;
737  char *data;
738 
739  _dbus_assert (count >= 0);
740 
741  start = _dbus_string_get_length (buffer);
742 
743  if (!_dbus_string_lengthen (buffer, count))
744  {
745  errno = ENOMEM;
746  return -1;
747  }
748 
749  data = _dbus_string_get_data_len (buffer, start, count);
750 
751  again:
752 
753  bytes_read = read (fd, data, count);
754 
755  if (bytes_read < 0)
756  {
757  if (errno == EINTR)
758  goto again;
759  else
760  {
761  /* put length back (note that this doesn't actually realloc anything) */
762  _dbus_string_set_length (buffer, start);
763  return -1;
764  }
765  }
766  else
767  {
768  /* put length back (doesn't actually realloc) */
769  _dbus_string_set_length (buffer, start + bytes_read);
770 
771 #if 0
772  if (bytes_read > 0)
773  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
774 #endif
775 
776  return bytes_read;
777  }
778 }
779 
790 int
791 _dbus_write (int fd,
792  const DBusString *buffer,
793  int start,
794  int len)
795 {
796  const char *data;
797  int bytes_written;
798 
799  data = _dbus_string_get_const_data_len (buffer, start, len);
800 
801  again:
802 
803  bytes_written = write (fd, data, len);
804 
805  if (bytes_written < 0 && errno == EINTR)
806  goto again;
807 
808 #if 0
809  if (bytes_written > 0)
810  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
811 #endif
812 
813  return bytes_written;
814 }
815 
836 int
838  const DBusString *buffer1,
839  int start1,
840  int len1,
841  const DBusString *buffer2,
842  int start2,
843  int len2)
844 {
845  _dbus_assert (buffer1 != NULL);
846  _dbus_assert (start1 >= 0);
847  _dbus_assert (start2 >= 0);
848  _dbus_assert (len1 >= 0);
849  _dbus_assert (len2 >= 0);
850 
851 #ifdef HAVE_WRITEV
852  {
853  struct iovec vectors[2];
854  const char *data1;
855  const char *data2;
856  int bytes_written;
857 
858  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
859 
860  if (buffer2 != NULL)
861  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
862  else
863  {
864  data2 = NULL;
865  start2 = 0;
866  len2 = 0;
867  }
868 
869  vectors[0].iov_base = (char*) data1;
870  vectors[0].iov_len = len1;
871  vectors[1].iov_base = (char*) data2;
872  vectors[1].iov_len = len2;
873 
874  again:
875 
876  bytes_written = writev (fd,
877  vectors,
878  data2 ? 2 : 1);
879 
880  if (bytes_written < 0 && errno == EINTR)
881  goto again;
882 
883  return bytes_written;
884  }
885 #else /* HAVE_WRITEV */
886  {
887  int ret1, ret2;
888 
889  ret1 = _dbus_write (fd, buffer1, start1, len1);
890  if (ret1 == len1 && buffer2 != NULL)
891  {
892  ret2 = _dbus_write (fd, buffer2, start2, len2);
893  if (ret2 < 0)
894  ret2 = 0; /* we can't report an error as the first write was OK */
895 
896  return ret1 + ret2;
897  }
898  else
899  return ret1;
900  }
901 #endif /* !HAVE_WRITEV */
902 }
903 
904 #define _DBUS_MAX_SUN_PATH_LENGTH 99
905 
935 int
936 _dbus_connect_unix_socket (const char *path,
937  dbus_bool_t abstract,
938  DBusError *error)
939 {
940  int fd;
941  size_t path_len;
942  struct sockaddr_un addr;
943  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
944 
945  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
946 
947  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
948  path, abstract);
949 
950 
951  if (!_dbus_open_unix_socket (&fd, error))
952  {
953  _DBUS_ASSERT_ERROR_IS_SET(error);
954  return -1;
955  }
956  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
957 
958  _DBUS_ZERO (addr);
959  addr.sun_family = AF_UNIX;
960  path_len = strlen (path);
961 
962  if (abstract)
963  {
964 #ifdef __linux__
965  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
966  path_len++; /* Account for the extra nul byte added to the start of sun_path */
967 
968  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
969  {
971  "Abstract socket name too long\n");
972  _dbus_close (fd, NULL);
973  return -1;
974  }
975 
976  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
977  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
978 #else /* !__linux__ */
980  "Operating system does not support abstract socket namespace\n");
981  _dbus_close (fd, NULL);
982  return -1;
983 #endif /* !__linux__ */
984  }
985  else
986  {
987  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
988  {
990  "Socket name too long\n");
991  _dbus_close (fd, NULL);
992  return -1;
993  }
994 
995  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
996  }
997 
998  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
999  {
1000  dbus_set_error (error,
1001  _dbus_error_from_errno (errno),
1002  "Failed to connect to socket %s: %s",
1003  path, _dbus_strerror (errno));
1004 
1005  _dbus_close (fd, NULL);
1006  return -1;
1007  }
1008 
1009  if (!_dbus_set_fd_nonblocking (fd, error))
1010  {
1011  _DBUS_ASSERT_ERROR_IS_SET (error);
1012 
1013  _dbus_close (fd, NULL);
1014  return -1;
1015  }
1016 
1017  return fd;
1018 }
1019 
1032 int
1033 _dbus_connect_exec (const char *path,
1034  char *const argv[],
1035  DBusError *error)
1036 {
1037  int fds[2];
1038  pid_t pid;
1039  int retval;
1040  dbus_bool_t cloexec_done = 0;
1041 
1042  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1043 
1044  _dbus_verbose ("connecting to process %s\n", path);
1045 
1046 #ifdef SOCK_CLOEXEC
1047  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1048  cloexec_done = (retval >= 0);
1049 
1050  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1051 #endif
1052  {
1053  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1054  }
1055 
1056  if (retval < 0)
1057  {
1058  dbus_set_error (error,
1059  _dbus_error_from_errno (errno),
1060  "Failed to create socket pair: %s",
1061  _dbus_strerror (errno));
1062  return -1;
1063  }
1064 
1065  if (!cloexec_done)
1066  {
1067  _dbus_fd_set_close_on_exec (fds[0]);
1068  _dbus_fd_set_close_on_exec (fds[1]);
1069  }
1070 
1071  /* Make sure our output buffers aren't redundantly printed by both the
1072  * parent and the child */
1073  fflush (stdout);
1074  fflush (stderr);
1075 
1076  pid = fork ();
1077  if (pid < 0)
1078  {
1079  dbus_set_error (error,
1080  _dbus_error_from_errno (errno),
1081  "Failed to fork() to call %s: %s",
1082  path, _dbus_strerror (errno));
1083  close (fds[0]);
1084  close (fds[1]);
1085  return -1;
1086  }
1087 
1088  if (pid == 0)
1089  {
1090  /* child */
1091  close (fds[0]);
1092 
1093  dup2 (fds[1], STDIN_FILENO);
1094  dup2 (fds[1], STDOUT_FILENO);
1095 
1096  if (fds[1] != STDIN_FILENO &&
1097  fds[1] != STDOUT_FILENO)
1098  close (fds[1]);
1099 
1100  /* Inherit STDERR and the controlling terminal from the
1101  parent */
1102 
1103  _dbus_close_all ();
1104 
1105  execvp (path, (char * const *) argv);
1106 
1107  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1108 
1109  _exit(1);
1110  }
1111 
1112  /* parent */
1113  close (fds[1]);
1114 
1115  if (!_dbus_set_fd_nonblocking (fds[0], error))
1116  {
1117  _DBUS_ASSERT_ERROR_IS_SET (error);
1118 
1119  close (fds[0]);
1120  return -1;
1121  }
1122 
1123  return fds[0];
1124 }
1125 
1143 int
1144 _dbus_listen_unix_socket (const char *path,
1145  dbus_bool_t abstract,
1146  DBusError *error)
1147 {
1148  int listen_fd;
1149  struct sockaddr_un addr;
1150  size_t path_len;
1151  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1152 
1153  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1154 
1155  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1156  path, abstract);
1157 
1158  if (!_dbus_open_unix_socket (&listen_fd, error))
1159  {
1160  _DBUS_ASSERT_ERROR_IS_SET(error);
1161  return -1;
1162  }
1163  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1164 
1165  _DBUS_ZERO (addr);
1166  addr.sun_family = AF_UNIX;
1167  path_len = strlen (path);
1168 
1169  if (abstract)
1170  {
1171 #ifdef __linux__
1172  /* remember that abstract names aren't nul-terminated so we rely
1173  * on sun_path being filled in with zeroes above.
1174  */
1175  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1176  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1177 
1178  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1179  {
1181  "Abstract socket name too long\n");
1182  _dbus_close (listen_fd, NULL);
1183  return -1;
1184  }
1185 
1186  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1187  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1188 #else /* !__linux__ */
1190  "Operating system does not support abstract socket namespace\n");
1191  _dbus_close (listen_fd, NULL);
1192  return -1;
1193 #endif /* !__linux__ */
1194  }
1195  else
1196  {
1197  /* Discussed security implications of this with Nalin,
1198  * and we couldn't think of where it would kick our ass, but
1199  * it still seems a bit sucky. It also has non-security suckage;
1200  * really we'd prefer to exit if the socket is already in use.
1201  * But there doesn't seem to be a good way to do this.
1202  *
1203  * Just to be extra careful, I threw in the stat() - clearly
1204  * the stat() can't *fix* any security issue, but it at least
1205  * avoids inadvertent/accidental data loss.
1206  */
1207  {
1208  struct stat sb;
1209 
1210  if (stat (path, &sb) == 0 &&
1211  S_ISSOCK (sb.st_mode))
1212  unlink (path);
1213  }
1214 
1215  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1216  {
1218  "Socket name too long\n");
1219  _dbus_close (listen_fd, NULL);
1220  return -1;
1221  }
1222 
1223  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1224  }
1225 
1226  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1227  {
1228  dbus_set_error (error, _dbus_error_from_errno (errno),
1229  "Failed to bind socket \"%s\": %s",
1230  path, _dbus_strerror (errno));
1231  _dbus_close (listen_fd, NULL);
1232  return -1;
1233  }
1234 
1235  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1236  {
1237  dbus_set_error (error, _dbus_error_from_errno (errno),
1238  "Failed to listen on socket \"%s\": %s",
1239  path, _dbus_strerror (errno));
1240  _dbus_close (listen_fd, NULL);
1241  return -1;
1242  }
1243 
1244  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1245  {
1246  _DBUS_ASSERT_ERROR_IS_SET (error);
1247  _dbus_close (listen_fd, NULL);
1248  return -1;
1249  }
1250 
1251  /* Try opening up the permissions, but if we can't, just go ahead
1252  * and continue, maybe it will be good enough.
1253  */
1254  if (!abstract && chmod (path, 0777) < 0)
1255  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1256 
1257  return listen_fd;
1258 }
1259 
1270 int
1272  DBusError *error)
1273 {
1274 #ifdef HAVE_SYSTEMD
1275  int r, n;
1276  int fd;
1277  DBusSocket *new_fds;
1278 
1279  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1280 
1281  n = sd_listen_fds (TRUE);
1282  if (n < 0)
1283  {
1285  "Failed to acquire systemd socket: %s",
1286  _dbus_strerror (-n));
1287  return -1;
1288  }
1289 
1290  if (n <= 0)
1291  {
1293  "No socket received.");
1294  return -1;
1295  }
1296 
1297  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1298  {
1299  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1300  if (r < 0)
1301  {
1303  "Failed to verify systemd socket type: %s",
1304  _dbus_strerror (-r));
1305  return -1;
1306  }
1307 
1308  if (!r)
1309  {
1311  "Passed socket has wrong type.");
1312  return -1;
1313  }
1314  }
1315 
1316  /* OK, the file descriptors are all good, so let's take posession of
1317  them then. */
1318 
1319  new_fds = dbus_new (DBusSocket, n);
1320  if (!new_fds)
1321  {
1323  "Failed to allocate file handle array.");
1324  goto fail;
1325  }
1326 
1327  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1328  {
1329  if (!_dbus_set_fd_nonblocking (fd, error))
1330  {
1331  _DBUS_ASSERT_ERROR_IS_SET (error);
1332  goto fail;
1333  }
1334 
1335  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1336  }
1337 
1338  *fds = new_fds;
1339  return n;
1340 
1341  fail:
1342 
1343  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1344  {
1345  _dbus_close (fd, NULL);
1346  }
1347 
1348  dbus_free (new_fds);
1349  return -1;
1350 #else
1352  "dbus was compiled without systemd support");
1353  return -1;
1354 #endif
1355 }
1356 
1357 /* Convert an error code from getaddrinfo() or getnameinfo() into
1358  * a D-Bus error name. */
1359 static const char *
1360 _dbus_error_from_gai (int gai_res,
1361  int saved_errno)
1362 {
1363  switch (gai_res)
1364  {
1365 #ifdef EAI_FAMILY
1366  case EAI_FAMILY:
1367  /* ai_family not supported (at all) */
1368  return DBUS_ERROR_NOT_SUPPORTED;
1369 #endif
1370 
1371 #ifdef EAI_SOCKTYPE
1372  case EAI_SOCKTYPE:
1373  /* ai_socktype not supported (at all) */
1374  return DBUS_ERROR_NOT_SUPPORTED;
1375 #endif
1376 
1377 #ifdef EAI_MEMORY
1378  case EAI_MEMORY:
1379  /* Out of memory */
1380  return DBUS_ERROR_NO_MEMORY;
1381 #endif
1382 
1383 #ifdef EAI_SYSTEM
1384  case EAI_SYSTEM:
1385  /* Unspecified system error, details in errno */
1386  return _dbus_error_from_errno (saved_errno);
1387 #endif
1388 
1389  case 0:
1390  /* It succeeded, but we didn't get any addresses? */
1391  return DBUS_ERROR_FAILED;
1392 
1393  /* EAI_AGAIN: Transient failure */
1394  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1395  /* EAI_FAIL: Non-recoverable failure */
1396  /* EAI_NODATA: host exists but has no addresses */
1397  /* EAI_NONAME: host does not exist */
1398  /* EAI_OVERFLOW: argument buffer overflow */
1399  /* EAI_SERVICE: service not available for specified socket
1400  * type (we should never see this because we use numeric
1401  * ports) */
1402  default:
1403  return DBUS_ERROR_FAILED;
1404  }
1405 }
1406 
1420 DBusSocket
1421 _dbus_connect_tcp_socket (const char *host,
1422  const char *port,
1423  const char *family,
1424  DBusError *error)
1425 {
1426  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1427 }
1428 
1429 DBusSocket
1430 _dbus_connect_tcp_socket_with_nonce (const char *host,
1431  const char *port,
1432  const char *family,
1433  const char *noncefile,
1434  DBusError *error)
1435 {
1436  int saved_errno = 0;
1437  DBusList *connect_errors = NULL;
1438  DBusSocket fd = DBUS_SOCKET_INIT;
1439  int res;
1440  struct addrinfo hints;
1441  struct addrinfo *ai = NULL;
1442  const struct addrinfo *tmp;
1443  DBusError *connect_error;
1444 
1445  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1446 
1447  _DBUS_ZERO (hints);
1448 
1449  if (!family)
1450  hints.ai_family = AF_UNSPEC;
1451  else if (!strcmp(family, "ipv4"))
1452  hints.ai_family = AF_INET;
1453  else if (!strcmp(family, "ipv6"))
1454  hints.ai_family = AF_INET6;
1455  else
1456  {
1457  dbus_set_error (error,
1459  "Unknown address family %s", family);
1460  return _dbus_socket_get_invalid ();
1461  }
1462  hints.ai_protocol = IPPROTO_TCP;
1463  hints.ai_socktype = SOCK_STREAM;
1464  hints.ai_flags = AI_ADDRCONFIG;
1465 
1466  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1467  {
1468  dbus_set_error (error,
1469  _dbus_error_from_gai (res, errno),
1470  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1471  host, port, gai_strerror(res), res);
1472  _dbus_socket_invalidate (&fd);
1473  goto out;
1474  }
1475 
1476  tmp = ai;
1477  while (tmp)
1478  {
1479  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1480  {
1481  _DBUS_ASSERT_ERROR_IS_SET(error);
1482  _dbus_socket_invalidate (&fd);
1483  goto out;
1484  }
1485  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1486 
1487  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1488  {
1489  saved_errno = errno;
1490  _dbus_close (fd.fd, NULL);
1491  _dbus_socket_invalidate (&fd);
1492 
1493  connect_error = dbus_new0 (DBusError, 1);
1494 
1495  if (connect_error == NULL)
1496  {
1497  _DBUS_SET_OOM (error);
1498  goto out;
1499  }
1500 
1501  dbus_error_init (connect_error);
1502  _dbus_set_error_with_inet_sockaddr (connect_error,
1503  tmp->ai_addr, tmp->ai_addrlen,
1504  "Failed to connect to socket",
1505  saved_errno);
1506 
1507  if (!_dbus_list_append (&connect_errors, connect_error))
1508  {
1509  dbus_error_free (connect_error);
1510  dbus_free (connect_error);
1511  _DBUS_SET_OOM (error);
1512  goto out;
1513  }
1514 
1515  tmp = tmp->ai_next;
1516  continue;
1517  }
1518 
1519  break;
1520  }
1521 
1522  if (!_dbus_socket_is_valid (fd))
1523  {
1524  _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1525  host, port, error);
1526  goto out;
1527  }
1528 
1529  if (noncefile != NULL)
1530  {
1531  DBusString noncefileStr;
1532  dbus_bool_t ret;
1533  _dbus_string_init_const (&noncefileStr, noncefile);
1534  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1535 
1536  if (!ret)
1537  {
1538  _dbus_close (fd.fd, NULL);
1539  _dbus_socket_invalidate (&fd);
1540  goto out;
1541  }
1542  }
1543 
1544  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1545  {
1546  _dbus_close (fd.fd, NULL);
1547  _dbus_socket_invalidate (&fd);
1548  goto out;
1549  }
1550 
1551 out:
1552  if (ai != NULL)
1553  freeaddrinfo (ai);
1554 
1555  while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1556  {
1557  dbus_error_free (connect_error);
1558  dbus_free (connect_error);
1559  }
1560 
1561  return fd;
1562 }
1563 
1581 int
1582 _dbus_listen_tcp_socket (const char *host,
1583  const char *port,
1584  const char *family,
1585  DBusString *retport,
1586  const char **retfamily,
1587  DBusSocket **fds_p,
1588  DBusError *error)
1589 {
1590  int saved_errno;
1591  int nlisten_fd = 0, res, i;
1592  DBusList *bind_errors = NULL;
1593  DBusError *bind_error = NULL;
1594  DBusSocket *listen_fd = NULL;
1595  struct addrinfo hints;
1596  struct addrinfo *ai, *tmp;
1597  unsigned int reuseaddr;
1598  dbus_bool_t have_ipv4 = FALSE;
1599  dbus_bool_t have_ipv6 = FALSE;
1600 
1601  *fds_p = NULL;
1602  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1603 
1604  _DBUS_ZERO (hints);
1605 
1606  if (!family)
1607  hints.ai_family = AF_UNSPEC;
1608  else if (!strcmp(family, "ipv4"))
1609  hints.ai_family = AF_INET;
1610  else if (!strcmp(family, "ipv6"))
1611  hints.ai_family = AF_INET6;
1612  else
1613  {
1614  dbus_set_error (error,
1616  "Unknown address family %s", family);
1617  return -1;
1618  }
1619 
1620  hints.ai_protocol = IPPROTO_TCP;
1621  hints.ai_socktype = SOCK_STREAM;
1622  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1623 
1624  redo_lookup_with_port:
1625  ai = NULL;
1626  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1627  {
1628  dbus_set_error (error,
1629  _dbus_error_from_gai (res, errno),
1630  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1631  host ? host : "*", port, gai_strerror(res), res);
1632  goto failed;
1633  }
1634 
1635  tmp = ai;
1636  while (tmp)
1637  {
1638  int fd = -1, tcp_nodelay_on;
1639  DBusSocket *newlisten_fd;
1640 
1641  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1642  {
1643  _DBUS_ASSERT_ERROR_IS_SET(error);
1644  goto failed;
1645  }
1646  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1647 
1648  reuseaddr = 1;
1649  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1650  {
1651  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1652  host ? host : "*", port, _dbus_strerror (errno));
1653  }
1654 
1655  /* Nagle's algorithm imposes a huge delay on the initial messages
1656  going over TCP. */
1657  tcp_nodelay_on = 1;
1658  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1659  {
1660  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1661  host ? host : "*", port, _dbus_strerror (errno));
1662  }
1663 
1664  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1665  {
1666  saved_errno = errno;
1667  _dbus_close(fd, NULL);
1668 
1669  /*
1670  * We don't treat this as a fatal error, because there might be
1671  * other addresses that we can listen on. In particular:
1672  *
1673  * - If saved_errno is EADDRINUSE after we
1674  * "goto redo_lookup_with_port" after binding a port on one of the
1675  * possible addresses, we will try to bind that same port on
1676  * every address, including the same address again for a second
1677  * time, which will fail with EADDRINUSE.
1678  *
1679  * - If saved_errno is EADDRINUSE, it might be because binding to
1680  * an IPv6 address implicitly binds to a corresponding IPv4
1681  * address or vice versa (e.g. Linux with bindv6only=0).
1682  *
1683  * - If saved_errno is EADDRNOTAVAIL when we asked for family
1684  * AF_UNSPEC, it might be because IPv6 is disabled for this
1685  * particular interface (e.g. Linux with
1686  * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1687  */
1688  bind_error = dbus_new0 (DBusError, 1);
1689 
1690  if (bind_error == NULL)
1691  {
1692  _DBUS_SET_OOM (error);
1693  goto failed;
1694  }
1695 
1696  dbus_error_init (bind_error);
1697  _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1698  "Failed to bind socket",
1699  saved_errno);
1700 
1701  if (!_dbus_list_append (&bind_errors, bind_error))
1702  {
1703  dbus_error_free (bind_error);
1704  dbus_free (bind_error);
1705  _DBUS_SET_OOM (error);
1706  goto failed;
1707  }
1708 
1709  /* Try the next address, maybe it will work better */
1710  tmp = tmp->ai_next;
1711  continue;
1712  }
1713 
1714  if (listen (fd, 30 /* backlog */) < 0)
1715  {
1716  saved_errno = errno;
1717  _dbus_close (fd, NULL);
1718  _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1719  "Failed to listen on socket",
1720  saved_errno);
1721  goto failed;
1722  }
1723 
1724  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1725  if (!newlisten_fd)
1726  {
1727  _dbus_close (fd, NULL);
1729  "Failed to allocate file handle array");
1730  goto failed;
1731  }
1732  listen_fd = newlisten_fd;
1733  listen_fd[nlisten_fd].fd = fd;
1734  nlisten_fd++;
1735 
1736  if (tmp->ai_addr->sa_family == AF_INET)
1737  have_ipv4 = TRUE;
1738  else if (tmp->ai_addr->sa_family == AF_INET6)
1739  have_ipv6 = TRUE;
1740 
1741  if (!_dbus_string_get_length(retport))
1742  {
1743  /* If the user didn't specify a port, or used 0, then
1744  the kernel chooses a port. After the first address
1745  is bound to, we need to force all remaining addresses
1746  to use the same port */
1747  if (!port || !strcmp(port, "0"))
1748  {
1749  int result;
1750  struct sockaddr_storage addr;
1751  socklen_t addrlen;
1752  char portbuf[50];
1753 
1754  addrlen = sizeof(addr);
1755  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1756 
1757  if (result == -1)
1758  {
1759  saved_errno = errno;
1760  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1761  "Failed to retrieve socket name for \"%s:%s\": %s",
1762  host ? host : "*", port, _dbus_strerror (saved_errno));
1763  goto failed;
1764  }
1765 
1766  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1767  portbuf, sizeof(portbuf),
1768  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1769  {
1770  saved_errno = errno;
1771  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1772  "Failed to resolve port \"%s:%s\": %s (%d)",
1773  host ? host : "*", port, gai_strerror(res), res);
1774  goto failed;
1775  }
1776 
1777  if (!_dbus_string_append(retport, portbuf))
1778  {
1780  goto failed;
1781  }
1782 
1783  /* Release current address list & redo lookup */
1784  port = _dbus_string_get_const_data(retport);
1785  freeaddrinfo(ai);
1786  goto redo_lookup_with_port;
1787  }
1788  else
1789  {
1790  if (!_dbus_string_append(retport, port))
1791  {
1793  goto failed;
1794  }
1795  }
1796  }
1797 
1798  tmp = tmp->ai_next;
1799  }
1800  freeaddrinfo(ai);
1801  ai = NULL;
1802 
1803  if (!nlisten_fd)
1804  {
1805  _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1806  port, error);
1807  goto failed;
1808  }
1809 
1810  if (have_ipv4 && !have_ipv6)
1811  *retfamily = "ipv4";
1812  else if (!have_ipv4 && have_ipv6)
1813  *retfamily = "ipv6";
1814 
1815  for (i = 0 ; i < nlisten_fd ; i++)
1816  {
1817  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1818  {
1819  goto failed;
1820  }
1821  }
1822 
1823  *fds_p = listen_fd;
1824 
1825  /* This list might be non-empty even on success, because we might be
1826  * ignoring EADDRINUSE or EADDRNOTAVAIL */
1827  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1828  {
1829  dbus_error_free (bind_error);
1830  dbus_free (bind_error);
1831  }
1832 
1833  return nlisten_fd;
1834 
1835  failed:
1836  if (ai)
1837  freeaddrinfo(ai);
1838  for (i = 0 ; i < nlisten_fd ; i++)
1839  _dbus_close(listen_fd[i].fd, NULL);
1840 
1841  while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1842  {
1843  dbus_error_free (bind_error);
1844  dbus_free (bind_error);
1845  }
1846 
1847  dbus_free(listen_fd);
1848  return -1;
1849 }
1850 
1851 static dbus_bool_t
1852 write_credentials_byte (int server_fd,
1853  DBusError *error)
1854 {
1855  int bytes_written;
1856  char buf[1] = { '\0' };
1857 #if defined(HAVE_CMSGCRED)
1858  union {
1859  struct cmsghdr hdr;
1860  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1861  } cmsg;
1862  struct iovec iov;
1863  struct msghdr msg;
1864  iov.iov_base = buf;
1865  iov.iov_len = 1;
1866 
1867  _DBUS_ZERO(msg);
1868  msg.msg_iov = &iov;
1869  msg.msg_iovlen = 1;
1870 
1871  msg.msg_control = (caddr_t) &cmsg;
1872  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1873  _DBUS_ZERO(cmsg);
1874  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1875  cmsg.hdr.cmsg_level = SOL_SOCKET;
1876  cmsg.hdr.cmsg_type = SCM_CREDS;
1877 #endif
1878 
1879  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1880 
1881  again:
1882 
1883 #if defined(HAVE_CMSGCRED)
1884  bytes_written = sendmsg (server_fd, &msg, 0
1885 #if HAVE_DECL_MSG_NOSIGNAL
1886  |MSG_NOSIGNAL
1887 #endif
1888  );
1889 
1890  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1891  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1892  * only allows that on AF_UNIX. Try just doing a send() instead. */
1893  if (bytes_written < 0 && errno == EINVAL)
1894 #endif
1895  {
1896  bytes_written = send (server_fd, buf, 1, 0
1897 #if HAVE_DECL_MSG_NOSIGNAL
1898  |MSG_NOSIGNAL
1899 #endif
1900  );
1901  }
1902 
1903  if (bytes_written < 0 && errno == EINTR)
1904  goto again;
1905 
1906  if (bytes_written < 0)
1907  {
1908  dbus_set_error (error, _dbus_error_from_errno (errno),
1909  "Failed to write credentials byte: %s",
1910  _dbus_strerror (errno));
1911  return FALSE;
1912  }
1913  else if (bytes_written == 0)
1914  {
1916  "wrote zero bytes writing credentials byte");
1917  return FALSE;
1918  }
1919  else
1920  {
1921  _dbus_assert (bytes_written == 1);
1922  _dbus_verbose ("wrote credentials byte\n");
1923  return TRUE;
1924  }
1925 }
1926 
1927 /* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1928 static dbus_bool_t
1929 add_groups_to_credentials (int client_fd,
1930  DBusCredentials *credentials,
1931  dbus_gid_t primary)
1932 {
1933 #if defined(__linux__) && defined(SO_PEERGROUPS)
1934  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1935  gid_t *buf = NULL;
1936  socklen_t len = 1024;
1937  dbus_bool_t oom = FALSE;
1938  /* libdbus has a different representation of group IDs just to annoy you */
1939  dbus_gid_t *converted_gids = NULL;
1940  dbus_bool_t need_primary = TRUE;
1941  size_t n_gids;
1942  size_t i;
1943 
1944  n_gids = ((size_t) len) / sizeof (gid_t);
1945  buf = dbus_new (gid_t, n_gids);
1946 
1947  if (buf == NULL)
1948  return FALSE;
1949 
1950  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1951  {
1952  int e = errno;
1953  gid_t *replacement;
1954 
1955  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1956  _dbus_strerror (e), (unsigned long) len);
1957 
1958  if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1959  {
1960  _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1961  _dbus_strerror (e));
1962  goto out;
1963  }
1964 
1965  /* If not enough space, len is updated to be enough.
1966  * Try again with a large enough buffer. */
1967  n_gids = ((size_t) len) / sizeof (gid_t);
1968  replacement = dbus_realloc (buf, len);
1969 
1970  if (replacement == NULL)
1971  {
1972  oom = TRUE;
1973  goto out;
1974  }
1975 
1976  buf = replacement;
1977  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1978  }
1979 
1980  if (len <= 0)
1981  {
1982  _dbus_verbose ("getsockopt(SO_PEERGROUPS) yielded <= 0 bytes: %ld\n",
1983  (long) len);
1984  goto out;
1985  }
1986 
1987  if (len > n_gids * sizeof (gid_t))
1988  {
1989  _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
1990  _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
1991  }
1992 
1993  if (len % sizeof (gid_t) != 0)
1994  {
1995  _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
1996  "integer multiple of sizeof(gid_t): %lu should be "
1997  "divisible by %zu",
1998  (unsigned long) len, sizeof (gid_t));
1999  goto out;
2000  }
2001 
2002  /* Allocate an extra space for the primary group ID */
2003  n_gids = ((size_t) len) / sizeof (gid_t);
2004 
2005  /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
2006  * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
2007  * This is using _DBUS_INT32_MAX as a conservative lower bound for
2008  * the maximum size_t. */
2009  if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
2010  {
2011  _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
2012  "of groups (%lu bytes), ignoring",
2013  (unsigned long) len);
2014  goto out;
2015  }
2016 
2017  converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
2018 
2019  if (converted_gids == NULL)
2020  {
2021  oom = TRUE;
2022  goto out;
2023  }
2024 
2025  for (i = 0; i < n_gids; i++)
2026  {
2027  converted_gids[i] = (dbus_gid_t) buf[i];
2028 
2029  if (converted_gids[i] == primary)
2030  need_primary = FALSE;
2031  }
2032 
2033  if (need_primary && primary != DBUS_GID_UNSET)
2034  {
2035  converted_gids[n_gids] = primary;
2036  n_gids++;
2037  }
2038 
2039  _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2040 
2041 out:
2042  dbus_free (buf);
2043  return !oom;
2044 #else
2045  /* no error */
2046  return TRUE;
2047 #endif
2048 }
2049 
2050 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2051 static dbus_bool_t
2052 add_linux_security_label_to_credentials (int client_fd,
2053  DBusCredentials *credentials)
2054 {
2055 #if defined(__linux__) && defined(SO_PEERSEC)
2056  DBusString buf;
2057  socklen_t len = 1024;
2058  dbus_bool_t oom = FALSE;
2059 
2060  if (!_dbus_string_init_preallocated (&buf, len) ||
2061  !_dbus_string_set_length (&buf, len))
2062  return FALSE;
2063 
2064  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2065  _dbus_string_get_data (&buf), &len) < 0)
2066  {
2067  int e = errno;
2068 
2069  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2070  _dbus_strerror (e), (unsigned long) len);
2071 
2072  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2073  {
2074  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2075  _dbus_strerror (e));
2076  goto out;
2077  }
2078 
2079  /* If not enough space, len is updated to be enough.
2080  * Try again with a large enough buffer. */
2081  if (!_dbus_string_set_length (&buf, len))
2082  {
2083  oom = TRUE;
2084  goto out;
2085  }
2086 
2087  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2088  }
2089 
2090  if (len <= 0)
2091  {
2092  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2093  (unsigned long) len);
2094  goto out;
2095  }
2096 
2097  if (len > _dbus_string_get_length_uint (&buf))
2098  {
2099  _dbus_verbose ("%lu > %u", (unsigned long) len,
2100  _dbus_string_get_length_uint (&buf));
2101  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2102  }
2103 
2104  if (_dbus_string_get_byte (&buf, len - 1) == 0)
2105  {
2106  /* the kernel included the trailing \0 in its count,
2107  * but DBusString always has an extra \0 after the data anyway */
2108  _dbus_verbose ("subtracting trailing \\0\n");
2109  len--;
2110  }
2111 
2112  if (!_dbus_string_set_length (&buf, len))
2113  {
2114  _dbus_assert_not_reached ("shortening string should not lead to OOM");
2115  oom = TRUE;
2116  goto out;
2117  }
2118 
2119  if (strlen (_dbus_string_get_const_data (&buf)) != len)
2120  {
2121  /* LSM people on the linux-security-module@ mailing list say this
2122  * should never happen: the label should be a bytestring with
2123  * an optional trailing \0 */
2124  _dbus_verbose ("security label from kernel had an embedded \\0, "
2125  "ignoring it\n");
2126  goto out;
2127  }
2128 
2129  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2130  (unsigned long) len,
2131  _dbus_string_get_const_data (&buf));
2132 
2134  _dbus_string_get_const_data (&buf)))
2135  {
2136  oom = TRUE;
2137  goto out;
2138  }
2139 
2140 out:
2141  _dbus_string_free (&buf);
2142  return !oom;
2143 #else
2144  /* no error */
2145  return TRUE;
2146 #endif
2147 }
2148 
2191  DBusCredentials *credentials,
2192  DBusError *error)
2193 {
2194  struct msghdr msg;
2195  struct iovec iov;
2196  char buf;
2197  dbus_uid_t uid_read;
2198  dbus_gid_t primary_gid_read;
2199  dbus_pid_t pid_read;
2200  int bytes_read;
2201 
2202 #ifdef HAVE_CMSGCRED
2203  union {
2204  struct cmsghdr hdr;
2205  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2206  } cmsg;
2207 #endif
2208 
2209  /* The POSIX spec certainly doesn't promise this, but
2210  * we need these assertions to fail as soon as we're wrong about
2211  * it so we can do the porting fixups
2212  */
2213  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2214  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2215  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2216 
2217  uid_read = DBUS_UID_UNSET;
2218  primary_gid_read = DBUS_GID_UNSET;
2219  pid_read = DBUS_PID_UNSET;
2220 
2221  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2222 
2223  _dbus_credentials_clear (credentials);
2224 
2225  iov.iov_base = &buf;
2226  iov.iov_len = 1;
2227 
2228  _DBUS_ZERO(msg);
2229  msg.msg_iov = &iov;
2230  msg.msg_iovlen = 1;
2231 
2232 #if defined(HAVE_CMSGCRED)
2233  _DBUS_ZERO(cmsg);
2234  msg.msg_control = (caddr_t) &cmsg;
2235  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2236 #endif
2237 
2238  again:
2239  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2240 
2241  if (bytes_read < 0)
2242  {
2243  if (errno == EINTR)
2244  goto again;
2245 
2246  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2247  * normally only call read_credentials if the socket was ready
2248  * for reading
2249  */
2250 
2251  dbus_set_error (error, _dbus_error_from_errno (errno),
2252  "Failed to read credentials byte: %s",
2253  _dbus_strerror (errno));
2254  return FALSE;
2255  }
2256  else if (bytes_read == 0)
2257  {
2258  /* this should not happen unless we are using recvmsg wrong,
2259  * so is essentially here for paranoia
2260  */
2262  "Failed to read credentials byte (zero-length read)");
2263  return FALSE;
2264  }
2265  else if (buf != '\0')
2266  {
2268  "Credentials byte was not nul");
2269  return FALSE;
2270  }
2271 
2272  _dbus_verbose ("read credentials byte\n");
2273 
2274  {
2275 #ifdef SO_PEERCRED
2276  /* Supported by at least Linux and OpenBSD, with minor differences.
2277  *
2278  * This mechanism passes the process ID through and does not require
2279  * the peer's cooperation, so we prefer it over all others. Notably,
2280  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2281  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2282  * because this is much less fragile.
2283  */
2284 #ifdef __OpenBSD__
2285  struct sockpeercred cr;
2286 #else
2287  struct ucred cr;
2288 #endif
2289  socklen_t cr_len = sizeof (cr);
2290 
2291  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2292  {
2293  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2294  _dbus_strerror (errno));
2295  }
2296  else if (cr_len != sizeof (cr))
2297  {
2298  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2299  cr_len, (int) sizeof (cr));
2300  }
2301  else
2302  {
2303  pid_read = cr.pid;
2304  uid_read = cr.uid;
2305 #ifdef __linux__
2306  /* Do other platforms have cr.gid? (Not that it really matters,
2307  * because the gid is useless to us unless we know the complete
2308  * group vector, which we only know on Linux.) */
2309  primary_gid_read = cr.gid;
2310 #endif
2311  }
2312 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2313  /* Another variant of the above - used on NetBSD
2314  */
2315  struct unpcbid cr;
2316  socklen_t cr_len = sizeof (cr);
2317 
2318  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2319  {
2320  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2321  _dbus_strerror (errno));
2322  }
2323  else if (cr_len != sizeof (cr))
2324  {
2325  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2326  cr_len, (int) sizeof (cr));
2327  }
2328  else
2329  {
2330  pid_read = cr.unp_pid;
2331  uid_read = cr.unp_euid;
2332  }
2333 #elif defined(HAVE_CMSGCRED)
2334  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2335  * presence of that struct implies SCM_CREDS. Supported by at least
2336  * FreeBSD and DragonflyBSD.
2337  *
2338  * This mechanism requires the peer to help us (it has to send us a
2339  * SCM_CREDS message) but it does pass the process ID through,
2340  * which makes it better than getpeereid().
2341  */
2342  struct cmsgcred *cred;
2343  struct cmsghdr *cmsgp;
2344 
2345  for (cmsgp = CMSG_FIRSTHDR (&msg);
2346  cmsgp != NULL;
2347  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2348  {
2349  if (cmsgp->cmsg_type == SCM_CREDS &&
2350  cmsgp->cmsg_level == SOL_SOCKET &&
2351  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2352  {
2353  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2354  pid_read = cred->cmcred_pid;
2355  uid_read = cred->cmcred_euid;
2356  break;
2357  }
2358  }
2359 
2360 #elif defined(HAVE_GETPEERUCRED)
2361  /* Supported in at least Solaris >= 10. It should probably be higher
2362  * up this list, because it carries the pid and we use this code path
2363  * for audit data. */
2364  ucred_t * ucred = NULL;
2365  if (getpeerucred (client_fd.fd, &ucred) == 0)
2366  {
2367 #ifdef HAVE_ADT
2368  adt_session_data_t *adth = NULL;
2369 #endif
2370  pid_read = ucred_getpid (ucred);
2371  uid_read = ucred_geteuid (ucred);
2372 #ifdef HAVE_ADT
2373  /* generate audit session data based on socket ucred */
2374  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2375  {
2376  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2377  }
2378  else
2379  {
2380  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2381  {
2382  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2383  }
2384  else
2385  {
2386  adt_export_data_t *data = NULL;
2387  size_t size = adt_export_session_data (adth, &data);
2388  if (size <= 0)
2389  {
2390  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2391  }
2392  else
2393  {
2394  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2395  free (data);
2396  }
2397  }
2398  (void) adt_end_session (adth);
2399  }
2400 #endif /* HAVE_ADT */
2401  }
2402  else
2403  {
2404  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2405  }
2406  if (ucred != NULL)
2407  ucred_free (ucred);
2408 
2409  /* ----------------------------------------------------------------
2410  * When adding new mechanisms, please add them above this point
2411  * if they support passing the process ID through, or below if not.
2412  * ---------------------------------------------------------------- */
2413 
2414 #elif defined(HAVE_GETPEEREID)
2415  /* getpeereid() originates from D.J. Bernstein and is fairly
2416  * widely-supported. According to a web search, it might be present in
2417  * any/all of:
2418  *
2419  * - AIX?
2420  * - Blackberry?
2421  * - Cygwin
2422  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2423  * - Mac OS X
2424  * - Minix 3.1.8+
2425  * - MirBSD?
2426  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2427  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2428  * - QNX?
2429  */
2430  uid_t euid;
2431  gid_t egid;
2432  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2433  {
2434  uid_read = euid;
2435  }
2436  else
2437  {
2438  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2439  }
2440 #else /* no supported mechanism */
2441 
2442 #warning Socket credentials not supported on this Unix OS
2443 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2444 
2445  /* Please add other operating systems known to support at least one of
2446  * the mechanisms above to this list, keeping alphabetical order.
2447  * Everything not in this list is best-effort.
2448  */
2449 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2450  defined(__linux__) || \
2451  defined(__OpenBSD__) || \
2452  defined(__NetBSD__)
2453 # error Credentials passing not working on this OS is a regression!
2454 #endif
2455 
2456  _dbus_verbose ("Socket credentials not supported on this OS\n");
2457 #endif
2458  }
2459 
2460  _dbus_verbose ("Credentials:"
2461  " pid "DBUS_PID_FORMAT
2462  " uid "DBUS_UID_FORMAT
2463  "\n",
2464  pid_read,
2465  uid_read);
2466 
2467  if (pid_read != DBUS_PID_UNSET)
2468  {
2469  if (!_dbus_credentials_add_pid (credentials, pid_read))
2470  {
2471  _DBUS_SET_OOM (error);
2472  return FALSE;
2473  }
2474  }
2475 
2476  if (uid_read != DBUS_UID_UNSET)
2477  {
2478  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2479  {
2480  _DBUS_SET_OOM (error);
2481  return FALSE;
2482  }
2483  }
2484 
2485  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2486  {
2487  _DBUS_SET_OOM (error);
2488  return FALSE;
2489  }
2490 
2491  /* We don't put any groups in the credentials unless we can put them
2492  * all there. */
2493  if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2494  {
2495  _DBUS_SET_OOM (error);
2496  return FALSE;
2497  }
2498 
2499  return TRUE;
2500 }
2501 
2521  DBusError *error)
2522 {
2523  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2524 
2525  if (write_credentials_byte (server_fd.fd, error))
2526  return TRUE;
2527  else
2528  return FALSE;
2529 }
2530 
2540 DBusSocket
2542 {
2543  DBusSocket client_fd;
2544  struct sockaddr addr;
2545  socklen_t addrlen;
2546 #ifdef HAVE_ACCEPT4
2547  dbus_bool_t cloexec_done;
2548 #endif
2549 
2550  addrlen = sizeof (addr);
2551 
2552  retry:
2553 
2554 #ifdef HAVE_ACCEPT4
2555  /*
2556  * At compile-time, we assume that if accept4() is available in
2557  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2558  * not necessarily true that either is supported by the running kernel.
2559  */
2560  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2561  cloexec_done = client_fd.fd >= 0;
2562 
2563  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2564 #endif
2565  {
2566  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2567  }
2568 
2569  if (client_fd.fd < 0)
2570  {
2571  if (errno == EINTR)
2572  goto retry;
2573  }
2574 
2575  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2576 
2577 #ifdef HAVE_ACCEPT4
2578  if (!cloexec_done)
2579 #endif
2580  {
2581  _dbus_fd_set_close_on_exec(client_fd.fd);
2582  }
2583 
2584  return client_fd;
2585 }
2586 
2597 {
2598  const char *directory;
2599  struct stat sb;
2600 
2601  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2602 
2603  directory = _dbus_string_get_const_data (dir);
2604 
2605  if (stat (directory, &sb) < 0)
2606  {
2607  dbus_set_error (error, _dbus_error_from_errno (errno),
2608  "%s", _dbus_strerror (errno));
2609 
2610  return FALSE;
2611  }
2612 
2613  if (sb.st_uid != geteuid ())
2614  {
2616  "%s directory is owned by user %lu, not %lu",
2617  directory,
2618  (unsigned long) sb.st_uid,
2619  (unsigned long) geteuid ());
2620  return FALSE;
2621  }
2622 
2623  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2624  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2625  {
2627  "%s directory is not private to the user", directory);
2628  return FALSE;
2629  }
2630 
2631  return TRUE;
2632 }
2633 
2634 static dbus_bool_t
2635 fill_user_info_from_passwd (struct passwd *p,
2636  DBusUserInfo *info,
2637  DBusError *error)
2638 {
2639  _dbus_assert (p->pw_name != NULL);
2640  _dbus_assert (p->pw_dir != NULL);
2641 
2642  info->uid = p->pw_uid;
2643  info->primary_gid = p->pw_gid;
2644  info->username = _dbus_strdup (p->pw_name);
2645  info->homedir = _dbus_strdup (p->pw_dir);
2646 
2647  if (info->username == NULL ||
2648  info->homedir == NULL)
2649  {
2651  return FALSE;
2652  }
2653 
2654  return TRUE;
2655 }
2656 
2657 static dbus_bool_t
2658 fill_user_info (DBusUserInfo *info,
2659  dbus_uid_t uid,
2660  const DBusString *username,
2661  DBusError *error)
2662 {
2663  const char *username_c;
2664 
2665  /* exactly one of username/uid provided */
2666  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2667  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2668 
2669  info->uid = DBUS_UID_UNSET;
2670  info->primary_gid = DBUS_GID_UNSET;
2671  info->group_ids = NULL;
2672  info->n_group_ids = 0;
2673  info->username = NULL;
2674  info->homedir = NULL;
2675 
2676  if (username != NULL)
2677  username_c = _dbus_string_get_const_data (username);
2678  else
2679  username_c = NULL;
2680 
2681  /* For now assuming that the getpwnam() and getpwuid() flavors
2682  * are always symmetrical, if not we have to add more configure
2683  * checks
2684  */
2685 
2686 #ifdef HAVE_GETPWNAM_R
2687  {
2688  struct passwd *p;
2689  int result;
2690  size_t buflen;
2691  char *buf;
2692  struct passwd p_str;
2693 
2694  /* retrieve maximum needed size for buf */
2695  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2696 
2697  /* sysconf actually returns a long, but everything else expects size_t,
2698  * so just recast here.
2699  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2700  */
2701  if ((long) buflen <= 0)
2702  buflen = 1024;
2703 
2704  result = -1;
2705  while (1)
2706  {
2707  buf = dbus_malloc (buflen);
2708  if (buf == NULL)
2709  {
2711  return FALSE;
2712  }
2713 
2714  p = NULL;
2715  if (uid != DBUS_UID_UNSET)
2716  result = getpwuid_r (uid, &p_str, buf, buflen,
2717  &p);
2718  else
2719  result = getpwnam_r (username_c, &p_str, buf, buflen,
2720  &p);
2721  //Try a bigger buffer if ERANGE was returned
2722  if (result == ERANGE && buflen < 512 * 1024)
2723  {
2724  dbus_free (buf);
2725  buflen *= 2;
2726  }
2727  else
2728  {
2729  break;
2730  }
2731  }
2732  if (result == 0 && p == &p_str)
2733  {
2734  if (!fill_user_info_from_passwd (p, info, error))
2735  {
2736  dbus_free (buf);
2737  return FALSE;
2738  }
2739  dbus_free (buf);
2740  }
2741  else
2742  {
2743  dbus_set_error (error, _dbus_error_from_errno (errno),
2744  "User \"%s\" unknown or no memory to allocate password entry\n",
2745  username_c ? username_c : "???");
2746  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2747  dbus_free (buf);
2748  return FALSE;
2749  }
2750  }
2751 #else /* ! HAVE_GETPWNAM_R */
2752  {
2753  /* I guess we're screwed on thread safety here */
2754  struct passwd *p;
2755 
2756 #warning getpwnam_r() not available, please report this to the dbus maintainers with details of your OS
2757 
2758  if (uid != DBUS_UID_UNSET)
2759  p = getpwuid (uid);
2760  else
2761  p = getpwnam (username_c);
2762 
2763  if (p != NULL)
2764  {
2765  if (!fill_user_info_from_passwd (p, info, error))
2766  {
2767  return FALSE;
2768  }
2769  }
2770  else
2771  {
2772  dbus_set_error (error, _dbus_error_from_errno (errno),
2773  "User \"%s\" unknown or no memory to allocate password entry\n",
2774  username_c ? username_c : "???");
2775  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2776  return FALSE;
2777  }
2778  }
2779 #endif /* ! HAVE_GETPWNAM_R */
2780 
2781  /* Fill this in so we can use it to get groups */
2782  username_c = info->username;
2783 
2784 #ifdef HAVE_GETGROUPLIST
2785  {
2786  gid_t *buf;
2787  int buf_count;
2788  int i;
2789  int initial_buf_count;
2790 
2791  initial_buf_count = 17;
2792  buf_count = initial_buf_count;
2793  buf = dbus_new (gid_t, buf_count);
2794  if (buf == NULL)
2795  {
2797  goto failed;
2798  }
2799 
2800  if (getgrouplist (username_c,
2801  info->primary_gid,
2802  buf, &buf_count) < 0)
2803  {
2804  gid_t *new;
2805  /* Presumed cause of negative return code: buf has insufficient
2806  entries to hold the entire group list. The Linux behavior in this
2807  case is to pass back the actual number of groups in buf_count, but
2808  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2809  So as a hack, try to help out a bit by guessing a larger
2810  number of groups, within reason.. might still fail, of course,
2811  but we can at least print a more informative message. I looked up
2812  the "right way" to do this by downloading Apple's own source code
2813  for the "id" command, and it turns out that they use an
2814  undocumented library function getgrouplist_2 (!) which is not
2815  declared in any header in /usr/include (!!). That did not seem
2816  like the way to go here.
2817  */
2818  if (buf_count == initial_buf_count)
2819  {
2820  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2821  }
2822  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2823  if (new == NULL)
2824  {
2826  dbus_free (buf);
2827  goto failed;
2828  }
2829 
2830  buf = new;
2831 
2832  errno = 0;
2833  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2834  {
2835  if (errno == 0)
2836  {
2837  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2838  username_c, buf_count, buf_count);
2839  }
2840  else
2841  {
2842  dbus_set_error (error,
2843  _dbus_error_from_errno (errno),
2844  "Failed to get groups for username \"%s\" primary GID "
2845  DBUS_GID_FORMAT ": %s\n",
2846  username_c, info->primary_gid,
2847  _dbus_strerror (errno));
2848  dbus_free (buf);
2849  goto failed;
2850  }
2851  }
2852  }
2853 
2854  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2855  if (info->group_ids == NULL)
2856  {
2858  dbus_free (buf);
2859  goto failed;
2860  }
2861 
2862  for (i = 0; i < buf_count; ++i)
2863  info->group_ids[i] = buf[i];
2864 
2865  info->n_group_ids = buf_count;
2866 
2867  dbus_free (buf);
2868  }
2869 #else /* HAVE_GETGROUPLIST */
2870  {
2871  /* We just get the one group ID */
2872  info->group_ids = dbus_new (dbus_gid_t, 1);
2873  if (info->group_ids == NULL)
2874  {
2876  goto failed;
2877  }
2878 
2879  info->n_group_ids = 1;
2880 
2881  (info->group_ids)[0] = info->primary_gid;
2882  }
2883 #endif /* HAVE_GETGROUPLIST */
2884 
2885  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2886 
2887  return TRUE;
2888 
2889  failed:
2890  _DBUS_ASSERT_ERROR_IS_SET (error);
2891  return FALSE;
2892 }
2893 
2904  const DBusString *username,
2905  DBusError *error)
2906 {
2907  return fill_user_info (info, DBUS_UID_UNSET,
2908  username, error);
2909 }
2910 
2921  dbus_uid_t uid,
2922  DBusError *error)
2923 {
2924  return fill_user_info (info, uid,
2925  NULL, error);
2926 }
2927 
2943 {
2944  /* The POSIX spec certainly doesn't promise this, but
2945  * we need these assertions to fail as soon as we're wrong about
2946  * it so we can do the porting fixups
2947  */
2948  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2949  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2950  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2951 
2952  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2953  return FALSE;
2954  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2955  return FALSE;
2956 
2957  return TRUE;
2958 }
2959 
2973 {
2974  return _dbus_string_append_uint (str,
2975  _dbus_geteuid ());
2976 }
2977 
2982 dbus_pid_t
2984 {
2985  return getpid ();
2986 }
2987 
2991 dbus_uid_t
2993 {
2994  return getuid ();
2995 }
2996 
3000 dbus_uid_t
3002 {
3003  return geteuid ();
3004 }
3005 
3012 unsigned long
3014 {
3015  return getpid ();
3016 }
3017 
3018 #if !DBUS_USE_SYNC
3019 /* To be thread-safe by default on platforms that don't necessarily have
3020  * atomic operations (notably Debian armel, which is armv4t), we must
3021  * use a mutex that can be initialized statically, like this.
3022  * GLib >= 2.32 uses a similar system.
3023  */
3024 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3025 #endif
3026 
3033 dbus_int32_t
3035 {
3036 #if DBUS_USE_SYNC
3037  return __sync_add_and_fetch(&atomic->value, 1)-1;
3038 #else
3039  dbus_int32_t res;
3040 
3041  pthread_mutex_lock (&atomic_mutex);
3042  res = atomic->value;
3043  atomic->value += 1;
3044  pthread_mutex_unlock (&atomic_mutex);
3045 
3046  return res;
3047 #endif
3048 }
3049 
3056 dbus_int32_t
3058 {
3059 #if DBUS_USE_SYNC
3060  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3061 #else
3062  dbus_int32_t res;
3063 
3064  pthread_mutex_lock (&atomic_mutex);
3065  res = atomic->value;
3066  atomic->value -= 1;
3067  pthread_mutex_unlock (&atomic_mutex);
3068 
3069  return res;
3070 #endif
3071 }
3072 
3080 dbus_int32_t
3082 {
3083 #if DBUS_USE_SYNC
3084  __sync_synchronize ();
3085  return atomic->value;
3086 #else
3087  dbus_int32_t res;
3088 
3089  pthread_mutex_lock (&atomic_mutex);
3090  res = atomic->value;
3091  pthread_mutex_unlock (&atomic_mutex);
3092 
3093  return res;
3094 #endif
3095 }
3096 
3102 void
3104 {
3105 #if DBUS_USE_SYNC
3106  /* Atomic version of "*atomic &= 0; return *atomic" */
3107  __sync_and_and_fetch (&atomic->value, 0);
3108 #else
3109  pthread_mutex_lock (&atomic_mutex);
3110  atomic->value = 0;
3111  pthread_mutex_unlock (&atomic_mutex);
3112 #endif
3113 }
3114 
3120 void
3122 {
3123 #if DBUS_USE_SYNC
3124  /* Atomic version of "*atomic |= 1; return *atomic" */
3125  __sync_or_and_fetch (&atomic->value, 1);
3126 #else
3127  pthread_mutex_lock (&atomic_mutex);
3128  atomic->value = 1;
3129  pthread_mutex_unlock (&atomic_mutex);
3130 #endif
3131 }
3132 
3141 int
3143  int n_fds,
3144  int timeout_milliseconds)
3145 {
3146 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3147  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3148  if (timeout_milliseconds < -1)
3149  {
3150  timeout_milliseconds = -1;
3151  }
3152 
3153  return poll (fds,
3154  n_fds,
3155  timeout_milliseconds);
3156 #else /* ! HAVE_POLL */
3157  /* Emulate poll() in terms of select() */
3158  fd_set read_set, write_set, err_set;
3159  int max_fd = 0;
3160  int i;
3161  struct timeval tv;
3162  int ready;
3163 
3164  FD_ZERO (&read_set);
3165  FD_ZERO (&write_set);
3166  FD_ZERO (&err_set);
3167 
3168  for (i = 0; i < n_fds; i++)
3169  {
3170  DBusPollFD *fdp = &fds[i];
3171 
3172  if (fdp->events & _DBUS_POLLIN)
3173  FD_SET (fdp->fd, &read_set);
3174 
3175  if (fdp->events & _DBUS_POLLOUT)
3176  FD_SET (fdp->fd, &write_set);
3177 
3178  FD_SET (fdp->fd, &err_set);
3179 
3180  max_fd = MAX (max_fd, fdp->fd);
3181  }
3182 
3183  tv.tv_sec = timeout_milliseconds / 1000;
3184  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3185 
3186  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3187  timeout_milliseconds < 0 ? NULL : &tv);
3188 
3189  if (ready > 0)
3190  {
3191  for (i = 0; i < n_fds; i++)
3192  {
3193  DBusPollFD *fdp = &fds[i];
3194 
3195  fdp->revents = 0;
3196 
3197  if (FD_ISSET (fdp->fd, &read_set))
3198  fdp->revents |= _DBUS_POLLIN;
3199 
3200  if (FD_ISSET (fdp->fd, &write_set))
3201  fdp->revents |= _DBUS_POLLOUT;
3202 
3203  if (FD_ISSET (fdp->fd, &err_set))
3204  fdp->revents |= _DBUS_POLLERR;
3205  }
3206  }
3207 
3208  return ready;
3209 #endif
3210 }
3211 
3219 void
3221  long *tv_usec)
3222 {
3223 #ifdef HAVE_MONOTONIC_CLOCK
3224  struct timespec ts;
3225  clock_gettime (CLOCK_MONOTONIC, &ts);
3226 
3227  if (tv_sec)
3228  *tv_sec = ts.tv_sec;
3229  if (tv_usec)
3230  *tv_usec = ts.tv_nsec / 1000;
3231 #else
3232  struct timeval t;
3233 
3234  gettimeofday (&t, NULL);
3235 
3236  if (tv_sec)
3237  *tv_sec = t.tv_sec;
3238  if (tv_usec)
3239  *tv_usec = t.tv_usec;
3240 #endif
3241 }
3242 
3250 void
3251 _dbus_get_real_time (long *tv_sec,
3252  long *tv_usec)
3253 {
3254  struct timeval t;
3255 
3256  gettimeofday (&t, NULL);
3257 
3258  if (tv_sec)
3259  *tv_sec = t.tv_sec;
3260  if (tv_usec)
3261  *tv_usec = t.tv_usec;
3262 }
3263 
3274  DBusError *error)
3275 {
3276  const char *filename_c;
3277 
3278  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3279 
3280  filename_c = _dbus_string_get_const_data (filename);
3281 
3282  if (mkdir (filename_c, 0700) < 0)
3283  {
3284  if (errno == EEXIST)
3285  return TRUE;
3286 
3288  "Failed to create directory %s: %s\n",
3289  filename_c, _dbus_strerror (errno));
3290  return FALSE;
3291  }
3292  else
3293  return TRUE;
3294 }
3295 
3306  DBusError *error)
3307 {
3308  const char *filename_c;
3309 
3310  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3311 
3312  filename_c = _dbus_string_get_const_data (filename);
3313 
3314  if (mkdir (filename_c, 0700) < 0)
3315  {
3317  "Failed to create directory %s: %s\n",
3318  filename_c, _dbus_strerror (errno));
3319  return FALSE;
3320  }
3321  else
3322  return TRUE;
3323 }
3324 
3337  const DBusString *next_component)
3338 {
3339  dbus_bool_t dir_ends_in_slash;
3340  dbus_bool_t file_starts_with_slash;
3341 
3342  if (_dbus_string_get_length (dir) == 0 ||
3343  _dbus_string_get_length (next_component) == 0)
3344  return TRUE;
3345 
3346  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3347  _dbus_string_get_length (dir) - 1);
3348 
3349  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3350 
3351  if (dir_ends_in_slash && file_starts_with_slash)
3352  {
3353  _dbus_string_shorten (dir, 1);
3354  }
3355  else if (!(dir_ends_in_slash || file_starts_with_slash))
3356  {
3357  if (!_dbus_string_append_byte (dir, '/'))
3358  return FALSE;
3359  }
3360 
3361  return _dbus_string_copy (next_component, 0, dir,
3362  _dbus_string_get_length (dir));
3363 }
3364 
3366 #define NANOSECONDS_PER_SECOND 1000000000
3368 #define MICROSECONDS_PER_SECOND 1000000
3370 #define MILLISECONDS_PER_SECOND 1000
3372 #define NANOSECONDS_PER_MILLISECOND 1000000
3374 #define MICROSECONDS_PER_MILLISECOND 1000
3375 
3380 void
3381 _dbus_sleep_milliseconds (int milliseconds)
3382 {
3383 #ifdef HAVE_NANOSLEEP
3384  struct timespec req;
3385  struct timespec rem;
3386 
3387  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3388  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3389  rem.tv_sec = 0;
3390  rem.tv_nsec = 0;
3391 
3392  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3393  req = rem;
3394 #elif defined (HAVE_USLEEP)
3395  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3396 #else /* ! HAVE_USLEEP */
3397  sleep (MAX (milliseconds / 1000, 1));
3398 #endif
3399 }
3400 
3412  int n_bytes,
3413  DBusError *error)
3414 {
3415  int old_len = _dbus_string_get_length (str);
3416  int fd;
3417  int result;
3418 #ifdef HAVE_GETRANDOM
3419  char *buffer;
3420 
3421  if (!_dbus_string_lengthen (str, n_bytes))
3422  {
3423  _DBUS_SET_OOM (error);
3424  return FALSE;
3425  }
3426 
3427  buffer = _dbus_string_get_data_len (str, old_len, n_bytes);
3428  result = getrandom (buffer, n_bytes, GRND_NONBLOCK);
3429 
3430  if (result == n_bytes)
3431  return TRUE;
3432 
3433  _dbus_string_set_length (str, old_len);
3434 #endif
3435 
3436  /* note, urandom on linux will fall back to pseudorandom */
3437  fd = open ("/dev/urandom", O_RDONLY);
3438 
3439  if (fd < 0)
3440  {
3441  dbus_set_error (error, _dbus_error_from_errno (errno),
3442  "Could not open /dev/urandom: %s",
3443  _dbus_strerror (errno));
3444  return FALSE;
3445  }
3446 
3447  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3448 
3449  result = _dbus_read (fd, str, n_bytes);
3450 
3451  if (result != n_bytes)
3452  {
3453  if (result < 0)
3454  dbus_set_error (error, _dbus_error_from_errno (errno),
3455  "Could not read /dev/urandom: %s",
3456  _dbus_strerror (errno));
3457  else
3459  "Short read from /dev/urandom");
3460 
3461  _dbus_close (fd, NULL);
3462  _dbus_string_set_length (str, old_len);
3463  return FALSE;
3464  }
3465 
3466  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3467  n_bytes);
3468 
3469  _dbus_close (fd, NULL);
3470 
3471  return TRUE;
3472 }
3473 
3479 void
3480 _dbus_exit (int code)
3481 {
3482  _exit (code);
3483 }
3484 
3493 const char*
3494 _dbus_strerror (int error_number)
3495 {
3496  const char *msg;
3497 
3498  msg = strerror (error_number);
3499  if (msg == NULL)
3500  msg = "unknown";
3501 
3502  return msg;
3503 }
3504 
3508 void
3510 {
3511  signal (SIGPIPE, SIG_IGN);
3512 }
3513 
3521 void
3523 {
3524  int val;
3525 
3526  val = fcntl (fd, F_GETFD, 0);
3527 
3528  if (val < 0)
3529  return;
3530 
3531  val |= FD_CLOEXEC;
3532 
3533  fcntl (fd, F_SETFD, val);
3534 }
3535 
3543 void
3545 {
3546  int val;
3547 
3548  val = fcntl (fd, F_GETFD, 0);
3549 
3550  if (val < 0)
3551  return;
3552 
3553  val &= ~FD_CLOEXEC;
3554 
3555  fcntl (fd, F_SETFD, val);
3556 }
3557 
3566 _dbus_close (int fd,
3567  DBusError *error)
3568 {
3569  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3570 
3571  again:
3572  if (close (fd) < 0)
3573  {
3574  if (errno == EINTR)
3575  goto again;
3576 
3577  dbus_set_error (error, _dbus_error_from_errno (errno),
3578  "Could not close fd %d", fd);
3579  return FALSE;
3580  }
3581 
3582  return TRUE;
3583 }
3584 
3593 int
3594 _dbus_dup(int fd,
3595  DBusError *error)
3596 {
3597  int new_fd;
3598 
3599 #ifdef F_DUPFD_CLOEXEC
3600  dbus_bool_t cloexec_done;
3601 
3602  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3603  cloexec_done = new_fd >= 0;
3604 
3605  if (new_fd < 0 && errno == EINVAL)
3606 #endif
3607  {
3608  new_fd = fcntl(fd, F_DUPFD, 3);
3609  }
3610 
3611  if (new_fd < 0) {
3612 
3613  dbus_set_error (error, _dbus_error_from_errno (errno),
3614  "Could not duplicate fd %d", fd);
3615  return -1;
3616  }
3617 
3618 #ifdef F_DUPFD_CLOEXEC
3619  if (!cloexec_done)
3620 #endif
3621  {
3623  }
3624 
3625  return new_fd;
3626 }
3627 
3637  DBusError *error)
3638 {
3639  return _dbus_set_fd_nonblocking (fd.fd, error);
3640 }
3641 
3642 static dbus_bool_t
3643 _dbus_set_fd_nonblocking (int fd,
3644  DBusError *error)
3645 {
3646  int val;
3647 
3648  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3649 
3650  val = fcntl (fd, F_GETFL, 0);
3651  if (val < 0)
3652  {
3653  dbus_set_error (error, _dbus_error_from_errno (errno),
3654  "Failed to get flags from file descriptor %d: %s",
3655  fd, _dbus_strerror (errno));
3656  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3657  _dbus_strerror (errno));
3658  return FALSE;
3659  }
3660 
3661  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3662  {
3663  dbus_set_error (error, _dbus_error_from_errno (errno),
3664  "Failed to set nonblocking flag of file descriptor %d: %s",
3665  fd, _dbus_strerror (errno));
3666  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3667  fd, _dbus_strerror (errno));
3668 
3669  return FALSE;
3670  }
3671 
3672  return TRUE;
3673 }
3674 
3680 void
3682 {
3683 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3684  void *bt[500];
3685  int bt_size;
3686  int i;
3687  char **syms;
3688 
3689  bt_size = backtrace (bt, 500);
3690 
3691  syms = backtrace_symbols (bt, bt_size);
3692 
3693  i = 0;
3694  while (i < bt_size)
3695  {
3696  /* don't use dbus_warn since it can _dbus_abort() */
3697  fprintf (stderr, " %s\n", syms[i]);
3698  ++i;
3699  }
3700  fflush (stderr);
3701 
3702  free (syms);
3703 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3704  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3705 #else
3706  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3707 #endif
3708 }
3709 
3724  DBusSocket *fd2,
3725  dbus_bool_t blocking,
3726  DBusError *error)
3727 {
3728 #ifdef HAVE_SOCKETPAIR
3729  int fds[2];
3730  int retval;
3731 
3732 #ifdef SOCK_CLOEXEC
3733  dbus_bool_t cloexec_done;
3734 
3735  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3736  cloexec_done = retval >= 0;
3737 
3738  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3739 #endif
3740  {
3741  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3742  }
3743 
3744  if (retval < 0)
3745  {
3746  dbus_set_error (error, _dbus_error_from_errno (errno),
3747  "Could not create full-duplex pipe");
3748  return FALSE;
3749  }
3750 
3751  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3752 
3753 #ifdef SOCK_CLOEXEC
3754  if (!cloexec_done)
3755 #endif
3756  {
3757  _dbus_fd_set_close_on_exec (fds[0]);
3758  _dbus_fd_set_close_on_exec (fds[1]);
3759  }
3760 
3761  if (!blocking &&
3762  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3763  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3764  {
3765  dbus_set_error (error, _dbus_error_from_errno (errno),
3766  "Could not set full-duplex pipe nonblocking");
3767 
3768  _dbus_close (fds[0], NULL);
3769  _dbus_close (fds[1], NULL);
3770 
3771  return FALSE;
3772  }
3773 
3774  fd1->fd = fds[0];
3775  fd2->fd = fds[1];
3776 
3777  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3778  fd1->fd, fd2->fd);
3779 
3780  return TRUE;
3781 #else
3782  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3784  "_dbus_socketpair() not implemented on this OS");
3785  return FALSE;
3786 #endif
3787 }
3788 
3797 int
3799  va_list args)
3800 {
3801  char static_buf[1024];
3802  int bufsize = sizeof (static_buf);
3803  int len;
3804  va_list args_copy;
3805 
3806  DBUS_VA_COPY (args_copy, args);
3807  len = vsnprintf (static_buf, bufsize, format, args_copy);
3808  va_end (args_copy);
3809 
3810  /* If vsnprintf() returned non-negative, then either the string fits in
3811  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3812  * returns the number of characters that were needed, or this OS returns the
3813  * truncated length.
3814  *
3815  * We ignore the possibility that snprintf might just ignore the length and
3816  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3817  * If your libc is really that bad, come back when you have a better one. */
3818  if (len == bufsize)
3819  {
3820  /* This could be the truncated length (Tru64 and IRIX have this bug),
3821  * or the real length could be coincidentally the same. Which is it?
3822  * If vsnprintf returns the truncated length, we'll go to the slow
3823  * path. */
3824  DBUS_VA_COPY (args_copy, args);
3825 
3826  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3827  len = -1;
3828 
3829  va_end (args_copy);
3830  }
3831 
3832  /* If vsnprintf() returned negative, we have to do more work.
3833  * HP-UX returns negative. */
3834  while (len < 0)
3835  {
3836  char *buf;
3837 
3838  bufsize *= 2;
3839 
3840  buf = dbus_malloc (bufsize);
3841 
3842  if (buf == NULL)
3843  return -1;
3844 
3845  DBUS_VA_COPY (args_copy, args);
3846  len = vsnprintf (buf, bufsize, format, args_copy);
3847  va_end (args_copy);
3848 
3849  dbus_free (buf);
3850 
3851  /* If the reported length is exactly the buffer size, round up to the
3852  * next size, in case vsnprintf has been returning the truncated
3853  * length */
3854  if (len == bufsize)
3855  len = -1;
3856  }
3857 
3858  return len;
3859 }
3860 
3867 const char*
3869 {
3870  /* Protected by _DBUS_LOCK_sysdeps */
3871  static const char* tmpdir = NULL;
3872 
3873  if (!_DBUS_LOCK (sysdeps))
3874  return NULL;
3875 
3876  if (tmpdir == NULL)
3877  {
3878  /* TMPDIR is what glibc uses, then
3879  * glibc falls back to the P_tmpdir macro which
3880  * just expands to "/tmp"
3881  */
3882  if (tmpdir == NULL)
3883  tmpdir = getenv("TMPDIR");
3884 
3885  /* These two env variables are probably
3886  * broken, but maybe some OS uses them?
3887  */
3888  if (tmpdir == NULL)
3889  tmpdir = getenv("TMP");
3890  if (tmpdir == NULL)
3891  tmpdir = getenv("TEMP");
3892 
3893  /* And this is the sane fallback. */
3894  if (tmpdir == NULL)
3895  tmpdir = "/tmp";
3896  }
3897 
3898  _DBUS_UNLOCK (sysdeps);
3899 
3900  _dbus_assert(tmpdir != NULL);
3901 
3902  return tmpdir;
3903 }
3904 
3905 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3925 static dbus_bool_t
3926 _read_subprocess_line_argv (const char *progpath,
3927  dbus_bool_t path_fallback,
3928  const char * const *argv,
3929  DBusString *result,
3930  DBusError *error)
3931 {
3932  int result_pipe[2] = { -1, -1 };
3933  int errors_pipe[2] = { -1, -1 };
3934  pid_t pid;
3935  int ret;
3936  int status;
3937  int orig_len;
3938 
3939  dbus_bool_t retval;
3940  sigset_t new_set, old_set;
3941 
3942  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3943  retval = FALSE;
3944 
3945  /* We need to block any existing handlers for SIGCHLD temporarily; they
3946  * will cause waitpid() below to fail.
3947  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3948  */
3949  sigemptyset (&new_set);
3950  sigaddset (&new_set, SIGCHLD);
3951  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3952 
3953  orig_len = _dbus_string_get_length (result);
3954 
3955 #define READ_END 0
3956 #define WRITE_END 1
3957  if (pipe (result_pipe) < 0)
3958  {
3959  dbus_set_error (error, _dbus_error_from_errno (errno),
3960  "Failed to create a pipe to call %s: %s",
3961  progpath, _dbus_strerror (errno));
3962  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3963  progpath, _dbus_strerror (errno));
3964  goto out;
3965  }
3966  if (pipe (errors_pipe) < 0)
3967  {
3968  dbus_set_error (error, _dbus_error_from_errno (errno),
3969  "Failed to create a pipe to call %s: %s",
3970  progpath, _dbus_strerror (errno));
3971  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3972  progpath, _dbus_strerror (errno));
3973  goto out;
3974  }
3975 
3976  /* Make sure our output buffers aren't redundantly printed by both the
3977  * parent and the child */
3978  fflush (stdout);
3979  fflush (stderr);
3980 
3981  pid = fork ();
3982  if (pid < 0)
3983  {
3984  dbus_set_error (error, _dbus_error_from_errno (errno),
3985  "Failed to fork() to call %s: %s",
3986  progpath, _dbus_strerror (errno));
3987  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3988  progpath, _dbus_strerror (errno));
3989  goto out;
3990  }
3991 
3992  if (pid == 0)
3993  {
3994  /* child process */
3995  const char *error_str;
3996 
3997  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3998  {
3999  int saved_errno = errno;
4000 
4001  /* Try to write details into the pipe, but don't bother
4002  * trying too hard (no retry loop). */
4003 
4004  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
4005  write (errors_pipe[WRITE_END], ": ", 2) < 0)
4006  {
4007  /* ignore, not much we can do */
4008  }
4009 
4010  error_str = _dbus_strerror (saved_errno);
4011 
4012  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
4013  {
4014  /* ignore, not much we can do */
4015  }
4016 
4017  _exit (1);
4018  }
4019 
4020  /* set-up stdXXX */
4021  close (result_pipe[READ_END]);
4022  close (errors_pipe[READ_END]);
4023 
4024  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
4025  _exit (1);
4026  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
4027  _exit (1);
4028 
4029  _dbus_close_all ();
4030 
4031  sigprocmask (SIG_SETMASK, &old_set, NULL);
4032 
4033  /* If it looks fully-qualified, try execv first */
4034  if (progpath[0] == '/')
4035  {
4036  execv (progpath, (char * const *) argv);
4037  /* Ok, that failed. Now if path_fallback is given, let's
4038  * try unqualified. This is mostly a hack to work
4039  * around systems which ship dbus-launch in /usr/bin
4040  * but everything else in /bin (because dbus-launch
4041  * depends on X11).
4042  */
4043  if (path_fallback)
4044  /* We must have a slash, because we checked above */
4045  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4046  }
4047  else
4048  execvp (progpath, (char * const *) argv);
4049 
4050  /* still nothing, we failed */
4051  _exit (1);
4052  }
4053 
4054  /* parent process */
4055  close (result_pipe[WRITE_END]);
4056  close (errors_pipe[WRITE_END]);
4057  result_pipe[WRITE_END] = -1;
4058  errors_pipe[WRITE_END] = -1;
4059 
4060  ret = 0;
4061  do
4062  {
4063  ret = _dbus_read (result_pipe[READ_END], result, 1024);
4064  }
4065  while (ret > 0);
4066 
4067  /* reap the child process to avoid it lingering as zombie */
4068  do
4069  {
4070  ret = waitpid (pid, &status, 0);
4071  }
4072  while (ret == -1 && errno == EINTR);
4073 
4074  /* We succeeded if the process exited with status 0 and
4075  anything was read */
4076  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4077  {
4078  /* The process ended with error */
4079  DBusString error_message;
4080  if (!_dbus_string_init (&error_message))
4081  {
4082  _DBUS_SET_OOM (error);
4083  goto out;
4084  }
4085 
4086  ret = 0;
4087  do
4088  {
4089  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4090  }
4091  while (ret > 0);
4092 
4093  _dbus_string_set_length (result, orig_len);
4094  if (_dbus_string_get_length (&error_message) > 0)
4096  "%s terminated abnormally with the following error: %s",
4097  progpath, _dbus_string_get_data (&error_message));
4098  else
4100  "%s terminated abnormally without any error message",
4101  progpath);
4102  goto out;
4103  }
4104 
4105  retval = TRUE;
4106 
4107  out:
4108  sigprocmask (SIG_SETMASK, &old_set, NULL);
4109 
4110  _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4111 
4112  if (result_pipe[0] != -1)
4113  close (result_pipe[0]);
4114  if (result_pipe[1] != -1)
4115  close (result_pipe[1]);
4116  if (errors_pipe[0] != -1)
4117  close (errors_pipe[0]);
4118  if (errors_pipe[1] != -1)
4119  close (errors_pipe[1]);
4120 
4121  return retval;
4122 }
4123 #endif
4124 
4138 _dbus_get_autolaunch_address (const char *scope,
4139  DBusString *address,
4140  DBusError *error)
4141 {
4142 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4143  static const char arg_dbus_launch[] = "dbus-launch";
4144  static const char arg_autolaunch[] = "--autolaunch";
4145  static const char arg_binary_syntax[] = "--binary-syntax";
4146  static const char arg_close_stderr[] = "--close-stderr";
4147 
4148  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4149  * but that's done elsewhere, and if it worked, this function wouldn't
4150  * be called.) */
4151  const char *display;
4152  const char *progpath;
4153  const char *argv[6];
4154  int i;
4155  DBusString uuid;
4156  dbus_bool_t retval;
4157 
4158  if (_dbus_check_setuid ())
4159  {
4161  "Unable to autolaunch when setuid");
4162  return FALSE;
4163  }
4164 
4165  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4166  retval = FALSE;
4167 
4168  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4169  * dbus-launch-x11 is just going to fail. Rather than trying to
4170  * run it, we might as well bail out early with a nice error.
4171  *
4172  * This is not strictly true in a world where the user bus exists,
4173  * because dbus-launch --autolaunch knows how to connect to that -
4174  * but if we were going to connect to the user bus, we'd have done
4175  * so before trying autolaunch: in any case. */
4176  display = _dbus_getenv ("DISPLAY");
4177 
4178  if (display == NULL || display[0] == '\0')
4179  {
4181  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4182  return FALSE;
4183  }
4184 
4185  if (!_dbus_string_init (&uuid))
4186  {
4187  _DBUS_SET_OOM (error);
4188  return FALSE;
4189  }
4190 
4191  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4192  {
4193  goto out;
4194  }
4195 
4196 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4197  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4198 
4199  if (progpath == NULL)
4200 #endif
4201  progpath = DBUS_BINDIR "/dbus-launch";
4202  /*
4203  * argv[0] is always dbus-launch, that's the name what we'll
4204  * get from /proc, or ps(1), regardless what the progpath is,
4205  * see fd.o#69716
4206  */
4207  i = 0;
4208  argv[i] = arg_dbus_launch;
4209  ++i;
4210  argv[i] = arg_autolaunch;
4211  ++i;
4212  argv[i] = _dbus_string_get_data (&uuid);
4213  ++i;
4214  argv[i] = arg_binary_syntax;
4215  ++i;
4216  argv[i] = arg_close_stderr;
4217  ++i;
4218  argv[i] = NULL;
4219  ++i;
4220 
4221  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4222 
4223  retval = _read_subprocess_line_argv (progpath,
4224  TRUE,
4225  argv, address, error);
4226 
4227  out:
4228  _dbus_string_free (&uuid);
4229  return retval;
4230 #else
4232  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4233  "set your DBUS_SESSION_BUS_ADDRESS instead");
4234  return FALSE;
4235 #endif
4236 }
4237 
4258  dbus_bool_t create_if_not_found,
4259  DBusError *error)
4260 {
4261  DBusError our_error = DBUS_ERROR_INIT;
4262  DBusError etc_error = DBUS_ERROR_INIT;
4263  DBusString filename;
4264  dbus_bool_t b;
4265 
4266  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4267 
4268  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4269  if (b)
4270  return TRUE;
4271 
4272  /* Fallback to the system machine ID */
4273  _dbus_string_init_const (&filename, "/etc/machine-id");
4274  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4275 
4276  if (b)
4277  {
4278  if (create_if_not_found)
4279  {
4280  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4281  * complain if that isn't possible for whatever reason */
4282  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4283  _dbus_write_uuid_file (&filename, machine_id, NULL);
4284  }
4285 
4286  dbus_error_free (&our_error);
4287  return TRUE;
4288  }
4289 
4290  if (!create_if_not_found)
4291  {
4292  dbus_set_error (error, etc_error.name,
4293  "D-Bus library appears to be incorrectly set up: "
4294  "see the manual page for dbus-uuidgen to correct "
4295  "this issue. (%s; %s)",
4296  our_error.message, etc_error.message);
4297  dbus_error_free (&our_error);
4298  dbus_error_free (&etc_error);
4299  return FALSE;
4300  }
4301 
4302  dbus_error_free (&our_error);
4303  dbus_error_free (&etc_error);
4304 
4305  /* if none found, try to make a new one */
4306  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4307 
4308  if (!_dbus_generate_uuid (machine_id, error))
4309  return FALSE;
4310 
4311  return _dbus_write_uuid_file (&filename, machine_id, error);
4312 }
4313 
4323  const char *launchd_env_var,
4324  DBusError *error)
4325 {
4326 #ifdef DBUS_ENABLE_LAUNCHD
4327  char *argv[4];
4328  int i;
4329 
4330  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4331 
4332  if (_dbus_check_setuid ())
4333  {
4335  "Unable to find launchd socket when setuid");
4336  return FALSE;
4337  }
4338 
4339  i = 0;
4340  argv[i] = "launchctl";
4341  ++i;
4342  argv[i] = "getenv";
4343  ++i;
4344  argv[i] = (char*)launchd_env_var;
4345  ++i;
4346  argv[i] = NULL;
4347  ++i;
4348 
4349  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4350 
4351  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4352  {
4353  return FALSE;
4354  }
4355 
4356  /* no error, but no result either */
4357  if (_dbus_string_get_length(socket_path) == 0)
4358  {
4359  return FALSE;
4360  }
4361 
4362  /* strip the carriage-return */
4363  _dbus_string_shorten(socket_path, 1);
4364  return TRUE;
4365 #else /* DBUS_ENABLE_LAUNCHD */
4367  "can't lookup socket from launchd; launchd support not compiled in");
4368  return FALSE;
4369 #endif
4370 }
4371 
4372 #ifdef DBUS_ENABLE_LAUNCHD
4373 static dbus_bool_t
4374 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4375 {
4376  dbus_bool_t valid_socket;
4377  DBusString socket_path;
4378 
4379  if (_dbus_check_setuid ())
4380  {
4382  "Unable to find launchd socket when setuid");
4383  return FALSE;
4384  }
4385 
4386  if (!_dbus_string_init (&socket_path))
4387  {
4388  _DBUS_SET_OOM (error);
4389  return FALSE;
4390  }
4391 
4392  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4393 
4394  if (dbus_error_is_set(error))
4395  {
4396  _dbus_string_free(&socket_path);
4397  return FALSE;
4398  }
4399 
4400  if (!valid_socket)
4401  {
4402  dbus_set_error(error, "no socket path",
4403  "launchd did not provide a socket path, "
4404  "verify that org.freedesktop.dbus-session.plist is loaded!");
4405  _dbus_string_free(&socket_path);
4406  return FALSE;
4407  }
4408  if (!_dbus_string_append (address, "unix:path="))
4409  {
4410  _DBUS_SET_OOM (error);
4411  _dbus_string_free(&socket_path);
4412  return FALSE;
4413  }
4414  if (!_dbus_string_copy (&socket_path, 0, address,
4415  _dbus_string_get_length (address)))
4416  {
4417  _DBUS_SET_OOM (error);
4418  _dbus_string_free(&socket_path);
4419  return FALSE;
4420  }
4421 
4422  _dbus_string_free(&socket_path);
4423  return TRUE;
4424 }
4425 #endif
4426 
4428 _dbus_lookup_user_bus (dbus_bool_t *supported,
4429  DBusString *address,
4430  DBusError *error)
4431 {
4432  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4433  dbus_bool_t ret = FALSE;
4434  struct stat stbuf;
4435  DBusString user_bus_path;
4436 
4437  if (runtime_dir == NULL)
4438  {
4439  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4440  *supported = FALSE;
4441  return TRUE; /* Cannot use it, but not an error */
4442  }
4443 
4444  if (!_dbus_string_init (&user_bus_path))
4445  {
4446  _DBUS_SET_OOM (error);
4447  return FALSE;
4448  }
4449 
4450  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4451  {
4452  _DBUS_SET_OOM (error);
4453  goto out;
4454  }
4455 
4456  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4457  {
4458  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4459  _dbus_strerror (errno));
4460  *supported = FALSE;
4461  ret = TRUE; /* Cannot use it, but not an error */
4462  goto out;
4463  }
4464 
4465  if (stbuf.st_uid != getuid ())
4466  {
4467  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4468  (long) stbuf.st_uid, (long) getuid ());
4469  *supported = FALSE;
4470  ret = TRUE; /* Cannot use it, but not an error */
4471  goto out;
4472  }
4473 
4474  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4475  {
4476  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4477  (long) stbuf.st_mode);
4478  *supported = FALSE;
4479  ret = TRUE; /* Cannot use it, but not an error */
4480  goto out;
4481  }
4482 
4483  if (!_dbus_string_append (address, "unix:path=") ||
4484  !_dbus_address_append_escaped (address, &user_bus_path))
4485  {
4486  _DBUS_SET_OOM (error);
4487  goto out;
4488  }
4489 
4490  *supported = TRUE;
4491  ret = TRUE;
4492 
4493 out:
4494  _dbus_string_free (&user_bus_path);
4495  return ret;
4496 }
4497 
4519  DBusString *address,
4520  DBusError *error)
4521 {
4522 #ifdef DBUS_ENABLE_LAUNCHD
4523  *supported = TRUE;
4524  return _dbus_lookup_session_address_launchd (address, error);
4525 #else
4526  *supported = FALSE;
4527 
4528  if (!_dbus_lookup_user_bus (supported, address, error))
4529  return FALSE;
4530  else if (*supported)
4531  return TRUE;
4532 
4533  /* On non-Mac Unix platforms, if the session address isn't already
4534  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4535  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4536  * autolaunch: global default; see init_session_address in
4537  * dbus/dbus-bus.c. */
4538  return TRUE;
4539 #endif
4540 }
4541 
4549 void
4551 {
4553 }
4554 
4570  DBusCredentials *credentials)
4571 {
4572  DBusString homedir;
4573  DBusString dotdir;
4574  dbus_uid_t uid;
4575 
4576  _dbus_assert (credentials != NULL);
4578 
4579  if (!_dbus_string_init (&homedir))
4580  return FALSE;
4581 
4582  uid = _dbus_credentials_get_unix_uid (credentials);
4583  _dbus_assert (uid != DBUS_UID_UNSET);
4584 
4585  if (!_dbus_homedir_from_uid (uid, &homedir))
4586  goto failed;
4587 
4588 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4589  {
4590  const char *override;
4591 
4592  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4593  if (override != NULL && *override != '\0')
4594  {
4595  _dbus_string_set_length (&homedir, 0);
4596  if (!_dbus_string_append (&homedir, override))
4597  goto failed;
4598 
4599  _dbus_verbose ("Using fake homedir for testing: %s\n",
4600  _dbus_string_get_const_data (&homedir));
4601  }
4602  else
4603  {
4604  /* Not strictly thread-safe, but if we fail at thread-safety here,
4605  * the worst that will happen is some extra warnings. */
4606  static dbus_bool_t already_warned = FALSE;
4607  if (!already_warned)
4608  {
4609  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4610  _dbus_string_get_const_data (&homedir));
4611  already_warned = TRUE;
4612  }
4613  }
4614  }
4615 #endif
4616 
4617  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4618  if (!_dbus_concat_dir_and_file (&homedir,
4619  &dotdir))
4620  goto failed;
4621 
4622  if (!_dbus_string_copy (&homedir, 0,
4623  directory, _dbus_string_get_length (directory))) {
4624  goto failed;
4625  }
4626 
4627  _dbus_string_free (&homedir);
4628  return TRUE;
4629 
4630  failed:
4631  _dbus_string_free (&homedir);
4632  return FALSE;
4633 }
4634 
4635 /* Documented in dbus-sysdeps-win.c, does nothing on Unix */
4636 void
4637 _dbus_daemon_unpublish_session_bus_address (void)
4638 {
4639 }
4640 
4649 {
4650  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4651  * EWOULDBLOCK are numerically equal, which is permitted as described by
4652  * errno(3).
4653  */
4654 #if EAGAIN == EWOULDBLOCK
4655  return e == EAGAIN;
4656 #else
4657  return e == EAGAIN || e == EWOULDBLOCK;
4658 #endif
4659 }
4660 
4670  DBusError *error)
4671 {
4672  const char *filename_c;
4673 
4674  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4675 
4676  filename_c = _dbus_string_get_const_data (filename);
4677 
4678  if (rmdir (filename_c) != 0)
4679  {
4681  "Failed to remove directory %s: %s\n",
4682  filename_c, _dbus_strerror (errno));
4683  return FALSE;
4684  }
4685 
4686  return TRUE;
4687 }
4688 
4698 {
4699 #ifdef SCM_RIGHTS
4700  union {
4701  struct sockaddr sa;
4702  struct sockaddr_storage storage;
4703  struct sockaddr_un un;
4704  } sa_buf;
4705 
4706  socklen_t sa_len = sizeof(sa_buf);
4707 
4708  _DBUS_ZERO(sa_buf);
4709 
4710  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4711  return FALSE;
4712 
4713  return sa_buf.sa.sa_family == AF_UNIX;
4714 
4715 #else
4716  return FALSE;
4717 
4718 #endif
4719 }
4720 
4721 static void
4722 close_ignore_error (int fd)
4723 {
4724  close (fd);
4725 }
4726 
4727 /*
4728  * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4729  * and may call func for integers that are not actually valid fds.
4730  */
4731 static void
4732 act_on_fds_3_and_up (void (*func) (int fd))
4733 {
4734  int maxfds, i;
4735 
4736 #if defined(__linux__) && defined(__GLIBC__)
4737  DIR *d;
4738 
4739  /* On Linux we can optimize this a bit if /proc is available. If it
4740  isn't available, fall back to the brute force way. */
4741 
4742  d = opendir ("/proc/self/fd");
4743  if (d)
4744  {
4745  for (;;)
4746  {
4747  struct dirent *de;
4748  int fd;
4749  long l;
4750  char *e = NULL;
4751 
4752  de = readdir (d);
4753  if (!de)
4754  break;
4755 
4756  if (de->d_name[0] == '.')
4757  continue;
4758 
4759  errno = 0;
4760  l = strtol (de->d_name, &e, 10);
4761  if (errno != 0 || e == NULL || *e != '\0')
4762  continue;
4763 
4764  fd = (int) l;
4765  if (fd < 3)
4766  continue;
4767 
4768  if (fd == dirfd (d))
4769  continue;
4770 
4771  func (fd);
4772  }
4773 
4774  closedir (d);
4775  return;
4776  }
4777 #endif
4778 
4779  maxfds = sysconf (_SC_OPEN_MAX);
4780 
4781  /* Pick something reasonable if for some reason sysconf says
4782  * unlimited.
4783  */
4784  if (maxfds < 0)
4785  maxfds = 1024;
4786 
4787  /* close all inherited fds */
4788  for (i = 3; i < maxfds; i++)
4789  func (i);
4790 }
4791 
4796 void
4798 {
4799  act_on_fds_3_and_up (close_ignore_error);
4800 }
4801 
4806 void
4808 {
4809  act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4810 }
4811 
4823 {
4824  /* TODO: get __libc_enable_secure exported from glibc.
4825  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4826  */
4827 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4828  {
4829  /* See glibc/include/unistd.h */
4830  extern int __libc_enable_secure;
4831  return __libc_enable_secure;
4832  }
4833 #elif defined(HAVE_ISSETUGID)
4834  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4835  return issetugid ();
4836 #else
4837  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4838  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4839 
4840  /* We call into this function from _dbus_threads_init_platform_specific()
4841  * to make sure these are initialized before we start threading. */
4842  static dbus_bool_t check_setuid_initialised;
4843  static dbus_bool_t is_setuid;
4844 
4845  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4846  {
4847 #ifdef HAVE_GETRESUID
4848  if (getresuid (&ruid, &euid, &suid) != 0 ||
4849  getresgid (&rgid, &egid, &sgid) != 0)
4850 #endif /* HAVE_GETRESUID */
4851  {
4852  suid = ruid = getuid ();
4853  sgid = rgid = getgid ();
4854  euid = geteuid ();
4855  egid = getegid ();
4856  }
4857 
4858  check_setuid_initialised = TRUE;
4859  is_setuid = (ruid != euid || ruid != suid ||
4860  rgid != egid || rgid != sgid);
4861 
4862  }
4863  return is_setuid;
4864 #endif
4865 }
4866 
4876  DBusString *address,
4877  DBusError *error)
4878 {
4879  union {
4880  struct sockaddr sa;
4881  struct sockaddr_storage storage;
4882  struct sockaddr_un un;
4883  struct sockaddr_in ipv4;
4884  struct sockaddr_in6 ipv6;
4885  } socket;
4886  char hostip[INET6_ADDRSTRLEN];
4887  socklen_t size = sizeof (socket);
4888  DBusString path_str;
4889  const char *family_name = NULL;
4890  dbus_uint16_t port;
4891 
4892  if (getsockname (fd.fd, &socket.sa, &size))
4893  goto err;
4894 
4895  switch (socket.sa.sa_family)
4896  {
4897  case AF_UNIX:
4898  if (socket.un.sun_path[0]=='\0')
4899  {
4900  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4901  if (_dbus_string_append (address, "unix:abstract=") &&
4902  _dbus_address_append_escaped (address, &path_str))
4903  {
4904  return TRUE;
4905  }
4906  else
4907  {
4908  _DBUS_SET_OOM (error);
4909  return FALSE;
4910  }
4911  }
4912  else
4913  {
4914  _dbus_string_init_const (&path_str, socket.un.sun_path);
4915  if (_dbus_string_append (address, "unix:path=") &&
4916  _dbus_address_append_escaped (address, &path_str))
4917  {
4918  return TRUE;
4919  }
4920  else
4921  {
4922  _DBUS_SET_OOM (error);
4923  return FALSE;
4924  }
4925  }
4926  /* not reached */
4927  break;
4928 
4929  case AF_INET:
4930 #ifdef AF_INET6
4931  case AF_INET6:
4932 #endif
4933  _dbus_string_init_const (&path_str, hostip);
4934 
4935  if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
4936  &family_name, &port, error))
4937  {
4938  if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
4939  family_name, port) &&
4940  _dbus_address_append_escaped (address, &path_str))
4941  {
4942  return TRUE;
4943  }
4944  else
4945  {
4946  _DBUS_SET_OOM (error);
4947  return FALSE;
4948  }
4949  }
4950  else
4951  {
4952  return FALSE;
4953  }
4954  /* not reached */
4955  break;
4956 
4957  default:
4958  dbus_set_error (error,
4959  _dbus_error_from_errno (EINVAL),
4960  "Failed to read address from socket: Unknown socket type.");
4961  return FALSE;
4962  }
4963  err:
4964  dbus_set_error (error,
4965  _dbus_error_from_errno (errno),
4966  "Failed to read address from socket: %s",
4967  _dbus_strerror (errno));
4968  return FALSE;
4969 }
4970 
4971 int
4972 _dbus_save_socket_errno (void)
4973 {
4974  return errno;
4975 }
4976 
4977 void
4978 _dbus_restore_socket_errno (int saved_errno)
4979 {
4980  errno = saved_errno;
4981 }
4982 
4983 static const char *syslog_tag = "dbus";
4984 #ifdef HAVE_SYSLOG_H
4985 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4986 #endif
4987 
5002 void
5003 _dbus_init_system_log (const char *tag,
5004  DBusLogFlags flags)
5005 {
5006  /* We never want to turn off logging completely */
5007  _dbus_assert (
5008  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
5009 
5010  syslog_tag = tag;
5011 
5012 #ifdef HAVE_SYSLOG_H
5013  log_flags = flags;
5014 
5015  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5016  openlog (tag, LOG_PID, LOG_DAEMON);
5017 #endif
5018 }
5019 
5027 void
5028 _dbus_logv (DBusSystemLogSeverity severity,
5029  const char *msg,
5030  va_list args)
5031 {
5032  va_list tmp;
5033 #ifdef HAVE_SYSLOG_H
5034  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5035  {
5036  int flags;
5037  switch (severity)
5038  {
5039  case DBUS_SYSTEM_LOG_INFO:
5040  flags = LOG_DAEMON | LOG_INFO;
5041  break;
5042  case DBUS_SYSTEM_LOG_WARNING:
5043  flags = LOG_DAEMON | LOG_WARNING;
5044  break;
5045  case DBUS_SYSTEM_LOG_SECURITY:
5046  flags = LOG_AUTH | LOG_NOTICE;
5047  break;
5048  case DBUS_SYSTEM_LOG_ERROR:
5049  flags = LOG_DAEMON|LOG_CRIT;
5050  break;
5051  default:
5052  _dbus_assert_not_reached ("invalid log severity");
5053  }
5054 
5055  DBUS_VA_COPY (tmp, args);
5056  vsyslog (flags, msg, tmp);
5057  va_end (tmp);
5058  }
5059 
5060  /* If we don't have syslog.h, we always behave as though stderr was in
5061  * the flags */
5062  if (log_flags & DBUS_LOG_FLAGS_STDERR)
5063 #endif
5064  {
5065  DBUS_VA_COPY (tmp, args);
5066  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5067  vfprintf (stderr, msg, tmp);
5068  fputc ('\n', stderr);
5069  va_end (tmp);
5070  }
5071 }
5072 
5073 /*
5074  * Return the low-level representation of a socket error, as used by
5075  * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5076  * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5077  *
5078  * Some libdbus internal functions copy this into errno, but with
5079  * hindsight that was probably a design flaw.
5080  */
5081 int
5082 _dbus_get_low_level_socket_errno (void)
5083 {
5084  return errno;
5085 }
5086 
5087 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:107
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials.
void _dbus_credentials_take_unix_gids(DBusCredentials *credentials, dbus_gid_t *gids, size_t n_gids)
Add UNIX group IDs to the credentials, replacing any group IDs that might already have been present.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:599
#define READ_END
Helps remember which end of the pipe is which.
#define WRITE_END
Helps remember which end of the pipe is which.
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:394
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:464
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
#define _DBUS_INT32_MAX
Maximum value of type "int32".
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:692
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:592
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:452
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:833
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:966
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1343
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:139
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:278
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:521
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:811
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:791
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:401
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1188
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:1145
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.
void _dbus_fd_clear_close_on_exec(int fd)
Sets the file descriptor to not be close-on-exec.
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_fd_set_all_close_on_exec(void)
Sets all file descriptors except the first three (i.e.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
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.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer.
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:429
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:137
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted)
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:135
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
void _dbus_exit(int code)
Exit the process, returning the given value.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:431
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
void _dbus_atomic_set_nonzero(DBusAtomic *atomic)
Atomically set the value of an integer to something nonzero.
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:139
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, unsigned int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:144
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a 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...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:142
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR,...
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:146
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:425
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, const char **retfamily, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the most important credentials of the current process (the uid and pid) to the passed-in credent...
void _dbus_atomic_set_zero(DBusAtomic *atomic)
Atomically set the value of an integer to 0.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with.
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:153
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul.
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:151
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked.
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:149
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:323
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:327
Object representing an exception.
Definition: dbus-errors.h:49
const char * name
public error name field
Definition: dbus-errors.h:50
const char * message
public error message field
Definition: dbus-errors.h:51
A node in a linked list.
Definition: dbus-list.h:35
short events
Events to poll for.
Definition: dbus-sysdeps.h:420
short revents
Events that occurred.
Definition: dbus-sysdeps.h:421
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:419
Socket interface.
Definition: dbus-sysdeps.h:181
Information about a UNIX user.
int n_group_ids
Size of group IDs array.
dbus_uid_t uid
UID.
char * homedir
Home directory.
dbus_gid_t * group_ids
Groups IDs, including above primary group.
char * username
Username.
dbus_gid_t primary_gid
GID.
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...