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  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
354  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
355  {
356  size_t i;
357  int *payload = (int *) CMSG_DATA (cm);
358  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
359  size_t payload_len_fds = payload_len_bytes / sizeof (int);
360  size_t fds_to_use;
361 
362  /* Every non-negative int fits in a size_t without truncation,
363  * and we already know that *n_fds is non-negative, so
364  * casting (size_t) *n_fds is OK */
365  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
366 
367  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
368  {
369  /* The fds in the payload will fit in our buffer */
370  fds_to_use = payload_len_fds;
371  }
372  else
373  {
374  /* Too many fds in the payload. This shouldn't happen
375  * any more because we're setting m.msg_controllen to
376  * the exact number we can accept, but be safe and
377  * truncate. */
378  fds_to_use = (size_t) *n_fds;
379 
380  /* Close the excess fds to avoid DoS: if they stayed open,
381  * someone could send us an extra fd per message
382  * and we'd eventually run out. */
383  for (i = fds_to_use; i < payload_len_fds; i++)
384  {
385  close (payload[i]);
386  }
387  }
388 
389  memcpy (fds, payload, fds_to_use * sizeof (int));
390  found = TRUE;
391  /* This cannot overflow because we have chosen fds_to_use
392  * to be <= *n_fds */
393  *n_fds = (int) fds_to_use;
394 
395  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
396  worked, hence we need to go through this list and set
397  CLOEXEC everywhere in any case */
398  for (i = 0; i < fds_to_use; i++)
400 
401  break;
402  }
403 
404  if (!found)
405  *n_fds = 0;
406 
407  if (m.msg_flags & MSG_CTRUNC)
408  {
409  unsigned int i;
410 
411  /* Hmm, apparently the control data was truncated. The bad
412  thing is that we might have completely lost a couple of fds
413  without chance to recover them. Hence let's treat this as a
414  serious error. */
415 
416  /* We still need to close whatever fds we *did* receive,
417  * otherwise they'll never get closed. (CVE-2020-12049) */
418  for (i = 0; i < *n_fds; i++)
419  close (fds[i]);
420 
421  *n_fds = 0;
422  errno = ENOSPC;
423  _dbus_string_set_length (buffer, start);
424  return -1;
425  }
426 
427  /* put length back (doesn't actually realloc) */
428  _dbus_string_set_length (buffer, start + bytes_read);
429 
430 #if 0
431  if (bytes_read > 0)
432  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
433 #endif
434 
435  return bytes_read;
436  }
437 #endif
438 }
439 
440 int
441 _dbus_write_socket_with_unix_fds(int fd,
442  const DBusString *buffer,
443  int start,
444  int len,
445  const int *fds,
446  int n_fds) {
447 
448 #ifndef HAVE_UNIX_FD_PASSING
449 
450  if (n_fds > 0) {
451  errno = ENOTSUP;
452  return -1;
453  }
454 
455  return _dbus_write_socket(fd, buffer, start, len);
456 #else
457  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
458 #endif
459 }
460 
461 int
462 _dbus_write_socket_with_unix_fds_two(int fd,
463  const DBusString *buffer1,
464  int start1,
465  int len1,
466  const DBusString *buffer2,
467  int start2,
468  int len2,
469  const int *fds,
470  int n_fds) {
471 
472 #ifndef HAVE_UNIX_FD_PASSING
473 
474  if (n_fds > 0) {
475  errno = ENOTSUP;
476  return -1;
477  }
478 
479  return _dbus_write_socket_two(fd,
480  buffer1, start1, len1,
481  buffer2, start2, len2);
482 #else
483 
484  struct msghdr m;
485  struct cmsghdr *cm;
486  struct iovec iov[2];
487  int bytes_written;
488 
489  _dbus_assert (len1 >= 0);
490  _dbus_assert (len2 >= 0);
491  _dbus_assert (n_fds >= 0);
492 
493  _DBUS_ZERO(iov);
494  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
495  iov[0].iov_len = len1;
496 
497  if (buffer2)
498  {
499  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
500  iov[1].iov_len = len2;
501  }
502 
503  _DBUS_ZERO(m);
504  m.msg_iov = iov;
505  m.msg_iovlen = buffer2 ? 2 : 1;
506 
507  if (n_fds > 0)
508  {
509  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
510  m.msg_control = alloca(m.msg_controllen);
511  memset(m.msg_control, 0, m.msg_controllen);
512 
513  cm = CMSG_FIRSTHDR(&m);
514  cm->cmsg_level = SOL_SOCKET;
515  cm->cmsg_type = SCM_RIGHTS;
516  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
517  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
518  }
519 
520  again:
521 
522  bytes_written = sendmsg (fd, &m, 0
523 #if HAVE_DECL_MSG_NOSIGNAL
524  |MSG_NOSIGNAL
525 #endif
526  );
527 
528  if (bytes_written < 0 && errno == EINTR)
529  goto again;
530 
531 #if 0
532  if (bytes_written > 0)
533  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
534 #endif
535 
536  return bytes_written;
537 #endif
538 }
539 
553 int
555  const DBusString *buffer1,
556  int start1,
557  int len1,
558  const DBusString *buffer2,
559  int start2,
560  int len2)
561 {
562 #if HAVE_DECL_MSG_NOSIGNAL
563  struct iovec vectors[2];
564  const char *data1;
565  const char *data2;
566  int bytes_written;
567  struct msghdr m;
568 
569  _dbus_assert (buffer1 != NULL);
570  _dbus_assert (start1 >= 0);
571  _dbus_assert (start2 >= 0);
572  _dbus_assert (len1 >= 0);
573  _dbus_assert (len2 >= 0);
574 
575  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
576 
577  if (buffer2 != NULL)
578  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
579  else
580  {
581  data2 = NULL;
582  start2 = 0;
583  len2 = 0;
584  }
585 
586  vectors[0].iov_base = (char*) data1;
587  vectors[0].iov_len = len1;
588  vectors[1].iov_base = (char*) data2;
589  vectors[1].iov_len = len2;
590 
591  _DBUS_ZERO(m);
592  m.msg_iov = vectors;
593  m.msg_iovlen = data2 ? 2 : 1;
594 
595  again:
596 
597  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
598 
599  if (bytes_written < 0 && errno == EINTR)
600  goto again;
601 
602  return bytes_written;
603 
604 #else
605  return _dbus_write_two (fd, buffer1, start1, len1,
606  buffer2, start2, len2);
607 #endif
608 }
609 
611 _dbus_socket_is_invalid (int fd)
612 {
613  return fd < 0 ? TRUE : FALSE;
614 }
615 
632 int
633 _dbus_read (int fd,
634  DBusString *buffer,
635  int count)
636 {
637  int bytes_read;
638  int start;
639  char *data;
640 
641  _dbus_assert (count >= 0);
642 
643  start = _dbus_string_get_length (buffer);
644 
645  if (!_dbus_string_lengthen (buffer, count))
646  {
647  errno = ENOMEM;
648  return -1;
649  }
650 
651  data = _dbus_string_get_data_len (buffer, start, count);
652 
653  again:
654 
655  bytes_read = read (fd, data, count);
656 
657  if (bytes_read < 0)
658  {
659  if (errno == EINTR)
660  goto again;
661  else
662  {
663  /* put length back (note that this doesn't actually realloc anything) */
664  _dbus_string_set_length (buffer, start);
665  return -1;
666  }
667  }
668  else
669  {
670  /* put length back (doesn't actually realloc) */
671  _dbus_string_set_length (buffer, start + bytes_read);
672 
673 #if 0
674  if (bytes_read > 0)
675  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
676 #endif
677 
678  return bytes_read;
679  }
680 }
681 
692 int
693 _dbus_write (int fd,
694  const DBusString *buffer,
695  int start,
696  int len)
697 {
698  const char *data;
699  int bytes_written;
700 
701  data = _dbus_string_get_const_data_len (buffer, start, len);
702 
703  again:
704 
705  bytes_written = write (fd, data, len);
706 
707  if (bytes_written < 0 && errno == EINTR)
708  goto again;
709 
710 #if 0
711  if (bytes_written > 0)
712  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
713 #endif
714 
715  return bytes_written;
716 }
717 
738 int
740  const DBusString *buffer1,
741  int start1,
742  int len1,
743  const DBusString *buffer2,
744  int start2,
745  int len2)
746 {
747  _dbus_assert (buffer1 != NULL);
748  _dbus_assert (start1 >= 0);
749  _dbus_assert (start2 >= 0);
750  _dbus_assert (len1 >= 0);
751  _dbus_assert (len2 >= 0);
752 
753 #ifdef HAVE_WRITEV
754  {
755  struct iovec vectors[2];
756  const char *data1;
757  const char *data2;
758  int bytes_written;
759 
760  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
761 
762  if (buffer2 != NULL)
763  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
764  else
765  {
766  data2 = NULL;
767  start2 = 0;
768  len2 = 0;
769  }
770 
771  vectors[0].iov_base = (char*) data1;
772  vectors[0].iov_len = len1;
773  vectors[1].iov_base = (char*) data2;
774  vectors[1].iov_len = len2;
775 
776  again:
777 
778  bytes_written = writev (fd,
779  vectors,
780  data2 ? 2 : 1);
781 
782  if (bytes_written < 0 && errno == EINTR)
783  goto again;
784 
785  return bytes_written;
786  }
787 #else /* HAVE_WRITEV */
788  {
789  int ret1, ret2;
790 
791  ret1 = _dbus_write (fd, buffer1, start1, len1);
792  if (ret1 == len1 && buffer2 != NULL)
793  {
794  ret2 = _dbus_write (fd, buffer2, start2, len2);
795  if (ret2 < 0)
796  ret2 = 0; /* we can't report an error as the first write was OK */
797 
798  return ret1 + ret2;
799  }
800  else
801  return ret1;
802  }
803 #endif /* !HAVE_WRITEV */
804 }
805 
806 #define _DBUS_MAX_SUN_PATH_LENGTH 99
807 
837 int
838 _dbus_connect_unix_socket (const char *path,
839  dbus_bool_t abstract,
840  DBusError *error)
841 {
842  int fd;
843  size_t path_len;
844  struct sockaddr_un addr;
845 
846  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
847 
848  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
849  path, abstract);
850 
851 
852  if (!_dbus_open_unix_socket (&fd, error))
853  {
854  _DBUS_ASSERT_ERROR_IS_SET(error);
855  return -1;
856  }
857  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
858 
859  _DBUS_ZERO (addr);
860  addr.sun_family = AF_UNIX;
861  path_len = strlen (path);
862 
863  if (abstract)
864  {
865 #ifdef HAVE_ABSTRACT_SOCKETS
866  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
867  path_len++; /* Account for the extra nul byte added to the start of sun_path */
868 
869  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
870  {
872  "Abstract socket name too long\n");
873  _dbus_close (fd, NULL);
874  return -1;
875  }
876 
877  strncpy (&addr.sun_path[1], path, path_len);
878  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
879 #else /* HAVE_ABSTRACT_SOCKETS */
881  "Operating system does not support abstract socket namespace\n");
882  _dbus_close (fd, NULL);
883  return -1;
884 #endif /* ! HAVE_ABSTRACT_SOCKETS */
885  }
886  else
887  {
888  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
889  {
891  "Socket name too long\n");
892  _dbus_close (fd, NULL);
893  return -1;
894  }
895 
896  strncpy (addr.sun_path, path, path_len);
897  }
898 
899  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
900  {
901  dbus_set_error (error,
902  _dbus_error_from_errno (errno),
903  "Failed to connect to socket %s: %s",
904  path, _dbus_strerror (errno));
905 
906  _dbus_close (fd, NULL);
907  return -1;
908  }
909 
910  if (!_dbus_set_fd_nonblocking (fd, error))
911  {
912  _DBUS_ASSERT_ERROR_IS_SET (error);
913 
914  _dbus_close (fd, NULL);
915  return -1;
916  }
917 
918  return fd;
919 }
920 
933 int
934 _dbus_connect_exec (const char *path,
935  char *const argv[],
936  DBusError *error)
937 {
938  int fds[2];
939  pid_t pid;
940  int retval;
941  dbus_bool_t cloexec_done = 0;
942 
943  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
944 
945  _dbus_verbose ("connecting to process %s\n", path);
946 
947 #ifdef SOCK_CLOEXEC
948  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
949  cloexec_done = (retval >= 0);
950 
951  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
952 #endif
953  {
954  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
955  }
956 
957  if (retval < 0)
958  {
959  dbus_set_error (error,
960  _dbus_error_from_errno (errno),
961  "Failed to create socket pair: %s",
962  _dbus_strerror (errno));
963  return -1;
964  }
965 
966  if (!cloexec_done)
967  {
970  }
971 
972  pid = fork ();
973  if (pid < 0)
974  {
975  dbus_set_error (error,
976  _dbus_error_from_errno (errno),
977  "Failed to fork() to call %s: %s",
978  path, _dbus_strerror (errno));
979  close (fds[0]);
980  close (fds[1]);
981  return -1;
982  }
983 
984  if (pid == 0)
985  {
986  /* child */
987  close (fds[0]);
988 
989  dup2 (fds[1], STDIN_FILENO);
990  dup2 (fds[1], STDOUT_FILENO);
991 
992  if (fds[1] != STDIN_FILENO &&
993  fds[1] != STDOUT_FILENO)
994  close (fds[1]);
995 
996  /* Inherit STDERR and the controlling terminal from the
997  parent */
998 
999  _dbus_close_all ();
1000 
1001  execvp (path, argv);
1002 
1003  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1004 
1005  _exit(1);
1006  }
1007 
1008  /* parent */
1009  close (fds[1]);
1010 
1011  if (!_dbus_set_fd_nonblocking (fds[0], error))
1012  {
1013  _DBUS_ASSERT_ERROR_IS_SET (error);
1014 
1015  close (fds[0]);
1016  return -1;
1017  }
1018 
1019  return fds[0];
1020 }
1021 
1039 int
1040 _dbus_listen_unix_socket (const char *path,
1041  dbus_bool_t abstract,
1042  DBusError *error)
1043 {
1044  int listen_fd;
1045  struct sockaddr_un addr;
1046  size_t path_len;
1047 
1048  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1049 
1050  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1051  path, abstract);
1052 
1053  if (!_dbus_open_unix_socket (&listen_fd, error))
1054  {
1055  _DBUS_ASSERT_ERROR_IS_SET(error);
1056  return -1;
1057  }
1058  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1059 
1060  _DBUS_ZERO (addr);
1061  addr.sun_family = AF_UNIX;
1062  path_len = strlen (path);
1063 
1064  if (abstract)
1065  {
1066 #ifdef HAVE_ABSTRACT_SOCKETS
1067  /* remember that abstract names aren't nul-terminated so we rely
1068  * on sun_path being filled in with zeroes above.
1069  */
1070  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1071  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1072 
1073  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1074  {
1076  "Abstract socket name too long\n");
1077  _dbus_close (listen_fd, NULL);
1078  return -1;
1079  }
1080 
1081  strncpy (&addr.sun_path[1], path, path_len);
1082  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1083 #else /* HAVE_ABSTRACT_SOCKETS */
1085  "Operating system does not support abstract socket namespace\n");
1086  _dbus_close (listen_fd, NULL);
1087  return -1;
1088 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1089  }
1090  else
1091  {
1092  /* Discussed security implications of this with Nalin,
1093  * and we couldn't think of where it would kick our ass, but
1094  * it still seems a bit sucky. It also has non-security suckage;
1095  * really we'd prefer to exit if the socket is already in use.
1096  * But there doesn't seem to be a good way to do this.
1097  *
1098  * Just to be extra careful, I threw in the stat() - clearly
1099  * the stat() can't *fix* any security issue, but it at least
1100  * avoids inadvertent/accidental data loss.
1101  */
1102  {
1103  struct stat sb;
1104 
1105  if (stat (path, &sb) == 0 &&
1106  S_ISSOCK (sb.st_mode))
1107  unlink (path);
1108  }
1109 
1110  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1111  {
1113  "Abstract socket name too long\n");
1114  _dbus_close (listen_fd, NULL);
1115  return -1;
1116  }
1117 
1118  strncpy (addr.sun_path, path, path_len);
1119  }
1120 
1121  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1122  {
1123  dbus_set_error (error, _dbus_error_from_errno (errno),
1124  "Failed to bind socket \"%s\": %s",
1125  path, _dbus_strerror (errno));
1126  _dbus_close (listen_fd, NULL);
1127  return -1;
1128  }
1129 
1130  if (listen (listen_fd, 30 /* backlog */) < 0)
1131  {
1132  dbus_set_error (error, _dbus_error_from_errno (errno),
1133  "Failed to listen on socket \"%s\": %s",
1134  path, _dbus_strerror (errno));
1135  _dbus_close (listen_fd, NULL);
1136  return -1;
1137  }
1138 
1139  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1140  {
1141  _DBUS_ASSERT_ERROR_IS_SET (error);
1142  _dbus_close (listen_fd, NULL);
1143  return -1;
1144  }
1145 
1146  /* Try opening up the permissions, but if we can't, just go ahead
1147  * and continue, maybe it will be good enough.
1148  */
1149  if (!abstract && chmod (path, 0777) < 0)
1150  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1151  path);
1152 
1153  return listen_fd;
1154 }
1155 
1166 int
1168  DBusError *error)
1169 {
1170  int r, n;
1171  unsigned fd;
1172  int *new_fds;
1173 
1174  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1175 
1176  n = sd_listen_fds (TRUE);
1177  if (n < 0)
1178  {
1180  "Failed to acquire systemd socket: %s",
1181  _dbus_strerror (-n));
1182  return -1;
1183  }
1184 
1185  if (n <= 0)
1186  {
1188  "No socket received.");
1189  return -1;
1190  }
1191 
1192  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1193  {
1194  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1195  if (r < 0)
1196  {
1198  "Failed to verify systemd socket type: %s",
1199  _dbus_strerror (-r));
1200  return -1;
1201  }
1202 
1203  if (!r)
1204  {
1206  "Passed socket has wrong type.");
1207  return -1;
1208  }
1209  }
1210 
1211  /* OK, the file descriptors are all good, so let's take posession of
1212  them then. */
1213 
1214  new_fds = dbus_new (int, n);
1215  if (!new_fds)
1216  {
1218  "Failed to allocate file handle array.");
1219  goto fail;
1220  }
1221 
1222  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1223  {
1224  if (!_dbus_set_fd_nonblocking (fd, error))
1225  {
1226  _DBUS_ASSERT_ERROR_IS_SET (error);
1227  goto fail;
1228  }
1229 
1230  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1231  }
1232 
1233  *fds = new_fds;
1234  return n;
1235 
1236  fail:
1237 
1238  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1239  {
1240  _dbus_close (fd, NULL);
1241  }
1242 
1243  dbus_free (new_fds);
1244  return -1;
1245 }
1246 
1260 int
1261 _dbus_connect_tcp_socket (const char *host,
1262  const char *port,
1263  const char *family,
1264  DBusError *error)
1265 {
1266  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1267 }
1268 
1269 int
1270 _dbus_connect_tcp_socket_with_nonce (const char *host,
1271  const char *port,
1272  const char *family,
1273  const char *noncefile,
1274  DBusError *error)
1275 {
1276  int saved_errno = 0;
1277  int fd = -1, res;
1278  struct addrinfo hints;
1279  struct addrinfo *ai, *tmp;
1280 
1281  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1282 
1283  _DBUS_ZERO (hints);
1284 
1285  if (!family)
1286  hints.ai_family = AF_UNSPEC;
1287  else if (!strcmp(family, "ipv4"))
1288  hints.ai_family = AF_INET;
1289  else if (!strcmp(family, "ipv6"))
1290  hints.ai_family = AF_INET6;
1291  else
1292  {
1293  dbus_set_error (error,
1295  "Unknown address family %s", family);
1296  return -1;
1297  }
1298  hints.ai_protocol = IPPROTO_TCP;
1299  hints.ai_socktype = SOCK_STREAM;
1300  hints.ai_flags = AI_ADDRCONFIG;
1301 
1302  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1303  {
1304  dbus_set_error (error,
1305  _dbus_error_from_errno (errno),
1306  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1307  host, port, gai_strerror(res), res);
1308  return -1;
1309  }
1310 
1311  tmp = ai;
1312  while (tmp)
1313  {
1314  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1315  {
1316  freeaddrinfo(ai);
1317  _DBUS_ASSERT_ERROR_IS_SET(error);
1318  return -1;
1319  }
1320  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1321 
1322  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1323  {
1324  saved_errno = errno;
1325  _dbus_close(fd, NULL);
1326  fd = -1;
1327  tmp = tmp->ai_next;
1328  continue;
1329  }
1330 
1331  break;
1332  }
1333  freeaddrinfo(ai);
1334 
1335  if (fd == -1)
1336  {
1337  dbus_set_error (error,
1338  _dbus_error_from_errno (saved_errno),
1339  "Failed to connect to socket \"%s:%s\" %s",
1340  host, port, _dbus_strerror(saved_errno));
1341  return -1;
1342  }
1343 
1344  if (noncefile != NULL)
1345  {
1346  DBusString noncefileStr;
1347  dbus_bool_t ret;
1348  _dbus_string_init_const (&noncefileStr, noncefile);
1349  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1350  _dbus_string_free (&noncefileStr);
1351 
1352  if (!ret)
1353  {
1354  _dbus_close (fd, NULL);
1355  return -1;
1356  }
1357  }
1358 
1359  if (!_dbus_set_fd_nonblocking (fd, error))
1360  {
1361  _dbus_close (fd, NULL);
1362  return -1;
1363  }
1364 
1365  return fd;
1366 }
1367 
1384 int
1385 _dbus_listen_tcp_socket (const char *host,
1386  const char *port,
1387  const char *family,
1388  DBusString *retport,
1389  int **fds_p,
1390  DBusError *error)
1391 {
1392  int saved_errno;
1393  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1394  struct addrinfo hints;
1395  struct addrinfo *ai, *tmp;
1396  unsigned int reuseaddr;
1397 
1398  *fds_p = NULL;
1399  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1400 
1401  _DBUS_ZERO (hints);
1402 
1403  if (!family)
1404  hints.ai_family = AF_UNSPEC;
1405  else if (!strcmp(family, "ipv4"))
1406  hints.ai_family = AF_INET;
1407  else if (!strcmp(family, "ipv6"))
1408  hints.ai_family = AF_INET6;
1409  else
1410  {
1411  dbus_set_error (error,
1413  "Unknown address family %s", family);
1414  return -1;
1415  }
1416 
1417  hints.ai_protocol = IPPROTO_TCP;
1418  hints.ai_socktype = SOCK_STREAM;
1419  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1420 
1421  redo_lookup_with_port:
1422  ai = NULL;
1423  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1424  {
1425  dbus_set_error (error,
1426  _dbus_error_from_errno (errno),
1427  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1428  host ? host : "*", port, gai_strerror(res), res);
1429  goto failed;
1430  }
1431 
1432  tmp = ai;
1433  while (tmp)
1434  {
1435  int fd = -1, *newlisten_fd;
1436  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1437  {
1438  _DBUS_ASSERT_ERROR_IS_SET(error);
1439  goto failed;
1440  }
1441  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1442 
1443  reuseaddr = 1;
1444  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1445  {
1446  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1447  host ? host : "*", port, _dbus_strerror (errno));
1448  }
1449 
1450  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1451  {
1452  saved_errno = errno;
1453  _dbus_close(fd, NULL);
1454  if (saved_errno == EADDRINUSE)
1455  {
1456  /* Depending on kernel policy, it may or may not
1457  be neccessary to bind to both IPv4 & 6 addresses
1458  so ignore EADDRINUSE here */
1459  tmp = tmp->ai_next;
1460  continue;
1461  }
1462  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1463  "Failed to bind socket \"%s:%s\": %s",
1464  host ? host : "*", port, _dbus_strerror (saved_errno));
1465  goto failed;
1466  }
1467 
1468  if (listen (fd, 30 /* backlog */) < 0)
1469  {
1470  saved_errno = errno;
1471  _dbus_close (fd, NULL);
1472  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1473  "Failed to listen on socket \"%s:%s\": %s",
1474  host ? host : "*", port, _dbus_strerror (saved_errno));
1475  goto failed;
1476  }
1477 
1478  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1479  if (!newlisten_fd)
1480  {
1481  saved_errno = errno;
1482  _dbus_close (fd, NULL);
1483  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1484  "Failed to allocate file handle array: %s",
1485  _dbus_strerror (saved_errno));
1486  goto failed;
1487  }
1488  listen_fd = newlisten_fd;
1489  listen_fd[nlisten_fd] = fd;
1490  nlisten_fd++;
1491 
1492  if (!_dbus_string_get_length(retport))
1493  {
1494  /* If the user didn't specify a port, or used 0, then
1495  the kernel chooses a port. After the first address
1496  is bound to, we need to force all remaining addresses
1497  to use the same port */
1498  if (!port || !strcmp(port, "0"))
1499  {
1500  int result;
1501  struct sockaddr_storage addr;
1502  socklen_t addrlen;
1503  char portbuf[50];
1504 
1505  addrlen = sizeof(addr);
1506  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1507 
1508  if (result == -1 ||
1509  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1510  portbuf, sizeof(portbuf),
1511  NI_NUMERICHOST)) != 0)
1512  {
1513  dbus_set_error (error, _dbus_error_from_errno (errno),
1514  "Failed to resolve port \"%s:%s\": %s (%s)",
1515  host ? host : "*", port, gai_strerror(res), res);
1516  goto failed;
1517  }
1518  if (!_dbus_string_append(retport, portbuf))
1519  {
1521  goto failed;
1522  }
1523 
1524  /* Release current address list & redo lookup */
1525  port = _dbus_string_get_const_data(retport);
1526  freeaddrinfo(ai);
1527  goto redo_lookup_with_port;
1528  }
1529  else
1530  {
1531  if (!_dbus_string_append(retport, port))
1532  {
1534  goto failed;
1535  }
1536  }
1537  }
1538 
1539  tmp = tmp->ai_next;
1540  }
1541  freeaddrinfo(ai);
1542  ai = NULL;
1543 
1544  if (!nlisten_fd)
1545  {
1546  errno = EADDRINUSE;
1547  dbus_set_error (error, _dbus_error_from_errno (errno),
1548  "Failed to bind socket \"%s:%s\": %s",
1549  host ? host : "*", port, _dbus_strerror (errno));
1550  goto failed;
1551  }
1552 
1553  for (i = 0 ; i < nlisten_fd ; i++)
1554  {
1555  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1556  {
1557  goto failed;
1558  }
1559  }
1560 
1561  *fds_p = listen_fd;
1562 
1563  return nlisten_fd;
1564 
1565  failed:
1566  if (ai)
1567  freeaddrinfo(ai);
1568  for (i = 0 ; i < nlisten_fd ; i++)
1569  _dbus_close(listen_fd[i], NULL);
1570  dbus_free(listen_fd);
1571  return -1;
1572 }
1573 
1574 static dbus_bool_t
1575 write_credentials_byte (int server_fd,
1576  DBusError *error)
1577 {
1578  int bytes_written;
1579  char buf[1] = { '\0' };
1580 #if defined(HAVE_CMSGCRED)
1581  union {
1582  struct cmsghdr hdr;
1583  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1584  } cmsg;
1585  struct iovec iov;
1586  struct msghdr msg;
1587  iov.iov_base = buf;
1588  iov.iov_len = 1;
1589 
1590  _DBUS_ZERO(msg);
1591  msg.msg_iov = &iov;
1592  msg.msg_iovlen = 1;
1593 
1594  msg.msg_control = (caddr_t) &cmsg;
1595  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1596  _DBUS_ZERO(cmsg);
1597  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1598  cmsg.hdr.cmsg_level = SOL_SOCKET;
1599  cmsg.hdr.cmsg_type = SCM_CREDS;
1600 #endif
1601 
1602  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1603 
1604  again:
1605 
1606 #if defined(HAVE_CMSGCRED)
1607  bytes_written = sendmsg (server_fd, &msg, 0
1608 #if HAVE_DECL_MSG_NOSIGNAL
1609  |MSG_NOSIGNAL
1610 #endif
1611  );
1612 
1613  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1614  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1615  * only allows that on AF_UNIX. Try just doing a send() instead. */
1616  if (bytes_written < 0 && errno == EINVAL)
1617 #endif
1618  {
1619  bytes_written = send (server_fd, buf, 1, 0
1620 #if HAVE_DECL_MSG_NOSIGNAL
1621  |MSG_NOSIGNAL
1622 #endif
1623  );
1624  }
1625 
1626  if (bytes_written < 0 && errno == EINTR)
1627  goto again;
1628 
1629  if (bytes_written < 0)
1630  {
1631  dbus_set_error (error, _dbus_error_from_errno (errno),
1632  "Failed to write credentials byte: %s",
1633  _dbus_strerror (errno));
1634  return FALSE;
1635  }
1636  else if (bytes_written == 0)
1637  {
1639  "wrote zero bytes writing credentials byte");
1640  return FALSE;
1641  }
1642  else
1643  {
1644  _dbus_assert (bytes_written == 1);
1645  _dbus_verbose ("wrote credentials byte\n");
1646  return TRUE;
1647  }
1648 }
1649 
1673  DBusCredentials *credentials,
1674  DBusError *error)
1675 {
1676  struct msghdr msg;
1677  struct iovec iov;
1678  char buf;
1679  dbus_uid_t uid_read;
1680  dbus_pid_t pid_read;
1681  int bytes_read;
1682 
1683 #ifdef HAVE_CMSGCRED
1684  union {
1685  struct cmsghdr hdr;
1686  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1687  } cmsg;
1688 #endif
1689 
1690  uid_read = DBUS_UID_UNSET;
1691  pid_read = DBUS_PID_UNSET;
1692 
1693  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1694 
1695  /* The POSIX spec certainly doesn't promise this, but
1696  * we need these assertions to fail as soon as we're wrong about
1697  * it so we can do the porting fixups
1698  */
1699  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1700  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1701  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1702 
1703  _dbus_credentials_clear (credentials);
1704 
1705  iov.iov_base = &buf;
1706  iov.iov_len = 1;
1707 
1708  _DBUS_ZERO(msg);
1709  msg.msg_iov = &iov;
1710  msg.msg_iovlen = 1;
1711 
1712 #if defined(HAVE_CMSGCRED)
1713  _DBUS_ZERO(cmsg);
1714  msg.msg_control = (caddr_t) &cmsg;
1715  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1716 #endif
1717 
1718  again:
1719  bytes_read = recvmsg (client_fd, &msg, 0);
1720 
1721  if (bytes_read < 0)
1722  {
1723  if (errno == EINTR)
1724  goto again;
1725 
1726  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1727  * normally only call read_credentials if the socket was ready
1728  * for reading
1729  */
1730 
1731  dbus_set_error (error, _dbus_error_from_errno (errno),
1732  "Failed to read credentials byte: %s",
1733  _dbus_strerror (errno));
1734  return FALSE;
1735  }
1736  else if (bytes_read == 0)
1737  {
1738  /* this should not happen unless we are using recvmsg wrong,
1739  * so is essentially here for paranoia
1740  */
1742  "Failed to read credentials byte (zero-length read)");
1743  return FALSE;
1744  }
1745  else if (buf != '\0')
1746  {
1748  "Credentials byte was not nul");
1749  return FALSE;
1750  }
1751 
1752  _dbus_verbose ("read credentials byte\n");
1753 
1754  {
1755 #ifdef SO_PEERCRED
1756  /* Supported by at least Linux and OpenBSD, with minor differences.
1757  *
1758  * This mechanism passes the process ID through and does not require
1759  * the peer's cooperation, so we prefer it over all others. Notably,
1760  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1761  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1762  * because this is much less fragile.
1763  */
1764 #ifdef __OpenBSD__
1765  struct sockpeercred cr;
1766 #else
1767  struct ucred cr;
1768 #endif
1769  int cr_len = sizeof (cr);
1770 
1771  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1772  cr_len == sizeof (cr))
1773  {
1774  pid_read = cr.pid;
1775  uid_read = cr.uid;
1776  }
1777  else
1778  {
1779  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1780  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1781  }
1782 #elif defined(HAVE_CMSGCRED)
1783  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1784  * presence of that struct implies SCM_CREDS. Supported by at least
1785  * FreeBSD and DragonflyBSD.
1786  *
1787  * This mechanism requires the peer to help us (it has to send us a
1788  * SCM_CREDS message) but it does pass the process ID through,
1789  * which makes it better than getpeereid().
1790  */
1791  struct cmsgcred *cred;
1792  struct cmsghdr *cmsgp;
1793 
1794  for (cmsgp = CMSG_FIRSTHDR (&msg);
1795  cmsgp != NULL;
1796  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
1797  {
1798  if (cmsgp->cmsg_type == SCM_CREDS &&
1799  cmsgp->cmsg_level == SOL_SOCKET &&
1800  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
1801  {
1802  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
1803  pid_read = cred->cmcred_pid;
1804  uid_read = cred->cmcred_euid;
1805  break;
1806  }
1807  }
1808 
1809 #elif defined(HAVE_GETPEERUCRED)
1810  /* Supported in at least Solaris >= 10. It should probably be higher
1811  * up this list, because it carries the pid and we use this code path
1812  * for audit data. */
1813  ucred_t * ucred = NULL;
1814  if (getpeerucred (client_fd, &ucred) == 0)
1815  {
1816  pid_read = ucred_getpid (ucred);
1817  uid_read = ucred_geteuid (ucred);
1818 #ifdef HAVE_ADT
1819  /* generate audit session data based on socket ucred */
1820  adt_session_data_t *adth = NULL;
1821  adt_export_data_t *data = NULL;
1822  size_t size = 0;
1823  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1824  {
1825  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1826  }
1827  else
1828  {
1829  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1830  {
1831  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1832  }
1833  else
1834  {
1835  size = adt_export_session_data (adth, &data);
1836  if (size <= 0)
1837  {
1838  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1839  }
1840  else
1841  {
1842  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1843  free (data);
1844  }
1845  }
1846  (void) adt_end_session (adth);
1847  }
1848 #endif /* HAVE_ADT */
1849  }
1850  else
1851  {
1852  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1853  }
1854  if (ucred != NULL)
1855  ucred_free (ucred);
1856 
1857  /* ----------------------------------------------------------------
1858  * When adding new mechanisms, please add them above this point
1859  * if they support passing the process ID through, or below if not.
1860  * ---------------------------------------------------------------- */
1861 
1862 #elif defined(HAVE_GETPEEREID)
1863  /* getpeereid() originates from D.J. Bernstein and is fairly
1864  * widely-supported. According to a web search, it might be present in
1865  * any/all of:
1866  *
1867  * - AIX?
1868  * - Blackberry?
1869  * - Cygwin
1870  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
1871  * - Mac OS X
1872  * - Minix 3.1.8+
1873  * - MirBSD?
1874  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
1875  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
1876  * - QNX?
1877  */
1878  uid_t euid;
1879  gid_t egid;
1880  if (getpeereid (client_fd, &euid, &egid) == 0)
1881  {
1882  uid_read = euid;
1883  }
1884  else
1885  {
1886  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1887  }
1888 #else /* no supported mechanism */
1889 
1890 #warning Socket credentials not supported on this Unix OS
1891 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
1892 
1893  /* Please add other operating systems known to support at least one of
1894  * the mechanisms above to this list, keeping alphabetical order.
1895  * Everything not in this list is best-effort.
1896  */
1897 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
1898  defined(__linux__) || \
1899  defined(__OpenBSD__) || \
1900  defined(__NetBSD__)
1901 # error Credentials passing not working on this OS is a regression!
1902 #endif
1903 
1904  _dbus_verbose ("Socket credentials not supported on this OS\n");
1905 #endif
1906  }
1907 
1908  _dbus_verbose ("Credentials:"
1909  " pid "DBUS_PID_FORMAT
1910  " uid "DBUS_UID_FORMAT
1911  "\n",
1912  pid_read,
1913  uid_read);
1914 
1915  if (pid_read != DBUS_PID_UNSET)
1916  {
1917  if (!_dbus_credentials_add_pid (credentials, pid_read))
1918  {
1919  _DBUS_SET_OOM (error);
1920  return FALSE;
1921  }
1922  }
1923 
1924  if (uid_read != DBUS_UID_UNSET)
1925  {
1926  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1927  {
1928  _DBUS_SET_OOM (error);
1929  return FALSE;
1930  }
1931  }
1932 
1933  return TRUE;
1934 }
1935 
1955  DBusError *error)
1956 {
1957  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1958 
1959  if (write_credentials_byte (server_fd, error))
1960  return TRUE;
1961  else
1962  return FALSE;
1963 }
1964 
1974 int
1975 _dbus_accept (int listen_fd)
1976 {
1977  int client_fd;
1978  struct sockaddr addr;
1979  socklen_t addrlen;
1980 #ifdef HAVE_ACCEPT4
1981  dbus_bool_t cloexec_done;
1982 #endif
1983 
1984  addrlen = sizeof (addr);
1985 
1986  retry:
1987 
1988 #ifdef HAVE_ACCEPT4
1989  /*
1990  * At compile-time, we assume that if accept4() is available in
1991  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
1992  * not necessarily true that either is supported by the running kernel.
1993  */
1994  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1995  cloexec_done = client_fd >= 0;
1996 
1997  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
1998 #endif
1999  {
2000  client_fd = accept (listen_fd, &addr, &addrlen);
2001  }
2002 
2003  if (client_fd < 0)
2004  {
2005  if (errno == EINTR)
2006  goto retry;
2007  }
2008 
2009  _dbus_verbose ("client fd %d accepted\n", client_fd);
2010 
2011 #ifdef HAVE_ACCEPT4
2012  if (!cloexec_done)
2013 #endif
2014  {
2015  _dbus_fd_set_close_on_exec(client_fd);
2016  }
2017 
2018  return client_fd;
2019 }
2020 
2031 {
2032  const char *directory;
2033  struct stat sb;
2034 
2035  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2036 
2037  directory = _dbus_string_get_const_data (dir);
2038 
2039  if (stat (directory, &sb) < 0)
2040  {
2041  dbus_set_error (error, _dbus_error_from_errno (errno),
2042  "%s", _dbus_strerror (errno));
2043 
2044  return FALSE;
2045  }
2046 
2047  if (sb.st_uid != geteuid ())
2048  {
2050  "%s directory is owned by user %lu, not %lu",
2051  directory,
2052  (unsigned long) sb.st_uid,
2053  (unsigned long) geteuid ());
2054  return FALSE;
2055  }
2056 
2057  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2058  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2059  {
2061  "%s directory is not private to the user", directory);
2062  return FALSE;
2063  }
2064 
2065  return TRUE;
2066 }
2067 
2068 static dbus_bool_t
2069 fill_user_info_from_passwd (struct passwd *p,
2070  DBusUserInfo *info,
2071  DBusError *error)
2072 {
2073  _dbus_assert (p->pw_name != NULL);
2074  _dbus_assert (p->pw_dir != NULL);
2075 
2076  info->uid = p->pw_uid;
2077  info->primary_gid = p->pw_gid;
2078  info->username = _dbus_strdup (p->pw_name);
2079  info->homedir = _dbus_strdup (p->pw_dir);
2080 
2081  if (info->username == NULL ||
2082  info->homedir == NULL)
2083  {
2085  return FALSE;
2086  }
2087 
2088  return TRUE;
2089 }
2090 
2091 static dbus_bool_t
2092 fill_user_info (DBusUserInfo *info,
2093  dbus_uid_t uid,
2094  const DBusString *username,
2095  DBusError *error)
2096 {
2097  const char *username_c;
2098 
2099  /* exactly one of username/uid provided */
2100  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2101  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2102 
2103  info->uid = DBUS_UID_UNSET;
2104  info->primary_gid = DBUS_GID_UNSET;
2105  info->group_ids = NULL;
2106  info->n_group_ids = 0;
2107  info->username = NULL;
2108  info->homedir = NULL;
2109 
2110  if (username != NULL)
2111  username_c = _dbus_string_get_const_data (username);
2112  else
2113  username_c = NULL;
2114 
2115  /* For now assuming that the getpwnam() and getpwuid() flavors
2116  * are always symmetrical, if not we have to add more configure
2117  * checks
2118  */
2119 
2120 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2121  {
2122  struct passwd *p;
2123  int result;
2124  size_t buflen;
2125  char *buf;
2126  struct passwd p_str;
2127 
2128  /* retrieve maximum needed size for buf */
2129  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2130 
2131  /* sysconf actually returns a long, but everything else expects size_t,
2132  * so just recast here.
2133  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2134  */
2135  if ((long) buflen <= 0)
2136  buflen = 1024;
2137 
2138  result = -1;
2139  while (1)
2140  {
2141  buf = dbus_malloc (buflen);
2142  if (buf == NULL)
2143  {
2145  return FALSE;
2146  }
2147 
2148  p = NULL;
2149 #ifdef HAVE_POSIX_GETPWNAM_R
2150  if (uid != DBUS_UID_UNSET)
2151  result = getpwuid_r (uid, &p_str, buf, buflen,
2152  &p);
2153  else
2154  result = getpwnam_r (username_c, &p_str, buf, buflen,
2155  &p);
2156 #else
2157  if (uid != DBUS_UID_UNSET)
2158  p = getpwuid_r (uid, &p_str, buf, buflen);
2159  else
2160  p = getpwnam_r (username_c, &p_str, buf, buflen);
2161  result = 0;
2162 #endif /* !HAVE_POSIX_GETPWNAM_R */
2163  //Try a bigger buffer if ERANGE was returned
2164  if (result == ERANGE && buflen < 512 * 1024)
2165  {
2166  dbus_free (buf);
2167  buflen *= 2;
2168  }
2169  else
2170  {
2171  break;
2172  }
2173  }
2174  if (result == 0 && p == &p_str)
2175  {
2176  if (!fill_user_info_from_passwd (p, info, error))
2177  {
2178  dbus_free (buf);
2179  return FALSE;
2180  }
2181  dbus_free (buf);
2182  }
2183  else
2184  {
2185  dbus_set_error (error, _dbus_error_from_errno (errno),
2186  "User \"%s\" unknown or no memory to allocate password entry\n",
2187  username_c ? username_c : "???");
2188  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2189  dbus_free (buf);
2190  return FALSE;
2191  }
2192  }
2193 #else /* ! HAVE_GETPWNAM_R */
2194  {
2195  /* I guess we're screwed on thread safety here */
2196  struct passwd *p;
2197 
2198  if (uid != DBUS_UID_UNSET)
2199  p = getpwuid (uid);
2200  else
2201  p = getpwnam (username_c);
2202 
2203  if (p != NULL)
2204  {
2205  if (!fill_user_info_from_passwd (p, info, error))
2206  {
2207  return FALSE;
2208  }
2209  }
2210  else
2211  {
2212  dbus_set_error (error, _dbus_error_from_errno (errno),
2213  "User \"%s\" unknown or no memory to allocate password entry\n",
2214  username_c ? username_c : "???");
2215  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2216  return FALSE;
2217  }
2218  }
2219 #endif /* ! HAVE_GETPWNAM_R */
2220 
2221  /* Fill this in so we can use it to get groups */
2222  username_c = info->username;
2223 
2224 #ifdef HAVE_GETGROUPLIST
2225  {
2226  gid_t *buf;
2227  int buf_count;
2228  int i;
2229  int initial_buf_count;
2230 
2231  initial_buf_count = 17;
2232  buf_count = initial_buf_count;
2233  buf = dbus_new (gid_t, buf_count);
2234  if (buf == NULL)
2235  {
2237  goto failed;
2238  }
2239 
2240  if (getgrouplist (username_c,
2241  info->primary_gid,
2242  buf, &buf_count) < 0)
2243  {
2244  gid_t *new;
2245  /* Presumed cause of negative return code: buf has insufficient
2246  entries to hold the entire group list. The Linux behavior in this
2247  case is to pass back the actual number of groups in buf_count, but
2248  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2249  So as a hack, try to help out a bit by guessing a larger
2250  number of groups, within reason.. might still fail, of course,
2251  but we can at least print a more informative message. I looked up
2252  the "right way" to do this by downloading Apple's own source code
2253  for the "id" command, and it turns out that they use an
2254  undocumented library function getgrouplist_2 (!) which is not
2255  declared in any header in /usr/include (!!). That did not seem
2256  like the way to go here.
2257  */
2258  if (buf_count == initial_buf_count)
2259  {
2260  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2261  }
2262  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2263  if (new == NULL)
2264  {
2266  dbus_free (buf);
2267  goto failed;
2268  }
2269 
2270  buf = new;
2271 
2272  errno = 0;
2273  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2274  {
2275  if (errno == 0)
2276  {
2277  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2278  username_c, buf_count, buf_count);
2279  }
2280  else
2281  {
2282  dbus_set_error (error,
2283  _dbus_error_from_errno (errno),
2284  "Failed to get groups for username \"%s\" primary GID "
2285  DBUS_GID_FORMAT ": %s\n",
2286  username_c, info->primary_gid,
2287  _dbus_strerror (errno));
2288  dbus_free (buf);
2289  goto failed;
2290  }
2291  }
2292  }
2293 
2294  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2295  if (info->group_ids == NULL)
2296  {
2298  dbus_free (buf);
2299  goto failed;
2300  }
2301 
2302  for (i = 0; i < buf_count; ++i)
2303  info->group_ids[i] = buf[i];
2304 
2305  info->n_group_ids = buf_count;
2306 
2307  dbus_free (buf);
2308  }
2309 #else /* HAVE_GETGROUPLIST */
2310  {
2311  /* We just get the one group ID */
2312  info->group_ids = dbus_new (dbus_gid_t, 1);
2313  if (info->group_ids == NULL)
2314  {
2316  goto failed;
2317  }
2318 
2319  info->n_group_ids = 1;
2320 
2321  (info->group_ids)[0] = info->primary_gid;
2322  }
2323 #endif /* HAVE_GETGROUPLIST */
2324 
2325  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2326 
2327  return TRUE;
2328 
2329  failed:
2330  _DBUS_ASSERT_ERROR_IS_SET (error);
2331  return FALSE;
2332 }
2333 
2344  const DBusString *username,
2345  DBusError *error)
2346 {
2347  return fill_user_info (info, DBUS_UID_UNSET,
2348  username, error);
2349 }
2350 
2361  dbus_uid_t uid,
2362  DBusError *error)
2363 {
2364  return fill_user_info (info, uid,
2365  NULL, error);
2366 }
2367 
2377 {
2378  /* The POSIX spec certainly doesn't promise this, but
2379  * we need these assertions to fail as soon as we're wrong about
2380  * it so we can do the porting fixups
2381  */
2382  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2383  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2384  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2385 
2386  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2387  return FALSE;
2388  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2389  return FALSE;
2390 
2391  return TRUE;
2392 }
2393 
2407 {
2408  return _dbus_string_append_uint (str,
2409  _dbus_geteuid ());
2410 }
2411 
2416 dbus_pid_t
2418 {
2419  return getpid ();
2420 }
2421 
2425 dbus_uid_t
2427 {
2428  return getuid ();
2429 }
2430 
2434 dbus_uid_t
2436 {
2437  return geteuid ();
2438 }
2439 
2446 unsigned long
2448 {
2449  return getpid ();
2450 }
2451 
2460 _dbus_parse_uid (const DBusString *uid_str,
2461  dbus_uid_t *uid)
2462 {
2463  int end;
2464  long val;
2465 
2466  if (_dbus_string_get_length (uid_str) == 0)
2467  {
2468  _dbus_verbose ("UID string was zero length\n");
2469  return FALSE;
2470  }
2471 
2472  val = -1;
2473  end = 0;
2474  if (!_dbus_string_parse_int (uid_str, 0, &val,
2475  &end))
2476  {
2477  _dbus_verbose ("could not parse string as a UID\n");
2478  return FALSE;
2479  }
2480 
2481  if (end != _dbus_string_get_length (uid_str))
2482  {
2483  _dbus_verbose ("string contained trailing stuff after UID\n");
2484  return FALSE;
2485  }
2486 
2487  *uid = val;
2488 
2489  return TRUE;
2490 }
2491 
2492 #if !DBUS_USE_SYNC
2493 /* To be thread-safe by default on platforms that don't necessarily have
2494  * atomic operations (notably Debian armel, which is armv4t), we must
2495  * use a mutex that can be initialized statically, like this.
2496  * GLib >= 2.32 uses a similar system.
2497  */
2498 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2499 #endif
2500 
2507 dbus_int32_t
2509 {
2510 #if DBUS_USE_SYNC
2511  return __sync_add_and_fetch(&atomic->value, 1)-1;
2512 #else
2513  dbus_int32_t res;
2514 
2515  pthread_mutex_lock (&atomic_mutex);
2516  res = atomic->value;
2517  atomic->value += 1;
2518  pthread_mutex_unlock (&atomic_mutex);
2519 
2520  return res;
2521 #endif
2522 }
2523 
2530 dbus_int32_t
2532 {
2533 #if DBUS_USE_SYNC
2534  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2535 #else
2536  dbus_int32_t res;
2537 
2538  pthread_mutex_lock (&atomic_mutex);
2539  res = atomic->value;
2540  atomic->value -= 1;
2541  pthread_mutex_unlock (&atomic_mutex);
2542 
2543  return res;
2544 #endif
2545 }
2546 
2554 dbus_int32_t
2556 {
2557 #if DBUS_USE_SYNC
2558  __sync_synchronize ();
2559  return atomic->value;
2560 #else
2561  dbus_int32_t res;
2562 
2563  pthread_mutex_lock (&atomic_mutex);
2564  res = atomic->value;
2565  pthread_mutex_unlock (&atomic_mutex);
2566 
2567  return res;
2568 #endif
2569 }
2570 
2579 int
2581  int n_fds,
2582  int timeout_milliseconds)
2583 {
2584 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2585  /* This big thing is a constant expression and should get optimized
2586  * out of existence. So it's more robust than a configure check at
2587  * no cost.
2588  */
2589  if (_DBUS_POLLIN == POLLIN &&
2590  _DBUS_POLLPRI == POLLPRI &&
2591  _DBUS_POLLOUT == POLLOUT &&
2592  _DBUS_POLLERR == POLLERR &&
2593  _DBUS_POLLHUP == POLLHUP &&
2594  _DBUS_POLLNVAL == POLLNVAL &&
2595  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2596  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2597  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2598  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2599  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2600  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2601  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2602  {
2603  return poll ((struct pollfd*) fds,
2604  n_fds,
2605  timeout_milliseconds);
2606  }
2607  else
2608  {
2609  /* We have to convert the DBusPollFD to an array of
2610  * struct pollfd, poll, and convert back.
2611  */
2612  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2613  return -1;
2614  }
2615 #else /* ! HAVE_POLL */
2616 
2617  fd_set read_set, write_set, err_set;
2618  int max_fd = 0;
2619  int i;
2620  struct timeval tv;
2621  int ready;
2622 
2623  FD_ZERO (&read_set);
2624  FD_ZERO (&write_set);
2625  FD_ZERO (&err_set);
2626 
2627  for (i = 0; i < n_fds; i++)
2628  {
2629  DBusPollFD *fdp = &fds[i];
2630 
2631  if (fdp->events & _DBUS_POLLIN)
2632  FD_SET (fdp->fd, &read_set);
2633 
2634  if (fdp->events & _DBUS_POLLOUT)
2635  FD_SET (fdp->fd, &write_set);
2636 
2637  FD_SET (fdp->fd, &err_set);
2638 
2639  max_fd = MAX (max_fd, fdp->fd);
2640  }
2641 
2642  tv.tv_sec = timeout_milliseconds / 1000;
2643  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2644 
2645  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2646  timeout_milliseconds < 0 ? NULL : &tv);
2647 
2648  if (ready > 0)
2649  {
2650  for (i = 0; i < n_fds; i++)
2651  {
2652  DBusPollFD *fdp = &fds[i];
2653 
2654  fdp->revents = 0;
2655 
2656  if (FD_ISSET (fdp->fd, &read_set))
2657  fdp->revents |= _DBUS_POLLIN;
2658 
2659  if (FD_ISSET (fdp->fd, &write_set))
2660  fdp->revents |= _DBUS_POLLOUT;
2661 
2662  if (FD_ISSET (fdp->fd, &err_set))
2663  fdp->revents |= _DBUS_POLLERR;
2664  }
2665  }
2666 
2667  return ready;
2668 #endif
2669 }
2670 
2678 void
2680  long *tv_usec)
2681 {
2682 #ifdef HAVE_MONOTONIC_CLOCK
2683  struct timespec ts;
2684  clock_gettime (CLOCK_MONOTONIC, &ts);
2685 
2686  if (tv_sec)
2687  *tv_sec = ts.tv_sec;
2688  if (tv_usec)
2689  *tv_usec = ts.tv_nsec / 1000;
2690 #else
2691  struct timeval t;
2692 
2693  gettimeofday (&t, NULL);
2694 
2695  if (tv_sec)
2696  *tv_sec = t.tv_sec;
2697  if (tv_usec)
2698  *tv_usec = t.tv_usec;
2699 #endif
2700 }
2701 
2709 void
2710 _dbus_get_real_time (long *tv_sec,
2711  long *tv_usec)
2712 {
2713  struct timeval t;
2714 
2715  gettimeofday (&t, NULL);
2716 
2717  if (tv_sec)
2718  *tv_sec = t.tv_sec;
2719  if (tv_usec)
2720  *tv_usec = t.tv_usec;
2721 }
2722 
2733  DBusError *error)
2734 {
2735  const char *filename_c;
2736 
2737  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2738 
2739  filename_c = _dbus_string_get_const_data (filename);
2740 
2741  if (mkdir (filename_c, 0700) < 0)
2742  {
2743  if (errno == EEXIST)
2744  return TRUE;
2745 
2747  "Failed to create directory %s: %s\n",
2748  filename_c, _dbus_strerror (errno));
2749  return FALSE;
2750  }
2751  else
2752  return TRUE;
2753 }
2754 
2767  const DBusString *next_component)
2768 {
2769  dbus_bool_t dir_ends_in_slash;
2770  dbus_bool_t file_starts_with_slash;
2771 
2772  if (_dbus_string_get_length (dir) == 0 ||
2773  _dbus_string_get_length (next_component) == 0)
2774  return TRUE;
2775 
2776  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2777  _dbus_string_get_length (dir) - 1);
2778 
2779  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2780 
2781  if (dir_ends_in_slash && file_starts_with_slash)
2782  {
2783  _dbus_string_shorten (dir, 1);
2784  }
2785  else if (!(dir_ends_in_slash || file_starts_with_slash))
2786  {
2787  if (!_dbus_string_append_byte (dir, '/'))
2788  return FALSE;
2789  }
2790 
2791  return _dbus_string_copy (next_component, 0, dir,
2792  _dbus_string_get_length (dir));
2793 }
2794 
2796 #define NANOSECONDS_PER_SECOND 1000000000
2797 
2798 #define MICROSECONDS_PER_SECOND 1000000
2799 
2800 #define MILLISECONDS_PER_SECOND 1000
2801 
2802 #define NANOSECONDS_PER_MILLISECOND 1000000
2803 
2804 #define MICROSECONDS_PER_MILLISECOND 1000
2805 
2810 void
2811 _dbus_sleep_milliseconds (int milliseconds)
2812 {
2813 #ifdef HAVE_NANOSLEEP
2814  struct timespec req;
2815  struct timespec rem;
2816 
2817  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2818  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2819  rem.tv_sec = 0;
2820  rem.tv_nsec = 0;
2821 
2822  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2823  req = rem;
2824 #elif defined (HAVE_USLEEP)
2825  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2826 #else /* ! HAVE_USLEEP */
2827  sleep (MAX (milliseconds / 1000, 1));
2828 #endif
2829 }
2830 
2831 static dbus_bool_t
2832 _dbus_generate_pseudorandom_bytes (DBusString *str,
2833  int n_bytes)
2834 {
2835  int old_len;
2836  char *p;
2837 
2838  old_len = _dbus_string_get_length (str);
2839 
2840  if (!_dbus_string_lengthen (str, n_bytes))
2841  return FALSE;
2842 
2843  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2844 
2846 
2847  return TRUE;
2848 }
2849 
2860  int n_bytes)
2861 {
2862  int old_len;
2863  int fd;
2864 
2865  /* FALSE return means "no memory", if it could
2866  * mean something else then we'd need to return
2867  * a DBusError. So we always fall back to pseudorandom
2868  * if the I/O fails.
2869  */
2870 
2871  old_len = _dbus_string_get_length (str);
2872  fd = -1;
2873 
2874  /* note, urandom on linux will fall back to pseudorandom */
2875  fd = open ("/dev/urandom", O_RDONLY);
2876  if (fd < 0)
2877  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2878 
2879  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2880 
2881  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2882  {
2883  _dbus_close (fd, NULL);
2884  _dbus_string_set_length (str, old_len);
2885  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2886  }
2887 
2888  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2889  n_bytes);
2890 
2891  _dbus_close (fd, NULL);
2892 
2893  return TRUE;
2894 }
2895 
2901 void
2902 _dbus_exit (int code)
2903 {
2904  _exit (code);
2905 }
2906 
2915 const char*
2916 _dbus_strerror (int error_number)
2917 {
2918  const char *msg;
2919 
2920  msg = strerror (error_number);
2921  if (msg == NULL)
2922  msg = "unknown";
2923 
2924  return msg;
2925 }
2926 
2930 void
2932 {
2933  signal (SIGPIPE, SIG_IGN);
2934 }
2935 
2943 void
2945 {
2946  int val;
2947 
2948  val = fcntl (fd, F_GETFD, 0);
2949 
2950  if (val < 0)
2951  return;
2952 
2953  val |= FD_CLOEXEC;
2954 
2955  fcntl (fd, F_SETFD, val);
2956 }
2957 
2966 _dbus_close (int fd,
2967  DBusError *error)
2968 {
2969  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2970 
2971  again:
2972  if (close (fd) < 0)
2973  {
2974  if (errno == EINTR)
2975  goto again;
2976 
2977  dbus_set_error (error, _dbus_error_from_errno (errno),
2978  "Could not close fd %d", fd);
2979  return FALSE;
2980  }
2981 
2982  return TRUE;
2983 }
2984 
2993 int
2994 _dbus_dup(int fd,
2995  DBusError *error)
2996 {
2997  int new_fd;
2998 
2999 #ifdef F_DUPFD_CLOEXEC
3000  dbus_bool_t cloexec_done;
3001 
3002  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3003  cloexec_done = new_fd >= 0;
3004 
3005  if (new_fd < 0 && errno == EINVAL)
3006 #endif
3007  {
3008  new_fd = fcntl(fd, F_DUPFD, 3);
3009  }
3010 
3011  if (new_fd < 0) {
3012 
3013  dbus_set_error (error, _dbus_error_from_errno (errno),
3014  "Could not duplicate fd %d", fd);
3015  return -1;
3016  }
3017 
3018 #ifdef F_DUPFD_CLOEXEC
3019  if (!cloexec_done)
3020 #endif
3021  {
3023  }
3024 
3025  return new_fd;
3026 }
3027 
3036 _dbus_set_fd_nonblocking (int fd,
3037  DBusError *error)
3038 {
3039  int val;
3040 
3041  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3042 
3043  val = fcntl (fd, F_GETFL, 0);
3044  if (val < 0)
3045  {
3046  dbus_set_error (error, _dbus_error_from_errno (errno),
3047  "Failed to get flags from file descriptor %d: %s",
3048  fd, _dbus_strerror (errno));
3049  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3050  _dbus_strerror (errno));
3051  return FALSE;
3052  }
3053 
3054  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3055  {
3056  dbus_set_error (error, _dbus_error_from_errno (errno),
3057  "Failed to set nonblocking flag of file descriptor %d: %s",
3058  fd, _dbus_strerror (errno));
3059  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3060  fd, _dbus_strerror (errno));
3061 
3062  return FALSE;
3063  }
3064 
3065  return TRUE;
3066 }
3067 
3073 void
3075 {
3076 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3077  void *bt[500];
3078  int bt_size;
3079  int i;
3080  char **syms;
3081 
3082  bt_size = backtrace (bt, 500);
3083 
3084  syms = backtrace_symbols (bt, bt_size);
3085 
3086  i = 0;
3087  while (i < bt_size)
3088  {
3089  /* don't use dbus_warn since it can _dbus_abort() */
3090  fprintf (stderr, " %s\n", syms[i]);
3091  ++i;
3092  }
3093  fflush (stderr);
3094 
3095  free (syms);
3096 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3097  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3098 #else
3099  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3100 #endif
3101 }
3102 
3117  int *fd2,
3118  dbus_bool_t blocking,
3119  DBusError *error)
3120 {
3121 #ifdef HAVE_SOCKETPAIR
3122  int fds[2];
3123  int retval;
3124 
3125 #ifdef SOCK_CLOEXEC
3126  dbus_bool_t cloexec_done;
3127 
3128  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3129  cloexec_done = retval >= 0;
3130 
3131  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3132 #endif
3133  {
3134  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3135  }
3136 
3137  if (retval < 0)
3138  {
3139  dbus_set_error (error, _dbus_error_from_errno (errno),
3140  "Could not create full-duplex pipe");
3141  return FALSE;
3142  }
3143 
3144  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3145 
3146 #ifdef SOCK_CLOEXEC
3147  if (!cloexec_done)
3148 #endif
3149  {
3150  _dbus_fd_set_close_on_exec (fds[0]);
3151  _dbus_fd_set_close_on_exec (fds[1]);
3152  }
3153 
3154  if (!blocking &&
3155  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3156  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3157  {
3158  dbus_set_error (error, _dbus_error_from_errno (errno),
3159  "Could not set full-duplex pipe nonblocking");
3160 
3161  _dbus_close (fds[0], NULL);
3162  _dbus_close (fds[1], NULL);
3163 
3164  return FALSE;
3165  }
3166 
3167  *fd1 = fds[0];
3168  *fd2 = fds[1];
3169 
3170  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3171  *fd1, *fd2);
3172 
3173  return TRUE;
3174 #else
3175  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3177  "_dbus_full_duplex_pipe() not implemented on this OS");
3178  return FALSE;
3179 #endif
3180 }
3181 
3190 int
3192  va_list args)
3193 {
3194  char static_buf[1024];
3195  int bufsize = sizeof (static_buf);
3196  int len;
3197  va_list args_copy;
3198 
3199  DBUS_VA_COPY (args_copy, args);
3200  len = vsnprintf (static_buf, bufsize, format, args_copy);
3201  va_end (args_copy);
3202 
3203  /* If vsnprintf() returned non-negative, then either the string fits in
3204  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3205  * returns the number of characters that were needed, or this OS returns the
3206  * truncated length.
3207  *
3208  * We ignore the possibility that snprintf might just ignore the length and
3209  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3210  * If your libc is really that bad, come back when you have a better one. */
3211  if (len == bufsize)
3212  {
3213  /* This could be the truncated length (Tru64 and IRIX have this bug),
3214  * or the real length could be coincidentally the same. Which is it?
3215  * If vsnprintf returns the truncated length, we'll go to the slow
3216  * path. */
3217  DBUS_VA_COPY (args_copy, args);
3218 
3219  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3220  len = -1;
3221 
3222  va_end (args_copy);
3223  }
3224 
3225  /* If vsnprintf() returned negative, we have to do more work.
3226  * HP-UX returns negative. */
3227  while (len < 0)
3228  {
3229  char *buf;
3230 
3231  bufsize *= 2;
3232 
3233  buf = dbus_malloc (bufsize);
3234 
3235  if (buf == NULL)
3236  return -1;
3237 
3238  DBUS_VA_COPY (args_copy, args);
3239  len = vsnprintf (buf, bufsize, format, args_copy);
3240  va_end (args_copy);
3241 
3242  dbus_free (buf);
3243 
3244  /* If the reported length is exactly the buffer size, round up to the
3245  * next size, in case vsnprintf has been returning the truncated
3246  * length */
3247  if (len == bufsize)
3248  len = -1;
3249  }
3250 
3251  return len;
3252 }
3253 
3260 const char*
3262 {
3263  /* Protected by _DBUS_LOCK_sysdeps */
3264  static const char* tmpdir = NULL;
3265 
3266  if (!_DBUS_LOCK (sysdeps))
3267  return NULL;
3268 
3269  if (tmpdir == NULL)
3270  {
3271  /* TMPDIR is what glibc uses, then
3272  * glibc falls back to the P_tmpdir macro which
3273  * just expands to "/tmp"
3274  */
3275  if (tmpdir == NULL)
3276  tmpdir = getenv("TMPDIR");
3277 
3278  /* These two env variables are probably
3279  * broken, but maybe some OS uses them?
3280  */
3281  if (tmpdir == NULL)
3282  tmpdir = getenv("TMP");
3283  if (tmpdir == NULL)
3284  tmpdir = getenv("TEMP");
3285 
3286  /* And this is the sane fallback. */
3287  if (tmpdir == NULL)
3288  tmpdir = "/tmp";
3289  }
3290 
3291  _DBUS_UNLOCK (sysdeps);
3292 
3293  _dbus_assert(tmpdir != NULL);
3294 
3295  return tmpdir;
3296 }
3297 
3298 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3299 
3318 static dbus_bool_t
3319 _read_subprocess_line_argv (const char *progpath,
3320  dbus_bool_t path_fallback,
3321  char * const *argv,
3322  DBusString *result,
3323  DBusError *error)
3324 {
3325  int result_pipe[2] = { -1, -1 };
3326  int errors_pipe[2] = { -1, -1 };
3327  pid_t pid;
3328  int ret;
3329  int status;
3330  int orig_len;
3331 
3332  dbus_bool_t retval;
3333  sigset_t new_set, old_set;
3334 
3335  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3336  retval = FALSE;
3337 
3338  /* We need to block any existing handlers for SIGCHLD temporarily; they
3339  * will cause waitpid() below to fail.
3340  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3341  */
3342  sigemptyset (&new_set);
3343  sigaddset (&new_set, SIGCHLD);
3344  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3345 
3346  orig_len = _dbus_string_get_length (result);
3347 
3348 #define READ_END 0
3349 #define WRITE_END 1
3350  if (pipe (result_pipe) < 0)
3351  {
3352  dbus_set_error (error, _dbus_error_from_errno (errno),
3353  "Failed to create a pipe to call %s: %s",
3354  progpath, _dbus_strerror (errno));
3355  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3356  progpath, _dbus_strerror (errno));
3357  goto out;
3358  }
3359  if (pipe (errors_pipe) < 0)
3360  {
3361  dbus_set_error (error, _dbus_error_from_errno (errno),
3362  "Failed to create a pipe to call %s: %s",
3363  progpath, _dbus_strerror (errno));
3364  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3365  progpath, _dbus_strerror (errno));
3366  goto out;
3367  }
3368 
3369  pid = fork ();
3370  if (pid < 0)
3371  {
3372  dbus_set_error (error, _dbus_error_from_errno (errno),
3373  "Failed to fork() to call %s: %s",
3374  progpath, _dbus_strerror (errno));
3375  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3376  progpath, _dbus_strerror (errno));
3377  goto out;
3378  }
3379 
3380  if (pid == 0)
3381  {
3382  /* child process */
3383  int fd;
3384 
3385  fd = open ("/dev/null", O_RDWR);
3386  if (fd == -1)
3387  /* huh?! can't open /dev/null? */
3388  _exit (1);
3389 
3390  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3391 
3392  /* set-up stdXXX */
3393  close (result_pipe[READ_END]);
3394  close (errors_pipe[READ_END]);
3395 
3396  if (dup2 (fd, 0) == -1) /* setup stdin */
3397  _exit (1);
3398  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3399  _exit (1);
3400  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3401  _exit (1);
3402 
3403  _dbus_close_all ();
3404 
3405  sigprocmask (SIG_SETMASK, &old_set, NULL);
3406 
3407  /* If it looks fully-qualified, try execv first */
3408  if (progpath[0] == '/')
3409  {
3410  execv (progpath, argv);
3411  /* Ok, that failed. Now if path_fallback is given, let's
3412  * try unqualified. This is mostly a hack to work
3413  * around systems which ship dbus-launch in /usr/bin
3414  * but everything else in /bin (because dbus-launch
3415  * depends on X11).
3416  */
3417  if (path_fallback)
3418  /* We must have a slash, because we checked above */
3419  execvp (strrchr (progpath, '/')+1, argv);
3420  }
3421  else
3422  execvp (progpath, argv);
3423 
3424  /* still nothing, we failed */
3425  _exit (1);
3426  }
3427 
3428  /* parent process */
3429  close (result_pipe[WRITE_END]);
3430  close (errors_pipe[WRITE_END]);
3431  result_pipe[WRITE_END] = -1;
3432  errors_pipe[WRITE_END] = -1;
3433 
3434  ret = 0;
3435  do
3436  {
3437  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3438  }
3439  while (ret > 0);
3440 
3441  /* reap the child process to avoid it lingering as zombie */
3442  do
3443  {
3444  ret = waitpid (pid, &status, 0);
3445  }
3446  while (ret == -1 && errno == EINTR);
3447 
3448  /* We succeeded if the process exited with status 0 and
3449  anything was read */
3450  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3451  {
3452  /* The process ended with error */
3453  DBusString error_message;
3454  if (!_dbus_string_init (&error_message))
3455  {
3456  _DBUS_SET_OOM (error);
3457  goto out;
3458  }
3459 
3460  ret = 0;
3461  do
3462  {
3463  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3464  }
3465  while (ret > 0);
3466 
3467  _dbus_string_set_length (result, orig_len);
3468  if (_dbus_string_get_length (&error_message) > 0)
3470  "%s terminated abnormally with the following error: %s",
3471  progpath, _dbus_string_get_data (&error_message));
3472  else
3474  "%s terminated abnormally without any error message",
3475  progpath);
3476  goto out;
3477  }
3478 
3479  retval = TRUE;
3480 
3481  out:
3482  sigprocmask (SIG_SETMASK, &old_set, NULL);
3483 
3484  if (retval)
3485  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3486  else
3487  _DBUS_ASSERT_ERROR_IS_SET (error);
3488 
3489  if (result_pipe[0] != -1)
3490  close (result_pipe[0]);
3491  if (result_pipe[1] != -1)
3492  close (result_pipe[1]);
3493  if (errors_pipe[0] != -1)
3494  close (errors_pipe[0]);
3495  if (errors_pipe[1] != -1)
3496  close (errors_pipe[1]);
3497 
3498  return retval;
3499 }
3500 #endif
3501 
3515 _dbus_get_autolaunch_address (const char *scope,
3516  DBusString *address,
3517  DBusError *error)
3518 {
3519 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3520  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3521  * but that's done elsewhere, and if it worked, this function wouldn't
3522  * be called.) */
3523  const char *display;
3524  char *argv[6];
3525  int i;
3526  DBusString uuid;
3527  dbus_bool_t retval;
3528 
3529  if (_dbus_check_setuid ())
3530  {
3532  "Unable to autolaunch when setuid");
3533  return FALSE;
3534  }
3535 
3536  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3537  retval = FALSE;
3538 
3539  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3540  * dbus-launch-x11 is just going to fail. Rather than trying to
3541  * run it, we might as well bail out early with a nice error. */
3542  display = _dbus_getenv ("DISPLAY");
3543 
3544  if (display == NULL || display[0] == '\0')
3545  {
3547  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3548  return FALSE;
3549  }
3550 
3551  if (!_dbus_string_init (&uuid))
3552  {
3553  _DBUS_SET_OOM (error);
3554  return FALSE;
3555  }
3556 
3558  {
3559  _DBUS_SET_OOM (error);
3560  goto out;
3561  }
3562 
3563  i = 0;
3564 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3565  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3566  argv[i] = TEST_BUS_LAUNCH_BINARY;
3567  else
3568 #endif
3569  argv[i] = DBUS_BINDIR "/dbus-launch";
3570  ++i;
3571  argv[i] = "--autolaunch";
3572  ++i;
3573  argv[i] = _dbus_string_get_data (&uuid);
3574  ++i;
3575  argv[i] = "--binary-syntax";
3576  ++i;
3577  argv[i] = "--close-stderr";
3578  ++i;
3579  argv[i] = NULL;
3580  ++i;
3581 
3582  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3583 
3584  retval = _read_subprocess_line_argv (argv[0],
3585  TRUE,
3586  argv, address, error);
3587 
3588  out:
3589  _dbus_string_free (&uuid);
3590  return retval;
3591 #else
3593  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3594  "set your DBUS_SESSION_BUS_ADDRESS instead");
3595  return FALSE;
3596 #endif
3597 }
3598 
3619  dbus_bool_t create_if_not_found,
3620  DBusError *error)
3621 {
3622  DBusString filename;
3623  dbus_bool_t b;
3624 
3625  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3626 
3627  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3628  if (b)
3629  return TRUE;
3630 
3631  dbus_error_free (error);
3632 
3633  /* Fallback to the system machine ID */
3634  _dbus_string_init_const (&filename, "/etc/machine-id");
3635  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3636 
3637  if (b)
3638  {
3639  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3640  * complain if that isn't possible for whatever reason */
3641  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3642  _dbus_write_uuid_file (&filename, machine_id, NULL);
3643 
3644  return TRUE;
3645  }
3646 
3647  if (!create_if_not_found)
3648  return FALSE;
3649 
3650  /* if none found, try to make a new one */
3651  dbus_error_free (error);
3652  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3653  _dbus_generate_uuid (machine_id);
3654  return _dbus_write_uuid_file (&filename, machine_id, error);
3655 }
3656 
3666  const char *launchd_env_var,
3667  DBusError *error)
3668 {
3669 #ifdef DBUS_ENABLE_LAUNCHD
3670  char *argv[4];
3671  int i;
3672 
3673  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3674 
3675  if (_dbus_check_setuid ())
3676  {
3678  "Unable to find launchd socket when setuid");
3679  return FALSE;
3680  }
3681 
3682  i = 0;
3683  argv[i] = "launchctl";
3684  ++i;
3685  argv[i] = "getenv";
3686  ++i;
3687  argv[i] = (char*)launchd_env_var;
3688  ++i;
3689  argv[i] = NULL;
3690  ++i;
3691 
3692  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3693 
3694  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3695  {
3696  return FALSE;
3697  }
3698 
3699  /* no error, but no result either */
3700  if (_dbus_string_get_length(socket_path) == 0)
3701  {
3702  return FALSE;
3703  }
3704 
3705  /* strip the carriage-return */
3706  _dbus_string_shorten(socket_path, 1);
3707  return TRUE;
3708 #else /* DBUS_ENABLE_LAUNCHD */
3710  "can't lookup socket from launchd; launchd support not compiled in");
3711  return FALSE;
3712 #endif
3713 }
3714 
3715 #ifdef DBUS_ENABLE_LAUNCHD
3716 static dbus_bool_t
3717 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3718 {
3719  dbus_bool_t valid_socket;
3720  DBusString socket_path;
3721 
3722  if (_dbus_check_setuid ())
3723  {
3725  "Unable to find launchd socket when setuid");
3726  return FALSE;
3727  }
3728 
3729  if (!_dbus_string_init (&socket_path))
3730  {
3731  _DBUS_SET_OOM (error);
3732  return FALSE;
3733  }
3734 
3735  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3736 
3737  if (dbus_error_is_set(error))
3738  {
3739  _dbus_string_free(&socket_path);
3740  return FALSE;
3741  }
3742 
3743  if (!valid_socket)
3744  {
3745  dbus_set_error(error, "no socket path",
3746  "launchd did not provide a socket path, "
3747  "verify that org.freedesktop.dbus-session.plist is loaded!");
3748  _dbus_string_free(&socket_path);
3749  return FALSE;
3750  }
3751  if (!_dbus_string_append (address, "unix:path="))
3752  {
3753  _DBUS_SET_OOM (error);
3754  _dbus_string_free(&socket_path);
3755  return FALSE;
3756  }
3757  if (!_dbus_string_copy (&socket_path, 0, address,
3758  _dbus_string_get_length (address)))
3759  {
3760  _DBUS_SET_OOM (error);
3761  _dbus_string_free(&socket_path);
3762  return FALSE;
3763  }
3764 
3765  _dbus_string_free(&socket_path);
3766  return TRUE;
3767 }
3768 #endif
3769 
3791  DBusString *address,
3792  DBusError *error)
3793 {
3794 #ifdef DBUS_ENABLE_LAUNCHD
3795  *supported = TRUE;
3796  return _dbus_lookup_session_address_launchd (address, error);
3797 #else
3798  /* On non-Mac Unix platforms, if the session address isn't already
3799  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3800  * fall back to the autolaunch: global default; see
3801  * init_session_address in dbus/dbus-bus.c. */
3802  *supported = FALSE;
3803  return TRUE;
3804 #endif
3805 }
3806 
3814 void
3816 {
3818 }
3819 
3835  DBusCredentials *credentials)
3836 {
3837  DBusString homedir;
3838  DBusString dotdir;
3839  dbus_uid_t uid;
3840 
3841  _dbus_assert (credentials != NULL);
3843 
3844  if (!_dbus_string_init (&homedir))
3845  return FALSE;
3846 
3847  uid = _dbus_credentials_get_unix_uid (credentials);
3848  _dbus_assert (uid != DBUS_UID_UNSET);
3849 
3850  if (!_dbus_homedir_from_uid (uid, &homedir))
3851  goto failed;
3852 
3853 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3854  {
3855  const char *override;
3856 
3857  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3858  if (override != NULL && *override != '\0')
3859  {
3860  _dbus_string_set_length (&homedir, 0);
3861  if (!_dbus_string_append (&homedir, override))
3862  goto failed;
3863 
3864  _dbus_verbose ("Using fake homedir for testing: %s\n",
3865  _dbus_string_get_const_data (&homedir));
3866  }
3867  else
3868  {
3869  /* Not strictly thread-safe, but if we fail at thread-safety here,
3870  * the worst that will happen is some extra warnings. */
3871  static dbus_bool_t already_warned = FALSE;
3872  if (!already_warned)
3873  {
3874  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3875  already_warned = TRUE;
3876  }
3877  }
3878  }
3879 #endif
3880 
3881  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3882  if (!_dbus_concat_dir_and_file (&homedir,
3883  &dotdir))
3884  goto failed;
3885 
3886  if (!_dbus_string_copy (&homedir, 0,
3887  directory, _dbus_string_get_length (directory))) {
3888  goto failed;
3889  }
3890 
3891  _dbus_string_free (&homedir);
3892  return TRUE;
3893 
3894  failed:
3895  _dbus_string_free (&homedir);
3896  return FALSE;
3897 }
3898 
3899 //PENDING(kdab) docs
3901 _dbus_daemon_publish_session_bus_address (const char* addr,
3902  const char *scope)
3903 {
3904  return TRUE;
3905 }
3906 
3907 //PENDING(kdab) docs
3908 void
3909 _dbus_daemon_unpublish_session_bus_address (void)
3910 {
3911 
3912 }
3913 
3922 {
3923  return errno == EAGAIN || errno == EWOULDBLOCK;
3924 }
3925 
3935  DBusError *error)
3936 {
3937  const char *filename_c;
3938 
3939  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3940 
3941  filename_c = _dbus_string_get_const_data (filename);
3942 
3943  if (rmdir (filename_c) != 0)
3944  {
3946  "Failed to remove directory %s: %s\n",
3947  filename_c, _dbus_strerror (errno));
3948  return FALSE;
3949  }
3950 
3951  return TRUE;
3952 }
3953 
3963 
3964 #ifdef SCM_RIGHTS
3965  union {
3966  struct sockaddr sa;
3967  struct sockaddr_storage storage;
3968  struct sockaddr_un un;
3969  } sa_buf;
3970 
3971  socklen_t sa_len = sizeof(sa_buf);
3972 
3973  _DBUS_ZERO(sa_buf);
3974 
3975  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3976  return FALSE;
3977 
3978  return sa_buf.sa.sa_family == AF_UNIX;
3979 
3980 #else
3981  return FALSE;
3982 
3983 #endif
3984 }
3985 
3990 void
3992 {
3993  int maxfds, i;
3994 
3995 #ifdef __linux__
3996  DIR *d;
3997 
3998  /* On Linux we can optimize this a bit if /proc is available. If it
3999  isn't available, fall back to the brute force way. */
4000 
4001  d = opendir ("/proc/self/fd");
4002  if (d)
4003  {
4004  for (;;)
4005  {
4006  struct dirent buf, *de;
4007  int k, fd;
4008  long l;
4009  char *e = NULL;
4010 
4011  k = readdir_r (d, &buf, &de);
4012  if (k != 0 || !de)
4013  break;
4014 
4015  if (de->d_name[0] == '.')
4016  continue;
4017 
4018  errno = 0;
4019  l = strtol (de->d_name, &e, 10);
4020  if (errno != 0 || e == NULL || *e != '\0')
4021  continue;
4022 
4023  fd = (int) l;
4024  if (fd < 3)
4025  continue;
4026 
4027  if (fd == dirfd (d))
4028  continue;
4029 
4030  close (fd);
4031  }
4032 
4033  closedir (d);
4034  return;
4035  }
4036 #endif
4037 
4038  maxfds = sysconf (_SC_OPEN_MAX);
4039 
4040  /* Pick something reasonable if for some reason sysconf says
4041  * unlimited.
4042  */
4043  if (maxfds < 0)
4044  maxfds = 1024;
4045 
4046  /* close all inherited fds */
4047  for (i = 3; i < maxfds; i++)
4048  close (i);
4049 }
4050 
4062 {
4063  /* TODO: get __libc_enable_secure exported from glibc.
4064  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4065  */
4066 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4067  {
4068  /* See glibc/include/unistd.h */
4069  extern int __libc_enable_secure;
4070  return __libc_enable_secure;
4071  }
4072 #elif defined(HAVE_ISSETUGID)
4073  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4074  return issetugid ();
4075 #else
4076  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4077  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4078 
4079  /* We call into this function from _dbus_threads_init_platform_specific()
4080  * to make sure these are initialized before we start threading. */
4081  static dbus_bool_t check_setuid_initialised;
4082  static dbus_bool_t is_setuid;
4083 
4084  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4085  {
4086 #ifdef HAVE_GETRESUID
4087  if (getresuid (&ruid, &euid, &suid) != 0 ||
4088  getresgid (&rgid, &egid, &sgid) != 0)
4089 #endif /* HAVE_GETRESUID */
4090  {
4091  suid = ruid = getuid ();
4092  sgid = rgid = getgid ();
4093  euid = geteuid ();
4094  egid = getegid ();
4095  }
4096 
4097  check_setuid_initialised = TRUE;
4098  is_setuid = (ruid != euid || ruid != suid ||
4099  rgid != egid || rgid != sgid);
4100 
4101  }
4102  return is_setuid;
4103 #endif
4104 }
4105 
4115  DBusString *address,
4116  DBusError *error)
4117 {
4118  union {
4119  struct sockaddr sa;
4120  struct sockaddr_storage storage;
4121  struct sockaddr_un un;
4122  struct sockaddr_in ipv4;
4123  struct sockaddr_in6 ipv6;
4124  } socket;
4125  char hostip[INET6_ADDRSTRLEN];
4126  int size = sizeof (socket);
4127  DBusString path_str;
4128 
4129  if (getsockname (fd, &socket.sa, &size))
4130  goto err;
4131 
4132  switch (socket.sa.sa_family)
4133  {
4134  case AF_UNIX:
4135  if (socket.un.sun_path[0]=='\0')
4136  {
4137  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4138  if (_dbus_string_append (address, "unix:abstract=") &&
4139  _dbus_address_append_escaped (address, &path_str))
4140  return TRUE;
4141  }
4142  else
4143  {
4144  _dbus_string_init_const (&path_str, socket.un.sun_path);
4145  if (_dbus_string_append (address, "unix:path=") &&
4146  _dbus_address_append_escaped (address, &path_str))
4147  return TRUE;
4148  }
4149  break;
4150  case AF_INET:
4151  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4152  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4153  hostip, ntohs (socket.ipv4.sin_port)))
4154  return TRUE;
4155  break;
4156 #ifdef AF_INET6
4157  case AF_INET6:
4158  _dbus_string_init_const (&path_str, hostip);
4159  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4160  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4161  ntohs (socket.ipv6.sin6_port)) &&
4162  _dbus_address_append_escaped (address, &path_str))
4163  return TRUE;
4164  break;
4165 #endif
4166  default:
4167  dbus_set_error (error,
4168  _dbus_error_from_errno (EINVAL),
4169  "Failed to read address from socket: Unknown socket type.");
4170  return FALSE;
4171  }
4172  err:
4173  dbus_set_error (error,
4174  _dbus_error_from_errno (errno),
4175  "Failed to open socket: %s",
4176  _dbus_strerror (errno));
4177  return FALSE;
4178 }
4179 
4180 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:918
dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:227
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:392
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:232
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:302
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:743
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd)
Checks whether file descriptors may be passed via the socket.
#define _DBUS_POLLNVAL
Invalid request: fd not open.
Definition: dbus-sysdeps.h:304
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
dbus_bool_t _dbus_append_address_from_socket(int fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:114
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:110
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_full_duplex_pipe(int *fd1, int *fd2, dbus_bool_t blocking, DBusError *error)
Creates a full-duplex pipe (as in socketpair()).
int _dbus_write_socket_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:349
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_gid_t primary_gid
GID.
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h:296
int _dbus_read_socket_with_unix_fds(int fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
A portable struct pollfd wrapper.
Definition: dbus-sysdeps.h:310
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
int _dbus_accept(int listen_fd)
Accepts a connection on a listening socket.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:294
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:473
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:763
short events
Events to poll for.
Definition: dbus-sysdeps.h:313
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1265
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:103
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:105
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str)
Gets the hex-encoded UUID of the machine this function is executed on.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:614
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:461
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:96
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:298
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1096
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int fd
File descriptor.
Definition: dbus-sysdeps.h:312
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
int _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute. ...
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1139
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:107
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:857
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:112
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
void _dbus_generate_pseudorandom_bytes_buffer(char *buffer, int n_bytes)
Random numbers.
Definition: dbus-sysdeps.c:508
int _dbus_write_socket(int fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(void)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
void _dbus_generate_uuid(DBusGUID *uuid)
Generates a new UUID.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:785
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:859
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:100
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:98
short revents
Events that occurred.
Definition: dbus-sysdeps.h:314
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
int _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
int _dbus_listen_systemd_sockets(int **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:300