D-Bus  1.8.12
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 #include <arpa/inet.h>
59 
60 #ifdef HAVE_ERRNO_H
61 #include <errno.h>
62 #endif
63 #ifdef HAVE_WRITEV
64 #include <sys/uio.h>
65 #endif
66 #ifdef HAVE_POLL
67 #include <sys/poll.h>
68 #endif
69 #ifdef HAVE_BACKTRACE
70 #include <execinfo.h>
71 #endif
72 #ifdef HAVE_GETPEERUCRED
73 #include <ucred.h>
74 #endif
75 #ifdef HAVE_ALLOCA_H
76 #include <alloca.h>
77 #endif
78 
79 #ifdef HAVE_ADT
80 #include <bsm/adt.h>
81 #endif
82 
83 #include "sd-daemon.h"
84 
85 #if !DBUS_USE_SYNC
86 #include <pthread.h>
87 #endif
88 
89 #ifndef O_BINARY
90 #define O_BINARY 0
91 #endif
92 
93 #ifndef AI_ADDRCONFIG
94 #define AI_ADDRCONFIG 0
95 #endif
96 
97 #ifndef HAVE_SOCKLEN_T
98 #define socklen_t int
99 #endif
100 
101 #if defined (__sun) || defined (__sun__)
102 /*
103  * CMS_SPACE etc. definitions for Solaris < 10, based on
104  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
105  * via
106  * http://wiki.opencsw.org/porting-faq#toc10
107  *
108  * These are only redefined for Solaris, for now: if your OS needs these too,
109  * please file a bug. (Or preferably, improve your OS so they're not needed.)
110  */
111 
112 # ifndef CMSG_ALIGN
113 # ifdef __sun__
114 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
115 # else
116  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
117 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
118  ~(sizeof (long) - 1))
119 # endif
120 # endif
121 
122 # ifndef CMSG_SPACE
123 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
124  CMSG_ALIGN (len))
125 # endif
126 
127 # ifndef CMSG_LEN
128 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
129 # endif
130 
131 #endif /* Solaris */
132 
133 static dbus_bool_t
134 _dbus_open_socket (int *fd_p,
135  int domain,
136  int type,
137  int protocol,
138  DBusError *error)
139 {
140 #ifdef SOCK_CLOEXEC
141  dbus_bool_t cloexec_done;
142 
143  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
144  cloexec_done = *fd_p >= 0;
145 
146  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
147  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
148 #endif
149  {
150  *fd_p = socket (domain, type, protocol);
151  }
152 
153  if (*fd_p >= 0)
154  {
155 #ifdef SOCK_CLOEXEC
156  if (!cloexec_done)
157 #endif
158  {
160  }
161 
162  _dbus_verbose ("socket fd %d opened\n", *fd_p);
163  return TRUE;
164  }
165  else
166  {
167  dbus_set_error(error,
168  _dbus_error_from_errno (errno),
169  "Failed to open socket: %s",
170  _dbus_strerror (errno));
171  return FALSE;
172  }
173 }
174 
185 static dbus_bool_t
186 _dbus_open_unix_socket (int *fd,
187  DBusError *error)
188 {
189  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
190 }
191 
202  DBusError *error)
203 {
204  return _dbus_close (fd, error);
205 }
206 
216 int
218  DBusString *buffer,
219  int count)
220 {
221  return _dbus_read (fd, buffer, count);
222 }
223 
234 int
236  const DBusString *buffer,
237  int start,
238  int len)
239 {
240 #if HAVE_DECL_MSG_NOSIGNAL
241  const char *data;
242  int bytes_written;
243 
244  data = _dbus_string_get_const_data_len (buffer, start, len);
245 
246  again:
247 
248  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
249 
250  if (bytes_written < 0 && errno == EINTR)
251  goto again;
252 
253  return bytes_written;
254 
255 #else
256  return _dbus_write (fd, buffer, start, len);
257 #endif
258 }
259 
272 int
274  DBusString *buffer,
275  int count,
276  int *fds,
277  int *n_fds) {
278 #ifndef HAVE_UNIX_FD_PASSING
279  int r;
280 
281  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
282  return r;
283 
284  *n_fds = 0;
285  return r;
286 
287 #else
288  int bytes_read;
289  int start;
290  struct msghdr m;
291  struct iovec iov;
292 
293  _dbus_assert (count >= 0);
294  _dbus_assert (*n_fds >= 0);
295 
296  start = _dbus_string_get_length (buffer);
297 
298  if (!_dbus_string_lengthen (buffer, count))
299  {
300  errno = ENOMEM;
301  return -1;
302  }
303 
304  _DBUS_ZERO(iov);
305  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
306  iov.iov_len = count;
307 
308  _DBUS_ZERO(m);
309  m.msg_iov = &iov;
310  m.msg_iovlen = 1;
311 
312  /* Hmm, we have no clue how long the control data will actually be
313  that is queued for us. The least we can do is assume that the
314  caller knows. Hence let's make space for the number of fds that
315  we shall read at max plus the cmsg header. */
316  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
317 
318  /* It's probably safe to assume that systems with SCM_RIGHTS also
319  know alloca() */
320  m.msg_control = alloca(m.msg_controllen);
321  memset(m.msg_control, 0, m.msg_controllen);
322 
323  /* Do not include the padding at the end when we tell the kernel
324  * how much we're willing to receive. This avoids getting
325  * the padding filled with additional fds that we weren't expecting,
326  * if a (potentially malicious) sender included them. (fd.o #83622) */
327  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
328 
329  again:
330 
331  bytes_read = recvmsg(fd, &m, 0
332 #ifdef MSG_CMSG_CLOEXEC
333  |MSG_CMSG_CLOEXEC
334 #endif
335  );
336 
337  if (bytes_read < 0)
338  {
339  if (errno == EINTR)
340  goto again;
341  else
342  {
343  /* put length back (note that this doesn't actually realloc anything) */
344  _dbus_string_set_length (buffer, start);
345  return -1;
346  }
347  }
348  else
349  {
350  struct cmsghdr *cm;
351  dbus_bool_t found = FALSE;
352 
353  if (m.msg_flags & MSG_CTRUNC)
354  {
355  /* Hmm, apparently the control data was truncated. The bad
356  thing is that we might have completely lost a couple of fds
357  without chance to recover them. Hence let's treat this as a
358  serious error. */
359 
360  errno = ENOSPC;
361  _dbus_string_set_length (buffer, start);
362  return -1;
363  }
364 
365  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
366  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
367  {
368  size_t i;
369  int *payload = (int *) CMSG_DATA (cm);
370  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
371  size_t payload_len_fds = payload_len_bytes / sizeof (int);
372  size_t fds_to_use;
373 
374  /* Every non-negative int fits in a size_t without truncation,
375  * and we already know that *n_fds is non-negative, so
376  * casting (size_t) *n_fds is OK */
377  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
378 
379  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
380  {
381  /* The fds in the payload will fit in our buffer */
382  fds_to_use = payload_len_fds;
383  }
384  else
385  {
386  /* Too many fds in the payload. This shouldn't happen
387  * any more because we're setting m.msg_controllen to
388  * the exact number we can accept, but be safe and
389  * truncate. */
390  fds_to_use = (size_t) *n_fds;
391 
392  /* Close the excess fds to avoid DoS: if they stayed open,
393  * someone could send us an extra fd per message
394  * and we'd eventually run out. */
395  for (i = fds_to_use; i < payload_len_fds; i++)
396  {
397  close (payload[i]);
398  }
399  }
400 
401  memcpy (fds, payload, fds_to_use * sizeof (int));
402  found = TRUE;
403  /* This cannot overflow because we have chosen fds_to_use
404  * to be <= *n_fds */
405  *n_fds = (int) fds_to_use;
406 
407  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
408  worked, hence we need to go through this list and set
409  CLOEXEC everywhere in any case */
410  for (i = 0; i < fds_to_use; i++)
412 
413  break;
414  }
415 
416  if (!found)
417  *n_fds = 0;
418 
419  /* put length back (doesn't actually realloc) */
420  _dbus_string_set_length (buffer, start + bytes_read);
421 
422 #if 0
423  if (bytes_read > 0)
424  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
425 #endif
426 
427  return bytes_read;
428  }
429 #endif
430 }
431 
432 int
433 _dbus_write_socket_with_unix_fds(int fd,
434  const DBusString *buffer,
435  int start,
436  int len,
437  const int *fds,
438  int n_fds) {
439 
440 #ifndef HAVE_UNIX_FD_PASSING
441 
442  if (n_fds > 0) {
443  errno = ENOTSUP;
444  return -1;
445  }
446 
447  return _dbus_write_socket(fd, buffer, start, len);
448 #else
449  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
450 #endif
451 }
452 
453 int
454 _dbus_write_socket_with_unix_fds_two(int fd,
455  const DBusString *buffer1,
456  int start1,
457  int len1,
458  const DBusString *buffer2,
459  int start2,
460  int len2,
461  const int *fds,
462  int n_fds) {
463 
464 #ifndef HAVE_UNIX_FD_PASSING
465 
466  if (n_fds > 0) {
467  errno = ENOTSUP;
468  return -1;
469  }
470 
471  return _dbus_write_socket_two(fd,
472  buffer1, start1, len1,
473  buffer2, start2, len2);
474 #else
475 
476  struct msghdr m;
477  struct cmsghdr *cm;
478  struct iovec iov[2];
479  int bytes_written;
480 
481  _dbus_assert (len1 >= 0);
482  _dbus_assert (len2 >= 0);
483  _dbus_assert (n_fds >= 0);
484 
485  _DBUS_ZERO(iov);
486  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
487  iov[0].iov_len = len1;
488 
489  if (buffer2)
490  {
491  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
492  iov[1].iov_len = len2;
493  }
494 
495  _DBUS_ZERO(m);
496  m.msg_iov = iov;
497  m.msg_iovlen = buffer2 ? 2 : 1;
498 
499  if (n_fds > 0)
500  {
501  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
502  m.msg_control = alloca(m.msg_controllen);
503  memset(m.msg_control, 0, m.msg_controllen);
504 
505  cm = CMSG_FIRSTHDR(&m);
506  cm->cmsg_level = SOL_SOCKET;
507  cm->cmsg_type = SCM_RIGHTS;
508  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
509  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
510  }
511 
512  again:
513 
514  bytes_written = sendmsg (fd, &m, 0
515 #if HAVE_DECL_MSG_NOSIGNAL
516  |MSG_NOSIGNAL
517 #endif
518  );
519 
520  if (bytes_written < 0 && errno == EINTR)
521  goto again;
522 
523 #if 0
524  if (bytes_written > 0)
525  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
526 #endif
527 
528  return bytes_written;
529 #endif
530 }
531 
545 int
547  const DBusString *buffer1,
548  int start1,
549  int len1,
550  const DBusString *buffer2,
551  int start2,
552  int len2)
553 {
554 #if HAVE_DECL_MSG_NOSIGNAL
555  struct iovec vectors[2];
556  const char *data1;
557  const char *data2;
558  int bytes_written;
559  struct msghdr m;
560 
561  _dbus_assert (buffer1 != NULL);
562  _dbus_assert (start1 >= 0);
563  _dbus_assert (start2 >= 0);
564  _dbus_assert (len1 >= 0);
565  _dbus_assert (len2 >= 0);
566 
567  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
568 
569  if (buffer2 != NULL)
570  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
571  else
572  {
573  data2 = NULL;
574  start2 = 0;
575  len2 = 0;
576  }
577 
578  vectors[0].iov_base = (char*) data1;
579  vectors[0].iov_len = len1;
580  vectors[1].iov_base = (char*) data2;
581  vectors[1].iov_len = len2;
582 
583  _DBUS_ZERO(m);
584  m.msg_iov = vectors;
585  m.msg_iovlen = data2 ? 2 : 1;
586 
587  again:
588 
589  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
590 
591  if (bytes_written < 0 && errno == EINTR)
592  goto again;
593 
594  return bytes_written;
595 
596 #else
597  return _dbus_write_two (fd, buffer1, start1, len1,
598  buffer2, start2, len2);
599 #endif
600 }
601 
603 _dbus_socket_is_invalid (int fd)
604 {
605  return fd < 0 ? TRUE : FALSE;
606 }
607 
624 int
625 _dbus_read (int fd,
626  DBusString *buffer,
627  int count)
628 {
629  int bytes_read;
630  int start;
631  char *data;
632 
633  _dbus_assert (count >= 0);
634 
635  start = _dbus_string_get_length (buffer);
636 
637  if (!_dbus_string_lengthen (buffer, count))
638  {
639  errno = ENOMEM;
640  return -1;
641  }
642 
643  data = _dbus_string_get_data_len (buffer, start, count);
644 
645  again:
646 
647  bytes_read = read (fd, data, count);
648 
649  if (bytes_read < 0)
650  {
651  if (errno == EINTR)
652  goto again;
653  else
654  {
655  /* put length back (note that this doesn't actually realloc anything) */
656  _dbus_string_set_length (buffer, start);
657  return -1;
658  }
659  }
660  else
661  {
662  /* put length back (doesn't actually realloc) */
663  _dbus_string_set_length (buffer, start + bytes_read);
664 
665 #if 0
666  if (bytes_read > 0)
667  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
668 #endif
669 
670  return bytes_read;
671  }
672 }
673 
684 int
685 _dbus_write (int fd,
686  const DBusString *buffer,
687  int start,
688  int len)
689 {
690  const char *data;
691  int bytes_written;
692 
693  data = _dbus_string_get_const_data_len (buffer, start, len);
694 
695  again:
696 
697  bytes_written = write (fd, data, len);
698 
699  if (bytes_written < 0 && errno == EINTR)
700  goto again;
701 
702 #if 0
703  if (bytes_written > 0)
704  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
705 #endif
706 
707  return bytes_written;
708 }
709 
730 int
732  const DBusString *buffer1,
733  int start1,
734  int len1,
735  const DBusString *buffer2,
736  int start2,
737  int len2)
738 {
739  _dbus_assert (buffer1 != NULL);
740  _dbus_assert (start1 >= 0);
741  _dbus_assert (start2 >= 0);
742  _dbus_assert (len1 >= 0);
743  _dbus_assert (len2 >= 0);
744 
745 #ifdef HAVE_WRITEV
746  {
747  struct iovec vectors[2];
748  const char *data1;
749  const char *data2;
750  int bytes_written;
751 
752  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
753 
754  if (buffer2 != NULL)
755  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
756  else
757  {
758  data2 = NULL;
759  start2 = 0;
760  len2 = 0;
761  }
762 
763  vectors[0].iov_base = (char*) data1;
764  vectors[0].iov_len = len1;
765  vectors[1].iov_base = (char*) data2;
766  vectors[1].iov_len = len2;
767 
768  again:
769 
770  bytes_written = writev (fd,
771  vectors,
772  data2 ? 2 : 1);
773 
774  if (bytes_written < 0 && errno == EINTR)
775  goto again;
776 
777  return bytes_written;
778  }
779 #else /* HAVE_WRITEV */
780  {
781  int ret1, ret2;
782 
783  ret1 = _dbus_write (fd, buffer1, start1, len1);
784  if (ret1 == len1 && buffer2 != NULL)
785  {
786  ret2 = _dbus_write (fd, buffer2, start2, len2);
787  if (ret2 < 0)
788  ret2 = 0; /* we can't report an error as the first write was OK */
789 
790  return ret1 + ret2;
791  }
792  else
793  return ret1;
794  }
795 #endif /* !HAVE_WRITEV */
796 }
797 
798 #define _DBUS_MAX_SUN_PATH_LENGTH 99
799 
829 int
830 _dbus_connect_unix_socket (const char *path,
831  dbus_bool_t abstract,
832  DBusError *error)
833 {
834  int fd;
835  size_t path_len;
836  struct sockaddr_un addr;
837 
838  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
839 
840  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
841  path, abstract);
842 
843 
844  if (!_dbus_open_unix_socket (&fd, error))
845  {
846  _DBUS_ASSERT_ERROR_IS_SET(error);
847  return -1;
848  }
849  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
850 
851  _DBUS_ZERO (addr);
852  addr.sun_family = AF_UNIX;
853  path_len = strlen (path);
854 
855  if (abstract)
856  {
857 #ifdef HAVE_ABSTRACT_SOCKETS
858  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
859  path_len++; /* Account for the extra nul byte added to the start of sun_path */
860 
861  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
862  {
864  "Abstract socket name too long\n");
865  _dbus_close (fd, NULL);
866  return -1;
867  }
868 
869  strncpy (&addr.sun_path[1], path, path_len);
870  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
871 #else /* HAVE_ABSTRACT_SOCKETS */
873  "Operating system does not support abstract socket namespace\n");
874  _dbus_close (fd, NULL);
875  return -1;
876 #endif /* ! HAVE_ABSTRACT_SOCKETS */
877  }
878  else
879  {
880  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
881  {
883  "Socket name too long\n");
884  _dbus_close (fd, NULL);
885  return -1;
886  }
887 
888  strncpy (addr.sun_path, path, path_len);
889  }
890 
891  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
892  {
893  dbus_set_error (error,
894  _dbus_error_from_errno (errno),
895  "Failed to connect to socket %s: %s",
896  path, _dbus_strerror (errno));
897 
898  _dbus_close (fd, NULL);
899  return -1;
900  }
901 
902  if (!_dbus_set_fd_nonblocking (fd, error))
903  {
904  _DBUS_ASSERT_ERROR_IS_SET (error);
905 
906  _dbus_close (fd, NULL);
907  return -1;
908  }
909 
910  return fd;
911 }
912 
925 int
926 _dbus_connect_exec (const char *path,
927  char *const argv[],
928  DBusError *error)
929 {
930  int fds[2];
931  pid_t pid;
932  int retval;
933  dbus_bool_t cloexec_done = 0;
934 
935  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
936 
937  _dbus_verbose ("connecting to process %s\n", path);
938 
939 #ifdef SOCK_CLOEXEC
940  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
941  cloexec_done = (retval >= 0);
942 
943  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
944 #endif
945  {
946  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
947  }
948 
949  if (retval < 0)
950  {
951  dbus_set_error (error,
952  _dbus_error_from_errno (errno),
953  "Failed to create socket pair: %s",
954  _dbus_strerror (errno));
955  return -1;
956  }
957 
958  if (!cloexec_done)
959  {
962  }
963 
964  pid = fork ();
965  if (pid < 0)
966  {
967  dbus_set_error (error,
968  _dbus_error_from_errno (errno),
969  "Failed to fork() to call %s: %s",
970  path, _dbus_strerror (errno));
971  close (fds[0]);
972  close (fds[1]);
973  return -1;
974  }
975 
976  if (pid == 0)
977  {
978  /* child */
979  close (fds[0]);
980 
981  dup2 (fds[1], STDIN_FILENO);
982  dup2 (fds[1], STDOUT_FILENO);
983 
984  if (fds[1] != STDIN_FILENO &&
985  fds[1] != STDOUT_FILENO)
986  close (fds[1]);
987 
988  /* Inherit STDERR and the controlling terminal from the
989  parent */
990 
991  _dbus_close_all ();
992 
993  execvp (path, argv);
994 
995  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
996 
997  _exit(1);
998  }
999 
1000  /* parent */
1001  close (fds[1]);
1002 
1003  if (!_dbus_set_fd_nonblocking (fds[0], error))
1004  {
1005  _DBUS_ASSERT_ERROR_IS_SET (error);
1006 
1007  close (fds[0]);
1008  return -1;
1009  }
1010 
1011  return fds[0];
1012 }
1013 
1031 int
1032 _dbus_listen_unix_socket (const char *path,
1033  dbus_bool_t abstract,
1034  DBusError *error)
1035 {
1036  int listen_fd;
1037  struct sockaddr_un addr;
1038  size_t path_len;
1039 
1040  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1041 
1042  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1043  path, abstract);
1044 
1045  if (!_dbus_open_unix_socket (&listen_fd, error))
1046  {
1047  _DBUS_ASSERT_ERROR_IS_SET(error);
1048  return -1;
1049  }
1050  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1051 
1052  _DBUS_ZERO (addr);
1053  addr.sun_family = AF_UNIX;
1054  path_len = strlen (path);
1055 
1056  if (abstract)
1057  {
1058 #ifdef HAVE_ABSTRACT_SOCKETS
1059  /* remember that abstract names aren't nul-terminated so we rely
1060  * on sun_path being filled in with zeroes above.
1061  */
1062  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1063  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1064 
1065  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1066  {
1068  "Abstract socket name too long\n");
1069  _dbus_close (listen_fd, NULL);
1070  return -1;
1071  }
1072 
1073  strncpy (&addr.sun_path[1], path, path_len);
1074  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1075 #else /* HAVE_ABSTRACT_SOCKETS */
1077  "Operating system does not support abstract socket namespace\n");
1078  _dbus_close (listen_fd, NULL);
1079  return -1;
1080 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1081  }
1082  else
1083  {
1084  /* Discussed security implications of this with Nalin,
1085  * and we couldn't think of where it would kick our ass, but
1086  * it still seems a bit sucky. It also has non-security suckage;
1087  * really we'd prefer to exit if the socket is already in use.
1088  * But there doesn't seem to be a good way to do this.
1089  *
1090  * Just to be extra careful, I threw in the stat() - clearly
1091  * the stat() can't *fix* any security issue, but it at least
1092  * avoids inadvertent/accidental data loss.
1093  */
1094  {
1095  struct stat sb;
1096 
1097  if (stat (path, &sb) == 0 &&
1098  S_ISSOCK (sb.st_mode))
1099  unlink (path);
1100  }
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, path, path_len);
1111  }
1112 
1113  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1114  {
1115  dbus_set_error (error, _dbus_error_from_errno (errno),
1116  "Failed to bind socket \"%s\": %s",
1117  path, _dbus_strerror (errno));
1118  _dbus_close (listen_fd, NULL);
1119  return -1;
1120  }
1121 
1122  if (listen (listen_fd, 30 /* backlog */) < 0)
1123  {
1124  dbus_set_error (error, _dbus_error_from_errno (errno),
1125  "Failed to listen on socket \"%s\": %s",
1126  path, _dbus_strerror (errno));
1127  _dbus_close (listen_fd, NULL);
1128  return -1;
1129  }
1130 
1131  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1132  {
1133  _DBUS_ASSERT_ERROR_IS_SET (error);
1134  _dbus_close (listen_fd, NULL);
1135  return -1;
1136  }
1137 
1138  /* Try opening up the permissions, but if we can't, just go ahead
1139  * and continue, maybe it will be good enough.
1140  */
1141  if (!abstract && chmod (path, 0777) < 0)
1142  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1143  path);
1144 
1145  return listen_fd;
1146 }
1147 
1158 int
1160  DBusError *error)
1161 {
1162  int r, n;
1163  unsigned fd;
1164  int *new_fds;
1165 
1166  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1167 
1168  n = sd_listen_fds (TRUE);
1169  if (n < 0)
1170  {
1172  "Failed to acquire systemd socket: %s",
1173  _dbus_strerror (-n));
1174  return -1;
1175  }
1176 
1177  if (n <= 0)
1178  {
1180  "No socket received.");
1181  return -1;
1182  }
1183 
1184  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1185  {
1186  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1187  if (r < 0)
1188  {
1190  "Failed to verify systemd socket type: %s",
1191  _dbus_strerror (-r));
1192  return -1;
1193  }
1194 
1195  if (!r)
1196  {
1198  "Passed socket has wrong type.");
1199  return -1;
1200  }
1201  }
1202 
1203  /* OK, the file descriptors are all good, so let's take posession of
1204  them then. */
1205 
1206  new_fds = dbus_new (int, n);
1207  if (!new_fds)
1208  {
1210  "Failed to allocate file handle array.");
1211  goto fail;
1212  }
1213 
1214  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1215  {
1216  if (!_dbus_set_fd_nonblocking (fd, error))
1217  {
1218  _DBUS_ASSERT_ERROR_IS_SET (error);
1219  goto fail;
1220  }
1221 
1222  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1223  }
1224 
1225  *fds = new_fds;
1226  return n;
1227 
1228  fail:
1229 
1230  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1231  {
1232  _dbus_close (fd, NULL);
1233  }
1234 
1235  dbus_free (new_fds);
1236  return -1;
1237 }
1238 
1252 int
1253 _dbus_connect_tcp_socket (const char *host,
1254  const char *port,
1255  const char *family,
1256  DBusError *error)
1257 {
1258  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1259 }
1260 
1261 int
1262 _dbus_connect_tcp_socket_with_nonce (const char *host,
1263  const char *port,
1264  const char *family,
1265  const char *noncefile,
1266  DBusError *error)
1267 {
1268  int saved_errno = 0;
1269  int fd = -1, res;
1270  struct addrinfo hints;
1271  struct addrinfo *ai, *tmp;
1272 
1273  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1274 
1275  _DBUS_ZERO (hints);
1276 
1277  if (!family)
1278  hints.ai_family = AF_UNSPEC;
1279  else if (!strcmp(family, "ipv4"))
1280  hints.ai_family = AF_INET;
1281  else if (!strcmp(family, "ipv6"))
1282  hints.ai_family = AF_INET6;
1283  else
1284  {
1285  dbus_set_error (error,
1287  "Unknown address family %s", family);
1288  return -1;
1289  }
1290  hints.ai_protocol = IPPROTO_TCP;
1291  hints.ai_socktype = SOCK_STREAM;
1292  hints.ai_flags = AI_ADDRCONFIG;
1293 
1294  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1295  {
1296  dbus_set_error (error,
1297  _dbus_error_from_errno (errno),
1298  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1299  host, port, gai_strerror(res), res);
1300  return -1;
1301  }
1302 
1303  tmp = ai;
1304  while (tmp)
1305  {
1306  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1307  {
1308  freeaddrinfo(ai);
1309  _DBUS_ASSERT_ERROR_IS_SET(error);
1310  return -1;
1311  }
1312  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1313 
1314  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1315  {
1316  saved_errno = errno;
1317  _dbus_close(fd, NULL);
1318  fd = -1;
1319  tmp = tmp->ai_next;
1320  continue;
1321  }
1322 
1323  break;
1324  }
1325  freeaddrinfo(ai);
1326 
1327  if (fd == -1)
1328  {
1329  dbus_set_error (error,
1330  _dbus_error_from_errno (saved_errno),
1331  "Failed to connect to socket \"%s:%s\" %s",
1332  host, port, _dbus_strerror(saved_errno));
1333  return -1;
1334  }
1335 
1336  if (noncefile != NULL)
1337  {
1338  DBusString noncefileStr;
1339  dbus_bool_t ret;
1340  _dbus_string_init_const (&noncefileStr, noncefile);
1341  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1342  _dbus_string_free (&noncefileStr);
1343 
1344  if (!ret)
1345  {
1346  _dbus_close (fd, NULL);
1347  return -1;
1348  }
1349  }
1350 
1351  if (!_dbus_set_fd_nonblocking (fd, error))
1352  {
1353  _dbus_close (fd, NULL);
1354  return -1;
1355  }
1356 
1357  return fd;
1358 }
1359 
1376 int
1377 _dbus_listen_tcp_socket (const char *host,
1378  const char *port,
1379  const char *family,
1380  DBusString *retport,
1381  int **fds_p,
1382  DBusError *error)
1383 {
1384  int saved_errno;
1385  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1386  struct addrinfo hints;
1387  struct addrinfo *ai, *tmp;
1388  unsigned int reuseaddr;
1389 
1390  *fds_p = NULL;
1391  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1392 
1393  _DBUS_ZERO (hints);
1394 
1395  if (!family)
1396  hints.ai_family = AF_UNSPEC;
1397  else if (!strcmp(family, "ipv4"))
1398  hints.ai_family = AF_INET;
1399  else if (!strcmp(family, "ipv6"))
1400  hints.ai_family = AF_INET6;
1401  else
1402  {
1403  dbus_set_error (error,
1405  "Unknown address family %s", family);
1406  return -1;
1407  }
1408 
1409  hints.ai_protocol = IPPROTO_TCP;
1410  hints.ai_socktype = SOCK_STREAM;
1411  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1412 
1413  redo_lookup_with_port:
1414  ai = NULL;
1415  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1416  {
1417  dbus_set_error (error,
1418  _dbus_error_from_errno (errno),
1419  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1420  host ? host : "*", port, gai_strerror(res), res);
1421  goto failed;
1422  }
1423 
1424  tmp = ai;
1425  while (tmp)
1426  {
1427  int fd = -1, *newlisten_fd;
1428  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1429  {
1430  _DBUS_ASSERT_ERROR_IS_SET(error);
1431  goto failed;
1432  }
1433  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1434 
1435  reuseaddr = 1;
1436  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1437  {
1438  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1439  host ? host : "*", port, _dbus_strerror (errno));
1440  }
1441 
1442  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1443  {
1444  saved_errno = errno;
1445  _dbus_close(fd, NULL);
1446  if (saved_errno == EADDRINUSE)
1447  {
1448  /* Depending on kernel policy, it may or may not
1449  be neccessary to bind to both IPv4 & 6 addresses
1450  so ignore EADDRINUSE here */
1451  tmp = tmp->ai_next;
1452  continue;
1453  }
1454  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1455  "Failed to bind socket \"%s:%s\": %s",
1456  host ? host : "*", port, _dbus_strerror (saved_errno));
1457  goto failed;
1458  }
1459 
1460  if (listen (fd, 30 /* backlog */) < 0)
1461  {
1462  saved_errno = errno;
1463  _dbus_close (fd, NULL);
1464  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1465  "Failed to listen on socket \"%s:%s\": %s",
1466  host ? host : "*", port, _dbus_strerror (saved_errno));
1467  goto failed;
1468  }
1469 
1470  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1471  if (!newlisten_fd)
1472  {
1473  saved_errno = errno;
1474  _dbus_close (fd, NULL);
1475  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1476  "Failed to allocate file handle array: %s",
1477  _dbus_strerror (saved_errno));
1478  goto failed;
1479  }
1480  listen_fd = newlisten_fd;
1481  listen_fd[nlisten_fd] = fd;
1482  nlisten_fd++;
1483 
1484  if (!_dbus_string_get_length(retport))
1485  {
1486  /* If the user didn't specify a port, or used 0, then
1487  the kernel chooses a port. After the first address
1488  is bound to, we need to force all remaining addresses
1489  to use the same port */
1490  if (!port || !strcmp(port, "0"))
1491  {
1492  int result;
1493  struct sockaddr_storage addr;
1494  socklen_t addrlen;
1495  char portbuf[50];
1496 
1497  addrlen = sizeof(addr);
1498  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1499 
1500  if (result == -1 ||
1501  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1502  portbuf, sizeof(portbuf),
1503  NI_NUMERICHOST)) != 0)
1504  {
1505  dbus_set_error (error, _dbus_error_from_errno (errno),
1506  "Failed to resolve port \"%s:%s\": %s (%s)",
1507  host ? host : "*", port, gai_strerror(res), res);
1508  goto failed;
1509  }
1510  if (!_dbus_string_append(retport, portbuf))
1511  {
1513  goto failed;
1514  }
1515 
1516  /* Release current address list & redo lookup */
1517  port = _dbus_string_get_const_data(retport);
1518  freeaddrinfo(ai);
1519  goto redo_lookup_with_port;
1520  }
1521  else
1522  {
1523  if (!_dbus_string_append(retport, port))
1524  {
1526  goto failed;
1527  }
1528  }
1529  }
1530 
1531  tmp = tmp->ai_next;
1532  }
1533  freeaddrinfo(ai);
1534  ai = NULL;
1535 
1536  if (!nlisten_fd)
1537  {
1538  errno = EADDRINUSE;
1539  dbus_set_error (error, _dbus_error_from_errno (errno),
1540  "Failed to bind socket \"%s:%s\": %s",
1541  host ? host : "*", port, _dbus_strerror (errno));
1542  goto failed;
1543  }
1544 
1545  for (i = 0 ; i < nlisten_fd ; i++)
1546  {
1547  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1548  {
1549  goto failed;
1550  }
1551  }
1552 
1553  *fds_p = listen_fd;
1554 
1555  return nlisten_fd;
1556 
1557  failed:
1558  if (ai)
1559  freeaddrinfo(ai);
1560  for (i = 0 ; i < nlisten_fd ; i++)
1561  _dbus_close(listen_fd[i], NULL);
1562  dbus_free(listen_fd);
1563  return -1;
1564 }
1565 
1566 static dbus_bool_t
1567 write_credentials_byte (int server_fd,
1568  DBusError *error)
1569 {
1570  int bytes_written;
1571  char buf[1] = { '\0' };
1572 #if defined(HAVE_CMSGCRED)
1573  union {
1574  struct cmsghdr hdr;
1575  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1576  } cmsg;
1577  struct iovec iov;
1578  struct msghdr msg;
1579  iov.iov_base = buf;
1580  iov.iov_len = 1;
1581 
1582  _DBUS_ZERO(msg);
1583  msg.msg_iov = &iov;
1584  msg.msg_iovlen = 1;
1585 
1586  msg.msg_control = (caddr_t) &cmsg;
1587  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1588  _DBUS_ZERO(cmsg);
1589  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1590  cmsg.hdr.cmsg_level = SOL_SOCKET;
1591  cmsg.hdr.cmsg_type = SCM_CREDS;
1592 #endif
1593 
1594  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1595 
1596  again:
1597 
1598 #if defined(HAVE_CMSGCRED)
1599  bytes_written = sendmsg (server_fd, &msg, 0
1600 #if HAVE_DECL_MSG_NOSIGNAL
1601  |MSG_NOSIGNAL
1602 #endif
1603  );
1604 
1605  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1606  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1607  * only allows that on AF_UNIX. Try just doing a send() instead. */
1608  if (bytes_written < 0 && errno == EINVAL)
1609 #endif
1610  {
1611  bytes_written = send (server_fd, buf, 1, 0
1612 #if HAVE_DECL_MSG_NOSIGNAL
1613  |MSG_NOSIGNAL
1614 #endif
1615  );
1616  }
1617 
1618  if (bytes_written < 0 && errno == EINTR)
1619  goto again;
1620 
1621  if (bytes_written < 0)
1622  {
1623  dbus_set_error (error, _dbus_error_from_errno (errno),
1624  "Failed to write credentials byte: %s",
1625  _dbus_strerror (errno));
1626  return FALSE;
1627  }
1628  else if (bytes_written == 0)
1629  {
1631  "wrote zero bytes writing credentials byte");
1632  return FALSE;
1633  }
1634  else
1635  {
1636  _dbus_assert (bytes_written == 1);
1637  _dbus_verbose ("wrote credentials byte\n");
1638  return TRUE;
1639  }
1640 }
1641 
1642 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1643 static dbus_bool_t
1644 add_linux_security_label_to_credentials (int client_fd,
1645  DBusCredentials *credentials)
1646 {
1647 #if defined(__linux__) && defined(SO_PEERSEC)
1648  DBusString buf;
1649  socklen_t len = 1024;
1650  dbus_bool_t oom = FALSE;
1651 
1652  if (!_dbus_string_init_preallocated (&buf, len) ||
1653  !_dbus_string_set_length (&buf, len))
1654  return FALSE;
1655 
1656  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1657  _dbus_string_get_data (&buf), &len) < 0)
1658  {
1659  int e = errno;
1660 
1661  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1662  _dbus_strerror (e), (unsigned long) len);
1663 
1664  if (e != ERANGE || len <= _dbus_string_get_length (&buf))
1665  {
1666  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1667  _dbus_strerror (e));
1668  goto out;
1669  }
1670 
1671  /* If not enough space, len is updated to be enough.
1672  * Try again with a large enough buffer. */
1673  if (!_dbus_string_set_length (&buf, len))
1674  {
1675  oom = TRUE;
1676  goto out;
1677  }
1678 
1679  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1680  }
1681 
1682  if (len <= 0)
1683  {
1684  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1685  (unsigned long) len);
1686  goto out;
1687  }
1688 
1689  if (len > _dbus_string_get_length (&buf))
1690  {
1691  _dbus_verbose ("%lu > %d", (unsigned long) len,
1692  _dbus_string_get_length (&buf));
1693  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1694  }
1695 
1696  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1697  {
1698  /* the kernel included the trailing \0 in its count,
1699  * but DBusString always has an extra \0 after the data anyway */
1700  _dbus_verbose ("subtracting trailing \\0\n");
1701  len--;
1702  }
1703 
1704  if (!_dbus_string_set_length (&buf, len))
1705  {
1706  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1707  oom = TRUE;
1708  goto out;
1709  }
1710 
1711  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1712  {
1713  /* LSM people on the linux-security-module@ mailing list say this
1714  * should never happen: the label should be a bytestring with
1715  * an optional trailing \0 */
1716  _dbus_verbose ("security label from kernel had an embedded \\0, "
1717  "ignoring it\n");
1718  goto out;
1719  }
1720 
1721  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1722  (unsigned long) len,
1723  _dbus_string_get_const_data (&buf));
1724 
1726  _dbus_string_get_const_data (&buf)))
1727  {
1728  oom = TRUE;
1729  goto out;
1730  }
1731 
1732 out:
1733  _dbus_string_free (&buf);
1734  return !oom;
1735 #else
1736  /* no error */
1737  return TRUE;
1738 #endif
1739 }
1740 
1764  DBusCredentials *credentials,
1765  DBusError *error)
1766 {
1767  struct msghdr msg;
1768  struct iovec iov;
1769  char buf;
1770  dbus_uid_t uid_read;
1771  dbus_pid_t pid_read;
1772  int bytes_read;
1773 
1774 #ifdef HAVE_CMSGCRED
1775  union {
1776  struct cmsghdr hdr;
1777  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1778  } cmsg;
1779 #endif
1780 
1781  uid_read = DBUS_UID_UNSET;
1782  pid_read = DBUS_PID_UNSET;
1783 
1784  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1785 
1786  /* The POSIX spec certainly doesn't promise this, but
1787  * we need these assertions to fail as soon as we're wrong about
1788  * it so we can do the porting fixups
1789  */
1790  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1791  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1792  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1793 
1794  _dbus_credentials_clear (credentials);
1795 
1796  iov.iov_base = &buf;
1797  iov.iov_len = 1;
1798 
1799  _DBUS_ZERO(msg);
1800  msg.msg_iov = &iov;
1801  msg.msg_iovlen = 1;
1802 
1803 #if defined(HAVE_CMSGCRED)
1804  _DBUS_ZERO(cmsg);
1805  msg.msg_control = (caddr_t) &cmsg;
1806  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1807 #endif
1808 
1809  again:
1810  bytes_read = recvmsg (client_fd, &msg, 0);
1811 
1812  if (bytes_read < 0)
1813  {
1814  if (errno == EINTR)
1815  goto again;
1816 
1817  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1818  * normally only call read_credentials if the socket was ready
1819  * for reading
1820  */
1821 
1822  dbus_set_error (error, _dbus_error_from_errno (errno),
1823  "Failed to read credentials byte: %s",
1824  _dbus_strerror (errno));
1825  return FALSE;
1826  }
1827  else if (bytes_read == 0)
1828  {
1829  /* this should not happen unless we are using recvmsg wrong,
1830  * so is essentially here for paranoia
1831  */
1833  "Failed to read credentials byte (zero-length read)");
1834  return FALSE;
1835  }
1836  else if (buf != '\0')
1837  {
1839  "Credentials byte was not nul");
1840  return FALSE;
1841  }
1842 
1843  _dbus_verbose ("read credentials byte\n");
1844 
1845  {
1846 #ifdef SO_PEERCRED
1847  /* Supported by at least Linux and OpenBSD, with minor differences.
1848  *
1849  * This mechanism passes the process ID through and does not require
1850  * the peer's cooperation, so we prefer it over all others. Notably,
1851  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1852  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1853  * because this is much less fragile.
1854  */
1855 #ifdef __OpenBSD__
1856  struct sockpeercred cr;
1857 #else
1858  struct ucred cr;
1859 #endif
1860  int cr_len = sizeof (cr);
1861 
1862  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1863  cr_len == sizeof (cr))
1864  {
1865  pid_read = cr.pid;
1866  uid_read = cr.uid;
1867  }
1868  else
1869  {
1870  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1871  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1872  }
1873 #elif defined(HAVE_CMSGCRED)
1874  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1875  * presence of that struct implies SCM_CREDS. Supported by at least
1876  * FreeBSD and DragonflyBSD.
1877  *
1878  * This mechanism requires the peer to help us (it has to send us a
1879  * SCM_CREDS message) but it does pass the process ID through,
1880  * which makes it better than getpeereid().
1881  */
1882  struct cmsgcred *cred;
1883  struct cmsghdr *cmsgp;
1884 
1885  for (cmsgp = CMSG_FIRSTHDR (&msg);
1886  cmsgp != NULL;
1887  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
1888  {
1889  if (cmsgp->cmsg_type == SCM_CREDS &&
1890  cmsgp->cmsg_level == SOL_SOCKET &&
1891  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
1892  {
1893  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
1894  pid_read = cred->cmcred_pid;
1895  uid_read = cred->cmcred_euid;
1896  break;
1897  }
1898  }
1899 
1900 #elif defined(HAVE_GETPEERUCRED)
1901  /* Supported in at least Solaris >= 10. It should probably be higher
1902  * up this list, because it carries the pid and we use this code path
1903  * for audit data. */
1904  ucred_t * ucred = NULL;
1905  if (getpeerucred (client_fd, &ucred) == 0)
1906  {
1907  pid_read = ucred_getpid (ucred);
1908  uid_read = ucred_geteuid (ucred);
1909 #ifdef HAVE_ADT
1910  /* generate audit session data based on socket ucred */
1911  adt_session_data_t *adth = NULL;
1912  adt_export_data_t *data = NULL;
1913  size_t size = 0;
1914  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1915  {
1916  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1917  }
1918  else
1919  {
1920  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1921  {
1922  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1923  }
1924  else
1925  {
1926  size = adt_export_session_data (adth, &data);
1927  if (size <= 0)
1928  {
1929  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1930  }
1931  else
1932  {
1933  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1934  free (data);
1935  }
1936  }
1937  (void) adt_end_session (adth);
1938  }
1939 #endif /* HAVE_ADT */
1940  }
1941  else
1942  {
1943  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1944  }
1945  if (ucred != NULL)
1946  ucred_free (ucred);
1947 
1948  /* ----------------------------------------------------------------
1949  * When adding new mechanisms, please add them above this point
1950  * if they support passing the process ID through, or below if not.
1951  * ---------------------------------------------------------------- */
1952 
1953 #elif defined(HAVE_GETPEEREID)
1954  /* getpeereid() originates from D.J. Bernstein and is fairly
1955  * widely-supported. According to a web search, it might be present in
1956  * any/all of:
1957  *
1958  * - AIX?
1959  * - Blackberry?
1960  * - Cygwin
1961  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
1962  * - Mac OS X
1963  * - Minix 3.1.8+
1964  * - MirBSD?
1965  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
1966  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
1967  * - QNX?
1968  */
1969  uid_t euid;
1970  gid_t egid;
1971  if (getpeereid (client_fd, &euid, &egid) == 0)
1972  {
1973  uid_read = euid;
1974  }
1975  else
1976  {
1977  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1978  }
1979 #else /* no supported mechanism */
1980 
1981 #warning Socket credentials not supported on this Unix OS
1982 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
1983 
1984  /* Please add other operating systems known to support at least one of
1985  * the mechanisms above to this list, keeping alphabetical order.
1986  * Everything not in this list is best-effort.
1987  */
1988 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
1989  defined(__linux__) || \
1990  defined(__OpenBSD__) || \
1991  defined(__NetBSD__)
1992 # error Credentials passing not working on this OS is a regression!
1993 #endif
1994 
1995  _dbus_verbose ("Socket credentials not supported on this OS\n");
1996 #endif
1997  }
1998 
1999  _dbus_verbose ("Credentials:"
2000  " pid "DBUS_PID_FORMAT
2001  " uid "DBUS_UID_FORMAT
2002  "\n",
2003  pid_read,
2004  uid_read);
2005 
2006  if (pid_read != DBUS_PID_UNSET)
2007  {
2008  if (!_dbus_credentials_add_pid (credentials, pid_read))
2009  {
2010  _DBUS_SET_OOM (error);
2011  return FALSE;
2012  }
2013  }
2014 
2015  if (uid_read != DBUS_UID_UNSET)
2016  {
2017  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2018  {
2019  _DBUS_SET_OOM (error);
2020  return FALSE;
2021  }
2022  }
2023 
2024  if (!add_linux_security_label_to_credentials (client_fd, credentials))
2025  {
2026  _DBUS_SET_OOM (error);
2027  return FALSE;
2028  }
2029 
2030  return TRUE;
2031 }
2032 
2052  DBusError *error)
2053 {
2054  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2055 
2056  if (write_credentials_byte (server_fd, error))
2057  return TRUE;
2058  else
2059  return FALSE;
2060 }
2061 
2071 int
2072 _dbus_accept (int listen_fd)
2073 {
2074  int client_fd;
2075  struct sockaddr addr;
2076  socklen_t addrlen;
2077 #ifdef HAVE_ACCEPT4
2078  dbus_bool_t cloexec_done;
2079 #endif
2080 
2081  addrlen = sizeof (addr);
2082 
2083  retry:
2084 
2085 #ifdef HAVE_ACCEPT4
2086  /*
2087  * At compile-time, we assume that if accept4() is available in
2088  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2089  * not necessarily true that either is supported by the running kernel.
2090  */
2091  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
2092  cloexec_done = client_fd >= 0;
2093 
2094  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
2095 #endif
2096  {
2097  client_fd = accept (listen_fd, &addr, &addrlen);
2098  }
2099 
2100  if (client_fd < 0)
2101  {
2102  if (errno == EINTR)
2103  goto retry;
2104  }
2105 
2106  _dbus_verbose ("client fd %d accepted\n", client_fd);
2107 
2108 #ifdef HAVE_ACCEPT4
2109  if (!cloexec_done)
2110 #endif
2111  {
2112  _dbus_fd_set_close_on_exec(client_fd);
2113  }
2114 
2115  return client_fd;
2116 }
2117 
2128 {
2129  const char *directory;
2130  struct stat sb;
2131 
2132  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2133 
2134  directory = _dbus_string_get_const_data (dir);
2135 
2136  if (stat (directory, &sb) < 0)
2137  {
2138  dbus_set_error (error, _dbus_error_from_errno (errno),
2139  "%s", _dbus_strerror (errno));
2140 
2141  return FALSE;
2142  }
2143 
2144  if (sb.st_uid != geteuid ())
2145  {
2147  "%s directory is owned by user %lu, not %lu",
2148  directory,
2149  (unsigned long) sb.st_uid,
2150  (unsigned long) geteuid ());
2151  return FALSE;
2152  }
2153 
2154  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2155  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2156  {
2158  "%s directory is not private to the user", directory);
2159  return FALSE;
2160  }
2161 
2162  return TRUE;
2163 }
2164 
2165 static dbus_bool_t
2166 fill_user_info_from_passwd (struct passwd *p,
2167  DBusUserInfo *info,
2168  DBusError *error)
2169 {
2170  _dbus_assert (p->pw_name != NULL);
2171  _dbus_assert (p->pw_dir != NULL);
2172 
2173  info->uid = p->pw_uid;
2174  info->primary_gid = p->pw_gid;
2175  info->username = _dbus_strdup (p->pw_name);
2176  info->homedir = _dbus_strdup (p->pw_dir);
2177 
2178  if (info->username == NULL ||
2179  info->homedir == NULL)
2180  {
2182  return FALSE;
2183  }
2184 
2185  return TRUE;
2186 }
2187 
2188 static dbus_bool_t
2189 fill_user_info (DBusUserInfo *info,
2190  dbus_uid_t uid,
2191  const DBusString *username,
2192  DBusError *error)
2193 {
2194  const char *username_c;
2195 
2196  /* exactly one of username/uid provided */
2197  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2198  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2199 
2200  info->uid = DBUS_UID_UNSET;
2201  info->primary_gid = DBUS_GID_UNSET;
2202  info->group_ids = NULL;
2203  info->n_group_ids = 0;
2204  info->username = NULL;
2205  info->homedir = NULL;
2206 
2207  if (username != NULL)
2208  username_c = _dbus_string_get_const_data (username);
2209  else
2210  username_c = NULL;
2211 
2212  /* For now assuming that the getpwnam() and getpwuid() flavors
2213  * are always symmetrical, if not we have to add more configure
2214  * checks
2215  */
2216 
2217 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2218  {
2219  struct passwd *p;
2220  int result;
2221  size_t buflen;
2222  char *buf;
2223  struct passwd p_str;
2224 
2225  /* retrieve maximum needed size for buf */
2226  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2227 
2228  /* sysconf actually returns a long, but everything else expects size_t,
2229  * so just recast here.
2230  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2231  */
2232  if ((long) buflen <= 0)
2233  buflen = 1024;
2234 
2235  result = -1;
2236  while (1)
2237  {
2238  buf = dbus_malloc (buflen);
2239  if (buf == NULL)
2240  {
2242  return FALSE;
2243  }
2244 
2245  p = NULL;
2246 #ifdef HAVE_POSIX_GETPWNAM_R
2247  if (uid != DBUS_UID_UNSET)
2248  result = getpwuid_r (uid, &p_str, buf, buflen,
2249  &p);
2250  else
2251  result = getpwnam_r (username_c, &p_str, buf, buflen,
2252  &p);
2253 #else
2254  if (uid != DBUS_UID_UNSET)
2255  p = getpwuid_r (uid, &p_str, buf, buflen);
2256  else
2257  p = getpwnam_r (username_c, &p_str, buf, buflen);
2258  result = 0;
2259 #endif /* !HAVE_POSIX_GETPWNAM_R */
2260  //Try a bigger buffer if ERANGE was returned
2261  if (result == ERANGE && buflen < 512 * 1024)
2262  {
2263  dbus_free (buf);
2264  buflen *= 2;
2265  }
2266  else
2267  {
2268  break;
2269  }
2270  }
2271  if (result == 0 && p == &p_str)
2272  {
2273  if (!fill_user_info_from_passwd (p, info, error))
2274  {
2275  dbus_free (buf);
2276  return FALSE;
2277  }
2278  dbus_free (buf);
2279  }
2280  else
2281  {
2282  dbus_set_error (error, _dbus_error_from_errno (errno),
2283  "User \"%s\" unknown or no memory to allocate password entry\n",
2284  username_c ? username_c : "???");
2285  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2286  dbus_free (buf);
2287  return FALSE;
2288  }
2289  }
2290 #else /* ! HAVE_GETPWNAM_R */
2291  {
2292  /* I guess we're screwed on thread safety here */
2293  struct passwd *p;
2294 
2295  if (uid != DBUS_UID_UNSET)
2296  p = getpwuid (uid);
2297  else
2298  p = getpwnam (username_c);
2299 
2300  if (p != NULL)
2301  {
2302  if (!fill_user_info_from_passwd (p, info, error))
2303  {
2304  return FALSE;
2305  }
2306  }
2307  else
2308  {
2309  dbus_set_error (error, _dbus_error_from_errno (errno),
2310  "User \"%s\" unknown or no memory to allocate password entry\n",
2311  username_c ? username_c : "???");
2312  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2313  return FALSE;
2314  }
2315  }
2316 #endif /* ! HAVE_GETPWNAM_R */
2317 
2318  /* Fill this in so we can use it to get groups */
2319  username_c = info->username;
2320 
2321 #ifdef HAVE_GETGROUPLIST
2322  {
2323  gid_t *buf;
2324  int buf_count;
2325  int i;
2326  int initial_buf_count;
2327 
2328  initial_buf_count = 17;
2329  buf_count = initial_buf_count;
2330  buf = dbus_new (gid_t, buf_count);
2331  if (buf == NULL)
2332  {
2334  goto failed;
2335  }
2336 
2337  if (getgrouplist (username_c,
2338  info->primary_gid,
2339  buf, &buf_count) < 0)
2340  {
2341  gid_t *new;
2342  /* Presumed cause of negative return code: buf has insufficient
2343  entries to hold the entire group list. The Linux behavior in this
2344  case is to pass back the actual number of groups in buf_count, but
2345  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2346  So as a hack, try to help out a bit by guessing a larger
2347  number of groups, within reason.. might still fail, of course,
2348  but we can at least print a more informative message. I looked up
2349  the "right way" to do this by downloading Apple's own source code
2350  for the "id" command, and it turns out that they use an
2351  undocumented library function getgrouplist_2 (!) which is not
2352  declared in any header in /usr/include (!!). That did not seem
2353  like the way to go here.
2354  */
2355  if (buf_count == initial_buf_count)
2356  {
2357  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2358  }
2359  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2360  if (new == NULL)
2361  {
2363  dbus_free (buf);
2364  goto failed;
2365  }
2366 
2367  buf = new;
2368 
2369  errno = 0;
2370  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2371  {
2372  if (errno == 0)
2373  {
2374  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2375  username_c, buf_count, buf_count);
2376  }
2377  else
2378  {
2379  dbus_set_error (error,
2380  _dbus_error_from_errno (errno),
2381  "Failed to get groups for username \"%s\" primary GID "
2382  DBUS_GID_FORMAT ": %s\n",
2383  username_c, info->primary_gid,
2384  _dbus_strerror (errno));
2385  dbus_free (buf);
2386  goto failed;
2387  }
2388  }
2389  }
2390 
2391  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2392  if (info->group_ids == NULL)
2393  {
2395  dbus_free (buf);
2396  goto failed;
2397  }
2398 
2399  for (i = 0; i < buf_count; ++i)
2400  info->group_ids[i] = buf[i];
2401 
2402  info->n_group_ids = buf_count;
2403 
2404  dbus_free (buf);
2405  }
2406 #else /* HAVE_GETGROUPLIST */
2407  {
2408  /* We just get the one group ID */
2409  info->group_ids = dbus_new (dbus_gid_t, 1);
2410  if (info->group_ids == NULL)
2411  {
2413  goto failed;
2414  }
2415 
2416  info->n_group_ids = 1;
2417 
2418  (info->group_ids)[0] = info->primary_gid;
2419  }
2420 #endif /* HAVE_GETGROUPLIST */
2421 
2422  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2423 
2424  return TRUE;
2425 
2426  failed:
2427  _DBUS_ASSERT_ERROR_IS_SET (error);
2428  return FALSE;
2429 }
2430 
2441  const DBusString *username,
2442  DBusError *error)
2443 {
2444  return fill_user_info (info, DBUS_UID_UNSET,
2445  username, error);
2446 }
2447 
2458  dbus_uid_t uid,
2459  DBusError *error)
2460 {
2461  return fill_user_info (info, uid,
2462  NULL, error);
2463 }
2464 
2474 {
2475  /* The POSIX spec certainly doesn't promise this, but
2476  * we need these assertions to fail as soon as we're wrong about
2477  * it so we can do the porting fixups
2478  */
2479  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2480  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2481  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2482 
2483  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2484  return FALSE;
2485  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2486  return FALSE;
2487 
2488  return TRUE;
2489 }
2490 
2504 {
2505  return _dbus_string_append_uint (str,
2506  _dbus_geteuid ());
2507 }
2508 
2513 dbus_pid_t
2515 {
2516  return getpid ();
2517 }
2518 
2522 dbus_uid_t
2524 {
2525  return getuid ();
2526 }
2527 
2531 dbus_uid_t
2533 {
2534  return geteuid ();
2535 }
2536 
2543 unsigned long
2545 {
2546  return getpid ();
2547 }
2548 
2557 _dbus_parse_uid (const DBusString *uid_str,
2558  dbus_uid_t *uid)
2559 {
2560  int end;
2561  long val;
2562 
2563  if (_dbus_string_get_length (uid_str) == 0)
2564  {
2565  _dbus_verbose ("UID string was zero length\n");
2566  return FALSE;
2567  }
2568 
2569  val = -1;
2570  end = 0;
2571  if (!_dbus_string_parse_int (uid_str, 0, &val,
2572  &end))
2573  {
2574  _dbus_verbose ("could not parse string as a UID\n");
2575  return FALSE;
2576  }
2577 
2578  if (end != _dbus_string_get_length (uid_str))
2579  {
2580  _dbus_verbose ("string contained trailing stuff after UID\n");
2581  return FALSE;
2582  }
2583 
2584  *uid = val;
2585 
2586  return TRUE;
2587 }
2588 
2589 #if !DBUS_USE_SYNC
2590 /* To be thread-safe by default on platforms that don't necessarily have
2591  * atomic operations (notably Debian armel, which is armv4t), we must
2592  * use a mutex that can be initialized statically, like this.
2593  * GLib >= 2.32 uses a similar system.
2594  */
2595 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2596 #endif
2597 
2604 dbus_int32_t
2606 {
2607 #if DBUS_USE_SYNC
2608  return __sync_add_and_fetch(&atomic->value, 1)-1;
2609 #else
2610  dbus_int32_t res;
2611 
2612  pthread_mutex_lock (&atomic_mutex);
2613  res = atomic->value;
2614  atomic->value += 1;
2615  pthread_mutex_unlock (&atomic_mutex);
2616 
2617  return res;
2618 #endif
2619 }
2620 
2627 dbus_int32_t
2629 {
2630 #if DBUS_USE_SYNC
2631  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2632 #else
2633  dbus_int32_t res;
2634 
2635  pthread_mutex_lock (&atomic_mutex);
2636  res = atomic->value;
2637  atomic->value -= 1;
2638  pthread_mutex_unlock (&atomic_mutex);
2639 
2640  return res;
2641 #endif
2642 }
2643 
2651 dbus_int32_t
2653 {
2654 #if DBUS_USE_SYNC
2655  __sync_synchronize ();
2656  return atomic->value;
2657 #else
2658  dbus_int32_t res;
2659 
2660  pthread_mutex_lock (&atomic_mutex);
2661  res = atomic->value;
2662  pthread_mutex_unlock (&atomic_mutex);
2663 
2664  return res;
2665 #endif
2666 }
2667 
2676 int
2678  int n_fds,
2679  int timeout_milliseconds)
2680 {
2681 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2682  /* This big thing is a constant expression and should get optimized
2683  * out of existence. So it's more robust than a configure check at
2684  * no cost.
2685  */
2686  if (_DBUS_POLLIN == POLLIN &&
2687  _DBUS_POLLPRI == POLLPRI &&
2688  _DBUS_POLLOUT == POLLOUT &&
2689  _DBUS_POLLERR == POLLERR &&
2690  _DBUS_POLLHUP == POLLHUP &&
2691  _DBUS_POLLNVAL == POLLNVAL &&
2692  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2693  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2694  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2695  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2696  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2697  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2698  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2699  {
2700  return poll ((struct pollfd*) fds,
2701  n_fds,
2702  timeout_milliseconds);
2703  }
2704  else
2705  {
2706  /* We have to convert the DBusPollFD to an array of
2707  * struct pollfd, poll, and convert back.
2708  */
2709  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2710  return -1;
2711  }
2712 #else /* ! HAVE_POLL */
2713 
2714  fd_set read_set, write_set, err_set;
2715  int max_fd = 0;
2716  int i;
2717  struct timeval tv;
2718  int ready;
2719 
2720  FD_ZERO (&read_set);
2721  FD_ZERO (&write_set);
2722  FD_ZERO (&err_set);
2723 
2724  for (i = 0; i < n_fds; i++)
2725  {
2726  DBusPollFD *fdp = &fds[i];
2727 
2728  if (fdp->events & _DBUS_POLLIN)
2729  FD_SET (fdp->fd, &read_set);
2730 
2731  if (fdp->events & _DBUS_POLLOUT)
2732  FD_SET (fdp->fd, &write_set);
2733 
2734  FD_SET (fdp->fd, &err_set);
2735 
2736  max_fd = MAX (max_fd, fdp->fd);
2737  }
2738 
2739  tv.tv_sec = timeout_milliseconds / 1000;
2740  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2741 
2742  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2743  timeout_milliseconds < 0 ? NULL : &tv);
2744 
2745  if (ready > 0)
2746  {
2747  for (i = 0; i < n_fds; i++)
2748  {
2749  DBusPollFD *fdp = &fds[i];
2750 
2751  fdp->revents = 0;
2752 
2753  if (FD_ISSET (fdp->fd, &read_set))
2754  fdp->revents |= _DBUS_POLLIN;
2755 
2756  if (FD_ISSET (fdp->fd, &write_set))
2757  fdp->revents |= _DBUS_POLLOUT;
2758 
2759  if (FD_ISSET (fdp->fd, &err_set))
2760  fdp->revents |= _DBUS_POLLERR;
2761  }
2762  }
2763 
2764  return ready;
2765 #endif
2766 }
2767 
2775 void
2777  long *tv_usec)
2778 {
2779 #ifdef HAVE_MONOTONIC_CLOCK
2780  struct timespec ts;
2781  clock_gettime (CLOCK_MONOTONIC, &ts);
2782 
2783  if (tv_sec)
2784  *tv_sec = ts.tv_sec;
2785  if (tv_usec)
2786  *tv_usec = ts.tv_nsec / 1000;
2787 #else
2788  struct timeval t;
2789 
2790  gettimeofday (&t, NULL);
2791 
2792  if (tv_sec)
2793  *tv_sec = t.tv_sec;
2794  if (tv_usec)
2795  *tv_usec = t.tv_usec;
2796 #endif
2797 }
2798 
2806 void
2807 _dbus_get_real_time (long *tv_sec,
2808  long *tv_usec)
2809 {
2810  struct timeval t;
2811 
2812  gettimeofday (&t, NULL);
2813 
2814  if (tv_sec)
2815  *tv_sec = t.tv_sec;
2816  if (tv_usec)
2817  *tv_usec = t.tv_usec;
2818 }
2819 
2830  DBusError *error)
2831 {
2832  const char *filename_c;
2833 
2834  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2835 
2836  filename_c = _dbus_string_get_const_data (filename);
2837 
2838  if (mkdir (filename_c, 0700) < 0)
2839  {
2840  if (errno == EEXIST)
2841  return TRUE;
2842 
2844  "Failed to create directory %s: %s\n",
2845  filename_c, _dbus_strerror (errno));
2846  return FALSE;
2847  }
2848  else
2849  return TRUE;
2850 }
2851 
2864  const DBusString *next_component)
2865 {
2866  dbus_bool_t dir_ends_in_slash;
2867  dbus_bool_t file_starts_with_slash;
2868 
2869  if (_dbus_string_get_length (dir) == 0 ||
2870  _dbus_string_get_length (next_component) == 0)
2871  return TRUE;
2872 
2873  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2874  _dbus_string_get_length (dir) - 1);
2875 
2876  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2877 
2878  if (dir_ends_in_slash && file_starts_with_slash)
2879  {
2880  _dbus_string_shorten (dir, 1);
2881  }
2882  else if (!(dir_ends_in_slash || file_starts_with_slash))
2883  {
2884  if (!_dbus_string_append_byte (dir, '/'))
2885  return FALSE;
2886  }
2887 
2888  return _dbus_string_copy (next_component, 0, dir,
2889  _dbus_string_get_length (dir));
2890 }
2891 
2893 #define NANOSECONDS_PER_SECOND 1000000000
2894 
2895 #define MICROSECONDS_PER_SECOND 1000000
2896 
2897 #define MILLISECONDS_PER_SECOND 1000
2898 
2899 #define NANOSECONDS_PER_MILLISECOND 1000000
2900 
2901 #define MICROSECONDS_PER_MILLISECOND 1000
2902 
2907 void
2908 _dbus_sleep_milliseconds (int milliseconds)
2909 {
2910 #ifdef HAVE_NANOSLEEP
2911  struct timespec req;
2912  struct timespec rem;
2913 
2914  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2915  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2916  rem.tv_sec = 0;
2917  rem.tv_nsec = 0;
2918 
2919  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2920  req = rem;
2921 #elif defined (HAVE_USLEEP)
2922  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2923 #else /* ! HAVE_USLEEP */
2924  sleep (MAX (milliseconds / 1000, 1));
2925 #endif
2926 }
2927 
2928 static dbus_bool_t
2929 _dbus_generate_pseudorandom_bytes (DBusString *str,
2930  int n_bytes)
2931 {
2932  int old_len;
2933  char *p;
2934 
2935  old_len = _dbus_string_get_length (str);
2936 
2937  if (!_dbus_string_lengthen (str, n_bytes))
2938  return FALSE;
2939 
2940  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2941 
2943 
2944  return TRUE;
2945 }
2946 
2957  int n_bytes)
2958 {
2959  int old_len;
2960  int fd;
2961 
2962  /* FALSE return means "no memory", if it could
2963  * mean something else then we'd need to return
2964  * a DBusError. So we always fall back to pseudorandom
2965  * if the I/O fails.
2966  */
2967 
2968  old_len = _dbus_string_get_length (str);
2969  fd = -1;
2970 
2971  /* note, urandom on linux will fall back to pseudorandom */
2972  fd = open ("/dev/urandom", O_RDONLY);
2973  if (fd < 0)
2974  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2975 
2976  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2977 
2978  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2979  {
2980  _dbus_close (fd, NULL);
2981  _dbus_string_set_length (str, old_len);
2982  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2983  }
2984 
2985  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2986  n_bytes);
2987 
2988  _dbus_close (fd, NULL);
2989 
2990  return TRUE;
2991 }
2992 
2998 void
2999 _dbus_exit (int code)
3000 {
3001  _exit (code);
3002 }
3003 
3012 const char*
3013 _dbus_strerror (int error_number)
3014 {
3015  const char *msg;
3016 
3017  msg = strerror (error_number);
3018  if (msg == NULL)
3019  msg = "unknown";
3020 
3021  return msg;
3022 }
3023 
3027 void
3029 {
3030  signal (SIGPIPE, SIG_IGN);
3031 }
3032 
3040 void
3042 {
3043  int val;
3044 
3045  val = fcntl (fd, F_GETFD, 0);
3046 
3047  if (val < 0)
3048  return;
3049 
3050  val |= FD_CLOEXEC;
3051 
3052  fcntl (fd, F_SETFD, val);
3053 }
3054 
3063 _dbus_close (int fd,
3064  DBusError *error)
3065 {
3066  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3067 
3068  again:
3069  if (close (fd) < 0)
3070  {
3071  if (errno == EINTR)
3072  goto again;
3073 
3074  dbus_set_error (error, _dbus_error_from_errno (errno),
3075  "Could not close fd %d", fd);
3076  return FALSE;
3077  }
3078 
3079  return TRUE;
3080 }
3081 
3090 int
3091 _dbus_dup(int fd,
3092  DBusError *error)
3093 {
3094  int new_fd;
3095 
3096 #ifdef F_DUPFD_CLOEXEC
3097  dbus_bool_t cloexec_done;
3098 
3099  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3100  cloexec_done = new_fd >= 0;
3101 
3102  if (new_fd < 0 && errno == EINVAL)
3103 #endif
3104  {
3105  new_fd = fcntl(fd, F_DUPFD, 3);
3106  }
3107 
3108  if (new_fd < 0) {
3109 
3110  dbus_set_error (error, _dbus_error_from_errno (errno),
3111  "Could not duplicate fd %d", fd);
3112  return -1;
3113  }
3114 
3115 #ifdef F_DUPFD_CLOEXEC
3116  if (!cloexec_done)
3117 #endif
3118  {
3120  }
3121 
3122  return new_fd;
3123 }
3124 
3133 _dbus_set_fd_nonblocking (int fd,
3134  DBusError *error)
3135 {
3136  int val;
3137 
3138  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3139 
3140  val = fcntl (fd, F_GETFL, 0);
3141  if (val < 0)
3142  {
3143  dbus_set_error (error, _dbus_error_from_errno (errno),
3144  "Failed to get flags from file descriptor %d: %s",
3145  fd, _dbus_strerror (errno));
3146  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3147  _dbus_strerror (errno));
3148  return FALSE;
3149  }
3150 
3151  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3152  {
3153  dbus_set_error (error, _dbus_error_from_errno (errno),
3154  "Failed to set nonblocking flag of file descriptor %d: %s",
3155  fd, _dbus_strerror (errno));
3156  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3157  fd, _dbus_strerror (errno));
3158 
3159  return FALSE;
3160  }
3161 
3162  return TRUE;
3163 }
3164 
3170 void
3172 {
3173 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3174  void *bt[500];
3175  int bt_size;
3176  int i;
3177  char **syms;
3178 
3179  bt_size = backtrace (bt, 500);
3180 
3181  syms = backtrace_symbols (bt, bt_size);
3182 
3183  i = 0;
3184  while (i < bt_size)
3185  {
3186  /* don't use dbus_warn since it can _dbus_abort() */
3187  fprintf (stderr, " %s\n", syms[i]);
3188  ++i;
3189  }
3190  fflush (stderr);
3191 
3192  free (syms);
3193 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3194  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3195 #else
3196  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3197 #endif
3198 }
3199 
3214  int *fd2,
3215  dbus_bool_t blocking,
3216  DBusError *error)
3217 {
3218 #ifdef HAVE_SOCKETPAIR
3219  int fds[2];
3220  int retval;
3221 
3222 #ifdef SOCK_CLOEXEC
3223  dbus_bool_t cloexec_done;
3224 
3225  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3226  cloexec_done = retval >= 0;
3227 
3228  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3229 #endif
3230  {
3231  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3232  }
3233 
3234  if (retval < 0)
3235  {
3236  dbus_set_error (error, _dbus_error_from_errno (errno),
3237  "Could not create full-duplex pipe");
3238  return FALSE;
3239  }
3240 
3241  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3242 
3243 #ifdef SOCK_CLOEXEC
3244  if (!cloexec_done)
3245 #endif
3246  {
3247  _dbus_fd_set_close_on_exec (fds[0]);
3248  _dbus_fd_set_close_on_exec (fds[1]);
3249  }
3250 
3251  if (!blocking &&
3252  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3253  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3254  {
3255  dbus_set_error (error, _dbus_error_from_errno (errno),
3256  "Could not set full-duplex pipe nonblocking");
3257 
3258  _dbus_close (fds[0], NULL);
3259  _dbus_close (fds[1], NULL);
3260 
3261  return FALSE;
3262  }
3263 
3264  *fd1 = fds[0];
3265  *fd2 = fds[1];
3266 
3267  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3268  *fd1, *fd2);
3269 
3270  return TRUE;
3271 #else
3272  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3274  "_dbus_full_duplex_pipe() not implemented on this OS");
3275  return FALSE;
3276 #endif
3277 }
3278 
3287 int
3289  va_list args)
3290 {
3291  char static_buf[1024];
3292  int bufsize = sizeof (static_buf);
3293  int len;
3294  va_list args_copy;
3295 
3296  DBUS_VA_COPY (args_copy, args);
3297  len = vsnprintf (static_buf, bufsize, format, args_copy);
3298  va_end (args_copy);
3299 
3300  /* If vsnprintf() returned non-negative, then either the string fits in
3301  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3302  * returns the number of characters that were needed, or this OS returns the
3303  * truncated length.
3304  *
3305  * We ignore the possibility that snprintf might just ignore the length and
3306  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3307  * If your libc is really that bad, come back when you have a better one. */
3308  if (len == bufsize)
3309  {
3310  /* This could be the truncated length (Tru64 and IRIX have this bug),
3311  * or the real length could be coincidentally the same. Which is it?
3312  * If vsnprintf returns the truncated length, we'll go to the slow
3313  * path. */
3314  DBUS_VA_COPY (args_copy, args);
3315 
3316  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3317  len = -1;
3318 
3319  va_end (args_copy);
3320  }
3321 
3322  /* If vsnprintf() returned negative, we have to do more work.
3323  * HP-UX returns negative. */
3324  while (len < 0)
3325  {
3326  char *buf;
3327 
3328  bufsize *= 2;
3329 
3330  buf = dbus_malloc (bufsize);
3331 
3332  if (buf == NULL)
3333  return -1;
3334 
3335  DBUS_VA_COPY (args_copy, args);
3336  len = vsnprintf (buf, bufsize, format, args_copy);
3337  va_end (args_copy);
3338 
3339  dbus_free (buf);
3340 
3341  /* If the reported length is exactly the buffer size, round up to the
3342  * next size, in case vsnprintf has been returning the truncated
3343  * length */
3344  if (len == bufsize)
3345  len = -1;
3346  }
3347 
3348  return len;
3349 }
3350 
3357 const char*
3359 {
3360  /* Protected by _DBUS_LOCK_sysdeps */
3361  static const char* tmpdir = NULL;
3362 
3363  if (!_DBUS_LOCK (sysdeps))
3364  return NULL;
3365 
3366  if (tmpdir == NULL)
3367  {
3368  /* TMPDIR is what glibc uses, then
3369  * glibc falls back to the P_tmpdir macro which
3370  * just expands to "/tmp"
3371  */
3372  if (tmpdir == NULL)
3373  tmpdir = getenv("TMPDIR");
3374 
3375  /* These two env variables are probably
3376  * broken, but maybe some OS uses them?
3377  */
3378  if (tmpdir == NULL)
3379  tmpdir = getenv("TMP");
3380  if (tmpdir == NULL)
3381  tmpdir = getenv("TEMP");
3382 
3383  /* And this is the sane fallback. */
3384  if (tmpdir == NULL)
3385  tmpdir = "/tmp";
3386  }
3387 
3388  _DBUS_UNLOCK (sysdeps);
3389 
3390  _dbus_assert(tmpdir != NULL);
3391 
3392  return tmpdir;
3393 }
3394 
3395 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3396 
3415 static dbus_bool_t
3416 _read_subprocess_line_argv (const char *progpath,
3417  dbus_bool_t path_fallback,
3418  char * const *argv,
3419  DBusString *result,
3420  DBusError *error)
3421 {
3422  int result_pipe[2] = { -1, -1 };
3423  int errors_pipe[2] = { -1, -1 };
3424  pid_t pid;
3425  int ret;
3426  int status;
3427  int orig_len;
3428 
3429  dbus_bool_t retval;
3430  sigset_t new_set, old_set;
3431 
3432  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3433  retval = FALSE;
3434 
3435  /* We need to block any existing handlers for SIGCHLD temporarily; they
3436  * will cause waitpid() below to fail.
3437  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3438  */
3439  sigemptyset (&new_set);
3440  sigaddset (&new_set, SIGCHLD);
3441  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3442 
3443  orig_len = _dbus_string_get_length (result);
3444 
3445 #define READ_END 0
3446 #define WRITE_END 1
3447  if (pipe (result_pipe) < 0)
3448  {
3449  dbus_set_error (error, _dbus_error_from_errno (errno),
3450  "Failed to create a pipe to call %s: %s",
3451  progpath, _dbus_strerror (errno));
3452  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3453  progpath, _dbus_strerror (errno));
3454  goto out;
3455  }
3456  if (pipe (errors_pipe) < 0)
3457  {
3458  dbus_set_error (error, _dbus_error_from_errno (errno),
3459  "Failed to create a pipe to call %s: %s",
3460  progpath, _dbus_strerror (errno));
3461  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3462  progpath, _dbus_strerror (errno));
3463  goto out;
3464  }
3465 
3466  pid = fork ();
3467  if (pid < 0)
3468  {
3469  dbus_set_error (error, _dbus_error_from_errno (errno),
3470  "Failed to fork() to call %s: %s",
3471  progpath, _dbus_strerror (errno));
3472  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3473  progpath, _dbus_strerror (errno));
3474  goto out;
3475  }
3476 
3477  if (pid == 0)
3478  {
3479  /* child process */
3480  int fd;
3481 
3482  fd = open ("/dev/null", O_RDWR);
3483  if (fd == -1)
3484  /* huh?! can't open /dev/null? */
3485  _exit (1);
3486 
3487  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3488 
3489  /* set-up stdXXX */
3490  close (result_pipe[READ_END]);
3491  close (errors_pipe[READ_END]);
3492 
3493  if (dup2 (fd, 0) == -1) /* setup stdin */
3494  _exit (1);
3495  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3496  _exit (1);
3497  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3498  _exit (1);
3499 
3500  _dbus_close_all ();
3501 
3502  sigprocmask (SIG_SETMASK, &old_set, NULL);
3503 
3504  /* If it looks fully-qualified, try execv first */
3505  if (progpath[0] == '/')
3506  {
3507  execv (progpath, argv);
3508  /* Ok, that failed. Now if path_fallback is given, let's
3509  * try unqualified. This is mostly a hack to work
3510  * around systems which ship dbus-launch in /usr/bin
3511  * but everything else in /bin (because dbus-launch
3512  * depends on X11).
3513  */
3514  if (path_fallback)
3515  /* We must have a slash, because we checked above */
3516  execvp (strrchr (progpath, '/')+1, argv);
3517  }
3518  else
3519  execvp (progpath, argv);
3520 
3521  /* still nothing, we failed */
3522  _exit (1);
3523  }
3524 
3525  /* parent process */
3526  close (result_pipe[WRITE_END]);
3527  close (errors_pipe[WRITE_END]);
3528  result_pipe[WRITE_END] = -1;
3529  errors_pipe[WRITE_END] = -1;
3530 
3531  ret = 0;
3532  do
3533  {
3534  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3535  }
3536  while (ret > 0);
3537 
3538  /* reap the child process to avoid it lingering as zombie */
3539  do
3540  {
3541  ret = waitpid (pid, &status, 0);
3542  }
3543  while (ret == -1 && errno == EINTR);
3544 
3545  /* We succeeded if the process exited with status 0 and
3546  anything was read */
3547  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3548  {
3549  /* The process ended with error */
3550  DBusString error_message;
3551  if (!_dbus_string_init (&error_message))
3552  {
3553  _DBUS_SET_OOM (error);
3554  goto out;
3555  }
3556 
3557  ret = 0;
3558  do
3559  {
3560  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3561  }
3562  while (ret > 0);
3563 
3564  _dbus_string_set_length (result, orig_len);
3565  if (_dbus_string_get_length (&error_message) > 0)
3567  "%s terminated abnormally with the following error: %s",
3568  progpath, _dbus_string_get_data (&error_message));
3569  else
3571  "%s terminated abnormally without any error message",
3572  progpath);
3573  goto out;
3574  }
3575 
3576  retval = TRUE;
3577 
3578  out:
3579  sigprocmask (SIG_SETMASK, &old_set, NULL);
3580 
3581  if (retval)
3582  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3583  else
3584  _DBUS_ASSERT_ERROR_IS_SET (error);
3585 
3586  if (result_pipe[0] != -1)
3587  close (result_pipe[0]);
3588  if (result_pipe[1] != -1)
3589  close (result_pipe[1]);
3590  if (errors_pipe[0] != -1)
3591  close (errors_pipe[0]);
3592  if (errors_pipe[1] != -1)
3593  close (errors_pipe[1]);
3594 
3595  return retval;
3596 }
3597 #endif
3598 
3612 _dbus_get_autolaunch_address (const char *scope,
3613  DBusString *address,
3614  DBusError *error)
3615 {
3616 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3617  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3618  * but that's done elsewhere, and if it worked, this function wouldn't
3619  * be called.) */
3620  const char *display;
3621  char *argv[6];
3622  int i;
3623  DBusString uuid;
3624  dbus_bool_t retval;
3625 
3626  if (_dbus_check_setuid ())
3627  {
3629  "Unable to autolaunch when setuid");
3630  return FALSE;
3631  }
3632 
3633  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3634  retval = FALSE;
3635 
3636  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3637  * dbus-launch-x11 is just going to fail. Rather than trying to
3638  * run it, we might as well bail out early with a nice error. */
3639  display = _dbus_getenv ("DISPLAY");
3640 
3641  if (display == NULL || display[0] == '\0')
3642  {
3644  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3645  return FALSE;
3646  }
3647 
3648  if (!_dbus_string_init (&uuid))
3649  {
3650  _DBUS_SET_OOM (error);
3651  return FALSE;
3652  }
3653 
3655  {
3656  _DBUS_SET_OOM (error);
3657  goto out;
3658  }
3659 
3660  i = 0;
3661 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3662  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3663  argv[i] = TEST_BUS_LAUNCH_BINARY;
3664  else
3665 #endif
3666  argv[i] = DBUS_BINDIR "/dbus-launch";
3667  ++i;
3668  argv[i] = "--autolaunch";
3669  ++i;
3670  argv[i] = _dbus_string_get_data (&uuid);
3671  ++i;
3672  argv[i] = "--binary-syntax";
3673  ++i;
3674  argv[i] = "--close-stderr";
3675  ++i;
3676  argv[i] = NULL;
3677  ++i;
3678 
3679  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3680 
3681  retval = _read_subprocess_line_argv (argv[0],
3682  TRUE,
3683  argv, address, error);
3684 
3685  out:
3686  _dbus_string_free (&uuid);
3687  return retval;
3688 #else
3690  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3691  "set your DBUS_SESSION_BUS_ADDRESS instead");
3692  return FALSE;
3693 #endif
3694 }
3695 
3716  dbus_bool_t create_if_not_found,
3717  DBusError *error)
3718 {
3719  DBusString filename;
3720  dbus_bool_t b;
3721 
3722  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3723 
3724  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3725  if (b)
3726  return TRUE;
3727 
3728  dbus_error_free (error);
3729 
3730  /* Fallback to the system machine ID */
3731  _dbus_string_init_const (&filename, "/etc/machine-id");
3732  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3733 
3734  if (b)
3735  {
3736  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3737  * complain if that isn't possible for whatever reason */
3738  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3739  _dbus_write_uuid_file (&filename, machine_id, NULL);
3740 
3741  return TRUE;
3742  }
3743 
3744  if (!create_if_not_found)
3745  return FALSE;
3746 
3747  /* if none found, try to make a new one */
3748  dbus_error_free (error);
3749  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3750  _dbus_generate_uuid (machine_id);
3751  return _dbus_write_uuid_file (&filename, machine_id, error);
3752 }
3753 
3763  const char *launchd_env_var,
3764  DBusError *error)
3765 {
3766 #ifdef DBUS_ENABLE_LAUNCHD
3767  char *argv[4];
3768  int i;
3769 
3770  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3771 
3772  if (_dbus_check_setuid ())
3773  {
3775  "Unable to find launchd socket when setuid");
3776  return FALSE;
3777  }
3778 
3779  i = 0;
3780  argv[i] = "launchctl";
3781  ++i;
3782  argv[i] = "getenv";
3783  ++i;
3784  argv[i] = (char*)launchd_env_var;
3785  ++i;
3786  argv[i] = NULL;
3787  ++i;
3788 
3789  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3790 
3791  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3792  {
3793  return FALSE;
3794  }
3795 
3796  /* no error, but no result either */
3797  if (_dbus_string_get_length(socket_path) == 0)
3798  {
3799  return FALSE;
3800  }
3801 
3802  /* strip the carriage-return */
3803  _dbus_string_shorten(socket_path, 1);
3804  return TRUE;
3805 #else /* DBUS_ENABLE_LAUNCHD */
3807  "can't lookup socket from launchd; launchd support not compiled in");
3808  return FALSE;
3809 #endif
3810 }
3811 
3812 #ifdef DBUS_ENABLE_LAUNCHD
3813 static dbus_bool_t
3814 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3815 {
3816  dbus_bool_t valid_socket;
3817  DBusString socket_path;
3818 
3819  if (_dbus_check_setuid ())
3820  {
3822  "Unable to find launchd socket when setuid");
3823  return FALSE;
3824  }
3825 
3826  if (!_dbus_string_init (&socket_path))
3827  {
3828  _DBUS_SET_OOM (error);
3829  return FALSE;
3830  }
3831 
3832  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3833 
3834  if (dbus_error_is_set(error))
3835  {
3836  _dbus_string_free(&socket_path);
3837  return FALSE;
3838  }
3839 
3840  if (!valid_socket)
3841  {
3842  dbus_set_error(error, "no socket path",
3843  "launchd did not provide a socket path, "
3844  "verify that org.freedesktop.dbus-session.plist is loaded!");
3845  _dbus_string_free(&socket_path);
3846  return FALSE;
3847  }
3848  if (!_dbus_string_append (address, "unix:path="))
3849  {
3850  _DBUS_SET_OOM (error);
3851  _dbus_string_free(&socket_path);
3852  return FALSE;
3853  }
3854  if (!_dbus_string_copy (&socket_path, 0, address,
3855  _dbus_string_get_length (address)))
3856  {
3857  _DBUS_SET_OOM (error);
3858  _dbus_string_free(&socket_path);
3859  return FALSE;
3860  }
3861 
3862  _dbus_string_free(&socket_path);
3863  return TRUE;
3864 }
3865 #endif
3866 
3888  DBusString *address,
3889  DBusError *error)
3890 {
3891 #ifdef DBUS_ENABLE_LAUNCHD
3892  *supported = TRUE;
3893  return _dbus_lookup_session_address_launchd (address, error);
3894 #else
3895  /* On non-Mac Unix platforms, if the session address isn't already
3896  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3897  * fall back to the autolaunch: global default; see
3898  * init_session_address in dbus/dbus-bus.c. */
3899  *supported = FALSE;
3900  return TRUE;
3901 #endif
3902 }
3903 
3911 void
3913 {
3915 }
3916 
3932  DBusCredentials *credentials)
3933 {
3934  DBusString homedir;
3935  DBusString dotdir;
3936  dbus_uid_t uid;
3937 
3938  _dbus_assert (credentials != NULL);
3940 
3941  if (!_dbus_string_init (&homedir))
3942  return FALSE;
3943 
3944  uid = _dbus_credentials_get_unix_uid (credentials);
3945  _dbus_assert (uid != DBUS_UID_UNSET);
3946 
3947  if (!_dbus_homedir_from_uid (uid, &homedir))
3948  goto failed;
3949 
3950 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3951  {
3952  const char *override;
3953 
3954  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3955  if (override != NULL && *override != '\0')
3956  {
3957  _dbus_string_set_length (&homedir, 0);
3958  if (!_dbus_string_append (&homedir, override))
3959  goto failed;
3960 
3961  _dbus_verbose ("Using fake homedir for testing: %s\n",
3962  _dbus_string_get_const_data (&homedir));
3963  }
3964  else
3965  {
3966  /* Not strictly thread-safe, but if we fail at thread-safety here,
3967  * the worst that will happen is some extra warnings. */
3968  static dbus_bool_t already_warned = FALSE;
3969  if (!already_warned)
3970  {
3971  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3972  already_warned = TRUE;
3973  }
3974  }
3975  }
3976 #endif
3977 
3978  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3979  if (!_dbus_concat_dir_and_file (&homedir,
3980  &dotdir))
3981  goto failed;
3982 
3983  if (!_dbus_string_copy (&homedir, 0,
3984  directory, _dbus_string_get_length (directory))) {
3985  goto failed;
3986  }
3987 
3988  _dbus_string_free (&homedir);
3989  return TRUE;
3990 
3991  failed:
3992  _dbus_string_free (&homedir);
3993  return FALSE;
3994 }
3995 
3996 //PENDING(kdab) docs
3998 _dbus_daemon_publish_session_bus_address (const char* addr,
3999  const char *scope)
4000 {
4001  return TRUE;
4002 }
4003 
4004 //PENDING(kdab) docs
4005 void
4006 _dbus_daemon_unpublish_session_bus_address (void)
4007 {
4008 
4009 }
4010 
4019 {
4020  return errno == EAGAIN || errno == EWOULDBLOCK;
4021 }
4022 
4032  DBusError *error)
4033 {
4034  const char *filename_c;
4035 
4036  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4037 
4038  filename_c = _dbus_string_get_const_data (filename);
4039 
4040  if (rmdir (filename_c) != 0)
4041  {
4043  "Failed to remove directory %s: %s\n",
4044  filename_c, _dbus_strerror (errno));
4045  return FALSE;
4046  }
4047 
4048  return TRUE;
4049 }
4050 
4060 
4061 #ifdef SCM_RIGHTS
4062  union {
4063  struct sockaddr sa;
4064  struct sockaddr_storage storage;
4065  struct sockaddr_un un;
4066  } sa_buf;
4067 
4068  socklen_t sa_len = sizeof(sa_buf);
4069 
4070  _DBUS_ZERO(sa_buf);
4071 
4072  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4073  return FALSE;
4074 
4075  return sa_buf.sa.sa_family == AF_UNIX;
4076 
4077 #else
4078  return FALSE;
4079 
4080 #endif
4081 }
4082 
4087 void
4089 {
4090  int maxfds, i;
4091 
4092 #ifdef __linux__
4093  DIR *d;
4094 
4095  /* On Linux we can optimize this a bit if /proc is available. If it
4096  isn't available, fall back to the brute force way. */
4097 
4098  d = opendir ("/proc/self/fd");
4099  if (d)
4100  {
4101  for (;;)
4102  {
4103  struct dirent buf, *de;
4104  int k, fd;
4105  long l;
4106  char *e = NULL;
4107 
4108  k = readdir_r (d, &buf, &de);
4109  if (k != 0 || !de)
4110  break;
4111 
4112  if (de->d_name[0] == '.')
4113  continue;
4114 
4115  errno = 0;
4116  l = strtol (de->d_name, &e, 10);
4117  if (errno != 0 || e == NULL || *e != '\0')
4118  continue;
4119 
4120  fd = (int) l;
4121  if (fd < 3)
4122  continue;
4123 
4124  if (fd == dirfd (d))
4125  continue;
4126 
4127  close (fd);
4128  }
4129 
4130  closedir (d);
4131  return;
4132  }
4133 #endif
4134 
4135  maxfds = sysconf (_SC_OPEN_MAX);
4136 
4137  /* Pick something reasonable if for some reason sysconf says
4138  * unlimited.
4139  */
4140  if (maxfds < 0)
4141  maxfds = 1024;
4142 
4143  /* close all inherited fds */
4144  for (i = 3; i < maxfds; i++)
4145  close (i);
4146 }
4147 
4159 {
4160  /* TODO: get __libc_enable_secure exported from glibc.
4161  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4162  */
4163 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4164  {
4165  /* See glibc/include/unistd.h */
4166  extern int __libc_enable_secure;
4167  return __libc_enable_secure;
4168  }
4169 #elif defined(HAVE_ISSETUGID)
4170  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4171  return issetugid ();
4172 #else
4173  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4174  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4175 
4176  /* We call into this function from _dbus_threads_init_platform_specific()
4177  * to make sure these are initialized before we start threading. */
4178  static dbus_bool_t check_setuid_initialised;
4179  static dbus_bool_t is_setuid;
4180 
4181  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4182  {
4183 #ifdef HAVE_GETRESUID
4184  if (getresuid (&ruid, &euid, &suid) != 0 ||
4185  getresgid (&rgid, &egid, &sgid) != 0)
4186 #endif /* HAVE_GETRESUID */
4187  {
4188  suid = ruid = getuid ();
4189  sgid = rgid = getgid ();
4190  euid = geteuid ();
4191  egid = getegid ();
4192  }
4193 
4194  check_setuid_initialised = TRUE;
4195  is_setuid = (ruid != euid || ruid != suid ||
4196  rgid != egid || rgid != sgid);
4197 
4198  }
4199  return is_setuid;
4200 #endif
4201 }
4202 
4212  DBusString *address,
4213  DBusError *error)
4214 {
4215  union {
4216  struct sockaddr sa;
4217  struct sockaddr_storage storage;
4218  struct sockaddr_un un;
4219  struct sockaddr_in ipv4;
4220  struct sockaddr_in6 ipv6;
4221  } socket;
4222  char hostip[INET6_ADDRSTRLEN];
4223  int size = sizeof (socket);
4224  DBusString path_str;
4225 
4226  if (getsockname (fd, &socket.sa, &size))
4227  goto err;
4228 
4229  switch (socket.sa.sa_family)
4230  {
4231  case AF_UNIX:
4232  if (socket.un.sun_path[0]=='\0')
4233  {
4234  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4235  if (_dbus_string_append (address, "unix:abstract=") &&
4236  _dbus_address_append_escaped (address, &path_str))
4237  return TRUE;
4238  }
4239  else
4240  {
4241  _dbus_string_init_const (&path_str, socket.un.sun_path);
4242  if (_dbus_string_append (address, "unix:path=") &&
4243  _dbus_address_append_escaped (address, &path_str))
4244  return TRUE;
4245  }
4246  break;
4247  case AF_INET:
4248  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4249  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4250  hostip, ntohs (socket.ipv4.sin_port)))
4251  return TRUE;
4252  break;
4253 #ifdef AF_INET6
4254  case AF_INET6:
4255  _dbus_string_init_const (&path_str, hostip);
4256  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4257  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4258  ntohs (socket.ipv6.sin6_port)) &&
4259  _dbus_address_append_escaped (address, &path_str))
4260  return TRUE;
4261  break;
4262 #endif
4263  default:
4264  dbus_set_error (error,
4265  _dbus_error_from_errno (EINVAL),
4266  "Failed to read address from socket: Unknown socket type.");
4267  return FALSE;
4268  }
4269  err:
4270  dbus_set_error (error,
4271  _dbus_error_from_errno (errno),
4272  "Failed to open socket: %s",
4273  _dbus_strerror (errno));
4274  return FALSE;
4275 }
4276 
4277 /* 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:918
dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:227
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:392
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++.
#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:232
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:302
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
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:743
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_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:304
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).
dbus_bool_t _dbus_append_address_from_socket(int fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
#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:114
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:110
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:349
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_gid_t primary_gid
GID.
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials...
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h:296
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:310
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:294
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:473
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:763
short events
Events to poll for.
Definition: dbus-sysdeps.h:313
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:1265
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:103
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:105
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:185
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:614
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:461
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:96
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:461
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:298
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
dbus_uid_t uid
UID.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1096
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
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_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:312
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:1139
#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:107
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_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:857
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:112
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.
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:508
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.
void _dbus_exit(int code)
Exit the process, returning the given value.
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. ...
#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_generate_uuid(DBusGUID *uuid)
Generates a new UUID.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:785
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
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:859
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:100
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.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:98
short revents
Events that occurred.
Definition: dbus-sysdeps.h:314
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
void _dbus_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:300