D-Bus  1.6.18
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-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
38 
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sys/socket.h>
47 #include <dirent.h>
48 #include <sys/un.h>
49 #include <pwd.h>
50 #include <time.h>
51 #include <locale.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <sys/wait.h>
55 #include <netinet/in.h>
56 #include <netdb.h>
57 #include <grp.h>
58 
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_WRITEV
63 #include <sys/uio.h>
64 #endif
65 #ifdef HAVE_POLL
66 #include <sys/poll.h>
67 #endif
68 #ifdef HAVE_BACKTRACE
69 #include <execinfo.h>
70 #endif
71 #ifdef HAVE_GETPEERUCRED
72 #include <ucred.h>
73 #endif
74 #ifdef HAVE_ALLOCA_H
75 #include <alloca.h>
76 #endif
77 
78 #ifdef HAVE_ADT
79 #include <bsm/adt.h>
80 #endif
81 
82 #include "sd-daemon.h"
83 
84 #ifndef O_BINARY
85 #define O_BINARY 0
86 #endif
87 
88 #ifndef AI_ADDRCONFIG
89 #define AI_ADDRCONFIG 0
90 #endif
91 
92 #ifndef HAVE_SOCKLEN_T
93 #define socklen_t int
94 #endif
95 
96 #if defined (__sun) || defined (__sun__)
97 /*
98  * CMS_SPACE etc. definitions for Solaris < 10, based on
99  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
100  * via
101  * http://wiki.opencsw.org/porting-faq#toc10
102  *
103  * These are only redefined for Solaris, for now: if your OS needs these too,
104  * please file a bug. (Or preferably, improve your OS so they're not needed.)
105  */
106 
107 # ifndef CMSG_ALIGN
108 # ifdef __sun__
109 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
110 # else
111  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
112 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
113  ~(sizeof (long) - 1))
114 # endif
115 # endif
116 
117 # ifndef CMSG_SPACE
118 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
119  CMSG_ALIGN (len))
120 # endif
121 
122 # ifndef CMSG_LEN
123 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
124 # endif
125 
126 #endif /* Solaris */
127 
128 static dbus_bool_t
129 _dbus_open_socket (int *fd_p,
130  int domain,
131  int type,
132  int protocol,
133  DBusError *error)
134 {
135 #ifdef SOCK_CLOEXEC
136  dbus_bool_t cloexec_done;
137 
138  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
139  cloexec_done = *fd_p >= 0;
140 
141  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
142  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
143 #endif
144  {
145  *fd_p = socket (domain, type, protocol);
146  }
147 
148  if (*fd_p >= 0)
149  {
150 #ifdef SOCK_CLOEXEC
151  if (!cloexec_done)
152 #endif
153  {
155  }
156 
157  _dbus_verbose ("socket fd %d opened\n", *fd_p);
158  return TRUE;
159  }
160  else
161  {
162  dbus_set_error(error,
163  _dbus_error_from_errno (errno),
164  "Failed to open socket: %s",
165  _dbus_strerror (errno));
166  return FALSE;
167  }
168 }
169 
180 static dbus_bool_t
181 _dbus_open_unix_socket (int *fd,
182  DBusError *error)
183 {
184  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
185 }
186 
197  DBusError *error)
198 {
199  return _dbus_close (fd, error);
200 }
201 
211 int
213  DBusString *buffer,
214  int count)
215 {
216  return _dbus_read (fd, buffer, count);
217 }
218 
229 int
231  const DBusString *buffer,
232  int start,
233  int len)
234 {
235 #if HAVE_DECL_MSG_NOSIGNAL
236  const char *data;
237  int bytes_written;
238 
239  data = _dbus_string_get_const_data_len (buffer, start, len);
240 
241  again:
242 
243  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
244 
245  if (bytes_written < 0 && errno == EINTR)
246  goto again;
247 
248  return bytes_written;
249 
250 #else
251  return _dbus_write (fd, buffer, start, len);
252 #endif
253 }
254 
267 int
269  DBusString *buffer,
270  int count,
271  int *fds,
272  int *n_fds) {
273 #ifndef HAVE_UNIX_FD_PASSING
274  int r;
275 
276  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
277  return r;
278 
279  *n_fds = 0;
280  return r;
281 
282 #else
283  int bytes_read;
284  int start;
285  struct msghdr m;
286  struct iovec iov;
287 
288  _dbus_assert (count >= 0);
289  _dbus_assert (*n_fds >= 0);
290 
291  start = _dbus_string_get_length (buffer);
292 
293  if (!_dbus_string_lengthen (buffer, count))
294  {
295  errno = ENOMEM;
296  return -1;
297  }
298 
299  _DBUS_ZERO(iov);
300  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
301  iov.iov_len = count;
302 
303  _DBUS_ZERO(m);
304  m.msg_iov = &iov;
305  m.msg_iovlen = 1;
306 
307  /* Hmm, we have no clue how long the control data will actually be
308  that is queued for us. The least we can do is assume that the
309  caller knows. Hence let's make space for the number of fds that
310  we shall read at max plus the cmsg header. */
311  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
312 
313  /* It's probably safe to assume that systems with SCM_RIGHTS also
314  know alloca() */
315  m.msg_control = alloca(m.msg_controllen);
316  memset(m.msg_control, 0, m.msg_controllen);
317 
318  /* Do not include the padding at the end when we tell the kernel
319  * how much we're willing to receive. This avoids getting
320  * the padding filled with additional fds that we weren't expecting,
321  * if a (potentially malicious) sender included them. (fd.o #83622) */
322  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
323 
324  again:
325 
326  bytes_read = recvmsg(fd, &m, 0
327 #ifdef MSG_CMSG_CLOEXEC
328  |MSG_CMSG_CLOEXEC
329 #endif
330  );
331 
332  if (bytes_read < 0)
333  {
334  if (errno == EINTR)
335  goto again;
336  else
337  {
338  /* put length back (note that this doesn't actually realloc anything) */
339  _dbus_string_set_length (buffer, start);
340  return -1;
341  }
342  }
343  else
344  {
345  struct cmsghdr *cm;
346  dbus_bool_t found = FALSE;
347 
348  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
349  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
350  {
351  size_t i;
352  int *payload = (int *) CMSG_DATA (cm);
353  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
354  size_t payload_len_fds = payload_len_bytes / sizeof (int);
355  size_t fds_to_use;
356 
357  /* Every non-negative int fits in a size_t without truncation,
358  * and we already know that *n_fds is non-negative, so
359  * casting (size_t) *n_fds is OK */
360  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
361 
362  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
363  {
364  /* The fds in the payload will fit in our buffer */
365  fds_to_use = payload_len_fds;
366  }
367  else
368  {
369  /* Too many fds in the payload. This shouldn't happen
370  * any more because we're setting m.msg_controllen to
371  * the exact number we can accept, but be safe and
372  * truncate. */
373  fds_to_use = (size_t) *n_fds;
374 
375  /* Close the excess fds to avoid DoS: if they stayed open,
376  * someone could send us an extra fd per message
377  * and we'd eventually run out. */
378  for (i = fds_to_use; i < payload_len_fds; i++)
379  {
380  close (payload[i]);
381  }
382  }
383 
384  memcpy (fds, payload, fds_to_use * sizeof (int));
385  found = TRUE;
386  /* This cannot overflow because we have chosen fds_to_use
387  * to be <= *n_fds */
388  *n_fds = (int) fds_to_use;
389 
390  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
391  worked, hence we need to go through this list and set
392  CLOEXEC everywhere in any case */
393  for (i = 0; i < fds_to_use; i++)
395 
396  break;
397  }
398 
399  if (!found)
400  *n_fds = 0;
401 
402  if (m.msg_flags & MSG_CTRUNC)
403  {
404  int i;
405 
406  /* Hmm, apparently the control data was truncated. The bad
407  thing is that we might have completely lost a couple of fds
408  without chance to recover them. Hence let's treat this as a
409  serious error. */
410 
411  /* We still need to close whatever fds we *did* receive,
412  * otherwise they'll never get closed. (CVE-2020-12049) */
413  for (i = 0; i < *n_fds; i++)
414  close (fds[i]);
415 
416  *n_fds = 0;
417  errno = ENOSPC;
418  _dbus_string_set_length (buffer, start);
419  return -1;
420  }
421 
422  /* put length back (doesn't actually realloc) */
423  _dbus_string_set_length (buffer, start + bytes_read);
424 
425 #if 0
426  if (bytes_read > 0)
427  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
428 #endif
429 
430  return bytes_read;
431  }
432 #endif
433 }
434 
435 int
436 _dbus_write_socket_with_unix_fds(int fd,
437  const DBusString *buffer,
438  int start,
439  int len,
440  const int *fds,
441  int n_fds) {
442 
443 #ifndef HAVE_UNIX_FD_PASSING
444 
445  if (n_fds > 0) {
446  errno = ENOTSUP;
447  return -1;
448  }
449 
450  return _dbus_write_socket(fd, buffer, start, len);
451 #else
452  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
453 #endif
454 }
455 
456 int
457 _dbus_write_socket_with_unix_fds_two(int fd,
458  const DBusString *buffer1,
459  int start1,
460  int len1,
461  const DBusString *buffer2,
462  int start2,
463  int len2,
464  const int *fds,
465  int n_fds) {
466 
467 #ifndef HAVE_UNIX_FD_PASSING
468 
469  if (n_fds > 0) {
470  errno = ENOTSUP;
471  return -1;
472  }
473 
474  return _dbus_write_socket_two(fd,
475  buffer1, start1, len1,
476  buffer2, start2, len2);
477 #else
478 
479  struct msghdr m;
480  struct cmsghdr *cm;
481  struct iovec iov[2];
482  int bytes_written;
483 
484  _dbus_assert (len1 >= 0);
485  _dbus_assert (len2 >= 0);
486  _dbus_assert (n_fds >= 0);
487 
488  _DBUS_ZERO(iov);
489  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
490  iov[0].iov_len = len1;
491 
492  if (buffer2)
493  {
494  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
495  iov[1].iov_len = len2;
496  }
497 
498  _DBUS_ZERO(m);
499  m.msg_iov = iov;
500  m.msg_iovlen = buffer2 ? 2 : 1;
501 
502  if (n_fds > 0)
503  {
504  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
505  m.msg_control = alloca(m.msg_controllen);
506  memset(m.msg_control, 0, m.msg_controllen);
507 
508  cm = CMSG_FIRSTHDR(&m);
509  cm->cmsg_level = SOL_SOCKET;
510  cm->cmsg_type = SCM_RIGHTS;
511  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
512  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
513  }
514 
515  again:
516 
517  bytes_written = sendmsg (fd, &m, 0
518 #if HAVE_DECL_MSG_NOSIGNAL
519  |MSG_NOSIGNAL
520 #endif
521  );
522 
523  if (bytes_written < 0 && errno == EINTR)
524  goto again;
525 
526 #if 0
527  if (bytes_written > 0)
528  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
529 #endif
530 
531  return bytes_written;
532 #endif
533 }
534 
548 int
550  const DBusString *buffer1,
551  int start1,
552  int len1,
553  const DBusString *buffer2,
554  int start2,
555  int len2)
556 {
557 #if HAVE_DECL_MSG_NOSIGNAL
558  struct iovec vectors[2];
559  const char *data1;
560  const char *data2;
561  int bytes_written;
562  struct msghdr m;
563 
564  _dbus_assert (buffer1 != NULL);
565  _dbus_assert (start1 >= 0);
566  _dbus_assert (start2 >= 0);
567  _dbus_assert (len1 >= 0);
568  _dbus_assert (len2 >= 0);
569 
570  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
571 
572  if (buffer2 != NULL)
573  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
574  else
575  {
576  data2 = NULL;
577  start2 = 0;
578  len2 = 0;
579  }
580 
581  vectors[0].iov_base = (char*) data1;
582  vectors[0].iov_len = len1;
583  vectors[1].iov_base = (char*) data2;
584  vectors[1].iov_len = len2;
585 
586  _DBUS_ZERO(m);
587  m.msg_iov = vectors;
588  m.msg_iovlen = data2 ? 2 : 1;
589 
590  again:
591 
592  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
593 
594  if (bytes_written < 0 && errno == EINTR)
595  goto again;
596 
597  return bytes_written;
598 
599 #else
600  return _dbus_write_two (fd, buffer1, start1, len1,
601  buffer2, start2, len2);
602 #endif
603 }
604 
606 _dbus_socket_is_invalid (int fd)
607 {
608  return fd < 0 ? TRUE : FALSE;
609 }
610 
627 int
628 _dbus_read (int fd,
629  DBusString *buffer,
630  int count)
631 {
632  int bytes_read;
633  int start;
634  char *data;
635 
636  _dbus_assert (count >= 0);
637 
638  start = _dbus_string_get_length (buffer);
639 
640  if (!_dbus_string_lengthen (buffer, count))
641  {
642  errno = ENOMEM;
643  return -1;
644  }
645 
646  data = _dbus_string_get_data_len (buffer, start, count);
647 
648  again:
649 
650  bytes_read = read (fd, data, count);
651 
652  if (bytes_read < 0)
653  {
654  if (errno == EINTR)
655  goto again;
656  else
657  {
658  /* put length back (note that this doesn't actually realloc anything) */
659  _dbus_string_set_length (buffer, start);
660  return -1;
661  }
662  }
663  else
664  {
665  /* put length back (doesn't actually realloc) */
666  _dbus_string_set_length (buffer, start + bytes_read);
667 
668 #if 0
669  if (bytes_read > 0)
670  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
671 #endif
672 
673  return bytes_read;
674  }
675 }
676 
687 int
688 _dbus_write (int fd,
689  const DBusString *buffer,
690  int start,
691  int len)
692 {
693  const char *data;
694  int bytes_written;
695 
696  data = _dbus_string_get_const_data_len (buffer, start, len);
697 
698  again:
699 
700  bytes_written = write (fd, data, len);
701 
702  if (bytes_written < 0 && errno == EINTR)
703  goto again;
704 
705 #if 0
706  if (bytes_written > 0)
707  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
708 #endif
709 
710  return bytes_written;
711 }
712 
733 int
735  const DBusString *buffer1,
736  int start1,
737  int len1,
738  const DBusString *buffer2,
739  int start2,
740  int len2)
741 {
742  _dbus_assert (buffer1 != NULL);
743  _dbus_assert (start1 >= 0);
744  _dbus_assert (start2 >= 0);
745  _dbus_assert (len1 >= 0);
746  _dbus_assert (len2 >= 0);
747 
748 #ifdef HAVE_WRITEV
749  {
750  struct iovec vectors[2];
751  const char *data1;
752  const char *data2;
753  int bytes_written;
754 
755  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
756 
757  if (buffer2 != NULL)
758  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
759  else
760  {
761  data2 = NULL;
762  start2 = 0;
763  len2 = 0;
764  }
765 
766  vectors[0].iov_base = (char*) data1;
767  vectors[0].iov_len = len1;
768  vectors[1].iov_base = (char*) data2;
769  vectors[1].iov_len = len2;
770 
771  again:
772 
773  bytes_written = writev (fd,
774  vectors,
775  data2 ? 2 : 1);
776 
777  if (bytes_written < 0 && errno == EINTR)
778  goto again;
779 
780  return bytes_written;
781  }
782 #else /* HAVE_WRITEV */
783  {
784  int ret1, ret2;
785 
786  ret1 = _dbus_write (fd, buffer1, start1, len1);
787  if (ret1 == len1 && buffer2 != NULL)
788  {
789  ret2 = _dbus_write (fd, buffer2, start2, len2);
790  if (ret2 < 0)
791  ret2 = 0; /* we can't report an error as the first write was OK */
792 
793  return ret1 + ret2;
794  }
795  else
796  return ret1;
797  }
798 #endif /* !HAVE_WRITEV */
799 }
800 
801 #define _DBUS_MAX_SUN_PATH_LENGTH 99
802 
832 int
833 _dbus_connect_unix_socket (const char *path,
834  dbus_bool_t abstract,
835  DBusError *error)
836 {
837  int fd;
838  size_t path_len;
839  struct sockaddr_un addr;
840 
841  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
842 
843  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
844  path, abstract);
845 
846 
847  if (!_dbus_open_unix_socket (&fd, error))
848  {
849  _DBUS_ASSERT_ERROR_IS_SET(error);
850  return -1;
851  }
852  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
853 
854  _DBUS_ZERO (addr);
855  addr.sun_family = AF_UNIX;
856  path_len = strlen (path);
857 
858  if (abstract)
859  {
860 #ifdef HAVE_ABSTRACT_SOCKETS
861  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
862  path_len++; /* Account for the extra nul byte added to the start of sun_path */
863 
864  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
865  {
867  "Abstract socket name too long\n");
868  _dbus_close (fd, NULL);
869  return -1;
870  }
871 
872  strncpy (&addr.sun_path[1], path, path_len);
873  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
874 #else /* HAVE_ABSTRACT_SOCKETS */
876  "Operating system does not support abstract socket namespace\n");
877  _dbus_close (fd, NULL);
878  return -1;
879 #endif /* ! HAVE_ABSTRACT_SOCKETS */
880  }
881  else
882  {
883  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
884  {
886  "Socket name too long\n");
887  _dbus_close (fd, NULL);
888  return -1;
889  }
890 
891  strncpy (addr.sun_path, path, path_len);
892  }
893 
894  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
895  {
896  dbus_set_error (error,
897  _dbus_error_from_errno (errno),
898  "Failed to connect to socket %s: %s",
899  path, _dbus_strerror (errno));
900 
901  _dbus_close (fd, NULL);
902  return -1;
903  }
904 
905  if (!_dbus_set_fd_nonblocking (fd, error))
906  {
907  _DBUS_ASSERT_ERROR_IS_SET (error);
908 
909  _dbus_close (fd, NULL);
910  return -1;
911  }
912 
913  return fd;
914 }
915 
928 int
929 _dbus_connect_exec (const char *path,
930  char *const argv[],
931  DBusError *error)
932 {
933  int fds[2];
934  pid_t pid;
935  int retval;
936  dbus_bool_t cloexec_done = 0;
937 
938  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
939 
940  _dbus_verbose ("connecting to process %s\n", path);
941 
942 #ifdef SOCK_CLOEXEC
943  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
944  cloexec_done = (retval >= 0);
945 
946  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
947 #endif
948  {
949  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
950  }
951 
952  if (retval < 0)
953  {
954  dbus_set_error (error,
955  _dbus_error_from_errno (errno),
956  "Failed to create socket pair: %s",
957  _dbus_strerror (errno));
958  return -1;
959  }
960 
961  if (!cloexec_done)
962  {
965  }
966 
967  pid = fork ();
968  if (pid < 0)
969  {
970  dbus_set_error (error,
971  _dbus_error_from_errno (errno),
972  "Failed to fork() to call %s: %s",
973  path, _dbus_strerror (errno));
974  close (fds[0]);
975  close (fds[1]);
976  return -1;
977  }
978 
979  if (pid == 0)
980  {
981  /* child */
982  close (fds[0]);
983 
984  dup2 (fds[1], STDIN_FILENO);
985  dup2 (fds[1], STDOUT_FILENO);
986 
987  if (fds[1] != STDIN_FILENO &&
988  fds[1] != STDOUT_FILENO)
989  close (fds[1]);
990 
991  /* Inherit STDERR and the controlling terminal from the
992  parent */
993 
994  _dbus_close_all ();
995 
996  execvp (path, argv);
997 
998  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
999 
1000  _exit(1);
1001  }
1002 
1003  /* parent */
1004  close (fds[1]);
1005 
1006  if (!_dbus_set_fd_nonblocking (fds[0], error))
1007  {
1008  _DBUS_ASSERT_ERROR_IS_SET (error);
1009 
1010  close (fds[0]);
1011  return -1;
1012  }
1013 
1014  return fds[0];
1015 }
1016 
1026 static dbus_bool_t
1027 _dbus_set_local_creds (int fd, dbus_bool_t on)
1028 {
1029  dbus_bool_t retval = TRUE;
1030 
1031 #if defined(HAVE_CMSGCRED)
1032  /* NOOP just to make sure only one codepath is used
1033  * and to prefer CMSGCRED
1034  */
1035 #elif defined(LOCAL_CREDS)
1036  int val = on ? 1 : 0;
1037  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
1038  {
1039  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
1040  retval = FALSE;
1041  }
1042  else
1043  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
1044  on ? "enabled" : "disabled", fd);
1045 #endif
1046 
1047  return retval;
1048 }
1049 
1067 int
1068 _dbus_listen_unix_socket (const char *path,
1069  dbus_bool_t abstract,
1070  DBusError *error)
1071 {
1072  int listen_fd;
1073  struct sockaddr_un addr;
1074  size_t path_len;
1075  unsigned int reuseaddr;
1076 
1077  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1078 
1079  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1080  path, abstract);
1081 
1082  if (!_dbus_open_unix_socket (&listen_fd, error))
1083  {
1084  _DBUS_ASSERT_ERROR_IS_SET(error);
1085  return -1;
1086  }
1087  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1088 
1089  _DBUS_ZERO (addr);
1090  addr.sun_family = AF_UNIX;
1091  path_len = strlen (path);
1092 
1093  if (abstract)
1094  {
1095 #ifdef HAVE_ABSTRACT_SOCKETS
1096  /* remember that abstract names aren't nul-terminated so we rely
1097  * on sun_path being filled in with zeroes above.
1098  */
1099  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1100  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1101 
1102  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1103  {
1105  "Abstract socket name too long\n");
1106  _dbus_close (listen_fd, NULL);
1107  return -1;
1108  }
1109 
1110  strncpy (&addr.sun_path[1], path, path_len);
1111  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1112 #else /* HAVE_ABSTRACT_SOCKETS */
1114  "Operating system does not support abstract socket namespace\n");
1115  _dbus_close (listen_fd, NULL);
1116  return -1;
1117 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1118  }
1119  else
1120  {
1121  /* Discussed security implications of this with Nalin,
1122  * and we couldn't think of where it would kick our ass, but
1123  * it still seems a bit sucky. It also has non-security suckage;
1124  * really we'd prefer to exit if the socket is already in use.
1125  * But there doesn't seem to be a good way to do this.
1126  *
1127  * Just to be extra careful, I threw in the stat() - clearly
1128  * the stat() can't *fix* any security issue, but it at least
1129  * avoids inadvertent/accidental data loss.
1130  */
1131  {
1132  struct stat sb;
1133 
1134  if (stat (path, &sb) == 0 &&
1135  S_ISSOCK (sb.st_mode))
1136  unlink (path);
1137  }
1138 
1139  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1140  {
1142  "Abstract socket name too long\n");
1143  _dbus_close (listen_fd, NULL);
1144  return -1;
1145  }
1146 
1147  strncpy (addr.sun_path, path, path_len);
1148  }
1149 
1150  reuseaddr = 1;
1151  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1152  {
1153  _dbus_warn ("Failed to set socket option\"%s\": %s",
1154  path, _dbus_strerror (errno));
1155  }
1156 
1157  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1158  {
1159  dbus_set_error (error, _dbus_error_from_errno (errno),
1160  "Failed to bind socket \"%s\": %s",
1161  path, _dbus_strerror (errno));
1162  _dbus_close (listen_fd, NULL);
1163  return -1;
1164  }
1165 
1166  if (listen (listen_fd, 30 /* backlog */) < 0)
1167  {
1168  dbus_set_error (error, _dbus_error_from_errno (errno),
1169  "Failed to listen on socket \"%s\": %s",
1170  path, _dbus_strerror (errno));
1171  _dbus_close (listen_fd, NULL);
1172  return -1;
1173  }
1174 
1175  if (!_dbus_set_local_creds (listen_fd, TRUE))
1176  {
1177  dbus_set_error (error, _dbus_error_from_errno (errno),
1178  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1179  path, _dbus_strerror (errno));
1180  close (listen_fd);
1181  return -1;
1182  }
1183 
1184  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1185  {
1186  _DBUS_ASSERT_ERROR_IS_SET (error);
1187  _dbus_close (listen_fd, NULL);
1188  return -1;
1189  }
1190 
1191  /* Try opening up the permissions, but if we can't, just go ahead
1192  * and continue, maybe it will be good enough.
1193  */
1194  if (!abstract && chmod (path, 0777) < 0)
1195  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1196  path);
1197 
1198  return listen_fd;
1199 }
1200 
1211 int
1213  DBusError *error)
1214 {
1215  int r, n;
1216  unsigned fd;
1217  int *new_fds;
1218 
1219  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1220 
1221  n = sd_listen_fds (TRUE);
1222  if (n < 0)
1223  {
1225  "Failed to acquire systemd socket: %s",
1226  _dbus_strerror (-n));
1227  return -1;
1228  }
1229 
1230  if (n <= 0)
1231  {
1233  "No socket received.");
1234  return -1;
1235  }
1236 
1237  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1238  {
1239  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1240  if (r < 0)
1241  {
1243  "Failed to verify systemd socket type: %s",
1244  _dbus_strerror (-r));
1245  return -1;
1246  }
1247 
1248  if (!r)
1249  {
1251  "Passed socket has wrong type.");
1252  return -1;
1253  }
1254  }
1255 
1256  /* OK, the file descriptors are all good, so let's take posession of
1257  them then. */
1258 
1259  new_fds = dbus_new (int, n);
1260  if (!new_fds)
1261  {
1263  "Failed to allocate file handle array.");
1264  goto fail;
1265  }
1266 
1267  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1268  {
1269  if (!_dbus_set_local_creds (fd, TRUE))
1270  {
1271  dbus_set_error (error, _dbus_error_from_errno (errno),
1272  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1273  _dbus_strerror (errno));
1274  goto fail;
1275  }
1276 
1277  if (!_dbus_set_fd_nonblocking (fd, error))
1278  {
1279  _DBUS_ASSERT_ERROR_IS_SET (error);
1280  goto fail;
1281  }
1282 
1283  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1284  }
1285 
1286  *fds = new_fds;
1287  return n;
1288 
1289  fail:
1290 
1291  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1292  {
1293  _dbus_close (fd, NULL);
1294  }
1295 
1296  dbus_free (new_fds);
1297  return -1;
1298 }
1299 
1313 int
1314 _dbus_connect_tcp_socket (const char *host,
1315  const char *port,
1316  const char *family,
1317  DBusError *error)
1318 {
1319  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1320 }
1321 
1322 int
1323 _dbus_connect_tcp_socket_with_nonce (const char *host,
1324  const char *port,
1325  const char *family,
1326  const char *noncefile,
1327  DBusError *error)
1328 {
1329  int saved_errno = 0;
1330  int fd = -1, res;
1331  struct addrinfo hints;
1332  struct addrinfo *ai, *tmp;
1333 
1334  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1335 
1336  _DBUS_ZERO (hints);
1337 
1338  if (!family)
1339  hints.ai_family = AF_UNSPEC;
1340  else if (!strcmp(family, "ipv4"))
1341  hints.ai_family = AF_INET;
1342  else if (!strcmp(family, "ipv6"))
1343  hints.ai_family = AF_INET6;
1344  else
1345  {
1346  dbus_set_error (error,
1348  "Unknown address family %s", family);
1349  return -1;
1350  }
1351  hints.ai_protocol = IPPROTO_TCP;
1352  hints.ai_socktype = SOCK_STREAM;
1353  hints.ai_flags = AI_ADDRCONFIG;
1354 
1355  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1356  {
1357  dbus_set_error (error,
1358  _dbus_error_from_errno (errno),
1359  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1360  host, port, gai_strerror(res), res);
1361  return -1;
1362  }
1363 
1364  tmp = ai;
1365  while (tmp)
1366  {
1367  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1368  {
1369  freeaddrinfo(ai);
1370  _DBUS_ASSERT_ERROR_IS_SET(error);
1371  return -1;
1372  }
1373  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1374 
1375  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1376  {
1377  saved_errno = errno;
1378  _dbus_close(fd, NULL);
1379  fd = -1;
1380  tmp = tmp->ai_next;
1381  continue;
1382  }
1383 
1384  break;
1385  }
1386  freeaddrinfo(ai);
1387 
1388  if (fd == -1)
1389  {
1390  dbus_set_error (error,
1391  _dbus_error_from_errno (saved_errno),
1392  "Failed to connect to socket \"%s:%s\" %s",
1393  host, port, _dbus_strerror(saved_errno));
1394  return -1;
1395  }
1396 
1397  if (noncefile != NULL)
1398  {
1399  DBusString noncefileStr;
1400  dbus_bool_t ret;
1401  _dbus_string_init_const (&noncefileStr, noncefile);
1402  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1403  _dbus_string_free (&noncefileStr);
1404 
1405  if (!ret)
1406  {
1407  _dbus_close (fd, NULL);
1408  return -1;
1409  }
1410  }
1411 
1412  if (!_dbus_set_fd_nonblocking (fd, error))
1413  {
1414  _dbus_close (fd, NULL);
1415  return -1;
1416  }
1417 
1418  return fd;
1419 }
1420 
1437 int
1438 _dbus_listen_tcp_socket (const char *host,
1439  const char *port,
1440  const char *family,
1441  DBusString *retport,
1442  int **fds_p,
1443  DBusError *error)
1444 {
1445  int saved_errno;
1446  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1447  struct addrinfo hints;
1448  struct addrinfo *ai, *tmp;
1449  unsigned int reuseaddr;
1450 
1451  *fds_p = NULL;
1452  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1453 
1454  _DBUS_ZERO (hints);
1455 
1456  if (!family)
1457  hints.ai_family = AF_UNSPEC;
1458  else if (!strcmp(family, "ipv4"))
1459  hints.ai_family = AF_INET;
1460  else if (!strcmp(family, "ipv6"))
1461  hints.ai_family = AF_INET6;
1462  else
1463  {
1464  dbus_set_error (error,
1466  "Unknown address family %s", family);
1467  return -1;
1468  }
1469 
1470  hints.ai_protocol = IPPROTO_TCP;
1471  hints.ai_socktype = SOCK_STREAM;
1472  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1473 
1474  redo_lookup_with_port:
1475  ai = NULL;
1476  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1477  {
1478  dbus_set_error (error,
1479  _dbus_error_from_errno (errno),
1480  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1481  host ? host : "*", port, gai_strerror(res), res);
1482  goto failed;
1483  }
1484 
1485  tmp = ai;
1486  while (tmp)
1487  {
1488  int fd = -1, *newlisten_fd;
1489  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1490  {
1491  _DBUS_ASSERT_ERROR_IS_SET(error);
1492  goto failed;
1493  }
1494  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1495 
1496  reuseaddr = 1;
1497  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1498  {
1499  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1500  host ? host : "*", port, _dbus_strerror (errno));
1501  }
1502 
1503  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1504  {
1505  saved_errno = errno;
1506  _dbus_close(fd, NULL);
1507  if (saved_errno == EADDRINUSE)
1508  {
1509  /* Depending on kernel policy, it may or may not
1510  be neccessary to bind to both IPv4 & 6 addresses
1511  so ignore EADDRINUSE here */
1512  tmp = tmp->ai_next;
1513  continue;
1514  }
1515  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1516  "Failed to bind socket \"%s:%s\": %s",
1517  host ? host : "*", port, _dbus_strerror (saved_errno));
1518  goto failed;
1519  }
1520 
1521  if (listen (fd, 30 /* backlog */) < 0)
1522  {
1523  saved_errno = errno;
1524  _dbus_close (fd, NULL);
1525  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1526  "Failed to listen on socket \"%s:%s\": %s",
1527  host ? host : "*", port, _dbus_strerror (saved_errno));
1528  goto failed;
1529  }
1530 
1531  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1532  if (!newlisten_fd)
1533  {
1534  saved_errno = errno;
1535  _dbus_close (fd, NULL);
1536  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1537  "Failed to allocate file handle array: %s",
1538  _dbus_strerror (saved_errno));
1539  goto failed;
1540  }
1541  listen_fd = newlisten_fd;
1542  listen_fd[nlisten_fd] = fd;
1543  nlisten_fd++;
1544 
1545  if (!_dbus_string_get_length(retport))
1546  {
1547  /* If the user didn't specify a port, or used 0, then
1548  the kernel chooses a port. After the first address
1549  is bound to, we need to force all remaining addresses
1550  to use the same port */
1551  if (!port || !strcmp(port, "0"))
1552  {
1553  int result;
1554  struct sockaddr_storage addr;
1555  socklen_t addrlen;
1556  char portbuf[50];
1557 
1558  addrlen = sizeof(addr);
1559  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1560 
1561  if (result == -1 ||
1562  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1563  portbuf, sizeof(portbuf),
1564  NI_NUMERICHOST)) != 0)
1565  {
1566  dbus_set_error (error, _dbus_error_from_errno (errno),
1567  "Failed to resolve port \"%s:%s\": %s (%s)",
1568  host ? host : "*", port, gai_strerror(res), res);
1569  goto failed;
1570  }
1571  if (!_dbus_string_append(retport, portbuf))
1572  {
1574  goto failed;
1575  }
1576 
1577  /* Release current address list & redo lookup */
1578  port = _dbus_string_get_const_data(retport);
1579  freeaddrinfo(ai);
1580  goto redo_lookup_with_port;
1581  }
1582  else
1583  {
1584  if (!_dbus_string_append(retport, port))
1585  {
1587  goto failed;
1588  }
1589  }
1590  }
1591 
1592  tmp = tmp->ai_next;
1593  }
1594  freeaddrinfo(ai);
1595  ai = NULL;
1596 
1597  if (!nlisten_fd)
1598  {
1599  errno = EADDRINUSE;
1600  dbus_set_error (error, _dbus_error_from_errno (errno),
1601  "Failed to bind socket \"%s:%s\": %s",
1602  host ? host : "*", port, _dbus_strerror (errno));
1603  goto failed;
1604  }
1605 
1606  for (i = 0 ; i < nlisten_fd ; i++)
1607  {
1608  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1609  {
1610  goto failed;
1611  }
1612  }
1613 
1614  *fds_p = listen_fd;
1615 
1616  return nlisten_fd;
1617 
1618  failed:
1619  if (ai)
1620  freeaddrinfo(ai);
1621  for (i = 0 ; i < nlisten_fd ; i++)
1622  _dbus_close(listen_fd[i], NULL);
1623  dbus_free(listen_fd);
1624  return -1;
1625 }
1626 
1627 static dbus_bool_t
1628 write_credentials_byte (int server_fd,
1629  DBusError *error)
1630 {
1631  int bytes_written;
1632  char buf[1] = { '\0' };
1633 #if defined(HAVE_CMSGCRED)
1634  union {
1635  struct cmsghdr hdr;
1636  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1637  } cmsg;
1638  struct iovec iov;
1639  struct msghdr msg;
1640  iov.iov_base = buf;
1641  iov.iov_len = 1;
1642 
1643  _DBUS_ZERO(msg);
1644  msg.msg_iov = &iov;
1645  msg.msg_iovlen = 1;
1646 
1647  msg.msg_control = (caddr_t) &cmsg;
1648  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1649  _DBUS_ZERO(cmsg);
1650  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1651  cmsg.hdr.cmsg_level = SOL_SOCKET;
1652  cmsg.hdr.cmsg_type = SCM_CREDS;
1653 #endif
1654 
1655  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1656 
1657  again:
1658 
1659 #if defined(HAVE_CMSGCRED)
1660  bytes_written = sendmsg (server_fd, &msg, 0
1661 #if HAVE_DECL_MSG_NOSIGNAL
1662  |MSG_NOSIGNAL
1663 #endif
1664  );
1665 #else
1666  bytes_written = send (server_fd, buf, 1, 0
1667 #if HAVE_DECL_MSG_NOSIGNAL
1668  |MSG_NOSIGNAL
1669 #endif
1670  );
1671 #endif
1672 
1673  if (bytes_written < 0 && errno == EINTR)
1674  goto again;
1675 
1676  if (bytes_written < 0)
1677  {
1678  dbus_set_error (error, _dbus_error_from_errno (errno),
1679  "Failed to write credentials byte: %s",
1680  _dbus_strerror (errno));
1681  return FALSE;
1682  }
1683  else if (bytes_written == 0)
1684  {
1686  "wrote zero bytes writing credentials byte");
1687  return FALSE;
1688  }
1689  else
1690  {
1691  _dbus_assert (bytes_written == 1);
1692  _dbus_verbose ("wrote credentials byte\n");
1693  return TRUE;
1694  }
1695 }
1696 
1720  DBusCredentials *credentials,
1721  DBusError *error)
1722 {
1723  struct msghdr msg;
1724  struct iovec iov;
1725  char buf;
1726  dbus_uid_t uid_read;
1727  dbus_pid_t pid_read;
1728  int bytes_read;
1729 
1730 #ifdef HAVE_CMSGCRED
1731  union {
1732  struct cmsghdr hdr;
1733  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1734  } cmsg;
1735 
1736 #elif defined(LOCAL_CREDS)
1737  struct {
1738  struct cmsghdr hdr;
1739  struct sockcred cred;
1740  } cmsg;
1741 #endif
1742 
1743  uid_read = DBUS_UID_UNSET;
1744  pid_read = DBUS_PID_UNSET;
1745 
1746  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1747 
1748  /* The POSIX spec certainly doesn't promise this, but
1749  * we need these assertions to fail as soon as we're wrong about
1750  * it so we can do the porting fixups
1751  */
1752  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1753  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1754  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1755 
1756  _dbus_credentials_clear (credentials);
1757 
1758  /* Systems supporting LOCAL_CREDS are configured to have this feature
1759  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1760  * the connection. Therefore, the received message must carry the
1761  * credentials information without doing anything special.
1762  */
1763 
1764  iov.iov_base = &buf;
1765  iov.iov_len = 1;
1766 
1767  _DBUS_ZERO(msg);
1768  msg.msg_iov = &iov;
1769  msg.msg_iovlen = 1;
1770 
1771 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1772  _DBUS_ZERO(cmsg);
1773  msg.msg_control = (caddr_t) &cmsg;
1774  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1775 #endif
1776 
1777  again:
1778  bytes_read = recvmsg (client_fd, &msg, 0);
1779 
1780  if (bytes_read < 0)
1781  {
1782  if (errno == EINTR)
1783  goto again;
1784 
1785  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1786  * normally only call read_credentials if the socket was ready
1787  * for reading
1788  */
1789 
1790  dbus_set_error (error, _dbus_error_from_errno (errno),
1791  "Failed to read credentials byte: %s",
1792  _dbus_strerror (errno));
1793  return FALSE;
1794  }
1795  else if (bytes_read == 0)
1796  {
1797  /* this should not happen unless we are using recvmsg wrong,
1798  * so is essentially here for paranoia
1799  */
1801  "Failed to read credentials byte (zero-length read)");
1802  return FALSE;
1803  }
1804  else if (buf != '\0')
1805  {
1807  "Credentials byte was not nul");
1808  return FALSE;
1809  }
1810 
1811 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1812  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1813  || cmsg.hdr.cmsg_type != SCM_CREDS)
1814  {
1816  "Message from recvmsg() was not SCM_CREDS");
1817  return FALSE;
1818  }
1819 #endif
1820 
1821  _dbus_verbose ("read credentials byte\n");
1822 
1823  {
1824 #ifdef SO_PEERCRED
1825 #ifdef __OpenBSD__
1826  struct sockpeercred cr;
1827 #else
1828  struct ucred cr;
1829 #endif
1830  int cr_len = sizeof (cr);
1831 
1832  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1833  cr_len == sizeof (cr))
1834  {
1835  pid_read = cr.pid;
1836  uid_read = cr.uid;
1837  }
1838  else
1839  {
1840  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1841  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1842  }
1843 #elif defined(HAVE_CMSGCRED)
1844  struct cmsgcred *cred;
1845 
1846  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1847  pid_read = cred->cmcred_pid;
1848  uid_read = cred->cmcred_euid;
1849 #elif defined(LOCAL_CREDS)
1850  pid_read = DBUS_PID_UNSET;
1851  uid_read = cmsg.cred.sc_uid;
1852  /* Since we have already got the credentials from this socket, we can
1853  * disable its LOCAL_CREDS flag if it was ever set. */
1854  _dbus_set_local_creds (client_fd, FALSE);
1855 #elif defined(HAVE_GETPEEREID)
1856  uid_t euid;
1857  gid_t egid;
1858  if (getpeereid (client_fd, &euid, &egid) == 0)
1859  {
1860  uid_read = euid;
1861  }
1862  else
1863  {
1864  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1865  }
1866 #elif defined(HAVE_GETPEERUCRED)
1867  ucred_t * ucred = NULL;
1868  if (getpeerucred (client_fd, &ucred) == 0)
1869  {
1870  pid_read = ucred_getpid (ucred);
1871  uid_read = ucred_geteuid (ucred);
1872 #ifdef HAVE_ADT
1873  /* generate audit session data based on socket ucred */
1874  adt_session_data_t *adth = NULL;
1875  adt_export_data_t *data = NULL;
1876  size_t size = 0;
1877  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1878  {
1879  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1880  }
1881  else
1882  {
1883  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1884  {
1885  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1886  }
1887  else
1888  {
1889  size = adt_export_session_data (adth, &data);
1890  if (size <= 0)
1891  {
1892  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1893  }
1894  else
1895  {
1896  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1897  free (data);
1898  }
1899  }
1900  (void) adt_end_session (adth);
1901  }
1902 #endif /* HAVE_ADT */
1903  }
1904  else
1905  {
1906  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1907  }
1908  if (ucred != NULL)
1909  ucred_free (ucred);
1910 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1911  _dbus_verbose ("Socket credentials not supported on this OS\n");
1912 #endif
1913  }
1914 
1915  _dbus_verbose ("Credentials:"
1916  " pid "DBUS_PID_FORMAT
1917  " uid "DBUS_UID_FORMAT
1918  "\n",
1919  pid_read,
1920  uid_read);
1921 
1922  if (pid_read != DBUS_PID_UNSET)
1923  {
1924  if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1925  {
1926  _DBUS_SET_OOM (error);
1927  return FALSE;
1928  }
1929  }
1930 
1931  if (uid_read != DBUS_UID_UNSET)
1932  {
1933  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1934  {
1935  _DBUS_SET_OOM (error);
1936  return FALSE;
1937  }
1938  }
1939 
1940  return TRUE;
1941 }
1942 
1962  DBusError *error)
1963 {
1964  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1965 
1966  if (write_credentials_byte (server_fd, error))
1967  return TRUE;
1968  else
1969  return FALSE;
1970 }
1971 
1981 int
1982 _dbus_accept (int listen_fd)
1983 {
1984  int client_fd;
1985  struct sockaddr addr;
1986  socklen_t addrlen;
1987 #ifdef HAVE_ACCEPT4
1988  dbus_bool_t cloexec_done;
1989 #endif
1990 
1991  addrlen = sizeof (addr);
1992 
1993  retry:
1994 
1995 #ifdef HAVE_ACCEPT4
1996  /*
1997  * At compile-time, we assume that if accept4() is available in
1998  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
1999  * not necessarily true that either is supported by the running kernel.
2000  */
2001  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
2002  cloexec_done = client_fd >= 0;
2003 
2004  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
2005 #endif
2006  {
2007  client_fd = accept (listen_fd, &addr, &addrlen);
2008  }
2009 
2010  if (client_fd < 0)
2011  {
2012  if (errno == EINTR)
2013  goto retry;
2014  }
2015 
2016  _dbus_verbose ("client fd %d accepted\n", client_fd);
2017 
2018 #ifdef HAVE_ACCEPT4
2019  if (!cloexec_done)
2020 #endif
2021  {
2022  _dbus_fd_set_close_on_exec(client_fd);
2023  }
2024 
2025  return client_fd;
2026 }
2027 
2038 {
2039  const char *directory;
2040  struct stat sb;
2041 
2042  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2043 
2044  directory = _dbus_string_get_const_data (dir);
2045 
2046  if (stat (directory, &sb) < 0)
2047  {
2048  dbus_set_error (error, _dbus_error_from_errno (errno),
2049  "%s", _dbus_strerror (errno));
2050 
2051  return FALSE;
2052  }
2053 
2054  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2055  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2056  {
2058  "%s directory is not private to the user", directory);
2059  return FALSE;
2060  }
2061 
2062  return TRUE;
2063 }
2064 
2065 static dbus_bool_t
2066 fill_user_info_from_passwd (struct passwd *p,
2067  DBusUserInfo *info,
2068  DBusError *error)
2069 {
2070  _dbus_assert (p->pw_name != NULL);
2071  _dbus_assert (p->pw_dir != NULL);
2072 
2073  info->uid = p->pw_uid;
2074  info->primary_gid = p->pw_gid;
2075  info->username = _dbus_strdup (p->pw_name);
2076  info->homedir = _dbus_strdup (p->pw_dir);
2077 
2078  if (info->username == NULL ||
2079  info->homedir == NULL)
2080  {
2082  return FALSE;
2083  }
2084 
2085  return TRUE;
2086 }
2087 
2088 static dbus_bool_t
2089 fill_user_info (DBusUserInfo *info,
2090  dbus_uid_t uid,
2091  const DBusString *username,
2092  DBusError *error)
2093 {
2094  const char *username_c;
2095 
2096  /* exactly one of username/uid provided */
2097  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2098  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2099 
2100  info->uid = DBUS_UID_UNSET;
2101  info->primary_gid = DBUS_GID_UNSET;
2102  info->group_ids = NULL;
2103  info->n_group_ids = 0;
2104  info->username = NULL;
2105  info->homedir = NULL;
2106 
2107  if (username != NULL)
2108  username_c = _dbus_string_get_const_data (username);
2109  else
2110  username_c = NULL;
2111 
2112  /* For now assuming that the getpwnam() and getpwuid() flavors
2113  * are always symmetrical, if not we have to add more configure
2114  * checks
2115  */
2116 
2117 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2118  {
2119  struct passwd *p;
2120  int result;
2121  size_t buflen;
2122  char *buf;
2123  struct passwd p_str;
2124 
2125  /* retrieve maximum needed size for buf */
2126  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2127 
2128  /* sysconf actually returns a long, but everything else expects size_t,
2129  * so just recast here.
2130  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2131  */
2132  if ((long) buflen <= 0)
2133  buflen = 1024;
2134 
2135  result = -1;
2136  while (1)
2137  {
2138  buf = dbus_malloc (buflen);
2139  if (buf == NULL)
2140  {
2142  return FALSE;
2143  }
2144 
2145  p = NULL;
2146 #ifdef HAVE_POSIX_GETPWNAM_R
2147  if (uid != DBUS_UID_UNSET)
2148  result = getpwuid_r (uid, &p_str, buf, buflen,
2149  &p);
2150  else
2151  result = getpwnam_r (username_c, &p_str, buf, buflen,
2152  &p);
2153 #else
2154  if (uid != DBUS_UID_UNSET)
2155  p = getpwuid_r (uid, &p_str, buf, buflen);
2156  else
2157  p = getpwnam_r (username_c, &p_str, buf, buflen);
2158  result = 0;
2159 #endif /* !HAVE_POSIX_GETPWNAM_R */
2160  //Try a bigger buffer if ERANGE was returned
2161  if (result == ERANGE && buflen < 512 * 1024)
2162  {
2163  dbus_free (buf);
2164  buflen *= 2;
2165  }
2166  else
2167  {
2168  break;
2169  }
2170  }
2171  if (result == 0 && p == &p_str)
2172  {
2173  if (!fill_user_info_from_passwd (p, info, error))
2174  {
2175  dbus_free (buf);
2176  return FALSE;
2177  }
2178  dbus_free (buf);
2179  }
2180  else
2181  {
2182  dbus_set_error (error, _dbus_error_from_errno (errno),
2183  "User \"%s\" unknown or no memory to allocate password entry\n",
2184  username_c ? username_c : "???");
2185  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2186  dbus_free (buf);
2187  return FALSE;
2188  }
2189  }
2190 #else /* ! HAVE_GETPWNAM_R */
2191  {
2192  /* I guess we're screwed on thread safety here */
2193  struct passwd *p;
2194 
2195  if (uid != DBUS_UID_UNSET)
2196  p = getpwuid (uid);
2197  else
2198  p = getpwnam (username_c);
2199 
2200  if (p != NULL)
2201  {
2202  if (!fill_user_info_from_passwd (p, info, error))
2203  {
2204  return FALSE;
2205  }
2206  }
2207  else
2208  {
2209  dbus_set_error (error, _dbus_error_from_errno (errno),
2210  "User \"%s\" unknown or no memory to allocate password entry\n",
2211  username_c ? username_c : "???");
2212  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2213  return FALSE;
2214  }
2215  }
2216 #endif /* ! HAVE_GETPWNAM_R */
2217 
2218  /* Fill this in so we can use it to get groups */
2219  username_c = info->username;
2220 
2221 #ifdef HAVE_GETGROUPLIST
2222  {
2223  gid_t *buf;
2224  int buf_count;
2225  int i;
2226  int initial_buf_count;
2227 
2228  initial_buf_count = 17;
2229  buf_count = initial_buf_count;
2230  buf = dbus_new (gid_t, buf_count);
2231  if (buf == NULL)
2232  {
2234  goto failed;
2235  }
2236 
2237  if (getgrouplist (username_c,
2238  info->primary_gid,
2239  buf, &buf_count) < 0)
2240  {
2241  gid_t *new;
2242  /* Presumed cause of negative return code: buf has insufficient
2243  entries to hold the entire group list. The Linux behavior in this
2244  case is to pass back the actual number of groups in buf_count, but
2245  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2246  So as a hack, try to help out a bit by guessing a larger
2247  number of groups, within reason.. might still fail, of course,
2248  but we can at least print a more informative message. I looked up
2249  the "right way" to do this by downloading Apple's own source code
2250  for the "id" command, and it turns out that they use an
2251  undocumented library function getgrouplist_2 (!) which is not
2252  declared in any header in /usr/include (!!). That did not seem
2253  like the way to go here.
2254  */
2255  if (buf_count == initial_buf_count)
2256  {
2257  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2258  }
2259  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2260  if (new == NULL)
2261  {
2263  dbus_free (buf);
2264  goto failed;
2265  }
2266 
2267  buf = new;
2268 
2269  errno = 0;
2270  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2271  {
2272  if (errno == 0)
2273  {
2274  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2275  username_c, buf_count, buf_count);
2276  }
2277  else
2278  {
2279  dbus_set_error (error,
2280  _dbus_error_from_errno (errno),
2281  "Failed to get groups for username \"%s\" primary GID "
2282  DBUS_GID_FORMAT ": %s\n",
2283  username_c, info->primary_gid,
2284  _dbus_strerror (errno));
2285  dbus_free (buf);
2286  goto failed;
2287  }
2288  }
2289  }
2290 
2291  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2292  if (info->group_ids == NULL)
2293  {
2295  dbus_free (buf);
2296  goto failed;
2297  }
2298 
2299  for (i = 0; i < buf_count; ++i)
2300  info->group_ids[i] = buf[i];
2301 
2302  info->n_group_ids = buf_count;
2303 
2304  dbus_free (buf);
2305  }
2306 #else /* HAVE_GETGROUPLIST */
2307  {
2308  /* We just get the one group ID */
2309  info->group_ids = dbus_new (dbus_gid_t, 1);
2310  if (info->group_ids == NULL)
2311  {
2313  goto failed;
2314  }
2315 
2316  info->n_group_ids = 1;
2317 
2318  (info->group_ids)[0] = info->primary_gid;
2319  }
2320 #endif /* HAVE_GETGROUPLIST */
2321 
2322  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2323 
2324  return TRUE;
2325 
2326  failed:
2327  _DBUS_ASSERT_ERROR_IS_SET (error);
2328  return FALSE;
2329 }
2330 
2341  const DBusString *username,
2342  DBusError *error)
2343 {
2344  return fill_user_info (info, DBUS_UID_UNSET,
2345  username, error);
2346 }
2347 
2358  dbus_uid_t uid,
2359  DBusError *error)
2360 {
2361  return fill_user_info (info, uid,
2362  NULL, error);
2363 }
2364 
2374 {
2375  /* The POSIX spec certainly doesn't promise this, but
2376  * we need these assertions to fail as soon as we're wrong about
2377  * it so we can do the porting fixups
2378  */
2379  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2380  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2381  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2382 
2383  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2384  return FALSE;
2385  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2386  return FALSE;
2387 
2388  return TRUE;
2389 }
2390 
2404 {
2405  return _dbus_string_append_uint (str,
2406  _dbus_geteuid ());
2407 }
2408 
2413 dbus_pid_t
2415 {
2416  return getpid ();
2417 }
2418 
2422 dbus_uid_t
2424 {
2425  return getuid ();
2426 }
2427 
2431 dbus_uid_t
2433 {
2434  return geteuid ();
2435 }
2436 
2443 unsigned long
2445 {
2446  return getpid ();
2447 }
2448 
2457 _dbus_parse_uid (const DBusString *uid_str,
2458  dbus_uid_t *uid)
2459 {
2460  int end;
2461  long val;
2462 
2463  if (_dbus_string_get_length (uid_str) == 0)
2464  {
2465  _dbus_verbose ("UID string was zero length\n");
2466  return FALSE;
2467  }
2468 
2469  val = -1;
2470  end = 0;
2471  if (!_dbus_string_parse_int (uid_str, 0, &val,
2472  &end))
2473  {
2474  _dbus_verbose ("could not parse string as a UID\n");
2475  return FALSE;
2476  }
2477 
2478  if (end != _dbus_string_get_length (uid_str))
2479  {
2480  _dbus_verbose ("string contained trailing stuff after UID\n");
2481  return FALSE;
2482  }
2483 
2484  *uid = val;
2485 
2486  return TRUE;
2487 }
2488 
2489 #if !DBUS_USE_SYNC
2490 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2491 #endif
2492 
2499 dbus_int32_t
2501 {
2502 #if DBUS_USE_SYNC
2503  return __sync_add_and_fetch(&atomic->value, 1)-1;
2504 #else
2505  dbus_int32_t res;
2506  _DBUS_LOCK (atomic);
2507  res = atomic->value;
2508  atomic->value += 1;
2509  _DBUS_UNLOCK (atomic);
2510  return res;
2511 #endif
2512 }
2513 
2520 dbus_int32_t
2522 {
2523 #if DBUS_USE_SYNC
2524  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2525 #else
2526  dbus_int32_t res;
2527 
2528  _DBUS_LOCK (atomic);
2529  res = atomic->value;
2530  atomic->value -= 1;
2531  _DBUS_UNLOCK (atomic);
2532  return res;
2533 #endif
2534 }
2535 
2543 dbus_int32_t
2545 {
2546 #if DBUS_USE_SYNC
2547  __sync_synchronize ();
2548  return atomic->value;
2549 #else
2550  dbus_int32_t res;
2551 
2552  _DBUS_LOCK (atomic);
2553  res = atomic->value;
2554  _DBUS_UNLOCK (atomic);
2555  return res;
2556 #endif
2557 }
2558 
2567 int
2569  int n_fds,
2570  int timeout_milliseconds)
2571 {
2572 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2573  /* This big thing is a constant expression and should get optimized
2574  * out of existence. So it's more robust than a configure check at
2575  * no cost.
2576  */
2577  if (_DBUS_POLLIN == POLLIN &&
2578  _DBUS_POLLPRI == POLLPRI &&
2579  _DBUS_POLLOUT == POLLOUT &&
2580  _DBUS_POLLERR == POLLERR &&
2581  _DBUS_POLLHUP == POLLHUP &&
2582  _DBUS_POLLNVAL == POLLNVAL &&
2583  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2584  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2585  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2586  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2587  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2588  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2589  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2590  {
2591  return poll ((struct pollfd*) fds,
2592  n_fds,
2593  timeout_milliseconds);
2594  }
2595  else
2596  {
2597  /* We have to convert the DBusPollFD to an array of
2598  * struct pollfd, poll, and convert back.
2599  */
2600  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2601  return -1;
2602  }
2603 #else /* ! HAVE_POLL */
2604 
2605  fd_set read_set, write_set, err_set;
2606  int max_fd = 0;
2607  int i;
2608  struct timeval tv;
2609  int ready;
2610 
2611  FD_ZERO (&read_set);
2612  FD_ZERO (&write_set);
2613  FD_ZERO (&err_set);
2614 
2615  for (i = 0; i < n_fds; i++)
2616  {
2617  DBusPollFD *fdp = &fds[i];
2618 
2619  if (fdp->events & _DBUS_POLLIN)
2620  FD_SET (fdp->fd, &read_set);
2621 
2622  if (fdp->events & _DBUS_POLLOUT)
2623  FD_SET (fdp->fd, &write_set);
2624 
2625  FD_SET (fdp->fd, &err_set);
2626 
2627  max_fd = MAX (max_fd, fdp->fd);
2628  }
2629 
2630  tv.tv_sec = timeout_milliseconds / 1000;
2631  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2632 
2633  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2634  timeout_milliseconds < 0 ? NULL : &tv);
2635 
2636  if (ready > 0)
2637  {
2638  for (i = 0; i < n_fds; i++)
2639  {
2640  DBusPollFD *fdp = &fds[i];
2641 
2642  fdp->revents = 0;
2643 
2644  if (FD_ISSET (fdp->fd, &read_set))
2645  fdp->revents |= _DBUS_POLLIN;
2646 
2647  if (FD_ISSET (fdp->fd, &write_set))
2648  fdp->revents |= _DBUS_POLLOUT;
2649 
2650  if (FD_ISSET (fdp->fd, &err_set))
2651  fdp->revents |= _DBUS_POLLERR;
2652  }
2653  }
2654 
2655  return ready;
2656 #endif
2657 }
2658 
2666 void
2668  long *tv_usec)
2669 {
2670 #ifdef HAVE_MONOTONIC_CLOCK
2671  struct timespec ts;
2672  clock_gettime (CLOCK_MONOTONIC, &ts);
2673 
2674  if (tv_sec)
2675  *tv_sec = ts.tv_sec;
2676  if (tv_usec)
2677  *tv_usec = ts.tv_nsec / 1000;
2678 #else
2679  struct timeval t;
2680 
2681  gettimeofday (&t, NULL);
2682 
2683  if (tv_sec)
2684  *tv_sec = t.tv_sec;
2685  if (tv_usec)
2686  *tv_usec = t.tv_usec;
2687 #endif
2688 }
2689 
2697 void
2698 _dbus_get_real_time (long *tv_sec,
2699  long *tv_usec)
2700 {
2701  struct timeval t;
2702 
2703  gettimeofday (&t, NULL);
2704 
2705  if (tv_sec)
2706  *tv_sec = t.tv_sec;
2707  if (tv_usec)
2708  *tv_usec = t.tv_usec;
2709 }
2710 
2721  DBusError *error)
2722 {
2723  const char *filename_c;
2724 
2725  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2726 
2727  filename_c = _dbus_string_get_const_data (filename);
2728 
2729  if (mkdir (filename_c, 0700) < 0)
2730  {
2731  if (errno == EEXIST)
2732  return TRUE;
2733 
2735  "Failed to create directory %s: %s\n",
2736  filename_c, _dbus_strerror (errno));
2737  return FALSE;
2738  }
2739  else
2740  return TRUE;
2741 }
2742 
2755  const DBusString *next_component)
2756 {
2757  dbus_bool_t dir_ends_in_slash;
2758  dbus_bool_t file_starts_with_slash;
2759 
2760  if (_dbus_string_get_length (dir) == 0 ||
2761  _dbus_string_get_length (next_component) == 0)
2762  return TRUE;
2763 
2764  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2765  _dbus_string_get_length (dir) - 1);
2766 
2767  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2768 
2769  if (dir_ends_in_slash && file_starts_with_slash)
2770  {
2771  _dbus_string_shorten (dir, 1);
2772  }
2773  else if (!(dir_ends_in_slash || file_starts_with_slash))
2774  {
2775  if (!_dbus_string_append_byte (dir, '/'))
2776  return FALSE;
2777  }
2778 
2779  return _dbus_string_copy (next_component, 0, dir,
2780  _dbus_string_get_length (dir));
2781 }
2782 
2784 #define NANOSECONDS_PER_SECOND 1000000000
2785 
2786 #define MICROSECONDS_PER_SECOND 1000000
2787 
2788 #define MILLISECONDS_PER_SECOND 1000
2789 
2790 #define NANOSECONDS_PER_MILLISECOND 1000000
2791 
2792 #define MICROSECONDS_PER_MILLISECOND 1000
2793 
2798 void
2799 _dbus_sleep_milliseconds (int milliseconds)
2800 {
2801 #ifdef HAVE_NANOSLEEP
2802  struct timespec req;
2803  struct timespec rem;
2804 
2805  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2806  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2807  rem.tv_sec = 0;
2808  rem.tv_nsec = 0;
2809 
2810  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2811  req = rem;
2812 #elif defined (HAVE_USLEEP)
2813  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2814 #else /* ! HAVE_USLEEP */
2815  sleep (MAX (milliseconds / 1000, 1));
2816 #endif
2817 }
2818 
2819 static dbus_bool_t
2820 _dbus_generate_pseudorandom_bytes (DBusString *str,
2821  int n_bytes)
2822 {
2823  int old_len;
2824  char *p;
2825 
2826  old_len = _dbus_string_get_length (str);
2827 
2828  if (!_dbus_string_lengthen (str, n_bytes))
2829  return FALSE;
2830 
2831  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2832 
2834 
2835  return TRUE;
2836 }
2837 
2848  int n_bytes)
2849 {
2850  int old_len;
2851  int fd;
2852 
2853  /* FALSE return means "no memory", if it could
2854  * mean something else then we'd need to return
2855  * a DBusError. So we always fall back to pseudorandom
2856  * if the I/O fails.
2857  */
2858 
2859  old_len = _dbus_string_get_length (str);
2860  fd = -1;
2861 
2862  /* note, urandom on linux will fall back to pseudorandom */
2863  fd = open ("/dev/urandom", O_RDONLY);
2864  if (fd < 0)
2865  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2866 
2867  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2868 
2869  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2870  {
2871  _dbus_close (fd, NULL);
2872  _dbus_string_set_length (str, old_len);
2873  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2874  }
2875 
2876  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2877  n_bytes);
2878 
2879  _dbus_close (fd, NULL);
2880 
2881  return TRUE;
2882 }
2883 
2889 void
2890 _dbus_exit (int code)
2891 {
2892  _exit (code);
2893 }
2894 
2903 const char*
2904 _dbus_strerror (int error_number)
2905 {
2906  const char *msg;
2907 
2908  msg = strerror (error_number);
2909  if (msg == NULL)
2910  msg = "unknown";
2911 
2912  return msg;
2913 }
2914 
2918 void
2920 {
2921  signal (SIGPIPE, SIG_IGN);
2922 }
2923 
2931 void
2933 {
2934  int val;
2935 
2936  val = fcntl (fd, F_GETFD, 0);
2937 
2938  if (val < 0)
2939  return;
2940 
2941  val |= FD_CLOEXEC;
2942 
2943  fcntl (fd, F_SETFD, val);
2944 }
2945 
2954 _dbus_close (int fd,
2955  DBusError *error)
2956 {
2957  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2958 
2959  again:
2960  if (close (fd) < 0)
2961  {
2962  if (errno == EINTR)
2963  goto again;
2964 
2965  dbus_set_error (error, _dbus_error_from_errno (errno),
2966  "Could not close fd %d", fd);
2967  return FALSE;
2968  }
2969 
2970  return TRUE;
2971 }
2972 
2980 int
2981 _dbus_dup(int fd,
2982  DBusError *error)
2983 {
2984  int new_fd;
2985 
2986 #ifdef F_DUPFD_CLOEXEC
2987  dbus_bool_t cloexec_done;
2988 
2989  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2990  cloexec_done = new_fd >= 0;
2991 
2992  if (new_fd < 0 && errno == EINVAL)
2993 #endif
2994  {
2995  new_fd = fcntl(fd, F_DUPFD, 3);
2996  }
2997 
2998  if (new_fd < 0) {
2999 
3000  dbus_set_error (error, _dbus_error_from_errno (errno),
3001  "Could not duplicate fd %d", fd);
3002  return -1;
3003  }
3004 
3005 #ifdef F_DUPFD_CLOEXEC
3006  if (!cloexec_done)
3007 #endif
3008  {
3010  }
3011 
3012  return new_fd;
3013 }
3014 
3023 _dbus_set_fd_nonblocking (int fd,
3024  DBusError *error)
3025 {
3026  int val;
3027 
3028  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3029 
3030  val = fcntl (fd, F_GETFL, 0);
3031  if (val < 0)
3032  {
3033  dbus_set_error (error, _dbus_error_from_errno (errno),
3034  "Failed to get flags from file descriptor %d: %s",
3035  fd, _dbus_strerror (errno));
3036  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3037  _dbus_strerror (errno));
3038  return FALSE;
3039  }
3040 
3041  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3042  {
3043  dbus_set_error (error, _dbus_error_from_errno (errno),
3044  "Failed to set nonblocking flag of file descriptor %d: %s",
3045  fd, _dbus_strerror (errno));
3046  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3047  fd, _dbus_strerror (errno));
3048 
3049  return FALSE;
3050  }
3051 
3052  return TRUE;
3053 }
3054 
3060 void
3062 {
3063 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3064  void *bt[500];
3065  int bt_size;
3066  int i;
3067  char **syms;
3068 
3069  bt_size = backtrace (bt, 500);
3070 
3071  syms = backtrace_symbols (bt, bt_size);
3072 
3073  i = 0;
3074  while (i < bt_size)
3075  {
3076  /* don't use dbus_warn since it can _dbus_abort() */
3077  fprintf (stderr, " %s\n", syms[i]);
3078  ++i;
3079  }
3080  fflush (stderr);
3081 
3082  free (syms);
3083 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3084  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3085 #else
3086  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3087 #endif
3088 }
3089 
3104  int *fd2,
3105  dbus_bool_t blocking,
3106  DBusError *error)
3107 {
3108 #ifdef HAVE_SOCKETPAIR
3109  int fds[2];
3110  int retval;
3111 
3112 #ifdef SOCK_CLOEXEC
3113  dbus_bool_t cloexec_done;
3114 
3115  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3116  cloexec_done = retval >= 0;
3117 
3118  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3119 #endif
3120  {
3121  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3122  }
3123 
3124  if (retval < 0)
3125  {
3126  dbus_set_error (error, _dbus_error_from_errno (errno),
3127  "Could not create full-duplex pipe");
3128  return FALSE;
3129  }
3130 
3131  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3132 
3133 #ifdef SOCK_CLOEXEC
3134  if (!cloexec_done)
3135 #endif
3136  {
3137  _dbus_fd_set_close_on_exec (fds[0]);
3138  _dbus_fd_set_close_on_exec (fds[1]);
3139  }
3140 
3141  if (!blocking &&
3142  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3143  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3144  {
3145  dbus_set_error (error, _dbus_error_from_errno (errno),
3146  "Could not set full-duplex pipe nonblocking");
3147 
3148  _dbus_close (fds[0], NULL);
3149  _dbus_close (fds[1], NULL);
3150 
3151  return FALSE;
3152  }
3153 
3154  *fd1 = fds[0];
3155  *fd2 = fds[1];
3156 
3157  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3158  *fd1, *fd2);
3159 
3160  return TRUE;
3161 #else
3162  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3164  "_dbus_full_duplex_pipe() not implemented on this OS");
3165  return FALSE;
3166 #endif
3167 }
3168 
3177 int
3179  va_list args)
3180 {
3181  char static_buf[1024];
3182  int bufsize = sizeof (static_buf);
3183  int len;
3184  va_list args_copy;
3185 
3186  DBUS_VA_COPY (args_copy, args);
3187  len = vsnprintf (static_buf, bufsize, format, args_copy);
3188  va_end (args_copy);
3189 
3190  /* If vsnprintf() returned non-negative, then either the string fits in
3191  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3192  * returns the number of characters that were needed, or this OS returns the
3193  * truncated length.
3194  *
3195  * We ignore the possibility that snprintf might just ignore the length and
3196  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3197  * If your libc is really that bad, come back when you have a better one. */
3198  if (len == bufsize)
3199  {
3200  /* This could be the truncated length (Tru64 and IRIX have this bug),
3201  * or the real length could be coincidentally the same. Which is it?
3202  * If vsnprintf returns the truncated length, we'll go to the slow
3203  * path. */
3204  DBUS_VA_COPY (args_copy, args);
3205 
3206  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3207  len = -1;
3208 
3209  va_end (args_copy);
3210  }
3211 
3212  /* If vsnprintf() returned negative, we have to do more work.
3213  * HP-UX returns negative. */
3214  while (len < 0)
3215  {
3216  char *buf;
3217 
3218  bufsize *= 2;
3219 
3220  buf = dbus_malloc (bufsize);
3221 
3222  if (buf == NULL)
3223  return -1;
3224 
3225  DBUS_VA_COPY (args_copy, args);
3226  len = vsnprintf (buf, bufsize, format, args_copy);
3227  va_end (args_copy);
3228 
3229  dbus_free (buf);
3230 
3231  /* If the reported length is exactly the buffer size, round up to the
3232  * next size, in case vsnprintf has been returning the truncated
3233  * length */
3234  if (len == bufsize)
3235  len = -1;
3236  }
3237 
3238  return len;
3239 }
3240 
3247 const char*
3249 {
3250  static const char* tmpdir = NULL;
3251 
3252  if (tmpdir == NULL)
3253  {
3254  /* TMPDIR is what glibc uses, then
3255  * glibc falls back to the P_tmpdir macro which
3256  * just expands to "/tmp"
3257  */
3258  if (tmpdir == NULL)
3259  tmpdir = getenv("TMPDIR");
3260 
3261  /* These two env variables are probably
3262  * broken, but maybe some OS uses them?
3263  */
3264  if (tmpdir == NULL)
3265  tmpdir = getenv("TMP");
3266  if (tmpdir == NULL)
3267  tmpdir = getenv("TEMP");
3268 
3269  /* And this is the sane fallback. */
3270  if (tmpdir == NULL)
3271  tmpdir = "/tmp";
3272  }
3273 
3274  _dbus_assert(tmpdir != NULL);
3275 
3276  return tmpdir;
3277 }
3278 
3298 static dbus_bool_t
3299 _read_subprocess_line_argv (const char *progpath,
3300  dbus_bool_t path_fallback,
3301  char * const *argv,
3302  DBusString *result,
3303  DBusError *error)
3304 {
3305  int result_pipe[2] = { -1, -1 };
3306  int errors_pipe[2] = { -1, -1 };
3307  pid_t pid;
3308  int ret;
3309  int status;
3310  int orig_len;
3311 
3312  dbus_bool_t retval;
3313  sigset_t new_set, old_set;
3314 
3315  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3316  retval = FALSE;
3317 
3318  /* We need to block any existing handlers for SIGCHLD temporarily; they
3319  * will cause waitpid() below to fail.
3320  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3321  */
3322  sigemptyset (&new_set);
3323  sigaddset (&new_set, SIGCHLD);
3324  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3325 
3326  orig_len = _dbus_string_get_length (result);
3327 
3328 #define READ_END 0
3329 #define WRITE_END 1
3330  if (pipe (result_pipe) < 0)
3331  {
3332  dbus_set_error (error, _dbus_error_from_errno (errno),
3333  "Failed to create a pipe to call %s: %s",
3334  progpath, _dbus_strerror (errno));
3335  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3336  progpath, _dbus_strerror (errno));
3337  goto out;
3338  }
3339  if (pipe (errors_pipe) < 0)
3340  {
3341  dbus_set_error (error, _dbus_error_from_errno (errno),
3342  "Failed to create a pipe to call %s: %s",
3343  progpath, _dbus_strerror (errno));
3344  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3345  progpath, _dbus_strerror (errno));
3346  goto out;
3347  }
3348 
3349  pid = fork ();
3350  if (pid < 0)
3351  {
3352  dbus_set_error (error, _dbus_error_from_errno (errno),
3353  "Failed to fork() to call %s: %s",
3354  progpath, _dbus_strerror (errno));
3355  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3356  progpath, _dbus_strerror (errno));
3357  goto out;
3358  }
3359 
3360  if (pid == 0)
3361  {
3362  /* child process */
3363  int fd;
3364 
3365  fd = open ("/dev/null", O_RDWR);
3366  if (fd == -1)
3367  /* huh?! can't open /dev/null? */
3368  _exit (1);
3369 
3370  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3371 
3372  /* set-up stdXXX */
3373  close (result_pipe[READ_END]);
3374  close (errors_pipe[READ_END]);
3375  close (0); /* close stdin */
3376  close (1); /* close stdout */
3377  close (2); /* close stderr */
3378 
3379  if (dup2 (fd, 0) == -1)
3380  _exit (1);
3381  if (dup2 (result_pipe[WRITE_END], 1) == -1)
3382  _exit (1);
3383  if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3384  _exit (1);
3385 
3386  _dbus_close_all ();
3387 
3388  sigprocmask (SIG_SETMASK, &old_set, NULL);
3389 
3390  /* If it looks fully-qualified, try execv first */
3391  if (progpath[0] == '/')
3392  {
3393  execv (progpath, argv);
3394  /* Ok, that failed. Now if path_fallback is given, let's
3395  * try unqualified. This is mostly a hack to work
3396  * around systems which ship dbus-launch in /usr/bin
3397  * but everything else in /bin (because dbus-launch
3398  * depends on X11).
3399  */
3400  if (path_fallback)
3401  /* We must have a slash, because we checked above */
3402  execvp (strrchr (progpath, '/')+1, argv);
3403  }
3404  else
3405  execvp (progpath, argv);
3406 
3407  /* still nothing, we failed */
3408  _exit (1);
3409  }
3410 
3411  /* parent process */
3412  close (result_pipe[WRITE_END]);
3413  close (errors_pipe[WRITE_END]);
3414  result_pipe[WRITE_END] = -1;
3415  errors_pipe[WRITE_END] = -1;
3416 
3417  ret = 0;
3418  do
3419  {
3420  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3421  }
3422  while (ret > 0);
3423 
3424  /* reap the child process to avoid it lingering as zombie */
3425  do
3426  {
3427  ret = waitpid (pid, &status, 0);
3428  }
3429  while (ret == -1 && errno == EINTR);
3430 
3431  /* We succeeded if the process exited with status 0 and
3432  anything was read */
3433  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3434  {
3435  /* The process ended with error */
3436  DBusString error_message;
3437  if (!_dbus_string_init (&error_message))
3438  {
3439  _DBUS_SET_OOM (error);
3440  goto out;
3441  }
3442 
3443  ret = 0;
3444  do
3445  {
3446  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3447  }
3448  while (ret > 0);
3449 
3450  _dbus_string_set_length (result, orig_len);
3451  if (_dbus_string_get_length (&error_message) > 0)
3453  "%s terminated abnormally with the following error: %s",
3454  progpath, _dbus_string_get_data (&error_message));
3455  else
3457  "%s terminated abnormally without any error message",
3458  progpath);
3459  goto out;
3460  }
3461 
3462  retval = TRUE;
3463 
3464  out:
3465  sigprocmask (SIG_SETMASK, &old_set, NULL);
3466 
3467  if (retval)
3468  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3469  else
3470  _DBUS_ASSERT_ERROR_IS_SET (error);
3471 
3472  if (result_pipe[0] != -1)
3473  close (result_pipe[0]);
3474  if (result_pipe[1] != -1)
3475  close (result_pipe[1]);
3476  if (errors_pipe[0] != -1)
3477  close (errors_pipe[0]);
3478  if (errors_pipe[1] != -1)
3479  close (errors_pipe[1]);
3480 
3481  return retval;
3482 }
3483 
3496 _dbus_get_autolaunch_address (const char *scope,
3497  DBusString *address,
3498  DBusError *error)
3499 {
3500 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3501  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3502  * but that's done elsewhere, and if it worked, this function wouldn't
3503  * be called.) */
3504  const char *display;
3505  static char *argv[6];
3506  int i;
3507  DBusString uuid;
3508  dbus_bool_t retval;
3509 
3510  if (_dbus_check_setuid ())
3511  {
3513  "Unable to autolaunch when setuid");
3514  return FALSE;
3515  }
3516 
3517  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3518  retval = FALSE;
3519 
3520  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3521  * dbus-launch-x11 is just going to fail. Rather than trying to
3522  * run it, we might as well bail out early with a nice error. */
3523  display = _dbus_getenv ("DISPLAY");
3524 
3525  if (display == NULL || display[0] == '\0')
3526  {
3528  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3529  return FALSE;
3530  }
3531 
3532  if (!_dbus_string_init (&uuid))
3533  {
3534  _DBUS_SET_OOM (error);
3535  return FALSE;
3536  }
3537 
3539  {
3540  _DBUS_SET_OOM (error);
3541  goto out;
3542  }
3543 
3544  i = 0;
3545  argv[i] = "dbus-launch";
3546  ++i;
3547  argv[i] = "--autolaunch";
3548  ++i;
3549  argv[i] = _dbus_string_get_data (&uuid);
3550  ++i;
3551  argv[i] = "--binary-syntax";
3552  ++i;
3553  argv[i] = "--close-stderr";
3554  ++i;
3555  argv[i] = NULL;
3556  ++i;
3557 
3558  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3559 
3560  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3561  TRUE,
3562  argv, address, error);
3563 
3564  out:
3565  _dbus_string_free (&uuid);
3566  return retval;
3567 #else
3569  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3570  "set your DBUS_SESSION_BUS_ADDRESS instead");
3571  return FALSE;
3572 #endif
3573 }
3574 
3595  dbus_bool_t create_if_not_found,
3596  DBusError *error)
3597 {
3598  DBusString filename;
3599  dbus_bool_t b;
3600 
3601  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3602 
3603  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3604  if (b)
3605  return TRUE;
3606 
3607  dbus_error_free (error);
3608 
3609  /* Fallback to the system machine ID */
3610  _dbus_string_init_const (&filename, "/etc/machine-id");
3611  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3612 }
3613 
3614 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3615 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3616 
3625  const char *launchd_env_var,
3626  DBusError *error)
3627 {
3628 #ifdef DBUS_ENABLE_LAUNCHD
3629  char *argv[4];
3630  int i;
3631 
3632  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3633 
3634  if (_dbus_check_setuid ())
3635  {
3637  "Unable to find launchd socket when setuid");
3638  return FALSE;
3639  }
3640 
3641  i = 0;
3642  argv[i] = "launchctl";
3643  ++i;
3644  argv[i] = "getenv";
3645  ++i;
3646  argv[i] = (char*)launchd_env_var;
3647  ++i;
3648  argv[i] = NULL;
3649  ++i;
3650 
3651  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3652 
3653  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3654  {
3655  return FALSE;
3656  }
3657 
3658  /* no error, but no result either */
3659  if (_dbus_string_get_length(socket_path) == 0)
3660  {
3661  return FALSE;
3662  }
3663 
3664  /* strip the carriage-return */
3665  _dbus_string_shorten(socket_path, 1);
3666  return TRUE;
3667 #else /* DBUS_ENABLE_LAUNCHD */
3669  "can't lookup socket from launchd; launchd support not compiled in");
3670  return FALSE;
3671 #endif
3672 }
3673 
3674 #ifdef DBUS_ENABLE_LAUNCHD
3675 static dbus_bool_t
3676 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3677 {
3678  dbus_bool_t valid_socket;
3679  DBusString socket_path;
3680 
3681  if (_dbus_check_setuid ())
3682  {
3684  "Unable to find launchd socket when setuid");
3685  return FALSE;
3686  }
3687 
3688  if (!_dbus_string_init (&socket_path))
3689  {
3690  _DBUS_SET_OOM (error);
3691  return FALSE;
3692  }
3693 
3694  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3695 
3696  if (dbus_error_is_set(error))
3697  {
3698  _dbus_string_free(&socket_path);
3699  return FALSE;
3700  }
3701 
3702  if (!valid_socket)
3703  {
3704  dbus_set_error(error, "no socket path",
3705  "launchd did not provide a socket path, "
3706  "verify that org.freedesktop.dbus-session.plist is loaded!");
3707  _dbus_string_free(&socket_path);
3708  return FALSE;
3709  }
3710  if (!_dbus_string_append (address, "unix:path="))
3711  {
3712  _DBUS_SET_OOM (error);
3713  _dbus_string_free(&socket_path);
3714  return FALSE;
3715  }
3716  if (!_dbus_string_copy (&socket_path, 0, address,
3717  _dbus_string_get_length (address)))
3718  {
3719  _DBUS_SET_OOM (error);
3720  _dbus_string_free(&socket_path);
3721  return FALSE;
3722  }
3723 
3724  _dbus_string_free(&socket_path);
3725  return TRUE;
3726 }
3727 #endif
3728 
3750  DBusString *address,
3751  DBusError *error)
3752 {
3753 #ifdef DBUS_ENABLE_LAUNCHD
3754  *supported = TRUE;
3755  return _dbus_lookup_session_address_launchd (address, error);
3756 #else
3757  /* On non-Mac Unix platforms, if the session address isn't already
3758  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3759  * fall back to the autolaunch: global default; see
3760  * init_session_address in dbus/dbus-bus.c. */
3761  *supported = FALSE;
3762  return TRUE;
3763 #endif
3764 }
3765 
3785 {
3786  const char *xdg_data_home;
3787  const char *xdg_data_dirs;
3788  DBusString servicedir_path;
3789 
3790  if (!_dbus_string_init (&servicedir_path))
3791  return FALSE;
3792 
3793  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3794  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3795 
3796  if (xdg_data_home != NULL)
3797  {
3798  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3799  goto oom;
3800  }
3801  else
3802  {
3803  const DBusString *homedir;
3804  DBusString local_share;
3805 
3806  if (!_dbus_homedir_from_current_process (&homedir))
3807  goto oom;
3808 
3809  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3810  goto oom;
3811 
3812  _dbus_string_init_const (&local_share, "/.local/share");
3813  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3814  goto oom;
3815  }
3816 
3817  if (!_dbus_string_append (&servicedir_path, ":"))
3818  goto oom;
3819 
3820  if (xdg_data_dirs != NULL)
3821  {
3822  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3823  goto oom;
3824 
3825  if (!_dbus_string_append (&servicedir_path, ":"))
3826  goto oom;
3827  }
3828  else
3829  {
3830  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3831  goto oom;
3832  }
3833 
3834  /*
3835  * add configured datadir to defaults
3836  * this may be the same as an xdg dir
3837  * however the config parser should take
3838  * care of duplicates
3839  */
3840  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3841  goto oom;
3842 
3843  if (!_dbus_split_paths_and_append (&servicedir_path,
3844  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3845  dirs))
3846  goto oom;
3847 
3848  _dbus_string_free (&servicedir_path);
3849  return TRUE;
3850 
3851  oom:
3852  _dbus_string_free (&servicedir_path);
3853  return FALSE;
3854 }
3855 
3856 
3877 {
3878  /*
3879  * DBUS_DATADIR may be the same as one of the standard directories. However,
3880  * the config parser should take care of the duplicates.
3881  *
3882  * Also, append /lib as counterpart of /usr/share on the root
3883  * directory (the root directory does not know /share), in order to
3884  * facilitate early boot system bus activation where /usr might not
3885  * be available.
3886  */
3887  static const char standard_search_path[] =
3888  "/usr/local/share:"
3889  "/usr/share:"
3890  DBUS_DATADIR ":"
3891  "/lib";
3892  DBusString servicedir_path;
3893 
3894  _dbus_string_init_const (&servicedir_path, standard_search_path);
3895 
3896  return _dbus_split_paths_and_append (&servicedir_path,
3897  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3898  dirs);
3899 }
3900 
3911 {
3912  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3913 }
3914 
3923 {
3924  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3925 }
3926 
3934 void
3936 {
3938 }
3939 
3955  DBusCredentials *credentials)
3956 {
3957  DBusString homedir;
3958  DBusString dotdir;
3959  dbus_uid_t uid;
3960 
3961  _dbus_assert (credentials != NULL);
3963 
3964  if (!_dbus_string_init (&homedir))
3965  return FALSE;
3966 
3967  uid = _dbus_credentials_get_unix_uid (credentials);
3968  _dbus_assert (uid != DBUS_UID_UNSET);
3969 
3970  if (!_dbus_homedir_from_uid (uid, &homedir))
3971  goto failed;
3972 
3973 #ifdef DBUS_BUILD_TESTS
3974  {
3975  const char *override;
3976 
3977  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3978  if (override != NULL && *override != '\0')
3979  {
3980  _dbus_string_set_length (&homedir, 0);
3981  if (!_dbus_string_append (&homedir, override))
3982  goto failed;
3983 
3984  _dbus_verbose ("Using fake homedir for testing: %s\n",
3985  _dbus_string_get_const_data (&homedir));
3986  }
3987  else
3988  {
3989  static dbus_bool_t already_warned = FALSE;
3990  if (!already_warned)
3991  {
3992  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3993  already_warned = TRUE;
3994  }
3995  }
3996  }
3997 #endif
3998 
3999  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4000  if (!_dbus_concat_dir_and_file (&homedir,
4001  &dotdir))
4002  goto failed;
4003 
4004  if (!_dbus_string_copy (&homedir, 0,
4005  directory, _dbus_string_get_length (directory))) {
4006  goto failed;
4007  }
4008 
4009  _dbus_string_free (&homedir);
4010  return TRUE;
4011 
4012  failed:
4013  _dbus_string_free (&homedir);
4014  return FALSE;
4015 }
4016 
4017 //PENDING(kdab) docs
4019 _dbus_daemon_publish_session_bus_address (const char* addr,
4020  const char *scope)
4021 {
4022  return TRUE;
4023 }
4024 
4025 //PENDING(kdab) docs
4026 void
4027 _dbus_daemon_unpublish_session_bus_address (void)
4028 {
4029 
4030 }
4031 
4040 {
4041  return errno == EAGAIN || errno == EWOULDBLOCK;
4042 }
4043 
4053  DBusError *error)
4054 {
4055  const char *filename_c;
4056 
4057  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4058 
4059  filename_c = _dbus_string_get_const_data (filename);
4060 
4061  if (rmdir (filename_c) != 0)
4062  {
4064  "Failed to remove directory %s: %s\n",
4065  filename_c, _dbus_strerror (errno));
4066  return FALSE;
4067  }
4068 
4069  return TRUE;
4070 }
4071 
4081 
4082 #ifdef SCM_RIGHTS
4083  union {
4084  struct sockaddr sa;
4085  struct sockaddr_storage storage;
4086  struct sockaddr_un un;
4087  } sa_buf;
4088 
4089  socklen_t sa_len = sizeof(sa_buf);
4090 
4091  _DBUS_ZERO(sa_buf);
4092 
4093  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4094  return FALSE;
4095 
4096  return sa_buf.sa.sa_family == AF_UNIX;
4097 
4098 #else
4099  return FALSE;
4100 
4101 #endif
4102 }
4103 
4104 
4105 /*
4106  * replaces the term DBUS_PREFIX in configure_time_path by the
4107  * current dbus installation directory. On unix this function is a noop
4108  *
4109  * @param configure_time_path
4110  * @return real path
4111  */
4112 const char *
4113 _dbus_replace_install_prefix (const char *configure_time_path)
4114 {
4115  return configure_time_path;
4116 }
4117 
4122 void
4124 {
4125  int maxfds, i;
4126 
4127 #ifdef __linux__
4128  DIR *d;
4129 
4130  /* On Linux we can optimize this a bit if /proc is available. If it
4131  isn't available, fall back to the brute force way. */
4132 
4133  d = opendir ("/proc/self/fd");
4134  if (d)
4135  {
4136  for (;;)
4137  {
4138  struct dirent buf, *de;
4139  int k, fd;
4140  long l;
4141  char *e = NULL;
4142 
4143  k = readdir_r (d, &buf, &de);
4144  if (k != 0 || !de)
4145  break;
4146 
4147  if (de->d_name[0] == '.')
4148  continue;
4149 
4150  errno = 0;
4151  l = strtol (de->d_name, &e, 10);
4152  if (errno != 0 || e == NULL || *e != '\0')
4153  continue;
4154 
4155  fd = (int) l;
4156  if (fd < 3)
4157  continue;
4158 
4159  if (fd == dirfd (d))
4160  continue;
4161 
4162  close (fd);
4163  }
4164 
4165  closedir (d);
4166  return;
4167  }
4168 #endif
4169 
4170  maxfds = sysconf (_SC_OPEN_MAX);
4171 
4172  /* Pick something reasonable if for some reason sysconf says
4173  * unlimited.
4174  */
4175  if (maxfds < 0)
4176  maxfds = 1024;
4177 
4178  /* close all inherited fds */
4179  for (i = 3; i < maxfds; i++)
4180  close (i);
4181 }
4182 
4194 {
4195  /* TODO: get __libc_enable_secure exported from glibc.
4196  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4197  */
4198 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4199  {
4200  /* See glibc/include/unistd.h */
4201  extern int __libc_enable_secure;
4202  return __libc_enable_secure;
4203  }
4204 #elif defined(HAVE_ISSETUGID)
4205  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4206  return issetugid ();
4207 #else
4208  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4209  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4210 
4211  static dbus_bool_t check_setuid_initialised;
4212  static dbus_bool_t is_setuid;
4213 
4214  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4215  {
4216 #ifdef HAVE_GETRESUID
4217  if (getresuid (&ruid, &euid, &suid) != 0 ||
4218  getresgid (&rgid, &egid, &sgid) != 0)
4219 #endif /* HAVE_GETRESUID */
4220  {
4221  suid = ruid = getuid ();
4222  sgid = rgid = getgid ();
4223  euid = geteuid ();
4224  egid = getegid ();
4225  }
4226 
4227  check_setuid_initialised = TRUE;
4228  is_setuid = (ruid != euid || ruid != suid ||
4229  rgid != egid || rgid != sgid);
4230 
4231  }
4232  return is_setuid;
4233 #endif
4234 }
4235 
4236 /* 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:921
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:433
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:229
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:390
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_append_system_config_file(DBusString *str)
Append the absolute path of the system.conf file (there is no system bus on Windows so this can just ...
#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:234
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:291
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:600
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:746
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd)
Checks whether file descriptors may be passed via the socket.
#define _DBUS_POLLNVAL
Invalid request: fd not open.
Definition: dbus-sysdeps.h:293
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 ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:116
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:112
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_full_duplex_pipe(int *fd1, int *fd2, dbus_bool_t blocking, DBusError *error)
Creates a full-duplex pipe (as in socketpair()).
int _dbus_write_socket_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_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:346
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t _dbus_get_standard_session_servicedirs(DBusList **dirs)
Returns the standard directories for a session bus to look for service activation files...
dbus_gid_t primary_gid
GID.
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h:285
int _dbus_read_socket_with_unix_fds(int fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
A portable struct pollfd wrapper.
Definition: dbus-sysdeps.h:299
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
int _dbus_accept(int listen_fd)
Accepts a connection on a listening socket.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:283
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:476
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:766
short events
Events to poll for.
Definition: dbus-sysdeps.h:302
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1288
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:105
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:107
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:183
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str)
Gets the hex-encoded UUID of the machine this function is executed on.
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:612
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:447
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:98
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
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_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:460
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
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_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:287
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
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.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
#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.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int fd
File descriptor.
Definition: dbus-sysdeps.h:301
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
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. ...
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:1162
#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:242
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:109
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".
#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:808
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:114
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.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
dbus_bool_t _dbus_homedir_from_current_process(const DBusString **homedir)
Gets homedir of user owning current process.
Definition: dbus-userdb.c:386
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_generate_pseudorandom_bytes_buffer(char *buffer, int n_bytes)
Random numbers.
Definition: dbus-sysdeps.c:506
int _dbus_write_socket(int fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
A node in a linked list.
Definition: dbus-list.h:34
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_split_paths_and_append(DBusString *dirs, const char *suffix, DBusList **dir_list)
Split paths into a list of char strings.
Definition: dbus-sysdeps.c:224
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(void)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
#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_credentials_add_unix_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#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're running on from the dbus configuration.
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:788
#define _DBUS_LOCK(name)
Locks a global lock.
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.
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:810
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:102
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_append_session_config_file(DBusString *str)
Append the absolute path of the session.conf file.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:100
short revents
Events that occurred.
Definition: dbus-sysdeps.h:303
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_get_standard_system_servicedirs(DBusList **dirs)
Returns the standard directories for a system bus to look for service activation files.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
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_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.
int _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.
int _dbus_listen_systemd_sockets(int **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:289