D-Bus  1.6.28
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 
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_WRITEV
63 #include <sys/uio.h>
64 #endif
65 #ifdef HAVE_POLL
66 #include <sys/poll.h>
67 #endif
68 #ifdef HAVE_BACKTRACE
69 #include <execinfo.h>
70 #endif
71 #ifdef HAVE_GETPEERUCRED
72 #include <ucred.h>
73 #endif
74 #ifdef HAVE_ALLOCA_H
75 #include <alloca.h>
76 #endif
77 
78 #ifdef HAVE_ADT
79 #include <bsm/adt.h>
80 #endif
81 
82 #include "sd-daemon.h"
83 
84 #ifndef O_BINARY
85 #define O_BINARY 0
86 #endif
87 
88 #ifndef AI_ADDRCONFIG
89 #define AI_ADDRCONFIG 0
90 #endif
91 
92 #ifndef HAVE_SOCKLEN_T
93 #define socklen_t int
94 #endif
95 
96 #if defined (__sun) || defined (__sun__)
97 /*
98  * CMS_SPACE etc. definitions for Solaris < 10, based on
99  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
100  * via
101  * http://wiki.opencsw.org/porting-faq#toc10
102  *
103  * These are only redefined for Solaris, for now: if your OS needs these too,
104  * please file a bug. (Or preferably, improve your OS so they're not needed.)
105  */
106 
107 # ifndef CMSG_ALIGN
108 # ifdef __sun__
109 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
110 # else
111  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
112 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
113  ~(sizeof (long) - 1))
114 # endif
115 # endif
116 
117 # ifndef CMSG_SPACE
118 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
119  CMSG_ALIGN (len))
120 # endif
121 
122 # ifndef CMSG_LEN
123 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
124 # endif
125 
126 #endif /* Solaris */
127 
128 static dbus_bool_t
129 _dbus_open_socket (int *fd_p,
130  int domain,
131  int type,
132  int protocol,
133  DBusError *error)
134 {
135 #ifdef SOCK_CLOEXEC
136  dbus_bool_t cloexec_done;
137 
138  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
139  cloexec_done = *fd_p >= 0;
140 
141  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
142  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
143 #endif
144  {
145  *fd_p = socket (domain, type, protocol);
146  }
147 
148  if (*fd_p >= 0)
149  {
150 #ifdef SOCK_CLOEXEC
151  if (!cloexec_done)
152 #endif
153  {
155  }
156 
157  _dbus_verbose ("socket fd %d opened\n", *fd_p);
158  return TRUE;
159  }
160  else
161  {
162  dbus_set_error(error,
163  _dbus_error_from_errno (errno),
164  "Failed to open socket: %s",
165  _dbus_strerror (errno));
166  return FALSE;
167  }
168 }
169 
180 static dbus_bool_t
181 _dbus_open_unix_socket (int *fd,
182  DBusError *error)
183 {
184  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
185 }
186 
197  DBusError *error)
198 {
199  return _dbus_close (fd, error);
200 }
201 
211 int
213  DBusString *buffer,
214  int count)
215 {
216  return _dbus_read (fd, buffer, count);
217 }
218 
229 int
231  const DBusString *buffer,
232  int start,
233  int len)
234 {
235 #if HAVE_DECL_MSG_NOSIGNAL
236  const char *data;
237  int bytes_written;
238 
239  data = _dbus_string_get_const_data_len (buffer, start, len);
240 
241  again:
242 
243  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
244 
245  if (bytes_written < 0 && errno == EINTR)
246  goto again;
247 
248  return bytes_written;
249 
250 #else
251  return _dbus_write (fd, buffer, start, len);
252 #endif
253 }
254 
267 int
269  DBusString *buffer,
270  int count,
271  int *fds,
272  int *n_fds) {
273 #ifndef HAVE_UNIX_FD_PASSING
274  int r;
275 
276  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
277  return r;
278 
279  *n_fds = 0;
280  return r;
281 
282 #else
283  int bytes_read;
284  int start;
285  struct msghdr m;
286  struct iovec iov;
287 
288  _dbus_assert (count >= 0);
289  _dbus_assert (*n_fds >= 0);
290 
291  start = _dbus_string_get_length (buffer);
292 
293  if (!_dbus_string_lengthen (buffer, count))
294  {
295  errno = ENOMEM;
296  return -1;
297  }
298 
299  _DBUS_ZERO(iov);
300  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
301  iov.iov_len = count;
302 
303  _DBUS_ZERO(m);
304  m.msg_iov = &iov;
305  m.msg_iovlen = 1;
306 
307  /* Hmm, we have no clue how long the control data will actually be
308  that is queued for us. The least we can do is assume that the
309  caller knows. Hence let's make space for the number of fds that
310  we shall read at max plus the cmsg header. */
311  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
312 
313  /* It's probably safe to assume that systems with SCM_RIGHTS also
314  know alloca() */
315  m.msg_control = alloca(m.msg_controllen);
316  memset(m.msg_control, 0, m.msg_controllen);
317 
318  /* Do not include the padding at the end when we tell the kernel
319  * how much we're willing to receive. This avoids getting
320  * the padding filled with additional fds that we weren't expecting,
321  * if a (potentially malicious) sender included them. (fd.o #83622) */
322  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
323 
324  again:
325 
326  bytes_read = recvmsg(fd, &m, 0
327 #ifdef MSG_CMSG_CLOEXEC
328  |MSG_CMSG_CLOEXEC
329 #endif
330  );
331 
332  if (bytes_read < 0)
333  {
334  if (errno == EINTR)
335  goto again;
336  else
337  {
338  /* put length back (note that this doesn't actually realloc anything) */
339  _dbus_string_set_length (buffer, start);
340  return -1;
341  }
342  }
343  else
344  {
345  struct cmsghdr *cm;
346  dbus_bool_t found = FALSE;
347 
348  if (m.msg_flags & MSG_CTRUNC)
349  {
350  /* Hmm, apparently the control data was truncated. The bad
351  thing is that we might have completely lost a couple of fds
352  without chance to recover them. Hence let's treat this as a
353  serious error. */
354 
355  errno = ENOSPC;
356  _dbus_string_set_length (buffer, start);
357  return -1;
358  }
359 
360  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
361  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
362  {
363  size_t i;
364  int *payload = (int *) CMSG_DATA (cm);
365  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
366  size_t payload_len_fds = payload_len_bytes / sizeof (int);
367  size_t fds_to_use;
368 
369  /* Every non-negative int fits in a size_t without truncation,
370  * and we already know that *n_fds is non-negative, so
371  * casting (size_t) *n_fds is OK */
372  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
373 
374  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
375  {
376  /* The fds in the payload will fit in our buffer */
377  fds_to_use = payload_len_fds;
378  }
379  else
380  {
381  /* Too many fds in the payload. This shouldn't happen
382  * any more because we're setting m.msg_controllen to
383  * the exact number we can accept, but be safe and
384  * truncate. */
385  fds_to_use = (size_t) *n_fds;
386 
387  /* Close the excess fds to avoid DoS: if they stayed open,
388  * someone could send us an extra fd per message
389  * and we'd eventually run out. */
390  for (i = fds_to_use; i < payload_len_fds; i++)
391  {
392  close (payload[i]);
393  }
394  }
395 
396  memcpy (fds, payload, fds_to_use * sizeof (int));
397  found = TRUE;
398  /* This cannot overflow because we have chosen fds_to_use
399  * to be <= *n_fds */
400  *n_fds = (int) fds_to_use;
401 
402  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
403  worked, hence we need to go through this list and set
404  CLOEXEC everywhere in any case */
405  for (i = 0; i < fds_to_use; i++)
407 
408  break;
409  }
410 
411  if (!found)
412  *n_fds = 0;
413 
414  /* put length back (doesn't actually realloc) */
415  _dbus_string_set_length (buffer, start + bytes_read);
416 
417 #if 0
418  if (bytes_read > 0)
419  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
420 #endif
421 
422  return bytes_read;
423  }
424 #endif
425 }
426 
427 int
428 _dbus_write_socket_with_unix_fds(int fd,
429  const DBusString *buffer,
430  int start,
431  int len,
432  const int *fds,
433  int n_fds) {
434 
435 #ifndef HAVE_UNIX_FD_PASSING
436 
437  if (n_fds > 0) {
438  errno = ENOTSUP;
439  return -1;
440  }
441 
442  return _dbus_write_socket(fd, buffer, start, len);
443 #else
444  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
445 #endif
446 }
447 
448 int
449 _dbus_write_socket_with_unix_fds_two(int fd,
450  const DBusString *buffer1,
451  int start1,
452  int len1,
453  const DBusString *buffer2,
454  int start2,
455  int len2,
456  const int *fds,
457  int n_fds) {
458 
459 #ifndef HAVE_UNIX_FD_PASSING
460 
461  if (n_fds > 0) {
462  errno = ENOTSUP;
463  return -1;
464  }
465 
466  return _dbus_write_socket_two(fd,
467  buffer1, start1, len1,
468  buffer2, start2, len2);
469 #else
470 
471  struct msghdr m;
472  struct cmsghdr *cm;
473  struct iovec iov[2];
474  int bytes_written;
475 
476  _dbus_assert (len1 >= 0);
477  _dbus_assert (len2 >= 0);
478  _dbus_assert (n_fds >= 0);
479 
480  _DBUS_ZERO(iov);
481  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
482  iov[0].iov_len = len1;
483 
484  if (buffer2)
485  {
486  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
487  iov[1].iov_len = len2;
488  }
489 
490  _DBUS_ZERO(m);
491  m.msg_iov = iov;
492  m.msg_iovlen = buffer2 ? 2 : 1;
493 
494  if (n_fds > 0)
495  {
496  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
497  m.msg_control = alloca(m.msg_controllen);
498  memset(m.msg_control, 0, m.msg_controllen);
499 
500  cm = CMSG_FIRSTHDR(&m);
501  cm->cmsg_level = SOL_SOCKET;
502  cm->cmsg_type = SCM_RIGHTS;
503  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
504  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
505  }
506 
507  again:
508 
509  bytes_written = sendmsg (fd, &m, 0
510 #if HAVE_DECL_MSG_NOSIGNAL
511  |MSG_NOSIGNAL
512 #endif
513  );
514 
515  if (bytes_written < 0 && errno == EINTR)
516  goto again;
517 
518 #if 0
519  if (bytes_written > 0)
520  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
521 #endif
522 
523  return bytes_written;
524 #endif
525 }
526 
540 int
542  const DBusString *buffer1,
543  int start1,
544  int len1,
545  const DBusString *buffer2,
546  int start2,
547  int len2)
548 {
549 #if HAVE_DECL_MSG_NOSIGNAL
550  struct iovec vectors[2];
551  const char *data1;
552  const char *data2;
553  int bytes_written;
554  struct msghdr m;
555 
556  _dbus_assert (buffer1 != NULL);
557  _dbus_assert (start1 >= 0);
558  _dbus_assert (start2 >= 0);
559  _dbus_assert (len1 >= 0);
560  _dbus_assert (len2 >= 0);
561 
562  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
563 
564  if (buffer2 != NULL)
565  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
566  else
567  {
568  data2 = NULL;
569  start2 = 0;
570  len2 = 0;
571  }
572 
573  vectors[0].iov_base = (char*) data1;
574  vectors[0].iov_len = len1;
575  vectors[1].iov_base = (char*) data2;
576  vectors[1].iov_len = len2;
577 
578  _DBUS_ZERO(m);
579  m.msg_iov = vectors;
580  m.msg_iovlen = data2 ? 2 : 1;
581 
582  again:
583 
584  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
585 
586  if (bytes_written < 0 && errno == EINTR)
587  goto again;
588 
589  return bytes_written;
590 
591 #else
592  return _dbus_write_two (fd, buffer1, start1, len1,
593  buffer2, start2, len2);
594 #endif
595 }
596 
598 _dbus_socket_is_invalid (int fd)
599 {
600  return fd < 0 ? TRUE : FALSE;
601 }
602 
619 int
620 _dbus_read (int fd,
621  DBusString *buffer,
622  int count)
623 {
624  int bytes_read;
625  int start;
626  char *data;
627 
628  _dbus_assert (count >= 0);
629 
630  start = _dbus_string_get_length (buffer);
631 
632  if (!_dbus_string_lengthen (buffer, count))
633  {
634  errno = ENOMEM;
635  return -1;
636  }
637 
638  data = _dbus_string_get_data_len (buffer, start, count);
639 
640  again:
641 
642  bytes_read = read (fd, data, count);
643 
644  if (bytes_read < 0)
645  {
646  if (errno == EINTR)
647  goto again;
648  else
649  {
650  /* put length back (note that this doesn't actually realloc anything) */
651  _dbus_string_set_length (buffer, start);
652  return -1;
653  }
654  }
655  else
656  {
657  /* put length back (doesn't actually realloc) */
658  _dbus_string_set_length (buffer, start + bytes_read);
659 
660 #if 0
661  if (bytes_read > 0)
662  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
663 #endif
664 
665  return bytes_read;
666  }
667 }
668 
679 int
680 _dbus_write (int fd,
681  const DBusString *buffer,
682  int start,
683  int len)
684 {
685  const char *data;
686  int bytes_written;
687 
688  data = _dbus_string_get_const_data_len (buffer, start, len);
689 
690  again:
691 
692  bytes_written = write (fd, data, len);
693 
694  if (bytes_written < 0 && errno == EINTR)
695  goto again;
696 
697 #if 0
698  if (bytes_written > 0)
699  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
700 #endif
701 
702  return bytes_written;
703 }
704 
725 int
727  const DBusString *buffer1,
728  int start1,
729  int len1,
730  const DBusString *buffer2,
731  int start2,
732  int len2)
733 {
734  _dbus_assert (buffer1 != NULL);
735  _dbus_assert (start1 >= 0);
736  _dbus_assert (start2 >= 0);
737  _dbus_assert (len1 >= 0);
738  _dbus_assert (len2 >= 0);
739 
740 #ifdef HAVE_WRITEV
741  {
742  struct iovec vectors[2];
743  const char *data1;
744  const char *data2;
745  int bytes_written;
746 
747  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
748 
749  if (buffer2 != NULL)
750  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
751  else
752  {
753  data2 = NULL;
754  start2 = 0;
755  len2 = 0;
756  }
757 
758  vectors[0].iov_base = (char*) data1;
759  vectors[0].iov_len = len1;
760  vectors[1].iov_base = (char*) data2;
761  vectors[1].iov_len = len2;
762 
763  again:
764 
765  bytes_written = writev (fd,
766  vectors,
767  data2 ? 2 : 1);
768 
769  if (bytes_written < 0 && errno == EINTR)
770  goto again;
771 
772  return bytes_written;
773  }
774 #else /* HAVE_WRITEV */
775  {
776  int ret1, ret2;
777 
778  ret1 = _dbus_write (fd, buffer1, start1, len1);
779  if (ret1 == len1 && buffer2 != NULL)
780  {
781  ret2 = _dbus_write (fd, buffer2, start2, len2);
782  if (ret2 < 0)
783  ret2 = 0; /* we can't report an error as the first write was OK */
784 
785  return ret1 + ret2;
786  }
787  else
788  return ret1;
789  }
790 #endif /* !HAVE_WRITEV */
791 }
792 
793 #define _DBUS_MAX_SUN_PATH_LENGTH 99
794 
824 int
825 _dbus_connect_unix_socket (const char *path,
826  dbus_bool_t abstract,
827  DBusError *error)
828 {
829  int fd;
830  size_t path_len;
831  struct sockaddr_un addr;
832 
833  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
834 
835  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
836  path, abstract);
837 
838 
839  if (!_dbus_open_unix_socket (&fd, error))
840  {
841  _DBUS_ASSERT_ERROR_IS_SET(error);
842  return -1;
843  }
844  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
845 
846  _DBUS_ZERO (addr);
847  addr.sun_family = AF_UNIX;
848  path_len = strlen (path);
849 
850  if (abstract)
851  {
852 #ifdef HAVE_ABSTRACT_SOCKETS
853  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
854  path_len++; /* Account for the extra nul byte added to the start of sun_path */
855 
856  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
857  {
859  "Abstract socket name too long\n");
860  _dbus_close (fd, NULL);
861  return -1;
862  }
863 
864  strncpy (&addr.sun_path[1], path, path_len);
865  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
866 #else /* HAVE_ABSTRACT_SOCKETS */
868  "Operating system does not support abstract socket namespace\n");
869  _dbus_close (fd, NULL);
870  return -1;
871 #endif /* ! HAVE_ABSTRACT_SOCKETS */
872  }
873  else
874  {
875  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
876  {
878  "Socket name too long\n");
879  _dbus_close (fd, NULL);
880  return -1;
881  }
882 
883  strncpy (addr.sun_path, path, path_len);
884  }
885 
886  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
887  {
888  dbus_set_error (error,
889  _dbus_error_from_errno (errno),
890  "Failed to connect to socket %s: %s",
891  path, _dbus_strerror (errno));
892 
893  _dbus_close (fd, NULL);
894  return -1;
895  }
896 
897  if (!_dbus_set_fd_nonblocking (fd, error))
898  {
899  _DBUS_ASSERT_ERROR_IS_SET (error);
900 
901  _dbus_close (fd, NULL);
902  return -1;
903  }
904 
905  return fd;
906 }
907 
920 int
921 _dbus_connect_exec (const char *path,
922  char *const argv[],
923  DBusError *error)
924 {
925  int fds[2];
926  pid_t pid;
927  int retval;
928  dbus_bool_t cloexec_done = 0;
929 
930  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
931 
932  _dbus_verbose ("connecting to process %s\n", path);
933 
934 #ifdef SOCK_CLOEXEC
935  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
936  cloexec_done = (retval >= 0);
937 
938  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
939 #endif
940  {
941  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
942  }
943 
944  if (retval < 0)
945  {
946  dbus_set_error (error,
947  _dbus_error_from_errno (errno),
948  "Failed to create socket pair: %s",
949  _dbus_strerror (errno));
950  return -1;
951  }
952 
953  if (!cloexec_done)
954  {
957  }
958 
959  pid = fork ();
960  if (pid < 0)
961  {
962  dbus_set_error (error,
963  _dbus_error_from_errno (errno),
964  "Failed to fork() to call %s: %s",
965  path, _dbus_strerror (errno));
966  close (fds[0]);
967  close (fds[1]);
968  return -1;
969  }
970 
971  if (pid == 0)
972  {
973  /* child */
974  close (fds[0]);
975 
976  dup2 (fds[1], STDIN_FILENO);
977  dup2 (fds[1], STDOUT_FILENO);
978 
979  if (fds[1] != STDIN_FILENO &&
980  fds[1] != STDOUT_FILENO)
981  close (fds[1]);
982 
983  /* Inherit STDERR and the controlling terminal from the
984  parent */
985 
986  _dbus_close_all ();
987 
988  execvp (path, argv);
989 
990  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
991 
992  _exit(1);
993  }
994 
995  /* parent */
996  close (fds[1]);
997 
998  if (!_dbus_set_fd_nonblocking (fds[0], error))
999  {
1000  _DBUS_ASSERT_ERROR_IS_SET (error);
1001 
1002  close (fds[0]);
1003  return -1;
1004  }
1005 
1006  return fds[0];
1007 }
1008 
1018 static dbus_bool_t
1019 _dbus_set_local_creds (int fd, dbus_bool_t on)
1020 {
1021  dbus_bool_t retval = TRUE;
1022 
1023 #if defined(HAVE_CMSGCRED)
1024  /* NOOP just to make sure only one codepath is used
1025  * and to prefer CMSGCRED
1026  */
1027 #elif defined(LOCAL_CREDS)
1028  int val = on ? 1 : 0;
1029  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
1030  {
1031  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
1032  retval = FALSE;
1033  }
1034  else
1035  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
1036  on ? "enabled" : "disabled", fd);
1037 #endif
1038 
1039  return retval;
1040 }
1041 
1059 int
1060 _dbus_listen_unix_socket (const char *path,
1061  dbus_bool_t abstract,
1062  DBusError *error)
1063 {
1064  int listen_fd;
1065  struct sockaddr_un addr;
1066  size_t path_len;
1067  unsigned int reuseaddr;
1068 
1069  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1070 
1071  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1072  path, abstract);
1073 
1074  if (!_dbus_open_unix_socket (&listen_fd, error))
1075  {
1076  _DBUS_ASSERT_ERROR_IS_SET(error);
1077  return -1;
1078  }
1079  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1080 
1081  _DBUS_ZERO (addr);
1082  addr.sun_family = AF_UNIX;
1083  path_len = strlen (path);
1084 
1085  if (abstract)
1086  {
1087 #ifdef HAVE_ABSTRACT_SOCKETS
1088  /* remember that abstract names aren't nul-terminated so we rely
1089  * on sun_path being filled in with zeroes above.
1090  */
1091  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1092  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1093 
1094  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1095  {
1097  "Abstract socket name too long\n");
1098  _dbus_close (listen_fd, NULL);
1099  return -1;
1100  }
1101 
1102  strncpy (&addr.sun_path[1], path, path_len);
1103  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1104 #else /* HAVE_ABSTRACT_SOCKETS */
1106  "Operating system does not support abstract socket namespace\n");
1107  _dbus_close (listen_fd, NULL);
1108  return -1;
1109 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1110  }
1111  else
1112  {
1113  /* Discussed security implications of this with Nalin,
1114  * and we couldn't think of where it would kick our ass, but
1115  * it still seems a bit sucky. It also has non-security suckage;
1116  * really we'd prefer to exit if the socket is already in use.
1117  * But there doesn't seem to be a good way to do this.
1118  *
1119  * Just to be extra careful, I threw in the stat() - clearly
1120  * the stat() can't *fix* any security issue, but it at least
1121  * avoids inadvertent/accidental data loss.
1122  */
1123  {
1124  struct stat sb;
1125 
1126  if (stat (path, &sb) == 0 &&
1127  S_ISSOCK (sb.st_mode))
1128  unlink (path);
1129  }
1130 
1131  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1132  {
1134  "Abstract socket name too long\n");
1135  _dbus_close (listen_fd, NULL);
1136  return -1;
1137  }
1138 
1139  strncpy (addr.sun_path, path, path_len);
1140  }
1141 
1142  reuseaddr = 1;
1143  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1144  {
1145  _dbus_warn ("Failed to set socket option\"%s\": %s",
1146  path, _dbus_strerror (errno));
1147  }
1148 
1149  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1150  {
1151  dbus_set_error (error, _dbus_error_from_errno (errno),
1152  "Failed to bind socket \"%s\": %s",
1153  path, _dbus_strerror (errno));
1154  _dbus_close (listen_fd, NULL);
1155  return -1;
1156  }
1157 
1158  if (listen (listen_fd, 30 /* backlog */) < 0)
1159  {
1160  dbus_set_error (error, _dbus_error_from_errno (errno),
1161  "Failed to listen on socket \"%s\": %s",
1162  path, _dbus_strerror (errno));
1163  _dbus_close (listen_fd, NULL);
1164  return -1;
1165  }
1166 
1167  if (!_dbus_set_local_creds (listen_fd, TRUE))
1168  {
1169  dbus_set_error (error, _dbus_error_from_errno (errno),
1170  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1171  path, _dbus_strerror (errno));
1172  close (listen_fd);
1173  return -1;
1174  }
1175 
1176  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1177  {
1178  _DBUS_ASSERT_ERROR_IS_SET (error);
1179  _dbus_close (listen_fd, NULL);
1180  return -1;
1181  }
1182 
1183  /* Try opening up the permissions, but if we can't, just go ahead
1184  * and continue, maybe it will be good enough.
1185  */
1186  if (!abstract && chmod (path, 0777) < 0)
1187  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1188  path);
1189 
1190  return listen_fd;
1191 }
1192 
1203 int
1205  DBusError *error)
1206 {
1207  int r, n;
1208  unsigned fd;
1209  int *new_fds;
1210 
1211  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1212 
1213  n = sd_listen_fds (TRUE);
1214  if (n < 0)
1215  {
1217  "Failed to acquire systemd socket: %s",
1218  _dbus_strerror (-n));
1219  return -1;
1220  }
1221 
1222  if (n <= 0)
1223  {
1225  "No socket received.");
1226  return -1;
1227  }
1228 
1229  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1230  {
1231  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1232  if (r < 0)
1233  {
1235  "Failed to verify systemd socket type: %s",
1236  _dbus_strerror (-r));
1237  return -1;
1238  }
1239 
1240  if (!r)
1241  {
1243  "Passed socket has wrong type.");
1244  return -1;
1245  }
1246  }
1247 
1248  /* OK, the file descriptors are all good, so let's take posession of
1249  them then. */
1250 
1251  new_fds = dbus_new (int, n);
1252  if (!new_fds)
1253  {
1255  "Failed to allocate file handle array.");
1256  goto fail;
1257  }
1258 
1259  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1260  {
1261  if (!_dbus_set_local_creds (fd, TRUE))
1262  {
1263  dbus_set_error (error, _dbus_error_from_errno (errno),
1264  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1265  _dbus_strerror (errno));
1266  goto fail;
1267  }
1268 
1269  if (!_dbus_set_fd_nonblocking (fd, error))
1270  {
1271  _DBUS_ASSERT_ERROR_IS_SET (error);
1272  goto fail;
1273  }
1274 
1275  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1276  }
1277 
1278  *fds = new_fds;
1279  return n;
1280 
1281  fail:
1282 
1283  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1284  {
1285  _dbus_close (fd, NULL);
1286  }
1287 
1288  dbus_free (new_fds);
1289  return -1;
1290 }
1291 
1305 int
1306 _dbus_connect_tcp_socket (const char *host,
1307  const char *port,
1308  const char *family,
1309  DBusError *error)
1310 {
1311  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1312 }
1313 
1314 int
1315 _dbus_connect_tcp_socket_with_nonce (const char *host,
1316  const char *port,
1317  const char *family,
1318  const char *noncefile,
1319  DBusError *error)
1320 {
1321  int saved_errno = 0;
1322  int fd = -1, res;
1323  struct addrinfo hints;
1324  struct addrinfo *ai, *tmp;
1325 
1326  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1327 
1328  _DBUS_ZERO (hints);
1329 
1330  if (!family)
1331  hints.ai_family = AF_UNSPEC;
1332  else if (!strcmp(family, "ipv4"))
1333  hints.ai_family = AF_INET;
1334  else if (!strcmp(family, "ipv6"))
1335  hints.ai_family = AF_INET6;
1336  else
1337  {
1338  dbus_set_error (error,
1340  "Unknown address family %s", family);
1341  return -1;
1342  }
1343  hints.ai_protocol = IPPROTO_TCP;
1344  hints.ai_socktype = SOCK_STREAM;
1345  hints.ai_flags = AI_ADDRCONFIG;
1346 
1347  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1348  {
1349  dbus_set_error (error,
1350  _dbus_error_from_errno (errno),
1351  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1352  host, port, gai_strerror(res), res);
1353  return -1;
1354  }
1355 
1356  tmp = ai;
1357  while (tmp)
1358  {
1359  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1360  {
1361  freeaddrinfo(ai);
1362  _DBUS_ASSERT_ERROR_IS_SET(error);
1363  return -1;
1364  }
1365  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1366 
1367  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1368  {
1369  saved_errno = errno;
1370  _dbus_close(fd, NULL);
1371  fd = -1;
1372  tmp = tmp->ai_next;
1373  continue;
1374  }
1375 
1376  break;
1377  }
1378  freeaddrinfo(ai);
1379 
1380  if (fd == -1)
1381  {
1382  dbus_set_error (error,
1383  _dbus_error_from_errno (saved_errno),
1384  "Failed to connect to socket \"%s:%s\" %s",
1385  host, port, _dbus_strerror(saved_errno));
1386  return -1;
1387  }
1388 
1389  if (noncefile != NULL)
1390  {
1391  DBusString noncefileStr;
1392  dbus_bool_t ret;
1393  _dbus_string_init_const (&noncefileStr, noncefile);
1394  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1395  _dbus_string_free (&noncefileStr);
1396 
1397  if (!ret)
1398  {
1399  _dbus_close (fd, NULL);
1400  return -1;
1401  }
1402  }
1403 
1404  if (!_dbus_set_fd_nonblocking (fd, error))
1405  {
1406  _dbus_close (fd, NULL);
1407  return -1;
1408  }
1409 
1410  return fd;
1411 }
1412 
1429 int
1430 _dbus_listen_tcp_socket (const char *host,
1431  const char *port,
1432  const char *family,
1433  DBusString *retport,
1434  int **fds_p,
1435  DBusError *error)
1436 {
1437  int saved_errno;
1438  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1439  struct addrinfo hints;
1440  struct addrinfo *ai, *tmp;
1441  unsigned int reuseaddr;
1442 
1443  *fds_p = NULL;
1444  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1445 
1446  _DBUS_ZERO (hints);
1447 
1448  if (!family)
1449  hints.ai_family = AF_UNSPEC;
1450  else if (!strcmp(family, "ipv4"))
1451  hints.ai_family = AF_INET;
1452  else if (!strcmp(family, "ipv6"))
1453  hints.ai_family = AF_INET6;
1454  else
1455  {
1456  dbus_set_error (error,
1458  "Unknown address family %s", family);
1459  return -1;
1460  }
1461 
1462  hints.ai_protocol = IPPROTO_TCP;
1463  hints.ai_socktype = SOCK_STREAM;
1464  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1465 
1466  redo_lookup_with_port:
1467  ai = NULL;
1468  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1469  {
1470  dbus_set_error (error,
1471  _dbus_error_from_errno (errno),
1472  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1473  host ? host : "*", port, gai_strerror(res), res);
1474  goto failed;
1475  }
1476 
1477  tmp = ai;
1478  while (tmp)
1479  {
1480  int fd = -1, *newlisten_fd;
1481  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1482  {
1483  _DBUS_ASSERT_ERROR_IS_SET(error);
1484  goto failed;
1485  }
1486  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1487 
1488  reuseaddr = 1;
1489  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1490  {
1491  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1492  host ? host : "*", port, _dbus_strerror (errno));
1493  }
1494 
1495  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1496  {
1497  saved_errno = errno;
1498  _dbus_close(fd, NULL);
1499  if (saved_errno == EADDRINUSE)
1500  {
1501  /* Depending on kernel policy, it may or may not
1502  be neccessary to bind to both IPv4 & 6 addresses
1503  so ignore EADDRINUSE here */
1504  tmp = tmp->ai_next;
1505  continue;
1506  }
1507  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1508  "Failed to bind socket \"%s:%s\": %s",
1509  host ? host : "*", port, _dbus_strerror (saved_errno));
1510  goto failed;
1511  }
1512 
1513  if (listen (fd, 30 /* backlog */) < 0)
1514  {
1515  saved_errno = errno;
1516  _dbus_close (fd, NULL);
1517  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1518  "Failed to listen on socket \"%s:%s\": %s",
1519  host ? host : "*", port, _dbus_strerror (saved_errno));
1520  goto failed;
1521  }
1522 
1523  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1524  if (!newlisten_fd)
1525  {
1526  saved_errno = errno;
1527  _dbus_close (fd, NULL);
1528  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1529  "Failed to allocate file handle array: %s",
1530  _dbus_strerror (saved_errno));
1531  goto failed;
1532  }
1533  listen_fd = newlisten_fd;
1534  listen_fd[nlisten_fd] = fd;
1535  nlisten_fd++;
1536 
1537  if (!_dbus_string_get_length(retport))
1538  {
1539  /* If the user didn't specify a port, or used 0, then
1540  the kernel chooses a port. After the first address
1541  is bound to, we need to force all remaining addresses
1542  to use the same port */
1543  if (!port || !strcmp(port, "0"))
1544  {
1545  int result;
1546  struct sockaddr_storage addr;
1547  socklen_t addrlen;
1548  char portbuf[50];
1549 
1550  addrlen = sizeof(addr);
1551  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1552 
1553  if (result == -1 ||
1554  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1555  portbuf, sizeof(portbuf),
1556  NI_NUMERICHOST)) != 0)
1557  {
1558  dbus_set_error (error, _dbus_error_from_errno (errno),
1559  "Failed to resolve port \"%s:%s\": %s (%s)",
1560  host ? host : "*", port, gai_strerror(res), res);
1561  goto failed;
1562  }
1563  if (!_dbus_string_append(retport, portbuf))
1564  {
1566  goto failed;
1567  }
1568 
1569  /* Release current address list & redo lookup */
1570  port = _dbus_string_get_const_data(retport);
1571  freeaddrinfo(ai);
1572  goto redo_lookup_with_port;
1573  }
1574  else
1575  {
1576  if (!_dbus_string_append(retport, port))
1577  {
1579  goto failed;
1580  }
1581  }
1582  }
1583 
1584  tmp = tmp->ai_next;
1585  }
1586  freeaddrinfo(ai);
1587  ai = NULL;
1588 
1589  if (!nlisten_fd)
1590  {
1591  errno = EADDRINUSE;
1592  dbus_set_error (error, _dbus_error_from_errno (errno),
1593  "Failed to bind socket \"%s:%s\": %s",
1594  host ? host : "*", port, _dbus_strerror (errno));
1595  goto failed;
1596  }
1597 
1598  for (i = 0 ; i < nlisten_fd ; i++)
1599  {
1600  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1601  {
1602  goto failed;
1603  }
1604  }
1605 
1606  *fds_p = listen_fd;
1607 
1608  return nlisten_fd;
1609 
1610  failed:
1611  if (ai)
1612  freeaddrinfo(ai);
1613  for (i = 0 ; i < nlisten_fd ; i++)
1614  _dbus_close(listen_fd[i], NULL);
1615  dbus_free(listen_fd);
1616  return -1;
1617 }
1618 
1619 static dbus_bool_t
1620 write_credentials_byte (int server_fd,
1621  DBusError *error)
1622 {
1623  int bytes_written;
1624  char buf[1] = { '\0' };
1625 #if defined(HAVE_CMSGCRED)
1626  union {
1627  struct cmsghdr hdr;
1628  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1629  } cmsg;
1630  struct iovec iov;
1631  struct msghdr msg;
1632  iov.iov_base = buf;
1633  iov.iov_len = 1;
1634 
1635  _DBUS_ZERO(msg);
1636  msg.msg_iov = &iov;
1637  msg.msg_iovlen = 1;
1638 
1639  msg.msg_control = (caddr_t) &cmsg;
1640  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1641  _DBUS_ZERO(cmsg);
1642  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1643  cmsg.hdr.cmsg_level = SOL_SOCKET;
1644  cmsg.hdr.cmsg_type = SCM_CREDS;
1645 #endif
1646 
1647  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1648 
1649  again:
1650 
1651 #if defined(HAVE_CMSGCRED)
1652  bytes_written = sendmsg (server_fd, &msg, 0
1653 #if HAVE_DECL_MSG_NOSIGNAL
1654  |MSG_NOSIGNAL
1655 #endif
1656  );
1657 #else
1658  bytes_written = send (server_fd, buf, 1, 0
1659 #if HAVE_DECL_MSG_NOSIGNAL
1660  |MSG_NOSIGNAL
1661 #endif
1662  );
1663 #endif
1664 
1665  if (bytes_written < 0 && errno == EINTR)
1666  goto again;
1667 
1668  if (bytes_written < 0)
1669  {
1670  dbus_set_error (error, _dbus_error_from_errno (errno),
1671  "Failed to write credentials byte: %s",
1672  _dbus_strerror (errno));
1673  return FALSE;
1674  }
1675  else if (bytes_written == 0)
1676  {
1678  "wrote zero bytes writing credentials byte");
1679  return FALSE;
1680  }
1681  else
1682  {
1683  _dbus_assert (bytes_written == 1);
1684  _dbus_verbose ("wrote credentials byte\n");
1685  return TRUE;
1686  }
1687 }
1688 
1712  DBusCredentials *credentials,
1713  DBusError *error)
1714 {
1715  struct msghdr msg;
1716  struct iovec iov;
1717  char buf;
1718  dbus_uid_t uid_read;
1719  dbus_pid_t pid_read;
1720  int bytes_read;
1721 
1722 #ifdef HAVE_CMSGCRED
1723  union {
1724  struct cmsghdr hdr;
1725  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1726  } cmsg;
1727 
1728 #elif defined(LOCAL_CREDS)
1729  struct {
1730  struct cmsghdr hdr;
1731  struct sockcred cred;
1732  } cmsg;
1733 #endif
1734 
1735  uid_read = DBUS_UID_UNSET;
1736  pid_read = DBUS_PID_UNSET;
1737 
1738  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1739 
1740  /* The POSIX spec certainly doesn't promise this, but
1741  * we need these assertions to fail as soon as we're wrong about
1742  * it so we can do the porting fixups
1743  */
1744  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1745  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1746  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1747 
1748  _dbus_credentials_clear (credentials);
1749 
1750  /* Systems supporting LOCAL_CREDS are configured to have this feature
1751  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1752  * the connection. Therefore, the received message must carry the
1753  * credentials information without doing anything special.
1754  */
1755 
1756  iov.iov_base = &buf;
1757  iov.iov_len = 1;
1758 
1759  _DBUS_ZERO(msg);
1760  msg.msg_iov = &iov;
1761  msg.msg_iovlen = 1;
1762 
1763 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1764  _DBUS_ZERO(cmsg);
1765  msg.msg_control = (caddr_t) &cmsg;
1766  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1767 #endif
1768 
1769  again:
1770  bytes_read = recvmsg (client_fd, &msg, 0);
1771 
1772  if (bytes_read < 0)
1773  {
1774  if (errno == EINTR)
1775  goto again;
1776 
1777  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1778  * normally only call read_credentials if the socket was ready
1779  * for reading
1780  */
1781 
1782  dbus_set_error (error, _dbus_error_from_errno (errno),
1783  "Failed to read credentials byte: %s",
1784  _dbus_strerror (errno));
1785  return FALSE;
1786  }
1787  else if (bytes_read == 0)
1788  {
1789  /* this should not happen unless we are using recvmsg wrong,
1790  * so is essentially here for paranoia
1791  */
1793  "Failed to read credentials byte (zero-length read)");
1794  return FALSE;
1795  }
1796  else if (buf != '\0')
1797  {
1799  "Credentials byte was not nul");
1800  return FALSE;
1801  }
1802 
1803 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1804  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1805  || cmsg.hdr.cmsg_type != SCM_CREDS)
1806  {
1808  "Message from recvmsg() was not SCM_CREDS");
1809  return FALSE;
1810  }
1811 #endif
1812 
1813  _dbus_verbose ("read credentials byte\n");
1814 
1815  {
1816 #ifdef SO_PEERCRED
1817 #ifdef __OpenBSD__
1818  struct sockpeercred cr;
1819 #else
1820  struct ucred cr;
1821 #endif
1822  int cr_len = sizeof (cr);
1823 
1824  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1825  cr_len == sizeof (cr))
1826  {
1827  pid_read = cr.pid;
1828  uid_read = cr.uid;
1829  }
1830  else
1831  {
1832  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1833  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1834  }
1835 #elif defined(HAVE_CMSGCRED)
1836  struct cmsgcred *cred;
1837 
1838  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1839  pid_read = cred->cmcred_pid;
1840  uid_read = cred->cmcred_euid;
1841 #elif defined(LOCAL_CREDS)
1842  pid_read = DBUS_PID_UNSET;
1843  uid_read = cmsg.cred.sc_uid;
1844  /* Since we have already got the credentials from this socket, we can
1845  * disable its LOCAL_CREDS flag if it was ever set. */
1846  _dbus_set_local_creds (client_fd, FALSE);
1847 #elif defined(HAVE_GETPEEREID)
1848  uid_t euid;
1849  gid_t egid;
1850  if (getpeereid (client_fd, &euid, &egid) == 0)
1851  {
1852  uid_read = euid;
1853  }
1854  else
1855  {
1856  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1857  }
1858 #elif defined(HAVE_GETPEERUCRED)
1859  ucred_t * ucred = NULL;
1860  if (getpeerucred (client_fd, &ucred) == 0)
1861  {
1862  pid_read = ucred_getpid (ucred);
1863  uid_read = ucred_geteuid (ucred);
1864 #ifdef HAVE_ADT
1865  /* generate audit session data based on socket ucred */
1866  adt_session_data_t *adth = NULL;
1867  adt_export_data_t *data = NULL;
1868  size_t size = 0;
1869  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1870  {
1871  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1872  }
1873  else
1874  {
1875  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1876  {
1877  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1878  }
1879  else
1880  {
1881  size = adt_export_session_data (adth, &data);
1882  if (size <= 0)
1883  {
1884  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1885  }
1886  else
1887  {
1888  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1889  free (data);
1890  }
1891  }
1892  (void) adt_end_session (adth);
1893  }
1894 #endif /* HAVE_ADT */
1895  }
1896  else
1897  {
1898  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1899  }
1900  if (ucred != NULL)
1901  ucred_free (ucred);
1902 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1903  _dbus_verbose ("Socket credentials not supported on this OS\n");
1904 #endif
1905  }
1906 
1907  _dbus_verbose ("Credentials:"
1908  " pid "DBUS_PID_FORMAT
1909  " uid "DBUS_UID_FORMAT
1910  "\n",
1911  pid_read,
1912  uid_read);
1913 
1914  if (pid_read != DBUS_PID_UNSET)
1915  {
1916  if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1917  {
1918  _DBUS_SET_OOM (error);
1919  return FALSE;
1920  }
1921  }
1922 
1923  if (uid_read != DBUS_UID_UNSET)
1924  {
1925  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1926  {
1927  _DBUS_SET_OOM (error);
1928  return FALSE;
1929  }
1930  }
1931 
1932  return TRUE;
1933 }
1934 
1954  DBusError *error)
1955 {
1956  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1957 
1958  if (write_credentials_byte (server_fd, error))
1959  return TRUE;
1960  else
1961  return FALSE;
1962 }
1963 
1973 int
1974 _dbus_accept (int listen_fd)
1975 {
1976  int client_fd;
1977  struct sockaddr addr;
1978  socklen_t addrlen;
1979 #ifdef HAVE_ACCEPT4
1980  dbus_bool_t cloexec_done;
1981 #endif
1982 
1983  addrlen = sizeof (addr);
1984 
1985  retry:
1986 
1987 #ifdef HAVE_ACCEPT4
1988  /*
1989  * At compile-time, we assume that if accept4() is available in
1990  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
1991  * not necessarily true that either is supported by the running kernel.
1992  */
1993  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1994  cloexec_done = client_fd >= 0;
1995 
1996  if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
1997 #endif
1998  {
1999  client_fd = accept (listen_fd, &addr, &addrlen);
2000  }
2001 
2002  if (client_fd < 0)
2003  {
2004  if (errno == EINTR)
2005  goto retry;
2006  }
2007 
2008  _dbus_verbose ("client fd %d accepted\n", client_fd);
2009 
2010 #ifdef HAVE_ACCEPT4
2011  if (!cloexec_done)
2012 #endif
2013  {
2014  _dbus_fd_set_close_on_exec(client_fd);
2015  }
2016 
2017  return client_fd;
2018 }
2019 
2030 {
2031  const char *directory;
2032  struct stat sb;
2033 
2034  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2035 
2036  directory = _dbus_string_get_const_data (dir);
2037 
2038  if (stat (directory, &sb) < 0)
2039  {
2040  dbus_set_error (error, _dbus_error_from_errno (errno),
2041  "%s", _dbus_strerror (errno));
2042 
2043  return FALSE;
2044  }
2045 
2046  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2047  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2048  {
2050  "%s directory is not private to the user", directory);
2051  return FALSE;
2052  }
2053 
2054  return TRUE;
2055 }
2056 
2057 static dbus_bool_t
2058 fill_user_info_from_passwd (struct passwd *p,
2059  DBusUserInfo *info,
2060  DBusError *error)
2061 {
2062  _dbus_assert (p->pw_name != NULL);
2063  _dbus_assert (p->pw_dir != NULL);
2064 
2065  info->uid = p->pw_uid;
2066  info->primary_gid = p->pw_gid;
2067  info->username = _dbus_strdup (p->pw_name);
2068  info->homedir = _dbus_strdup (p->pw_dir);
2069 
2070  if (info->username == NULL ||
2071  info->homedir == NULL)
2072  {
2074  return FALSE;
2075  }
2076 
2077  return TRUE;
2078 }
2079 
2080 static dbus_bool_t
2081 fill_user_info (DBusUserInfo *info,
2082  dbus_uid_t uid,
2083  const DBusString *username,
2084  DBusError *error)
2085 {
2086  const char *username_c;
2087 
2088  /* exactly one of username/uid provided */
2089  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2090  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2091 
2092  info->uid = DBUS_UID_UNSET;
2093  info->primary_gid = DBUS_GID_UNSET;
2094  info->group_ids = NULL;
2095  info->n_group_ids = 0;
2096  info->username = NULL;
2097  info->homedir = NULL;
2098 
2099  if (username != NULL)
2100  username_c = _dbus_string_get_const_data (username);
2101  else
2102  username_c = NULL;
2103 
2104  /* For now assuming that the getpwnam() and getpwuid() flavors
2105  * are always symmetrical, if not we have to add more configure
2106  * checks
2107  */
2108 
2109 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2110  {
2111  struct passwd *p;
2112  int result;
2113  size_t buflen;
2114  char *buf;
2115  struct passwd p_str;
2116 
2117  /* retrieve maximum needed size for buf */
2118  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2119 
2120  /* sysconf actually returns a long, but everything else expects size_t,
2121  * so just recast here.
2122  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2123  */
2124  if ((long) buflen <= 0)
2125  buflen = 1024;
2126 
2127  result = -1;
2128  while (1)
2129  {
2130  buf = dbus_malloc (buflen);
2131  if (buf == NULL)
2132  {
2134  return FALSE;
2135  }
2136 
2137  p = NULL;
2138 #ifdef HAVE_POSIX_GETPWNAM_R
2139  if (uid != DBUS_UID_UNSET)
2140  result = getpwuid_r (uid, &p_str, buf, buflen,
2141  &p);
2142  else
2143  result = getpwnam_r (username_c, &p_str, buf, buflen,
2144  &p);
2145 #else
2146  if (uid != DBUS_UID_UNSET)
2147  p = getpwuid_r (uid, &p_str, buf, buflen);
2148  else
2149  p = getpwnam_r (username_c, &p_str, buf, buflen);
2150  result = 0;
2151 #endif /* !HAVE_POSIX_GETPWNAM_R */
2152  //Try a bigger buffer if ERANGE was returned
2153  if (result == ERANGE && buflen < 512 * 1024)
2154  {
2155  dbus_free (buf);
2156  buflen *= 2;
2157  }
2158  else
2159  {
2160  break;
2161  }
2162  }
2163  if (result == 0 && p == &p_str)
2164  {
2165  if (!fill_user_info_from_passwd (p, info, error))
2166  {
2167  dbus_free (buf);
2168  return FALSE;
2169  }
2170  dbus_free (buf);
2171  }
2172  else
2173  {
2174  dbus_set_error (error, _dbus_error_from_errno (errno),
2175  "User \"%s\" unknown or no memory to allocate password entry\n",
2176  username_c ? username_c : "???");
2177  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2178  dbus_free (buf);
2179  return FALSE;
2180  }
2181  }
2182 #else /* ! HAVE_GETPWNAM_R */
2183  {
2184  /* I guess we're screwed on thread safety here */
2185  struct passwd *p;
2186 
2187  if (uid != DBUS_UID_UNSET)
2188  p = getpwuid (uid);
2189  else
2190  p = getpwnam (username_c);
2191 
2192  if (p != NULL)
2193  {
2194  if (!fill_user_info_from_passwd (p, info, error))
2195  {
2196  return FALSE;
2197  }
2198  }
2199  else
2200  {
2201  dbus_set_error (error, _dbus_error_from_errno (errno),
2202  "User \"%s\" unknown or no memory to allocate password entry\n",
2203  username_c ? username_c : "???");
2204  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2205  return FALSE;
2206  }
2207  }
2208 #endif /* ! HAVE_GETPWNAM_R */
2209 
2210  /* Fill this in so we can use it to get groups */
2211  username_c = info->username;
2212 
2213 #ifdef HAVE_GETGROUPLIST
2214  {
2215  gid_t *buf;
2216  int buf_count;
2217  int i;
2218  int initial_buf_count;
2219 
2220  initial_buf_count = 17;
2221  buf_count = initial_buf_count;
2222  buf = dbus_new (gid_t, buf_count);
2223  if (buf == NULL)
2224  {
2226  goto failed;
2227  }
2228 
2229  if (getgrouplist (username_c,
2230  info->primary_gid,
2231  buf, &buf_count) < 0)
2232  {
2233  gid_t *new;
2234  /* Presumed cause of negative return code: buf has insufficient
2235  entries to hold the entire group list. The Linux behavior in this
2236  case is to pass back the actual number of groups in buf_count, but
2237  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2238  So as a hack, try to help out a bit by guessing a larger
2239  number of groups, within reason.. might still fail, of course,
2240  but we can at least print a more informative message. I looked up
2241  the "right way" to do this by downloading Apple's own source code
2242  for the "id" command, and it turns out that they use an
2243  undocumented library function getgrouplist_2 (!) which is not
2244  declared in any header in /usr/include (!!). That did not seem
2245  like the way to go here.
2246  */
2247  if (buf_count == initial_buf_count)
2248  {
2249  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2250  }
2251  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2252  if (new == NULL)
2253  {
2255  dbus_free (buf);
2256  goto failed;
2257  }
2258 
2259  buf = new;
2260 
2261  errno = 0;
2262  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2263  {
2264  if (errno == 0)
2265  {
2266  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2267  username_c, buf_count, buf_count);
2268  }
2269  else
2270  {
2271  dbus_set_error (error,
2272  _dbus_error_from_errno (errno),
2273  "Failed to get groups for username \"%s\" primary GID "
2274  DBUS_GID_FORMAT ": %s\n",
2275  username_c, info->primary_gid,
2276  _dbus_strerror (errno));
2277  dbus_free (buf);
2278  goto failed;
2279  }
2280  }
2281  }
2282 
2283  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2284  if (info->group_ids == NULL)
2285  {
2287  dbus_free (buf);
2288  goto failed;
2289  }
2290 
2291  for (i = 0; i < buf_count; ++i)
2292  info->group_ids[i] = buf[i];
2293 
2294  info->n_group_ids = buf_count;
2295 
2296  dbus_free (buf);
2297  }
2298 #else /* HAVE_GETGROUPLIST */
2299  {
2300  /* We just get the one group ID */
2301  info->group_ids = dbus_new (dbus_gid_t, 1);
2302  if (info->group_ids == NULL)
2303  {
2305  goto failed;
2306  }
2307 
2308  info->n_group_ids = 1;
2309 
2310  (info->group_ids)[0] = info->primary_gid;
2311  }
2312 #endif /* HAVE_GETGROUPLIST */
2313 
2314  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2315 
2316  return TRUE;
2317 
2318  failed:
2319  _DBUS_ASSERT_ERROR_IS_SET (error);
2320  return FALSE;
2321 }
2322 
2333  const DBusString *username,
2334  DBusError *error)
2335 {
2336  return fill_user_info (info, DBUS_UID_UNSET,
2337  username, error);
2338 }
2339 
2350  dbus_uid_t uid,
2351  DBusError *error)
2352 {
2353  return fill_user_info (info, uid,
2354  NULL, error);
2355 }
2356 
2366 {
2367  /* The POSIX spec certainly doesn't promise this, but
2368  * we need these assertions to fail as soon as we're wrong about
2369  * it so we can do the porting fixups
2370  */
2371  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2372  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2373  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2374 
2375  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2376  return FALSE;
2377  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2378  return FALSE;
2379 
2380  return TRUE;
2381 }
2382 
2396 {
2397  return _dbus_string_append_uint (str,
2398  _dbus_geteuid ());
2399 }
2400 
2405 dbus_pid_t
2407 {
2408  return getpid ();
2409 }
2410 
2414 dbus_uid_t
2416 {
2417  return getuid ();
2418 }
2419 
2423 dbus_uid_t
2425 {
2426  return geteuid ();
2427 }
2428 
2435 unsigned long
2437 {
2438  return getpid ();
2439 }
2440 
2449 _dbus_parse_uid (const DBusString *uid_str,
2450  dbus_uid_t *uid)
2451 {
2452  int end;
2453  long val;
2454 
2455  if (_dbus_string_get_length (uid_str) == 0)
2456  {
2457  _dbus_verbose ("UID string was zero length\n");
2458  return FALSE;
2459  }
2460 
2461  val = -1;
2462  end = 0;
2463  if (!_dbus_string_parse_int (uid_str, 0, &val,
2464  &end))
2465  {
2466  _dbus_verbose ("could not parse string as a UID\n");
2467  return FALSE;
2468  }
2469 
2470  if (end != _dbus_string_get_length (uid_str))
2471  {
2472  _dbus_verbose ("string contained trailing stuff after UID\n");
2473  return FALSE;
2474  }
2475 
2476  *uid = val;
2477 
2478  return TRUE;
2479 }
2480 
2481 #if !DBUS_USE_SYNC
2482 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2483 #endif
2484 
2493 {
2494 #if DBUS_USE_SYNC
2495  return __sync_add_and_fetch(&atomic->value, 1)-1;
2496 #else
2497  dbus_int32_t res;
2498  _DBUS_LOCK (atomic);
2499  res = atomic->value;
2500  atomic->value += 1;
2501  _DBUS_UNLOCK (atomic);
2502  return res;
2503 #endif
2504 }
2505 
2514 {
2515 #if DBUS_USE_SYNC
2516  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2517 #else
2518  dbus_int32_t res;
2519 
2520  _DBUS_LOCK (atomic);
2521  res = atomic->value;
2522  atomic->value -= 1;
2523  _DBUS_UNLOCK (atomic);
2524  return res;
2525 #endif
2526 }
2527 
2537 {
2538 #if DBUS_USE_SYNC
2539  __sync_synchronize ();
2540  return atomic->value;
2541 #else
2542  dbus_int32_t res;
2543 
2544  _DBUS_LOCK (atomic);
2545  res = atomic->value;
2546  _DBUS_UNLOCK (atomic);
2547  return res;
2548 #endif
2549 }
2550 
2559 int
2561  int n_fds,
2562  int timeout_milliseconds)
2563 {
2564 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2565  /* This big thing is a constant expression and should get optimized
2566  * out of existence. So it's more robust than a configure check at
2567  * no cost.
2568  */
2569  if (_DBUS_POLLIN == POLLIN &&
2570  _DBUS_POLLPRI == POLLPRI &&
2571  _DBUS_POLLOUT == POLLOUT &&
2572  _DBUS_POLLERR == POLLERR &&
2573  _DBUS_POLLHUP == POLLHUP &&
2574  _DBUS_POLLNVAL == POLLNVAL &&
2575  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2576  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2577  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2578  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2579  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2580  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2581  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2582  {
2583  return poll ((struct pollfd*) fds,
2584  n_fds,
2585  timeout_milliseconds);
2586  }
2587  else
2588  {
2589  /* We have to convert the DBusPollFD to an array of
2590  * struct pollfd, poll, and convert back.
2591  */
2592  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2593  return -1;
2594  }
2595 #else /* ! HAVE_POLL */
2596 
2597  fd_set read_set, write_set, err_set;
2598  int max_fd = 0;
2599  int i;
2600  struct timeval tv;
2601  int ready;
2602 
2603  FD_ZERO (&read_set);
2604  FD_ZERO (&write_set);
2605  FD_ZERO (&err_set);
2606 
2607  for (i = 0; i < n_fds; i++)
2608  {
2609  DBusPollFD *fdp = &fds[i];
2610 
2611  if (fdp->events & _DBUS_POLLIN)
2612  FD_SET (fdp->fd, &read_set);
2613 
2614  if (fdp->events & _DBUS_POLLOUT)
2615  FD_SET (fdp->fd, &write_set);
2616 
2617  FD_SET (fdp->fd, &err_set);
2618 
2619  max_fd = MAX (max_fd, fdp->fd);
2620  }
2621 
2622  tv.tv_sec = timeout_milliseconds / 1000;
2623  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2624 
2625  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2626  timeout_milliseconds < 0 ? NULL : &tv);
2627 
2628  if (ready > 0)
2629  {
2630  for (i = 0; i < n_fds; i++)
2631  {
2632  DBusPollFD *fdp = &fds[i];
2633 
2634  fdp->revents = 0;
2635 
2636  if (FD_ISSET (fdp->fd, &read_set))
2637  fdp->revents |= _DBUS_POLLIN;
2638 
2639  if (FD_ISSET (fdp->fd, &write_set))
2640  fdp->revents |= _DBUS_POLLOUT;
2641 
2642  if (FD_ISSET (fdp->fd, &err_set))
2643  fdp->revents |= _DBUS_POLLERR;
2644  }
2645  }
2646 
2647  return ready;
2648 #endif
2649 }
2650 
2658 void
2660  long *tv_usec)
2661 {
2662 #ifdef HAVE_MONOTONIC_CLOCK
2663  struct timespec ts;
2664  clock_gettime (CLOCK_MONOTONIC, &ts);
2665 
2666  if (tv_sec)
2667  *tv_sec = ts.tv_sec;
2668  if (tv_usec)
2669  *tv_usec = ts.tv_nsec / 1000;
2670 #else
2671  struct timeval t;
2672 
2673  gettimeofday (&t, NULL);
2674 
2675  if (tv_sec)
2676  *tv_sec = t.tv_sec;
2677  if (tv_usec)
2678  *tv_usec = t.tv_usec;
2679 #endif
2680 }
2681 
2689 void
2690 _dbus_get_real_time (long *tv_sec,
2691  long *tv_usec)
2692 {
2693  struct timeval t;
2694 
2695  gettimeofday (&t, NULL);
2696 
2697  if (tv_sec)
2698  *tv_sec = t.tv_sec;
2699  if (tv_usec)
2700  *tv_usec = t.tv_usec;
2701 }
2702 
2713  DBusError *error)
2714 {
2715  const char *filename_c;
2716 
2717  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2718 
2719  filename_c = _dbus_string_get_const_data (filename);
2720 
2721  if (mkdir (filename_c, 0700) < 0)
2722  {
2723  if (errno == EEXIST)
2724  return TRUE;
2725 
2727  "Failed to create directory %s: %s\n",
2728  filename_c, _dbus_strerror (errno));
2729  return FALSE;
2730  }
2731  else
2732  return TRUE;
2733 }
2734 
2747  const DBusString *next_component)
2748 {
2749  dbus_bool_t dir_ends_in_slash;
2750  dbus_bool_t file_starts_with_slash;
2751 
2752  if (_dbus_string_get_length (dir) == 0 ||
2753  _dbus_string_get_length (next_component) == 0)
2754  return TRUE;
2755 
2756  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2757  _dbus_string_get_length (dir) - 1);
2758 
2759  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2760 
2761  if (dir_ends_in_slash && file_starts_with_slash)
2762  {
2763  _dbus_string_shorten (dir, 1);
2764  }
2765  else if (!(dir_ends_in_slash || file_starts_with_slash))
2766  {
2767  if (!_dbus_string_append_byte (dir, '/'))
2768  return FALSE;
2769  }
2770 
2771  return _dbus_string_copy (next_component, 0, dir,
2772  _dbus_string_get_length (dir));
2773 }
2774 
2776 #define NANOSECONDS_PER_SECOND 1000000000
2777 
2778 #define MICROSECONDS_PER_SECOND 1000000
2779 
2780 #define MILLISECONDS_PER_SECOND 1000
2781 
2782 #define NANOSECONDS_PER_MILLISECOND 1000000
2783 
2784 #define MICROSECONDS_PER_MILLISECOND 1000
2785 
2790 void
2791 _dbus_sleep_milliseconds (int milliseconds)
2792 {
2793 #ifdef HAVE_NANOSLEEP
2794  struct timespec req;
2795  struct timespec rem;
2796 
2797  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2798  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2799  rem.tv_sec = 0;
2800  rem.tv_nsec = 0;
2801 
2802  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2803  req = rem;
2804 #elif defined (HAVE_USLEEP)
2805  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2806 #else /* ! HAVE_USLEEP */
2807  sleep (MAX (milliseconds / 1000, 1));
2808 #endif
2809 }
2810 
2811 static dbus_bool_t
2812 _dbus_generate_pseudorandom_bytes (DBusString *str,
2813  int n_bytes)
2814 {
2815  int old_len;
2816  char *p;
2817 
2818  old_len = _dbus_string_get_length (str);
2819 
2820  if (!_dbus_string_lengthen (str, n_bytes))
2821  return FALSE;
2822 
2823  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2824 
2826 
2827  return TRUE;
2828 }
2829 
2840  int n_bytes)
2841 {
2842  int old_len;
2843  int fd;
2844 
2845  /* FALSE return means "no memory", if it could
2846  * mean something else then we'd need to return
2847  * a DBusError. So we always fall back to pseudorandom
2848  * if the I/O fails.
2849  */
2850 
2851  old_len = _dbus_string_get_length (str);
2852  fd = -1;
2853 
2854  /* note, urandom on linux will fall back to pseudorandom */
2855  fd = open ("/dev/urandom", O_RDONLY);
2856  if (fd < 0)
2857  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2858 
2859  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2860 
2861  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2862  {
2863  _dbus_close (fd, NULL);
2864  _dbus_string_set_length (str, old_len);
2865  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2866  }
2867 
2868  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2869  n_bytes);
2870 
2871  _dbus_close (fd, NULL);
2872 
2873  return TRUE;
2874 }
2875 
2881 void
2882 _dbus_exit (int code)
2883 {
2884  _exit (code);
2885 }
2886 
2895 const char*
2896 _dbus_strerror (int error_number)
2897 {
2898  const char *msg;
2899 
2900  msg = strerror (error_number);
2901  if (msg == NULL)
2902  msg = "unknown";
2903 
2904  return msg;
2905 }
2906 
2910 void
2912 {
2913  signal (SIGPIPE, SIG_IGN);
2914 }
2915 
2923 void
2925 {
2926  int val;
2927 
2928  val = fcntl (fd, F_GETFD, 0);
2929 
2930  if (val < 0)
2931  return;
2932 
2933  val |= FD_CLOEXEC;
2934 
2935  fcntl (fd, F_SETFD, val);
2936 }
2937 
2946 _dbus_close (int fd,
2947  DBusError *error)
2948 {
2949  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2950 
2951  again:
2952  if (close (fd) < 0)
2953  {
2954  if (errno == EINTR)
2955  goto again;
2956 
2957  dbus_set_error (error, _dbus_error_from_errno (errno),
2958  "Could not close fd %d", fd);
2959  return FALSE;
2960  }
2961 
2962  return TRUE;
2963 }
2964 
2972 int
2973 _dbus_dup(int fd,
2974  DBusError *error)
2975 {
2976  int new_fd;
2977 
2978 #ifdef F_DUPFD_CLOEXEC
2979  dbus_bool_t cloexec_done;
2980 
2981  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2982  cloexec_done = new_fd >= 0;
2983 
2984  if (new_fd < 0 && errno == EINVAL)
2985 #endif
2986  {
2987  new_fd = fcntl(fd, F_DUPFD, 3);
2988  }
2989 
2990  if (new_fd < 0) {
2991 
2992  dbus_set_error (error, _dbus_error_from_errno (errno),
2993  "Could not duplicate fd %d", fd);
2994  return -1;
2995  }
2996 
2997 #ifdef F_DUPFD_CLOEXEC
2998  if (!cloexec_done)
2999 #endif
3000  {
3002  }
3003 
3004  return new_fd;
3005 }
3006 
3015 _dbus_set_fd_nonblocking (int fd,
3016  DBusError *error)
3017 {
3018  int val;
3019 
3020  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3021 
3022  val = fcntl (fd, F_GETFL, 0);
3023  if (val < 0)
3024  {
3025  dbus_set_error (error, _dbus_error_from_errno (errno),
3026  "Failed to get flags from file descriptor %d: %s",
3027  fd, _dbus_strerror (errno));
3028  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3029  _dbus_strerror (errno));
3030  return FALSE;
3031  }
3032 
3033  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3034  {
3035  dbus_set_error (error, _dbus_error_from_errno (errno),
3036  "Failed to set nonblocking flag of file descriptor %d: %s",
3037  fd, _dbus_strerror (errno));
3038  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3039  fd, _dbus_strerror (errno));
3040 
3041  return FALSE;
3042  }
3043 
3044  return TRUE;
3045 }
3046 
3052 void
3054 {
3055 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3056  void *bt[500];
3057  int bt_size;
3058  int i;
3059  char **syms;
3060 
3061  bt_size = backtrace (bt, 500);
3062 
3063  syms = backtrace_symbols (bt, bt_size);
3064 
3065  i = 0;
3066  while (i < bt_size)
3067  {
3068  /* don't use dbus_warn since it can _dbus_abort() */
3069  fprintf (stderr, " %s\n", syms[i]);
3070  ++i;
3071  }
3072  fflush (stderr);
3073 
3074  free (syms);
3075 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3076  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3077 #else
3078  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3079 #endif
3080 }
3081 
3096  int *fd2,
3097  dbus_bool_t blocking,
3098  DBusError *error)
3099 {
3100 #ifdef HAVE_SOCKETPAIR
3101  int fds[2];
3102  int retval;
3103 
3104 #ifdef SOCK_CLOEXEC
3105  dbus_bool_t cloexec_done;
3106 
3107  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3108  cloexec_done = retval >= 0;
3109 
3110  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3111 #endif
3112  {
3113  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3114  }
3115 
3116  if (retval < 0)
3117  {
3118  dbus_set_error (error, _dbus_error_from_errno (errno),
3119  "Could not create full-duplex pipe");
3120  return FALSE;
3121  }
3122 
3123  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3124 
3125 #ifdef SOCK_CLOEXEC
3126  if (!cloexec_done)
3127 #endif
3128  {
3129  _dbus_fd_set_close_on_exec (fds[0]);
3130  _dbus_fd_set_close_on_exec (fds[1]);
3131  }
3132 
3133  if (!blocking &&
3134  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3135  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3136  {
3137  dbus_set_error (error, _dbus_error_from_errno (errno),
3138  "Could not set full-duplex pipe nonblocking");
3139 
3140  _dbus_close (fds[0], NULL);
3141  _dbus_close (fds[1], NULL);
3142 
3143  return FALSE;
3144  }
3145 
3146  *fd1 = fds[0];
3147  *fd2 = fds[1];
3148 
3149  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3150  *fd1, *fd2);
3151 
3152  return TRUE;
3153 #else
3154  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3156  "_dbus_full_duplex_pipe() not implemented on this OS");
3157  return FALSE;
3158 #endif
3159 }
3160 
3169 int
3171  va_list args)
3172 {
3173  char static_buf[1024];
3174  int bufsize = sizeof (static_buf);
3175  int len;
3176  va_list args_copy;
3177 
3178  DBUS_VA_COPY (args_copy, args);
3179  len = vsnprintf (static_buf, bufsize, format, args_copy);
3180  va_end (args_copy);
3181 
3182  /* If vsnprintf() returned non-negative, then either the string fits in
3183  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3184  * returns the number of characters that were needed, or this OS returns the
3185  * truncated length.
3186  *
3187  * We ignore the possibility that snprintf might just ignore the length and
3188  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3189  * If your libc is really that bad, come back when you have a better one. */
3190  if (len == bufsize)
3191  {
3192  /* This could be the truncated length (Tru64 and IRIX have this bug),
3193  * or the real length could be coincidentally the same. Which is it?
3194  * If vsnprintf returns the truncated length, we'll go to the slow
3195  * path. */
3196  DBUS_VA_COPY (args_copy, args);
3197 
3198  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3199  len = -1;
3200 
3201  va_end (args_copy);
3202  }
3203 
3204  /* If vsnprintf() returned negative, we have to do more work.
3205  * HP-UX returns negative. */
3206  while (len < 0)
3207  {
3208  char *buf;
3209 
3210  bufsize *= 2;
3211 
3212  buf = dbus_malloc (bufsize);
3213 
3214  if (buf == NULL)
3215  return -1;
3216 
3217  DBUS_VA_COPY (args_copy, args);
3218  len = vsnprintf (buf, bufsize, format, args_copy);
3219  va_end (args_copy);
3220 
3221  dbus_free (buf);
3222 
3223  /* If the reported length is exactly the buffer size, round up to the
3224  * next size, in case vsnprintf has been returning the truncated
3225  * length */
3226  if (len == bufsize)
3227  len = -1;
3228  }
3229 
3230  return len;
3231 }
3232 
3239 const char*
3241 {
3242  static const char* tmpdir = NULL;
3243 
3244  if (tmpdir == NULL)
3245  {
3246  /* TMPDIR is what glibc uses, then
3247  * glibc falls back to the P_tmpdir macro which
3248  * just expands to "/tmp"
3249  */
3250  if (tmpdir == NULL)
3251  tmpdir = getenv("TMPDIR");
3252 
3253  /* These two env variables are probably
3254  * broken, but maybe some OS uses them?
3255  */
3256  if (tmpdir == NULL)
3257  tmpdir = getenv("TMP");
3258  if (tmpdir == NULL)
3259  tmpdir = getenv("TEMP");
3260 
3261  /* And this is the sane fallback. */
3262  if (tmpdir == NULL)
3263  tmpdir = "/tmp";
3264  }
3265 
3266  _dbus_assert(tmpdir != NULL);
3267 
3268  return tmpdir;
3269 }
3270 
3290 static dbus_bool_t
3291 _read_subprocess_line_argv (const char *progpath,
3292  dbus_bool_t path_fallback,
3293  char * const *argv,
3294  DBusString *result,
3295  DBusError *error)
3296 {
3297  int result_pipe[2] = { -1, -1 };
3298  int errors_pipe[2] = { -1, -1 };
3299  pid_t pid;
3300  int ret;
3301  int status;
3302  int orig_len;
3303 
3304  dbus_bool_t retval;
3305  sigset_t new_set, old_set;
3306 
3307  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3308  retval = FALSE;
3309 
3310  /* We need to block any existing handlers for SIGCHLD temporarily; they
3311  * will cause waitpid() below to fail.
3312  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3313  */
3314  sigemptyset (&new_set);
3315  sigaddset (&new_set, SIGCHLD);
3316  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3317 
3318  orig_len = _dbus_string_get_length (result);
3319 
3320 #define READ_END 0
3321 #define WRITE_END 1
3322  if (pipe (result_pipe) < 0)
3323  {
3324  dbus_set_error (error, _dbus_error_from_errno (errno),
3325  "Failed to create a pipe to call %s: %s",
3326  progpath, _dbus_strerror (errno));
3327  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3328  progpath, _dbus_strerror (errno));
3329  goto out;
3330  }
3331  if (pipe (errors_pipe) < 0)
3332  {
3333  dbus_set_error (error, _dbus_error_from_errno (errno),
3334  "Failed to create a pipe to call %s: %s",
3335  progpath, _dbus_strerror (errno));
3336  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3337  progpath, _dbus_strerror (errno));
3338  goto out;
3339  }
3340 
3341  pid = fork ();
3342  if (pid < 0)
3343  {
3344  dbus_set_error (error, _dbus_error_from_errno (errno),
3345  "Failed to fork() to call %s: %s",
3346  progpath, _dbus_strerror (errno));
3347  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3348  progpath, _dbus_strerror (errno));
3349  goto out;
3350  }
3351 
3352  if (pid == 0)
3353  {
3354  /* child process */
3355  int fd;
3356 
3357  fd = open ("/dev/null", O_RDWR);
3358  if (fd == -1)
3359  /* huh?! can't open /dev/null? */
3360  _exit (1);
3361 
3362  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3363 
3364  /* set-up stdXXX */
3365  close (result_pipe[READ_END]);
3366  close (errors_pipe[READ_END]);
3367  close (0); /* close stdin */
3368  close (1); /* close stdout */
3369  close (2); /* close stderr */
3370 
3371  if (dup2 (fd, 0) == -1)
3372  _exit (1);
3373  if (dup2 (result_pipe[WRITE_END], 1) == -1)
3374  _exit (1);
3375  if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3376  _exit (1);
3377 
3378  _dbus_close_all ();
3379 
3380  sigprocmask (SIG_SETMASK, &old_set, NULL);
3381 
3382  /* If it looks fully-qualified, try execv first */
3383  if (progpath[0] == '/')
3384  {
3385  execv (progpath, argv);
3386  /* Ok, that failed. Now if path_fallback is given, let's
3387  * try unqualified. This is mostly a hack to work
3388  * around systems which ship dbus-launch in /usr/bin
3389  * but everything else in /bin (because dbus-launch
3390  * depends on X11).
3391  */
3392  if (path_fallback)
3393  /* We must have a slash, because we checked above */
3394  execvp (strrchr (progpath, '/')+1, argv);
3395  }
3396  else
3397  execvp (progpath, argv);
3398 
3399  /* still nothing, we failed */
3400  _exit (1);
3401  }
3402 
3403  /* parent process */
3404  close (result_pipe[WRITE_END]);
3405  close (errors_pipe[WRITE_END]);
3406  result_pipe[WRITE_END] = -1;
3407  errors_pipe[WRITE_END] = -1;
3408 
3409  ret = 0;
3410  do
3411  {
3412  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3413  }
3414  while (ret > 0);
3415 
3416  /* reap the child process to avoid it lingering as zombie */
3417  do
3418  {
3419  ret = waitpid (pid, &status, 0);
3420  }
3421  while (ret == -1 && errno == EINTR);
3422 
3423  /* We succeeded if the process exited with status 0 and
3424  anything was read */
3425  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3426  {
3427  /* The process ended with error */
3428  DBusString error_message;
3429  if (!_dbus_string_init (&error_message))
3430  {
3431  _DBUS_SET_OOM (error);
3432  goto out;
3433  }
3434 
3435  ret = 0;
3436  do
3437  {
3438  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3439  }
3440  while (ret > 0);
3441 
3442  _dbus_string_set_length (result, orig_len);
3443  if (_dbus_string_get_length (&error_message) > 0)
3445  "%s terminated abnormally with the following error: %s",
3446  progpath, _dbus_string_get_data (&error_message));
3447  else
3449  "%s terminated abnormally without any error message",
3450  progpath);
3451  goto out;
3452  }
3453 
3454  retval = TRUE;
3455 
3456  out:
3457  sigprocmask (SIG_SETMASK, &old_set, NULL);
3458 
3459  if (retval)
3460  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3461  else
3462  _DBUS_ASSERT_ERROR_IS_SET (error);
3463 
3464  if (result_pipe[0] != -1)
3465  close (result_pipe[0]);
3466  if (result_pipe[1] != -1)
3467  close (result_pipe[1]);
3468  if (errors_pipe[0] != -1)
3469  close (errors_pipe[0]);
3470  if (errors_pipe[1] != -1)
3471  close (errors_pipe[1]);
3472 
3473  return retval;
3474 }
3475 
3488 _dbus_get_autolaunch_address (const char *scope,
3489  DBusString *address,
3490  DBusError *error)
3491 {
3492 #if 1
3493  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3494  * but that's done elsewhere, and if it worked, this function wouldn't
3495  * be called.) */
3496  const char *display;
3497  static char *argv[6];
3498  int i;
3499  DBusString uuid;
3500  dbus_bool_t retval;
3501 
3502  if (_dbus_check_setuid ())
3503  {
3505  "Unable to autolaunch when setuid");
3506  return FALSE;
3507  }
3508 
3509  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3510  retval = FALSE;
3511 
3512  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3513  * dbus-launch-x11 is just going to fail. Rather than trying to
3514  * run it, we might as well bail out early with a nice error. */
3515  display = _dbus_getenv ("DISPLAY");
3516 
3517  if (display == NULL || display[0] == '\0')
3518  {
3520  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3521  return FALSE;
3522  }
3523 
3524  if (!_dbus_string_init (&uuid))
3525  {
3526  _DBUS_SET_OOM (error);
3527  return FALSE;
3528  }
3529 
3531  {
3532  _DBUS_SET_OOM (error);
3533  goto out;
3534  }
3535 
3536  i = 0;
3537  argv[i] = "dbus-launch";
3538  ++i;
3539  argv[i] = "--autolaunch";
3540  ++i;
3541  argv[i] = _dbus_string_get_data (&uuid);
3542  ++i;
3543  argv[i] = "--binary-syntax";
3544  ++i;
3545  argv[i] = "--close-stderr";
3546  ++i;
3547  argv[i] = NULL;
3548  ++i;
3549 
3550  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3551 
3552  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3553  TRUE,
3554  argv, address, error);
3555 
3556  out:
3557  _dbus_string_free (&uuid);
3558  return retval;
3559 #else
3561  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3562  "set your DBUS_SESSION_BUS_ADDRESS instead");
3563  return FALSE;
3564 #endif
3565 }
3566 
3587  dbus_bool_t create_if_not_found,
3588  DBusError *error)
3589 {
3590  DBusString filename;
3591  dbus_bool_t b;
3592 
3593  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3594 
3595  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3596  if (b)
3597  return TRUE;
3598 
3599  dbus_error_free (error);
3600 
3601  /* Fallback to the system machine ID */
3602  _dbus_string_init_const (&filename, "/etc/machine-id");
3603  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3604 }
3605 
3606 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3607 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3608 
3617  const char *launchd_env_var,
3618  DBusError *error)
3619 {
3620 #ifdef DBUS_ENABLE_LAUNCHD
3621  char *argv[4];
3622  int i;
3623 
3624  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3625 
3626  if (_dbus_check_setuid ())
3627  {
3629  "Unable to find launchd socket when setuid");
3630  return FALSE;
3631  }
3632 
3633  i = 0;
3634  argv[i] = "launchctl";
3635  ++i;
3636  argv[i] = "getenv";
3637  ++i;
3638  argv[i] = (char*)launchd_env_var;
3639  ++i;
3640  argv[i] = NULL;
3641  ++i;
3642 
3643  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3644 
3645  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3646  {
3647  return FALSE;
3648  }
3649 
3650  /* no error, but no result either */
3651  if (_dbus_string_get_length(socket_path) == 0)
3652  {
3653  return FALSE;
3654  }
3655 
3656  /* strip the carriage-return */
3657  _dbus_string_shorten(socket_path, 1);
3658  return TRUE;
3659 #else /* DBUS_ENABLE_LAUNCHD */
3661  "can't lookup socket from launchd; launchd support not compiled in");
3662  return FALSE;
3663 #endif
3664 }
3665 
3666 #ifdef DBUS_ENABLE_LAUNCHD
3667 static dbus_bool_t
3668 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3669 {
3670  dbus_bool_t valid_socket;
3671  DBusString socket_path;
3672 
3673  if (_dbus_check_setuid ())
3674  {
3676  "Unable to find launchd socket when setuid");
3677  return FALSE;
3678  }
3679 
3680  if (!_dbus_string_init (&socket_path))
3681  {
3682  _DBUS_SET_OOM (error);
3683  return FALSE;
3684  }
3685 
3686  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3687 
3688  if (dbus_error_is_set(error))
3689  {
3690  _dbus_string_free(&socket_path);
3691  return FALSE;
3692  }
3693 
3694  if (!valid_socket)
3695  {
3696  dbus_set_error(error, "no socket path",
3697  "launchd did not provide a socket path, "
3698  "verify that org.freedesktop.dbus-session.plist is loaded!");
3699  _dbus_string_free(&socket_path);
3700  return FALSE;
3701  }
3702  if (!_dbus_string_append (address, "unix:path="))
3703  {
3704  _DBUS_SET_OOM (error);
3705  _dbus_string_free(&socket_path);
3706  return FALSE;
3707  }
3708  if (!_dbus_string_copy (&socket_path, 0, address,
3709  _dbus_string_get_length (address)))
3710  {
3711  _DBUS_SET_OOM (error);
3712  _dbus_string_free(&socket_path);
3713  return FALSE;
3714  }
3715 
3716  _dbus_string_free(&socket_path);
3717  return TRUE;
3718 }
3719 #endif
3720 
3742  DBusString *address,
3743  DBusError *error)
3744 {
3745 #ifdef DBUS_ENABLE_LAUNCHD
3746  *supported = TRUE;
3747  return _dbus_lookup_session_address_launchd (address, error);
3748 #else
3749  /* On non-Mac Unix platforms, if the session address isn't already
3750  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3751  * fall back to the autolaunch: global default; see
3752  * init_session_address in dbus/dbus-bus.c. */
3753  *supported = FALSE;
3754  return TRUE;
3755 #endif
3756 }
3757 
3777 {
3778  const char *xdg_data_home;
3779  const char *xdg_data_dirs;
3780  DBusString servicedir_path;
3781 
3782  if (!_dbus_string_init (&servicedir_path))
3783  return FALSE;
3784 
3785  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3786  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3787 
3788  if (xdg_data_home != NULL)
3789  {
3790  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3791  goto oom;
3792  }
3793  else
3794  {
3795  const DBusString *homedir;
3796  DBusString local_share;
3797 
3798  if (!_dbus_homedir_from_current_process (&homedir))
3799  goto oom;
3800 
3801  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3802  goto oom;
3803 
3804  _dbus_string_init_const (&local_share, "/.local/share");
3805  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3806  goto oom;
3807  }
3808 
3809  if (!_dbus_string_append (&servicedir_path, ":"))
3810  goto oom;
3811 
3812  if (xdg_data_dirs != NULL)
3813  {
3814  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3815  goto oom;
3816 
3817  if (!_dbus_string_append (&servicedir_path, ":"))
3818  goto oom;
3819  }
3820  else
3821  {
3822  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3823  goto oom;
3824  }
3825 
3826  /*
3827  * add configured datadir to defaults
3828  * this may be the same as an xdg dir
3829  * however the config parser should take
3830  * care of duplicates
3831  */
3832  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3833  goto oom;
3834 
3835  if (!_dbus_split_paths_and_append (&servicedir_path,
3836  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3837  dirs))
3838  goto oom;
3839 
3840  _dbus_string_free (&servicedir_path);
3841  return TRUE;
3842 
3843  oom:
3844  _dbus_string_free (&servicedir_path);
3845  return FALSE;
3846 }
3847 
3848 
3869 {
3870  /*
3871  * DBUS_DATADIR may be the same as one of the standard directories. However,
3872  * the config parser should take care of the duplicates.
3873  *
3874  * Also, append /lib as counterpart of /usr/share on the root
3875  * directory (the root directory does not know /share), in order to
3876  * facilitate early boot system bus activation where /usr might not
3877  * be available.
3878  */
3879  static const char standard_search_path[] =
3880  "/usr/local/share:"
3881  "/usr/share:"
3882  DBUS_DATADIR ":"
3883  "/lib";
3884  DBusString servicedir_path;
3885 
3886  _dbus_string_init_const (&servicedir_path, standard_search_path);
3887 
3888  return _dbus_split_paths_and_append (&servicedir_path,
3889  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3890  dirs);
3891 }
3892 
3903 {
3904  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3905 }
3906 
3915 {
3916  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3917 }
3918 
3926 void
3928 {
3930 }
3931 
3947  DBusCredentials *credentials)
3948 {
3949  DBusString homedir;
3950  DBusString dotdir;
3951  dbus_uid_t uid;
3952 
3953  _dbus_assert (credentials != NULL);
3955 
3956  if (!_dbus_string_init (&homedir))
3957  return FALSE;
3958 
3959  uid = _dbus_credentials_get_unix_uid (credentials);
3960  _dbus_assert (uid != DBUS_UID_UNSET);
3961 
3962  if (!_dbus_homedir_from_uid (uid, &homedir))
3963  goto failed;
3964 
3965 #ifdef DBUS_BUILD_TESTS
3966  {
3967  const char *override;
3968 
3969  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3970  if (override != NULL && *override != '\0')
3971  {
3972  _dbus_string_set_length (&homedir, 0);
3973  if (!_dbus_string_append (&homedir, override))
3974  goto failed;
3975 
3976  _dbus_verbose ("Using fake homedir for testing: %s\n",
3977  _dbus_string_get_const_data (&homedir));
3978  }
3979  else
3980  {
3981  static dbus_bool_t already_warned = FALSE;
3982  if (!already_warned)
3983  {
3984  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3985  already_warned = TRUE;
3986  }
3987  }
3988  }
3989 #endif
3990 
3991  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3992  if (!_dbus_concat_dir_and_file (&homedir,
3993  &dotdir))
3994  goto failed;
3995 
3996  if (!_dbus_string_copy (&homedir, 0,
3997  directory, _dbus_string_get_length (directory))) {
3998  goto failed;
3999  }
4000 
4001  _dbus_string_free (&homedir);
4002  return TRUE;
4003 
4004  failed:
4005  _dbus_string_free (&homedir);
4006  return FALSE;
4007 }
4008 
4009 //PENDING(kdab) docs
4011 _dbus_daemon_publish_session_bus_address (const char* addr,
4012  const char *scope)
4013 {
4014  return TRUE;
4015 }
4016 
4017 //PENDING(kdab) docs
4018 void
4019 _dbus_daemon_unpublish_session_bus_address (void)
4020 {
4021 
4022 }
4023 
4032 {
4033  return errno == EAGAIN || errno == EWOULDBLOCK;
4034 }
4035 
4045  DBusError *error)
4046 {
4047  const char *filename_c;
4048 
4049  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4050 
4051  filename_c = _dbus_string_get_const_data (filename);
4052 
4053  if (rmdir (filename_c) != 0)
4054  {
4056  "Failed to remove directory %s: %s\n",
4057  filename_c, _dbus_strerror (errno));
4058  return FALSE;
4059  }
4060 
4061  return TRUE;
4062 }
4063 
4073 
4074 #ifdef SCM_RIGHTS
4075  union {
4076  struct sockaddr sa;
4077  struct sockaddr_storage storage;
4078  struct sockaddr_un un;
4079  } sa_buf;
4080 
4081  socklen_t sa_len = sizeof(sa_buf);
4082 
4083  _DBUS_ZERO(sa_buf);
4084 
4085  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4086  return FALSE;
4087 
4088  return sa_buf.sa.sa_family == AF_UNIX;
4089 
4090 #else
4091  return FALSE;
4092 
4093 #endif
4094 }
4095 
4096 
4097 /*
4098  * replaces the term DBUS_PREFIX in configure_time_path by the
4099  * current dbus installation directory. On unix this function is a noop
4100  *
4101  * @param configure_time_path
4102  * @return real path
4103  */
4104 const char *
4105 _dbus_replace_install_prefix (const char *configure_time_path)
4106 {
4107  return configure_time_path;
4108 }
4109 
4114 void
4116 {
4117  int maxfds, i;
4118 
4119 #ifdef __linux__
4120  DIR *d;
4121 
4122  /* On Linux we can optimize this a bit if /proc is available. If it
4123  isn't available, fall back to the brute force way. */
4124 
4125  d = opendir ("/proc/self/fd");
4126  if (d)
4127  {
4128  for (;;)
4129  {
4130  struct dirent buf, *de;
4131  int k, fd;
4132  long l;
4133  char *e = NULL;
4134 
4135  k = readdir_r (d, &buf, &de);
4136  if (k != 0 || !de)
4137  break;
4138 
4139  if (de->d_name[0] == '.')
4140  continue;
4141 
4142  errno = 0;
4143  l = strtol (de->d_name, &e, 10);
4144  if (errno != 0 || e == NULL || *e != '\0')
4145  continue;
4146 
4147  fd = (int) l;
4148  if (fd < 3)
4149  continue;
4150 
4151  if (fd == dirfd (d))
4152  continue;
4153 
4154  close (fd);
4155  }
4156 
4157  closedir (d);
4158  return;
4159  }
4160 #endif
4161 
4162  maxfds = sysconf (_SC_OPEN_MAX);
4163 
4164  /* Pick something reasonable if for some reason sysconf says
4165  * unlimited.
4166  */
4167  if (maxfds < 0)
4168  maxfds = 1024;
4169 
4170  /* close all inherited fds */
4171  for (i = 3; i < maxfds; i++)
4172  close (i);
4173 }
4174 
4186 {
4187  /* TODO: get __libc_enable_secure exported from glibc.
4188  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4189  */
4190 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4191  {
4192  /* See glibc/include/unistd.h */
4193  extern int __libc_enable_secure;
4194  return __libc_enable_secure;
4195  }
4196 #elif defined(HAVE_ISSETUGID)
4197  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4198  return issetugid ();
4199 #else
4200  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4201  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4202 
4203  static dbus_bool_t check_setuid_initialised;
4204  static dbus_bool_t is_setuid;
4205 
4206  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4207  {
4208 #ifdef HAVE_GETRESUID
4209  if (getresuid (&ruid, &euid, &suid) != 0 ||
4210  getresgid (&rgid, &egid, &sgid) != 0)
4211 #endif /* HAVE_GETRESUID */
4212  {
4213  suid = ruid = getuid ();
4214  sgid = rgid = getgid ();
4215  euid = geteuid ();
4216  egid = getegid ();
4217  }
4218 
4219  check_setuid_initialised = TRUE;
4220  is_setuid = (ruid != euid || ruid != suid ||
4221  rgid != egid || rgid != sgid);
4222 
4223  }
4224  return is_setuid;
4225 #endif
4226 }
4227 
4228 /* tests in dbus-sysdeps-util.c */