D-Bus  1.7.6
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  unsigned int reuseaddr;
1003 
1004  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1005 
1006  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1007  path, abstract);
1008 
1009  if (!_dbus_open_unix_socket (&listen_fd, error))
1010  {
1011  _DBUS_ASSERT_ERROR_IS_SET(error);
1012  return -1;
1013  }
1014  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1015 
1016  _DBUS_ZERO (addr);
1017  addr.sun_family = AF_UNIX;
1018  path_len = strlen (path);
1019 
1020  if (abstract)
1021  {
1022 #ifdef HAVE_ABSTRACT_SOCKETS
1023  /* remember that abstract names aren't nul-terminated so we rely
1024  * on sun_path being filled in with zeroes above.
1025  */
1026  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1027  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1028 
1029  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1030  {
1032  "Abstract socket name too long\n");
1033  _dbus_close (listen_fd, NULL);
1034  return -1;
1035  }
1036 
1037  strncpy (&addr.sun_path[1], path, path_len);
1038  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1039 #else /* HAVE_ABSTRACT_SOCKETS */
1041  "Operating system does not support abstract socket namespace\n");
1042  _dbus_close (listen_fd, NULL);
1043  return -1;
1044 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1045  }
1046  else
1047  {
1048  /* Discussed security implications of this with Nalin,
1049  * and we couldn't think of where it would kick our ass, but
1050  * it still seems a bit sucky. It also has non-security suckage;
1051  * really we'd prefer to exit if the socket is already in use.
1052  * But there doesn't seem to be a good way to do this.
1053  *
1054  * Just to be extra careful, I threw in the stat() - clearly
1055  * the stat() can't *fix* any security issue, but it at least
1056  * avoids inadvertent/accidental data loss.
1057  */
1058  {
1059  struct stat sb;
1060 
1061  if (stat (path, &sb) == 0 &&
1062  S_ISSOCK (sb.st_mode))
1063  unlink (path);
1064  }
1065 
1066  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1067  {
1069  "Abstract socket name too long\n");
1070  _dbus_close (listen_fd, NULL);
1071  return -1;
1072  }
1073 
1074  strncpy (addr.sun_path, path, path_len);
1075  }
1076 
1077  reuseaddr = 1;
1078  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1079  {
1080  _dbus_warn ("Failed to set socket option\"%s\": %s",
1081  path, _dbus_strerror (errno));
1082  }
1083 
1084  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1085  {
1086  dbus_set_error (error, _dbus_error_from_errno (errno),
1087  "Failed to bind socket \"%s\": %s",
1088  path, _dbus_strerror (errno));
1089  _dbus_close (listen_fd, NULL);
1090  return -1;
1091  }
1092 
1093  if (listen (listen_fd, 30 /* backlog */) < 0)
1094  {
1095  dbus_set_error (error, _dbus_error_from_errno (errno),
1096  "Failed to listen on socket \"%s\": %s",
1097  path, _dbus_strerror (errno));
1098  _dbus_close (listen_fd, NULL);
1099  return -1;
1100  }
1101 
1102  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1103  {
1104  _DBUS_ASSERT_ERROR_IS_SET (error);
1105  _dbus_close (listen_fd, NULL);
1106  return -1;
1107  }
1108 
1109  /* Try opening up the permissions, but if we can't, just go ahead
1110  * and continue, maybe it will be good enough.
1111  */
1112  if (!abstract && chmod (path, 0777) < 0)
1113  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1114  path);
1115 
1116  return listen_fd;
1117 }
1118 
1129 int
1131  DBusError *error)
1132 {
1133  int r, n;
1134  unsigned fd;
1135  int *new_fds;
1136 
1137  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1138 
1139  n = sd_listen_fds (TRUE);
1140  if (n < 0)
1141  {
1143  "Failed to acquire systemd socket: %s",
1144  _dbus_strerror (-n));
1145  return -1;
1146  }
1147 
1148  if (n <= 0)
1149  {
1151  "No socket received.");
1152  return -1;
1153  }
1154 
1155  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1156  {
1157  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1158  if (r < 0)
1159  {
1161  "Failed to verify systemd socket type: %s",
1162  _dbus_strerror (-r));
1163  return -1;
1164  }
1165 
1166  if (!r)
1167  {
1169  "Passed socket has wrong type.");
1170  return -1;
1171  }
1172  }
1173 
1174  /* OK, the file descriptors are all good, so let's take posession of
1175  them then. */
1176 
1177  new_fds = dbus_new (int, n);
1178  if (!new_fds)
1179  {
1181  "Failed to allocate file handle array.");
1182  goto fail;
1183  }
1184 
1185  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1186  {
1187  if (!_dbus_set_fd_nonblocking (fd, error))
1188  {
1189  _DBUS_ASSERT_ERROR_IS_SET (error);
1190  goto fail;
1191  }
1192 
1193  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1194  }
1195 
1196  *fds = new_fds;
1197  return n;
1198 
1199  fail:
1200 
1201  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1202  {
1203  _dbus_close (fd, NULL);
1204  }
1205 
1206  dbus_free (new_fds);
1207  return -1;
1208 }
1209 
1223 int
1224 _dbus_connect_tcp_socket (const char *host,
1225  const char *port,
1226  const char *family,
1227  DBusError *error)
1228 {
1229  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1230 }
1231 
1232 int
1233 _dbus_connect_tcp_socket_with_nonce (const char *host,
1234  const char *port,
1235  const char *family,
1236  const char *noncefile,
1237  DBusError *error)
1238 {
1239  int saved_errno = 0;
1240  int fd = -1, res;
1241  struct addrinfo hints;
1242  struct addrinfo *ai, *tmp;
1243 
1244  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1245 
1246  _DBUS_ZERO (hints);
1247 
1248  if (!family)
1249  hints.ai_family = AF_UNSPEC;
1250  else if (!strcmp(family, "ipv4"))
1251  hints.ai_family = AF_INET;
1252  else if (!strcmp(family, "ipv6"))
1253  hints.ai_family = AF_INET6;
1254  else
1255  {
1256  dbus_set_error (error,
1258  "Unknown address family %s", family);
1259  return -1;
1260  }
1261  hints.ai_protocol = IPPROTO_TCP;
1262  hints.ai_socktype = SOCK_STREAM;
1263  hints.ai_flags = AI_ADDRCONFIG;
1264 
1265  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1266  {
1267  dbus_set_error (error,
1268  _dbus_error_from_errno (errno),
1269  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1270  host, port, gai_strerror(res), res);
1271  return -1;
1272  }
1273 
1274  tmp = ai;
1275  while (tmp)
1276  {
1277  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1278  {
1279  freeaddrinfo(ai);
1280  _DBUS_ASSERT_ERROR_IS_SET(error);
1281  return -1;
1282  }
1283  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1284 
1285  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1286  {
1287  saved_errno = errno;
1288  _dbus_close(fd, NULL);
1289  fd = -1;
1290  tmp = tmp->ai_next;
1291  continue;
1292  }
1293 
1294  break;
1295  }
1296  freeaddrinfo(ai);
1297 
1298  if (fd == -1)
1299  {
1300  dbus_set_error (error,
1301  _dbus_error_from_errno (saved_errno),
1302  "Failed to connect to socket \"%s:%s\" %s",
1303  host, port, _dbus_strerror(saved_errno));
1304  return -1;
1305  }
1306 
1307  if (noncefile != NULL)
1308  {
1309  DBusString noncefileStr;
1310  dbus_bool_t ret;
1311  _dbus_string_init_const (&noncefileStr, noncefile);
1312  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1313  _dbus_string_free (&noncefileStr);
1314 
1315  if (!ret)
1316  {
1317  _dbus_close (fd, NULL);
1318  return -1;
1319  }
1320  }
1321 
1322  if (!_dbus_set_fd_nonblocking (fd, error))
1323  {
1324  _dbus_close (fd, NULL);
1325  return -1;
1326  }
1327 
1328  return fd;
1329 }
1330 
1347 int
1348 _dbus_listen_tcp_socket (const char *host,
1349  const char *port,
1350  const char *family,
1351  DBusString *retport,
1352  int **fds_p,
1353  DBusError *error)
1354 {
1355  int saved_errno;
1356  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1357  struct addrinfo hints;
1358  struct addrinfo *ai, *tmp;
1359  unsigned int reuseaddr;
1360 
1361  *fds_p = NULL;
1362  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1363 
1364  _DBUS_ZERO (hints);
1365 
1366  if (!family)
1367  hints.ai_family = AF_UNSPEC;
1368  else if (!strcmp(family, "ipv4"))
1369  hints.ai_family = AF_INET;
1370  else if (!strcmp(family, "ipv6"))
1371  hints.ai_family = AF_INET6;
1372  else
1373  {
1374  dbus_set_error (error,
1376  "Unknown address family %s", family);
1377  return -1;
1378  }
1379 
1380  hints.ai_protocol = IPPROTO_TCP;
1381  hints.ai_socktype = SOCK_STREAM;
1382  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1383 
1384  redo_lookup_with_port:
1385  ai = NULL;
1386  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1387  {
1388  dbus_set_error (error,
1389  _dbus_error_from_errno (errno),
1390  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1391  host ? host : "*", port, gai_strerror(res), res);
1392  goto failed;
1393  }
1394 
1395  tmp = ai;
1396  while (tmp)
1397  {
1398  int fd = -1, *newlisten_fd;
1399  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1400  {
1401  _DBUS_ASSERT_ERROR_IS_SET(error);
1402  goto failed;
1403  }
1404  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1405 
1406  reuseaddr = 1;
1407  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1408  {
1409  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1410  host ? host : "*", port, _dbus_strerror (errno));
1411  }
1412 
1413  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1414  {
1415  saved_errno = errno;
1416  _dbus_close(fd, NULL);
1417  if (saved_errno == EADDRINUSE)
1418  {
1419  /* Depending on kernel policy, it may or may not
1420  be neccessary to bind to both IPv4 & 6 addresses
1421  so ignore EADDRINUSE here */
1422  tmp = tmp->ai_next;
1423  continue;
1424  }
1425  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1426  "Failed to bind socket \"%s:%s\": %s",
1427  host ? host : "*", port, _dbus_strerror (saved_errno));
1428  goto failed;
1429  }
1430 
1431  if (listen (fd, 30 /* backlog */) < 0)
1432  {
1433  saved_errno = errno;
1434  _dbus_close (fd, NULL);
1435  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1436  "Failed to listen on socket \"%s:%s\": %s",
1437  host ? host : "*", port, _dbus_strerror (saved_errno));
1438  goto failed;
1439  }
1440 
1441  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1442  if (!newlisten_fd)
1443  {
1444  saved_errno = errno;
1445  _dbus_close (fd, NULL);
1446  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1447  "Failed to allocate file handle array: %s",
1448  _dbus_strerror (saved_errno));
1449  goto failed;
1450  }
1451  listen_fd = newlisten_fd;
1452  listen_fd[nlisten_fd] = fd;
1453  nlisten_fd++;
1454 
1455  if (!_dbus_string_get_length(retport))
1456  {
1457  /* If the user didn't specify a port, or used 0, then
1458  the kernel chooses a port. After the first address
1459  is bound to, we need to force all remaining addresses
1460  to use the same port */
1461  if (!port || !strcmp(port, "0"))
1462  {
1463  int result;
1464  struct sockaddr_storage addr;
1465  socklen_t addrlen;
1466  char portbuf[50];
1467 
1468  addrlen = sizeof(addr);
1469  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1470 
1471  if (result == -1 ||
1472  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1473  portbuf, sizeof(portbuf),
1474  NI_NUMERICHOST)) != 0)
1475  {
1476  dbus_set_error (error, _dbus_error_from_errno (errno),
1477  "Failed to resolve port \"%s:%s\": %s (%s)",
1478  host ? host : "*", port, gai_strerror(res), res);
1479  goto failed;
1480  }
1481  if (!_dbus_string_append(retport, portbuf))
1482  {
1484  goto failed;
1485  }
1486 
1487  /* Release current address list & redo lookup */
1488  port = _dbus_string_get_const_data(retport);
1489  freeaddrinfo(ai);
1490  goto redo_lookup_with_port;
1491  }
1492  else
1493  {
1494  if (!_dbus_string_append(retport, port))
1495  {
1497  goto failed;
1498  }
1499  }
1500  }
1501 
1502  tmp = tmp->ai_next;
1503  }
1504  freeaddrinfo(ai);
1505  ai = NULL;
1506 
1507  if (!nlisten_fd)
1508  {
1509  errno = EADDRINUSE;
1510  dbus_set_error (error, _dbus_error_from_errno (errno),
1511  "Failed to bind socket \"%s:%s\": %s",
1512  host ? host : "*", port, _dbus_strerror (errno));
1513  goto failed;
1514  }
1515 
1516  for (i = 0 ; i < nlisten_fd ; i++)
1517  {
1518  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1519  {
1520  goto failed;
1521  }
1522  }
1523 
1524  *fds_p = listen_fd;
1525 
1526  return nlisten_fd;
1527 
1528  failed:
1529  if (ai)
1530  freeaddrinfo(ai);
1531  for (i = 0 ; i < nlisten_fd ; i++)
1532  _dbus_close(listen_fd[i], NULL);
1533  dbus_free(listen_fd);
1534  return -1;
1535 }
1536 
1537 static dbus_bool_t
1538 write_credentials_byte (int server_fd,
1539  DBusError *error)
1540 {
1541  int bytes_written;
1542  char buf[1] = { '\0' };
1543 #if defined(HAVE_CMSGCRED)
1544  union {
1545  struct cmsghdr hdr;
1546  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1547  } cmsg;
1548  struct iovec iov;
1549  struct msghdr msg;
1550  iov.iov_base = buf;
1551  iov.iov_len = 1;
1552 
1553  _DBUS_ZERO(msg);
1554  msg.msg_iov = &iov;
1555  msg.msg_iovlen = 1;
1556 
1557  msg.msg_control = (caddr_t) &cmsg;
1558  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1559  _DBUS_ZERO(cmsg);
1560  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1561  cmsg.hdr.cmsg_level = SOL_SOCKET;
1562  cmsg.hdr.cmsg_type = SCM_CREDS;
1563 #endif
1564 
1565  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1566 
1567  again:
1568 
1569 #if defined(HAVE_CMSGCRED)
1570  bytes_written = sendmsg (server_fd, &msg, 0
1571 #if HAVE_DECL_MSG_NOSIGNAL
1572  |MSG_NOSIGNAL
1573 #endif
1574  );
1575 #else
1576  bytes_written = send (server_fd, buf, 1, 0
1577 #if HAVE_DECL_MSG_NOSIGNAL
1578  |MSG_NOSIGNAL
1579 #endif
1580  );
1581 #endif
1582 
1583  if (bytes_written < 0 && errno == EINTR)
1584  goto again;
1585 
1586  if (bytes_written < 0)
1587  {
1588  dbus_set_error (error, _dbus_error_from_errno (errno),
1589  "Failed to write credentials byte: %s",
1590  _dbus_strerror (errno));
1591  return FALSE;
1592  }
1593  else if (bytes_written == 0)
1594  {
1596  "wrote zero bytes writing credentials byte");
1597  return FALSE;
1598  }
1599  else
1600  {
1601  _dbus_assert (bytes_written == 1);
1602  _dbus_verbose ("wrote credentials byte\n");
1603  return TRUE;
1604  }
1605 }
1606 
1630  DBusCredentials *credentials,
1631  DBusError *error)
1632 {
1633  struct msghdr msg;
1634  struct iovec iov;
1635  char buf;
1636  dbus_uid_t uid_read;
1637  dbus_pid_t pid_read;
1638  int bytes_read;
1639 
1640 #ifdef HAVE_CMSGCRED
1641  union {
1642  struct cmsghdr hdr;
1643  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1644  } cmsg;
1645 #endif
1646 
1647  uid_read = DBUS_UID_UNSET;
1648  pid_read = DBUS_PID_UNSET;
1649 
1650  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1651 
1652  /* The POSIX spec certainly doesn't promise this, but
1653  * we need these assertions to fail as soon as we're wrong about
1654  * it so we can do the porting fixups
1655  */
1656  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1657  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1658  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1659 
1660  _dbus_credentials_clear (credentials);
1661 
1662  iov.iov_base = &buf;
1663  iov.iov_len = 1;
1664 
1665  _DBUS_ZERO(msg);
1666  msg.msg_iov = &iov;
1667  msg.msg_iovlen = 1;
1668 
1669 #if defined(HAVE_CMSGCRED)
1670  _DBUS_ZERO(cmsg);
1671  msg.msg_control = (caddr_t) &cmsg;
1672  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1673 #endif
1674 
1675  again:
1676  bytes_read = recvmsg (client_fd, &msg, 0);
1677 
1678  if (bytes_read < 0)
1679  {
1680  if (errno == EINTR)
1681  goto again;
1682 
1683  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1684  * normally only call read_credentials if the socket was ready
1685  * for reading
1686  */
1687 
1688  dbus_set_error (error, _dbus_error_from_errno (errno),
1689  "Failed to read credentials byte: %s",
1690  _dbus_strerror (errno));
1691  return FALSE;
1692  }
1693  else if (bytes_read == 0)
1694  {
1695  /* this should not happen unless we are using recvmsg wrong,
1696  * so is essentially here for paranoia
1697  */
1699  "Failed to read credentials byte (zero-length read)");
1700  return FALSE;
1701  }
1702  else if (buf != '\0')
1703  {
1705  "Credentials byte was not nul");
1706  return FALSE;
1707  }
1708 
1709 #if defined(HAVE_CMSGCRED)
1710  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1711  || cmsg.hdr.cmsg_type != SCM_CREDS)
1712  {
1714  "Message from recvmsg() was not SCM_CREDS");
1715  return FALSE;
1716  }
1717 #endif
1718 
1719  _dbus_verbose ("read credentials byte\n");
1720 
1721  {
1722 #ifdef SO_PEERCRED
1723  /* Supported by at least Linux and OpenBSD, with minor differences.
1724  *
1725  * This mechanism passes the process ID through and does not require
1726  * the peer's cooperation, so we prefer it over all others. Notably,
1727  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1728  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1729  * because this is much less fragile.
1730  */
1731 #ifdef __OpenBSD__
1732  struct sockpeercred cr;
1733 #else
1734  struct ucred cr;
1735 #endif
1736  int cr_len = sizeof (cr);
1737 
1738  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1739  cr_len == sizeof (cr))
1740  {
1741  pid_read = cr.pid;
1742  uid_read = cr.uid;
1743  }
1744  else
1745  {
1746  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1747  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1748  }
1749 #elif defined(HAVE_CMSGCRED)
1750  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1751  * presence of that struct implies SCM_CREDS. Supported by at least
1752  * FreeBSD and DragonflyBSD.
1753  *
1754  * This mechanism requires the peer to help us (it has to send us a
1755  * SCM_CREDS message) but it does pass the process ID through,
1756  * which makes it better than getpeereid().
1757  */
1758  struct cmsgcred *cred;
1759 
1760  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1761  pid_read = cred->cmcred_pid;
1762  uid_read = cred->cmcred_euid;
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 ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2003  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2004  {
2006  "%s directory is not private to the user", directory);
2007  return FALSE;
2008  }
2009 
2010  return TRUE;
2011 }
2012 
2013 static dbus_bool_t
2014 fill_user_info_from_passwd (struct passwd *p,
2015  DBusUserInfo *info,
2016  DBusError *error)
2017 {
2018  _dbus_assert (p->pw_name != NULL);
2019  _dbus_assert (p->pw_dir != NULL);
2020 
2021  info->uid = p->pw_uid;
2022  info->primary_gid = p->pw_gid;
2023  info->username = _dbus_strdup (p->pw_name);
2024  info->homedir = _dbus_strdup (p->pw_dir);
2025 
2026  if (info->username == NULL ||
2027  info->homedir == NULL)
2028  {
2030  return FALSE;
2031  }
2032 
2033  return TRUE;
2034 }
2035 
2036 static dbus_bool_t
2037 fill_user_info (DBusUserInfo *info,
2038  dbus_uid_t uid,
2039  const DBusString *username,
2040  DBusError *error)
2041 {
2042  const char *username_c;
2043 
2044  /* exactly one of username/uid provided */
2045  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2046  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2047 
2048  info->uid = DBUS_UID_UNSET;
2049  info->primary_gid = DBUS_GID_UNSET;
2050  info->group_ids = NULL;
2051  info->n_group_ids = 0;
2052  info->username = NULL;
2053  info->homedir = NULL;
2054 
2055  if (username != NULL)
2056  username_c = _dbus_string_get_const_data (username);
2057  else
2058  username_c = NULL;
2059 
2060  /* For now assuming that the getpwnam() and getpwuid() flavors
2061  * are always symmetrical, if not we have to add more configure
2062  * checks
2063  */
2064 
2065 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2066  {
2067  struct passwd *p;
2068  int result;
2069  size_t buflen;
2070  char *buf;
2071  struct passwd p_str;
2072 
2073  /* retrieve maximum needed size for buf */
2074  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2075 
2076  /* sysconf actually returns a long, but everything else expects size_t,
2077  * so just recast here.
2078  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2079  */
2080  if ((long) buflen <= 0)
2081  buflen = 1024;
2082 
2083  result = -1;
2084  while (1)
2085  {
2086  buf = dbus_malloc (buflen);
2087  if (buf == NULL)
2088  {
2090  return FALSE;
2091  }
2092 
2093  p = NULL;
2094 #ifdef HAVE_POSIX_GETPWNAM_R
2095  if (uid != DBUS_UID_UNSET)
2096  result = getpwuid_r (uid, &p_str, buf, buflen,
2097  &p);
2098  else
2099  result = getpwnam_r (username_c, &p_str, buf, buflen,
2100  &p);
2101 #else
2102  if (uid != DBUS_UID_UNSET)
2103  p = getpwuid_r (uid, &p_str, buf, buflen);
2104  else
2105  p = getpwnam_r (username_c, &p_str, buf, buflen);
2106  result = 0;
2107 #endif /* !HAVE_POSIX_GETPWNAM_R */
2108  //Try a bigger buffer if ERANGE was returned
2109  if (result == ERANGE && buflen < 512 * 1024)
2110  {
2111  dbus_free (buf);
2112  buflen *= 2;
2113  }
2114  else
2115  {
2116  break;
2117  }
2118  }
2119  if (result == 0 && p == &p_str)
2120  {
2121  if (!fill_user_info_from_passwd (p, info, error))
2122  {
2123  dbus_free (buf);
2124  return FALSE;
2125  }
2126  dbus_free (buf);
2127  }
2128  else
2129  {
2130  dbus_set_error (error, _dbus_error_from_errno (errno),
2131  "User \"%s\" unknown or no memory to allocate password entry\n",
2132  username_c ? username_c : "???");
2133  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2134  dbus_free (buf);
2135  return FALSE;
2136  }
2137  }
2138 #else /* ! HAVE_GETPWNAM_R */
2139  {
2140  /* I guess we're screwed on thread safety here */
2141  struct passwd *p;
2142 
2143  if (uid != DBUS_UID_UNSET)
2144  p = getpwuid (uid);
2145  else
2146  p = getpwnam (username_c);
2147 
2148  if (p != NULL)
2149  {
2150  if (!fill_user_info_from_passwd (p, info, error))
2151  {
2152  return FALSE;
2153  }
2154  }
2155  else
2156  {
2157  dbus_set_error (error, _dbus_error_from_errno (errno),
2158  "User \"%s\" unknown or no memory to allocate password entry\n",
2159  username_c ? username_c : "???");
2160  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2161  return FALSE;
2162  }
2163  }
2164 #endif /* ! HAVE_GETPWNAM_R */
2165 
2166  /* Fill this in so we can use it to get groups */
2167  username_c = info->username;
2168 
2169 #ifdef HAVE_GETGROUPLIST
2170  {
2171  gid_t *buf;
2172  int buf_count;
2173  int i;
2174  int initial_buf_count;
2175 
2176  initial_buf_count = 17;
2177  buf_count = initial_buf_count;
2178  buf = dbus_new (gid_t, buf_count);
2179  if (buf == NULL)
2180  {
2182  goto failed;
2183  }
2184 
2185  if (getgrouplist (username_c,
2186  info->primary_gid,
2187  buf, &buf_count) < 0)
2188  {
2189  gid_t *new;
2190  /* Presumed cause of negative return code: buf has insufficient
2191  entries to hold the entire group list. The Linux behavior in this
2192  case is to pass back the actual number of groups in buf_count, but
2193  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2194  So as a hack, try to help out a bit by guessing a larger
2195  number of groups, within reason.. might still fail, of course,
2196  but we can at least print a more informative message. I looked up
2197  the "right way" to do this by downloading Apple's own source code
2198  for the "id" command, and it turns out that they use an
2199  undocumented library function getgrouplist_2 (!) which is not
2200  declared in any header in /usr/include (!!). That did not seem
2201  like the way to go here.
2202  */
2203  if (buf_count == initial_buf_count)
2204  {
2205  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2206  }
2207  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2208  if (new == NULL)
2209  {
2211  dbus_free (buf);
2212  goto failed;
2213  }
2214 
2215  buf = new;
2216 
2217  errno = 0;
2218  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2219  {
2220  if (errno == 0)
2221  {
2222  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2223  username_c, buf_count, buf_count);
2224  }
2225  else
2226  {
2227  dbus_set_error (error,
2228  _dbus_error_from_errno (errno),
2229  "Failed to get groups for username \"%s\" primary GID "
2230  DBUS_GID_FORMAT ": %s\n",
2231  username_c, info->primary_gid,
2232  _dbus_strerror (errno));
2233  dbus_free (buf);
2234  goto failed;
2235  }
2236  }
2237  }
2238 
2239  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2240  if (info->group_ids == NULL)
2241  {
2243  dbus_free (buf);
2244  goto failed;
2245  }
2246 
2247  for (i = 0; i < buf_count; ++i)
2248  info->group_ids[i] = buf[i];
2249 
2250  info->n_group_ids = buf_count;
2251 
2252  dbus_free (buf);
2253  }
2254 #else /* HAVE_GETGROUPLIST */
2255  {
2256  /* We just get the one group ID */
2257  info->group_ids = dbus_new (dbus_gid_t, 1);
2258  if (info->group_ids == NULL)
2259  {
2261  goto failed;
2262  }
2263 
2264  info->n_group_ids = 1;
2265 
2266  (info->group_ids)[0] = info->primary_gid;
2267  }
2268 #endif /* HAVE_GETGROUPLIST */
2269 
2270  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2271 
2272  return TRUE;
2273 
2274  failed:
2275  _DBUS_ASSERT_ERROR_IS_SET (error);
2276  return FALSE;
2277 }
2278 
2289  const DBusString *username,
2290  DBusError *error)
2291 {
2292  return fill_user_info (info, DBUS_UID_UNSET,
2293  username, error);
2294 }
2295 
2306  dbus_uid_t uid,
2307  DBusError *error)
2308 {
2309  return fill_user_info (info, uid,
2310  NULL, error);
2311 }
2312 
2322 {
2323  /* The POSIX spec certainly doesn't promise this, but
2324  * we need these assertions to fail as soon as we're wrong about
2325  * it so we can do the porting fixups
2326  */
2327  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2328  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2329  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2330 
2331  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2332  return FALSE;
2333  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2334  return FALSE;
2335 
2336  return TRUE;
2337 }
2338 
2352 {
2353  return _dbus_string_append_uint (str,
2354  _dbus_geteuid ());
2355 }
2356 
2361 dbus_pid_t
2363 {
2364  return getpid ();
2365 }
2366 
2370 dbus_uid_t
2372 {
2373  return getuid ();
2374 }
2375 
2379 dbus_uid_t
2381 {
2382  return geteuid ();
2383 }
2384 
2391 unsigned long
2393 {
2394  return getpid ();
2395 }
2396 
2405 _dbus_parse_uid (const DBusString *uid_str,
2406  dbus_uid_t *uid)
2407 {
2408  int end;
2409  long val;
2410 
2411  if (_dbus_string_get_length (uid_str) == 0)
2412  {
2413  _dbus_verbose ("UID string was zero length\n");
2414  return FALSE;
2415  }
2416 
2417  val = -1;
2418  end = 0;
2419  if (!_dbus_string_parse_int (uid_str, 0, &val,
2420  &end))
2421  {
2422  _dbus_verbose ("could not parse string as a UID\n");
2423  return FALSE;
2424  }
2425 
2426  if (end != _dbus_string_get_length (uid_str))
2427  {
2428  _dbus_verbose ("string contained trailing stuff after UID\n");
2429  return FALSE;
2430  }
2431 
2432  *uid = val;
2433 
2434  return TRUE;
2435 }
2436 
2437 #if !DBUS_USE_SYNC
2438 /* To be thread-safe by default on platforms that don't necessarily have
2439  * atomic operations (notably Debian armel, which is armv4t), we must
2440  * use a mutex that can be initialized statically, like this.
2441  * GLib >= 2.32 uses a similar system.
2442  */
2443 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2444 #endif
2445 
2452 dbus_int32_t
2454 {
2455 #if DBUS_USE_SYNC
2456  return __sync_add_and_fetch(&atomic->value, 1)-1;
2457 #else
2458  dbus_int32_t res;
2459 
2460  pthread_mutex_lock (&atomic_mutex);
2461  res = atomic->value;
2462  atomic->value += 1;
2463  pthread_mutex_unlock (&atomic_mutex);
2464 
2465  return res;
2466 #endif
2467 }
2468 
2475 dbus_int32_t
2477 {
2478 #if DBUS_USE_SYNC
2479  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2480 #else
2481  dbus_int32_t res;
2482 
2483  pthread_mutex_lock (&atomic_mutex);
2484  res = atomic->value;
2485  atomic->value -= 1;
2486  pthread_mutex_unlock (&atomic_mutex);
2487 
2488  return res;
2489 #endif
2490 }
2491 
2499 dbus_int32_t
2501 {
2502 #if DBUS_USE_SYNC
2503  __sync_synchronize ();
2504  return atomic->value;
2505 #else
2506  dbus_int32_t res;
2507 
2508  pthread_mutex_lock (&atomic_mutex);
2509  res = atomic->value;
2510  pthread_mutex_unlock (&atomic_mutex);
2511 
2512  return res;
2513 #endif
2514 }
2515 
2524 int
2526  int n_fds,
2527  int timeout_milliseconds)
2528 {
2529 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2530  /* This big thing is a constant expression and should get optimized
2531  * out of existence. So it's more robust than a configure check at
2532  * no cost.
2533  */
2534  if (_DBUS_POLLIN == POLLIN &&
2535  _DBUS_POLLPRI == POLLPRI &&
2536  _DBUS_POLLOUT == POLLOUT &&
2537  _DBUS_POLLERR == POLLERR &&
2538  _DBUS_POLLHUP == POLLHUP &&
2539  _DBUS_POLLNVAL == POLLNVAL &&
2540  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2541  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2542  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2543  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2544  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2545  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2546  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2547  {
2548  return poll ((struct pollfd*) fds,
2549  n_fds,
2550  timeout_milliseconds);
2551  }
2552  else
2553  {
2554  /* We have to convert the DBusPollFD to an array of
2555  * struct pollfd, poll, and convert back.
2556  */
2557  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2558  return -1;
2559  }
2560 #else /* ! HAVE_POLL */
2561 
2562  fd_set read_set, write_set, err_set;
2563  int max_fd = 0;
2564  int i;
2565  struct timeval tv;
2566  int ready;
2567 
2568  FD_ZERO (&read_set);
2569  FD_ZERO (&write_set);
2570  FD_ZERO (&err_set);
2571 
2572  for (i = 0; i < n_fds; i++)
2573  {
2574  DBusPollFD *fdp = &fds[i];
2575 
2576  if (fdp->events & _DBUS_POLLIN)
2577  FD_SET (fdp->fd, &read_set);
2578 
2579  if (fdp->events & _DBUS_POLLOUT)
2580  FD_SET (fdp->fd, &write_set);
2581 
2582  FD_SET (fdp->fd, &err_set);
2583 
2584  max_fd = MAX (max_fd, fdp->fd);
2585  }
2586 
2587  tv.tv_sec = timeout_milliseconds / 1000;
2588  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2589 
2590  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2591  timeout_milliseconds < 0 ? NULL : &tv);
2592 
2593  if (ready > 0)
2594  {
2595  for (i = 0; i < n_fds; i++)
2596  {
2597  DBusPollFD *fdp = &fds[i];
2598 
2599  fdp->revents = 0;
2600 
2601  if (FD_ISSET (fdp->fd, &read_set))
2602  fdp->revents |= _DBUS_POLLIN;
2603 
2604  if (FD_ISSET (fdp->fd, &write_set))
2605  fdp->revents |= _DBUS_POLLOUT;
2606 
2607  if (FD_ISSET (fdp->fd, &err_set))
2608  fdp->revents |= _DBUS_POLLERR;
2609  }
2610  }
2611 
2612  return ready;
2613 #endif
2614 }
2615 
2623 void
2625  long *tv_usec)
2626 {
2627 #ifdef HAVE_MONOTONIC_CLOCK
2628  struct timespec ts;
2629  clock_gettime (CLOCK_MONOTONIC, &ts);
2630 
2631  if (tv_sec)
2632  *tv_sec = ts.tv_sec;
2633  if (tv_usec)
2634  *tv_usec = ts.tv_nsec / 1000;
2635 #else
2636  struct timeval t;
2637 
2638  gettimeofday (&t, NULL);
2639 
2640  if (tv_sec)
2641  *tv_sec = t.tv_sec;
2642  if (tv_usec)
2643  *tv_usec = t.tv_usec;
2644 #endif
2645 }
2646 
2654 void
2655 _dbus_get_real_time (long *tv_sec,
2656  long *tv_usec)
2657 {
2658  struct timeval t;
2659 
2660  gettimeofday (&t, NULL);
2661 
2662  if (tv_sec)
2663  *tv_sec = t.tv_sec;
2664  if (tv_usec)
2665  *tv_usec = t.tv_usec;
2666 }
2667 
2678  DBusError *error)
2679 {
2680  const char *filename_c;
2681 
2682  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2683 
2684  filename_c = _dbus_string_get_const_data (filename);
2685 
2686  if (mkdir (filename_c, 0700) < 0)
2687  {
2688  if (errno == EEXIST)
2689  return TRUE;
2690 
2692  "Failed to create directory %s: %s\n",
2693  filename_c, _dbus_strerror (errno));
2694  return FALSE;
2695  }
2696  else
2697  return TRUE;
2698 }
2699 
2712  const DBusString *next_component)
2713 {
2714  dbus_bool_t dir_ends_in_slash;
2715  dbus_bool_t file_starts_with_slash;
2716 
2717  if (_dbus_string_get_length (dir) == 0 ||
2718  _dbus_string_get_length (next_component) == 0)
2719  return TRUE;
2720 
2721  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2722  _dbus_string_get_length (dir) - 1);
2723 
2724  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2725 
2726  if (dir_ends_in_slash && file_starts_with_slash)
2727  {
2728  _dbus_string_shorten (dir, 1);
2729  }
2730  else if (!(dir_ends_in_slash || file_starts_with_slash))
2731  {
2732  if (!_dbus_string_append_byte (dir, '/'))
2733  return FALSE;
2734  }
2735 
2736  return _dbus_string_copy (next_component, 0, dir,
2737  _dbus_string_get_length (dir));
2738 }
2739 
2741 #define NANOSECONDS_PER_SECOND 1000000000
2742 
2743 #define MICROSECONDS_PER_SECOND 1000000
2744 
2745 #define MILLISECONDS_PER_SECOND 1000
2746 
2747 #define NANOSECONDS_PER_MILLISECOND 1000000
2748 
2749 #define MICROSECONDS_PER_MILLISECOND 1000
2750 
2755 void
2756 _dbus_sleep_milliseconds (int milliseconds)
2757 {
2758 #ifdef HAVE_NANOSLEEP
2759  struct timespec req;
2760  struct timespec rem;
2761 
2762  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2763  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2764  rem.tv_sec = 0;
2765  rem.tv_nsec = 0;
2766 
2767  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2768  req = rem;
2769 #elif defined (HAVE_USLEEP)
2770  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2771 #else /* ! HAVE_USLEEP */
2772  sleep (MAX (milliseconds / 1000, 1));
2773 #endif
2774 }
2775 
2776 static dbus_bool_t
2777 _dbus_generate_pseudorandom_bytes (DBusString *str,
2778  int n_bytes)
2779 {
2780  int old_len;
2781  char *p;
2782 
2783  old_len = _dbus_string_get_length (str);
2784 
2785  if (!_dbus_string_lengthen (str, n_bytes))
2786  return FALSE;
2787 
2788  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2789 
2791 
2792  return TRUE;
2793 }
2794 
2805  int n_bytes)
2806 {
2807  int old_len;
2808  int fd;
2809 
2810  /* FALSE return means "no memory", if it could
2811  * mean something else then we'd need to return
2812  * a DBusError. So we always fall back to pseudorandom
2813  * if the I/O fails.
2814  */
2815 
2816  old_len = _dbus_string_get_length (str);
2817  fd = -1;
2818 
2819  /* note, urandom on linux will fall back to pseudorandom */
2820  fd = open ("/dev/urandom", O_RDONLY);
2821  if (fd < 0)
2822  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2823 
2824  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2825 
2826  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2827  {
2828  _dbus_close (fd, NULL);
2829  _dbus_string_set_length (str, old_len);
2830  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2831  }
2832 
2833  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2834  n_bytes);
2835 
2836  _dbus_close (fd, NULL);
2837 
2838  return TRUE;
2839 }
2840 
2846 void
2847 _dbus_exit (int code)
2848 {
2849  _exit (code);
2850 }
2851 
2860 const char*
2861 _dbus_strerror (int error_number)
2862 {
2863  const char *msg;
2864 
2865  msg = strerror (error_number);
2866  if (msg == NULL)
2867  msg = "unknown";
2868 
2869  return msg;
2870 }
2871 
2875 void
2877 {
2878  signal (SIGPIPE, SIG_IGN);
2879 }
2880 
2888 void
2890 {
2891  int val;
2892 
2893  val = fcntl (fd, F_GETFD, 0);
2894 
2895  if (val < 0)
2896  return;
2897 
2898  val |= FD_CLOEXEC;
2899 
2900  fcntl (fd, F_SETFD, val);
2901 }
2902 
2911 _dbus_close (int fd,
2912  DBusError *error)
2913 {
2914  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2915 
2916  again:
2917  if (close (fd) < 0)
2918  {
2919  if (errno == EINTR)
2920  goto again;
2921 
2922  dbus_set_error (error, _dbus_error_from_errno (errno),
2923  "Could not close fd %d", fd);
2924  return FALSE;
2925  }
2926 
2927  return TRUE;
2928 }
2929 
2938 int
2939 _dbus_dup(int fd,
2940  DBusError *error)
2941 {
2942  int new_fd;
2943 
2944 #ifdef F_DUPFD_CLOEXEC
2945  dbus_bool_t cloexec_done;
2946 
2947  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2948  cloexec_done = new_fd >= 0;
2949 
2950  if (new_fd < 0 && errno == EINVAL)
2951 #endif
2952  {
2953  new_fd = fcntl(fd, F_DUPFD, 3);
2954  }
2955 
2956  if (new_fd < 0) {
2957 
2958  dbus_set_error (error, _dbus_error_from_errno (errno),
2959  "Could not duplicate fd %d", fd);
2960  return -1;
2961  }
2962 
2963 #ifdef F_DUPFD_CLOEXEC
2964  if (!cloexec_done)
2965 #endif
2966  {
2968  }
2969 
2970  return new_fd;
2971 }
2972 
2981 _dbus_set_fd_nonblocking (int fd,
2982  DBusError *error)
2983 {
2984  int val;
2985 
2986  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2987 
2988  val = fcntl (fd, F_GETFL, 0);
2989  if (val < 0)
2990  {
2991  dbus_set_error (error, _dbus_error_from_errno (errno),
2992  "Failed to get flags from file descriptor %d: %s",
2993  fd, _dbus_strerror (errno));
2994  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2995  _dbus_strerror (errno));
2996  return FALSE;
2997  }
2998 
2999  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3000  {
3001  dbus_set_error (error, _dbus_error_from_errno (errno),
3002  "Failed to set nonblocking flag of file descriptor %d: %s",
3003  fd, _dbus_strerror (errno));
3004  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3005  fd, _dbus_strerror (errno));
3006 
3007  return FALSE;
3008  }
3009 
3010  return TRUE;
3011 }
3012 
3018 void
3020 {
3021 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3022  void *bt[500];
3023  int bt_size;
3024  int i;
3025  char **syms;
3026 
3027  bt_size = backtrace (bt, 500);
3028 
3029  syms = backtrace_symbols (bt, bt_size);
3030 
3031  i = 0;
3032  while (i < bt_size)
3033  {
3034  /* don't use dbus_warn since it can _dbus_abort() */
3035  fprintf (stderr, " %s\n", syms[i]);
3036  ++i;
3037  }
3038  fflush (stderr);
3039 
3040  free (syms);
3041 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3042  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3043 #else
3044  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3045 #endif
3046 }
3047 
3062  int *fd2,
3063  dbus_bool_t blocking,
3064  DBusError *error)
3065 {
3066 #ifdef HAVE_SOCKETPAIR
3067  int fds[2];
3068  int retval;
3069 
3070 #ifdef SOCK_CLOEXEC
3071  dbus_bool_t cloexec_done;
3072 
3073  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3074  cloexec_done = retval >= 0;
3075 
3076  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3077 #endif
3078  {
3079  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3080  }
3081 
3082  if (retval < 0)
3083  {
3084  dbus_set_error (error, _dbus_error_from_errno (errno),
3085  "Could not create full-duplex pipe");
3086  return FALSE;
3087  }
3088 
3089  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3090 
3091 #ifdef SOCK_CLOEXEC
3092  if (!cloexec_done)
3093 #endif
3094  {
3095  _dbus_fd_set_close_on_exec (fds[0]);
3096  _dbus_fd_set_close_on_exec (fds[1]);
3097  }
3098 
3099  if (!blocking &&
3100  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3101  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3102  {
3103  dbus_set_error (error, _dbus_error_from_errno (errno),
3104  "Could not set full-duplex pipe nonblocking");
3105 
3106  _dbus_close (fds[0], NULL);
3107  _dbus_close (fds[1], NULL);
3108 
3109  return FALSE;
3110  }
3111 
3112  *fd1 = fds[0];
3113  *fd2 = fds[1];
3114 
3115  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3116  *fd1, *fd2);
3117 
3118  return TRUE;
3119 #else
3120  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3122  "_dbus_full_duplex_pipe() not implemented on this OS");
3123  return FALSE;
3124 #endif
3125 }
3126 
3135 int
3137  va_list args)
3138 {
3139  char static_buf[1024];
3140  int bufsize = sizeof (static_buf);
3141  int len;
3142  va_list args_copy;
3143 
3144  DBUS_VA_COPY (args_copy, args);
3145  len = vsnprintf (static_buf, bufsize, format, args_copy);
3146  va_end (args_copy);
3147 
3148  /* If vsnprintf() returned non-negative, then either the string fits in
3149  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3150  * returns the number of characters that were needed, or this OS returns the
3151  * truncated length.
3152  *
3153  * We ignore the possibility that snprintf might just ignore the length and
3154  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3155  * If your libc is really that bad, come back when you have a better one. */
3156  if (len == bufsize)
3157  {
3158  /* This could be the truncated length (Tru64 and IRIX have this bug),
3159  * or the real length could be coincidentally the same. Which is it?
3160  * If vsnprintf returns the truncated length, we'll go to the slow
3161  * path. */
3162  DBUS_VA_COPY (args_copy, args);
3163 
3164  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3165  len = -1;
3166 
3167  va_end (args_copy);
3168  }
3169 
3170  /* If vsnprintf() returned negative, we have to do more work.
3171  * HP-UX returns negative. */
3172  while (len < 0)
3173  {
3174  char *buf;
3175 
3176  bufsize *= 2;
3177 
3178  buf = dbus_malloc (bufsize);
3179 
3180  if (buf == NULL)
3181  return -1;
3182 
3183  DBUS_VA_COPY (args_copy, args);
3184  len = vsnprintf (buf, bufsize, format, args_copy);
3185  va_end (args_copy);
3186 
3187  dbus_free (buf);
3188 
3189  /* If the reported length is exactly the buffer size, round up to the
3190  * next size, in case vsnprintf has been returning the truncated
3191  * length */
3192  if (len == bufsize)
3193  len = -1;
3194  }
3195 
3196  return len;
3197 }
3198 
3205 const char*
3207 {
3208  /* Protected by _DBUS_LOCK_sysdeps */
3209  static const char* tmpdir = NULL;
3210 
3211  if (!_DBUS_LOCK (sysdeps))
3212  return NULL;
3213 
3214  if (tmpdir == NULL)
3215  {
3216  /* TMPDIR is what glibc uses, then
3217  * glibc falls back to the P_tmpdir macro which
3218  * just expands to "/tmp"
3219  */
3220  if (tmpdir == NULL)
3221  tmpdir = getenv("TMPDIR");
3222 
3223  /* These two env variables are probably
3224  * broken, but maybe some OS uses them?
3225  */
3226  if (tmpdir == NULL)
3227  tmpdir = getenv("TMP");
3228  if (tmpdir == NULL)
3229  tmpdir = getenv("TEMP");
3230 
3231  /* And this is the sane fallback. */
3232  if (tmpdir == NULL)
3233  tmpdir = "/tmp";
3234  }
3235 
3236  _DBUS_UNLOCK (sysdeps);
3237 
3238  _dbus_assert(tmpdir != NULL);
3239 
3240  return tmpdir;
3241 }
3242 
3243 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3244 
3263 static dbus_bool_t
3264 _read_subprocess_line_argv (const char *progpath,
3265  dbus_bool_t path_fallback,
3266  char * const *argv,
3267  DBusString *result,
3268  DBusError *error)
3269 {
3270  int result_pipe[2] = { -1, -1 };
3271  int errors_pipe[2] = { -1, -1 };
3272  pid_t pid;
3273  int ret;
3274  int status;
3275  int orig_len;
3276 
3277  dbus_bool_t retval;
3278  sigset_t new_set, old_set;
3279 
3280  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3281  retval = FALSE;
3282 
3283  /* We need to block any existing handlers for SIGCHLD temporarily; they
3284  * will cause waitpid() below to fail.
3285  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3286  */
3287  sigemptyset (&new_set);
3288  sigaddset (&new_set, SIGCHLD);
3289  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3290 
3291  orig_len = _dbus_string_get_length (result);
3292 
3293 #define READ_END 0
3294 #define WRITE_END 1
3295  if (pipe (result_pipe) < 0)
3296  {
3297  dbus_set_error (error, _dbus_error_from_errno (errno),
3298  "Failed to create a pipe to call %s: %s",
3299  progpath, _dbus_strerror (errno));
3300  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3301  progpath, _dbus_strerror (errno));
3302  goto out;
3303  }
3304  if (pipe (errors_pipe) < 0)
3305  {
3306  dbus_set_error (error, _dbus_error_from_errno (errno),
3307  "Failed to create a pipe to call %s: %s",
3308  progpath, _dbus_strerror (errno));
3309  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3310  progpath, _dbus_strerror (errno));
3311  goto out;
3312  }
3313 
3314  pid = fork ();
3315  if (pid < 0)
3316  {
3317  dbus_set_error (error, _dbus_error_from_errno (errno),
3318  "Failed to fork() to call %s: %s",
3319  progpath, _dbus_strerror (errno));
3320  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3321  progpath, _dbus_strerror (errno));
3322  goto out;
3323  }
3324 
3325  if (pid == 0)
3326  {
3327  /* child process */
3328  int fd;
3329 
3330  fd = open ("/dev/null", O_RDWR);
3331  if (fd == -1)
3332  /* huh?! can't open /dev/null? */
3333  _exit (1);
3334 
3335  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3336 
3337  /* set-up stdXXX */
3338  close (result_pipe[READ_END]);
3339  close (errors_pipe[READ_END]);
3340 
3341  if (dup2 (fd, 0) == -1) /* setup stdin */
3342  _exit (1);
3343  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3344  _exit (1);
3345  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3346  _exit (1);
3347 
3348  _dbus_close_all ();
3349 
3350  sigprocmask (SIG_SETMASK, &old_set, NULL);
3351 
3352  /* If it looks fully-qualified, try execv first */
3353  if (progpath[0] == '/')
3354  {
3355  execv (progpath, argv);
3356  /* Ok, that failed. Now if path_fallback is given, let's
3357  * try unqualified. This is mostly a hack to work
3358  * around systems which ship dbus-launch in /usr/bin
3359  * but everything else in /bin (because dbus-launch
3360  * depends on X11).
3361  */
3362  if (path_fallback)
3363  /* We must have a slash, because we checked above */
3364  execvp (strrchr (progpath, '/')+1, argv);
3365  }
3366  else
3367  execvp (progpath, argv);
3368 
3369  /* still nothing, we failed */
3370  _exit (1);
3371  }
3372 
3373  /* parent process */
3374  close (result_pipe[WRITE_END]);
3375  close (errors_pipe[WRITE_END]);
3376  result_pipe[WRITE_END] = -1;
3377  errors_pipe[WRITE_END] = -1;
3378 
3379  ret = 0;
3380  do
3381  {
3382  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3383  }
3384  while (ret > 0);
3385 
3386  /* reap the child process to avoid it lingering as zombie */
3387  do
3388  {
3389  ret = waitpid (pid, &status, 0);
3390  }
3391  while (ret == -1 && errno == EINTR);
3392 
3393  /* We succeeded if the process exited with status 0 and
3394  anything was read */
3395  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3396  {
3397  /* The process ended with error */
3398  DBusString error_message;
3399  if (!_dbus_string_init (&error_message))
3400  {
3401  _DBUS_SET_OOM (error);
3402  goto out;
3403  }
3404 
3405  ret = 0;
3406  do
3407  {
3408  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3409  }
3410  while (ret > 0);
3411 
3412  _dbus_string_set_length (result, orig_len);
3413  if (_dbus_string_get_length (&error_message) > 0)
3415  "%s terminated abnormally with the following error: %s",
3416  progpath, _dbus_string_get_data (&error_message));
3417  else
3419  "%s terminated abnormally without any error message",
3420  progpath);
3421  goto out;
3422  }
3423 
3424  retval = TRUE;
3425 
3426  out:
3427  sigprocmask (SIG_SETMASK, &old_set, NULL);
3428 
3429  if (retval)
3430  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3431  else
3432  _DBUS_ASSERT_ERROR_IS_SET (error);
3433 
3434  if (result_pipe[0] != -1)
3435  close (result_pipe[0]);
3436  if (result_pipe[1] != -1)
3437  close (result_pipe[1]);
3438  if (errors_pipe[0] != -1)
3439  close (errors_pipe[0]);
3440  if (errors_pipe[1] != -1)
3441  close (errors_pipe[1]);
3442 
3443  return retval;
3444 }
3445 #endif
3446 
3460 _dbus_get_autolaunch_address (const char *scope,
3461  DBusString *address,
3462  DBusError *error)
3463 {
3464 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3465  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3466  * but that's done elsewhere, and if it worked, this function wouldn't
3467  * be called.) */
3468  const char *display;
3469  char *argv[6];
3470  int i;
3471  DBusString uuid;
3472  dbus_bool_t retval;
3473 
3474  if (_dbus_check_setuid ())
3475  {
3477  "Unable to autolaunch when setuid");
3478  return FALSE;
3479  }
3480 
3481  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3482  retval = FALSE;
3483 
3484  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3485  * dbus-launch-x11 is just going to fail. Rather than trying to
3486  * run it, we might as well bail out early with a nice error. */
3487  display = _dbus_getenv ("DISPLAY");
3488 
3489  if (display == NULL || display[0] == '\0')
3490  {
3492  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3493  return FALSE;
3494  }
3495 
3496  if (!_dbus_string_init (&uuid))
3497  {
3498  _DBUS_SET_OOM (error);
3499  return FALSE;
3500  }
3501 
3503  {
3504  _DBUS_SET_OOM (error);
3505  goto out;
3506  }
3507 
3508  i = 0;
3509 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3510  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3511  argv[i] = TEST_BUS_LAUNCH_BINARY;
3512  else
3513 #endif
3514  argv[i] = DBUS_BINDIR "/dbus-launch";
3515  ++i;
3516  argv[i] = "--autolaunch";
3517  ++i;
3518  argv[i] = _dbus_string_get_data (&uuid);
3519  ++i;
3520  argv[i] = "--binary-syntax";
3521  ++i;
3522  argv[i] = "--close-stderr";
3523  ++i;
3524  argv[i] = NULL;
3525  ++i;
3526 
3527  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3528 
3529  retval = _read_subprocess_line_argv (argv[0],
3530  TRUE,
3531  argv, address, error);
3532 
3533  out:
3534  _dbus_string_free (&uuid);
3535  return retval;
3536 #else
3538  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3539  "set your DBUS_SESSION_BUS_ADDRESS instead");
3540  return FALSE;
3541 #endif
3542 }
3543 
3564  dbus_bool_t create_if_not_found,
3565  DBusError *error)
3566 {
3567  DBusString filename;
3568  dbus_bool_t b;
3569 
3570  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3571 
3572  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3573  if (b)
3574  return TRUE;
3575 
3576  dbus_error_free (error);
3577 
3578  /* Fallback to the system machine ID */
3579  _dbus_string_init_const (&filename, "/etc/machine-id");
3580  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3581 }
3582 
3592  const char *launchd_env_var,
3593  DBusError *error)
3594 {
3595 #ifdef DBUS_ENABLE_LAUNCHD
3596  char *argv[4];
3597  int i;
3598 
3599  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3600 
3601  if (_dbus_check_setuid ())
3602  {
3604  "Unable to find launchd socket when setuid");
3605  return FALSE;
3606  }
3607 
3608  i = 0;
3609  argv[i] = "launchctl";
3610  ++i;
3611  argv[i] = "getenv";
3612  ++i;
3613  argv[i] = (char*)launchd_env_var;
3614  ++i;
3615  argv[i] = NULL;
3616  ++i;
3617 
3618  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3619 
3620  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3621  {
3622  return FALSE;
3623  }
3624 
3625  /* no error, but no result either */
3626  if (_dbus_string_get_length(socket_path) == 0)
3627  {
3628  return FALSE;
3629  }
3630 
3631  /* strip the carriage-return */
3632  _dbus_string_shorten(socket_path, 1);
3633  return TRUE;
3634 #else /* DBUS_ENABLE_LAUNCHD */
3636  "can't lookup socket from launchd; launchd support not compiled in");
3637  return FALSE;
3638 #endif
3639 }
3640 
3641 #ifdef DBUS_ENABLE_LAUNCHD
3642 static dbus_bool_t
3643 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3644 {
3645  dbus_bool_t valid_socket;
3646  DBusString socket_path;
3647 
3648  if (_dbus_check_setuid ())
3649  {
3651  "Unable to find launchd socket when setuid");
3652  return FALSE;
3653  }
3654 
3655  if (!_dbus_string_init (&socket_path))
3656  {
3657  _DBUS_SET_OOM (error);
3658  return FALSE;
3659  }
3660 
3661  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3662 
3663  if (dbus_error_is_set(error))
3664  {
3665  _dbus_string_free(&socket_path);
3666  return FALSE;
3667  }
3668 
3669  if (!valid_socket)
3670  {
3671  dbus_set_error(error, "no socket path",
3672  "launchd did not provide a socket path, "
3673  "verify that org.freedesktop.dbus-session.plist is loaded!");
3674  _dbus_string_free(&socket_path);
3675  return FALSE;
3676  }
3677  if (!_dbus_string_append (address, "unix:path="))
3678  {
3679  _DBUS_SET_OOM (error);
3680  _dbus_string_free(&socket_path);
3681  return FALSE;
3682  }
3683  if (!_dbus_string_copy (&socket_path, 0, address,
3684  _dbus_string_get_length (address)))
3685  {
3686  _DBUS_SET_OOM (error);
3687  _dbus_string_free(&socket_path);
3688  return FALSE;
3689  }
3690 
3691  _dbus_string_free(&socket_path);
3692  return TRUE;
3693 }
3694 #endif
3695 
3717  DBusString *address,
3718  DBusError *error)
3719 {
3720 #ifdef DBUS_ENABLE_LAUNCHD
3721  *supported = TRUE;
3722  return _dbus_lookup_session_address_launchd (address, error);
3723 #else
3724  /* On non-Mac Unix platforms, if the session address isn't already
3725  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3726  * fall back to the autolaunch: global default; see
3727  * init_session_address in dbus/dbus-bus.c. */
3728  *supported = FALSE;
3729  return TRUE;
3730 #endif
3731 }
3732 
3740 void
3742 {
3744 }
3745 
3761  DBusCredentials *credentials)
3762 {
3763  DBusString homedir;
3764  DBusString dotdir;
3765  dbus_uid_t uid;
3766 
3767  _dbus_assert (credentials != NULL);
3769 
3770  if (!_dbus_string_init (&homedir))
3771  return FALSE;
3772 
3773  uid = _dbus_credentials_get_unix_uid (credentials);
3774  _dbus_assert (uid != DBUS_UID_UNSET);
3775 
3776  if (!_dbus_homedir_from_uid (uid, &homedir))
3777  goto failed;
3778 
3779 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3780  {
3781  const char *override;
3782 
3783  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3784  if (override != NULL && *override != '\0')
3785  {
3786  _dbus_string_set_length (&homedir, 0);
3787  if (!_dbus_string_append (&homedir, override))
3788  goto failed;
3789 
3790  _dbus_verbose ("Using fake homedir for testing: %s\n",
3791  _dbus_string_get_const_data (&homedir));
3792  }
3793  else
3794  {
3795  /* Not strictly thread-safe, but if we fail at thread-safety here,
3796  * the worst that will happen is some extra warnings. */
3797  static dbus_bool_t already_warned = FALSE;
3798  if (!already_warned)
3799  {
3800  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3801  already_warned = TRUE;
3802  }
3803  }
3804  }
3805 #endif
3806 
3807  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3808  if (!_dbus_concat_dir_and_file (&homedir,
3809  &dotdir))
3810  goto failed;
3811 
3812  if (!_dbus_string_copy (&homedir, 0,
3813  directory, _dbus_string_get_length (directory))) {
3814  goto failed;
3815  }
3816 
3817  _dbus_string_free (&homedir);
3818  return TRUE;
3819 
3820  failed:
3821  _dbus_string_free (&homedir);
3822  return FALSE;
3823 }
3824 
3825 //PENDING(kdab) docs
3827 _dbus_daemon_publish_session_bus_address (const char* addr,
3828  const char *scope)
3829 {
3830  return TRUE;
3831 }
3832 
3833 //PENDING(kdab) docs
3834 void
3835 _dbus_daemon_unpublish_session_bus_address (void)
3836 {
3837 
3838 }
3839 
3848 {
3849  return errno == EAGAIN || errno == EWOULDBLOCK;
3850 }
3851 
3861  DBusError *error)
3862 {
3863  const char *filename_c;
3864 
3865  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3866 
3867  filename_c = _dbus_string_get_const_data (filename);
3868 
3869  if (rmdir (filename_c) != 0)
3870  {
3872  "Failed to remove directory %s: %s\n",
3873  filename_c, _dbus_strerror (errno));
3874  return FALSE;
3875  }
3876 
3877  return TRUE;
3878 }
3879 
3889 
3890 #ifdef SCM_RIGHTS
3891  union {
3892  struct sockaddr sa;
3893  struct sockaddr_storage storage;
3894  struct sockaddr_un un;
3895  } sa_buf;
3896 
3897  socklen_t sa_len = sizeof(sa_buf);
3898 
3899  _DBUS_ZERO(sa_buf);
3900 
3901  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3902  return FALSE;
3903 
3904  return sa_buf.sa.sa_family == AF_UNIX;
3905 
3906 #else
3907  return FALSE;
3908 
3909 #endif
3910 }
3911 
3916 void
3918 {
3919  int maxfds, i;
3920 
3921 #ifdef __linux__
3922  DIR *d;
3923 
3924  /* On Linux we can optimize this a bit if /proc is available. If it
3925  isn't available, fall back to the brute force way. */
3926 
3927  d = opendir ("/proc/self/fd");
3928  if (d)
3929  {
3930  for (;;)
3931  {
3932  struct dirent buf, *de;
3933  int k, fd;
3934  long l;
3935  char *e = NULL;
3936 
3937  k = readdir_r (d, &buf, &de);
3938  if (k != 0 || !de)
3939  break;
3940 
3941  if (de->d_name[0] == '.')
3942  continue;
3943 
3944  errno = 0;
3945  l = strtol (de->d_name, &e, 10);
3946  if (errno != 0 || e == NULL || *e != '\0')
3947  continue;
3948 
3949  fd = (int) l;
3950  if (fd < 3)
3951  continue;
3952 
3953  if (fd == dirfd (d))
3954  continue;
3955 
3956  close (fd);
3957  }
3958 
3959  closedir (d);
3960  return;
3961  }
3962 #endif
3963 
3964  maxfds = sysconf (_SC_OPEN_MAX);
3965 
3966  /* Pick something reasonable if for some reason sysconf says
3967  * unlimited.
3968  */
3969  if (maxfds < 0)
3970  maxfds = 1024;
3971 
3972  /* close all inherited fds */
3973  for (i = 3; i < maxfds; i++)
3974  close (i);
3975 }
3976 
3988 {
3989  /* TODO: get __libc_enable_secure exported from glibc.
3990  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
3991  */
3992 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
3993  {
3994  /* See glibc/include/unistd.h */
3995  extern int __libc_enable_secure;
3996  return __libc_enable_secure;
3997  }
3998 #elif defined(HAVE_ISSETUGID)
3999  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4000  return issetugid ();
4001 #else
4002  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4003  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4004 
4005  /* We call into this function from _dbus_threads_init_platform_specific()
4006  * to make sure these are initialized before we start threading. */
4007  static dbus_bool_t check_setuid_initialised;
4008  static dbus_bool_t is_setuid;
4009 
4010  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4011  {
4012 #ifdef HAVE_GETRESUID
4013  if (getresuid (&ruid, &euid, &suid) != 0 ||
4014  getresgid (&rgid, &egid, &sgid) != 0)
4015 #endif /* HAVE_GETRESUID */
4016  {
4017  suid = ruid = getuid ();
4018  sgid = rgid = getgid ();
4019  euid = geteuid ();
4020  egid = getegid ();
4021  }
4022 
4023  check_setuid_initialised = TRUE;
4024  is_setuid = (ruid != euid || ruid != suid ||
4025  rgid != egid || rgid != sgid);
4026 
4027  }
4028  return is_setuid;
4029 #endif
4030 }
4031 
4041  DBusString *address,
4042  DBusError *error)
4043 {
4044  union {
4045  struct sockaddr sa;
4046  struct sockaddr_storage storage;
4047  struct sockaddr_un un;
4048  struct sockaddr_in ipv4;
4049  struct sockaddr_in6 ipv6;
4050  } socket;
4051  char hostip[INET6_ADDRSTRLEN];
4052  int size = sizeof (socket);
4053 
4054  if (getsockname (fd, &socket.sa, &size))
4055  goto err;
4056 
4057  switch (socket.sa.sa_family)
4058  {
4059  case AF_UNIX:
4060  if (socket.un.sun_path[0]=='\0')
4061  {
4062  if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1])))
4063  return TRUE;
4064  }
4065  else
4066  {
4067  if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path))
4068  return TRUE;
4069  }
4070  break;
4071  case AF_INET:
4072  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4073  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4074  hostip, ntohs (socket.ipv4.sin_port)))
4075  return TRUE;
4076  break;
4077 #ifdef AF_INET6
4078  case AF_INET6:
4079  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4080  if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u",
4081  hostip, ntohs (socket.ipv6.sin6_port)))
4082  return TRUE;
4083  break;
4084 #endif
4085  default:
4086  dbus_set_error (error,
4087  _dbus_error_from_errno (EINVAL),
4088  "Failed to read address from socket: Unknown socket type.");
4089  return FALSE;
4090  }
4091  err:
4092  dbus_set_error (error,
4093  _dbus_error_from_errno (errno),
4094  "Failed to open socket: %s",
4095  _dbus_strerror (errno));
4096  return FALSE;
4097 }
4098 
4099 /* tests in dbus-sysdeps-util.c */