D-Bus  1.8.4
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  again:
324 
325  bytes_read = recvmsg(fd, &m, 0
326 #ifdef MSG_CMSG_CLOEXEC
327  |MSG_CMSG_CLOEXEC
328 #endif
329  );
330 
331  if (bytes_read < 0)
332  {
333  if (errno == EINTR)
334  goto again;
335  else
336  {
337  /* put length back (note that this doesn't actually realloc anything) */
338  _dbus_string_set_length (buffer, start);
339  return -1;
340  }
341  }
342  else
343  {
344  struct cmsghdr *cm;
345  dbus_bool_t found = FALSE;
346 
347  if (m.msg_flags & MSG_CTRUNC)
348  {
349  /* Hmm, apparently the control data was truncated. The bad
350  thing is that we might have completely lost a couple of fds
351  without chance to recover them. Hence let's treat this as a
352  serious error. */
353 
354  errno = ENOSPC;
355  _dbus_string_set_length (buffer, start);
356  return -1;
357  }
358 
359  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
360  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
361  {
362  unsigned i;
363 
364  _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
365  *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
366 
367  memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
368  found = TRUE;
369 
370  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
371  worked, hence we need to go through this list and set
372  CLOEXEC everywhere in any case */
373  for (i = 0; i < *n_fds; i++)
375 
376  break;
377  }
378 
379  if (!found)
380  *n_fds = 0;
381 
382  /* put length back (doesn't actually realloc) */
383  _dbus_string_set_length (buffer, start + bytes_read);
384 
385 #if 0
386  if (bytes_read > 0)
387  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
388 #endif
389 
390  return bytes_read;
391  }
392 #endif
393 }
394 
395 int
396 _dbus_write_socket_with_unix_fds(int fd,
397  const DBusString *buffer,
398  int start,
399  int len,
400  const int *fds,
401  int n_fds) {
402 
403 #ifndef HAVE_UNIX_FD_PASSING
404 
405  if (n_fds > 0) {
406  errno = ENOTSUP;
407  return -1;
408  }
409 
410  return _dbus_write_socket(fd, buffer, start, len);
411 #else
412  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
413 #endif
414 }
415 
416 int
417 _dbus_write_socket_with_unix_fds_two(int fd,
418  const DBusString *buffer1,
419  int start1,
420  int len1,
421  const DBusString *buffer2,
422  int start2,
423  int len2,
424  const int *fds,
425  int n_fds) {
426 
427 #ifndef HAVE_UNIX_FD_PASSING
428 
429  if (n_fds > 0) {
430  errno = ENOTSUP;
431  return -1;
432  }
433 
434  return _dbus_write_socket_two(fd,
435  buffer1, start1, len1,
436  buffer2, start2, len2);
437 #else
438 
439  struct msghdr m;
440  struct cmsghdr *cm;
441  struct iovec iov[2];
442  int bytes_written;
443 
444  _dbus_assert (len1 >= 0);
445  _dbus_assert (len2 >= 0);
446  _dbus_assert (n_fds >= 0);
447 
448  _DBUS_ZERO(iov);
449  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
450  iov[0].iov_len = len1;
451 
452  if (buffer2)
453  {
454  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
455  iov[1].iov_len = len2;
456  }
457 
458  _DBUS_ZERO(m);
459  m.msg_iov = iov;
460  m.msg_iovlen = buffer2 ? 2 : 1;
461 
462  if (n_fds > 0)
463  {
464  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
465  m.msg_control = alloca(m.msg_controllen);
466  memset(m.msg_control, 0, m.msg_controllen);
467 
468  cm = CMSG_FIRSTHDR(&m);
469  cm->cmsg_level = SOL_SOCKET;
470  cm->cmsg_type = SCM_RIGHTS;
471  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
472  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
473  }
474 
475  again:
476 
477  bytes_written = sendmsg (fd, &m, 0
478 #if HAVE_DECL_MSG_NOSIGNAL
479  |MSG_NOSIGNAL
480 #endif
481  );
482 
483  if (bytes_written < 0 && errno == EINTR)
484  goto again;
485 
486 #if 0
487  if (bytes_written > 0)
488  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
489 #endif
490 
491  return bytes_written;
492 #endif
493 }
494 
508 int
510  const DBusString *buffer1,
511  int start1,
512  int len1,
513  const DBusString *buffer2,
514  int start2,
515  int len2)
516 {
517 #if HAVE_DECL_MSG_NOSIGNAL
518  struct iovec vectors[2];
519  const char *data1;
520  const char *data2;
521  int bytes_written;
522  struct msghdr m;
523 
524  _dbus_assert (buffer1 != NULL);
525  _dbus_assert (start1 >= 0);
526  _dbus_assert (start2 >= 0);
527  _dbus_assert (len1 >= 0);
528  _dbus_assert (len2 >= 0);
529 
530  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
531 
532  if (buffer2 != NULL)
533  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
534  else
535  {
536  data2 = NULL;
537  start2 = 0;
538  len2 = 0;
539  }
540 
541  vectors[0].iov_base = (char*) data1;
542  vectors[0].iov_len = len1;
543  vectors[1].iov_base = (char*) data2;
544  vectors[1].iov_len = len2;
545 
546  _DBUS_ZERO(m);
547  m.msg_iov = vectors;
548  m.msg_iovlen = data2 ? 2 : 1;
549 
550  again:
551 
552  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
553 
554  if (bytes_written < 0 && errno == EINTR)
555  goto again;
556 
557  return bytes_written;
558 
559 #else
560  return _dbus_write_two (fd, buffer1, start1, len1,
561  buffer2, start2, len2);
562 #endif
563 }
564 
566 _dbus_socket_is_invalid (int fd)
567 {
568  return fd < 0 ? TRUE : FALSE;
569 }
570 
587 int
588 _dbus_read (int fd,
589  DBusString *buffer,
590  int count)
591 {
592  int bytes_read;
593  int start;
594  char *data;
595 
596  _dbus_assert (count >= 0);
597 
598  start = _dbus_string_get_length (buffer);
599 
600  if (!_dbus_string_lengthen (buffer, count))
601  {
602  errno = ENOMEM;
603  return -1;
604  }
605 
606  data = _dbus_string_get_data_len (buffer, start, count);
607 
608  again:
609 
610  bytes_read = read (fd, data, count);
611 
612  if (bytes_read < 0)
613  {
614  if (errno == EINTR)
615  goto again;
616  else
617  {
618  /* put length back (note that this doesn't actually realloc anything) */
619  _dbus_string_set_length (buffer, start);
620  return -1;
621  }
622  }
623  else
624  {
625  /* put length back (doesn't actually realloc) */
626  _dbus_string_set_length (buffer, start + bytes_read);
627 
628 #if 0
629  if (bytes_read > 0)
630  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
631 #endif
632 
633  return bytes_read;
634  }
635 }
636 
647 int
648 _dbus_write (int fd,
649  const DBusString *buffer,
650  int start,
651  int len)
652 {
653  const char *data;
654  int bytes_written;
655 
656  data = _dbus_string_get_const_data_len (buffer, start, len);
657 
658  again:
659 
660  bytes_written = write (fd, data, len);
661 
662  if (bytes_written < 0 && errno == EINTR)
663  goto again;
664 
665 #if 0
666  if (bytes_written > 0)
667  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
668 #endif
669 
670  return bytes_written;
671 }
672 
693 int
695  const DBusString *buffer1,
696  int start1,
697  int len1,
698  const DBusString *buffer2,
699  int start2,
700  int len2)
701 {
702  _dbus_assert (buffer1 != NULL);
703  _dbus_assert (start1 >= 0);
704  _dbus_assert (start2 >= 0);
705  _dbus_assert (len1 >= 0);
706  _dbus_assert (len2 >= 0);
707 
708 #ifdef HAVE_WRITEV
709  {
710  struct iovec vectors[2];
711  const char *data1;
712  const char *data2;
713  int bytes_written;
714 
715  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
716 
717  if (buffer2 != NULL)
718  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
719  else
720  {
721  data2 = NULL;
722  start2 = 0;
723  len2 = 0;
724  }
725 
726  vectors[0].iov_base = (char*) data1;
727  vectors[0].iov_len = len1;
728  vectors[1].iov_base = (char*) data2;
729  vectors[1].iov_len = len2;
730 
731  again:
732 
733  bytes_written = writev (fd,
734  vectors,
735  data2 ? 2 : 1);
736 
737  if (bytes_written < 0 && errno == EINTR)
738  goto again;
739 
740  return bytes_written;
741  }
742 #else /* HAVE_WRITEV */
743  {
744  int ret1, ret2;
745 
746  ret1 = _dbus_write (fd, buffer1, start1, len1);
747  if (ret1 == len1 && buffer2 != NULL)
748  {
749  ret2 = _dbus_write (fd, buffer2, start2, len2);
750  if (ret2 < 0)
751  ret2 = 0; /* we can't report an error as the first write was OK */
752 
753  return ret1 + ret2;
754  }
755  else
756  return ret1;
757  }
758 #endif /* !HAVE_WRITEV */
759 }
760 
761 #define _DBUS_MAX_SUN_PATH_LENGTH 99
762 
792 int
793 _dbus_connect_unix_socket (const char *path,
794  dbus_bool_t abstract,
795  DBusError *error)
796 {
797  int fd;
798  size_t path_len;
799  struct sockaddr_un addr;
800 
801  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
802 
803  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
804  path, abstract);
805 
806 
807  if (!_dbus_open_unix_socket (&fd, error))
808  {
809  _DBUS_ASSERT_ERROR_IS_SET(error);
810  return -1;
811  }
812  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
813 
814  _DBUS_ZERO (addr);
815  addr.sun_family = AF_UNIX;
816  path_len = strlen (path);
817 
818  if (abstract)
819  {
820 #ifdef HAVE_ABSTRACT_SOCKETS
821  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
822  path_len++; /* Account for the extra nul byte added to the start of sun_path */
823 
824  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
825  {
827  "Abstract socket name too long\n");
828  _dbus_close (fd, NULL);
829  return -1;
830  }
831 
832  strncpy (&addr.sun_path[1], path, path_len);
833  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
834 #else /* HAVE_ABSTRACT_SOCKETS */
836  "Operating system does not support abstract socket namespace\n");
837  _dbus_close (fd, NULL);
838  return -1;
839 #endif /* ! HAVE_ABSTRACT_SOCKETS */
840  }
841  else
842  {
843  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
844  {
846  "Socket name too long\n");
847  _dbus_close (fd, NULL);
848  return -1;
849  }
850 
851  strncpy (addr.sun_path, path, path_len);
852  }
853 
854  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
855  {
856  dbus_set_error (error,
857  _dbus_error_from_errno (errno),
858  "Failed to connect to socket %s: %s",
859  path, _dbus_strerror (errno));
860 
861  _dbus_close (fd, NULL);
862  return -1;
863  }
864 
865  if (!_dbus_set_fd_nonblocking (fd, error))
866  {
867  _DBUS_ASSERT_ERROR_IS_SET (error);
868 
869  _dbus_close (fd, NULL);
870  return -1;
871  }
872 
873  return fd;
874 }
875 
888 int
889 _dbus_connect_exec (const char *path,
890  char *const argv[],
891  DBusError *error)
892 {
893  int fds[2];
894  pid_t pid;
895  int retval;
896  dbus_bool_t cloexec_done = 0;
897 
898  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
899 
900  _dbus_verbose ("connecting to process %s\n", path);
901 
902 #ifdef SOCK_CLOEXEC
903  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
904  cloexec_done = (retval >= 0);
905 
906  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
907 #endif
908  {
909  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
910  }
911 
912  if (retval < 0)
913  {
914  dbus_set_error (error,
915  _dbus_error_from_errno (errno),
916  "Failed to create socket pair: %s",
917  _dbus_strerror (errno));
918  return -1;
919  }
920 
921  if (!cloexec_done)
922  {
925  }
926 
927  pid = fork ();
928  if (pid < 0)
929  {
930  dbus_set_error (error,
931  _dbus_error_from_errno (errno),
932  "Failed to fork() to call %s: %s",
933  path, _dbus_strerror (errno));
934  close (fds[0]);
935  close (fds[1]);
936  return -1;
937  }
938 
939  if (pid == 0)
940  {
941  /* child */
942  close (fds[0]);
943 
944  dup2 (fds[1], STDIN_FILENO);
945  dup2 (fds[1], STDOUT_FILENO);
946 
947  if (fds[1] != STDIN_FILENO &&
948  fds[1] != STDOUT_FILENO)
949  close (fds[1]);
950 
951  /* Inherit STDERR and the controlling terminal from the
952  parent */
953 
954  _dbus_close_all ();
955 
956  execvp (path, argv);
957 
958  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
959 
960  _exit(1);
961  }
962 
963  /* parent */
964  close (fds[1]);
965 
966  if (!_dbus_set_fd_nonblocking (fds[0], error))
967  {
968  _DBUS_ASSERT_ERROR_IS_SET (error);
969 
970  close (fds[0]);
971  return -1;
972  }
973 
974  return fds[0];
975 }
976 
994 int
995 _dbus_listen_unix_socket (const char *path,
996  dbus_bool_t abstract,
997  DBusError *error)
998 {
999  int listen_fd;
1000  struct sockaddr_un addr;
1001  size_t path_len;
1002 
1003  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1004 
1005  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1006  path, abstract);
1007 
1008  if (!_dbus_open_unix_socket (&listen_fd, error))
1009  {
1010  _DBUS_ASSERT_ERROR_IS_SET(error);
1011  return -1;
1012  }
1013  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1014 
1015  _DBUS_ZERO (addr);
1016  addr.sun_family = AF_UNIX;
1017  path_len = strlen (path);
1018 
1019  if (abstract)
1020  {
1021 #ifdef HAVE_ABSTRACT_SOCKETS
1022  /* remember that abstract names aren't nul-terminated so we rely
1023  * on sun_path being filled in with zeroes above.
1024  */
1025  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1026  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1027 
1028  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1029  {
1031  "Abstract socket name too long\n");
1032  _dbus_close (listen_fd, NULL);
1033  return -1;
1034  }
1035 
1036  strncpy (&addr.sun_path[1], path, path_len);
1037  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1038 #else /* HAVE_ABSTRACT_SOCKETS */
1040  "Operating system does not support abstract socket namespace\n");
1041  _dbus_close (listen_fd, NULL);
1042  return -1;
1043 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1044  }
1045  else
1046  {
1047  /* Discussed security implications of this with Nalin,
1048  * and we couldn't think of where it would kick our ass, but
1049  * it still seems a bit sucky. It also has non-security suckage;
1050  * really we'd prefer to exit if the socket is already in use.
1051  * But there doesn't seem to be a good way to do this.
1052  *
1053  * Just to be extra careful, I threw in the stat() - clearly
1054  * the stat() can't *fix* any security issue, but it at least
1055  * avoids inadvertent/accidental data loss.
1056  */
1057  {
1058  struct stat sb;
1059 
1060  if (stat (path, &sb) == 0 &&
1061  S_ISSOCK (sb.st_mode))
1062  unlink (path);
1063  }
1064 
1065  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1066  {
1068  "Abstract socket name too long\n");
1069  _dbus_close (listen_fd, NULL);
1070  return -1;
1071  }
1072 
1073  strncpy (addr.sun_path, path, path_len);
1074  }
1075 
1076  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1077  {
1078  dbus_set_error (error, _dbus_error_from_errno (errno),
1079  "Failed to bind socket \"%s\": %s",
1080  path, _dbus_strerror (errno));
1081  _dbus_close (listen_fd, NULL);
1082  return -1;
1083  }
1084 
1085  if (listen (listen_fd, 30 /* backlog */) < 0)
1086  {
1087  dbus_set_error (error, _dbus_error_from_errno (errno),
1088  "Failed to listen on socket \"%s\": %s",
1089  path, _dbus_strerror (errno));
1090  _dbus_close (listen_fd, NULL);
1091  return -1;
1092  }
1093 
1094  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1095  {
1096  _DBUS_ASSERT_ERROR_IS_SET (error);
1097  _dbus_close (listen_fd, NULL);
1098  return -1;
1099  }
1100 
1101  /* Try opening up the permissions, but if we can't, just go ahead
1102  * and continue, maybe it will be good enough.
1103  */
1104  if (!abstract && chmod (path, 0777) < 0)
1105  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1106  path);
1107 
1108  return listen_fd;
1109 }
1110 
1121 int
1123  DBusError *error)
1124 {
1125  int r, n;
1126  unsigned fd;
1127  int *new_fds;
1128 
1129  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1130 
1131  n = sd_listen_fds (TRUE);
1132  if (n < 0)
1133  {
1135  "Failed to acquire systemd socket: %s",
1136  _dbus_strerror (-n));
1137  return -1;
1138  }
1139 
1140  if (n <= 0)
1141  {
1143  "No socket received.");
1144  return -1;
1145  }
1146 
1147  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1148  {
1149  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1150  if (r < 0)
1151  {
1153  "Failed to verify systemd socket type: %s",
1154  _dbus_strerror (-r));
1155  return -1;
1156  }
1157 
1158  if (!r)
1159  {
1161  "Passed socket has wrong type.");
1162  return -1;
1163  }
1164  }
1165 
1166  /* OK, the file descriptors are all good, so let's take posession of
1167  them then. */
1168 
1169  new_fds = dbus_new (int, n);
1170  if (!new_fds)
1171  {
1173  "Failed to allocate file handle array.");
1174  goto fail;
1175  }
1176 
1177  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1178  {
1179  if (!_dbus_set_fd_nonblocking (fd, error))
1180  {
1181  _DBUS_ASSERT_ERROR_IS_SET (error);
1182  goto fail;
1183  }
1184 
1185  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1186  }
1187 
1188  *fds = new_fds;
1189  return n;
1190 
1191  fail:
1192 
1193  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1194  {
1195  _dbus_close (fd, NULL);
1196  }
1197 
1198  dbus_free (new_fds);
1199  return -1;
1200 }
1201 
1215 int
1216 _dbus_connect_tcp_socket (const char *host,
1217  const char *port,
1218  const char *family,
1219  DBusError *error)
1220 {
1221  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1222 }
1223 
1224 int
1225 _dbus_connect_tcp_socket_with_nonce (const char *host,
1226  const char *port,
1227  const char *family,
1228  const char *noncefile,
1229  DBusError *error)
1230 {
1231  int saved_errno = 0;
1232  int fd = -1, res;
1233  struct addrinfo hints;
1234  struct addrinfo *ai, *tmp;
1235 
1236  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1237 
1238  _DBUS_ZERO (hints);
1239 
1240  if (!family)
1241  hints.ai_family = AF_UNSPEC;
1242  else if (!strcmp(family, "ipv4"))
1243  hints.ai_family = AF_INET;
1244  else if (!strcmp(family, "ipv6"))
1245  hints.ai_family = AF_INET6;
1246  else
1247  {
1248  dbus_set_error (error,
1250  "Unknown address family %s", family);
1251  return -1;
1252  }
1253  hints.ai_protocol = IPPROTO_TCP;
1254  hints.ai_socktype = SOCK_STREAM;
1255  hints.ai_flags = AI_ADDRCONFIG;
1256 
1257  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1258  {
1259  dbus_set_error (error,
1260  _dbus_error_from_errno (errno),
1261  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1262  host, port, gai_strerror(res), res);
1263  return -1;
1264  }
1265 
1266  tmp = ai;
1267  while (tmp)
1268  {
1269  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1270  {
1271  freeaddrinfo(ai);
1272  _DBUS_ASSERT_ERROR_IS_SET(error);
1273  return -1;
1274  }
1275  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1276 
1277  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1278  {
1279  saved_errno = errno;
1280  _dbus_close(fd, NULL);
1281  fd = -1;
1282  tmp = tmp->ai_next;
1283  continue;
1284  }
1285 
1286  break;
1287  }
1288  freeaddrinfo(ai);
1289 
1290  if (fd == -1)
1291  {
1292  dbus_set_error (error,
1293  _dbus_error_from_errno (saved_errno),
1294  "Failed to connect to socket \"%s:%s\" %s",
1295  host, port, _dbus_strerror(saved_errno));
1296  return -1;
1297  }
1298 
1299  if (noncefile != NULL)
1300  {
1301  DBusString noncefileStr;
1302  dbus_bool_t ret;
1303  _dbus_string_init_const (&noncefileStr, noncefile);
1304  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1305  _dbus_string_free (&noncefileStr);
1306 
1307  if (!ret)
1308  {
1309  _dbus_close (fd, NULL);
1310  return -1;
1311  }
1312  }
1313 
1314  if (!_dbus_set_fd_nonblocking (fd, error))
1315  {
1316  _dbus_close (fd, NULL);
1317  return -1;
1318  }
1319 
1320  return fd;
1321 }
1322 
1339 int
1340 _dbus_listen_tcp_socket (const char *host,
1341  const char *port,
1342  const char *family,
1343  DBusString *retport,
1344  int **fds_p,
1345  DBusError *error)
1346 {
1347  int saved_errno;
1348  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1349  struct addrinfo hints;
1350  struct addrinfo *ai, *tmp;
1351  unsigned int reuseaddr;
1352 
1353  *fds_p = NULL;
1354  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1355 
1356  _DBUS_ZERO (hints);
1357 
1358  if (!family)
1359  hints.ai_family = AF_UNSPEC;
1360  else if (!strcmp(family, "ipv4"))
1361  hints.ai_family = AF_INET;
1362  else if (!strcmp(family, "ipv6"))
1363  hints.ai_family = AF_INET6;
1364  else
1365  {
1366  dbus_set_error (error,
1368  "Unknown address family %s", family);
1369  return -1;
1370  }
1371 
1372  hints.ai_protocol = IPPROTO_TCP;
1373  hints.ai_socktype = SOCK_STREAM;
1374  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1375 
1376  redo_lookup_with_port:
1377  ai = NULL;
1378  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1379  {
1380  dbus_set_error (error,
1381  _dbus_error_from_errno (errno),
1382  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1383  host ? host : "*", port, gai_strerror(res), res);
1384  goto failed;
1385  }
1386 
1387  tmp = ai;
1388  while (tmp)
1389  {
1390  int fd = -1, *newlisten_fd;
1391  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1392  {
1393  _DBUS_ASSERT_ERROR_IS_SET(error);
1394  goto failed;
1395  }
1396  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1397 
1398  reuseaddr = 1;
1399  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1400  {
1401  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1402  host ? host : "*", port, _dbus_strerror (errno));
1403  }
1404 
1405  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1406  {
1407  saved_errno = errno;
1408  _dbus_close(fd, NULL);
1409  if (saved_errno == EADDRINUSE)
1410  {
1411  /* Depending on kernel policy, it may or may not
1412  be neccessary to bind to both IPv4 & 6 addresses
1413  so ignore EADDRINUSE here */
1414  tmp = tmp->ai_next;
1415  continue;
1416  }
1417  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1418  "Failed to bind socket \"%s:%s\": %s",
1419  host ? host : "*", port, _dbus_strerror (saved_errno));
1420  goto failed;
1421  }
1422 
1423  if (listen (fd, 30 /* backlog */) < 0)
1424  {
1425  saved_errno = errno;
1426  _dbus_close (fd, NULL);
1427  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1428  "Failed to listen on socket \"%s:%s\": %s",
1429  host ? host : "*", port, _dbus_strerror (saved_errno));
1430  goto failed;
1431  }
1432 
1433  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1434  if (!newlisten_fd)
1435  {
1436  saved_errno = errno;
1437  _dbus_close (fd, NULL);
1438  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1439  "Failed to allocate file handle array: %s",
1440  _dbus_strerror (saved_errno));
1441  goto failed;
1442  }
1443  listen_fd = newlisten_fd;
1444  listen_fd[nlisten_fd] = fd;
1445  nlisten_fd++;
1446 
1447  if (!_dbus_string_get_length(retport))
1448  {
1449  /* If the user didn't specify a port, or used 0, then
1450  the kernel chooses a port. After the first address
1451  is bound to, we need to force all remaining addresses
1452  to use the same port */
1453  if (!port || !strcmp(port, "0"))
1454  {
1455  int result;
1456  struct sockaddr_storage addr;
1457  socklen_t addrlen;
1458  char portbuf[50];
1459 
1460  addrlen = sizeof(addr);
1461  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1462 
1463  if (result == -1 ||
1464  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1465  portbuf, sizeof(portbuf),
1466  NI_NUMERICHOST)) != 0)
1467  {
1468  dbus_set_error (error, _dbus_error_from_errno (errno),
1469  "Failed to resolve port \"%s:%s\": %s (%s)",
1470  host ? host : "*", port, gai_strerror(res), res);
1471  goto failed;
1472  }
1473  if (!_dbus_string_append(retport, portbuf))
1474  {
1476  goto failed;
1477  }
1478 
1479  /* Release current address list & redo lookup */
1480  port = _dbus_string_get_const_data(retport);
1481  freeaddrinfo(ai);
1482  goto redo_lookup_with_port;
1483  }
1484  else
1485  {
1486  if (!_dbus_string_append(retport, port))
1487  {
1489  goto failed;
1490  }
1491  }
1492  }
1493 
1494  tmp = tmp->ai_next;
1495  }
1496  freeaddrinfo(ai);
1497  ai = NULL;
1498 
1499  if (!nlisten_fd)
1500  {
1501  errno = EADDRINUSE;
1502  dbus_set_error (error, _dbus_error_from_errno (errno),
1503  "Failed to bind socket \"%s:%s\": %s",
1504  host ? host : "*", port, _dbus_strerror (errno));
1505  goto failed;
1506  }
1507 
1508  for (i = 0 ; i < nlisten_fd ; i++)
1509  {
1510  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1511  {
1512  goto failed;
1513  }
1514  }
1515 
1516  *fds_p = listen_fd;
1517 
1518  return nlisten_fd;
1519 
1520  failed:
1521  if (ai)
1522  freeaddrinfo(ai);
1523  for (i = 0 ; i < nlisten_fd ; i++)
1524  _dbus_close(listen_fd[i], NULL);
1525  dbus_free(listen_fd);
1526  return -1;
1527 }
1528 
1529 static dbus_bool_t
1530 write_credentials_byte (int server_fd,
1531  DBusError *error)
1532 {
1533  int bytes_written;
1534  char buf[1] = { '\0' };
1535 #if defined(HAVE_CMSGCRED)
1536  union {
1537  struct cmsghdr hdr;
1538  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1539  } cmsg;
1540  struct iovec iov;
1541  struct msghdr msg;
1542  iov.iov_base = buf;
1543  iov.iov_len = 1;
1544 
1545  _DBUS_ZERO(msg);
1546  msg.msg_iov = &iov;
1547  msg.msg_iovlen = 1;
1548 
1549  msg.msg_control = (caddr_t) &cmsg;
1550  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1551  _DBUS_ZERO(cmsg);
1552  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1553  cmsg.hdr.cmsg_level = SOL_SOCKET;
1554  cmsg.hdr.cmsg_type = SCM_CREDS;
1555 #endif
1556 
1557  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1558 
1559  again:
1560 
1561 #if defined(HAVE_CMSGCRED)
1562  bytes_written = sendmsg (server_fd, &msg, 0
1563 #if HAVE_DECL_MSG_NOSIGNAL
1564  |MSG_NOSIGNAL
1565 #endif
1566  );
1567 
1568  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1569  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1570  * only allows that on AF_UNIX. Try just doing a send() instead. */
1571  if (bytes_written < 0 && errno == EINVAL)
1572 #endif
1573  {
1574  bytes_written = send (server_fd, buf, 1, 0
1575 #if HAVE_DECL_MSG_NOSIGNAL
1576  |MSG_NOSIGNAL
1577 #endif
1578  );
1579  }
1580 
1581  if (bytes_written < 0 && errno == EINTR)
1582  goto again;
1583 
1584  if (bytes_written < 0)
1585  {
1586  dbus_set_error (error, _dbus_error_from_errno (errno),
1587  "Failed to write credentials byte: %s",
1588  _dbus_strerror (errno));
1589  return FALSE;
1590  }
1591  else if (bytes_written == 0)
1592  {
1594  "wrote zero bytes writing credentials byte");
1595  return FALSE;
1596  }
1597  else
1598  {
1599  _dbus_assert (bytes_written == 1);
1600  _dbus_verbose ("wrote credentials byte\n");
1601  return TRUE;
1602  }
1603 }
1604 
1628  DBusCredentials *credentials,
1629  DBusError *error)
1630 {
1631  struct msghdr msg;
1632  struct iovec iov;
1633  char buf;
1634  dbus_uid_t uid_read;
1635  dbus_pid_t pid_read;
1636  int bytes_read;
1637 
1638 #ifdef HAVE_CMSGCRED
1639  union {
1640  struct cmsghdr hdr;
1641  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1642  } cmsg;
1643 #endif
1644 
1645  uid_read = DBUS_UID_UNSET;
1646  pid_read = DBUS_PID_UNSET;
1647 
1648  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1649 
1650  /* The POSIX spec certainly doesn't promise this, but
1651  * we need these assertions to fail as soon as we're wrong about
1652  * it so we can do the porting fixups
1653  */
1654  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1655  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1656  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1657 
1658  _dbus_credentials_clear (credentials);
1659 
1660  iov.iov_base = &buf;
1661  iov.iov_len = 1;
1662 
1663  _DBUS_ZERO(msg);
1664  msg.msg_iov = &iov;
1665  msg.msg_iovlen = 1;
1666 
1667 #if defined(HAVE_CMSGCRED)
1668  _DBUS_ZERO(cmsg);
1669  msg.msg_control = (caddr_t) &cmsg;
1670  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1671 #endif
1672 
1673  again:
1674  bytes_read = recvmsg (client_fd, &msg, 0);
1675 
1676  if (bytes_read < 0)
1677  {
1678  if (errno == EINTR)
1679  goto again;
1680 
1681  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1682  * normally only call read_credentials if the socket was ready
1683  * for reading
1684  */
1685 
1686  dbus_set_error (error, _dbus_error_from_errno (errno),
1687  "Failed to read credentials byte: %s",
1688  _dbus_strerror (errno));
1689  return FALSE;
1690  }
1691  else if (bytes_read == 0)
1692  {
1693  /* this should not happen unless we are using recvmsg wrong,
1694  * so is essentially here for paranoia
1695  */
1697  "Failed to read credentials byte (zero-length read)");
1698  return FALSE;
1699  }
1700  else if (buf != '\0')
1701  {
1703  "Credentials byte was not nul");
1704  return FALSE;
1705  }
1706 
1707  _dbus_verbose ("read credentials byte\n");
1708 
1709  {
1710 #ifdef SO_PEERCRED
1711  /* Supported by at least Linux and OpenBSD, with minor differences.
1712  *
1713  * This mechanism passes the process ID through and does not require
1714  * the peer's cooperation, so we prefer it over all others. Notably,
1715  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1716  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1717  * because this is much less fragile.
1718  */
1719 #ifdef __OpenBSD__
1720  struct sockpeercred cr;
1721 #else
1722  struct ucred cr;
1723 #endif
1724  int cr_len = sizeof (cr);
1725 
1726  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1727  cr_len == sizeof (cr))
1728  {
1729  pid_read = cr.pid;
1730  uid_read = cr.uid;
1731  }
1732  else
1733  {
1734  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1735  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1736  }
1737 #elif defined(HAVE_CMSGCRED)
1738  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1739  * presence of that struct implies SCM_CREDS. Supported by at least
1740  * FreeBSD and DragonflyBSD.
1741  *
1742  * This mechanism requires the peer to help us (it has to send us a
1743  * SCM_CREDS message) but it does pass the process ID through,
1744  * which makes it better than getpeereid().
1745  */
1746  struct cmsgcred *cred;
1747  struct cmsghdr *cmsgp;
1748 
1749  for (cmsgp = CMSG_FIRSTHDR (&msg);
1750  cmsgp != NULL;
1751  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
1752  {
1753  if (cmsgp->cmsg_type == SCM_CREDS &&
1754  cmsgp->cmsg_level == SOL_SOCKET &&
1755  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
1756  {
1757  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
1758  pid_read = cred->cmcred_pid;
1759  uid_read = cred->cmcred_euid;
1760  break;
1761  }
1762  }
1763 
1764 #elif defined(HAVE_GETPEERUCRED)
1765  /* Supported in at least Solaris >= 10. It should probably be higher
1766  * up this list, because it carries the pid and we use this code path
1767  * for audit data. */
1768  ucred_t * ucred = NULL;
1769  if (getpeerucred (client_fd, &ucred) == 0)
1770  {
1771  pid_read = ucred_getpid (ucred);
1772  uid_read = ucred_geteuid (ucred);
1773 #ifdef HAVE_ADT
1774  /* generate audit session data based on socket ucred */
1775  adt_session_data_t *adth = NULL;
1776  adt_export_data_t *data = NULL;
1777  size_t size = 0;
1778  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1779  {
1780  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1781  }
1782  else
1783  {
1784  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1785  {
1786  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1787  }
1788  else
1789  {
1790  size = adt_export_session_data (adth, &data);
1791  if (size <= 0)
1792  {
1793  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1794  }
1795  else
1796  {
1797  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1798  free (data);
1799  }
1800  }
1801  (void) adt_end_session (adth);
1802  }
1803 #endif /* HAVE_ADT */
1804  }
1805  else
1806  {
1807  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1808  }
1809  if (ucred != NULL)
1810  ucred_free (ucred);
1811 
1812  /* ----------------------------------------------------------------
1813  * When adding new mechanisms, please add them above this point
1814  * if they support passing the process ID through, or below if not.
1815  * ---------------------------------------------------------------- */
1816 
1817 #elif defined(HAVE_GETPEEREID)
1818  /* getpeereid() originates from D.J. Bernstein and is fairly
1819  * widely-supported. According to a web search, it might be present in
1820  * any/all of:
1821  *
1822  * - AIX?
1823  * - Blackberry?
1824  * - Cygwin
1825  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
1826  * - Mac OS X
1827  * - Minix 3.1.8+
1828  * - MirBSD?
1829  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
1830  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
1831  * - QNX?
1832  */
1833  uid_t euid;
1834  gid_t egid;
1835  if (getpeereid (client_fd, &euid, &egid) == 0)
1836  {
1837  uid_read = euid;
1838  }
1839  else
1840  {
1841  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1842  }
1843 #else /* no supported mechanism */
1844 
1845 #warning Socket credentials not supported on this Unix OS
1846 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
1847 
1848  /* Please add other operating systems known to support at least one of
1849  * the mechanisms above to this list, keeping alphabetical order.
1850  * Everything not in this list is best-effort.
1851  */
1852 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
1853  defined(__linux__) || \
1854  defined(__OpenBSD__) || \
1855  defined(__NetBSD__)
1856 # error Credentials passing not working on this OS is a regression!
1857 #endif
1858 
1859  _dbus_verbose ("Socket credentials not supported on this OS\n");
1860 #endif
1861  }
1862 
1863  _dbus_verbose ("Credentials:"
1864  " pid "DBUS_PID_FORMAT
1865  " uid "DBUS_UID_FORMAT
1866  "\n",
1867  pid_read,
1868  uid_read);
1869 
1870  if (pid_read != DBUS_PID_UNSET)
1871  {
1872  if (!_dbus_credentials_add_pid (credentials, pid_read))
1873  {
1874  _DBUS_SET_OOM (error);
1875  return FALSE;
1876  }
1877  }
1878 
1879  if (uid_read != DBUS_UID_UNSET)
1880  {
1881  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1882  {
1883  _DBUS_SET_OOM (error);
1884  return FALSE;
1885  }
1886  }
1887 
1888  return TRUE;
1889 }
1890 
1910  DBusError *error)
1911 {
1912  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1913 
1914  if (write_credentials_byte (server_fd, error))
1915  return TRUE;
1916  else
1917  return FALSE;
1918 }
1919 
1929 int
1930 _dbus_accept (int listen_fd)
1931 {
1932  int client_fd;
1933  struct sockaddr addr;
1934  socklen_t addrlen;
1935 #ifdef HAVE_ACCEPT4
1936  dbus_bool_t cloexec_done;
1937 #endif
1938 
1939  addrlen = sizeof (addr);
1940 
1941  retry:
1942 
1943 #ifdef HAVE_ACCEPT4
1944  /*
1945  * At compile-time, we assume that if accept4() is available in
1946  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
1947  * not necessarily true that either is supported by the running kernel.
1948  */
1949  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1950  cloexec_done = client_fd >= 0;
1951 
1952  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
1953 #endif
1954  {
1955  client_fd = accept (listen_fd, &addr, &addrlen);
1956  }
1957 
1958  if (client_fd < 0)
1959  {
1960  if (errno == EINTR)
1961  goto retry;
1962  }
1963 
1964  _dbus_verbose ("client fd %d accepted\n", client_fd);
1965 
1966 #ifdef HAVE_ACCEPT4
1967  if (!cloexec_done)
1968 #endif
1969  {
1970  _dbus_fd_set_close_on_exec(client_fd);
1971  }
1972 
1973  return client_fd;
1974 }
1975 
1986 {
1987  const char *directory;
1988  struct stat sb;
1989 
1990  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1991 
1992  directory = _dbus_string_get_const_data (dir);
1993 
1994  if (stat (directory, &sb) < 0)
1995  {
1996  dbus_set_error (error, _dbus_error_from_errno (errno),
1997  "%s", _dbus_strerror (errno));
1998 
1999  return FALSE;
2000  }
2001 
2002  if (sb.st_uid != geteuid ())
2003  {
2005  "%s directory is owned by user %lu, not %lu",
2006  directory,
2007  (unsigned long) sb.st_uid,
2008  (unsigned long) geteuid ());
2009  return FALSE;
2010  }
2011 
2012  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2013  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2014  {
2016  "%s directory is not private to the user", directory);
2017  return FALSE;
2018  }
2019 
2020  return TRUE;
2021 }
2022 
2023 static dbus_bool_t
2024 fill_user_info_from_passwd (struct passwd *p,
2025  DBusUserInfo *info,
2026  DBusError *error)
2027 {
2028  _dbus_assert (p->pw_name != NULL);
2029  _dbus_assert (p->pw_dir != NULL);
2030 
2031  info->uid = p->pw_uid;
2032  info->primary_gid = p->pw_gid;
2033  info->username = _dbus_strdup (p->pw_name);
2034  info->homedir = _dbus_strdup (p->pw_dir);
2035 
2036  if (info->username == NULL ||
2037  info->homedir == NULL)
2038  {
2040  return FALSE;
2041  }
2042 
2043  return TRUE;
2044 }
2045 
2046 static dbus_bool_t
2047 fill_user_info (DBusUserInfo *info,
2048  dbus_uid_t uid,
2049  const DBusString *username,
2050  DBusError *error)
2051 {
2052  const char *username_c;
2053 
2054  /* exactly one of username/uid provided */
2055  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2056  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2057 
2058  info->uid = DBUS_UID_UNSET;
2059  info->primary_gid = DBUS_GID_UNSET;
2060  info->group_ids = NULL;
2061  info->n_group_ids = 0;
2062  info->username = NULL;
2063  info->homedir = NULL;
2064 
2065  if (username != NULL)
2066  username_c = _dbus_string_get_const_data (username);
2067  else
2068  username_c = NULL;
2069 
2070  /* For now assuming that the getpwnam() and getpwuid() flavors
2071  * are always symmetrical, if not we have to add more configure
2072  * checks
2073  */
2074 
2075 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2076  {
2077  struct passwd *p;
2078  int result;
2079  size_t buflen;
2080  char *buf;
2081  struct passwd p_str;
2082 
2083  /* retrieve maximum needed size for buf */
2084  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2085 
2086  /* sysconf actually returns a long, but everything else expects size_t,
2087  * so just recast here.
2088  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2089  */
2090  if ((long) buflen <= 0)
2091  buflen = 1024;
2092 
2093  result = -1;
2094  while (1)
2095  {
2096  buf = dbus_malloc (buflen);
2097  if (buf == NULL)
2098  {
2100  return FALSE;
2101  }
2102 
2103  p = NULL;
2104 #ifdef HAVE_POSIX_GETPWNAM_R
2105  if (uid != DBUS_UID_UNSET)
2106  result = getpwuid_r (uid, &p_str, buf, buflen,
2107  &p);
2108  else
2109  result = getpwnam_r (username_c, &p_str, buf, buflen,
2110  &p);
2111 #else
2112  if (uid != DBUS_UID_UNSET)
2113  p = getpwuid_r (uid, &p_str, buf, buflen);
2114  else
2115  p = getpwnam_r (username_c, &p_str, buf, buflen);
2116  result = 0;
2117 #endif /* !HAVE_POSIX_GETPWNAM_R */
2118  //Try a bigger buffer if ERANGE was returned
2119  if (result == ERANGE && buflen < 512 * 1024)
2120  {
2121  dbus_free (buf);
2122  buflen *= 2;
2123  }
2124  else
2125  {
2126  break;
2127  }
2128  }
2129  if (result == 0 && p == &p_str)
2130  {
2131  if (!fill_user_info_from_passwd (p, info, error))
2132  {
2133  dbus_free (buf);
2134  return FALSE;
2135  }
2136  dbus_free (buf);
2137  }
2138  else
2139  {
2140  dbus_set_error (error, _dbus_error_from_errno (errno),
2141  "User \"%s\" unknown or no memory to allocate password entry\n",
2142  username_c ? username_c : "???");
2143  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2144  dbus_free (buf);
2145  return FALSE;
2146  }
2147  }
2148 #else /* ! HAVE_GETPWNAM_R */
2149  {
2150  /* I guess we're screwed on thread safety here */
2151  struct passwd *p;
2152 
2153  if (uid != DBUS_UID_UNSET)
2154  p = getpwuid (uid);
2155  else
2156  p = getpwnam (username_c);
2157 
2158  if (p != NULL)
2159  {
2160  if (!fill_user_info_from_passwd (p, info, error))
2161  {
2162  return FALSE;
2163  }
2164  }
2165  else
2166  {
2167  dbus_set_error (error, _dbus_error_from_errno (errno),
2168  "User \"%s\" unknown or no memory to allocate password entry\n",
2169  username_c ? username_c : "???");
2170  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2171  return FALSE;
2172  }
2173  }
2174 #endif /* ! HAVE_GETPWNAM_R */
2175 
2176  /* Fill this in so we can use it to get groups */
2177  username_c = info->username;
2178 
2179 #ifdef HAVE_GETGROUPLIST
2180  {
2181  gid_t *buf;
2182  int buf_count;
2183  int i;
2184  int initial_buf_count;
2185 
2186  initial_buf_count = 17;
2187  buf_count = initial_buf_count;
2188  buf = dbus_new (gid_t, buf_count);
2189  if (buf == NULL)
2190  {
2192  goto failed;
2193  }
2194 
2195  if (getgrouplist (username_c,
2196  info->primary_gid,
2197  buf, &buf_count) < 0)
2198  {
2199  gid_t *new;
2200  /* Presumed cause of negative return code: buf has insufficient
2201  entries to hold the entire group list. The Linux behavior in this
2202  case is to pass back the actual number of groups in buf_count, but
2203  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2204  So as a hack, try to help out a bit by guessing a larger
2205  number of groups, within reason.. might still fail, of course,
2206  but we can at least print a more informative message. I looked up
2207  the "right way" to do this by downloading Apple's own source code
2208  for the "id" command, and it turns out that they use an
2209  undocumented library function getgrouplist_2 (!) which is not
2210  declared in any header in /usr/include (!!). That did not seem
2211  like the way to go here.
2212  */
2213  if (buf_count == initial_buf_count)
2214  {
2215  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2216  }
2217  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2218  if (new == NULL)
2219  {
2221  dbus_free (buf);
2222  goto failed;
2223  }
2224 
2225  buf = new;
2226 
2227  errno = 0;
2228  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2229  {
2230  if (errno == 0)
2231  {
2232  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2233  username_c, buf_count, buf_count);
2234  }
2235  else
2236  {
2237  dbus_set_error (error,
2238  _dbus_error_from_errno (errno),
2239  "Failed to get groups for username \"%s\" primary GID "
2240  DBUS_GID_FORMAT ": %s\n",
2241  username_c, info->primary_gid,
2242  _dbus_strerror (errno));
2243  dbus_free (buf);
2244  goto failed;
2245  }
2246  }
2247  }
2248 
2249  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2250  if (info->group_ids == NULL)
2251  {
2253  dbus_free (buf);
2254  goto failed;
2255  }
2256 
2257  for (i = 0; i < buf_count; ++i)
2258  info->group_ids[i] = buf[i];
2259 
2260  info->n_group_ids = buf_count;
2261 
2262  dbus_free (buf);
2263  }
2264 #else /* HAVE_GETGROUPLIST */
2265  {
2266  /* We just get the one group ID */
2267  info->group_ids = dbus_new (dbus_gid_t, 1);
2268  if (info->group_ids == NULL)
2269  {
2271  goto failed;
2272  }
2273 
2274  info->n_group_ids = 1;
2275 
2276  (info->group_ids)[0] = info->primary_gid;
2277  }
2278 #endif /* HAVE_GETGROUPLIST */
2279 
2280  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2281 
2282  return TRUE;
2283 
2284  failed:
2285  _DBUS_ASSERT_ERROR_IS_SET (error);
2286  return FALSE;
2287 }
2288 
2299  const DBusString *username,
2300  DBusError *error)
2301 {
2302  return fill_user_info (info, DBUS_UID_UNSET,
2303  username, error);
2304 }
2305 
2316  dbus_uid_t uid,
2317  DBusError *error)
2318 {
2319  return fill_user_info (info, uid,
2320  NULL, error);
2321 }
2322 
2332 {
2333  /* The POSIX spec certainly doesn't promise this, but
2334  * we need these assertions to fail as soon as we're wrong about
2335  * it so we can do the porting fixups
2336  */
2337  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2338  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2339  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2340 
2341  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2342  return FALSE;
2343  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2344  return FALSE;
2345 
2346  return TRUE;
2347 }
2348 
2362 {
2363  return _dbus_string_append_uint (str,
2364  _dbus_geteuid ());
2365 }
2366 
2371 dbus_pid_t
2373 {
2374  return getpid ();
2375 }
2376 
2380 dbus_uid_t
2382 {
2383  return getuid ();
2384 }
2385 
2389 dbus_uid_t
2391 {
2392  return geteuid ();
2393 }
2394 
2401 unsigned long
2403 {
2404  return getpid ();
2405 }
2406 
2415 _dbus_parse_uid (const DBusString *uid_str,
2416  dbus_uid_t *uid)
2417 {
2418  int end;
2419  long val;
2420 
2421  if (_dbus_string_get_length (uid_str) == 0)
2422  {
2423  _dbus_verbose ("UID string was zero length\n");
2424  return FALSE;
2425  }
2426 
2427  val = -1;
2428  end = 0;
2429  if (!_dbus_string_parse_int (uid_str, 0, &val,
2430  &end))
2431  {
2432  _dbus_verbose ("could not parse string as a UID\n");
2433  return FALSE;
2434  }
2435 
2436  if (end != _dbus_string_get_length (uid_str))
2437  {
2438  _dbus_verbose ("string contained trailing stuff after UID\n");
2439  return FALSE;
2440  }
2441 
2442  *uid = val;
2443 
2444  return TRUE;
2445 }
2446 
2447 #if !DBUS_USE_SYNC
2448 /* To be thread-safe by default on platforms that don't necessarily have
2449  * atomic operations (notably Debian armel, which is armv4t), we must
2450  * use a mutex that can be initialized statically, like this.
2451  * GLib >= 2.32 uses a similar system.
2452  */
2453 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2454 #endif
2455 
2464 {
2465 #if DBUS_USE_SYNC
2466  return __sync_add_and_fetch(&atomic->value, 1)-1;
2467 #else
2468  dbus_int32_t res;
2469 
2470  pthread_mutex_lock (&atomic_mutex);
2471  res = atomic->value;
2472  atomic->value += 1;
2473  pthread_mutex_unlock (&atomic_mutex);
2474 
2475  return res;
2476 #endif
2477 }
2478 
2487 {
2488 #if DBUS_USE_SYNC
2489  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2490 #else
2491  dbus_int32_t res;
2492 
2493  pthread_mutex_lock (&atomic_mutex);
2494  res = atomic->value;
2495  atomic->value -= 1;
2496  pthread_mutex_unlock (&atomic_mutex);
2497 
2498  return res;
2499 #endif
2500 }
2501 
2511 {
2512 #if DBUS_USE_SYNC
2513  __sync_synchronize ();
2514  return atomic->value;
2515 #else
2516  dbus_int32_t res;
2517 
2518  pthread_mutex_lock (&atomic_mutex);
2519  res = atomic->value;
2520  pthread_mutex_unlock (&atomic_mutex);
2521 
2522  return res;
2523 #endif
2524 }
2525 
2534 int
2536  int n_fds,
2537  int timeout_milliseconds)
2538 {
2539 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2540  /* This big thing is a constant expression and should get optimized
2541  * out of existence. So it's more robust than a configure check at
2542  * no cost.
2543  */
2544  if (_DBUS_POLLIN == POLLIN &&
2545  _DBUS_POLLPRI == POLLPRI &&
2546  _DBUS_POLLOUT == POLLOUT &&
2547  _DBUS_POLLERR == POLLERR &&
2548  _DBUS_POLLHUP == POLLHUP &&
2549  _DBUS_POLLNVAL == POLLNVAL &&
2550  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2551  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2552  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2553  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2554  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2555  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2556  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2557  {
2558  return poll ((struct pollfd*) fds,
2559  n_fds,
2560  timeout_milliseconds);
2561  }
2562  else
2563  {
2564  /* We have to convert the DBusPollFD to an array of
2565  * struct pollfd, poll, and convert back.
2566  */
2567  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2568  return -1;
2569  }
2570 #else /* ! HAVE_POLL */
2571 
2572  fd_set read_set, write_set, err_set;
2573  int max_fd = 0;
2574  int i;
2575  struct timeval tv;
2576  int ready;
2577 
2578  FD_ZERO (&read_set);
2579  FD_ZERO (&write_set);
2580  FD_ZERO (&err_set);
2581 
2582  for (i = 0; i < n_fds; i++)
2583  {
2584  DBusPollFD *fdp = &fds[i];
2585 
2586  if (fdp->events & _DBUS_POLLIN)
2587  FD_SET (fdp->fd, &read_set);
2588 
2589  if (fdp->events & _DBUS_POLLOUT)
2590  FD_SET (fdp->fd, &write_set);
2591 
2592  FD_SET (fdp->fd, &err_set);
2593 
2594  max_fd = MAX (max_fd, fdp->fd);
2595  }
2596 
2597  tv.tv_sec = timeout_milliseconds / 1000;
2598  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2599 
2600  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2601  timeout_milliseconds < 0 ? NULL : &tv);
2602 
2603  if (ready > 0)
2604  {
2605  for (i = 0; i < n_fds; i++)
2606  {
2607  DBusPollFD *fdp = &fds[i];
2608 
2609  fdp->revents = 0;
2610 
2611  if (FD_ISSET (fdp->fd, &read_set))
2612  fdp->revents |= _DBUS_POLLIN;
2613 
2614  if (FD_ISSET (fdp->fd, &write_set))
2615  fdp->revents |= _DBUS_POLLOUT;
2616 
2617  if (FD_ISSET (fdp->fd, &err_set))
2618  fdp->revents |= _DBUS_POLLERR;
2619  }
2620  }
2621 
2622  return ready;
2623 #endif
2624 }
2625 
2633 void
2635  long *tv_usec)
2636 {
2637 #ifdef HAVE_MONOTONIC_CLOCK
2638  struct timespec ts;
2639  clock_gettime (CLOCK_MONOTONIC, &ts);
2640 
2641  if (tv_sec)
2642  *tv_sec = ts.tv_sec;
2643  if (tv_usec)
2644  *tv_usec = ts.tv_nsec / 1000;
2645 #else
2646  struct timeval t;
2647 
2648  gettimeofday (&t, NULL);
2649 
2650  if (tv_sec)
2651  *tv_sec = t.tv_sec;
2652  if (tv_usec)
2653  *tv_usec = t.tv_usec;
2654 #endif
2655 }
2656 
2664 void
2665 _dbus_get_real_time (long *tv_sec,
2666  long *tv_usec)
2667 {
2668  struct timeval t;
2669 
2670  gettimeofday (&t, NULL);
2671 
2672  if (tv_sec)
2673  *tv_sec = t.tv_sec;
2674  if (tv_usec)
2675  *tv_usec = t.tv_usec;
2676 }
2677 
2688  DBusError *error)
2689 {
2690  const char *filename_c;
2691 
2692  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2693 
2694  filename_c = _dbus_string_get_const_data (filename);
2695 
2696  if (mkdir (filename_c, 0700) < 0)
2697  {
2698  if (errno == EEXIST)
2699  return TRUE;
2700 
2702  "Failed to create directory %s: %s\n",
2703  filename_c, _dbus_strerror (errno));
2704  return FALSE;
2705  }
2706  else
2707  return TRUE;
2708 }
2709 
2722  const DBusString *next_component)
2723 {
2724  dbus_bool_t dir_ends_in_slash;
2725  dbus_bool_t file_starts_with_slash;
2726 
2727  if (_dbus_string_get_length (dir) == 0 ||
2728  _dbus_string_get_length (next_component) == 0)
2729  return TRUE;
2730 
2731  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2732  _dbus_string_get_length (dir) - 1);
2733 
2734  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2735 
2736  if (dir_ends_in_slash && file_starts_with_slash)
2737  {
2738  _dbus_string_shorten (dir, 1);
2739  }
2740  else if (!(dir_ends_in_slash || file_starts_with_slash))
2741  {
2742  if (!_dbus_string_append_byte (dir, '/'))
2743  return FALSE;
2744  }
2745 
2746  return _dbus_string_copy (next_component, 0, dir,
2747  _dbus_string_get_length (dir));
2748 }
2749 
2751 #define NANOSECONDS_PER_SECOND 1000000000
2752 
2753 #define MICROSECONDS_PER_SECOND 1000000
2754 
2755 #define MILLISECONDS_PER_SECOND 1000
2756 
2757 #define NANOSECONDS_PER_MILLISECOND 1000000
2758 
2759 #define MICROSECONDS_PER_MILLISECOND 1000
2760 
2765 void
2766 _dbus_sleep_milliseconds (int milliseconds)
2767 {
2768 #ifdef HAVE_NANOSLEEP
2769  struct timespec req;
2770  struct timespec rem;
2771 
2772  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2773  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2774  rem.tv_sec = 0;
2775  rem.tv_nsec = 0;
2776 
2777  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2778  req = rem;
2779 #elif defined (HAVE_USLEEP)
2780  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2781 #else /* ! HAVE_USLEEP */
2782  sleep (MAX (milliseconds / 1000, 1));
2783 #endif
2784 }
2785 
2786 static dbus_bool_t
2787 _dbus_generate_pseudorandom_bytes (DBusString *str,
2788  int n_bytes)
2789 {
2790  int old_len;
2791  char *p;
2792 
2793  old_len = _dbus_string_get_length (str);
2794 
2795  if (!_dbus_string_lengthen (str, n_bytes))
2796  return FALSE;
2797 
2798  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2799 
2801 
2802  return TRUE;
2803 }
2804 
2815  int n_bytes)
2816 {
2817  int old_len;
2818  int fd;
2819 
2820  /* FALSE return means "no memory", if it could
2821  * mean something else then we'd need to return
2822  * a DBusError. So we always fall back to pseudorandom
2823  * if the I/O fails.
2824  */
2825 
2826  old_len = _dbus_string_get_length (str);
2827  fd = -1;
2828 
2829  /* note, urandom on linux will fall back to pseudorandom */
2830  fd = open ("/dev/urandom", O_RDONLY);
2831  if (fd < 0)
2832  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2833 
2834  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2835 
2836  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2837  {
2838  _dbus_close (fd, NULL);
2839  _dbus_string_set_length (str, old_len);
2840  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2841  }
2842 
2843  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2844  n_bytes);
2845 
2846  _dbus_close (fd, NULL);
2847 
2848  return TRUE;
2849 }
2850 
2856 void
2857 _dbus_exit (int code)
2858 {
2859  _exit (code);
2860 }
2861 
2870 const char*
2871 _dbus_strerror (int error_number)
2872 {
2873  const char *msg;
2874 
2875  msg = strerror (error_number);
2876  if (msg == NULL)
2877  msg = "unknown";
2878 
2879  return msg;
2880 }
2881 
2885 void
2887 {
2888  signal (SIGPIPE, SIG_IGN);
2889 }
2890 
2898 void
2900 {
2901  int val;
2902 
2903  val = fcntl (fd, F_GETFD, 0);
2904 
2905  if (val < 0)
2906  return;
2907 
2908  val |= FD_CLOEXEC;
2909 
2910  fcntl (fd, F_SETFD, val);
2911 }
2912 
2921 _dbus_close (int fd,
2922  DBusError *error)
2923 {
2924  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2925 
2926  again:
2927  if (close (fd) < 0)
2928  {
2929  if (errno == EINTR)
2930  goto again;
2931 
2932  dbus_set_error (error, _dbus_error_from_errno (errno),
2933  "Could not close fd %d", fd);
2934  return FALSE;
2935  }
2936 
2937  return TRUE;
2938 }
2939 
2948 int
2949 _dbus_dup(int fd,
2950  DBusError *error)
2951 {
2952  int new_fd;
2953 
2954 #ifdef F_DUPFD_CLOEXEC
2955  dbus_bool_t cloexec_done;
2956 
2957  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2958  cloexec_done = new_fd >= 0;
2959 
2960  if (new_fd < 0 && errno == EINVAL)
2961 #endif
2962  {
2963  new_fd = fcntl(fd, F_DUPFD, 3);
2964  }
2965 
2966  if (new_fd < 0) {
2967 
2968  dbus_set_error (error, _dbus_error_from_errno (errno),
2969  "Could not duplicate fd %d", fd);
2970  return -1;
2971  }
2972 
2973 #ifdef F_DUPFD_CLOEXEC
2974  if (!cloexec_done)
2975 #endif
2976  {
2978  }
2979 
2980  return new_fd;
2981 }
2982 
2991 _dbus_set_fd_nonblocking (int fd,
2992  DBusError *error)
2993 {
2994  int val;
2995 
2996  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2997 
2998  val = fcntl (fd, F_GETFL, 0);
2999  if (val < 0)
3000  {
3001  dbus_set_error (error, _dbus_error_from_errno (errno),
3002  "Failed to get flags from file descriptor %d: %s",
3003  fd, _dbus_strerror (errno));
3004  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3005  _dbus_strerror (errno));
3006  return FALSE;
3007  }
3008 
3009  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3010  {
3011  dbus_set_error (error, _dbus_error_from_errno (errno),
3012  "Failed to set nonblocking flag of file descriptor %d: %s",
3013  fd, _dbus_strerror (errno));
3014  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3015  fd, _dbus_strerror (errno));
3016 
3017  return FALSE;
3018  }
3019 
3020  return TRUE;
3021 }
3022 
3028 void
3030 {
3031 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3032  void *bt[500];
3033  int bt_size;
3034  int i;
3035  char **syms;
3036 
3037  bt_size = backtrace (bt, 500);
3038 
3039  syms = backtrace_symbols (bt, bt_size);
3040 
3041  i = 0;
3042  while (i < bt_size)
3043  {
3044  /* don't use dbus_warn since it can _dbus_abort() */
3045  fprintf (stderr, " %s\n", syms[i]);
3046  ++i;
3047  }
3048  fflush (stderr);
3049 
3050  free (syms);
3051 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3052  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3053 #else
3054  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3055 #endif
3056 }
3057 
3072  int *fd2,
3073  dbus_bool_t blocking,
3074  DBusError *error)
3075 {
3076 #ifdef HAVE_SOCKETPAIR
3077  int fds[2];
3078  int retval;
3079 
3080 #ifdef SOCK_CLOEXEC
3081  dbus_bool_t cloexec_done;
3082 
3083  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3084  cloexec_done = retval >= 0;
3085 
3086  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3087 #endif
3088  {
3089  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3090  }
3091 
3092  if (retval < 0)
3093  {
3094  dbus_set_error (error, _dbus_error_from_errno (errno),
3095  "Could not create full-duplex pipe");
3096  return FALSE;
3097  }
3098 
3099  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3100 
3101 #ifdef SOCK_CLOEXEC
3102  if (!cloexec_done)
3103 #endif
3104  {
3105  _dbus_fd_set_close_on_exec (fds[0]);
3106  _dbus_fd_set_close_on_exec (fds[1]);
3107  }
3108 
3109  if (!blocking &&
3110  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3111  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3112  {
3113  dbus_set_error (error, _dbus_error_from_errno (errno),
3114  "Could not set full-duplex pipe nonblocking");
3115 
3116  _dbus_close (fds[0], NULL);
3117  _dbus_close (fds[1], NULL);
3118 
3119  return FALSE;
3120  }
3121 
3122  *fd1 = fds[0];
3123  *fd2 = fds[1];
3124 
3125  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3126  *fd1, *fd2);
3127 
3128  return TRUE;
3129 #else
3130  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3132  "_dbus_full_duplex_pipe() not implemented on this OS");
3133  return FALSE;
3134 #endif
3135 }
3136 
3145 int
3147  va_list args)
3148 {
3149  char static_buf[1024];
3150  int bufsize = sizeof (static_buf);
3151  int len;
3152  va_list args_copy;
3153 
3154  DBUS_VA_COPY (args_copy, args);
3155  len = vsnprintf (static_buf, bufsize, format, args_copy);
3156  va_end (args_copy);
3157 
3158  /* If vsnprintf() returned non-negative, then either the string fits in
3159  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3160  * returns the number of characters that were needed, or this OS returns the
3161  * truncated length.
3162  *
3163  * We ignore the possibility that snprintf might just ignore the length and
3164  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3165  * If your libc is really that bad, come back when you have a better one. */
3166  if (len == bufsize)
3167  {
3168  /* This could be the truncated length (Tru64 and IRIX have this bug),
3169  * or the real length could be coincidentally the same. Which is it?
3170  * If vsnprintf returns the truncated length, we'll go to the slow
3171  * path. */
3172  DBUS_VA_COPY (args_copy, args);
3173 
3174  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3175  len = -1;
3176 
3177  va_end (args_copy);
3178  }
3179 
3180  /* If vsnprintf() returned negative, we have to do more work.
3181  * HP-UX returns negative. */
3182  while (len < 0)
3183  {
3184  char *buf;
3185 
3186  bufsize *= 2;
3187 
3188  buf = dbus_malloc (bufsize);
3189 
3190  if (buf == NULL)
3191  return -1;
3192 
3193  DBUS_VA_COPY (args_copy, args);
3194  len = vsnprintf (buf, bufsize, format, args_copy);
3195  va_end (args_copy);
3196 
3197  dbus_free (buf);
3198 
3199  /* If the reported length is exactly the buffer size, round up to the
3200  * next size, in case vsnprintf has been returning the truncated
3201  * length */
3202  if (len == bufsize)
3203  len = -1;
3204  }
3205 
3206  return len;
3207 }
3208 
3215 const char*
3217 {
3218  /* Protected by _DBUS_LOCK_sysdeps */
3219  static const char* tmpdir = NULL;
3220 
3221  if (!_DBUS_LOCK (sysdeps))
3222  return NULL;
3223 
3224  if (tmpdir == NULL)
3225  {
3226  /* TMPDIR is what glibc uses, then
3227  * glibc falls back to the P_tmpdir macro which
3228  * just expands to "/tmp"
3229  */
3230  if (tmpdir == NULL)
3231  tmpdir = getenv("TMPDIR");
3232 
3233  /* These two env variables are probably
3234  * broken, but maybe some OS uses them?
3235  */
3236  if (tmpdir == NULL)
3237  tmpdir = getenv("TMP");
3238  if (tmpdir == NULL)
3239  tmpdir = getenv("TEMP");
3240 
3241  /* And this is the sane fallback. */
3242  if (tmpdir == NULL)
3243  tmpdir = "/tmp";
3244  }
3245 
3246  _DBUS_UNLOCK (sysdeps);
3247 
3248  _dbus_assert(tmpdir != NULL);
3249 
3250  return tmpdir;
3251 }
3252 
3253 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3254 
3273 static dbus_bool_t
3274 _read_subprocess_line_argv (const char *progpath,
3275  dbus_bool_t path_fallback,
3276  char * const *argv,
3277  DBusString *result,
3278  DBusError *error)
3279 {
3280  int result_pipe[2] = { -1, -1 };
3281  int errors_pipe[2] = { -1, -1 };
3282  pid_t pid;
3283  int ret;
3284  int status;
3285  int orig_len;
3286 
3287  dbus_bool_t retval;
3288  sigset_t new_set, old_set;
3289 
3290  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3291  retval = FALSE;
3292 
3293  /* We need to block any existing handlers for SIGCHLD temporarily; they
3294  * will cause waitpid() below to fail.
3295  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3296  */
3297  sigemptyset (&new_set);
3298  sigaddset (&new_set, SIGCHLD);
3299  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3300 
3301  orig_len = _dbus_string_get_length (result);
3302 
3303 #define READ_END 0
3304 #define WRITE_END 1
3305  if (pipe (result_pipe) < 0)
3306  {
3307  dbus_set_error (error, _dbus_error_from_errno (errno),
3308  "Failed to create a pipe to call %s: %s",
3309  progpath, _dbus_strerror (errno));
3310  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3311  progpath, _dbus_strerror (errno));
3312  goto out;
3313  }
3314  if (pipe (errors_pipe) < 0)
3315  {
3316  dbus_set_error (error, _dbus_error_from_errno (errno),
3317  "Failed to create a pipe to call %s: %s",
3318  progpath, _dbus_strerror (errno));
3319  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3320  progpath, _dbus_strerror (errno));
3321  goto out;
3322  }
3323 
3324  pid = fork ();
3325  if (pid < 0)
3326  {
3327  dbus_set_error (error, _dbus_error_from_errno (errno),
3328  "Failed to fork() to call %s: %s",
3329  progpath, _dbus_strerror (errno));
3330  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3331  progpath, _dbus_strerror (errno));
3332  goto out;
3333  }
3334 
3335  if (pid == 0)
3336  {
3337  /* child process */
3338  int fd;
3339 
3340  fd = open ("/dev/null", O_RDWR);
3341  if (fd == -1)
3342  /* huh?! can't open /dev/null? */
3343  _exit (1);
3344 
3345  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3346 
3347  /* set-up stdXXX */
3348  close (result_pipe[READ_END]);
3349  close (errors_pipe[READ_END]);
3350 
3351  if (dup2 (fd, 0) == -1) /* setup stdin */
3352  _exit (1);
3353  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3354  _exit (1);
3355  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3356  _exit (1);
3357 
3358  _dbus_close_all ();
3359 
3360  sigprocmask (SIG_SETMASK, &old_set, NULL);
3361 
3362  /* If it looks fully-qualified, try execv first */
3363  if (progpath[0] == '/')
3364  {
3365  execv (progpath, argv);
3366  /* Ok, that failed. Now if path_fallback is given, let's
3367  * try unqualified. This is mostly a hack to work
3368  * around systems which ship dbus-launch in /usr/bin
3369  * but everything else in /bin (because dbus-launch
3370  * depends on X11).
3371  */
3372  if (path_fallback)
3373  /* We must have a slash, because we checked above */
3374  execvp (strrchr (progpath, '/')+1, argv);
3375  }
3376  else
3377  execvp (progpath, argv);
3378 
3379  /* still nothing, we failed */
3380  _exit (1);
3381  }
3382 
3383  /* parent process */
3384  close (result_pipe[WRITE_END]);
3385  close (errors_pipe[WRITE_END]);
3386  result_pipe[WRITE_END] = -1;
3387  errors_pipe[WRITE_END] = -1;
3388 
3389  ret = 0;
3390  do
3391  {
3392  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3393  }
3394  while (ret > 0);
3395 
3396  /* reap the child process to avoid it lingering as zombie */
3397  do
3398  {
3399  ret = waitpid (pid, &status, 0);
3400  }
3401  while (ret == -1 && errno == EINTR);
3402 
3403  /* We succeeded if the process exited with status 0 and
3404  anything was read */
3405  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3406  {
3407  /* The process ended with error */
3408  DBusString error_message;
3409  if (!_dbus_string_init (&error_message))
3410  {
3411  _DBUS_SET_OOM (error);
3412  goto out;
3413  }
3414 
3415  ret = 0;
3416  do
3417  {
3418  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3419  }
3420  while (ret > 0);
3421 
3422  _dbus_string_set_length (result, orig_len);
3423  if (_dbus_string_get_length (&error_message) > 0)
3425  "%s terminated abnormally with the following error: %s",
3426  progpath, _dbus_string_get_data (&error_message));
3427  else
3429  "%s terminated abnormally without any error message",
3430  progpath);
3431  goto out;
3432  }
3433 
3434  retval = TRUE;
3435 
3436  out:
3437  sigprocmask (SIG_SETMASK, &old_set, NULL);
3438 
3439  if (retval)
3440  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3441  else
3442  _DBUS_ASSERT_ERROR_IS_SET (error);
3443 
3444  if (result_pipe[0] != -1)
3445  close (result_pipe[0]);
3446  if (result_pipe[1] != -1)
3447  close (result_pipe[1]);
3448  if (errors_pipe[0] != -1)
3449  close (errors_pipe[0]);
3450  if (errors_pipe[1] != -1)
3451  close (errors_pipe[1]);
3452 
3453  return retval;
3454 }
3455 #endif
3456 
3470 _dbus_get_autolaunch_address (const char *scope,
3471  DBusString *address,
3472  DBusError *error)
3473 {
3474 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3475  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3476  * but that's done elsewhere, and if it worked, this function wouldn't
3477  * be called.) */
3478  const char *display;
3479  char *argv[6];
3480  int i;
3481  DBusString uuid;
3482  dbus_bool_t retval;
3483 
3484  if (_dbus_check_setuid ())
3485  {
3487  "Unable to autolaunch when setuid");
3488  return FALSE;
3489  }
3490 
3491  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3492  retval = FALSE;
3493 
3494  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3495  * dbus-launch-x11 is just going to fail. Rather than trying to
3496  * run it, we might as well bail out early with a nice error. */
3497  display = _dbus_getenv ("DISPLAY");
3498 
3499  if (display == NULL || display[0] == '\0')
3500  {
3502  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3503  return FALSE;
3504  }
3505 
3506  if (!_dbus_string_init (&uuid))
3507  {
3508  _DBUS_SET_OOM (error);
3509  return FALSE;
3510  }
3511 
3513  {
3514  _DBUS_SET_OOM (error);
3515  goto out;
3516  }
3517 
3518  i = 0;
3519 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3520  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3521  argv[i] = TEST_BUS_LAUNCH_BINARY;
3522  else
3523 #endif
3524  argv[i] = DBUS_BINDIR "/dbus-launch";
3525  ++i;
3526  argv[i] = "--autolaunch";
3527  ++i;
3528  argv[i] = _dbus_string_get_data (&uuid);
3529  ++i;
3530  argv[i] = "--binary-syntax";
3531  ++i;
3532  argv[i] = "--close-stderr";
3533  ++i;
3534  argv[i] = NULL;
3535  ++i;
3536 
3537  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3538 
3539  retval = _read_subprocess_line_argv (argv[0],
3540  TRUE,
3541  argv, address, error);
3542 
3543  out:
3544  _dbus_string_free (&uuid);
3545  return retval;
3546 #else
3548  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3549  "set your DBUS_SESSION_BUS_ADDRESS instead");
3550  return FALSE;
3551 #endif
3552 }
3553 
3574  dbus_bool_t create_if_not_found,
3575  DBusError *error)
3576 {
3577  DBusString filename;
3578  dbus_bool_t b;
3579 
3580  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3581 
3582  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3583  if (b)
3584  return TRUE;
3585 
3586  dbus_error_free (error);
3587 
3588  /* Fallback to the system machine ID */
3589  _dbus_string_init_const (&filename, "/etc/machine-id");
3590  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3591 
3592  if (b)
3593  {
3594  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3595  * complain if that isn't possible for whatever reason */
3596  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3597  _dbus_write_uuid_file (&filename, machine_id, NULL);
3598 
3599  return TRUE;
3600  }
3601 
3602  if (!create_if_not_found)
3603  return FALSE;
3604 
3605  /* if none found, try to make a new one */
3606  dbus_error_free (error);
3607  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3608  _dbus_generate_uuid (machine_id);
3609  return _dbus_write_uuid_file (&filename, machine_id, error);
3610 }
3611 
3621  const char *launchd_env_var,
3622  DBusError *error)
3623 {
3624 #ifdef DBUS_ENABLE_LAUNCHD
3625  char *argv[4];
3626  int i;
3627 
3628  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3629 
3630  if (_dbus_check_setuid ())
3631  {
3633  "Unable to find launchd socket when setuid");
3634  return FALSE;
3635  }
3636 
3637  i = 0;
3638  argv[i] = "launchctl";
3639  ++i;
3640  argv[i] = "getenv";
3641  ++i;
3642  argv[i] = (char*)launchd_env_var;
3643  ++i;
3644  argv[i] = NULL;
3645  ++i;
3646 
3647  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3648 
3649  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3650  {
3651  return FALSE;
3652  }
3653 
3654  /* no error, but no result either */
3655  if (_dbus_string_get_length(socket_path) == 0)
3656  {
3657  return FALSE;
3658  }
3659 
3660  /* strip the carriage-return */
3661  _dbus_string_shorten(socket_path, 1);
3662  return TRUE;
3663 #else /* DBUS_ENABLE_LAUNCHD */
3665  "can't lookup socket from launchd; launchd support not compiled in");
3666  return FALSE;
3667 #endif
3668 }
3669 
3670 #ifdef DBUS_ENABLE_LAUNCHD
3671 static dbus_bool_t
3672 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3673 {
3674  dbus_bool_t valid_socket;
3675  DBusString socket_path;
3676 
3677  if (_dbus_check_setuid ())
3678  {
3680  "Unable to find launchd socket when setuid");
3681  return FALSE;
3682  }
3683 
3684  if (!_dbus_string_init (&socket_path))
3685  {
3686  _DBUS_SET_OOM (error);
3687  return FALSE;
3688  }
3689 
3690  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3691 
3692  if (dbus_error_is_set(error))
3693  {
3694  _dbus_string_free(&socket_path);
3695  return FALSE;
3696  }
3697 
3698  if (!valid_socket)
3699  {
3700  dbus_set_error(error, "no socket path",
3701  "launchd did not provide a socket path, "
3702  "verify that org.freedesktop.dbus-session.plist is loaded!");
3703  _dbus_string_free(&socket_path);
3704  return FALSE;
3705  }
3706  if (!_dbus_string_append (address, "unix:path="))
3707  {
3708  _DBUS_SET_OOM (error);
3709  _dbus_string_free(&socket_path);
3710  return FALSE;
3711  }
3712  if (!_dbus_string_copy (&socket_path, 0, address,
3713  _dbus_string_get_length (address)))
3714  {
3715  _DBUS_SET_OOM (error);
3716  _dbus_string_free(&socket_path);
3717  return FALSE;
3718  }
3719 
3720  _dbus_string_free(&socket_path);
3721  return TRUE;
3722 }
3723 #endif
3724 
3746  DBusString *address,
3747  DBusError *error)
3748 {
3749 #ifdef DBUS_ENABLE_LAUNCHD
3750  *supported = TRUE;
3751  return _dbus_lookup_session_address_launchd (address, error);
3752 #else
3753  /* On non-Mac Unix platforms, if the session address isn't already
3754  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3755  * fall back to the autolaunch: global default; see
3756  * init_session_address in dbus/dbus-bus.c. */
3757  *supported = FALSE;
3758  return TRUE;
3759 #endif
3760 }
3761 
3769 void
3771 {
3773 }
3774 
3790  DBusCredentials *credentials)
3791 {
3792  DBusString homedir;
3793  DBusString dotdir;
3794  dbus_uid_t uid;
3795 
3796  _dbus_assert (credentials != NULL);
3798 
3799  if (!_dbus_string_init (&homedir))
3800  return FALSE;
3801 
3802  uid = _dbus_credentials_get_unix_uid (credentials);
3803  _dbus_assert (uid != DBUS_UID_UNSET);
3804 
3805  if (!_dbus_homedir_from_uid (uid, &homedir))
3806  goto failed;
3807 
3808 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3809  {
3810  const char *override;
3811 
3812  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3813  if (override != NULL && *override != '\0')
3814  {
3815  _dbus_string_set_length (&homedir, 0);
3816  if (!_dbus_string_append (&homedir, override))
3817  goto failed;
3818 
3819  _dbus_verbose ("Using fake homedir for testing: %s\n",
3820  _dbus_string_get_const_data (&homedir));
3821  }
3822  else
3823  {
3824  /* Not strictly thread-safe, but if we fail at thread-safety here,
3825  * the worst that will happen is some extra warnings. */
3826  static dbus_bool_t already_warned = FALSE;
3827  if (!already_warned)
3828  {
3829  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3830  already_warned = TRUE;
3831  }
3832  }
3833  }
3834 #endif
3835 
3836  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3837  if (!_dbus_concat_dir_and_file (&homedir,
3838  &dotdir))
3839  goto failed;
3840 
3841  if (!_dbus_string_copy (&homedir, 0,
3842  directory, _dbus_string_get_length (directory))) {
3843  goto failed;
3844  }
3845 
3846  _dbus_string_free (&homedir);
3847  return TRUE;
3848 
3849  failed:
3850  _dbus_string_free (&homedir);
3851  return FALSE;
3852 }
3853 
3854 //PENDING(kdab) docs
3856 _dbus_daemon_publish_session_bus_address (const char* addr,
3857  const char *scope)
3858 {
3859  return TRUE;
3860 }
3861 
3862 //PENDING(kdab) docs
3863 void
3864 _dbus_daemon_unpublish_session_bus_address (void)
3865 {
3866 
3867 }
3868 
3877 {
3878  return errno == EAGAIN || errno == EWOULDBLOCK;
3879 }
3880 
3890  DBusError *error)
3891 {
3892  const char *filename_c;
3893 
3894  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3895 
3896  filename_c = _dbus_string_get_const_data (filename);
3897 
3898  if (rmdir (filename_c) != 0)
3899  {
3901  "Failed to remove directory %s: %s\n",
3902  filename_c, _dbus_strerror (errno));
3903  return FALSE;
3904  }
3905 
3906  return TRUE;
3907 }
3908 
3918 
3919 #ifdef SCM_RIGHTS
3920  union {
3921  struct sockaddr sa;
3922  struct sockaddr_storage storage;
3923  struct sockaddr_un un;
3924  } sa_buf;
3925 
3926  socklen_t sa_len = sizeof(sa_buf);
3927 
3928  _DBUS_ZERO(sa_buf);
3929 
3930  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3931  return FALSE;
3932 
3933  return sa_buf.sa.sa_family == AF_UNIX;
3934 
3935 #else
3936  return FALSE;
3937 
3938 #endif
3939 }
3940 
3945 void
3947 {
3948  int maxfds, i;
3949 
3950 #ifdef __linux__
3951  DIR *d;
3952 
3953  /* On Linux we can optimize this a bit if /proc is available. If it
3954  isn't available, fall back to the brute force way. */
3955 
3956  d = opendir ("/proc/self/fd");
3957  if (d)
3958  {
3959  for (;;)
3960  {
3961  struct dirent buf, *de;
3962  int k, fd;
3963  long l;
3964  char *e = NULL;
3965 
3966  k = readdir_r (d, &buf, &de);
3967  if (k != 0 || !de)
3968  break;
3969 
3970  if (de->d_name[0] == '.')
3971  continue;
3972 
3973  errno = 0;
3974  l = strtol (de->d_name, &e, 10);
3975  if (errno != 0 || e == NULL || *e != '\0')
3976  continue;
3977 
3978  fd = (int) l;
3979  if (fd < 3)
3980  continue;
3981 
3982  if (fd == dirfd (d))
3983  continue;
3984 
3985  close (fd);
3986  }
3987 
3988  closedir (d);
3989  return;
3990  }
3991 #endif
3992 
3993  maxfds = sysconf (_SC_OPEN_MAX);
3994 
3995  /* Pick something reasonable if for some reason sysconf says
3996  * unlimited.
3997  */
3998  if (maxfds < 0)
3999  maxfds = 1024;
4000 
4001  /* close all inherited fds */
4002  for (i = 3; i < maxfds; i++)
4003  close (i);
4004 }
4005 
4017 {
4018  /* TODO: get __libc_enable_secure exported from glibc.
4019  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4020  */
4021 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4022  {
4023  /* See glibc/include/unistd.h */
4024  extern int __libc_enable_secure;
4025  return __libc_enable_secure;
4026  }
4027 #elif defined(HAVE_ISSETUGID)
4028  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4029  return issetugid ();
4030 #else
4031  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4032  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4033 
4034  /* We call into this function from _dbus_threads_init_platform_specific()
4035  * to make sure these are initialized before we start threading. */
4036  static dbus_bool_t check_setuid_initialised;
4037  static dbus_bool_t is_setuid;
4038 
4039  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4040  {
4041 #ifdef HAVE_GETRESUID
4042  if (getresuid (&ruid, &euid, &suid) != 0 ||
4043  getresgid (&rgid, &egid, &sgid) != 0)
4044 #endif /* HAVE_GETRESUID */
4045  {
4046  suid = ruid = getuid ();
4047  sgid = rgid = getgid ();
4048  euid = geteuid ();
4049  egid = getegid ();
4050  }
4051 
4052  check_setuid_initialised = TRUE;
4053  is_setuid = (ruid != euid || ruid != suid ||
4054  rgid != egid || rgid != sgid);
4055 
4056  }
4057  return is_setuid;
4058 #endif
4059 }
4060 
4070  DBusString *address,
4071  DBusError *error)
4072 {
4073  union {
4074  struct sockaddr sa;
4075  struct sockaddr_storage storage;
4076  struct sockaddr_un un;
4077  struct sockaddr_in ipv4;
4078  struct sockaddr_in6 ipv6;
4079  } socket;
4080  char hostip[INET6_ADDRSTRLEN];
4081  int size = sizeof (socket);
4082  DBusString path_str;
4083 
4084  if (getsockname (fd, &socket.sa, &size))
4085  goto err;
4086 
4087  switch (socket.sa.sa_family)
4088  {
4089  case AF_UNIX:
4090  if (socket.un.sun_path[0]=='\0')
4091  {
4092  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4093  if (_dbus_string_append (address, "unix:abstract=") &&
4094  _dbus_address_append_escaped (address, &path_str))
4095  return TRUE;
4096  }
4097  else
4098  {
4099  _dbus_string_init_const (&path_str, socket.un.sun_path);
4100  if (_dbus_string_append (address, "unix:path=") &&
4101  _dbus_address_append_escaped (address, &path_str))
4102  return TRUE;
4103  }
4104  break;
4105  case AF_INET:
4106  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4107  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4108  hostip, ntohs (socket.ipv4.sin_port)))
4109  return TRUE;
4110  break;
4111 #ifdef AF_INET6
4112  case AF_INET6:
4113  _dbus_string_init_const (&path_str, hostip);
4114  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4115  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4116  ntohs (socket.ipv6.sin6_port)) &&
4117  _dbus_address_append_escaped (address, &path_str))
4118  return TRUE;
4119  break;
4120 #endif
4121  default:
4122  dbus_set_error (error,
4123  _dbus_error_from_errno (EINVAL),
4124  "Failed to read address from socket: Unknown socket type.");
4125  return FALSE;
4126  }
4127  err:
4128  dbus_set_error (error,
4129  _dbus_error_from_errno (errno),
4130  "Failed to open socket: %s",
4131  _dbus_strerror (errno));
4132  return FALSE;
4133 }
4134 
4135 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:918
dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:227
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:392
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:232
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:302
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:743
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd)
Checks whether file descriptors may be passed via the socket.
#define _DBUS_POLLNVAL
Invalid request: fd not open.
Definition: dbus-sysdeps.h:304
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
dbus_bool_t _dbus_append_address_from_socket(int fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:114
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:110
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_full_duplex_pipe(int *fd1, int *fd2, dbus_bool_t blocking, DBusError *error)
Creates a full-duplex pipe (as in socketpair()).
int _dbus_write_socket_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:349
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_gid_t primary_gid
GID.
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h:296
int _dbus_read_socket_with_unix_fds(int fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
A portable struct pollfd wrapper.
Definition: dbus-sysdeps.h:310
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
int _dbus_accept(int listen_fd)
Accepts a connection on a listening socket.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:545
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:294
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:473
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:763
short events
Events to poll for.
Definition: dbus-sysdeps.h:313
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1265
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:103
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:105
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str)
Gets the hex-encoded UUID of the machine this function is executed on.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:614
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:461
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:96
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:434
int n_group_ids
Size of group IDs array.
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:298
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1096
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:722
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
#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.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:497
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(void)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
void _dbus_generate_uuid(DBusGUID *uuid)
Generates a new UUID.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:785
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:859
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:100
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:98
short revents
Events that occurred.
Definition: dbus-sysdeps.h:314
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:451
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
int _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
int _dbus_listen_systemd_sockets(int **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:300