D-Bus  1.10.32
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_WRITEV
66 #include <sys/uio.h>
67 #endif
68 #ifdef HAVE_POLL
69 #include <sys/poll.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 
81 #ifdef HAVE_ADT
82 #include <bsm/adt.h>
83 #endif
84 
85 #ifdef HAVE_SYSTEMD
86 #include <systemd/sd-daemon.h>
87 #endif
88 
89 #if !DBUS_USE_SYNC
90 #include <pthread.h>
91 #endif
92 
93 #ifndef O_BINARY
94 #define O_BINARY 0
95 #endif
96 
97 #ifndef AI_ADDRCONFIG
98 #define AI_ADDRCONFIG 0
99 #endif
100 
101 #ifndef HAVE_SOCKLEN_T
102 #define socklen_t int
103 #endif
104 
105 #if defined (__sun) || defined (__sun__)
106 /*
107  * CMS_SPACE etc. definitions for Solaris < 10, based on
108  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
109  * via
110  * http://wiki.opencsw.org/porting-faq#toc10
111  *
112  * These are only redefined for Solaris, for now: if your OS needs these too,
113  * please file a bug. (Or preferably, improve your OS so they're not needed.)
114  */
115 
116 # ifndef CMSG_ALIGN
117 # ifdef __sun__
118 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
119 # else
120  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
121 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
122  ~(sizeof (long) - 1))
123 # endif
124 # endif
125 
126 # ifndef CMSG_SPACE
127 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
128  CMSG_ALIGN (len))
129 # endif
130 
131 # ifndef CMSG_LEN
132 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
133 # endif
134 
135 #endif /* Solaris */
136 
152 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
153  const char **error_str_p)
154 {
155  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
156  DBUS_FORCE_STDOUT_NULL,
157  DBUS_FORCE_STDERR_NULL };
158  /* Should always get replaced with the real error before use */
159  const char *error_str = "Failed mysteriously";
160  int devnull = -1;
161  int saved_errno;
162  /* This function relies on the standard fds having their POSIX values. */
163  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
164  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
165  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
166  int i;
167 
168  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
169  {
170  /* Because we rely on being single-threaded, and we want the
171  * standard fds to not be close-on-exec, we don't set it
172  * close-on-exec. */
173  if (devnull < i)
174  devnull = open ("/dev/null", O_RDWR);
175 
176  if (devnull < 0)
177  {
178  error_str = "Failed to open /dev/null";
179  goto out;
180  }
181 
182  /* We already opened all fds < i, so the only way this assertion
183  * could fail is if another thread closed one, and we document
184  * this function as not safe for multi-threading. */
185  _dbus_assert (devnull >= i);
186 
187  if (devnull != i && (flags & relevant_flag[i]) != 0)
188  {
189  if (dup2 (devnull, i) < 0)
190  {
191  error_str = "Failed to dup2 /dev/null onto a standard fd";
192  goto out;
193  }
194  }
195  }
196 
197  error_str = NULL;
198 
199 out:
200  saved_errno = errno;
201 
202  if (devnull > STDERR_FILENO)
203  close (devnull);
204 
205  if (error_str_p != NULL)
206  *error_str_p = error_str;
207 
208  errno = saved_errno;
209  return (error_str == NULL);
210 }
211 
212 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
213  DBusError *error);
214 
215 static dbus_bool_t
216 _dbus_open_socket (int *fd_p,
217  int domain,
218  int type,
219  int protocol,
220  DBusError *error)
221 {
222 #ifdef SOCK_CLOEXEC
223  dbus_bool_t cloexec_done;
224 
225  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
226  cloexec_done = *fd_p >= 0;
227 
228  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
229  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
230 #endif
231  {
232  *fd_p = socket (domain, type, protocol);
233  }
234 
235  if (*fd_p >= 0)
236  {
237 #ifdef SOCK_CLOEXEC
238  if (!cloexec_done)
239 #endif
240  {
242  }
243 
244  _dbus_verbose ("socket fd %d opened\n", *fd_p);
245  return TRUE;
246  }
247  else
248  {
249  dbus_set_error(error,
250  _dbus_error_from_errno (errno),
251  "Failed to open socket: %s",
252  _dbus_strerror (errno));
253  return FALSE;
254  }
255 }
256 
267 static dbus_bool_t
268 _dbus_open_unix_socket (int *fd,
269  DBusError *error)
270 {
271  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
272 }
273 
284  DBusError *error)
285 {
286  return _dbus_close (fd.fd, error);
287 }
288 
298 int
300  DBusString *buffer,
301  int count)
302 {
303  return _dbus_read (fd.fd, buffer, count);
304 }
305 
316 int
318  const DBusString *buffer,
319  int start,
320  int len)
321 {
322 #if HAVE_DECL_MSG_NOSIGNAL
323  const char *data;
324  int bytes_written;
325 
326  data = _dbus_string_get_const_data_len (buffer, start, len);
327 
328  again:
329 
330  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
331 
332  if (bytes_written < 0 && errno == EINTR)
333  goto again;
334 
335  return bytes_written;
336 
337 #else
338  return _dbus_write (fd.fd, buffer, start, len);
339 #endif
340 }
341 
354 int
356  DBusString *buffer,
357  int count,
358  int *fds,
359  int *n_fds) {
360 #ifndef HAVE_UNIX_FD_PASSING
361  int r;
362 
363  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
364  return r;
365 
366  *n_fds = 0;
367  return r;
368 
369 #else
370  int bytes_read;
371  int start;
372  struct msghdr m;
373  struct iovec iov;
374 
375  _dbus_assert (count >= 0);
376  _dbus_assert (*n_fds >= 0);
377 
378  start = _dbus_string_get_length (buffer);
379 
380  if (!_dbus_string_lengthen (buffer, count))
381  {
382  errno = ENOMEM;
383  return -1;
384  }
385 
386  _DBUS_ZERO(iov);
387  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
388  iov.iov_len = count;
389 
390  _DBUS_ZERO(m);
391  m.msg_iov = &iov;
392  m.msg_iovlen = 1;
393 
394  /* Hmm, we have no clue how long the control data will actually be
395  that is queued for us. The least we can do is assume that the
396  caller knows. Hence let's make space for the number of fds that
397  we shall read at max plus the cmsg header. */
398  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
399 
400  /* It's probably safe to assume that systems with SCM_RIGHTS also
401  know alloca() */
402  m.msg_control = alloca(m.msg_controllen);
403  memset(m.msg_control, 0, m.msg_controllen);
404 
405  /* Do not include the padding at the end when we tell the kernel
406  * how much we're willing to receive. This avoids getting
407  * the padding filled with additional fds that we weren't expecting,
408  * if a (potentially malicious) sender included them. (fd.o #83622) */
409  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
410 
411  again:
412 
413  bytes_read = recvmsg (fd.fd, &m, 0
414 #ifdef MSG_CMSG_CLOEXEC
415  |MSG_CMSG_CLOEXEC
416 #endif
417  );
418 
419  if (bytes_read < 0)
420  {
421  if (errno == EINTR)
422  goto again;
423  else
424  {
425  /* put length back (note that this doesn't actually realloc anything) */
426  _dbus_string_set_length (buffer, start);
427  return -1;
428  }
429  }
430  else
431  {
432  struct cmsghdr *cm;
433  dbus_bool_t found = FALSE;
434 
435  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
436  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
437  {
438  size_t i;
439  int *payload = (int *) CMSG_DATA (cm);
440  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
441  size_t payload_len_fds;
442  size_t fds_to_use;
443 
444  /* Every non-negative int fits in a size_t without truncation,
445  * and we already know that *n_fds is non-negative, so
446  * casting (size_t) *n_fds is OK */
447  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
448 
449  if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
450  (char *) payload + payload_len_bytes >
451  (char *) m.msg_control + m.msg_controllen)
452  {
453  /* This is the last cmsg in a truncated message and using
454  * cmsg_len would apparently overrun the allocated buffer.
455  * Some operating systems (illumos and Solaris are known) do
456  * not adjust cmsg_len in the last cmsg when truncation occurs.
457  * Adjust the payload length here. The calculation for
458  * payload_len_fds below will discard any trailing bytes that
459  * belong to an incomplete file descriptor - the kernel will
460  * have already closed that (at least for illumos and Solaris)
461  */
462  payload_len_bytes = m.msg_controllen -
463  ((char *) payload - (char *) m.msg_control);
464  }
465 
466  payload_len_fds = payload_len_bytes / sizeof (int);
467 
468  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
469  {
470  /* The fds in the payload will fit in our buffer */
471  fds_to_use = payload_len_fds;
472  }
473  else
474  {
475  /* Too many fds in the payload. This shouldn't happen
476  * any more because we're setting m.msg_controllen to
477  * the exact number we can accept, but be safe and
478  * truncate. */
479  fds_to_use = (size_t) *n_fds;
480 
481  /* Close the excess fds to avoid DoS: if they stayed open,
482  * someone could send us an extra fd per message
483  * and we'd eventually run out. */
484  for (i = fds_to_use; i < payload_len_fds; i++)
485  {
486  close (payload[i]);
487  }
488  }
489 
490  memcpy (fds, payload, fds_to_use * sizeof (int));
491  found = TRUE;
492  /* This cannot overflow because we have chosen fds_to_use
493  * to be <= *n_fds */
494  *n_fds = (int) fds_to_use;
495 
496  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
497  worked, hence we need to go through this list and set
498  CLOEXEC everywhere in any case */
499  for (i = 0; i < fds_to_use; i++)
501 
502  break;
503  }
504 
505  if (!found)
506  *n_fds = 0;
507 
508  if (m.msg_flags & MSG_CTRUNC)
509  {
510  int i;
511 
512  /* Hmm, apparently the control data was truncated. The bad
513  thing is that we might have completely lost a couple of fds
514  without chance to recover them. Hence let's treat this as a
515  serious error. */
516 
517  /* We still need to close whatever fds we *did* receive,
518  * otherwise they'll never get closed. (CVE-2020-12049) */
519  for (i = 0; i < *n_fds; i++)
520  close (fds[i]);
521 
522  *n_fds = 0;
523  errno = ENOSPC;
524  _dbus_string_set_length (buffer, start);
525  return -1;
526  }
527 
528  /* put length back (doesn't actually realloc) */
529  _dbus_string_set_length (buffer, start + bytes_read);
530 
531 #if 0
532  if (bytes_read > 0)
533  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
534 #endif
535 
536  return bytes_read;
537  }
538 #endif
539 }
540 
541 int
542 _dbus_write_socket_with_unix_fds(DBusSocket fd,
543  const DBusString *buffer,
544  int start,
545  int len,
546  const int *fds,
547  int n_fds) {
548 
549 #ifndef HAVE_UNIX_FD_PASSING
550 
551  if (n_fds > 0) {
552  errno = ENOTSUP;
553  return -1;
554  }
555 
556  return _dbus_write_socket(fd, buffer, start, len);
557 #else
558  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
559 #endif
560 }
561 
562 int
563 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
564  const DBusString *buffer1,
565  int start1,
566  int len1,
567  const DBusString *buffer2,
568  int start2,
569  int len2,
570  const int *fds,
571  int n_fds) {
572 
573 #ifndef HAVE_UNIX_FD_PASSING
574 
575  if (n_fds > 0) {
576  errno = ENOTSUP;
577  return -1;
578  }
579 
580  return _dbus_write_socket_two(fd,
581  buffer1, start1, len1,
582  buffer2, start2, len2);
583 #else
584 
585  struct msghdr m;
586  struct cmsghdr *cm;
587  struct iovec iov[2];
588  int bytes_written;
589 
590  _dbus_assert (len1 >= 0);
591  _dbus_assert (len2 >= 0);
592  _dbus_assert (n_fds >= 0);
593 
594  _DBUS_ZERO(iov);
595  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
596  iov[0].iov_len = len1;
597 
598  if (buffer2)
599  {
600  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
601  iov[1].iov_len = len2;
602  }
603 
604  _DBUS_ZERO(m);
605  m.msg_iov = iov;
606  m.msg_iovlen = buffer2 ? 2 : 1;
607 
608  if (n_fds > 0)
609  {
610  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
611  m.msg_control = alloca(m.msg_controllen);
612  memset(m.msg_control, 0, m.msg_controllen);
613 
614  cm = CMSG_FIRSTHDR(&m);
615  cm->cmsg_level = SOL_SOCKET;
616  cm->cmsg_type = SCM_RIGHTS;
617  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
618  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
619  }
620 
621  again:
622 
623  bytes_written = sendmsg (fd.fd, &m, 0
624 #if HAVE_DECL_MSG_NOSIGNAL
625  |MSG_NOSIGNAL
626 #endif
627  );
628 
629  if (bytes_written < 0 && errno == EINTR)
630  goto again;
631 
632 #if 0
633  if (bytes_written > 0)
634  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
635 #endif
636 
637  return bytes_written;
638 #endif
639 }
640 
654 int
656  const DBusString *buffer1,
657  int start1,
658  int len1,
659  const DBusString *buffer2,
660  int start2,
661  int len2)
662 {
663 #if HAVE_DECL_MSG_NOSIGNAL
664  struct iovec vectors[2];
665  const char *data1;
666  const char *data2;
667  int bytes_written;
668  struct msghdr m;
669 
670  _dbus_assert (buffer1 != NULL);
671  _dbus_assert (start1 >= 0);
672  _dbus_assert (start2 >= 0);
673  _dbus_assert (len1 >= 0);
674  _dbus_assert (len2 >= 0);
675 
676  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
677 
678  if (buffer2 != NULL)
679  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
680  else
681  {
682  data2 = NULL;
683  start2 = 0;
684  len2 = 0;
685  }
686 
687  vectors[0].iov_base = (char*) data1;
688  vectors[0].iov_len = len1;
689  vectors[1].iov_base = (char*) data2;
690  vectors[1].iov_len = len2;
691 
692  _DBUS_ZERO(m);
693  m.msg_iov = vectors;
694  m.msg_iovlen = data2 ? 2 : 1;
695 
696  again:
697 
698  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
699 
700  if (bytes_written < 0 && errno == EINTR)
701  goto again;
702 
703  return bytes_written;
704 
705 #else
706  return _dbus_write_two (fd.fd, buffer1, start1, len1,
707  buffer2, start2, len2);
708 #endif
709 }
710 
727 int
728 _dbus_read (int fd,
729  DBusString *buffer,
730  int count)
731 {
732  int bytes_read;
733  int start;
734  char *data;
735 
736  _dbus_assert (count >= 0);
737 
738  start = _dbus_string_get_length (buffer);
739 
740  if (!_dbus_string_lengthen (buffer, count))
741  {
742  errno = ENOMEM;
743  return -1;
744  }
745 
746  data = _dbus_string_get_data_len (buffer, start, count);
747 
748  again:
749 
750  bytes_read = read (fd, data, count);
751 
752  if (bytes_read < 0)
753  {
754  if (errno == EINTR)
755  goto again;
756  else
757  {
758  /* put length back (note that this doesn't actually realloc anything) */
759  _dbus_string_set_length (buffer, start);
760  return -1;
761  }
762  }
763  else
764  {
765  /* put length back (doesn't actually realloc) */
766  _dbus_string_set_length (buffer, start + bytes_read);
767 
768 #if 0
769  if (bytes_read > 0)
770  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
771 #endif
772 
773  return bytes_read;
774  }
775 }
776 
787 int
788 _dbus_write (int fd,
789  const DBusString *buffer,
790  int start,
791  int len)
792 {
793  const char *data;
794  int bytes_written;
795 
796  data = _dbus_string_get_const_data_len (buffer, start, len);
797 
798  again:
799 
800  bytes_written = write (fd, data, len);
801 
802  if (bytes_written < 0 && errno == EINTR)
803  goto again;
804 
805 #if 0
806  if (bytes_written > 0)
807  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
808 #endif
809 
810  return bytes_written;
811 }
812 
833 int
835  const DBusString *buffer1,
836  int start1,
837  int len1,
838  const DBusString *buffer2,
839  int start2,
840  int len2)
841 {
842  _dbus_assert (buffer1 != NULL);
843  _dbus_assert (start1 >= 0);
844  _dbus_assert (start2 >= 0);
845  _dbus_assert (len1 >= 0);
846  _dbus_assert (len2 >= 0);
847 
848 #ifdef HAVE_WRITEV
849  {
850  struct iovec vectors[2];
851  const char *data1;
852  const char *data2;
853  int bytes_written;
854 
855  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
856 
857  if (buffer2 != NULL)
858  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
859  else
860  {
861  data2 = NULL;
862  start2 = 0;
863  len2 = 0;
864  }
865 
866  vectors[0].iov_base = (char*) data1;
867  vectors[0].iov_len = len1;
868  vectors[1].iov_base = (char*) data2;
869  vectors[1].iov_len = len2;
870 
871  again:
872 
873  bytes_written = writev (fd,
874  vectors,
875  data2 ? 2 : 1);
876 
877  if (bytes_written < 0 && errno == EINTR)
878  goto again;
879 
880  return bytes_written;
881  }
882 #else /* HAVE_WRITEV */
883  {
884  int ret1, ret2;
885 
886  ret1 = _dbus_write (fd, buffer1, start1, len1);
887  if (ret1 == len1 && buffer2 != NULL)
888  {
889  ret2 = _dbus_write (fd, buffer2, start2, len2);
890  if (ret2 < 0)
891  ret2 = 0; /* we can't report an error as the first write was OK */
892 
893  return ret1 + ret2;
894  }
895  else
896  return ret1;
897  }
898 #endif /* !HAVE_WRITEV */
899 }
900 
901 #define _DBUS_MAX_SUN_PATH_LENGTH 99
902 
932 int
933 _dbus_connect_unix_socket (const char *path,
934  dbus_bool_t abstract,
935  DBusError *error)
936 {
937  int fd;
938  size_t path_len;
939  struct sockaddr_un addr;
940  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
941 
942  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
943 
944  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
945  path, abstract);
946 
947 
948  if (!_dbus_open_unix_socket (&fd, error))
949  {
950  _DBUS_ASSERT_ERROR_IS_SET(error);
951  return -1;
952  }
953  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
954 
955  _DBUS_ZERO (addr);
956  addr.sun_family = AF_UNIX;
957  path_len = strlen (path);
958 
959  if (abstract)
960  {
961 #ifdef HAVE_ABSTRACT_SOCKETS
962  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
963  path_len++; /* Account for the extra nul byte added to the start of sun_path */
964 
965  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
966  {
968  "Abstract socket name too long\n");
969  _dbus_close (fd, NULL);
970  return -1;
971  }
972 
973  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
974  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
975 #else /* HAVE_ABSTRACT_SOCKETS */
977  "Operating system does not support abstract socket namespace\n");
978  _dbus_close (fd, NULL);
979  return -1;
980 #endif /* ! HAVE_ABSTRACT_SOCKETS */
981  }
982  else
983  {
984  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
985  {
987  "Socket name too long\n");
988  _dbus_close (fd, NULL);
989  return -1;
990  }
991 
992  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
993  }
994 
995  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
996  {
997  dbus_set_error (error,
998  _dbus_error_from_errno (errno),
999  "Failed to connect to socket %s: %s",
1000  path, _dbus_strerror (errno));
1001 
1002  _dbus_close (fd, NULL);
1003  return -1;
1004  }
1005 
1006  if (!_dbus_set_fd_nonblocking (fd, error))
1007  {
1008  _DBUS_ASSERT_ERROR_IS_SET (error);
1009 
1010  _dbus_close (fd, NULL);
1011  return -1;
1012  }
1013 
1014  return fd;
1015 }
1016 
1029 int
1030 _dbus_connect_exec (const char *path,
1031  char *const argv[],
1032  DBusError *error)
1033 {
1034  int fds[2];
1035  pid_t pid;
1036  int retval;
1037  dbus_bool_t cloexec_done = 0;
1038 
1039  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1040 
1041  _dbus_verbose ("connecting to process %s\n", path);
1042 
1043 #ifdef SOCK_CLOEXEC
1044  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1045  cloexec_done = (retval >= 0);
1046 
1047  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1048 #endif
1049  {
1050  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1051  }
1052 
1053  if (retval < 0)
1054  {
1055  dbus_set_error (error,
1056  _dbus_error_from_errno (errno),
1057  "Failed to create socket pair: %s",
1058  _dbus_strerror (errno));
1059  return -1;
1060  }
1061 
1062  if (!cloexec_done)
1063  {
1064  _dbus_fd_set_close_on_exec (fds[0]);
1065  _dbus_fd_set_close_on_exec (fds[1]);
1066  }
1067 
1068  pid = fork ();
1069  if (pid < 0)
1070  {
1071  dbus_set_error (error,
1072  _dbus_error_from_errno (errno),
1073  "Failed to fork() to call %s: %s",
1074  path, _dbus_strerror (errno));
1075  close (fds[0]);
1076  close (fds[1]);
1077  return -1;
1078  }
1079 
1080  if (pid == 0)
1081  {
1082  /* child */
1083  close (fds[0]);
1084 
1085  dup2 (fds[1], STDIN_FILENO);
1086  dup2 (fds[1], STDOUT_FILENO);
1087 
1088  if (fds[1] != STDIN_FILENO &&
1089  fds[1] != STDOUT_FILENO)
1090  close (fds[1]);
1091 
1092  /* Inherit STDERR and the controlling terminal from the
1093  parent */
1094 
1095  _dbus_close_all ();
1096 
1097  execvp (path, argv);
1098 
1099  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1100 
1101  _exit(1);
1102  }
1103 
1104  /* parent */
1105  close (fds[1]);
1106 
1107  if (!_dbus_set_fd_nonblocking (fds[0], error))
1108  {
1109  _DBUS_ASSERT_ERROR_IS_SET (error);
1110 
1111  close (fds[0]);
1112  return -1;
1113  }
1114 
1115  return fds[0];
1116 }
1117 
1135 int
1136 _dbus_listen_unix_socket (const char *path,
1137  dbus_bool_t abstract,
1138  DBusError *error)
1139 {
1140  int listen_fd;
1141  struct sockaddr_un addr;
1142  size_t path_len;
1143  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1144 
1145  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1146 
1147  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1148  path, abstract);
1149 
1150  if (!_dbus_open_unix_socket (&listen_fd, error))
1151  {
1152  _DBUS_ASSERT_ERROR_IS_SET(error);
1153  return -1;
1154  }
1155  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1156 
1157  _DBUS_ZERO (addr);
1158  addr.sun_family = AF_UNIX;
1159  path_len = strlen (path);
1160 
1161  if (abstract)
1162  {
1163 #ifdef HAVE_ABSTRACT_SOCKETS
1164  /* remember that abstract names aren't nul-terminated so we rely
1165  * on sun_path being filled in with zeroes above.
1166  */
1167  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1168  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1169 
1170  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1171  {
1173  "Abstract socket name too long\n");
1174  _dbus_close (listen_fd, NULL);
1175  return -1;
1176  }
1177 
1178  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1179  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1180 #else /* HAVE_ABSTRACT_SOCKETS */
1182  "Operating system does not support abstract socket namespace\n");
1183  _dbus_close (listen_fd, NULL);
1184  return -1;
1185 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1186  }
1187  else
1188  {
1189  /* Discussed security implications of this with Nalin,
1190  * and we couldn't think of where it would kick our ass, but
1191  * it still seems a bit sucky. It also has non-security suckage;
1192  * really we'd prefer to exit if the socket is already in use.
1193  * But there doesn't seem to be a good way to do this.
1194  *
1195  * Just to be extra careful, I threw in the stat() - clearly
1196  * the stat() can't *fix* any security issue, but it at least
1197  * avoids inadvertent/accidental data loss.
1198  */
1199  {
1200  struct stat sb;
1201 
1202  if (stat (path, &sb) == 0 &&
1203  S_ISSOCK (sb.st_mode))
1204  unlink (path);
1205  }
1206 
1207  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1208  {
1210  "Socket name too long\n");
1211  _dbus_close (listen_fd, NULL);
1212  return -1;
1213  }
1214 
1215  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1216  }
1217 
1218  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1219  {
1220  dbus_set_error (error, _dbus_error_from_errno (errno),
1221  "Failed to bind socket \"%s\": %s",
1222  path, _dbus_strerror (errno));
1223  _dbus_close (listen_fd, NULL);
1224  return -1;
1225  }
1226 
1227  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1228  {
1229  dbus_set_error (error, _dbus_error_from_errno (errno),
1230  "Failed to listen on socket \"%s\": %s",
1231  path, _dbus_strerror (errno));
1232  _dbus_close (listen_fd, NULL);
1233  return -1;
1234  }
1235 
1236  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1237  {
1238  _DBUS_ASSERT_ERROR_IS_SET (error);
1239  _dbus_close (listen_fd, NULL);
1240  return -1;
1241  }
1242 
1243  /* Try opening up the permissions, but if we can't, just go ahead
1244  * and continue, maybe it will be good enough.
1245  */
1246  if (!abstract && chmod (path, 0777) < 0)
1247  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1248  path);
1249 
1250  return listen_fd;
1251 }
1252 
1263 int
1265  DBusError *error)
1266 {
1267 #ifdef HAVE_SYSTEMD
1268  int r, n;
1269  int fd;
1270  DBusSocket *new_fds;
1271 
1272  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1273 
1274  n = sd_listen_fds (TRUE);
1275  if (n < 0)
1276  {
1278  "Failed to acquire systemd socket: %s",
1279  _dbus_strerror (-n));
1280  return -1;
1281  }
1282 
1283  if (n <= 0)
1284  {
1286  "No socket received.");
1287  return -1;
1288  }
1289 
1290  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1291  {
1292  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1293  if (r < 0)
1294  {
1296  "Failed to verify systemd socket type: %s",
1297  _dbus_strerror (-r));
1298  return -1;
1299  }
1300 
1301  if (!r)
1302  {
1304  "Passed socket has wrong type.");
1305  return -1;
1306  }
1307  }
1308 
1309  /* OK, the file descriptors are all good, so let's take posession of
1310  them then. */
1311 
1312  new_fds = dbus_new (DBusSocket, n);
1313  if (!new_fds)
1314  {
1316  "Failed to allocate file handle array.");
1317  goto fail;
1318  }
1319 
1320  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1321  {
1322  if (!_dbus_set_fd_nonblocking (fd, error))
1323  {
1324  _DBUS_ASSERT_ERROR_IS_SET (error);
1325  goto fail;
1326  }
1327 
1328  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1329  }
1330 
1331  *fds = new_fds;
1332  return n;
1333 
1334  fail:
1335 
1336  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1337  {
1338  _dbus_close (fd, NULL);
1339  }
1340 
1341  dbus_free (new_fds);
1342  return -1;
1343 #else
1345  "dbus was compiled without systemd support");
1346  return -1;
1347 #endif
1348 }
1349 
1363 DBusSocket
1364 _dbus_connect_tcp_socket (const char *host,
1365  const char *port,
1366  const char *family,
1367  DBusError *error)
1368 {
1369  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1370 }
1371 
1372 DBusSocket
1373 _dbus_connect_tcp_socket_with_nonce (const char *host,
1374  const char *port,
1375  const char *family,
1376  const char *noncefile,
1377  DBusError *error)
1378 {
1379  int saved_errno = 0;
1380  DBusSocket fd = DBUS_SOCKET_INIT;
1381  int res;
1382  struct addrinfo hints;
1383  struct addrinfo *ai, *tmp;
1384 
1385  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1386 
1387  _DBUS_ZERO (hints);
1388 
1389  if (!family)
1390  hints.ai_family = AF_UNSPEC;
1391  else if (!strcmp(family, "ipv4"))
1392  hints.ai_family = AF_INET;
1393  else if (!strcmp(family, "ipv6"))
1394  hints.ai_family = AF_INET6;
1395  else
1396  {
1397  dbus_set_error (error,
1399  "Unknown address family %s", family);
1400  return _dbus_socket_get_invalid ();
1401  }
1402  hints.ai_protocol = IPPROTO_TCP;
1403  hints.ai_socktype = SOCK_STREAM;
1404  hints.ai_flags = AI_ADDRCONFIG;
1405 
1406  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1407  {
1408  dbus_set_error (error,
1409  _dbus_error_from_errno (errno),
1410  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1411  host, port, gai_strerror(res), res);
1412  return _dbus_socket_get_invalid ();
1413  }
1414 
1415  tmp = ai;
1416  while (tmp)
1417  {
1418  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1419  {
1420  freeaddrinfo(ai);
1421  _DBUS_ASSERT_ERROR_IS_SET(error);
1422  return _dbus_socket_get_invalid ();
1423  }
1424  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1425 
1426  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1427  {
1428  saved_errno = errno;
1429  _dbus_close (fd.fd, NULL);
1430  fd.fd = -1;
1431  tmp = tmp->ai_next;
1432  continue;
1433  }
1434 
1435  break;
1436  }
1437  freeaddrinfo(ai);
1438 
1439  if (fd.fd == -1)
1440  {
1441  dbus_set_error (error,
1442  _dbus_error_from_errno (saved_errno),
1443  "Failed to connect to socket \"%s:%s\" %s",
1444  host, port, _dbus_strerror(saved_errno));
1445  return _dbus_socket_get_invalid ();
1446  }
1447 
1448  if (noncefile != NULL)
1449  {
1450  DBusString noncefileStr;
1451  dbus_bool_t ret;
1452  _dbus_string_init_const (&noncefileStr, noncefile);
1453  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1454  _dbus_string_free (&noncefileStr);
1455 
1456  if (!ret)
1457  {
1458  _dbus_close (fd.fd, NULL);
1459  return _dbus_socket_get_invalid ();
1460  }
1461  }
1462 
1463  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1464  {
1465  _dbus_close (fd.fd, NULL);
1466  return _dbus_socket_get_invalid ();
1467  }
1468 
1469  return fd;
1470 }
1471 
1488 int
1489 _dbus_listen_tcp_socket (const char *host,
1490  const char *port,
1491  const char *family,
1492  DBusString *retport,
1493  DBusSocket **fds_p,
1494  DBusError *error)
1495 {
1496  int saved_errno;
1497  int nlisten_fd = 0, res, i;
1498  DBusSocket *listen_fd = NULL;
1499  struct addrinfo hints;
1500  struct addrinfo *ai, *tmp;
1501  unsigned int reuseaddr;
1502 
1503  *fds_p = NULL;
1504  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1505 
1506  _DBUS_ZERO (hints);
1507 
1508  if (!family)
1509  hints.ai_family = AF_UNSPEC;
1510  else if (!strcmp(family, "ipv4"))
1511  hints.ai_family = AF_INET;
1512  else if (!strcmp(family, "ipv6"))
1513  hints.ai_family = AF_INET6;
1514  else
1515  {
1516  dbus_set_error (error,
1518  "Unknown address family %s", family);
1519  return -1;
1520  }
1521 
1522  hints.ai_protocol = IPPROTO_TCP;
1523  hints.ai_socktype = SOCK_STREAM;
1524  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1525 
1526  redo_lookup_with_port:
1527  ai = NULL;
1528  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1529  {
1530  dbus_set_error (error,
1531  _dbus_error_from_errno (errno),
1532  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1533  host ? host : "*", port, gai_strerror(res), res);
1534  goto failed;
1535  }
1536 
1537  tmp = ai;
1538  while (tmp)
1539  {
1540  int fd = -1, tcp_nodelay_on;
1541  DBusSocket *newlisten_fd;
1542 
1543  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1544  {
1545  _DBUS_ASSERT_ERROR_IS_SET(error);
1546  goto failed;
1547  }
1548  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1549 
1550  reuseaddr = 1;
1551  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1552  {
1553  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1554  host ? host : "*", port, _dbus_strerror (errno));
1555  }
1556 
1557  /* Nagle's algorithm imposes a huge delay on the initial messages
1558  going over TCP. */
1559  tcp_nodelay_on = 1;
1560  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1561  {
1562  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1563  host ? host : "*", port, _dbus_strerror (errno));
1564  }
1565 
1566  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1567  {
1568  saved_errno = errno;
1569  _dbus_close(fd, NULL);
1570  if (saved_errno == EADDRINUSE)
1571  {
1572  /* Depending on kernel policy, binding to an IPv6 address
1573  might implicitly bind to a corresponding IPv4
1574  address or vice versa, resulting in EADDRINUSE for the
1575  other one (e.g. bindv6only=0 on Linux).
1576 
1577  Also, after we "goto redo_lookup_with_port" after binding
1578  a port on one of the possible addresses, we will
1579  try to bind that same port on every address, including the
1580  same address again for a second time; that one will
1581  also fail with EADDRINUSE.
1582 
1583  For both those reasons, ignore EADDRINUSE here */
1584  tmp = tmp->ai_next;
1585  continue;
1586  }
1587  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1588  "Failed to bind socket \"%s:%s\": %s",
1589  host ? host : "*", port, _dbus_strerror (saved_errno));
1590  goto failed;
1591  }
1592 
1593  if (listen (fd, 30 /* backlog */) < 0)
1594  {
1595  saved_errno = errno;
1596  _dbus_close (fd, NULL);
1597  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1598  "Failed to listen on socket \"%s:%s\": %s",
1599  host ? host : "*", port, _dbus_strerror (saved_errno));
1600  goto failed;
1601  }
1602 
1603  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1604  if (!newlisten_fd)
1605  {
1606  saved_errno = errno;
1607  _dbus_close (fd, NULL);
1608  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1609  "Failed to allocate file handle array: %s",
1610  _dbus_strerror (saved_errno));
1611  goto failed;
1612  }
1613  listen_fd = newlisten_fd;
1614  listen_fd[nlisten_fd].fd = fd;
1615  nlisten_fd++;
1616 
1617  if (!_dbus_string_get_length(retport))
1618  {
1619  /* If the user didn't specify a port, or used 0, then
1620  the kernel chooses a port. After the first address
1621  is bound to, we need to force all remaining addresses
1622  to use the same port */
1623  if (!port || !strcmp(port, "0"))
1624  {
1625  int result;
1626  struct sockaddr_storage addr;
1627  socklen_t addrlen;
1628  char portbuf[50];
1629 
1630  addrlen = sizeof(addr);
1631  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1632 
1633  if (result == -1 ||
1634  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1635  portbuf, sizeof(portbuf),
1636  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1637  {
1638  dbus_set_error (error, _dbus_error_from_errno (errno),
1639  "Failed to resolve port \"%s:%s\": %s (%s)",
1640  host ? host : "*", port, gai_strerror(res), res);
1641  goto failed;
1642  }
1643  if (!_dbus_string_append(retport, portbuf))
1644  {
1646  goto failed;
1647  }
1648 
1649  /* Release current address list & redo lookup */
1650  port = _dbus_string_get_const_data(retport);
1651  freeaddrinfo(ai);
1652  goto redo_lookup_with_port;
1653  }
1654  else
1655  {
1656  if (!_dbus_string_append(retport, port))
1657  {
1659  goto failed;
1660  }
1661  }
1662  }
1663 
1664  tmp = tmp->ai_next;
1665  }
1666  freeaddrinfo(ai);
1667  ai = NULL;
1668 
1669  if (!nlisten_fd)
1670  {
1671  errno = EADDRINUSE;
1672  dbus_set_error (error, _dbus_error_from_errno (errno),
1673  "Failed to bind socket \"%s:%s\": %s",
1674  host ? host : "*", port, _dbus_strerror (errno));
1675  goto failed;
1676  }
1677 
1678  for (i = 0 ; i < nlisten_fd ; i++)
1679  {
1680  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1681  {
1682  goto failed;
1683  }
1684  }
1685 
1686  *fds_p = listen_fd;
1687 
1688  return nlisten_fd;
1689 
1690  failed:
1691  if (ai)
1692  freeaddrinfo(ai);
1693  for (i = 0 ; i < nlisten_fd ; i++)
1694  _dbus_close(listen_fd[i].fd, NULL);
1695  dbus_free(listen_fd);
1696  return -1;
1697 }
1698 
1699 static dbus_bool_t
1700 write_credentials_byte (int server_fd,
1701  DBusError *error)
1702 {
1703  int bytes_written;
1704  char buf[1] = { '\0' };
1705 #if defined(HAVE_CMSGCRED)
1706  union {
1707  struct cmsghdr hdr;
1708  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1709  } cmsg;
1710  struct iovec iov;
1711  struct msghdr msg;
1712  iov.iov_base = buf;
1713  iov.iov_len = 1;
1714 
1715  _DBUS_ZERO(msg);
1716  msg.msg_iov = &iov;
1717  msg.msg_iovlen = 1;
1718 
1719  msg.msg_control = (caddr_t) &cmsg;
1720  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1721  _DBUS_ZERO(cmsg);
1722  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1723  cmsg.hdr.cmsg_level = SOL_SOCKET;
1724  cmsg.hdr.cmsg_type = SCM_CREDS;
1725 #endif
1726 
1727  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1728 
1729  again:
1730 
1731 #if defined(HAVE_CMSGCRED)
1732  bytes_written = sendmsg (server_fd, &msg, 0
1733 #if HAVE_DECL_MSG_NOSIGNAL
1734  |MSG_NOSIGNAL
1735 #endif
1736  );
1737 
1738  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1739  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1740  * only allows that on AF_UNIX. Try just doing a send() instead. */
1741  if (bytes_written < 0 && errno == EINVAL)
1742 #endif
1743  {
1744  bytes_written = send (server_fd, buf, 1, 0
1745 #if HAVE_DECL_MSG_NOSIGNAL
1746  |MSG_NOSIGNAL
1747 #endif
1748  );
1749  }
1750 
1751  if (bytes_written < 0 && errno == EINTR)
1752  goto again;
1753 
1754  if (bytes_written < 0)
1755  {
1756  dbus_set_error (error, _dbus_error_from_errno (errno),
1757  "Failed to write credentials byte: %s",
1758  _dbus_strerror (errno));
1759  return FALSE;
1760  }
1761  else if (bytes_written == 0)
1762  {
1764  "wrote zero bytes writing credentials byte");
1765  return FALSE;
1766  }
1767  else
1768  {
1769  _dbus_assert (bytes_written == 1);
1770  _dbus_verbose ("wrote credentials byte\n");
1771  return TRUE;
1772  }
1773 }
1774 
1775 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1776 static dbus_bool_t
1777 add_linux_security_label_to_credentials (int client_fd,
1778  DBusCredentials *credentials)
1779 {
1780 #if defined(__linux__) && defined(SO_PEERSEC)
1781  DBusString buf;
1782  socklen_t len = 1024;
1783  dbus_bool_t oom = FALSE;
1784 
1785  if (!_dbus_string_init_preallocated (&buf, len) ||
1786  !_dbus_string_set_length (&buf, len))
1787  return FALSE;
1788 
1789  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1790  _dbus_string_get_data (&buf), &len) < 0)
1791  {
1792  int e = errno;
1793 
1794  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1795  _dbus_strerror (e), (unsigned long) len);
1796 
1797  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1798  {
1799  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1800  _dbus_strerror (e));
1801  goto out;
1802  }
1803 
1804  /* If not enough space, len is updated to be enough.
1805  * Try again with a large enough buffer. */
1806  if (!_dbus_string_set_length (&buf, len))
1807  {
1808  oom = TRUE;
1809  goto out;
1810  }
1811 
1812  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1813  }
1814 
1815  if (len <= 0)
1816  {
1817  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1818  (unsigned long) len);
1819  goto out;
1820  }
1821 
1822  if (len > _dbus_string_get_length_uint (&buf))
1823  {
1824  _dbus_verbose ("%lu > %u", (unsigned long) len,
1825  _dbus_string_get_length_uint (&buf));
1826  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1827  }
1828 
1829  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1830  {
1831  /* the kernel included the trailing \0 in its count,
1832  * but DBusString always has an extra \0 after the data anyway */
1833  _dbus_verbose ("subtracting trailing \\0\n");
1834  len--;
1835  }
1836 
1837  if (!_dbus_string_set_length (&buf, len))
1838  {
1839  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1840  oom = TRUE;
1841  goto out;
1842  }
1843 
1844  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1845  {
1846  /* LSM people on the linux-security-module@ mailing list say this
1847  * should never happen: the label should be a bytestring with
1848  * an optional trailing \0 */
1849  _dbus_verbose ("security label from kernel had an embedded \\0, "
1850  "ignoring it\n");
1851  goto out;
1852  }
1853 
1854  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1855  (unsigned long) len,
1856  _dbus_string_get_const_data (&buf));
1857 
1859  _dbus_string_get_const_data (&buf)))
1860  {
1861  oom = TRUE;
1862  goto out;
1863  }
1864 
1865 out:
1866  _dbus_string_free (&buf);
1867  return !oom;
1868 #else
1869  /* no error */
1870  return TRUE;
1871 #endif
1872 }
1873 
1916  DBusCredentials *credentials,
1917  DBusError *error)
1918 {
1919  struct msghdr msg;
1920  struct iovec iov;
1921  char buf;
1922  dbus_uid_t uid_read;
1923  dbus_pid_t pid_read;
1924  int bytes_read;
1925 
1926 #ifdef HAVE_CMSGCRED
1927  union {
1928  struct cmsghdr hdr;
1929  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1930  } cmsg;
1931 #endif
1932 
1933  /* The POSIX spec certainly doesn't promise this, but
1934  * we need these assertions to fail as soon as we're wrong about
1935  * it so we can do the porting fixups
1936  */
1937  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1938  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1939  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1940 
1941  uid_read = DBUS_UID_UNSET;
1942  pid_read = DBUS_PID_UNSET;
1943 
1944  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1945 
1946  _dbus_credentials_clear (credentials);
1947 
1948  iov.iov_base = &buf;
1949  iov.iov_len = 1;
1950 
1951  _DBUS_ZERO(msg);
1952  msg.msg_iov = &iov;
1953  msg.msg_iovlen = 1;
1954 
1955 #if defined(HAVE_CMSGCRED)
1956  _DBUS_ZERO(cmsg);
1957  msg.msg_control = (caddr_t) &cmsg;
1958  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1959 #endif
1960 
1961  again:
1962  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1963 
1964  if (bytes_read < 0)
1965  {
1966  if (errno == EINTR)
1967  goto again;
1968 
1969  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1970  * normally only call read_credentials if the socket was ready
1971  * for reading
1972  */
1973 
1974  dbus_set_error (error, _dbus_error_from_errno (errno),
1975  "Failed to read credentials byte: %s",
1976  _dbus_strerror (errno));
1977  return FALSE;
1978  }
1979  else if (bytes_read == 0)
1980  {
1981  /* this should not happen unless we are using recvmsg wrong,
1982  * so is essentially here for paranoia
1983  */
1985  "Failed to read credentials byte (zero-length read)");
1986  return FALSE;
1987  }
1988  else if (buf != '\0')
1989  {
1991  "Credentials byte was not nul");
1992  return FALSE;
1993  }
1994 
1995  _dbus_verbose ("read credentials byte\n");
1996 
1997  {
1998 #ifdef SO_PEERCRED
1999  /* Supported by at least Linux and OpenBSD, with minor differences.
2000  *
2001  * This mechanism passes the process ID through and does not require
2002  * the peer's cooperation, so we prefer it over all others. Notably,
2003  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2004  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2005  * because this is much less fragile.
2006  */
2007 #ifdef __OpenBSD__
2008  struct sockpeercred cr;
2009 #else
2010  struct ucred cr;
2011 #endif
2012  int cr_len = sizeof (cr);
2013 
2014  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2015  {
2016  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2017  _dbus_strerror (errno));
2018  }
2019  else if (cr_len != sizeof (cr))
2020  {
2021  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2022  cr_len, (int) sizeof (cr));
2023  }
2024  else
2025  {
2026  pid_read = cr.pid;
2027  uid_read = cr.uid;
2028  }
2029 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2030  /* Another variant of the above - used on NetBSD
2031  */
2032  struct unpcbid cr;
2033  socklen_t cr_len = sizeof (cr);
2034 
2035  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2036  {
2037  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2038  _dbus_strerror (errno));
2039  }
2040  else if (cr_len != sizeof (cr))
2041  {
2042  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2043  cr_len, (int) sizeof (cr));
2044  }
2045  else
2046  {
2047  pid_read = cr.unp_pid;
2048  uid_read = cr.unp_euid;
2049  }
2050 #elif defined(HAVE_CMSGCRED)
2051  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2052  * presence of that struct implies SCM_CREDS. Supported by at least
2053  * FreeBSD and DragonflyBSD.
2054  *
2055  * This mechanism requires the peer to help us (it has to send us a
2056  * SCM_CREDS message) but it does pass the process ID through,
2057  * which makes it better than getpeereid().
2058  */
2059  struct cmsgcred *cred;
2060  struct cmsghdr *cmsgp;
2061 
2062  for (cmsgp = CMSG_FIRSTHDR (&msg);
2063  cmsgp != NULL;
2064  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2065  {
2066  if (cmsgp->cmsg_type == SCM_CREDS &&
2067  cmsgp->cmsg_level == SOL_SOCKET &&
2068  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2069  {
2070  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2071  pid_read = cred->cmcred_pid;
2072  uid_read = cred->cmcred_euid;
2073  break;
2074  }
2075  }
2076 
2077 #elif defined(HAVE_GETPEERUCRED)
2078  /* Supported in at least Solaris >= 10. It should probably be higher
2079  * up this list, because it carries the pid and we use this code path
2080  * for audit data. */
2081  ucred_t * ucred = NULL;
2082  if (getpeerucred (client_fd.fd, &ucred) == 0)
2083  {
2084 #ifdef HAVE_ADT
2085  adt_session_data_t *adth = NULL;
2086 #endif
2087  pid_read = ucred_getpid (ucred);
2088  uid_read = ucred_geteuid (ucred);
2089 #ifdef HAVE_ADT
2090  /* generate audit session data based on socket ucred */
2091  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2092  {
2093  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2094  }
2095  else
2096  {
2097  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2098  {
2099  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2100  }
2101  else
2102  {
2103  adt_export_data_t *data = NULL;
2104  size_t size = adt_export_session_data (adth, &data);
2105  if (size <= 0)
2106  {
2107  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2108  }
2109  else
2110  {
2111  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2112  free (data);
2113  }
2114  }
2115  (void) adt_end_session (adth);
2116  }
2117 #endif /* HAVE_ADT */
2118  }
2119  else
2120  {
2121  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2122  }
2123  if (ucred != NULL)
2124  ucred_free (ucred);
2125 
2126  /* ----------------------------------------------------------------
2127  * When adding new mechanisms, please add them above this point
2128  * if they support passing the process ID through, or below if not.
2129  * ---------------------------------------------------------------- */
2130 
2131 #elif defined(HAVE_GETPEEREID)
2132  /* getpeereid() originates from D.J. Bernstein and is fairly
2133  * widely-supported. According to a web search, it might be present in
2134  * any/all of:
2135  *
2136  * - AIX?
2137  * - Blackberry?
2138  * - Cygwin
2139  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2140  * - Mac OS X
2141  * - Minix 3.1.8+
2142  * - MirBSD?
2143  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2144  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2145  * - QNX?
2146  */
2147  uid_t euid;
2148  gid_t egid;
2149  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2150  {
2151  uid_read = euid;
2152  }
2153  else
2154  {
2155  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2156  }
2157 #else /* no supported mechanism */
2158 
2159 #warning Socket credentials not supported on this Unix OS
2160 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2161 
2162  /* Please add other operating systems known to support at least one of
2163  * the mechanisms above to this list, keeping alphabetical order.
2164  * Everything not in this list is best-effort.
2165  */
2166 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2167  defined(__linux__) || \
2168  defined(__OpenBSD__) || \
2169  defined(__NetBSD__)
2170 # error Credentials passing not working on this OS is a regression!
2171 #endif
2172 
2173  _dbus_verbose ("Socket credentials not supported on this OS\n");
2174 #endif
2175  }
2176 
2177  _dbus_verbose ("Credentials:"
2178  " pid "DBUS_PID_FORMAT
2179  " uid "DBUS_UID_FORMAT
2180  "\n",
2181  pid_read,
2182  uid_read);
2183 
2184  if (pid_read != DBUS_PID_UNSET)
2185  {
2186  if (!_dbus_credentials_add_pid (credentials, pid_read))
2187  {
2188  _DBUS_SET_OOM (error);
2189  return FALSE;
2190  }
2191  }
2192 
2193  if (uid_read != DBUS_UID_UNSET)
2194  {
2195  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2196  {
2197  _DBUS_SET_OOM (error);
2198  return FALSE;
2199  }
2200  }
2201 
2202  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2203  {
2204  _DBUS_SET_OOM (error);
2205  return FALSE;
2206  }
2207 
2208  return TRUE;
2209 }
2210 
2230  DBusError *error)
2231 {
2232  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2233 
2234  if (write_credentials_byte (server_fd.fd, error))
2235  return TRUE;
2236  else
2237  return FALSE;
2238 }
2239 
2249 DBusSocket
2251 {
2252  DBusSocket client_fd;
2253  struct sockaddr addr;
2254  socklen_t addrlen;
2255 #ifdef HAVE_ACCEPT4
2256  dbus_bool_t cloexec_done;
2257 #endif
2258 
2259  addrlen = sizeof (addr);
2260 
2261  retry:
2262 
2263 #ifdef HAVE_ACCEPT4
2264  /*
2265  * At compile-time, we assume that if accept4() is available in
2266  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2267  * not necessarily true that either is supported by the running kernel.
2268  */
2269  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2270  cloexec_done = client_fd.fd >= 0;
2271 
2272  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2273 #endif
2274  {
2275  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2276  }
2277 
2278  if (client_fd.fd < 0)
2279  {
2280  if (errno == EINTR)
2281  goto retry;
2282  }
2283 
2284  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2285 
2286 #ifdef HAVE_ACCEPT4
2287  if (!cloexec_done)
2288 #endif
2289  {
2290  _dbus_fd_set_close_on_exec(client_fd.fd);
2291  }
2292 
2293  return client_fd;
2294 }
2295 
2306 {
2307  const char *directory;
2308  struct stat sb;
2309 
2310  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2311 
2312  directory = _dbus_string_get_const_data (dir);
2313 
2314  if (stat (directory, &sb) < 0)
2315  {
2316  dbus_set_error (error, _dbus_error_from_errno (errno),
2317  "%s", _dbus_strerror (errno));
2318 
2319  return FALSE;
2320  }
2321 
2322  if (sb.st_uid != geteuid ())
2323  {
2325  "%s directory is owned by user %lu, not %lu",
2326  directory,
2327  (unsigned long) sb.st_uid,
2328  (unsigned long) geteuid ());
2329  return FALSE;
2330  }
2331 
2332  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2333  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2334  {
2336  "%s directory is not private to the user", directory);
2337  return FALSE;
2338  }
2339 
2340  return TRUE;
2341 }
2342 
2343 static dbus_bool_t
2344 fill_user_info_from_passwd (struct passwd *p,
2345  DBusUserInfo *info,
2346  DBusError *error)
2347 {
2348  _dbus_assert (p->pw_name != NULL);
2349  _dbus_assert (p->pw_dir != NULL);
2350 
2351  info->uid = p->pw_uid;
2352  info->primary_gid = p->pw_gid;
2353  info->username = _dbus_strdup (p->pw_name);
2354  info->homedir = _dbus_strdup (p->pw_dir);
2355 
2356  if (info->username == NULL ||
2357  info->homedir == NULL)
2358  {
2360  return FALSE;
2361  }
2362 
2363  return TRUE;
2364 }
2365 
2366 static dbus_bool_t
2367 fill_user_info (DBusUserInfo *info,
2368  dbus_uid_t uid,
2369  const DBusString *username,
2370  DBusError *error)
2371 {
2372  const char *username_c;
2373 
2374  /* exactly one of username/uid provided */
2375  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2376  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2377 
2378  info->uid = DBUS_UID_UNSET;
2379  info->primary_gid = DBUS_GID_UNSET;
2380  info->group_ids = NULL;
2381  info->n_group_ids = 0;
2382  info->username = NULL;
2383  info->homedir = NULL;
2384 
2385  if (username != NULL)
2386  username_c = _dbus_string_get_const_data (username);
2387  else
2388  username_c = NULL;
2389 
2390  /* For now assuming that the getpwnam() and getpwuid() flavors
2391  * are always symmetrical, if not we have to add more configure
2392  * checks
2393  */
2394 
2395 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2396  {
2397  struct passwd *p;
2398  int result;
2399  size_t buflen;
2400  char *buf;
2401  struct passwd p_str;
2402 
2403  /* retrieve maximum needed size for buf */
2404  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2405 
2406  /* sysconf actually returns a long, but everything else expects size_t,
2407  * so just recast here.
2408  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2409  */
2410  if ((long) buflen <= 0)
2411  buflen = 1024;
2412 
2413  result = -1;
2414  while (1)
2415  {
2416  buf = dbus_malloc (buflen);
2417  if (buf == NULL)
2418  {
2420  return FALSE;
2421  }
2422 
2423  p = NULL;
2424 #ifdef HAVE_POSIX_GETPWNAM_R
2425  if (uid != DBUS_UID_UNSET)
2426  result = getpwuid_r (uid, &p_str, buf, buflen,
2427  &p);
2428  else
2429  result = getpwnam_r (username_c, &p_str, buf, buflen,
2430  &p);
2431 #else
2432  if (uid != DBUS_UID_UNSET)
2433  p = getpwuid_r (uid, &p_str, buf, buflen);
2434  else
2435  p = getpwnam_r (username_c, &p_str, buf, buflen);
2436  result = 0;
2437 #endif /* !HAVE_POSIX_GETPWNAM_R */
2438  //Try a bigger buffer if ERANGE was returned
2439  if (result == ERANGE && buflen < 512 * 1024)
2440  {
2441  dbus_free (buf);
2442  buflen *= 2;
2443  }
2444  else
2445  {
2446  break;
2447  }
2448  }
2449  if (result == 0 && p == &p_str)
2450  {
2451  if (!fill_user_info_from_passwd (p, info, error))
2452  {
2453  dbus_free (buf);
2454  return FALSE;
2455  }
2456  dbus_free (buf);
2457  }
2458  else
2459  {
2460  dbus_set_error (error, _dbus_error_from_errno (errno),
2461  "User \"%s\" unknown or no memory to allocate password entry\n",
2462  username_c ? username_c : "???");
2463  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2464  dbus_free (buf);
2465  return FALSE;
2466  }
2467  }
2468 #else /* ! HAVE_GETPWNAM_R */
2469  {
2470  /* I guess we're screwed on thread safety here */
2471  struct passwd *p;
2472 
2473  if (uid != DBUS_UID_UNSET)
2474  p = getpwuid (uid);
2475  else
2476  p = getpwnam (username_c);
2477 
2478  if (p != NULL)
2479  {
2480  if (!fill_user_info_from_passwd (p, info, error))
2481  {
2482  return FALSE;
2483  }
2484  }
2485  else
2486  {
2487  dbus_set_error (error, _dbus_error_from_errno (errno),
2488  "User \"%s\" unknown or no memory to allocate password entry\n",
2489  username_c ? username_c : "???");
2490  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2491  return FALSE;
2492  }
2493  }
2494 #endif /* ! HAVE_GETPWNAM_R */
2495 
2496  /* Fill this in so we can use it to get groups */
2497  username_c = info->username;
2498 
2499 #ifdef HAVE_GETGROUPLIST
2500  {
2501  gid_t *buf;
2502  int buf_count;
2503  int i;
2504  int initial_buf_count;
2505 
2506  initial_buf_count = 17;
2507  buf_count = initial_buf_count;
2508  buf = dbus_new (gid_t, buf_count);
2509  if (buf == NULL)
2510  {
2512  goto failed;
2513  }
2514 
2515  if (getgrouplist (username_c,
2516  info->primary_gid,
2517  buf, &buf_count) < 0)
2518  {
2519  gid_t *new;
2520  /* Presumed cause of negative return code: buf has insufficient
2521  entries to hold the entire group list. The Linux behavior in this
2522  case is to pass back the actual number of groups in buf_count, but
2523  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2524  So as a hack, try to help out a bit by guessing a larger
2525  number of groups, within reason.. might still fail, of course,
2526  but we can at least print a more informative message. I looked up
2527  the "right way" to do this by downloading Apple's own source code
2528  for the "id" command, and it turns out that they use an
2529  undocumented library function getgrouplist_2 (!) which is not
2530  declared in any header in /usr/include (!!). That did not seem
2531  like the way to go here.
2532  */
2533  if (buf_count == initial_buf_count)
2534  {
2535  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2536  }
2537  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2538  if (new == NULL)
2539  {
2541  dbus_free (buf);
2542  goto failed;
2543  }
2544 
2545  buf = new;
2546 
2547  errno = 0;
2548  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2549  {
2550  if (errno == 0)
2551  {
2552  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2553  username_c, buf_count, buf_count);
2554  }
2555  else
2556  {
2557  dbus_set_error (error,
2558  _dbus_error_from_errno (errno),
2559  "Failed to get groups for username \"%s\" primary GID "
2560  DBUS_GID_FORMAT ": %s\n",
2561  username_c, info->primary_gid,
2562  _dbus_strerror (errno));
2563  dbus_free (buf);
2564  goto failed;
2565  }
2566  }
2567  }
2568 
2569  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2570  if (info->group_ids == NULL)
2571  {
2573  dbus_free (buf);
2574  goto failed;
2575  }
2576 
2577  for (i = 0; i < buf_count; ++i)
2578  info->group_ids[i] = buf[i];
2579 
2580  info->n_group_ids = buf_count;
2581 
2582  dbus_free (buf);
2583  }
2584 #else /* HAVE_GETGROUPLIST */
2585  {
2586  /* We just get the one group ID */
2587  info->group_ids = dbus_new (dbus_gid_t, 1);
2588  if (info->group_ids == NULL)
2589  {
2591  goto failed;
2592  }
2593 
2594  info->n_group_ids = 1;
2595 
2596  (info->group_ids)[0] = info->primary_gid;
2597  }
2598 #endif /* HAVE_GETGROUPLIST */
2599 
2600  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2601 
2602  return TRUE;
2603 
2604  failed:
2605  _DBUS_ASSERT_ERROR_IS_SET (error);
2606  return FALSE;
2607 }
2608 
2619  const DBusString *username,
2620  DBusError *error)
2621 {
2622  return fill_user_info (info, DBUS_UID_UNSET,
2623  username, error);
2624 }
2625 
2636  dbus_uid_t uid,
2637  DBusError *error)
2638 {
2639  return fill_user_info (info, uid,
2640  NULL, error);
2641 }
2642 
2652 {
2653  /* The POSIX spec certainly doesn't promise this, but
2654  * we need these assertions to fail as soon as we're wrong about
2655  * it so we can do the porting fixups
2656  */
2657  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2658  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2659  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2660 
2661  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2662  return FALSE;
2663  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2664  return FALSE;
2665 
2666  return TRUE;
2667 }
2668 
2682 {
2683  return _dbus_string_append_uint (str,
2684  _dbus_geteuid ());
2685 }
2686 
2691 dbus_pid_t
2693 {
2694  return getpid ();
2695 }
2696 
2700 dbus_uid_t
2702 {
2703  return getuid ();
2704 }
2705 
2709 dbus_uid_t
2711 {
2712  return geteuid ();
2713 }
2714 
2721 unsigned long
2723 {
2724  return getpid ();
2725 }
2726 
2735 _dbus_parse_uid (const DBusString *uid_str,
2736  dbus_uid_t *uid)
2737 {
2738  int end;
2739  long val;
2740 
2741  if (_dbus_string_get_length (uid_str) == 0)
2742  {
2743  _dbus_verbose ("UID string was zero length\n");
2744  return FALSE;
2745  }
2746 
2747  val = -1;
2748  end = 0;
2749  if (!_dbus_string_parse_int (uid_str, 0, &val,
2750  &end))
2751  {
2752  _dbus_verbose ("could not parse string as a UID\n");
2753  return FALSE;
2754  }
2755 
2756  if (end != _dbus_string_get_length (uid_str))
2757  {
2758  _dbus_verbose ("string contained trailing stuff after UID\n");
2759  return FALSE;
2760  }
2761 
2762  *uid = val;
2763 
2764  return TRUE;
2765 }
2766 
2767 #if !DBUS_USE_SYNC
2768 /* To be thread-safe by default on platforms that don't necessarily have
2769  * atomic operations (notably Debian armel, which is armv4t), we must
2770  * use a mutex that can be initialized statically, like this.
2771  * GLib >= 2.32 uses a similar system.
2772  */
2773 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2774 #endif
2775 
2782 dbus_int32_t
2784 {
2785 #if DBUS_USE_SYNC
2786  return __sync_add_and_fetch(&atomic->value, 1)-1;
2787 #else
2788  dbus_int32_t res;
2789 
2790  pthread_mutex_lock (&atomic_mutex);
2791  res = atomic->value;
2792  atomic->value += 1;
2793  pthread_mutex_unlock (&atomic_mutex);
2794 
2795  return res;
2796 #endif
2797 }
2798 
2805 dbus_int32_t
2807 {
2808 #if DBUS_USE_SYNC
2809  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2810 #else
2811  dbus_int32_t res;
2812 
2813  pthread_mutex_lock (&atomic_mutex);
2814  res = atomic->value;
2815  atomic->value -= 1;
2816  pthread_mutex_unlock (&atomic_mutex);
2817 
2818  return res;
2819 #endif
2820 }
2821 
2829 dbus_int32_t
2831 {
2832 #if DBUS_USE_SYNC
2833  __sync_synchronize ();
2834  return atomic->value;
2835 #else
2836  dbus_int32_t res;
2837 
2838  pthread_mutex_lock (&atomic_mutex);
2839  res = atomic->value;
2840  pthread_mutex_unlock (&atomic_mutex);
2841 
2842  return res;
2843 #endif
2844 }
2845 
2854 int
2856  int n_fds,
2857  int timeout_milliseconds)
2858 {
2859 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2860  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2861  if (timeout_milliseconds < -1)
2862  {
2863  timeout_milliseconds = -1;
2864  }
2865 
2866  return poll (fds,
2867  n_fds,
2868  timeout_milliseconds);
2869 #else /* ! HAVE_POLL */
2870  /* Emulate poll() in terms of select() */
2871  fd_set read_set, write_set, err_set;
2872  int max_fd = 0;
2873  int i;
2874  struct timeval tv;
2875  int ready;
2876 
2877  FD_ZERO (&read_set);
2878  FD_ZERO (&write_set);
2879  FD_ZERO (&err_set);
2880 
2881  for (i = 0; i < n_fds; i++)
2882  {
2883  DBusPollFD *fdp = &fds[i];
2884 
2885  if (fdp->events & _DBUS_POLLIN)
2886  FD_SET (fdp->fd, &read_set);
2887 
2888  if (fdp->events & _DBUS_POLLOUT)
2889  FD_SET (fdp->fd, &write_set);
2890 
2891  FD_SET (fdp->fd, &err_set);
2892 
2893  max_fd = MAX (max_fd, fdp->fd);
2894  }
2895 
2896  tv.tv_sec = timeout_milliseconds / 1000;
2897  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2898 
2899  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2900  timeout_milliseconds < 0 ? NULL : &tv);
2901 
2902  if (ready > 0)
2903  {
2904  for (i = 0; i < n_fds; i++)
2905  {
2906  DBusPollFD *fdp = &fds[i];
2907 
2908  fdp->revents = 0;
2909 
2910  if (FD_ISSET (fdp->fd, &read_set))
2911  fdp->revents |= _DBUS_POLLIN;
2912 
2913  if (FD_ISSET (fdp->fd, &write_set))
2914  fdp->revents |= _DBUS_POLLOUT;
2915 
2916  if (FD_ISSET (fdp->fd, &err_set))
2917  fdp->revents |= _DBUS_POLLERR;
2918  }
2919  }
2920 
2921  return ready;
2922 #endif
2923 }
2924 
2932 void
2934  long *tv_usec)
2935 {
2936 #ifdef HAVE_MONOTONIC_CLOCK
2937  struct timespec ts;
2938  clock_gettime (CLOCK_MONOTONIC, &ts);
2939 
2940  if (tv_sec)
2941  *tv_sec = ts.tv_sec;
2942  if (tv_usec)
2943  *tv_usec = ts.tv_nsec / 1000;
2944 #else
2945  struct timeval t;
2946 
2947  gettimeofday (&t, NULL);
2948 
2949  if (tv_sec)
2950  *tv_sec = t.tv_sec;
2951  if (tv_usec)
2952  *tv_usec = t.tv_usec;
2953 #endif
2954 }
2955 
2963 void
2964 _dbus_get_real_time (long *tv_sec,
2965  long *tv_usec)
2966 {
2967  struct timeval t;
2968 
2969  gettimeofday (&t, NULL);
2970 
2971  if (tv_sec)
2972  *tv_sec = t.tv_sec;
2973  if (tv_usec)
2974  *tv_usec = t.tv_usec;
2975 }
2976 
2987  DBusError *error)
2988 {
2989  const char *filename_c;
2990 
2991  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2992 
2993  filename_c = _dbus_string_get_const_data (filename);
2994 
2995  if (mkdir (filename_c, 0700) < 0)
2996  {
2997  if (errno == EEXIST)
2998  return TRUE;
2999 
3001  "Failed to create directory %s: %s\n",
3002  filename_c, _dbus_strerror (errno));
3003  return FALSE;
3004  }
3005  else
3006  return TRUE;
3007 }
3008 
3019  DBusError *error)
3020 {
3021  const char *filename_c;
3022 
3023  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3024 
3025  filename_c = _dbus_string_get_const_data (filename);
3026 
3027  if (mkdir (filename_c, 0700) < 0)
3028  {
3030  "Failed to create directory %s: %s\n",
3031  filename_c, _dbus_strerror (errno));
3032  return FALSE;
3033  }
3034  else
3035  return TRUE;
3036 }
3037 
3050  const DBusString *next_component)
3051 {
3052  dbus_bool_t dir_ends_in_slash;
3053  dbus_bool_t file_starts_with_slash;
3054 
3055  if (_dbus_string_get_length (dir) == 0 ||
3056  _dbus_string_get_length (next_component) == 0)
3057  return TRUE;
3058 
3059  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3060  _dbus_string_get_length (dir) - 1);
3061 
3062  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3063 
3064  if (dir_ends_in_slash && file_starts_with_slash)
3065  {
3066  _dbus_string_shorten (dir, 1);
3067  }
3068  else if (!(dir_ends_in_slash || file_starts_with_slash))
3069  {
3070  if (!_dbus_string_append_byte (dir, '/'))
3071  return FALSE;
3072  }
3073 
3074  return _dbus_string_copy (next_component, 0, dir,
3075  _dbus_string_get_length (dir));
3076 }
3077 
3079 #define NANOSECONDS_PER_SECOND 1000000000
3080 
3081 #define MICROSECONDS_PER_SECOND 1000000
3082 
3083 #define MILLISECONDS_PER_SECOND 1000
3084 
3085 #define NANOSECONDS_PER_MILLISECOND 1000000
3086 
3087 #define MICROSECONDS_PER_MILLISECOND 1000
3088 
3093 void
3094 _dbus_sleep_milliseconds (int milliseconds)
3095 {
3096 #ifdef HAVE_NANOSLEEP
3097  struct timespec req;
3098  struct timespec rem;
3099 
3100  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3101  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3102  rem.tv_sec = 0;
3103  rem.tv_nsec = 0;
3104 
3105  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3106  req = rem;
3107 #elif defined (HAVE_USLEEP)
3108  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3109 #else /* ! HAVE_USLEEP */
3110  sleep (MAX (milliseconds / 1000, 1));
3111 #endif
3112 }
3113 
3125  int n_bytes,
3126  DBusError *error)
3127 {
3128  int old_len;
3129  int fd;
3130  int result;
3131 
3132  old_len = _dbus_string_get_length (str);
3133  fd = -1;
3134 
3135  /* note, urandom on linux will fall back to pseudorandom */
3136  fd = open ("/dev/urandom", O_RDONLY);
3137 
3138  if (fd < 0)
3139  {
3140  dbus_set_error (error, _dbus_error_from_errno (errno),
3141  "Could not open /dev/urandom: %s",
3142  _dbus_strerror (errno));
3143  return FALSE;
3144  }
3145 
3146  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3147 
3148  result = _dbus_read (fd, str, n_bytes);
3149 
3150  if (result != n_bytes)
3151  {
3152  if (result < 0)
3153  dbus_set_error (error, _dbus_error_from_errno (errno),
3154  "Could not read /dev/urandom: %s",
3155  _dbus_strerror (errno));
3156  else
3158  "Short read from /dev/urandom");
3159 
3160  _dbus_close (fd, NULL);
3161  _dbus_string_set_length (str, old_len);
3162  return FALSE;
3163  }
3164 
3165  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3166  n_bytes);
3167 
3168  _dbus_close (fd, NULL);
3169 
3170  return TRUE;
3171 }
3172 
3178 void
3179 _dbus_exit (int code)
3180 {
3181  _exit (code);
3182 }
3183 
3192 const char*
3193 _dbus_strerror (int error_number)
3194 {
3195  const char *msg;
3196 
3197  msg = strerror (error_number);
3198  if (msg == NULL)
3199  msg = "unknown";
3200 
3201  return msg;
3202 }
3203 
3207 void
3209 {
3210  signal (SIGPIPE, SIG_IGN);
3211 }
3212 
3220 void
3222 {
3223  int val;
3224 
3225  val = fcntl (fd, F_GETFD, 0);
3226 
3227  if (val < 0)
3228  return;
3229 
3230  val |= FD_CLOEXEC;
3231 
3232  fcntl (fd, F_SETFD, val);
3233 }
3234 
3243 _dbus_close (int fd,
3244  DBusError *error)
3245 {
3246  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3247 
3248  again:
3249  if (close (fd) < 0)
3250  {
3251  if (errno == EINTR)
3252  goto again;
3253 
3254  dbus_set_error (error, _dbus_error_from_errno (errno),
3255  "Could not close fd %d", fd);
3256  return FALSE;
3257  }
3258 
3259  return TRUE;
3260 }
3261 
3270 int
3271 _dbus_dup(int fd,
3272  DBusError *error)
3273 {
3274  int new_fd;
3275 
3276 #ifdef F_DUPFD_CLOEXEC
3277  dbus_bool_t cloexec_done;
3278 
3279  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3280  cloexec_done = new_fd >= 0;
3281 
3282  if (new_fd < 0 && errno == EINVAL)
3283 #endif
3284  {
3285  new_fd = fcntl(fd, F_DUPFD, 3);
3286  }
3287 
3288  if (new_fd < 0) {
3289 
3290  dbus_set_error (error, _dbus_error_from_errno (errno),
3291  "Could not duplicate fd %d", fd);
3292  return -1;
3293  }
3294 
3295 #ifdef F_DUPFD_CLOEXEC
3296  if (!cloexec_done)
3297 #endif
3298  {
3300  }
3301 
3302  return new_fd;
3303 }
3304 
3314  DBusError *error)
3315 {
3316  return _dbus_set_fd_nonblocking (fd.fd, error);
3317 }
3318 
3319 static dbus_bool_t
3320 _dbus_set_fd_nonblocking (int fd,
3321  DBusError *error)
3322 {
3323  int val;
3324 
3325  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3326 
3327  val = fcntl (fd, F_GETFL, 0);
3328  if (val < 0)
3329  {
3330  dbus_set_error (error, _dbus_error_from_errno (errno),
3331  "Failed to get flags from file descriptor %d: %s",
3332  fd, _dbus_strerror (errno));
3333  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3334  _dbus_strerror (errno));
3335  return FALSE;
3336  }
3337 
3338  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3339  {
3340  dbus_set_error (error, _dbus_error_from_errno (errno),
3341  "Failed to set nonblocking flag of file descriptor %d: %s",
3342  fd, _dbus_strerror (errno));
3343  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3344  fd, _dbus_strerror (errno));
3345 
3346  return FALSE;
3347  }
3348 
3349  return TRUE;
3350 }
3351 
3357 void
3359 {
3360 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3361  void *bt[500];
3362  int bt_size;
3363  int i;
3364  char **syms;
3365 
3366  bt_size = backtrace (bt, 500);
3367 
3368  syms = backtrace_symbols (bt, bt_size);
3369 
3370  i = 0;
3371  while (i < bt_size)
3372  {
3373  /* don't use dbus_warn since it can _dbus_abort() */
3374  fprintf (stderr, " %s\n", syms[i]);
3375  ++i;
3376  }
3377  fflush (stderr);
3378 
3379  free (syms);
3380 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3381  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3382 #else
3383  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3384 #endif
3385 }
3386 
3401  DBusSocket *fd2,
3402  dbus_bool_t blocking,
3403  DBusError *error)
3404 {
3405 #ifdef HAVE_SOCKETPAIR
3406  int fds[2];
3407  int retval;
3408 
3409 #ifdef SOCK_CLOEXEC
3410  dbus_bool_t cloexec_done;
3411 
3412  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3413  cloexec_done = retval >= 0;
3414 
3415  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3416 #endif
3417  {
3418  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3419  }
3420 
3421  if (retval < 0)
3422  {
3423  dbus_set_error (error, _dbus_error_from_errno (errno),
3424  "Could not create full-duplex pipe");
3425  return FALSE;
3426  }
3427 
3428  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3429 
3430 #ifdef SOCK_CLOEXEC
3431  if (!cloexec_done)
3432 #endif
3433  {
3434  _dbus_fd_set_close_on_exec (fds[0]);
3435  _dbus_fd_set_close_on_exec (fds[1]);
3436  }
3437 
3438  if (!blocking &&
3439  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3440  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3441  {
3442  dbus_set_error (error, _dbus_error_from_errno (errno),
3443  "Could not set full-duplex pipe nonblocking");
3444 
3445  _dbus_close (fds[0], NULL);
3446  _dbus_close (fds[1], NULL);
3447 
3448  return FALSE;
3449  }
3450 
3451  fd1->fd = fds[0];
3452  fd2->fd = fds[1];
3453 
3454  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3455  fd1->fd, fd2->fd);
3456 
3457  return TRUE;
3458 #else
3459  _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
3461  "_dbus_socketpair() not implemented on this OS");
3462  return FALSE;
3463 #endif
3464 }
3465 
3474 int
3476  va_list args)
3477 {
3478  char static_buf[1024];
3479  int bufsize = sizeof (static_buf);
3480  int len;
3481  va_list args_copy;
3482 
3483  DBUS_VA_COPY (args_copy, args);
3484  len = vsnprintf (static_buf, bufsize, format, args_copy);
3485  va_end (args_copy);
3486 
3487  /* If vsnprintf() returned non-negative, then either the string fits in
3488  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3489  * returns the number of characters that were needed, or this OS returns the
3490  * truncated length.
3491  *
3492  * We ignore the possibility that snprintf might just ignore the length and
3493  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3494  * If your libc is really that bad, come back when you have a better one. */
3495  if (len == bufsize)
3496  {
3497  /* This could be the truncated length (Tru64 and IRIX have this bug),
3498  * or the real length could be coincidentally the same. Which is it?
3499  * If vsnprintf returns the truncated length, we'll go to the slow
3500  * path. */
3501  DBUS_VA_COPY (args_copy, args);
3502 
3503  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3504  len = -1;
3505 
3506  va_end (args_copy);
3507  }
3508 
3509  /* If vsnprintf() returned negative, we have to do more work.
3510  * HP-UX returns negative. */
3511  while (len < 0)
3512  {
3513  char *buf;
3514 
3515  bufsize *= 2;
3516 
3517  buf = dbus_malloc (bufsize);
3518 
3519  if (buf == NULL)
3520  return -1;
3521 
3522  DBUS_VA_COPY (args_copy, args);
3523  len = vsnprintf (buf, bufsize, format, args_copy);
3524  va_end (args_copy);
3525 
3526  dbus_free (buf);
3527 
3528  /* If the reported length is exactly the buffer size, round up to the
3529  * next size, in case vsnprintf has been returning the truncated
3530  * length */
3531  if (len == bufsize)
3532  len = -1;
3533  }
3534 
3535  return len;
3536 }
3537 
3544 const char*
3546 {
3547  /* Protected by _DBUS_LOCK_sysdeps */
3548  static const char* tmpdir = NULL;
3549 
3550  if (!_DBUS_LOCK (sysdeps))
3551  return NULL;
3552 
3553  if (tmpdir == NULL)
3554  {
3555  /* TMPDIR is what glibc uses, then
3556  * glibc falls back to the P_tmpdir macro which
3557  * just expands to "/tmp"
3558  */
3559  if (tmpdir == NULL)
3560  tmpdir = getenv("TMPDIR");
3561 
3562  /* These two env variables are probably
3563  * broken, but maybe some OS uses them?
3564  */
3565  if (tmpdir == NULL)
3566  tmpdir = getenv("TMP");
3567  if (tmpdir == NULL)
3568  tmpdir = getenv("TEMP");
3569 
3570  /* And this is the sane fallback. */
3571  if (tmpdir == NULL)
3572  tmpdir = "/tmp";
3573  }
3574 
3575  _DBUS_UNLOCK (sysdeps);
3576 
3577  _dbus_assert(tmpdir != NULL);
3578 
3579  return tmpdir;
3580 }
3581 
3582 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3583 
3602 static dbus_bool_t
3603 _read_subprocess_line_argv (const char *progpath,
3604  dbus_bool_t path_fallback,
3605  char * const *argv,
3606  DBusString *result,
3607  DBusError *error)
3608 {
3609  int result_pipe[2] = { -1, -1 };
3610  int errors_pipe[2] = { -1, -1 };
3611  pid_t pid;
3612  int ret;
3613  int status;
3614  int orig_len;
3615 
3616  dbus_bool_t retval;
3617  sigset_t new_set, old_set;
3618 
3619  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3620  retval = FALSE;
3621 
3622  /* We need to block any existing handlers for SIGCHLD temporarily; they
3623  * will cause waitpid() below to fail.
3624  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3625  */
3626  sigemptyset (&new_set);
3627  sigaddset (&new_set, SIGCHLD);
3628  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3629 
3630  orig_len = _dbus_string_get_length (result);
3631 
3632 #define READ_END 0
3633 #define WRITE_END 1
3634  if (pipe (result_pipe) < 0)
3635  {
3636  dbus_set_error (error, _dbus_error_from_errno (errno),
3637  "Failed to create a pipe to call %s: %s",
3638  progpath, _dbus_strerror (errno));
3639  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3640  progpath, _dbus_strerror (errno));
3641  goto out;
3642  }
3643  if (pipe (errors_pipe) < 0)
3644  {
3645  dbus_set_error (error, _dbus_error_from_errno (errno),
3646  "Failed to create a pipe to call %s: %s",
3647  progpath, _dbus_strerror (errno));
3648  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3649  progpath, _dbus_strerror (errno));
3650  goto out;
3651  }
3652 
3653  pid = fork ();
3654  if (pid < 0)
3655  {
3656  dbus_set_error (error, _dbus_error_from_errno (errno),
3657  "Failed to fork() to call %s: %s",
3658  progpath, _dbus_strerror (errno));
3659  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3660  progpath, _dbus_strerror (errno));
3661  goto out;
3662  }
3663 
3664  if (pid == 0)
3665  {
3666  /* child process */
3667  int fd;
3668 
3669  fd = open ("/dev/null", O_RDWR);
3670  if (fd == -1)
3671  /* huh?! can't open /dev/null? */
3672  _exit (1);
3673 
3674  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3675 
3676  /* set-up stdXXX */
3677  close (result_pipe[READ_END]);
3678  close (errors_pipe[READ_END]);
3679 
3680  if (dup2 (fd, 0) == -1) /* setup stdin */
3681  _exit (1);
3682  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3683  _exit (1);
3684  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3685  _exit (1);
3686 
3687  _dbus_close_all ();
3688 
3689  sigprocmask (SIG_SETMASK, &old_set, NULL);
3690 
3691  /* If it looks fully-qualified, try execv first */
3692  if (progpath[0] == '/')
3693  {
3694  execv (progpath, argv);
3695  /* Ok, that failed. Now if path_fallback is given, let's
3696  * try unqualified. This is mostly a hack to work
3697  * around systems which ship dbus-launch in /usr/bin
3698  * but everything else in /bin (because dbus-launch
3699  * depends on X11).
3700  */
3701  if (path_fallback)
3702  /* We must have a slash, because we checked above */
3703  execvp (strrchr (progpath, '/')+1, argv);
3704  }
3705  else
3706  execvp (progpath, argv);
3707 
3708  /* still nothing, we failed */
3709  _exit (1);
3710  }
3711 
3712  /* parent process */
3713  close (result_pipe[WRITE_END]);
3714  close (errors_pipe[WRITE_END]);
3715  result_pipe[WRITE_END] = -1;
3716  errors_pipe[WRITE_END] = -1;
3717 
3718  ret = 0;
3719  do
3720  {
3721  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3722  }
3723  while (ret > 0);
3724 
3725  /* reap the child process to avoid it lingering as zombie */
3726  do
3727  {
3728  ret = waitpid (pid, &status, 0);
3729  }
3730  while (ret == -1 && errno == EINTR);
3731 
3732  /* We succeeded if the process exited with status 0 and
3733  anything was read */
3734  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3735  {
3736  /* The process ended with error */
3737  DBusString error_message;
3738  if (!_dbus_string_init (&error_message))
3739  {
3740  _DBUS_SET_OOM (error);
3741  goto out;
3742  }
3743 
3744  ret = 0;
3745  do
3746  {
3747  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3748  }
3749  while (ret > 0);
3750 
3751  _dbus_string_set_length (result, orig_len);
3752  if (_dbus_string_get_length (&error_message) > 0)
3754  "%s terminated abnormally with the following error: %s",
3755  progpath, _dbus_string_get_data (&error_message));
3756  else
3758  "%s terminated abnormally without any error message",
3759  progpath);
3760  goto out;
3761  }
3762 
3763  retval = TRUE;
3764 
3765  out:
3766  sigprocmask (SIG_SETMASK, &old_set, NULL);
3767 
3768  if (retval)
3769  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3770  else
3771  _DBUS_ASSERT_ERROR_IS_SET (error);
3772 
3773  if (result_pipe[0] != -1)
3774  close (result_pipe[0]);
3775  if (result_pipe[1] != -1)
3776  close (result_pipe[1]);
3777  if (errors_pipe[0] != -1)
3778  close (errors_pipe[0]);
3779  if (errors_pipe[1] != -1)
3780  close (errors_pipe[1]);
3781 
3782  return retval;
3783 }
3784 #endif
3785 
3799 _dbus_get_autolaunch_address (const char *scope,
3800  DBusString *address,
3801  DBusError *error)
3802 {
3803 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3804  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3805  * but that's done elsewhere, and if it worked, this function wouldn't
3806  * be called.) */
3807  const char *display;
3808  const char *progpath;
3809  char *argv[6];
3810  int i;
3811  DBusString uuid;
3812  dbus_bool_t retval;
3813 
3814  if (_dbus_check_setuid ())
3815  {
3817  "Unable to autolaunch when setuid");
3818  return FALSE;
3819  }
3820 
3821  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3822  retval = FALSE;
3823 
3824  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3825  * dbus-launch-x11 is just going to fail. Rather than trying to
3826  * run it, we might as well bail out early with a nice error.
3827  *
3828  * This is not strictly true in a world where the user bus exists,
3829  * because dbus-launch --autolaunch knows how to connect to that -
3830  * but if we were going to connect to the user bus, we'd have done
3831  * so before trying autolaunch: in any case. */
3832  display = _dbus_getenv ("DISPLAY");
3833 
3834  if (display == NULL || display[0] == '\0')
3835  {
3837  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3838  return FALSE;
3839  }
3840 
3841  if (!_dbus_string_init (&uuid))
3842  {
3843  _DBUS_SET_OOM (error);
3844  return FALSE;
3845  }
3846 
3847  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3848  {
3849  goto out;
3850  }
3851 
3852 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3853  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3854 
3855  if (progpath == NULL)
3856 #endif
3857  progpath = DBUS_BINDIR "/dbus-launch";
3858  /*
3859  * argv[0] is always dbus-launch, that's the name what we'll
3860  * get from /proc, or ps(1), regardless what the progpath is,
3861  * see fd.o#69716
3862  */
3863  i = 0;
3864  argv[i] = "dbus-launch";
3865  ++i;
3866  argv[i] = "--autolaunch";
3867  ++i;
3868  argv[i] = _dbus_string_get_data (&uuid);
3869  ++i;
3870  argv[i] = "--binary-syntax";
3871  ++i;
3872  argv[i] = "--close-stderr";
3873  ++i;
3874  argv[i] = NULL;
3875  ++i;
3876 
3877  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3878 
3879  retval = _read_subprocess_line_argv (progpath,
3880  TRUE,
3881  argv, address, error);
3882 
3883  out:
3884  _dbus_string_free (&uuid);
3885  return retval;
3886 #else
3888  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3889  "set your DBUS_SESSION_BUS_ADDRESS instead");
3890  return FALSE;
3891 #endif
3892 }
3893 
3914  dbus_bool_t create_if_not_found,
3915  DBusError *error)
3916 {
3917  DBusString filename;
3918  dbus_bool_t b;
3919 
3920  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3921 
3922  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3923  if (b)
3924  return TRUE;
3925 
3926  dbus_error_free (error);
3927 
3928  /* Fallback to the system machine ID */
3929  _dbus_string_init_const (&filename, "/etc/machine-id");
3930  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3931 
3932  if (b)
3933  {
3934  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3935  * complain if that isn't possible for whatever reason */
3936  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3937  _dbus_write_uuid_file (&filename, machine_id, NULL);
3938 
3939  return TRUE;
3940  }
3941 
3942  if (!create_if_not_found)
3943  return FALSE;
3944 
3945  /* if none found, try to make a new one */
3946  dbus_error_free (error);
3947  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3948 
3949  if (!_dbus_generate_uuid (machine_id, error))
3950  return FALSE;
3951 
3952  return _dbus_write_uuid_file (&filename, machine_id, error);
3953 }
3954 
3964  const char *launchd_env_var,
3965  DBusError *error)
3966 {
3967 #ifdef DBUS_ENABLE_LAUNCHD
3968  char *argv[4];
3969  int i;
3970 
3971  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3972 
3973  if (_dbus_check_setuid ())
3974  {
3976  "Unable to find launchd socket when setuid");
3977  return FALSE;
3978  }
3979 
3980  i = 0;
3981  argv[i] = "launchctl";
3982  ++i;
3983  argv[i] = "getenv";
3984  ++i;
3985  argv[i] = (char*)launchd_env_var;
3986  ++i;
3987  argv[i] = NULL;
3988  ++i;
3989 
3990  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3991 
3992  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3993  {
3994  return FALSE;
3995  }
3996 
3997  /* no error, but no result either */
3998  if (_dbus_string_get_length(socket_path) == 0)
3999  {
4000  return FALSE;
4001  }
4002 
4003  /* strip the carriage-return */
4004  _dbus_string_shorten(socket_path, 1);
4005  return TRUE;
4006 #else /* DBUS_ENABLE_LAUNCHD */
4008  "can't lookup socket from launchd; launchd support not compiled in");
4009  return FALSE;
4010 #endif
4011 }
4012 
4013 #ifdef DBUS_ENABLE_LAUNCHD
4014 static dbus_bool_t
4015 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4016 {
4017  dbus_bool_t valid_socket;
4018  DBusString socket_path;
4019 
4020  if (_dbus_check_setuid ())
4021  {
4023  "Unable to find launchd socket when setuid");
4024  return FALSE;
4025  }
4026 
4027  if (!_dbus_string_init (&socket_path))
4028  {
4029  _DBUS_SET_OOM (error);
4030  return FALSE;
4031  }
4032 
4033  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4034 
4035  if (dbus_error_is_set(error))
4036  {
4037  _dbus_string_free(&socket_path);
4038  return FALSE;
4039  }
4040 
4041  if (!valid_socket)
4042  {
4043  dbus_set_error(error, "no socket path",
4044  "launchd did not provide a socket path, "
4045  "verify that org.freedesktop.dbus-session.plist is loaded!");
4046  _dbus_string_free(&socket_path);
4047  return FALSE;
4048  }
4049  if (!_dbus_string_append (address, "unix:path="))
4050  {
4051  _DBUS_SET_OOM (error);
4052  _dbus_string_free(&socket_path);
4053  return FALSE;
4054  }
4055  if (!_dbus_string_copy (&socket_path, 0, address,
4056  _dbus_string_get_length (address)))
4057  {
4058  _DBUS_SET_OOM (error);
4059  _dbus_string_free(&socket_path);
4060  return FALSE;
4061  }
4062 
4063  _dbus_string_free(&socket_path);
4064  return TRUE;
4065 }
4066 #endif
4067 
4069 _dbus_lookup_user_bus (dbus_bool_t *supported,
4070  DBusString *address,
4071  DBusError *error)
4072 {
4073  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4074  dbus_bool_t ret = FALSE;
4075  struct stat stbuf;
4076  DBusString user_bus_path;
4077 
4078  if (runtime_dir == NULL)
4079  {
4080  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4081  *supported = FALSE;
4082  return TRUE; /* Cannot use it, but not an error */
4083  }
4084 
4085  if (!_dbus_string_init (&user_bus_path))
4086  {
4087  _DBUS_SET_OOM (error);
4088  return FALSE;
4089  }
4090 
4091  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4092  {
4093  _DBUS_SET_OOM (error);
4094  goto out;
4095  }
4096 
4097  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4098  {
4099  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4100  _dbus_strerror (errno));
4101  *supported = FALSE;
4102  ret = TRUE; /* Cannot use it, but not an error */
4103  goto out;
4104  }
4105 
4106  if (stbuf.st_uid != getuid ())
4107  {
4108  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4109  (long) stbuf.st_uid, (long) getuid ());
4110  *supported = FALSE;
4111  ret = TRUE; /* Cannot use it, but not an error */
4112  goto out;
4113  }
4114 
4115  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4116  {
4117  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4118  (long) stbuf.st_mode);
4119  *supported = FALSE;
4120  ret = TRUE; /* Cannot use it, but not an error */
4121  goto out;
4122  }
4123 
4124  if (!_dbus_string_append (address, "unix:path=") ||
4125  !_dbus_address_append_escaped (address, &user_bus_path))
4126  {
4127  _DBUS_SET_OOM (error);
4128  goto out;
4129  }
4130 
4131  *supported = TRUE;
4132  ret = TRUE;
4133 
4134 out:
4135  _dbus_string_free (&user_bus_path);
4136  return ret;
4137 }
4138 
4160  DBusString *address,
4161  DBusError *error)
4162 {
4163 #ifdef DBUS_ENABLE_LAUNCHD
4164  *supported = TRUE;
4165  return _dbus_lookup_session_address_launchd (address, error);
4166 #else
4167  *supported = FALSE;
4168 
4169  if (!_dbus_lookup_user_bus (supported, address, error))
4170  return FALSE;
4171  else if (*supported)
4172  return TRUE;
4173 
4174  /* On non-Mac Unix platforms, if the session address isn't already
4175  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4176  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4177  * autolaunch: global default; see init_session_address in
4178  * dbus/dbus-bus.c. */
4179  return TRUE;
4180 #endif
4181 }
4182 
4190 void
4192 {
4194 }
4195 
4211  DBusCredentials *credentials)
4212 {
4213  DBusString homedir;
4214  DBusString dotdir;
4215  dbus_uid_t uid;
4216 
4217  _dbus_assert (credentials != NULL);
4219 
4220  if (!_dbus_string_init (&homedir))
4221  return FALSE;
4222 
4223  uid = _dbus_credentials_get_unix_uid (credentials);
4224  _dbus_assert (uid != DBUS_UID_UNSET);
4225 
4226  if (!_dbus_homedir_from_uid (uid, &homedir))
4227  goto failed;
4228 
4229 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4230  {
4231  const char *override;
4232 
4233  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4234  if (override != NULL && *override != '\0')
4235  {
4236  _dbus_string_set_length (&homedir, 0);
4237  if (!_dbus_string_append (&homedir, override))
4238  goto failed;
4239 
4240  _dbus_verbose ("Using fake homedir for testing: %s\n",
4241  _dbus_string_get_const_data (&homedir));
4242  }
4243  else
4244  {
4245  /* Not strictly thread-safe, but if we fail at thread-safety here,
4246  * the worst that will happen is some extra warnings. */
4247  static dbus_bool_t already_warned = FALSE;
4248  if (!already_warned)
4249  {
4250  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid\n",
4251  _dbus_string_get_const_data (&homedir));
4252  already_warned = TRUE;
4253  }
4254  }
4255  }
4256 #endif
4257 
4258  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4259  if (!_dbus_concat_dir_and_file (&homedir,
4260  &dotdir))
4261  goto failed;
4262 
4263  if (!_dbus_string_copy (&homedir, 0,
4264  directory, _dbus_string_get_length (directory))) {
4265  goto failed;
4266  }
4267 
4268  _dbus_string_free (&homedir);
4269  return TRUE;
4270 
4271  failed:
4272  _dbus_string_free (&homedir);
4273  return FALSE;
4274 }
4275 
4276 //PENDING(kdab) docs
4278 _dbus_daemon_publish_session_bus_address (const char* addr,
4279  const char *scope)
4280 {
4281  return TRUE;
4282 }
4283 
4284 //PENDING(kdab) docs
4285 void
4286 _dbus_daemon_unpublish_session_bus_address (void)
4287 {
4288 
4289 }
4290 
4299 {
4300  return e == EAGAIN || e == EWOULDBLOCK;
4301 }
4302 
4312  DBusError *error)
4313 {
4314  const char *filename_c;
4315 
4316  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4317 
4318  filename_c = _dbus_string_get_const_data (filename);
4319 
4320  if (rmdir (filename_c) != 0)
4321  {
4323  "Failed to remove directory %s: %s\n",
4324  filename_c, _dbus_strerror (errno));
4325  return FALSE;
4326  }
4327 
4328  return TRUE;
4329 }
4330 
4340 {
4341 #ifdef SCM_RIGHTS
4342  union {
4343  struct sockaddr sa;
4344  struct sockaddr_storage storage;
4345  struct sockaddr_un un;
4346  } sa_buf;
4347 
4348  socklen_t sa_len = sizeof(sa_buf);
4349 
4350  _DBUS_ZERO(sa_buf);
4351 
4352  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4353  return FALSE;
4354 
4355  return sa_buf.sa.sa_family == AF_UNIX;
4356 
4357 #else
4358  return FALSE;
4359 
4360 #endif
4361 }
4362 
4367 void
4369 {
4370  int maxfds, i;
4371 
4372 #ifdef __linux__
4373  DIR *d;
4374 
4375  /* On Linux we can optimize this a bit if /proc is available. If it
4376  isn't available, fall back to the brute force way. */
4377 
4378  d = opendir ("/proc/self/fd");
4379  if (d)
4380  {
4381  for (;;)
4382  {
4383  struct dirent buf, *de;
4384  int k, fd;
4385  long l;
4386  char *e = NULL;
4387 
4388  k = readdir_r (d, &buf, &de);
4389  if (k != 0 || !de)
4390  break;
4391 
4392  if (de->d_name[0] == '.')
4393  continue;
4394 
4395  errno = 0;
4396  l = strtol (de->d_name, &e, 10);
4397  if (errno != 0 || e == NULL || *e != '\0')
4398  continue;
4399 
4400  fd = (int) l;
4401  if (fd < 3)
4402  continue;
4403 
4404  if (fd == dirfd (d))
4405  continue;
4406 
4407  close (fd);
4408  }
4409 
4410  closedir (d);
4411  return;
4412  }
4413 #endif
4414 
4415  maxfds = sysconf (_SC_OPEN_MAX);
4416 
4417  /* Pick something reasonable if for some reason sysconf says
4418  * unlimited.
4419  */
4420  if (maxfds < 0)
4421  maxfds = 1024;
4422 
4423  /* close all inherited fds */
4424  for (i = 3; i < maxfds; i++)
4425  close (i);
4426 }
4427 
4439 {
4440  /* TODO: get __libc_enable_secure exported from glibc.
4441  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4442  */
4443 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4444  {
4445  /* See glibc/include/unistd.h */
4446  extern int __libc_enable_secure;
4447  return __libc_enable_secure;
4448  }
4449 #elif defined(HAVE_ISSETUGID)
4450  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4451  return issetugid ();
4452 #else
4453  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4454  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4455 
4456  /* We call into this function from _dbus_threads_init_platform_specific()
4457  * to make sure these are initialized before we start threading. */
4458  static dbus_bool_t check_setuid_initialised;
4459  static dbus_bool_t is_setuid;
4460 
4461  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4462  {
4463 #ifdef HAVE_GETRESUID
4464  if (getresuid (&ruid, &euid, &suid) != 0 ||
4465  getresgid (&rgid, &egid, &sgid) != 0)
4466 #endif /* HAVE_GETRESUID */
4467  {
4468  suid = ruid = getuid ();
4469  sgid = rgid = getgid ();
4470  euid = geteuid ();
4471  egid = getegid ();
4472  }
4473 
4474  check_setuid_initialised = TRUE;
4475  is_setuid = (ruid != euid || ruid != suid ||
4476  rgid != egid || rgid != sgid);
4477 
4478  }
4479  return is_setuid;
4480 #endif
4481 }
4482 
4492  DBusString *address,
4493  DBusError *error)
4494 {
4495  union {
4496  struct sockaddr sa;
4497  struct sockaddr_storage storage;
4498  struct sockaddr_un un;
4499  struct sockaddr_in ipv4;
4500  struct sockaddr_in6 ipv6;
4501  } socket;
4502  char hostip[INET6_ADDRSTRLEN];
4503  int size = sizeof (socket);
4504  DBusString path_str;
4505 
4506  if (getsockname (fd.fd, &socket.sa, &size))
4507  goto err;
4508 
4509  switch (socket.sa.sa_family)
4510  {
4511  case AF_UNIX:
4512  if (socket.un.sun_path[0]=='\0')
4513  {
4514  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4515  if (_dbus_string_append (address, "unix:abstract=") &&
4516  _dbus_address_append_escaped (address, &path_str))
4517  return TRUE;
4518  }
4519  else
4520  {
4521  _dbus_string_init_const (&path_str, socket.un.sun_path);
4522  if (_dbus_string_append (address, "unix:path=") &&
4523  _dbus_address_append_escaped (address, &path_str))
4524  return TRUE;
4525  }
4526  break;
4527  case AF_INET:
4528  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4529  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4530  hostip, ntohs (socket.ipv4.sin_port)))
4531  return TRUE;
4532  break;
4533 #ifdef AF_INET6
4534  case AF_INET6:
4535  _dbus_string_init_const (&path_str, hostip);
4536  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4537  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4538  ntohs (socket.ipv6.sin6_port)) &&
4539  _dbus_address_append_escaped (address, &path_str))
4540  return TRUE;
4541  break;
4542 #endif
4543  default:
4544  dbus_set_error (error,
4545  _dbus_error_from_errno (EINVAL),
4546  "Failed to read address from socket: Unknown socket type.");
4547  return FALSE;
4548  }
4549  err:
4550  dbus_set_error (error,
4551  _dbus_error_from_errno (errno),
4552  "Failed to open socket: %s",
4553  _dbus_strerror (errno));
4554  return FALSE;
4555 }
4556 
4557 int
4558 _dbus_save_socket_errno (void)
4559 {
4560  return errno;
4561 }
4562 
4563 void
4564 _dbus_restore_socket_errno (int saved_errno)
4565 {
4566  errno = saved_errno;
4567 }
4568 
4569 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:935
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:279
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn&#39;t contain...
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:392
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:284
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.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:123
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:119
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:386
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_gid_t primary_gid
GID.
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials...
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:388
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:490
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
short events
Events to poll for.
Definition: dbus-sysdeps.h:383
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1283
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:112
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:114
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:590
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:498
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:105
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
Socket interface.
Definition: dbus-sysdeps.h:148
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:392
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_uid_t uid
UID.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
dbus_bool_t _dbus_read_credentials_socket(DBusSocket client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
int _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute. ...
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1157
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:116
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:382
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:873
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:121
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
void _dbus_exit(int code)
Exit the process, returning the given value.
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:875
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:109
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:601
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
char * _dbus_strdup(const char *str)
Duplicates a string.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:107
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:384
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:394