D-Bus  1.8.22
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 
2757  DBusError *error)
2758 {
2759  const char *filename_c;
2760 
2761  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2762 
2763  filename_c = _dbus_string_get_const_data (filename);
2764 
2765  if (mkdir (filename_c, 0700) < 0)
2766  {
2768  "Failed to create directory %s: %s\n",
2769  filename_c, _dbus_strerror (errno));
2770  return FALSE;
2771  }
2772  else
2773  return TRUE;
2774 }
2775 
2788  const DBusString *next_component)
2789 {
2790  dbus_bool_t dir_ends_in_slash;
2791  dbus_bool_t file_starts_with_slash;
2792 
2793  if (_dbus_string_get_length (dir) == 0 ||
2794  _dbus_string_get_length (next_component) == 0)
2795  return TRUE;
2796 
2797  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2798  _dbus_string_get_length (dir) - 1);
2799 
2800  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2801 
2802  if (dir_ends_in_slash && file_starts_with_slash)
2803  {
2804  _dbus_string_shorten (dir, 1);
2805  }
2806  else if (!(dir_ends_in_slash || file_starts_with_slash))
2807  {
2808  if (!_dbus_string_append_byte (dir, '/'))
2809  return FALSE;
2810  }
2811 
2812  return _dbus_string_copy (next_component, 0, dir,
2813  _dbus_string_get_length (dir));
2814 }
2815 
2817 #define NANOSECONDS_PER_SECOND 1000000000
2818 
2819 #define MICROSECONDS_PER_SECOND 1000000
2820 
2821 #define MILLISECONDS_PER_SECOND 1000
2822 
2823 #define NANOSECONDS_PER_MILLISECOND 1000000
2824 
2825 #define MICROSECONDS_PER_MILLISECOND 1000
2826 
2831 void
2832 _dbus_sleep_milliseconds (int milliseconds)
2833 {
2834 #ifdef HAVE_NANOSLEEP
2835  struct timespec req;
2836  struct timespec rem;
2837 
2838  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2839  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2840  rem.tv_sec = 0;
2841  rem.tv_nsec = 0;
2842 
2843  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2844  req = rem;
2845 #elif defined (HAVE_USLEEP)
2846  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2847 #else /* ! HAVE_USLEEP */
2848  sleep (MAX (milliseconds / 1000, 1));
2849 #endif
2850 }
2851 
2852 static dbus_bool_t
2853 _dbus_generate_pseudorandom_bytes (DBusString *str,
2854  int n_bytes)
2855 {
2856  int old_len;
2857  char *p;
2858 
2859  old_len = _dbus_string_get_length (str);
2860 
2861  if (!_dbus_string_lengthen (str, n_bytes))
2862  return FALSE;
2863 
2864  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2865 
2867 
2868  return TRUE;
2869 }
2870 
2881  int n_bytes)
2882 {
2883  int old_len;
2884  int fd;
2885 
2886  /* FALSE return means "no memory", if it could
2887  * mean something else then we'd need to return
2888  * a DBusError. So we always fall back to pseudorandom
2889  * if the I/O fails.
2890  */
2891 
2892  old_len = _dbus_string_get_length (str);
2893  fd = -1;
2894 
2895  /* note, urandom on linux will fall back to pseudorandom */
2896  fd = open ("/dev/urandom", O_RDONLY);
2897  if (fd < 0)
2898  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2899 
2900  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2901 
2902  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2903  {
2904  _dbus_close (fd, NULL);
2905  _dbus_string_set_length (str, old_len);
2906  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2907  }
2908 
2909  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2910  n_bytes);
2911 
2912  _dbus_close (fd, NULL);
2913 
2914  return TRUE;
2915 }
2916 
2922 void
2923 _dbus_exit (int code)
2924 {
2925  _exit (code);
2926 }
2927 
2936 const char*
2937 _dbus_strerror (int error_number)
2938 {
2939  const char *msg;
2940 
2941  msg = strerror (error_number);
2942  if (msg == NULL)
2943  msg = "unknown";
2944 
2945  return msg;
2946 }
2947 
2951 void
2953 {
2954  signal (SIGPIPE, SIG_IGN);
2955 }
2956 
2964 void
2966 {
2967  int val;
2968 
2969  val = fcntl (fd, F_GETFD, 0);
2970 
2971  if (val < 0)
2972  return;
2973 
2974  val |= FD_CLOEXEC;
2975 
2976  fcntl (fd, F_SETFD, val);
2977 }
2978 
2987 _dbus_close (int fd,
2988  DBusError *error)
2989 {
2990  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2991 
2992  again:
2993  if (close (fd) < 0)
2994  {
2995  if (errno == EINTR)
2996  goto again;
2997 
2998  dbus_set_error (error, _dbus_error_from_errno (errno),
2999  "Could not close fd %d", fd);
3000  return FALSE;
3001  }
3002 
3003  return TRUE;
3004 }
3005 
3014 int
3015 _dbus_dup(int fd,
3016  DBusError *error)
3017 {
3018  int new_fd;
3019 
3020 #ifdef F_DUPFD_CLOEXEC
3021  dbus_bool_t cloexec_done;
3022 
3023  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3024  cloexec_done = new_fd >= 0;
3025 
3026  if (new_fd < 0 && errno == EINVAL)
3027 #endif
3028  {
3029  new_fd = fcntl(fd, F_DUPFD, 3);
3030  }
3031 
3032  if (new_fd < 0) {
3033 
3034  dbus_set_error (error, _dbus_error_from_errno (errno),
3035  "Could not duplicate fd %d", fd);
3036  return -1;
3037  }
3038 
3039 #ifdef F_DUPFD_CLOEXEC
3040  if (!cloexec_done)
3041 #endif
3042  {
3044  }
3045 
3046  return new_fd;
3047 }
3048 
3057 _dbus_set_fd_nonblocking (int fd,
3058  DBusError *error)
3059 {
3060  int val;
3061 
3062  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3063 
3064  val = fcntl (fd, F_GETFL, 0);
3065  if (val < 0)
3066  {
3067  dbus_set_error (error, _dbus_error_from_errno (errno),
3068  "Failed to get flags from file descriptor %d: %s",
3069  fd, _dbus_strerror (errno));
3070  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3071  _dbus_strerror (errno));
3072  return FALSE;
3073  }
3074 
3075  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3076  {
3077  dbus_set_error (error, _dbus_error_from_errno (errno),
3078  "Failed to set nonblocking flag of file descriptor %d: %s",
3079  fd, _dbus_strerror (errno));
3080  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3081  fd, _dbus_strerror (errno));
3082 
3083  return FALSE;
3084  }
3085 
3086  return TRUE;
3087 }
3088 
3094 void
3096 {
3097 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3098  void *bt[500];
3099  int bt_size;
3100  int i;
3101  char **syms;
3102 
3103  bt_size = backtrace (bt, 500);
3104 
3105  syms = backtrace_symbols (bt, bt_size);
3106 
3107  i = 0;
3108  while (i < bt_size)
3109  {
3110  /* don't use dbus_warn since it can _dbus_abort() */
3111  fprintf (stderr, " %s\n", syms[i]);
3112  ++i;
3113  }
3114  fflush (stderr);
3115 
3116  free (syms);
3117 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3118  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3119 #else
3120  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3121 #endif
3122 }
3123 
3138  int *fd2,
3139  dbus_bool_t blocking,
3140  DBusError *error)
3141 {
3142 #ifdef HAVE_SOCKETPAIR
3143  int fds[2];
3144  int retval;
3145 
3146 #ifdef SOCK_CLOEXEC
3147  dbus_bool_t cloexec_done;
3148 
3149  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3150  cloexec_done = retval >= 0;
3151 
3152  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3153 #endif
3154  {
3155  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3156  }
3157 
3158  if (retval < 0)
3159  {
3160  dbus_set_error (error, _dbus_error_from_errno (errno),
3161  "Could not create full-duplex pipe");
3162  return FALSE;
3163  }
3164 
3165  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3166 
3167 #ifdef SOCK_CLOEXEC
3168  if (!cloexec_done)
3169 #endif
3170  {
3171  _dbus_fd_set_close_on_exec (fds[0]);
3172  _dbus_fd_set_close_on_exec (fds[1]);
3173  }
3174 
3175  if (!blocking &&
3176  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3177  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3178  {
3179  dbus_set_error (error, _dbus_error_from_errno (errno),
3180  "Could not set full-duplex pipe nonblocking");
3181 
3182  _dbus_close (fds[0], NULL);
3183  _dbus_close (fds[1], NULL);
3184 
3185  return FALSE;
3186  }
3187 
3188  *fd1 = fds[0];
3189  *fd2 = fds[1];
3190 
3191  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3192  *fd1, *fd2);
3193 
3194  return TRUE;
3195 #else
3196  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3198  "_dbus_full_duplex_pipe() not implemented on this OS");
3199  return FALSE;
3200 #endif
3201 }
3202 
3211 int
3213  va_list args)
3214 {
3215  char static_buf[1024];
3216  int bufsize = sizeof (static_buf);
3217  int len;
3218  va_list args_copy;
3219 
3220  DBUS_VA_COPY (args_copy, args);
3221  len = vsnprintf (static_buf, bufsize, format, args_copy);
3222  va_end (args_copy);
3223 
3224  /* If vsnprintf() returned non-negative, then either the string fits in
3225  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3226  * returns the number of characters that were needed, or this OS returns the
3227  * truncated length.
3228  *
3229  * We ignore the possibility that snprintf might just ignore the length and
3230  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3231  * If your libc is really that bad, come back when you have a better one. */
3232  if (len == bufsize)
3233  {
3234  /* This could be the truncated length (Tru64 and IRIX have this bug),
3235  * or the real length could be coincidentally the same. Which is it?
3236  * If vsnprintf returns the truncated length, we'll go to the slow
3237  * path. */
3238  DBUS_VA_COPY (args_copy, args);
3239 
3240  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3241  len = -1;
3242 
3243  va_end (args_copy);
3244  }
3245 
3246  /* If vsnprintf() returned negative, we have to do more work.
3247  * HP-UX returns negative. */
3248  while (len < 0)
3249  {
3250  char *buf;
3251 
3252  bufsize *= 2;
3253 
3254  buf = dbus_malloc (bufsize);
3255 
3256  if (buf == NULL)
3257  return -1;
3258 
3259  DBUS_VA_COPY (args_copy, args);
3260  len = vsnprintf (buf, bufsize, format, args_copy);
3261  va_end (args_copy);
3262 
3263  dbus_free (buf);
3264 
3265  /* If the reported length is exactly the buffer size, round up to the
3266  * next size, in case vsnprintf has been returning the truncated
3267  * length */
3268  if (len == bufsize)
3269  len = -1;
3270  }
3271 
3272  return len;
3273 }
3274 
3281 const char*
3283 {
3284  /* Protected by _DBUS_LOCK_sysdeps */
3285  static const char* tmpdir = NULL;
3286 
3287  if (!_DBUS_LOCK (sysdeps))
3288  return NULL;
3289 
3290  if (tmpdir == NULL)
3291  {
3292  /* TMPDIR is what glibc uses, then
3293  * glibc falls back to the P_tmpdir macro which
3294  * just expands to "/tmp"
3295  */
3296  if (tmpdir == NULL)
3297  tmpdir = getenv("TMPDIR");
3298 
3299  /* These two env variables are probably
3300  * broken, but maybe some OS uses them?
3301  */
3302  if (tmpdir == NULL)
3303  tmpdir = getenv("TMP");
3304  if (tmpdir == NULL)
3305  tmpdir = getenv("TEMP");
3306 
3307  /* And this is the sane fallback. */
3308  if (tmpdir == NULL)
3309  tmpdir = "/tmp";
3310  }
3311 
3312  _DBUS_UNLOCK (sysdeps);
3313 
3314  _dbus_assert(tmpdir != NULL);
3315 
3316  return tmpdir;
3317 }
3318 
3319 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3320 
3339 static dbus_bool_t
3340 _read_subprocess_line_argv (const char *progpath,
3341  dbus_bool_t path_fallback,
3342  char * const *argv,
3343  DBusString *result,
3344  DBusError *error)
3345 {
3346  int result_pipe[2] = { -1, -1 };
3347  int errors_pipe[2] = { -1, -1 };
3348  pid_t pid;
3349  int ret;
3350  int status;
3351  int orig_len;
3352 
3353  dbus_bool_t retval;
3354  sigset_t new_set, old_set;
3355 
3356  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3357  retval = FALSE;
3358 
3359  /* We need to block any existing handlers for SIGCHLD temporarily; they
3360  * will cause waitpid() below to fail.
3361  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3362  */
3363  sigemptyset (&new_set);
3364  sigaddset (&new_set, SIGCHLD);
3365  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3366 
3367  orig_len = _dbus_string_get_length (result);
3368 
3369 #define READ_END 0
3370 #define WRITE_END 1
3371  if (pipe (result_pipe) < 0)
3372  {
3373  dbus_set_error (error, _dbus_error_from_errno (errno),
3374  "Failed to create a pipe to call %s: %s",
3375  progpath, _dbus_strerror (errno));
3376  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3377  progpath, _dbus_strerror (errno));
3378  goto out;
3379  }
3380  if (pipe (errors_pipe) < 0)
3381  {
3382  dbus_set_error (error, _dbus_error_from_errno (errno),
3383  "Failed to create a pipe to call %s: %s",
3384  progpath, _dbus_strerror (errno));
3385  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3386  progpath, _dbus_strerror (errno));
3387  goto out;
3388  }
3389 
3390  pid = fork ();
3391  if (pid < 0)
3392  {
3393  dbus_set_error (error, _dbus_error_from_errno (errno),
3394  "Failed to fork() to call %s: %s",
3395  progpath, _dbus_strerror (errno));
3396  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3397  progpath, _dbus_strerror (errno));
3398  goto out;
3399  }
3400 
3401  if (pid == 0)
3402  {
3403  /* child process */
3404  int fd;
3405 
3406  fd = open ("/dev/null", O_RDWR);
3407  if (fd == -1)
3408  /* huh?! can't open /dev/null? */
3409  _exit (1);
3410 
3411  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3412 
3413  /* set-up stdXXX */
3414  close (result_pipe[READ_END]);
3415  close (errors_pipe[READ_END]);
3416 
3417  if (dup2 (fd, 0) == -1) /* setup stdin */
3418  _exit (1);
3419  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3420  _exit (1);
3421  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3422  _exit (1);
3423 
3424  _dbus_close_all ();
3425 
3426  sigprocmask (SIG_SETMASK, &old_set, NULL);
3427 
3428  /* If it looks fully-qualified, try execv first */
3429  if (progpath[0] == '/')
3430  {
3431  execv (progpath, argv);
3432  /* Ok, that failed. Now if path_fallback is given, let's
3433  * try unqualified. This is mostly a hack to work
3434  * around systems which ship dbus-launch in /usr/bin
3435  * but everything else in /bin (because dbus-launch
3436  * depends on X11).
3437  */
3438  if (path_fallback)
3439  /* We must have a slash, because we checked above */
3440  execvp (strrchr (progpath, '/')+1, argv);
3441  }
3442  else
3443  execvp (progpath, argv);
3444 
3445  /* still nothing, we failed */
3446  _exit (1);
3447  }
3448 
3449  /* parent process */
3450  close (result_pipe[WRITE_END]);
3451  close (errors_pipe[WRITE_END]);
3452  result_pipe[WRITE_END] = -1;
3453  errors_pipe[WRITE_END] = -1;
3454 
3455  ret = 0;
3456  do
3457  {
3458  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3459  }
3460  while (ret > 0);
3461 
3462  /* reap the child process to avoid it lingering as zombie */
3463  do
3464  {
3465  ret = waitpid (pid, &status, 0);
3466  }
3467  while (ret == -1 && errno == EINTR);
3468 
3469  /* We succeeded if the process exited with status 0 and
3470  anything was read */
3471  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3472  {
3473  /* The process ended with error */
3474  DBusString error_message;
3475  if (!_dbus_string_init (&error_message))
3476  {
3477  _DBUS_SET_OOM (error);
3478  goto out;
3479  }
3480 
3481  ret = 0;
3482  do
3483  {
3484  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3485  }
3486  while (ret > 0);
3487 
3488  _dbus_string_set_length (result, orig_len);
3489  if (_dbus_string_get_length (&error_message) > 0)
3491  "%s terminated abnormally with the following error: %s",
3492  progpath, _dbus_string_get_data (&error_message));
3493  else
3495  "%s terminated abnormally without any error message",
3496  progpath);
3497  goto out;
3498  }
3499 
3500  retval = TRUE;
3501 
3502  out:
3503  sigprocmask (SIG_SETMASK, &old_set, NULL);
3504 
3505  if (retval)
3506  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3507  else
3508  _DBUS_ASSERT_ERROR_IS_SET (error);
3509 
3510  if (result_pipe[0] != -1)
3511  close (result_pipe[0]);
3512  if (result_pipe[1] != -1)
3513  close (result_pipe[1]);
3514  if (errors_pipe[0] != -1)
3515  close (errors_pipe[0]);
3516  if (errors_pipe[1] != -1)
3517  close (errors_pipe[1]);
3518 
3519  return retval;
3520 }
3521 #endif
3522 
3536 _dbus_get_autolaunch_address (const char *scope,
3537  DBusString *address,
3538  DBusError *error)
3539 {
3540 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3541  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3542  * but that's done elsewhere, and if it worked, this function wouldn't
3543  * be called.) */
3544  const char *display;
3545  char *argv[6];
3546  int i;
3547  DBusString uuid;
3548  dbus_bool_t retval;
3549 
3550  if (_dbus_check_setuid ())
3551  {
3553  "Unable to autolaunch when setuid");
3554  return FALSE;
3555  }
3556 
3557  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3558  retval = FALSE;
3559 
3560  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3561  * dbus-launch-x11 is just going to fail. Rather than trying to
3562  * run it, we might as well bail out early with a nice error. */
3563  display = _dbus_getenv ("DISPLAY");
3564 
3565  if (display == NULL || display[0] == '\0')
3566  {
3568  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3569  return FALSE;
3570  }
3571 
3572  if (!_dbus_string_init (&uuid))
3573  {
3574  _DBUS_SET_OOM (error);
3575  return FALSE;
3576  }
3577 
3579  {
3580  _DBUS_SET_OOM (error);
3581  goto out;
3582  }
3583 
3584  i = 0;
3585 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3586  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3587  argv[i] = TEST_BUS_LAUNCH_BINARY;
3588  else
3589 #endif
3590  argv[i] = DBUS_BINDIR "/dbus-launch";
3591  ++i;
3592  argv[i] = "--autolaunch";
3593  ++i;
3594  argv[i] = _dbus_string_get_data (&uuid);
3595  ++i;
3596  argv[i] = "--binary-syntax";
3597  ++i;
3598  argv[i] = "--close-stderr";
3599  ++i;
3600  argv[i] = NULL;
3601  ++i;
3602 
3603  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3604 
3605  retval = _read_subprocess_line_argv (argv[0],
3606  TRUE,
3607  argv, address, error);
3608 
3609  out:
3610  _dbus_string_free (&uuid);
3611  return retval;
3612 #else
3614  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3615  "set your DBUS_SESSION_BUS_ADDRESS instead");
3616  return FALSE;
3617 #endif
3618 }
3619 
3640  dbus_bool_t create_if_not_found,
3641  DBusError *error)
3642 {
3643  DBusString filename;
3644  dbus_bool_t b;
3645 
3646  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3647 
3648  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3649  if (b)
3650  return TRUE;
3651 
3652  dbus_error_free (error);
3653 
3654  /* Fallback to the system machine ID */
3655  _dbus_string_init_const (&filename, "/etc/machine-id");
3656  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3657 
3658  if (b)
3659  {
3660  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3661  * complain if that isn't possible for whatever reason */
3662  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3663  _dbus_write_uuid_file (&filename, machine_id, NULL);
3664 
3665  return TRUE;
3666  }
3667 
3668  if (!create_if_not_found)
3669  return FALSE;
3670 
3671  /* if none found, try to make a new one */
3672  dbus_error_free (error);
3673  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3674  _dbus_generate_uuid (machine_id);
3675  return _dbus_write_uuid_file (&filename, machine_id, error);
3676 }
3677 
3687  const char *launchd_env_var,
3688  DBusError *error)
3689 {
3690 #ifdef DBUS_ENABLE_LAUNCHD
3691  char *argv[4];
3692  int i;
3693 
3694  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3695 
3696  if (_dbus_check_setuid ())
3697  {
3699  "Unable to find launchd socket when setuid");
3700  return FALSE;
3701  }
3702 
3703  i = 0;
3704  argv[i] = "launchctl";
3705  ++i;
3706  argv[i] = "getenv";
3707  ++i;
3708  argv[i] = (char*)launchd_env_var;
3709  ++i;
3710  argv[i] = NULL;
3711  ++i;
3712 
3713  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3714 
3715  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3716  {
3717  return FALSE;
3718  }
3719 
3720  /* no error, but no result either */
3721  if (_dbus_string_get_length(socket_path) == 0)
3722  {
3723  return FALSE;
3724  }
3725 
3726  /* strip the carriage-return */
3727  _dbus_string_shorten(socket_path, 1);
3728  return TRUE;
3729 #else /* DBUS_ENABLE_LAUNCHD */
3731  "can't lookup socket from launchd; launchd support not compiled in");
3732  return FALSE;
3733 #endif
3734 }
3735 
3736 #ifdef DBUS_ENABLE_LAUNCHD
3737 static dbus_bool_t
3738 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3739 {
3740  dbus_bool_t valid_socket;
3741  DBusString socket_path;
3742 
3743  if (_dbus_check_setuid ())
3744  {
3746  "Unable to find launchd socket when setuid");
3747  return FALSE;
3748  }
3749 
3750  if (!_dbus_string_init (&socket_path))
3751  {
3752  _DBUS_SET_OOM (error);
3753  return FALSE;
3754  }
3755 
3756  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3757 
3758  if (dbus_error_is_set(error))
3759  {
3760  _dbus_string_free(&socket_path);
3761  return FALSE;
3762  }
3763 
3764  if (!valid_socket)
3765  {
3766  dbus_set_error(error, "no socket path",
3767  "launchd did not provide a socket path, "
3768  "verify that org.freedesktop.dbus-session.plist is loaded!");
3769  _dbus_string_free(&socket_path);
3770  return FALSE;
3771  }
3772  if (!_dbus_string_append (address, "unix:path="))
3773  {
3774  _DBUS_SET_OOM (error);
3775  _dbus_string_free(&socket_path);
3776  return FALSE;
3777  }
3778  if (!_dbus_string_copy (&socket_path, 0, address,
3779  _dbus_string_get_length (address)))
3780  {
3781  _DBUS_SET_OOM (error);
3782  _dbus_string_free(&socket_path);
3783  return FALSE;
3784  }
3785 
3786  _dbus_string_free(&socket_path);
3787  return TRUE;
3788 }
3789 #endif
3790 
3812  DBusString *address,
3813  DBusError *error)
3814 {
3815 #ifdef DBUS_ENABLE_LAUNCHD
3816  *supported = TRUE;
3817  return _dbus_lookup_session_address_launchd (address, error);
3818 #else
3819  /* On non-Mac Unix platforms, if the session address isn't already
3820  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3821  * fall back to the autolaunch: global default; see
3822  * init_session_address in dbus/dbus-bus.c. */
3823  *supported = FALSE;
3824  return TRUE;
3825 #endif
3826 }
3827 
3835 void
3837 {
3839 }
3840 
3856  DBusCredentials *credentials)
3857 {
3858  DBusString homedir;
3859  DBusString dotdir;
3860  dbus_uid_t uid;
3861 
3862  _dbus_assert (credentials != NULL);
3864 
3865  if (!_dbus_string_init (&homedir))
3866  return FALSE;
3867 
3868  uid = _dbus_credentials_get_unix_uid (credentials);
3869  _dbus_assert (uid != DBUS_UID_UNSET);
3870 
3871  if (!_dbus_homedir_from_uid (uid, &homedir))
3872  goto failed;
3873 
3874 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3875  {
3876  const char *override;
3877 
3878  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3879  if (override != NULL && *override != '\0')
3880  {
3881  _dbus_string_set_length (&homedir, 0);
3882  if (!_dbus_string_append (&homedir, override))
3883  goto failed;
3884 
3885  _dbus_verbose ("Using fake homedir for testing: %s\n",
3886  _dbus_string_get_const_data (&homedir));
3887  }
3888  else
3889  {
3890  /* Not strictly thread-safe, but if we fail at thread-safety here,
3891  * the worst that will happen is some extra warnings. */
3892  static dbus_bool_t already_warned = FALSE;
3893  if (!already_warned)
3894  {
3895  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3896  already_warned = TRUE;
3897  }
3898  }
3899  }
3900 #endif
3901 
3902  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3903  if (!_dbus_concat_dir_and_file (&homedir,
3904  &dotdir))
3905  goto failed;
3906 
3907  if (!_dbus_string_copy (&homedir, 0,
3908  directory, _dbus_string_get_length (directory))) {
3909  goto failed;
3910  }
3911 
3912  _dbus_string_free (&homedir);
3913  return TRUE;
3914 
3915  failed:
3916  _dbus_string_free (&homedir);
3917  return FALSE;
3918 }
3919 
3920 //PENDING(kdab) docs
3922 _dbus_daemon_publish_session_bus_address (const char* addr,
3923  const char *scope)
3924 {
3925  return TRUE;
3926 }
3927 
3928 //PENDING(kdab) docs
3929 void
3930 _dbus_daemon_unpublish_session_bus_address (void)
3931 {
3932 
3933 }
3934 
3943 {
3944  return errno == EAGAIN || errno == EWOULDBLOCK;
3945 }
3946 
3956  DBusError *error)
3957 {
3958  const char *filename_c;
3959 
3960  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3961 
3962  filename_c = _dbus_string_get_const_data (filename);
3963 
3964  if (rmdir (filename_c) != 0)
3965  {
3967  "Failed to remove directory %s: %s\n",
3968  filename_c, _dbus_strerror (errno));
3969  return FALSE;
3970  }
3971 
3972  return TRUE;
3973 }
3974 
3984 
3985 #ifdef SCM_RIGHTS
3986  union {
3987  struct sockaddr sa;
3988  struct sockaddr_storage storage;
3989  struct sockaddr_un un;
3990  } sa_buf;
3991 
3992  socklen_t sa_len = sizeof(sa_buf);
3993 
3994  _DBUS_ZERO(sa_buf);
3995 
3996  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3997  return FALSE;
3998 
3999  return sa_buf.sa.sa_family == AF_UNIX;
4000 
4001 #else
4002  return FALSE;
4003 
4004 #endif
4005 }
4006 
4011 void
4013 {
4014  int maxfds, i;
4015 
4016 #ifdef __linux__
4017  DIR *d;
4018 
4019  /* On Linux we can optimize this a bit if /proc is available. If it
4020  isn't available, fall back to the brute force way. */
4021 
4022  d = opendir ("/proc/self/fd");
4023  if (d)
4024  {
4025  for (;;)
4026  {
4027  struct dirent buf, *de;
4028  int k, fd;
4029  long l;
4030  char *e = NULL;
4031 
4032  k = readdir_r (d, &buf, &de);
4033  if (k != 0 || !de)
4034  break;
4035 
4036  if (de->d_name[0] == '.')
4037  continue;
4038 
4039  errno = 0;
4040  l = strtol (de->d_name, &e, 10);
4041  if (errno != 0 || e == NULL || *e != '\0')
4042  continue;
4043 
4044  fd = (int) l;
4045  if (fd < 3)
4046  continue;
4047 
4048  if (fd == dirfd (d))
4049  continue;
4050 
4051  close (fd);
4052  }
4053 
4054  closedir (d);
4055  return;
4056  }
4057 #endif
4058 
4059  maxfds = sysconf (_SC_OPEN_MAX);
4060 
4061  /* Pick something reasonable if for some reason sysconf says
4062  * unlimited.
4063  */
4064  if (maxfds < 0)
4065  maxfds = 1024;
4066 
4067  /* close all inherited fds */
4068  for (i = 3; i < maxfds; i++)
4069  close (i);
4070 }
4071 
4083 {
4084  /* TODO: get __libc_enable_secure exported from glibc.
4085  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4086  */
4087 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4088  {
4089  /* See glibc/include/unistd.h */
4090  extern int __libc_enable_secure;
4091  return __libc_enable_secure;
4092  }
4093 #elif defined(HAVE_ISSETUGID)
4094  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4095  return issetugid ();
4096 #else
4097  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4098  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4099 
4100  /* We call into this function from _dbus_threads_init_platform_specific()
4101  * to make sure these are initialized before we start threading. */
4102  static dbus_bool_t check_setuid_initialised;
4103  static dbus_bool_t is_setuid;
4104 
4105  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4106  {
4107 #ifdef HAVE_GETRESUID
4108  if (getresuid (&ruid, &euid, &suid) != 0 ||
4109  getresgid (&rgid, &egid, &sgid) != 0)
4110 #endif /* HAVE_GETRESUID */
4111  {
4112  suid = ruid = getuid ();
4113  sgid = rgid = getgid ();
4114  euid = geteuid ();
4115  egid = getegid ();
4116  }
4117 
4118  check_setuid_initialised = TRUE;
4119  is_setuid = (ruid != euid || ruid != suid ||
4120  rgid != egid || rgid != sgid);
4121 
4122  }
4123  return is_setuid;
4124 #endif
4125 }
4126 
4136  DBusString *address,
4137  DBusError *error)
4138 {
4139  union {
4140  struct sockaddr sa;
4141  struct sockaddr_storage storage;
4142  struct sockaddr_un un;
4143  struct sockaddr_in ipv4;
4144  struct sockaddr_in6 ipv6;
4145  } socket;
4146  char hostip[INET6_ADDRSTRLEN];
4147  int size = sizeof (socket);
4148  DBusString path_str;
4149 
4150  if (getsockname (fd, &socket.sa, &size))
4151  goto err;
4152 
4153  switch (socket.sa.sa_family)
4154  {
4155  case AF_UNIX:
4156  if (socket.un.sun_path[0]=='\0')
4157  {
4158  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4159  if (_dbus_string_append (address, "unix:abstract=") &&
4160  _dbus_address_append_escaped (address, &path_str))
4161  return TRUE;
4162  }
4163  else
4164  {
4165  _dbus_string_init_const (&path_str, socket.un.sun_path);
4166  if (_dbus_string_append (address, "unix:path=") &&
4167  _dbus_address_append_escaped (address, &path_str))
4168  return TRUE;
4169  }
4170  break;
4171  case AF_INET:
4172  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4173  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4174  hostip, ntohs (socket.ipv4.sin_port)))
4175  return TRUE;
4176  break;
4177 #ifdef AF_INET6
4178  case AF_INET6:
4179  _dbus_string_init_const (&path_str, hostip);
4180  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4181  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4182  ntohs (socket.ipv6.sin6_port)) &&
4183  _dbus_address_append_escaped (address, &path_str))
4184  return TRUE;
4185  break;
4186 #endif
4187  default:
4188  dbus_set_error (error,
4189  _dbus_error_from_errno (EINVAL),
4190  "Failed to read address from socket: Unknown socket type.");
4191  return FALSE;
4192  }
4193  err:
4194  dbus_set_error (error,
4195  _dbus_error_from_errno (errno),
4196  "Failed to open socket: %s",
4197  _dbus_strerror (errno));
4198  return FALSE;
4199 }
4200 
4201 /* 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.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:545
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
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:434
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
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:722
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.
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
#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.
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.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:497
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
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:451
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