D-Bus  1.8.16
dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-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 
1665  DBusCredentials *credentials,
1666  DBusError *error)
1667 {
1668  struct msghdr msg;
1669  struct iovec iov;
1670  char buf;
1671  dbus_uid_t uid_read;
1672  dbus_pid_t pid_read;
1673  int bytes_read;
1674 
1675 #ifdef HAVE_CMSGCRED
1676  union {
1677  struct cmsghdr hdr;
1678  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1679  } cmsg;
1680 #endif
1681 
1682  uid_read = DBUS_UID_UNSET;
1683  pid_read = DBUS_PID_UNSET;
1684 
1685  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1686 
1687  /* The POSIX spec certainly doesn't promise this, but
1688  * we need these assertions to fail as soon as we're wrong about
1689  * it so we can do the porting fixups
1690  */
1691  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1692  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1693  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1694 
1695  _dbus_credentials_clear (credentials);
1696 
1697  iov.iov_base = &buf;
1698  iov.iov_len = 1;
1699 
1700  _DBUS_ZERO(msg);
1701  msg.msg_iov = &iov;
1702  msg.msg_iovlen = 1;
1703 
1704 #if defined(HAVE_CMSGCRED)
1705  _DBUS_ZERO(cmsg);
1706  msg.msg_control = (caddr_t) &cmsg;
1707  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1708 #endif
1709 
1710  again:
1711  bytes_read = recvmsg (client_fd, &msg, 0);
1712 
1713  if (bytes_read < 0)
1714  {
1715  if (errno == EINTR)
1716  goto again;
1717 
1718  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1719  * normally only call read_credentials if the socket was ready
1720  * for reading
1721  */
1722 
1723  dbus_set_error (error, _dbus_error_from_errno (errno),
1724  "Failed to read credentials byte: %s",
1725  _dbus_strerror (errno));
1726  return FALSE;
1727  }
1728  else if (bytes_read == 0)
1729  {
1730  /* this should not happen unless we are using recvmsg wrong,
1731  * so is essentially here for paranoia
1732  */
1734  "Failed to read credentials byte (zero-length read)");
1735  return FALSE;
1736  }
1737  else if (buf != '\0')
1738  {
1740  "Credentials byte was not nul");
1741  return FALSE;
1742  }
1743 
1744  _dbus_verbose ("read credentials byte\n");
1745 
1746  {
1747 #ifdef SO_PEERCRED
1748  /* Supported by at least Linux and OpenBSD, with minor differences.
1749  *
1750  * This mechanism passes the process ID through and does not require
1751  * the peer's cooperation, so we prefer it over all others. Notably,
1752  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1753  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1754  * because this is much less fragile.
1755  */
1756 #ifdef __OpenBSD__
1757  struct sockpeercred cr;
1758 #else
1759  struct ucred cr;
1760 #endif
1761  int cr_len = sizeof (cr);
1762 
1763  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1764  cr_len == sizeof (cr))
1765  {
1766  pid_read = cr.pid;
1767  uid_read = cr.uid;
1768  }
1769  else
1770  {
1771  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1772  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1773  }
1774 #elif defined(HAVE_CMSGCRED)
1775  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1776  * presence of that struct implies SCM_CREDS. Supported by at least
1777  * FreeBSD and DragonflyBSD.
1778  *
1779  * This mechanism requires the peer to help us (it has to send us a
1780  * SCM_CREDS message) but it does pass the process ID through,
1781  * which makes it better than getpeereid().
1782  */
1783  struct cmsgcred *cred;
1784  struct cmsghdr *cmsgp;
1785 
1786  for (cmsgp = CMSG_FIRSTHDR (&msg);
1787  cmsgp != NULL;
1788  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
1789  {
1790  if (cmsgp->cmsg_type == SCM_CREDS &&
1791  cmsgp->cmsg_level == SOL_SOCKET &&
1792  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
1793  {
1794  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
1795  pid_read = cred->cmcred_pid;
1796  uid_read = cred->cmcred_euid;
1797  break;
1798  }
1799  }
1800 
1801 #elif defined(HAVE_GETPEERUCRED)
1802  /* Supported in at least Solaris >= 10. It should probably be higher
1803  * up this list, because it carries the pid and we use this code path
1804  * for audit data. */
1805  ucred_t * ucred = NULL;
1806  if (getpeerucred (client_fd, &ucred) == 0)
1807  {
1808  pid_read = ucred_getpid (ucred);
1809  uid_read = ucred_geteuid (ucred);
1810 #ifdef HAVE_ADT
1811  /* generate audit session data based on socket ucred */
1812  adt_session_data_t *adth = NULL;
1813  adt_export_data_t *data = NULL;
1814  size_t size = 0;
1815  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1816  {
1817  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1818  }
1819  else
1820  {
1821  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1822  {
1823  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1824  }
1825  else
1826  {
1827  size = adt_export_session_data (adth, &data);
1828  if (size <= 0)
1829  {
1830  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1831  }
1832  else
1833  {
1834  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1835  free (data);
1836  }
1837  }
1838  (void) adt_end_session (adth);
1839  }
1840 #endif /* HAVE_ADT */
1841  }
1842  else
1843  {
1844  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1845  }
1846  if (ucred != NULL)
1847  ucred_free (ucred);
1848 
1849  /* ----------------------------------------------------------------
1850  * When adding new mechanisms, please add them above this point
1851  * if they support passing the process ID through, or below if not.
1852  * ---------------------------------------------------------------- */
1853 
1854 #elif defined(HAVE_GETPEEREID)
1855  /* getpeereid() originates from D.J. Bernstein and is fairly
1856  * widely-supported. According to a web search, it might be present in
1857  * any/all of:
1858  *
1859  * - AIX?
1860  * - Blackberry?
1861  * - Cygwin
1862  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
1863  * - Mac OS X
1864  * - Minix 3.1.8+
1865  * - MirBSD?
1866  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
1867  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
1868  * - QNX?
1869  */
1870  uid_t euid;
1871  gid_t egid;
1872  if (getpeereid (client_fd, &euid, &egid) == 0)
1873  {
1874  uid_read = euid;
1875  }
1876  else
1877  {
1878  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1879  }
1880 #else /* no supported mechanism */
1881 
1882 #warning Socket credentials not supported on this Unix OS
1883 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
1884 
1885  /* Please add other operating systems known to support at least one of
1886  * the mechanisms above to this list, keeping alphabetical order.
1887  * Everything not in this list is best-effort.
1888  */
1889 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
1890  defined(__linux__) || \
1891  defined(__OpenBSD__) || \
1892  defined(__NetBSD__)
1893 # error Credentials passing not working on this OS is a regression!
1894 #endif
1895 
1896  _dbus_verbose ("Socket credentials not supported on this OS\n");
1897 #endif
1898  }
1899 
1900  _dbus_verbose ("Credentials:"
1901  " pid "DBUS_PID_FORMAT
1902  " uid "DBUS_UID_FORMAT
1903  "\n",
1904  pid_read,
1905  uid_read);
1906 
1907  if (pid_read != DBUS_PID_UNSET)
1908  {
1909  if (!_dbus_credentials_add_pid (credentials, pid_read))
1910  {
1911  _DBUS_SET_OOM (error);
1912  return FALSE;
1913  }
1914  }
1915 
1916  if (uid_read != DBUS_UID_UNSET)
1917  {
1918  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1919  {
1920  _DBUS_SET_OOM (error);
1921  return FALSE;
1922  }
1923  }
1924 
1925  return TRUE;
1926 }
1927 
1947  DBusError *error)
1948 {
1949  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1950 
1951  if (write_credentials_byte (server_fd, error))
1952  return TRUE;
1953  else
1954  return FALSE;
1955 }
1956 
1966 int
1967 _dbus_accept (int listen_fd)
1968 {
1969  int client_fd;
1970  struct sockaddr addr;
1971  socklen_t addrlen;
1972 #ifdef HAVE_ACCEPT4
1973  dbus_bool_t cloexec_done;
1974 #endif
1975 
1976  addrlen = sizeof (addr);
1977 
1978  retry:
1979 
1980 #ifdef HAVE_ACCEPT4
1981  /*
1982  * At compile-time, we assume that if accept4() is available in
1983  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
1984  * not necessarily true that either is supported by the running kernel.
1985  */
1986  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1987  cloexec_done = client_fd >= 0;
1988 
1989  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
1990 #endif
1991  {
1992  client_fd = accept (listen_fd, &addr, &addrlen);
1993  }
1994 
1995  if (client_fd < 0)
1996  {
1997  if (errno == EINTR)
1998  goto retry;
1999  }
2000 
2001  _dbus_verbose ("client fd %d accepted\n", client_fd);
2002 
2003 #ifdef HAVE_ACCEPT4
2004  if (!cloexec_done)
2005 #endif
2006  {
2007  _dbus_fd_set_close_on_exec(client_fd);
2008  }
2009 
2010  return client_fd;
2011 }
2012 
2023 {
2024  const char *directory;
2025  struct stat sb;
2026 
2027  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2028 
2029  directory = _dbus_string_get_const_data (dir);
2030 
2031  if (stat (directory, &sb) < 0)
2032  {
2033  dbus_set_error (error, _dbus_error_from_errno (errno),
2034  "%s", _dbus_strerror (errno));
2035 
2036  return FALSE;
2037  }
2038 
2039  if (sb.st_uid != geteuid ())
2040  {
2042  "%s directory is owned by user %lu, not %lu",
2043  directory,
2044  (unsigned long) sb.st_uid,
2045  (unsigned long) geteuid ());
2046  return FALSE;
2047  }
2048 
2049  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2050  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2051  {
2053  "%s directory is not private to the user", directory);
2054  return FALSE;
2055  }
2056 
2057  return TRUE;
2058 }
2059 
2060 static dbus_bool_t
2061 fill_user_info_from_passwd (struct passwd *p,
2062  DBusUserInfo *info,
2063  DBusError *error)
2064 {
2065  _dbus_assert (p->pw_name != NULL);
2066  _dbus_assert (p->pw_dir != NULL);
2067 
2068  info->uid = p->pw_uid;
2069  info->primary_gid = p->pw_gid;
2070  info->username = _dbus_strdup (p->pw_name);
2071  info->homedir = _dbus_strdup (p->pw_dir);
2072 
2073  if (info->username == NULL ||
2074  info->homedir == NULL)
2075  {
2077  return FALSE;
2078  }
2079 
2080  return TRUE;
2081 }
2082 
2083 static dbus_bool_t
2084 fill_user_info (DBusUserInfo *info,
2085  dbus_uid_t uid,
2086  const DBusString *username,
2087  DBusError *error)
2088 {
2089  const char *username_c;
2090 
2091  /* exactly one of username/uid provided */
2092  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2093  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2094 
2095  info->uid = DBUS_UID_UNSET;
2096  info->primary_gid = DBUS_GID_UNSET;
2097  info->group_ids = NULL;
2098  info->n_group_ids = 0;
2099  info->username = NULL;
2100  info->homedir = NULL;
2101 
2102  if (username != NULL)
2103  username_c = _dbus_string_get_const_data (username);
2104  else
2105  username_c = NULL;
2106 
2107  /* For now assuming that the getpwnam() and getpwuid() flavors
2108  * are always symmetrical, if not we have to add more configure
2109  * checks
2110  */
2111 
2112 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2113  {
2114  struct passwd *p;
2115  int result;
2116  size_t buflen;
2117  char *buf;
2118  struct passwd p_str;
2119 
2120  /* retrieve maximum needed size for buf */
2121  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2122 
2123  /* sysconf actually returns a long, but everything else expects size_t,
2124  * so just recast here.
2125  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2126  */
2127  if ((long) buflen <= 0)
2128  buflen = 1024;
2129 
2130  result = -1;
2131  while (1)
2132  {
2133  buf = dbus_malloc (buflen);
2134  if (buf == NULL)
2135  {
2137  return FALSE;
2138  }
2139 
2140  p = NULL;
2141 #ifdef HAVE_POSIX_GETPWNAM_R
2142  if (uid != DBUS_UID_UNSET)
2143  result = getpwuid_r (uid, &p_str, buf, buflen,
2144  &p);
2145  else
2146  result = getpwnam_r (username_c, &p_str, buf, buflen,
2147  &p);
2148 #else
2149  if (uid != DBUS_UID_UNSET)
2150  p = getpwuid_r (uid, &p_str, buf, buflen);
2151  else
2152  p = getpwnam_r (username_c, &p_str, buf, buflen);
2153  result = 0;
2154 #endif /* !HAVE_POSIX_GETPWNAM_R */
2155  //Try a bigger buffer if ERANGE was returned
2156  if (result == ERANGE && buflen < 512 * 1024)
2157  {
2158  dbus_free (buf);
2159  buflen *= 2;
2160  }
2161  else
2162  {
2163  break;
2164  }
2165  }
2166  if (result == 0 && p == &p_str)
2167  {
2168  if (!fill_user_info_from_passwd (p, info, error))
2169  {
2170  dbus_free (buf);
2171  return FALSE;
2172  }
2173  dbus_free (buf);
2174  }
2175  else
2176  {
2177  dbus_set_error (error, _dbus_error_from_errno (errno),
2178  "User \"%s\" unknown or no memory to allocate password entry\n",
2179  username_c ? username_c : "???");
2180  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2181  dbus_free (buf);
2182  return FALSE;
2183  }
2184  }
2185 #else /* ! HAVE_GETPWNAM_R */
2186  {
2187  /* I guess we're screwed on thread safety here */
2188  struct passwd *p;
2189 
2190  if (uid != DBUS_UID_UNSET)
2191  p = getpwuid (uid);
2192  else
2193  p = getpwnam (username_c);
2194 
2195  if (p != NULL)
2196  {
2197  if (!fill_user_info_from_passwd (p, info, error))
2198  {
2199  return FALSE;
2200  }
2201  }
2202  else
2203  {
2204  dbus_set_error (error, _dbus_error_from_errno (errno),
2205  "User \"%s\" unknown or no memory to allocate password entry\n",
2206  username_c ? username_c : "???");
2207  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2208  return FALSE;
2209  }
2210  }
2211 #endif /* ! HAVE_GETPWNAM_R */
2212 
2213  /* Fill this in so we can use it to get groups */
2214  username_c = info->username;
2215 
2216 #ifdef HAVE_GETGROUPLIST
2217  {
2218  gid_t *buf;
2219  int buf_count;
2220  int i;
2221  int initial_buf_count;
2222 
2223  initial_buf_count = 17;
2224  buf_count = initial_buf_count;
2225  buf = dbus_new (gid_t, buf_count);
2226  if (buf == NULL)
2227  {
2229  goto failed;
2230  }
2231 
2232  if (getgrouplist (username_c,
2233  info->primary_gid,
2234  buf, &buf_count) < 0)
2235  {
2236  gid_t *new;
2237  /* Presumed cause of negative return code: buf has insufficient
2238  entries to hold the entire group list. The Linux behavior in this
2239  case is to pass back the actual number of groups in buf_count, but
2240  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2241  So as a hack, try to help out a bit by guessing a larger
2242  number of groups, within reason.. might still fail, of course,
2243  but we can at least print a more informative message. I looked up
2244  the "right way" to do this by downloading Apple's own source code
2245  for the "id" command, and it turns out that they use an
2246  undocumented library function getgrouplist_2 (!) which is not
2247  declared in any header in /usr/include (!!). That did not seem
2248  like the way to go here.
2249  */
2250  if (buf_count == initial_buf_count)
2251  {
2252  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2253  }
2254  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2255  if (new == NULL)
2256  {
2258  dbus_free (buf);
2259  goto failed;
2260  }
2261 
2262  buf = new;
2263 
2264  errno = 0;
2265  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2266  {
2267  if (errno == 0)
2268  {
2269  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2270  username_c, buf_count, buf_count);
2271  }
2272  else
2273  {
2274  dbus_set_error (error,
2275  _dbus_error_from_errno (errno),
2276  "Failed to get groups for username \"%s\" primary GID "
2277  DBUS_GID_FORMAT ": %s\n",
2278  username_c, info->primary_gid,
2279  _dbus_strerror (errno));
2280  dbus_free (buf);
2281  goto failed;
2282  }
2283  }
2284  }
2285 
2286  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2287  if (info->group_ids == NULL)
2288  {
2290  dbus_free (buf);
2291  goto failed;
2292  }
2293 
2294  for (i = 0; i < buf_count; ++i)
2295  info->group_ids[i] = buf[i];
2296 
2297  info->n_group_ids = buf_count;
2298 
2299  dbus_free (buf);
2300  }
2301 #else /* HAVE_GETGROUPLIST */
2302  {
2303  /* We just get the one group ID */
2304  info->group_ids = dbus_new (dbus_gid_t, 1);
2305  if (info->group_ids == NULL)
2306  {
2308  goto failed;
2309  }
2310 
2311  info->n_group_ids = 1;
2312 
2313  (info->group_ids)[0] = info->primary_gid;
2314  }
2315 #endif /* HAVE_GETGROUPLIST */
2316 
2317  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2318 
2319  return TRUE;
2320 
2321  failed:
2322  _DBUS_ASSERT_ERROR_IS_SET (error);
2323  return FALSE;
2324 }
2325 
2336  const DBusString *username,
2337  DBusError *error)
2338 {
2339  return fill_user_info (info, DBUS_UID_UNSET,
2340  username, error);
2341 }
2342 
2353  dbus_uid_t uid,
2354  DBusError *error)
2355 {
2356  return fill_user_info (info, uid,
2357  NULL, error);
2358 }
2359 
2369 {
2370  /* The POSIX spec certainly doesn't promise this, but
2371  * we need these assertions to fail as soon as we're wrong about
2372  * it so we can do the porting fixups
2373  */
2374  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2375  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2376  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2377 
2378  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2379  return FALSE;
2380  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2381  return FALSE;
2382 
2383  return TRUE;
2384 }
2385 
2399 {
2400  return _dbus_string_append_uint (str,
2401  _dbus_geteuid ());
2402 }
2403 
2408 dbus_pid_t
2410 {
2411  return getpid ();
2412 }
2413 
2417 dbus_uid_t
2419 {
2420  return getuid ();
2421 }
2422 
2426 dbus_uid_t
2428 {
2429  return geteuid ();
2430 }
2431 
2438 unsigned long
2440 {
2441  return getpid ();
2442 }
2443 
2452 _dbus_parse_uid (const DBusString *uid_str,
2453  dbus_uid_t *uid)
2454 {
2455  int end;
2456  long val;
2457 
2458  if (_dbus_string_get_length (uid_str) == 0)
2459  {
2460  _dbus_verbose ("UID string was zero length\n");
2461  return FALSE;
2462  }
2463 
2464  val = -1;
2465  end = 0;
2466  if (!_dbus_string_parse_int (uid_str, 0, &val,
2467  &end))
2468  {
2469  _dbus_verbose ("could not parse string as a UID\n");
2470  return FALSE;
2471  }
2472 
2473  if (end != _dbus_string_get_length (uid_str))
2474  {
2475  _dbus_verbose ("string contained trailing stuff after UID\n");
2476  return FALSE;
2477  }
2478 
2479  *uid = val;
2480 
2481  return TRUE;
2482 }
2483 
2484 #if !DBUS_USE_SYNC
2485 /* To be thread-safe by default on platforms that don't necessarily have
2486  * atomic operations (notably Debian armel, which is armv4t), we must
2487  * use a mutex that can be initialized statically, like this.
2488  * GLib >= 2.32 uses a similar system.
2489  */
2490 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2491 #endif
2492 
2501 {
2502 #if DBUS_USE_SYNC
2503  return __sync_add_and_fetch(&atomic->value, 1)-1;
2504 #else
2505  dbus_int32_t res;
2506 
2507  pthread_mutex_lock (&atomic_mutex);
2508  res = atomic->value;
2509  atomic->value += 1;
2510  pthread_mutex_unlock (&atomic_mutex);
2511 
2512  return res;
2513 #endif
2514 }
2515 
2524 {
2525 #if DBUS_USE_SYNC
2526  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2527 #else
2528  dbus_int32_t res;
2529 
2530  pthread_mutex_lock (&atomic_mutex);
2531  res = atomic->value;
2532  atomic->value -= 1;
2533  pthread_mutex_unlock (&atomic_mutex);
2534 
2535  return res;
2536 #endif
2537 }
2538 
2548 {
2549 #if DBUS_USE_SYNC
2550  __sync_synchronize ();
2551  return atomic->value;
2552 #else
2553  dbus_int32_t res;
2554 
2555  pthread_mutex_lock (&atomic_mutex);
2556  res = atomic->value;
2557  pthread_mutex_unlock (&atomic_mutex);
2558 
2559  return res;
2560 #endif
2561 }
2562 
2571 int
2573  int n_fds,
2574  int timeout_milliseconds)
2575 {
2576 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2577  /* This big thing is a constant expression and should get optimized
2578  * out of existence. So it's more robust than a configure check at
2579  * no cost.
2580  */
2581  if (_DBUS_POLLIN == POLLIN &&
2582  _DBUS_POLLPRI == POLLPRI &&
2583  _DBUS_POLLOUT == POLLOUT &&
2584  _DBUS_POLLERR == POLLERR &&
2585  _DBUS_POLLHUP == POLLHUP &&
2586  _DBUS_POLLNVAL == POLLNVAL &&
2587  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2588  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2589  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2590  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2591  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2592  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2593  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2594  {
2595  return poll ((struct pollfd*) fds,
2596  n_fds,
2597  timeout_milliseconds);
2598  }
2599  else
2600  {
2601  /* We have to convert the DBusPollFD to an array of
2602  * struct pollfd, poll, and convert back.
2603  */
2604  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2605  return -1;
2606  }
2607 #else /* ! HAVE_POLL */
2608 
2609  fd_set read_set, write_set, err_set;
2610  int max_fd = 0;
2611  int i;
2612  struct timeval tv;
2613  int ready;
2614 
2615  FD_ZERO (&read_set);
2616  FD_ZERO (&write_set);
2617  FD_ZERO (&err_set);
2618 
2619  for (i = 0; i < n_fds; i++)
2620  {
2621  DBusPollFD *fdp = &fds[i];
2622 
2623  if (fdp->events & _DBUS_POLLIN)
2624  FD_SET (fdp->fd, &read_set);
2625 
2626  if (fdp->events & _DBUS_POLLOUT)
2627  FD_SET (fdp->fd, &write_set);
2628 
2629  FD_SET (fdp->fd, &err_set);
2630 
2631  max_fd = MAX (max_fd, fdp->fd);
2632  }
2633 
2634  tv.tv_sec = timeout_milliseconds / 1000;
2635  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2636 
2637  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2638  timeout_milliseconds < 0 ? NULL : &tv);
2639 
2640  if (ready > 0)
2641  {
2642  for (i = 0; i < n_fds; i++)
2643  {
2644  DBusPollFD *fdp = &fds[i];
2645 
2646  fdp->revents = 0;
2647 
2648  if (FD_ISSET (fdp->fd, &read_set))
2649  fdp->revents |= _DBUS_POLLIN;
2650 
2651  if (FD_ISSET (fdp->fd, &write_set))
2652  fdp->revents |= _DBUS_POLLOUT;
2653 
2654  if (FD_ISSET (fdp->fd, &err_set))
2655  fdp->revents |= _DBUS_POLLERR;
2656  }
2657  }
2658 
2659  return ready;
2660 #endif
2661 }
2662 
2670 void
2672  long *tv_usec)
2673 {
2674 #ifdef HAVE_MONOTONIC_CLOCK
2675  struct timespec ts;
2676  clock_gettime (CLOCK_MONOTONIC, &ts);
2677 
2678  if (tv_sec)
2679  *tv_sec = ts.tv_sec;
2680  if (tv_usec)
2681  *tv_usec = ts.tv_nsec / 1000;
2682 #else
2683  struct timeval t;
2684 
2685  gettimeofday (&t, NULL);
2686 
2687  if (tv_sec)
2688  *tv_sec = t.tv_sec;
2689  if (tv_usec)
2690  *tv_usec = t.tv_usec;
2691 #endif
2692 }
2693 
2701 void
2702 _dbus_get_real_time (long *tv_sec,
2703  long *tv_usec)
2704 {
2705  struct timeval t;
2706 
2707  gettimeofday (&t, NULL);
2708 
2709  if (tv_sec)
2710  *tv_sec = t.tv_sec;
2711  if (tv_usec)
2712  *tv_usec = t.tv_usec;
2713 }
2714 
2725  DBusError *error)
2726 {
2727  const char *filename_c;
2728 
2729  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2730 
2731  filename_c = _dbus_string_get_const_data (filename);
2732 
2733  if (mkdir (filename_c, 0700) < 0)
2734  {
2735  if (errno == EEXIST)
2736  return TRUE;
2737 
2739  "Failed to create directory %s: %s\n",
2740  filename_c, _dbus_strerror (errno));
2741  return FALSE;
2742  }
2743  else
2744  return TRUE;
2745 }
2746 
2759  const DBusString *next_component)
2760 {
2761  dbus_bool_t dir_ends_in_slash;
2762  dbus_bool_t file_starts_with_slash;
2763 
2764  if (_dbus_string_get_length (dir) == 0 ||
2765  _dbus_string_get_length (next_component) == 0)
2766  return TRUE;
2767 
2768  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2769  _dbus_string_get_length (dir) - 1);
2770 
2771  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2772 
2773  if (dir_ends_in_slash && file_starts_with_slash)
2774  {
2775  _dbus_string_shorten (dir, 1);
2776  }
2777  else if (!(dir_ends_in_slash || file_starts_with_slash))
2778  {
2779  if (!_dbus_string_append_byte (dir, '/'))
2780  return FALSE;
2781  }
2782 
2783  return _dbus_string_copy (next_component, 0, dir,
2784  _dbus_string_get_length (dir));
2785 }
2786 
2788 #define NANOSECONDS_PER_SECOND 1000000000
2789 
2790 #define MICROSECONDS_PER_SECOND 1000000
2791 
2792 #define MILLISECONDS_PER_SECOND 1000
2793 
2794 #define NANOSECONDS_PER_MILLISECOND 1000000
2795 
2796 #define MICROSECONDS_PER_MILLISECOND 1000
2797 
2802 void
2803 _dbus_sleep_milliseconds (int milliseconds)
2804 {
2805 #ifdef HAVE_NANOSLEEP
2806  struct timespec req;
2807  struct timespec rem;
2808 
2809  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2810  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2811  rem.tv_sec = 0;
2812  rem.tv_nsec = 0;
2813 
2814  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2815  req = rem;
2816 #elif defined (HAVE_USLEEP)
2817  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2818 #else /* ! HAVE_USLEEP */
2819  sleep (MAX (milliseconds / 1000, 1));
2820 #endif
2821 }
2822 
2823 static dbus_bool_t
2824 _dbus_generate_pseudorandom_bytes (DBusString *str,
2825  int n_bytes)
2826 {
2827  int old_len;
2828  char *p;
2829 
2830  old_len = _dbus_string_get_length (str);
2831 
2832  if (!_dbus_string_lengthen (str, n_bytes))
2833  return FALSE;
2834 
2835  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2836 
2838 
2839  return TRUE;
2840 }
2841 
2852  int n_bytes)
2853 {
2854  int old_len;
2855  int fd;
2856 
2857  /* FALSE return means "no memory", if it could
2858  * mean something else then we'd need to return
2859  * a DBusError. So we always fall back to pseudorandom
2860  * if the I/O fails.
2861  */
2862 
2863  old_len = _dbus_string_get_length (str);
2864  fd = -1;
2865 
2866  /* note, urandom on linux will fall back to pseudorandom */
2867  fd = open ("/dev/urandom", O_RDONLY);
2868  if (fd < 0)
2869  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2870 
2871  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2872 
2873  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2874  {
2875  _dbus_close (fd, NULL);
2876  _dbus_string_set_length (str, old_len);
2877  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2878  }
2879 
2880  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2881  n_bytes);
2882 
2883  _dbus_close (fd, NULL);
2884 
2885  return TRUE;
2886 }
2887 
2893 void
2894 _dbus_exit (int code)
2895 {
2896  _exit (code);
2897 }
2898 
2907 const char*
2908 _dbus_strerror (int error_number)
2909 {
2910  const char *msg;
2911 
2912  msg = strerror (error_number);
2913  if (msg == NULL)
2914  msg = "unknown";
2915 
2916  return msg;
2917 }
2918 
2922 void
2924 {
2925  signal (SIGPIPE, SIG_IGN);
2926 }
2927 
2935 void
2937 {
2938  int val;
2939 
2940  val = fcntl (fd, F_GETFD, 0);
2941 
2942  if (val < 0)
2943  return;
2944 
2945  val |= FD_CLOEXEC;
2946 
2947  fcntl (fd, F_SETFD, val);
2948 }
2949 
2958 _dbus_close (int fd,
2959  DBusError *error)
2960 {
2961  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2962 
2963  again:
2964  if (close (fd) < 0)
2965  {
2966  if (errno == EINTR)
2967  goto again;
2968 
2969  dbus_set_error (error, _dbus_error_from_errno (errno),
2970  "Could not close fd %d", fd);
2971  return FALSE;
2972  }
2973 
2974  return TRUE;
2975 }
2976 
2985 int
2986 _dbus_dup(int fd,
2987  DBusError *error)
2988 {
2989  int new_fd;
2990 
2991 #ifdef F_DUPFD_CLOEXEC
2992  dbus_bool_t cloexec_done;
2993 
2994  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2995  cloexec_done = new_fd >= 0;
2996 
2997  if (new_fd < 0 && errno == EINVAL)
2998 #endif
2999  {
3000  new_fd = fcntl(fd, F_DUPFD, 3);
3001  }
3002 
3003  if (new_fd < 0) {
3004 
3005  dbus_set_error (error, _dbus_error_from_errno (errno),
3006  "Could not duplicate fd %d", fd);
3007  return -1;
3008  }
3009 
3010 #ifdef F_DUPFD_CLOEXEC
3011  if (!cloexec_done)
3012 #endif
3013  {
3015  }
3016 
3017  return new_fd;
3018 }
3019 
3028 _dbus_set_fd_nonblocking (int fd,
3029  DBusError *error)
3030 {
3031  int val;
3032 
3033  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3034 
3035  val = fcntl (fd, F_GETFL, 0);
3036  if (val < 0)
3037  {
3038  dbus_set_error (error, _dbus_error_from_errno (errno),
3039  "Failed to get flags from file descriptor %d: %s",
3040  fd, _dbus_strerror (errno));
3041  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3042  _dbus_strerror (errno));
3043  return FALSE;
3044  }
3045 
3046  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3047  {
3048  dbus_set_error (error, _dbus_error_from_errno (errno),
3049  "Failed to set nonblocking flag of file descriptor %d: %s",
3050  fd, _dbus_strerror (errno));
3051  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3052  fd, _dbus_strerror (errno));
3053 
3054  return FALSE;
3055  }
3056 
3057  return TRUE;
3058 }
3059 
3065 void
3067 {
3068 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3069  void *bt[500];
3070  int bt_size;
3071  int i;
3072  char **syms;
3073 
3074  bt_size = backtrace (bt, 500);
3075 
3076  syms = backtrace_symbols (bt, bt_size);
3077 
3078  i = 0;
3079  while (i < bt_size)
3080  {
3081  /* don't use dbus_warn since it can _dbus_abort() */
3082  fprintf (stderr, " %s\n", syms[i]);
3083  ++i;
3084  }
3085  fflush (stderr);
3086 
3087  free (syms);
3088 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3089  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3090 #else
3091  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3092 #endif
3093 }
3094 
3109  int *fd2,
3110  dbus_bool_t blocking,
3111  DBusError *error)
3112 {
3113 #ifdef HAVE_SOCKETPAIR
3114  int fds[2];
3115  int retval;
3116 
3117 #ifdef SOCK_CLOEXEC
3118  dbus_bool_t cloexec_done;
3119 
3120  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3121  cloexec_done = retval >= 0;
3122 
3123  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3124 #endif
3125  {
3126  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3127  }
3128 
3129  if (retval < 0)
3130  {
3131  dbus_set_error (error, _dbus_error_from_errno (errno),
3132  "Could not create full-duplex pipe");
3133  return FALSE;
3134  }
3135 
3136  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3137 
3138 #ifdef SOCK_CLOEXEC
3139  if (!cloexec_done)
3140 #endif
3141  {
3142  _dbus_fd_set_close_on_exec (fds[0]);
3143  _dbus_fd_set_close_on_exec (fds[1]);
3144  }
3145 
3146  if (!blocking &&
3147  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3148  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3149  {
3150  dbus_set_error (error, _dbus_error_from_errno (errno),
3151  "Could not set full-duplex pipe nonblocking");
3152 
3153  _dbus_close (fds[0], NULL);
3154  _dbus_close (fds[1], NULL);
3155 
3156  return FALSE;
3157  }
3158 
3159  *fd1 = fds[0];
3160  *fd2 = fds[1];
3161 
3162  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3163  *fd1, *fd2);
3164 
3165  return TRUE;
3166 #else
3167  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3169  "_dbus_full_duplex_pipe() not implemented on this OS");
3170  return FALSE;
3171 #endif
3172 }
3173 
3182 int
3184  va_list args)
3185 {
3186  char static_buf[1024];
3187  int bufsize = sizeof (static_buf);
3188  int len;
3189  va_list args_copy;
3190 
3191  DBUS_VA_COPY (args_copy, args);
3192  len = vsnprintf (static_buf, bufsize, format, args_copy);
3193  va_end (args_copy);
3194 
3195  /* If vsnprintf() returned non-negative, then either the string fits in
3196  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3197  * returns the number of characters that were needed, or this OS returns the
3198  * truncated length.
3199  *
3200  * We ignore the possibility that snprintf might just ignore the length and
3201  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3202  * If your libc is really that bad, come back when you have a better one. */
3203  if (len == bufsize)
3204  {
3205  /* This could be the truncated length (Tru64 and IRIX have this bug),
3206  * or the real length could be coincidentally the same. Which is it?
3207  * If vsnprintf returns the truncated length, we'll go to the slow
3208  * path. */
3209  DBUS_VA_COPY (args_copy, args);
3210 
3211  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3212  len = -1;
3213 
3214  va_end (args_copy);
3215  }
3216 
3217  /* If vsnprintf() returned negative, we have to do more work.
3218  * HP-UX returns negative. */
3219  while (len < 0)
3220  {
3221  char *buf;
3222 
3223  bufsize *= 2;
3224 
3225  buf = dbus_malloc (bufsize);
3226 
3227  if (buf == NULL)
3228  return -1;
3229 
3230  DBUS_VA_COPY (args_copy, args);
3231  len = vsnprintf (buf, bufsize, format, args_copy);
3232  va_end (args_copy);
3233 
3234  dbus_free (buf);
3235 
3236  /* If the reported length is exactly the buffer size, round up to the
3237  * next size, in case vsnprintf has been returning the truncated
3238  * length */
3239  if (len == bufsize)
3240  len = -1;
3241  }
3242 
3243  return len;
3244 }
3245 
3252 const char*
3254 {
3255  /* Protected by _DBUS_LOCK_sysdeps */
3256  static const char* tmpdir = NULL;
3257 
3258  if (!_DBUS_LOCK (sysdeps))
3259  return NULL;
3260 
3261  if (tmpdir == NULL)
3262  {
3263  /* TMPDIR is what glibc uses, then
3264  * glibc falls back to the P_tmpdir macro which
3265  * just expands to "/tmp"
3266  */
3267  if (tmpdir == NULL)
3268  tmpdir = getenv("TMPDIR");
3269 
3270  /* These two env variables are probably
3271  * broken, but maybe some OS uses them?
3272  */
3273  if (tmpdir == NULL)
3274  tmpdir = getenv("TMP");
3275  if (tmpdir == NULL)
3276  tmpdir = getenv("TEMP");
3277 
3278  /* And this is the sane fallback. */
3279  if (tmpdir == NULL)
3280  tmpdir = "/tmp";
3281  }
3282 
3283  _DBUS_UNLOCK (sysdeps);
3284 
3285  _dbus_assert(tmpdir != NULL);
3286 
3287  return tmpdir;
3288 }
3289 
3290 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3291 
3310 static dbus_bool_t
3311 _read_subprocess_line_argv (const char *progpath,
3312  dbus_bool_t path_fallback,
3313  char * const *argv,
3314  DBusString *result,
3315  DBusError *error)
3316 {
3317  int result_pipe[2] = { -1, -1 };
3318  int errors_pipe[2] = { -1, -1 };
3319  pid_t pid;
3320  int ret;
3321  int status;
3322  int orig_len;
3323 
3324  dbus_bool_t retval;
3325  sigset_t new_set, old_set;
3326 
3327  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3328  retval = FALSE;
3329 
3330  /* We need to block any existing handlers for SIGCHLD temporarily; they
3331  * will cause waitpid() below to fail.
3332  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3333  */
3334  sigemptyset (&new_set);
3335  sigaddset (&new_set, SIGCHLD);
3336  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3337 
3338  orig_len = _dbus_string_get_length (result);
3339 
3340 #define READ_END 0
3341 #define WRITE_END 1
3342  if (pipe (result_pipe) < 0)
3343  {
3344  dbus_set_error (error, _dbus_error_from_errno (errno),
3345  "Failed to create a pipe to call %s: %s",
3346  progpath, _dbus_strerror (errno));
3347  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3348  progpath, _dbus_strerror (errno));
3349  goto out;
3350  }
3351  if (pipe (errors_pipe) < 0)
3352  {
3353  dbus_set_error (error, _dbus_error_from_errno (errno),
3354  "Failed to create a pipe to call %s: %s",
3355  progpath, _dbus_strerror (errno));
3356  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3357  progpath, _dbus_strerror (errno));
3358  goto out;
3359  }
3360 
3361  pid = fork ();
3362  if (pid < 0)
3363  {
3364  dbus_set_error (error, _dbus_error_from_errno (errno),
3365  "Failed to fork() to call %s: %s",
3366  progpath, _dbus_strerror (errno));
3367  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3368  progpath, _dbus_strerror (errno));
3369  goto out;
3370  }
3371 
3372  if (pid == 0)
3373  {
3374  /* child process */
3375  int fd;
3376 
3377  fd = open ("/dev/null", O_RDWR);
3378  if (fd == -1)
3379  /* huh?! can't open /dev/null? */
3380  _exit (1);
3381 
3382  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3383 
3384  /* set-up stdXXX */
3385  close (result_pipe[READ_END]);
3386  close (errors_pipe[READ_END]);
3387 
3388  if (dup2 (fd, 0) == -1) /* setup stdin */
3389  _exit (1);
3390  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3391  _exit (1);
3392  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3393  _exit (1);
3394 
3395  _dbus_close_all ();
3396 
3397  sigprocmask (SIG_SETMASK, &old_set, NULL);
3398 
3399  /* If it looks fully-qualified, try execv first */
3400  if (progpath[0] == '/')
3401  {
3402  execv (progpath, argv);
3403  /* Ok, that failed. Now if path_fallback is given, let's
3404  * try unqualified. This is mostly a hack to work
3405  * around systems which ship dbus-launch in /usr/bin
3406  * but everything else in /bin (because dbus-launch
3407  * depends on X11).
3408  */
3409  if (path_fallback)
3410  /* We must have a slash, because we checked above */
3411  execvp (strrchr (progpath, '/')+1, argv);
3412  }
3413  else
3414  execvp (progpath, argv);
3415 
3416  /* still nothing, we failed */
3417  _exit (1);
3418  }
3419 
3420  /* parent process */
3421  close (result_pipe[WRITE_END]);
3422  close (errors_pipe[WRITE_END]);
3423  result_pipe[WRITE_END] = -1;
3424  errors_pipe[WRITE_END] = -1;
3425 
3426  ret = 0;
3427  do
3428  {
3429  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3430  }
3431  while (ret > 0);
3432 
3433  /* reap the child process to avoid it lingering as zombie */
3434  do
3435  {
3436  ret = waitpid (pid, &status, 0);
3437  }
3438  while (ret == -1 && errno == EINTR);
3439 
3440  /* We succeeded if the process exited with status 0 and
3441  anything was read */
3442  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3443  {
3444  /* The process ended with error */
3445  DBusString error_message;
3446  if (!_dbus_string_init (&error_message))
3447  {
3448  _DBUS_SET_OOM (error);
3449  goto out;
3450  }
3451 
3452  ret = 0;
3453  do
3454  {
3455  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3456  }
3457  while (ret > 0);
3458 
3459  _dbus_string_set_length (result, orig_len);
3460  if (_dbus_string_get_length (&error_message) > 0)
3462  "%s terminated abnormally with the following error: %s",
3463  progpath, _dbus_string_get_data (&error_message));
3464  else
3466  "%s terminated abnormally without any error message",
3467  progpath);
3468  goto out;
3469  }
3470 
3471  retval = TRUE;
3472 
3473  out:
3474  sigprocmask (SIG_SETMASK, &old_set, NULL);
3475 
3476  if (retval)
3477  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3478  else
3479  _DBUS_ASSERT_ERROR_IS_SET (error);
3480 
3481  if (result_pipe[0] != -1)
3482  close (result_pipe[0]);
3483  if (result_pipe[1] != -1)
3484  close (result_pipe[1]);
3485  if (errors_pipe[0] != -1)
3486  close (errors_pipe[0]);
3487  if (errors_pipe[1] != -1)
3488  close (errors_pipe[1]);
3489 
3490  return retval;
3491 }
3492 #endif
3493 
3507 _dbus_get_autolaunch_address (const char *scope,
3508  DBusString *address,
3509  DBusError *error)
3510 {
3511 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3512  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3513  * but that's done elsewhere, and if it worked, this function wouldn't
3514  * be called.) */
3515  const char *display;
3516  char *argv[6];
3517  int i;
3518  DBusString uuid;
3519  dbus_bool_t retval;
3520 
3521  if (_dbus_check_setuid ())
3522  {
3524  "Unable to autolaunch when setuid");
3525  return FALSE;
3526  }
3527 
3528  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3529  retval = FALSE;
3530 
3531  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3532  * dbus-launch-x11 is just going to fail. Rather than trying to
3533  * run it, we might as well bail out early with a nice error. */
3534  display = _dbus_getenv ("DISPLAY");
3535 
3536  if (display == NULL || display[0] == '\0')
3537  {
3539  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3540  return FALSE;
3541  }
3542 
3543  if (!_dbus_string_init (&uuid))
3544  {
3545  _DBUS_SET_OOM (error);
3546  return FALSE;
3547  }
3548 
3550  {
3551  _DBUS_SET_OOM (error);
3552  goto out;
3553  }
3554 
3555  i = 0;
3556 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3557  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3558  argv[i] = TEST_BUS_LAUNCH_BINARY;
3559  else
3560 #endif
3561  argv[i] = DBUS_BINDIR "/dbus-launch";
3562  ++i;
3563  argv[i] = "--autolaunch";
3564  ++i;
3565  argv[i] = _dbus_string_get_data (&uuid);
3566  ++i;
3567  argv[i] = "--binary-syntax";
3568  ++i;
3569  argv[i] = "--close-stderr";
3570  ++i;
3571  argv[i] = NULL;
3572  ++i;
3573 
3574  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3575 
3576  retval = _read_subprocess_line_argv (argv[0],
3577  TRUE,
3578  argv, address, error);
3579 
3580  out:
3581  _dbus_string_free (&uuid);
3582  return retval;
3583 #else
3585  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3586  "set your DBUS_SESSION_BUS_ADDRESS instead");
3587  return FALSE;
3588 #endif
3589 }
3590 
3611  dbus_bool_t create_if_not_found,
3612  DBusError *error)
3613 {
3614  DBusString filename;
3615  dbus_bool_t b;
3616 
3617  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3618 
3619  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3620  if (b)
3621  return TRUE;
3622 
3623  dbus_error_free (error);
3624 
3625  /* Fallback to the system machine ID */
3626  _dbus_string_init_const (&filename, "/etc/machine-id");
3627  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3628 
3629  if (b)
3630  {
3631  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3632  * complain if that isn't possible for whatever reason */
3633  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3634  _dbus_write_uuid_file (&filename, machine_id, NULL);
3635 
3636  return TRUE;
3637  }
3638 
3639  if (!create_if_not_found)
3640  return FALSE;
3641 
3642  /* if none found, try to make a new one */
3643  dbus_error_free (error);
3644  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3645  _dbus_generate_uuid (machine_id);
3646  return _dbus_write_uuid_file (&filename, machine_id, error);
3647 }
3648 
3658  const char *launchd_env_var,
3659  DBusError *error)
3660 {
3661 #ifdef DBUS_ENABLE_LAUNCHD
3662  char *argv[4];
3663  int i;
3664 
3665  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3666 
3667  if (_dbus_check_setuid ())
3668  {
3670  "Unable to find launchd socket when setuid");
3671  return FALSE;
3672  }
3673 
3674  i = 0;
3675  argv[i] = "launchctl";
3676  ++i;
3677  argv[i] = "getenv";
3678  ++i;
3679  argv[i] = (char*)launchd_env_var;
3680  ++i;
3681  argv[i] = NULL;
3682  ++i;
3683 
3684  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3685 
3686  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3687  {
3688  return FALSE;
3689  }
3690 
3691  /* no error, but no result either */
3692  if (_dbus_string_get_length(socket_path) == 0)
3693  {
3694  return FALSE;
3695  }
3696 
3697  /* strip the carriage-return */
3698  _dbus_string_shorten(socket_path, 1);
3699  return TRUE;
3700 #else /* DBUS_ENABLE_LAUNCHD */
3702  "can't lookup socket from launchd; launchd support not compiled in");
3703  return FALSE;
3704 #endif
3705 }
3706 
3707 #ifdef DBUS_ENABLE_LAUNCHD
3708 static dbus_bool_t
3709 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3710 {
3711  dbus_bool_t valid_socket;
3712  DBusString socket_path;
3713 
3714  if (_dbus_check_setuid ())
3715  {
3717  "Unable to find launchd socket when setuid");
3718  return FALSE;
3719  }
3720 
3721  if (!_dbus_string_init (&socket_path))
3722  {
3723  _DBUS_SET_OOM (error);
3724  return FALSE;
3725  }
3726 
3727  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3728 
3729  if (dbus_error_is_set(error))
3730  {
3731  _dbus_string_free(&socket_path);
3732  return FALSE;
3733  }
3734 
3735  if (!valid_socket)
3736  {
3737  dbus_set_error(error, "no socket path",
3738  "launchd did not provide a socket path, "
3739  "verify that org.freedesktop.dbus-session.plist is loaded!");
3740  _dbus_string_free(&socket_path);
3741  return FALSE;
3742  }
3743  if (!_dbus_string_append (address, "unix:path="))
3744  {
3745  _DBUS_SET_OOM (error);
3746  _dbus_string_free(&socket_path);
3747  return FALSE;
3748  }
3749  if (!_dbus_string_copy (&socket_path, 0, address,
3750  _dbus_string_get_length (address)))
3751  {
3752  _DBUS_SET_OOM (error);
3753  _dbus_string_free(&socket_path);
3754  return FALSE;
3755  }
3756 
3757  _dbus_string_free(&socket_path);
3758  return TRUE;
3759 }
3760 #endif
3761 
3783  DBusString *address,
3784  DBusError *error)
3785 {
3786 #ifdef DBUS_ENABLE_LAUNCHD
3787  *supported = TRUE;
3788  return _dbus_lookup_session_address_launchd (address, error);
3789 #else
3790  /* On non-Mac Unix platforms, if the session address isn't already
3791  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3792  * fall back to the autolaunch: global default; see
3793  * init_session_address in dbus/dbus-bus.c. */
3794  *supported = FALSE;
3795  return TRUE;
3796 #endif
3797 }
3798 
3806 void
3808 {
3810 }
3811 
3827  DBusCredentials *credentials)
3828 {
3829  DBusString homedir;
3830  DBusString dotdir;
3831  dbus_uid_t uid;
3832 
3833  _dbus_assert (credentials != NULL);
3835 
3836  if (!_dbus_string_init (&homedir))
3837  return FALSE;
3838 
3839  uid = _dbus_credentials_get_unix_uid (credentials);
3840  _dbus_assert (uid != DBUS_UID_UNSET);
3841 
3842  if (!_dbus_homedir_from_uid (uid, &homedir))
3843  goto failed;
3844 
3845 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3846  {
3847  const char *override;
3848 
3849  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3850  if (override != NULL && *override != '\0')
3851  {
3852  _dbus_string_set_length (&homedir, 0);
3853  if (!_dbus_string_append (&homedir, override))
3854  goto failed;
3855 
3856  _dbus_verbose ("Using fake homedir for testing: %s\n",
3857  _dbus_string_get_const_data (&homedir));
3858  }
3859  else
3860  {
3861  /* Not strictly thread-safe, but if we fail at thread-safety here,
3862  * the worst that will happen is some extra warnings. */
3863  static dbus_bool_t already_warned = FALSE;
3864  if (!already_warned)
3865  {
3866  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3867  already_warned = TRUE;
3868  }
3869  }
3870  }
3871 #endif
3872 
3873  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3874  if (!_dbus_concat_dir_and_file (&homedir,
3875  &dotdir))
3876  goto failed;
3877 
3878  if (!_dbus_string_copy (&homedir, 0,
3879  directory, _dbus_string_get_length (directory))) {
3880  goto failed;
3881  }
3882 
3883  _dbus_string_free (&homedir);
3884  return TRUE;
3885 
3886  failed:
3887  _dbus_string_free (&homedir);
3888  return FALSE;
3889 }
3890 
3891 //PENDING(kdab) docs
3893 _dbus_daemon_publish_session_bus_address (const char* addr,
3894  const char *scope)
3895 {
3896  return TRUE;
3897 }
3898 
3899 //PENDING(kdab) docs
3900 void
3901 _dbus_daemon_unpublish_session_bus_address (void)
3902 {
3903 
3904 }
3905 
3914 {
3915  return errno == EAGAIN || errno == EWOULDBLOCK;
3916 }
3917 
3927  DBusError *error)
3928 {
3929  const char *filename_c;
3930 
3931  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3932 
3933  filename_c = _dbus_string_get_const_data (filename);
3934 
3935  if (rmdir (filename_c) != 0)
3936  {
3938  "Failed to remove directory %s: %s\n",
3939  filename_c, _dbus_strerror (errno));
3940  return FALSE;
3941  }
3942 
3943  return TRUE;
3944 }
3945 
3955 
3956 #ifdef SCM_RIGHTS
3957  union {
3958  struct sockaddr sa;
3959  struct sockaddr_storage storage;
3960  struct sockaddr_un un;
3961  } sa_buf;
3962 
3963  socklen_t sa_len = sizeof(sa_buf);
3964 
3965  _DBUS_ZERO(sa_buf);
3966 
3967  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3968  return FALSE;
3969 
3970  return sa_buf.sa.sa_family == AF_UNIX;
3971 
3972 #else
3973  return FALSE;
3974 
3975 #endif
3976 }
3977 
3982 void
3984 {
3985  int maxfds, i;
3986 
3987 #ifdef __linux__
3988  DIR *d;
3989 
3990  /* On Linux we can optimize this a bit if /proc is available. If it
3991  isn't available, fall back to the brute force way. */
3992 
3993  d = opendir ("/proc/self/fd");
3994  if (d)
3995  {
3996  for (;;)
3997  {
3998  struct dirent buf, *de;
3999  int k, fd;
4000  long l;
4001  char *e = NULL;
4002 
4003  k = readdir_r (d, &buf, &de);
4004  if (k != 0 || !de)
4005  break;
4006 
4007  if (de->d_name[0] == '.')
4008  continue;
4009 
4010  errno = 0;
4011  l = strtol (de->d_name, &e, 10);
4012  if (errno != 0 || e == NULL || *e != '\0')
4013  continue;
4014 
4015  fd = (int) l;
4016  if (fd < 3)
4017  continue;
4018 
4019  if (fd == dirfd (d))
4020  continue;
4021 
4022  close (fd);
4023  }
4024 
4025  closedir (d);
4026  return;
4027  }
4028 #endif
4029 
4030  maxfds = sysconf (_SC_OPEN_MAX);
4031 
4032  /* Pick something reasonable if for some reason sysconf says
4033  * unlimited.
4034  */
4035  if (maxfds < 0)
4036  maxfds = 1024;
4037 
4038  /* close all inherited fds */
4039  for (i = 3; i < maxfds; i++)
4040  close (i);
4041 }
4042 
4054 {
4055  /* TODO: get __libc_enable_secure exported from glibc.
4056  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4057  */
4058 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4059  {
4060  /* See glibc/include/unistd.h */
4061  extern int __libc_enable_secure;
4062  return __libc_enable_secure;
4063  }
4064 #elif defined(HAVE_ISSETUGID)
4065  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4066  return issetugid ();
4067 #else
4068  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4069  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4070 
4071  /* We call into this function from _dbus_threads_init_platform_specific()
4072  * to make sure these are initialized before we start threading. */
4073  static dbus_bool_t check_setuid_initialised;
4074  static dbus_bool_t is_setuid;
4075 
4076  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4077  {
4078 #ifdef HAVE_GETRESUID
4079  if (getresuid (&ruid, &euid, &suid) != 0 ||
4080  getresgid (&rgid, &egid, &sgid) != 0)
4081 #endif /* HAVE_GETRESUID */
4082  {
4083  suid = ruid = getuid ();
4084  sgid = rgid = getgid ();
4085  euid = geteuid ();
4086  egid = getegid ();
4087  }
4088 
4089  check_setuid_initialised = TRUE;
4090  is_setuid = (ruid != euid || ruid != suid ||
4091  rgid != egid || rgid != sgid);
4092 
4093  }
4094  return is_setuid;
4095 #endif
4096 }
4097 
4107  DBusString *address,
4108  DBusError *error)
4109 {
4110  union {
4111  struct sockaddr sa;
4112  struct sockaddr_storage storage;
4113  struct sockaddr_un un;
4114  struct sockaddr_in ipv4;
4115  struct sockaddr_in6 ipv6;
4116  } socket;
4117  char hostip[INET6_ADDRSTRLEN];
4118  int size = sizeof (socket);
4119  DBusString path_str;
4120 
4121  if (getsockname (fd, &socket.sa, &size))
4122  goto err;
4123 
4124  switch (socket.sa.sa_family)
4125  {
4126  case AF_UNIX:
4127  if (socket.un.sun_path[0]=='\0')
4128  {
4129  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4130  if (_dbus_string_append (address, "unix:abstract=") &&
4131  _dbus_address_append_escaped (address, &path_str))
4132  return TRUE;
4133  }
4134  else
4135  {
4136  _dbus_string_init_const (&path_str, socket.un.sun_path);
4137  if (_dbus_string_append (address, "unix:path=") &&
4138  _dbus_address_append_escaped (address, &path_str))
4139  return TRUE;
4140  }
4141  break;
4142  case AF_INET:
4143  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4144  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4145  hostip, ntohs (socket.ipv4.sin_port)))
4146  return TRUE;
4147  break;
4148 #ifdef AF_INET6
4149  case AF_INET6:
4150  _dbus_string_init_const (&path_str, hostip);
4151  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4152  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4153  ntohs (socket.ipv6.sin6_port)) &&
4154  _dbus_address_append_escaped (address, &path_str))
4155  return TRUE;
4156  break;
4157 #endif
4158  default:
4159  dbus_set_error (error,
4160  _dbus_error_from_errno (EINVAL),
4161  "Failed to read address from socket: Unknown socket type.");
4162  return FALSE;
4163  }
4164  err:
4165  dbus_set_error (error,
4166  _dbus_error_from_errno (errno),
4167  "Failed to open socket: %s",
4168  _dbus_strerror (errno));
4169  return FALSE;
4170 }
4171 
4172 /* 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.
#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_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".
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
int dbus_int32_t
A 32-bit signed integer on all platforms.
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