D-Bus  1.4.10
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 
75 #ifdef HAVE_ADT
76 #include <bsm/adt.h>
77 #endif
78 
79 #include "sd-daemon.h"
80 
81 #ifndef O_BINARY
82 #define O_BINARY 0
83 #endif
84 
85 #ifndef AI_ADDRCONFIG
86 #define AI_ADDRCONFIG 0
87 #endif
88 
89 #ifndef HAVE_SOCKLEN_T
90 #define socklen_t int
91 #endif
92 
93 static dbus_bool_t
94 _dbus_open_socket (int *fd_p,
95  int domain,
96  int type,
97  int protocol,
98  DBusError *error)
99 {
100 #ifdef SOCK_CLOEXEC
101  dbus_bool_t cloexec_done;
102 
103  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
104  cloexec_done = *fd_p >= 0;
105 
106  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
107  if (*fd_p < 0 && errno == EINVAL)
108 #endif
109  {
110  *fd_p = socket (domain, type, protocol);
111  }
112 
113  if (*fd_p >= 0)
114  {
115 #ifdef SOCK_CLOEXEC
116  if (!cloexec_done)
117 #endif
118  {
120  }
121 
122  _dbus_verbose ("socket fd %d opened\n", *fd_p);
123  return TRUE;
124  }
125  else
126  {
127  dbus_set_error(error,
128  _dbus_error_from_errno (errno),
129  "Failed to open socket: %s",
130  _dbus_strerror (errno));
131  return FALSE;
132  }
133 }
134 
137  DBusError *error)
138 {
139  return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
140 }
141 
154  DBusError *error)
155 {
156  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
157 }
158 
169  DBusError *error)
170 {
171  return _dbus_close (fd, error);
172 }
173 
183 int
185  DBusString *buffer,
186  int count)
187 {
188  return _dbus_read (fd, buffer, count);
189 }
190 
201 int
203  const DBusString *buffer,
204  int start,
205  int len)
206 {
207 #if HAVE_DECL_MSG_NOSIGNAL
208  const char *data;
209  int bytes_written;
210 
211  data = _dbus_string_get_const_data_len (buffer, start, len);
212 
213  again:
214 
215  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
216 
217  if (bytes_written < 0 && errno == EINTR)
218  goto again;
219 
220  return bytes_written;
221 
222 #else
223  return _dbus_write (fd, buffer, start, len);
224 #endif
225 }
226 
239 int
241  DBusString *buffer,
242  int count,
243  int *fds,
244  int *n_fds) {
245 #ifndef HAVE_UNIX_FD_PASSING
246  int r;
247 
248  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
249  return r;
250 
251  *n_fds = 0;
252  return r;
253 
254 #else
255  int bytes_read;
256  int start;
257  struct msghdr m;
258  struct iovec iov;
259 
260  _dbus_assert (count >= 0);
261  _dbus_assert (*n_fds >= 0);
262 
263  start = _dbus_string_get_length (buffer);
264 
265  if (!_dbus_string_lengthen (buffer, count))
266  {
267  errno = ENOMEM;
268  return -1;
269  }
270 
271  _DBUS_ZERO(iov);
272  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
273  iov.iov_len = count;
274 
275  _DBUS_ZERO(m);
276  m.msg_iov = &iov;
277  m.msg_iovlen = 1;
278 
279  /* Hmm, we have no clue how long the control data will actually be
280  that is queued for us. The least we can do is assume that the
281  caller knows. Hence let's make space for the number of fds that
282  we shall read at max plus the cmsg header. */
283  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
284 
285  /* It's probably safe to assume that systems with SCM_RIGHTS also
286  know alloca() */
287  m.msg_control = alloca(m.msg_controllen);
288  memset(m.msg_control, 0, m.msg_controllen);
289 
290  again:
291 
292  bytes_read = recvmsg(fd, &m, 0
293 #ifdef MSG_CMSG_CLOEXEC
294  |MSG_CMSG_CLOEXEC
295 #endif
296  );
297 
298  if (bytes_read < 0)
299  {
300  if (errno == EINTR)
301  goto again;
302  else
303  {
304  /* put length back (note that this doesn't actually realloc anything) */
305  _dbus_string_set_length (buffer, start);
306  return -1;
307  }
308  }
309  else
310  {
311  struct cmsghdr *cm;
312  dbus_bool_t found = FALSE;
313 
314  if (m.msg_flags & MSG_CTRUNC)
315  {
316  /* Hmm, apparently the control data was truncated. The bad
317  thing is that we might have completely lost a couple of fds
318  without chance to recover them. Hence let's treat this as a
319  serious error. */
320 
321  errno = ENOSPC;
322  _dbus_string_set_length (buffer, start);
323  return -1;
324  }
325 
326  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
327  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
328  {
329  unsigned i;
330 
331  _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
332  *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
333 
334  memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
335  found = TRUE;
336 
337  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
338  worked, hence we need to go through this list and set
339  CLOEXEC everywhere in any case */
340  for (i = 0; i < *n_fds; i++)
342 
343  break;
344  }
345 
346  if (!found)
347  *n_fds = 0;
348 
349  /* put length back (doesn't actually realloc) */
350  _dbus_string_set_length (buffer, start + bytes_read);
351 
352 #if 0
353  if (bytes_read > 0)
354  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
355 #endif
356 
357  return bytes_read;
358  }
359 #endif
360 }
361 
362 int
363 _dbus_write_socket_with_unix_fds(int fd,
364  const DBusString *buffer,
365  int start,
366  int len,
367  const int *fds,
368  int n_fds) {
369 
370 #ifndef HAVE_UNIX_FD_PASSING
371 
372  if (n_fds > 0) {
373  errno = ENOTSUP;
374  return -1;
375  }
376 
377  return _dbus_write_socket(fd, buffer, start, len);
378 #else
379  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
380 #endif
381 }
382 
383 int
384 _dbus_write_socket_with_unix_fds_two(int fd,
385  const DBusString *buffer1,
386  int start1,
387  int len1,
388  const DBusString *buffer2,
389  int start2,
390  int len2,
391  const int *fds,
392  int n_fds) {
393 
394 #ifndef HAVE_UNIX_FD_PASSING
395 
396  if (n_fds > 0) {
397  errno = ENOTSUP;
398  return -1;
399  }
400 
401  return _dbus_write_socket_two(fd,
402  buffer1, start1, len1,
403  buffer2, start2, len2);
404 #else
405 
406  struct msghdr m;
407  struct cmsghdr *cm;
408  struct iovec iov[2];
409  int bytes_written;
410 
411  _dbus_assert (len1 >= 0);
412  _dbus_assert (len2 >= 0);
413  _dbus_assert (n_fds >= 0);
414 
415  _DBUS_ZERO(iov);
416  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
417  iov[0].iov_len = len1;
418 
419  if (buffer2)
420  {
421  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
422  iov[1].iov_len = len2;
423  }
424 
425  _DBUS_ZERO(m);
426  m.msg_iov = iov;
427  m.msg_iovlen = buffer2 ? 2 : 1;
428 
429  if (n_fds > 0)
430  {
431  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
432  m.msg_control = alloca(m.msg_controllen);
433  memset(m.msg_control, 0, m.msg_controllen);
434 
435  cm = CMSG_FIRSTHDR(&m);
436  cm->cmsg_level = SOL_SOCKET;
437  cm->cmsg_type = SCM_RIGHTS;
438  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
439  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
440  }
441 
442  again:
443 
444  bytes_written = sendmsg (fd, &m, 0
445 #if HAVE_DECL_MSG_NOSIGNAL
446  |MSG_NOSIGNAL
447 #endif
448  );
449 
450  if (bytes_written < 0 && errno == EINTR)
451  goto again;
452 
453 #if 0
454  if (bytes_written > 0)
455  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
456 #endif
457 
458  return bytes_written;
459 #endif
460 }
461 
475 int
477  const DBusString *buffer1,
478  int start1,
479  int len1,
480  const DBusString *buffer2,
481  int start2,
482  int len2)
483 {
484 #if HAVE_DECL_MSG_NOSIGNAL
485  struct iovec vectors[2];
486  const char *data1;
487  const char *data2;
488  int bytes_written;
489  struct msghdr m;
490 
491  _dbus_assert (buffer1 != NULL);
492  _dbus_assert (start1 >= 0);
493  _dbus_assert (start2 >= 0);
494  _dbus_assert (len1 >= 0);
495  _dbus_assert (len2 >= 0);
496 
497  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
498 
499  if (buffer2 != NULL)
500  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
501  else
502  {
503  data2 = NULL;
504  start2 = 0;
505  len2 = 0;
506  }
507 
508  vectors[0].iov_base = (char*) data1;
509  vectors[0].iov_len = len1;
510  vectors[1].iov_base = (char*) data2;
511  vectors[1].iov_len = len2;
512 
513  _DBUS_ZERO(m);
514  m.msg_iov = vectors;
515  m.msg_iovlen = data2 ? 2 : 1;
516 
517  again:
518 
519  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
520 
521  if (bytes_written < 0 && errno == EINTR)
522  goto again;
523 
524  return bytes_written;
525 
526 #else
527  return _dbus_write_two (fd, buffer1, start1, len1,
528  buffer2, start2, len2);
529 #endif
530 }
531 
533 _dbus_socket_is_invalid (int fd)
534 {
535  return fd < 0 ? TRUE : FALSE;
536 }
537 
554 int
555 _dbus_read (int fd,
556  DBusString *buffer,
557  int count)
558 {
559  int bytes_read;
560  int start;
561  char *data;
562 
563  _dbus_assert (count >= 0);
564 
565  start = _dbus_string_get_length (buffer);
566 
567  if (!_dbus_string_lengthen (buffer, count))
568  {
569  errno = ENOMEM;
570  return -1;
571  }
572 
573  data = _dbus_string_get_data_len (buffer, start, count);
574 
575  again:
576 
577  bytes_read = read (fd, data, count);
578 
579  if (bytes_read < 0)
580  {
581  if (errno == EINTR)
582  goto again;
583  else
584  {
585  /* put length back (note that this doesn't actually realloc anything) */
586  _dbus_string_set_length (buffer, start);
587  return -1;
588  }
589  }
590  else
591  {
592  /* put length back (doesn't actually realloc) */
593  _dbus_string_set_length (buffer, start + bytes_read);
594 
595 #if 0
596  if (bytes_read > 0)
597  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
598 #endif
599 
600  return bytes_read;
601  }
602 }
603 
614 int
615 _dbus_write (int fd,
616  const DBusString *buffer,
617  int start,
618  int len)
619 {
620  const char *data;
621  int bytes_written;
622 
623  data = _dbus_string_get_const_data_len (buffer, start, len);
624 
625  again:
626 
627  bytes_written = write (fd, data, len);
628 
629  if (bytes_written < 0 && errno == EINTR)
630  goto again;
631 
632 #if 0
633  if (bytes_written > 0)
634  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
635 #endif
636 
637  return bytes_written;
638 }
639 
660 int
662  const DBusString *buffer1,
663  int start1,
664  int len1,
665  const DBusString *buffer2,
666  int start2,
667  int len2)
668 {
669  _dbus_assert (buffer1 != NULL);
670  _dbus_assert (start1 >= 0);
671  _dbus_assert (start2 >= 0);
672  _dbus_assert (len1 >= 0);
673  _dbus_assert (len2 >= 0);
674 
675 #ifdef HAVE_WRITEV
676  {
677  struct iovec vectors[2];
678  const char *data1;
679  const char *data2;
680  int bytes_written;
681 
682  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
683 
684  if (buffer2 != NULL)
685  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
686  else
687  {
688  data2 = NULL;
689  start2 = 0;
690  len2 = 0;
691  }
692 
693  vectors[0].iov_base = (char*) data1;
694  vectors[0].iov_len = len1;
695  vectors[1].iov_base = (char*) data2;
696  vectors[1].iov_len = len2;
697 
698  again:
699 
700  bytes_written = writev (fd,
701  vectors,
702  data2 ? 2 : 1);
703 
704  if (bytes_written < 0 && errno == EINTR)
705  goto again;
706 
707  return bytes_written;
708  }
709 #else /* HAVE_WRITEV */
710  {
711  int ret1;
712 
713  ret1 = _dbus_write (fd, buffer1, start1, len1);
714  if (ret1 == len1 && buffer2 != NULL)
715  {
716  ret2 = _dbus_write (fd, buffer2, start2, len2);
717  if (ret2 < 0)
718  ret2 = 0; /* we can't report an error as the first write was OK */
719 
720  return ret1 + ret2;
721  }
722  else
723  return ret1;
724  }
725 #endif /* !HAVE_WRITEV */
726 }
727 
728 #define _DBUS_MAX_SUN_PATH_LENGTH 99
729 
759 int
760 _dbus_connect_unix_socket (const char *path,
761  dbus_bool_t abstract,
762  DBusError *error)
763 {
764  int fd;
765  size_t path_len;
766  struct sockaddr_un addr;
767 
768  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
769 
770  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
771  path, abstract);
772 
773 
774  if (!_dbus_open_unix_socket (&fd, error))
775  {
776  _DBUS_ASSERT_ERROR_IS_SET(error);
777  return -1;
778  }
779  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
780 
781  _DBUS_ZERO (addr);
782  addr.sun_family = AF_UNIX;
783  path_len = strlen (path);
784 
785  if (abstract)
786  {
787 #ifdef HAVE_ABSTRACT_SOCKETS
788  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
789  path_len++; /* Account for the extra nul byte added to the start of sun_path */
790 
791  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
792  {
794  "Abstract socket name too long\n");
795  _dbus_close (fd, NULL);
796  return -1;
797  }
798 
799  strncpy (&addr.sun_path[1], path, path_len);
800  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
801 #else /* HAVE_ABSTRACT_SOCKETS */
803  "Operating system does not support abstract socket namespace\n");
804  _dbus_close (fd, NULL);
805  return -1;
806 #endif /* ! HAVE_ABSTRACT_SOCKETS */
807  }
808  else
809  {
810  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
811  {
813  "Socket name too long\n");
814  _dbus_close (fd, NULL);
815  return -1;
816  }
817 
818  strncpy (addr.sun_path, path, path_len);
819  }
820 
821  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
822  {
823  dbus_set_error (error,
824  _dbus_error_from_errno (errno),
825  "Failed to connect to socket %s: %s",
826  path, _dbus_strerror (errno));
827 
828  _dbus_close (fd, NULL);
829  fd = -1;
830 
831  return -1;
832  }
833 
834  if (!_dbus_set_fd_nonblocking (fd, error))
835  {
836  _DBUS_ASSERT_ERROR_IS_SET (error);
837 
838  _dbus_close (fd, NULL);
839  fd = -1;
840 
841  return -1;
842  }
843 
844  return fd;
845 }
846 
856 static dbus_bool_t
857 _dbus_set_local_creds (int fd, dbus_bool_t on)
858 {
859  dbus_bool_t retval = TRUE;
860 
861 #if defined(HAVE_CMSGCRED)
862  /* NOOP just to make sure only one codepath is used
863  * and to prefer CMSGCRED
864  */
865 #elif defined(LOCAL_CREDS)
866  int val = on ? 1 : 0;
867  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
868  {
869  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
870  retval = FALSE;
871  }
872  else
873  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
874  on ? "enabled" : "disabled", fd);
875 #endif
876 
877  return retval;
878 }
879 
897 int
898 _dbus_listen_unix_socket (const char *path,
899  dbus_bool_t abstract,
900  DBusError *error)
901 {
902  int listen_fd;
903  struct sockaddr_un addr;
904  size_t path_len;
905  unsigned int reuseaddr;
906 
907  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
908 
909  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
910  path, abstract);
911 
912  if (!_dbus_open_unix_socket (&listen_fd, error))
913  {
914  _DBUS_ASSERT_ERROR_IS_SET(error);
915  return -1;
916  }
917  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
918 
919  _DBUS_ZERO (addr);
920  addr.sun_family = AF_UNIX;
921  path_len = strlen (path);
922 
923  if (abstract)
924  {
925 #ifdef HAVE_ABSTRACT_SOCKETS
926  /* remember that abstract names aren't nul-terminated so we rely
927  * on sun_path being filled in with zeroes above.
928  */
929  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
930  path_len++; /* Account for the extra nul byte added to the start of sun_path */
931 
932  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
933  {
935  "Abstract socket name too long\n");
936  _dbus_close (listen_fd, NULL);
937  return -1;
938  }
939 
940  strncpy (&addr.sun_path[1], path, path_len);
941  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
942 #else /* HAVE_ABSTRACT_SOCKETS */
944  "Operating system does not support abstract socket namespace\n");
945  _dbus_close (listen_fd, NULL);
946  return -1;
947 #endif /* ! HAVE_ABSTRACT_SOCKETS */
948  }
949  else
950  {
951  /* Discussed security implications of this with Nalin,
952  * and we couldn't think of where it would kick our ass, but
953  * it still seems a bit sucky. It also has non-security suckage;
954  * really we'd prefer to exit if the socket is already in use.
955  * But there doesn't seem to be a good way to do this.
956  *
957  * Just to be extra careful, I threw in the stat() - clearly
958  * the stat() can't *fix* any security issue, but it at least
959  * avoids inadvertent/accidental data loss.
960  */
961  {
962  struct stat sb;
963 
964  if (stat (path, &sb) == 0 &&
965  S_ISSOCK (sb.st_mode))
966  unlink (path);
967  }
968 
969  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
970  {
972  "Abstract socket name too long\n");
973  _dbus_close (listen_fd, NULL);
974  return -1;
975  }
976 
977  strncpy (addr.sun_path, path, path_len);
978  }
979 
980  reuseaddr = 1;
981  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
982  {
983  _dbus_warn ("Failed to set socket option\"%s\": %s",
984  path, _dbus_strerror (errno));
985  }
986 
987  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
988  {
989  dbus_set_error (error, _dbus_error_from_errno (errno),
990  "Failed to bind socket \"%s\": %s",
991  path, _dbus_strerror (errno));
992  _dbus_close (listen_fd, NULL);
993  return -1;
994  }
995 
996  if (listen (listen_fd, 30 /* backlog */) < 0)
997  {
998  dbus_set_error (error, _dbus_error_from_errno (errno),
999  "Failed to listen on socket \"%s\": %s",
1000  path, _dbus_strerror (errno));
1001  _dbus_close (listen_fd, NULL);
1002  return -1;
1003  }
1004 
1005  if (!_dbus_set_local_creds (listen_fd, TRUE))
1006  {
1007  dbus_set_error (error, _dbus_error_from_errno (errno),
1008  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1009  path, _dbus_strerror (errno));
1010  close (listen_fd);
1011  return -1;
1012  }
1013 
1014  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1015  {
1016  _DBUS_ASSERT_ERROR_IS_SET (error);
1017  _dbus_close (listen_fd, NULL);
1018  return -1;
1019  }
1020 
1021  /* Try opening up the permissions, but if we can't, just go ahead
1022  * and continue, maybe it will be good enough.
1023  */
1024  if (!abstract && chmod (path, 0777) < 0)
1025  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1026  path);
1027 
1028  return listen_fd;
1029 }
1030 
1041 int
1043  DBusError *error)
1044 {
1045  int r, n;
1046  unsigned fd;
1047  int *new_fds;
1048 
1049  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1050 
1051  n = sd_listen_fds (TRUE);
1052  if (n < 0)
1053  {
1055  "Failed to acquire systemd socket: %s",
1056  _dbus_strerror (-n));
1057  return -1;
1058  }
1059 
1060  if (n <= 0)
1061  {
1063  "No socket received.");
1064  return -1;
1065  }
1066 
1067  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1068  {
1069  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1070  if (r < 0)
1071  {
1073  "Failed to verify systemd socket type: %s",
1074  _dbus_strerror (-r));
1075  return -1;
1076  }
1077 
1078  if (!r)
1079  {
1081  "Passed socket has wrong type.");
1082  return -1;
1083  }
1084  }
1085 
1086  /* OK, the file descriptors are all good, so let's take posession of
1087  them then. */
1088 
1089  new_fds = dbus_new (int, n);
1090  if (!new_fds)
1091  {
1093  "Failed to allocate file handle array.");
1094  goto fail;
1095  }
1096 
1097  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1098  {
1099  if (!_dbus_set_local_creds (fd, TRUE))
1100  {
1101  dbus_set_error (error, _dbus_error_from_errno (errno),
1102  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1103  _dbus_strerror (errno));
1104  goto fail;
1105  }
1106 
1107  if (!_dbus_set_fd_nonblocking (fd, error))
1108  {
1109  _DBUS_ASSERT_ERROR_IS_SET (error);
1110  goto fail;
1111  }
1112 
1113  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1114  }
1115 
1116  *fds = new_fds;
1117  return n;
1118 
1119  fail:
1120 
1121  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1122  {
1123  _dbus_close (fd, NULL);
1124  }
1125 
1126  dbus_free (new_fds);
1127  return -1;
1128 }
1129 
1143 int
1144 _dbus_connect_tcp_socket (const char *host,
1145  const char *port,
1146  const char *family,
1147  DBusError *error)
1148 {
1149  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1150 }
1151 
1152 int
1153 _dbus_connect_tcp_socket_with_nonce (const char *host,
1154  const char *port,
1155  const char *family,
1156  const char *noncefile,
1157  DBusError *error)
1158 {
1159  int saved_errno = 0;
1160  int fd = -1, res;
1161  struct addrinfo hints;
1162  struct addrinfo *ai, *tmp;
1163 
1164  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1165 
1166  if (!_dbus_open_tcp_socket (&fd, error))
1167  {
1168  _DBUS_ASSERT_ERROR_IS_SET(error);
1169  return -1;
1170  }
1171 
1172  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1173 
1174  _DBUS_ZERO (hints);
1175 
1176  if (!family)
1177  hints.ai_family = AF_UNSPEC;
1178  else if (!strcmp(family, "ipv4"))
1179  hints.ai_family = AF_INET;
1180  else if (!strcmp(family, "ipv6"))
1181  hints.ai_family = AF_INET6;
1182  else
1183  {
1184  dbus_set_error (error,
1186  "Unknown address family %s", family);
1187  return -1;
1188  }
1189  hints.ai_protocol = IPPROTO_TCP;
1190  hints.ai_socktype = SOCK_STREAM;
1191  hints.ai_flags = AI_ADDRCONFIG;
1192 
1193  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1194  {
1195  dbus_set_error (error,
1196  _dbus_error_from_errno (errno),
1197  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1198  host, port, gai_strerror(res), res);
1199  _dbus_close (fd, NULL);
1200  return -1;
1201  }
1202 
1203  tmp = ai;
1204  while (tmp)
1205  {
1206  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1207  {
1208  freeaddrinfo(ai);
1209  _DBUS_ASSERT_ERROR_IS_SET(error);
1210  return -1;
1211  }
1212  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1213 
1214  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1215  {
1216  saved_errno = errno;
1217  _dbus_close(fd, NULL);
1218  fd = -1;
1219  tmp = tmp->ai_next;
1220  continue;
1221  }
1222 
1223  break;
1224  }
1225  freeaddrinfo(ai);
1226 
1227  if (fd == -1)
1228  {
1229  dbus_set_error (error,
1230  _dbus_error_from_errno (saved_errno),
1231  "Failed to connect to socket \"%s:%s\" %s",
1232  host, port, _dbus_strerror(saved_errno));
1233  return -1;
1234  }
1235 
1236  if (noncefile != NULL)
1237  {
1238  DBusString noncefileStr;
1239  dbus_bool_t ret;
1240  _dbus_string_init_const (&noncefileStr, noncefile);
1241  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1242  _dbus_string_free (&noncefileStr);
1243 
1244  if (!ret)
1245  {
1246  _dbus_close (fd, NULL);
1247  return -1;
1248  }
1249  }
1250 
1251  if (!_dbus_set_fd_nonblocking (fd, error))
1252  {
1253  _dbus_close (fd, NULL);
1254  return -1;
1255  }
1256 
1257  return fd;
1258 }
1259 
1276 int
1277 _dbus_listen_tcp_socket (const char *host,
1278  const char *port,
1279  const char *family,
1280  DBusString *retport,
1281  int **fds_p,
1282  DBusError *error)
1283 {
1284  int saved_errno;
1285  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1286  struct addrinfo hints;
1287  struct addrinfo *ai, *tmp;
1288  unsigned int reuseaddr;
1289 
1290  *fds_p = NULL;
1291  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1292 
1293  _DBUS_ZERO (hints);
1294 
1295  if (!family)
1296  hints.ai_family = AF_UNSPEC;
1297  else if (!strcmp(family, "ipv4"))
1298  hints.ai_family = AF_INET;
1299  else if (!strcmp(family, "ipv6"))
1300  hints.ai_family = AF_INET6;
1301  else
1302  {
1303  dbus_set_error (error,
1305  "Unknown address family %s", family);
1306  return -1;
1307  }
1308 
1309  hints.ai_protocol = IPPROTO_TCP;
1310  hints.ai_socktype = SOCK_STREAM;
1311  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1312 
1313  redo_lookup_with_port:
1314  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1315  {
1316  dbus_set_error (error,
1317  _dbus_error_from_errno (errno),
1318  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1319  host ? host : "*", port, gai_strerror(res), res);
1320  return -1;
1321  }
1322 
1323  tmp = ai;
1324  while (tmp)
1325  {
1326  int fd = -1, *newlisten_fd;
1327  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1328  {
1329  _DBUS_ASSERT_ERROR_IS_SET(error);
1330  goto failed;
1331  }
1332  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1333 
1334  reuseaddr = 1;
1335  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1336  {
1337  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1338  host ? host : "*", port, _dbus_strerror (errno));
1339  }
1340 
1341  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1342  {
1343  saved_errno = errno;
1344  _dbus_close(fd, NULL);
1345  if (saved_errno == EADDRINUSE)
1346  {
1347  /* Depending on kernel policy, it may or may not
1348  be neccessary to bind to both IPv4 & 6 addresses
1349  so ignore EADDRINUSE here */
1350  tmp = tmp->ai_next;
1351  continue;
1352  }
1353  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1354  "Failed to bind socket \"%s:%s\": %s",
1355  host ? host : "*", port, _dbus_strerror (saved_errno));
1356  goto failed;
1357  }
1358 
1359  if (listen (fd, 30 /* backlog */) < 0)
1360  {
1361  saved_errno = errno;
1362  _dbus_close (fd, NULL);
1363  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1364  "Failed to listen on socket \"%s:%s\": %s",
1365  host ? host : "*", port, _dbus_strerror (saved_errno));
1366  goto failed;
1367  }
1368 
1369  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1370  if (!newlisten_fd)
1371  {
1372  saved_errno = errno;
1373  _dbus_close (fd, NULL);
1374  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1375  "Failed to allocate file handle array: %s",
1376  _dbus_strerror (saved_errno));
1377  goto failed;
1378  }
1379  listen_fd = newlisten_fd;
1380  listen_fd[nlisten_fd] = fd;
1381  nlisten_fd++;
1382 
1383  if (!_dbus_string_get_length(retport))
1384  {
1385  /* If the user didn't specify a port, or used 0, then
1386  the kernel chooses a port. After the first address
1387  is bound to, we need to force all remaining addresses
1388  to use the same port */
1389  if (!port || !strcmp(port, "0"))
1390  {
1391  int result;
1392  struct sockaddr_storage addr;
1393  socklen_t addrlen;
1394  char portbuf[50];
1395 
1396  addrlen = sizeof(addr);
1397  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1398 
1399  if (result == -1 ||
1400  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1401  portbuf, sizeof(portbuf),
1402  NI_NUMERICHOST)) != 0)
1403  {
1404  dbus_set_error (error, _dbus_error_from_errno (errno),
1405  "Failed to resolve port \"%s:%s\": %s (%s)",
1406  host ? host : "*", port, gai_strerror(res), res);
1407  goto failed;
1408  }
1409  if (!_dbus_string_append(retport, portbuf))
1410  {
1412  goto failed;
1413  }
1414 
1415  /* Release current address list & redo lookup */
1416  port = _dbus_string_get_const_data(retport);
1417  freeaddrinfo(ai);
1418  goto redo_lookup_with_port;
1419  }
1420  else
1421  {
1422  if (!_dbus_string_append(retport, port))
1423  {
1425  goto failed;
1426  }
1427  }
1428  }
1429 
1430  tmp = tmp->ai_next;
1431  }
1432  freeaddrinfo(ai);
1433  ai = NULL;
1434 
1435  if (!nlisten_fd)
1436  {
1437  errno = EADDRINUSE;
1438  dbus_set_error (error, _dbus_error_from_errno (errno),
1439  "Failed to bind socket \"%s:%s\": %s",
1440  host ? host : "*", port, _dbus_strerror (errno));
1441  goto failed;
1442  }
1443 
1444  for (i = 0 ; i < nlisten_fd ; i++)
1445  {
1446  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1447  {
1448  goto failed;
1449  }
1450  }
1451 
1452  *fds_p = listen_fd;
1453 
1454  return nlisten_fd;
1455 
1456  failed:
1457  if (ai)
1458  freeaddrinfo(ai);
1459  for (i = 0 ; i < nlisten_fd ; i++)
1460  _dbus_close(listen_fd[i], NULL);
1461  dbus_free(listen_fd);
1462  return -1;
1463 }
1464 
1465 static dbus_bool_t
1466 write_credentials_byte (int server_fd,
1467  DBusError *error)
1468 {
1469  int bytes_written;
1470  char buf[1] = { '\0' };
1471 #if defined(HAVE_CMSGCRED)
1472  union {
1473  struct cmsghdr hdr;
1474  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1475  } cmsg;
1476  struct iovec iov;
1477  struct msghdr msg;
1478  iov.iov_base = buf;
1479  iov.iov_len = 1;
1480 
1481  _DBUS_ZERO(msg);
1482  msg.msg_iov = &iov;
1483  msg.msg_iovlen = 1;
1484 
1485  msg.msg_control = (caddr_t) &cmsg;
1486  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1487  _DBUS_ZERO(cmsg);
1488  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1489  cmsg.hdr.cmsg_level = SOL_SOCKET;
1490  cmsg.hdr.cmsg_type = SCM_CREDS;
1491 #endif
1492 
1493  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1494 
1495  again:
1496 
1497 #if defined(HAVE_CMSGCRED)
1498  bytes_written = sendmsg (server_fd, &msg, 0
1499 #if HAVE_DECL_MSG_NOSIGNAL
1500  |MSG_NOSIGNAL
1501 #endif
1502  );
1503 #else
1504  bytes_written = send (server_fd, buf, 1, 0
1505 #if HAVE_DECL_MSG_NOSIGNAL
1506  |MSG_NOSIGNAL
1507 #endif
1508  );
1509 #endif
1510 
1511  if (bytes_written < 0 && errno == EINTR)
1512  goto again;
1513 
1514  if (bytes_written < 0)
1515  {
1516  dbus_set_error (error, _dbus_error_from_errno (errno),
1517  "Failed to write credentials byte: %s",
1518  _dbus_strerror (errno));
1519  return FALSE;
1520  }
1521  else if (bytes_written == 0)
1522  {
1524  "wrote zero bytes writing credentials byte");
1525  return FALSE;
1526  }
1527  else
1528  {
1529  _dbus_assert (bytes_written == 1);
1530  _dbus_verbose ("wrote credentials byte\n");
1531  return TRUE;
1532  }
1533 }
1534 
1558  DBusCredentials *credentials,
1559  DBusError *error)
1560 {
1561  struct msghdr msg;
1562  struct iovec iov;
1563  char buf;
1564  dbus_uid_t uid_read;
1565  dbus_pid_t pid_read;
1566  int bytes_read;
1567 
1568 #ifdef HAVE_CMSGCRED
1569  union {
1570  struct cmsghdr hdr;
1571  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1572  } cmsg;
1573 
1574 #elif defined(LOCAL_CREDS)
1575  struct {
1576  struct cmsghdr hdr;
1577  struct sockcred cred;
1578  } cmsg;
1579 #endif
1580 
1581  uid_read = DBUS_UID_UNSET;
1582  pid_read = DBUS_PID_UNSET;
1583 
1584  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1585 
1586  /* The POSIX spec certainly doesn't promise this, but
1587  * we need these assertions to fail as soon as we're wrong about
1588  * it so we can do the porting fixups
1589  */
1590  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1591  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1592  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1593 
1594  _dbus_credentials_clear (credentials);
1595 
1596  /* Systems supporting LOCAL_CREDS are configured to have this feature
1597  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1598  * the connection. Therefore, the received message must carry the
1599  * credentials information without doing anything special.
1600  */
1601 
1602  iov.iov_base = &buf;
1603  iov.iov_len = 1;
1604 
1605  _DBUS_ZERO(msg);
1606  msg.msg_iov = &iov;
1607  msg.msg_iovlen = 1;
1608 
1609 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1610  _DBUS_ZERO(cmsg);
1611  msg.msg_control = (caddr_t) &cmsg;
1612  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1613 #endif
1614 
1615  again:
1616  bytes_read = recvmsg (client_fd, &msg, 0);
1617 
1618  if (bytes_read < 0)
1619  {
1620  if (errno == EINTR)
1621  goto again;
1622 
1623  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1624  * normally only call read_credentials if the socket was ready
1625  * for reading
1626  */
1627 
1628  dbus_set_error (error, _dbus_error_from_errno (errno),
1629  "Failed to read credentials byte: %s",
1630  _dbus_strerror (errno));
1631  return FALSE;
1632  }
1633  else if (bytes_read == 0)
1634  {
1635  /* this should not happen unless we are using recvmsg wrong,
1636  * so is essentially here for paranoia
1637  */
1639  "Failed to read credentials byte (zero-length read)");
1640  return FALSE;
1641  }
1642  else if (buf != '\0')
1643  {
1645  "Credentials byte was not nul");
1646  return FALSE;
1647  }
1648 
1649 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1650  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1651  || cmsg.hdr.cmsg_type != SCM_CREDS)
1652  {
1654  "Message from recvmsg() was not SCM_CREDS");
1655  return FALSE;
1656  }
1657 #endif
1658 
1659  _dbus_verbose ("read credentials byte\n");
1660 
1661  {
1662 #ifdef SO_PEERCRED
1663 #ifdef __OpenBSD__
1664  struct sockpeercred cr;
1665 #else
1666  struct ucred cr;
1667 #endif
1668  int cr_len = sizeof (cr);
1669 
1670  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1671  cr_len == sizeof (cr))
1672  {
1673  pid_read = cr.pid;
1674  uid_read = cr.uid;
1675  }
1676  else
1677  {
1678  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1679  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1680  }
1681 #elif defined(HAVE_CMSGCRED)
1682  struct cmsgcred *cred;
1683 
1684  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1685  pid_read = cred->cmcred_pid;
1686  uid_read = cred->cmcred_euid;
1687 #elif defined(LOCAL_CREDS)
1688  pid_read = DBUS_PID_UNSET;
1689  uid_read = cmsg.cred.sc_uid;
1690  /* Since we have already got the credentials from this socket, we can
1691  * disable its LOCAL_CREDS flag if it was ever set. */
1692  _dbus_set_local_creds (client_fd, FALSE);
1693 #elif defined(HAVE_GETPEEREID)
1694  uid_t euid;
1695  gid_t egid;
1696  if (getpeereid (client_fd, &euid, &egid) == 0)
1697  {
1698  uid_read = euid;
1699  }
1700  else
1701  {
1702  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1703  }
1704 #elif defined(HAVE_GETPEERUCRED)
1705  ucred_t * ucred = NULL;
1706  if (getpeerucred (client_fd, &ucred) == 0)
1707  {
1708  pid_read = ucred_getpid (ucred);
1709  uid_read = ucred_geteuid (ucred);
1710 #ifdef HAVE_ADT
1711  /* generate audit session data based on socket ucred */
1712  adt_session_data_t *adth = NULL;
1713  adt_export_data_t *data = NULL;
1714  size_t size = 0;
1715  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1716  {
1717  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1718  }
1719  else
1720  {
1721  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1722  {
1723  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1724  }
1725  else
1726  {
1727  size = adt_export_session_data (adth, &data);
1728  if (size <= 0)
1729  {
1730  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1731  }
1732  else
1733  {
1734  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1735  free (data);
1736  }
1737  }
1738  (void) adt_end_session (adth);
1739  }
1740 #endif /* HAVE_ADT */
1741  }
1742  else
1743  {
1744  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1745  }
1746  if (ucred != NULL)
1747  ucred_free (ucred);
1748 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1749  _dbus_verbose ("Socket credentials not supported on this OS\n");
1750 #endif
1751  }
1752 
1753  _dbus_verbose ("Credentials:"
1754  " pid "DBUS_PID_FORMAT
1755  " uid "DBUS_UID_FORMAT
1756  "\n",
1757  pid_read,
1758  uid_read);
1759 
1760  if (pid_read != DBUS_PID_UNSET)
1761  {
1762  if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1763  {
1764  _DBUS_SET_OOM (error);
1765  return FALSE;
1766  }
1767  }
1768 
1769  if (uid_read != DBUS_UID_UNSET)
1770  {
1771  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1772  {
1773  _DBUS_SET_OOM (error);
1774  return FALSE;
1775  }
1776  }
1777 
1778  return TRUE;
1779 }
1780 
1800  DBusError *error)
1801 {
1802  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1803 
1804  if (write_credentials_byte (server_fd, error))
1805  return TRUE;
1806  else
1807  return FALSE;
1808 }
1809 
1819 int
1820 _dbus_accept (int listen_fd)
1821 {
1822  int client_fd;
1823  struct sockaddr addr;
1824  socklen_t addrlen;
1825 #ifdef HAVE_ACCEPT4
1826  dbus_bool_t cloexec_done;
1827 #endif
1828 
1829  addrlen = sizeof (addr);
1830 
1831  retry:
1832 
1833 #ifdef HAVE_ACCEPT4
1834  /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1835  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1836  cloexec_done = client_fd >= 0;
1837 
1838  if (client_fd < 0 && errno == ENOSYS)
1839 #endif
1840  {
1841  client_fd = accept (listen_fd, &addr, &addrlen);
1842  }
1843 
1844  if (client_fd < 0)
1845  {
1846  if (errno == EINTR)
1847  goto retry;
1848  }
1849 
1850  _dbus_verbose ("client fd %d accepted\n", client_fd);
1851 
1852 #ifdef HAVE_ACCEPT4
1853  if (!cloexec_done)
1854 #endif
1855  {
1856  _dbus_fd_set_close_on_exec(client_fd);
1857  }
1858 
1859  return client_fd;
1860 }
1861 
1872 {
1873  const char *directory;
1874  struct stat sb;
1875 
1876  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1877 
1878  directory = _dbus_string_get_const_data (dir);
1879 
1880  if (stat (directory, &sb) < 0)
1881  {
1882  dbus_set_error (error, _dbus_error_from_errno (errno),
1883  "%s", _dbus_strerror (errno));
1884 
1885  return FALSE;
1886  }
1887 
1888  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1889  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1890  {
1892  "%s directory is not private to the user", directory);
1893  return FALSE;
1894  }
1895 
1896  return TRUE;
1897 }
1898 
1899 static dbus_bool_t
1900 fill_user_info_from_passwd (struct passwd *p,
1901  DBusUserInfo *info,
1902  DBusError *error)
1903 {
1904  _dbus_assert (p->pw_name != NULL);
1905  _dbus_assert (p->pw_dir != NULL);
1906 
1907  info->uid = p->pw_uid;
1908  info->primary_gid = p->pw_gid;
1909  info->username = _dbus_strdup (p->pw_name);
1910  info->homedir = _dbus_strdup (p->pw_dir);
1911 
1912  if (info->username == NULL ||
1913  info->homedir == NULL)
1914  {
1916  return FALSE;
1917  }
1918 
1919  return TRUE;
1920 }
1921 
1922 static dbus_bool_t
1923 fill_user_info (DBusUserInfo *info,
1924  dbus_uid_t uid,
1925  const DBusString *username,
1926  DBusError *error)
1927 {
1928  const char *username_c;
1929 
1930  /* exactly one of username/uid provided */
1931  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1932  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1933 
1934  info->uid = DBUS_UID_UNSET;
1935  info->primary_gid = DBUS_GID_UNSET;
1936  info->group_ids = NULL;
1937  info->n_group_ids = 0;
1938  info->username = NULL;
1939  info->homedir = NULL;
1940 
1941  if (username != NULL)
1942  username_c = _dbus_string_get_const_data (username);
1943  else
1944  username_c = NULL;
1945 
1946  /* For now assuming that the getpwnam() and getpwuid() flavors
1947  * are always symmetrical, if not we have to add more configure
1948  * checks
1949  */
1950 
1951 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1952  {
1953  struct passwd *p;
1954  int result;
1955  size_t buflen;
1956  char *buf;
1957  struct passwd p_str;
1958 
1959  /* retrieve maximum needed size for buf */
1960  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1961 
1962  /* sysconf actually returns a long, but everything else expects size_t,
1963  * so just recast here.
1964  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1965  */
1966  if ((long) buflen <= 0)
1967  buflen = 1024;
1968 
1969  result = -1;
1970  while (1)
1971  {
1972  buf = dbus_malloc (buflen);
1973  if (buf == NULL)
1974  {
1976  return FALSE;
1977  }
1978 
1979  p = NULL;
1980 #ifdef HAVE_POSIX_GETPWNAM_R
1981  if (uid != DBUS_UID_UNSET)
1982  result = getpwuid_r (uid, &p_str, buf, buflen,
1983  &p);
1984  else
1985  result = getpwnam_r (username_c, &p_str, buf, buflen,
1986  &p);
1987 #else
1988  if (uid != DBUS_UID_UNSET)
1989  p = getpwuid_r (uid, &p_str, buf, buflen);
1990  else
1991  p = getpwnam_r (username_c, &p_str, buf, buflen);
1992  result = 0;
1993 #endif /* !HAVE_POSIX_GETPWNAM_R */
1994  //Try a bigger buffer if ERANGE was returned
1995  if (result == ERANGE && buflen < 512 * 1024)
1996  {
1997  dbus_free (buf);
1998  buflen *= 2;
1999  }
2000  else
2001  {
2002  break;
2003  }
2004  }
2005  if (result == 0 && p == &p_str)
2006  {
2007  if (!fill_user_info_from_passwd (p, info, error))
2008  {
2009  dbus_free (buf);
2010  return FALSE;
2011  }
2012  dbus_free (buf);
2013  }
2014  else
2015  {
2016  dbus_set_error (error, _dbus_error_from_errno (errno),
2017  "User \"%s\" unknown or no memory to allocate password entry\n",
2018  username_c ? username_c : "???");
2019  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2020  dbus_free (buf);
2021  return FALSE;
2022  }
2023  }
2024 #else /* ! HAVE_GETPWNAM_R */
2025  {
2026  /* I guess we're screwed on thread safety here */
2027  struct passwd *p;
2028 
2029  if (uid != DBUS_UID_UNSET)
2030  p = getpwuid (uid);
2031  else
2032  p = getpwnam (username_c);
2033 
2034  if (p != NULL)
2035  {
2036  if (!fill_user_info_from_passwd (p, info, error))
2037  {
2038  return FALSE;
2039  }
2040  }
2041  else
2042  {
2043  dbus_set_error (error, _dbus_error_from_errno (errno),
2044  "User \"%s\" unknown or no memory to allocate password entry\n",
2045  username_c ? username_c : "???");
2046  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2047  return FALSE;
2048  }
2049  }
2050 #endif /* ! HAVE_GETPWNAM_R */
2051 
2052  /* Fill this in so we can use it to get groups */
2053  username_c = info->username;
2054 
2055 #ifdef HAVE_GETGROUPLIST
2056  {
2057  gid_t *buf;
2058  int buf_count;
2059  int i;
2060  int initial_buf_count;
2061 
2062  initial_buf_count = 17;
2063  buf_count = initial_buf_count;
2064  buf = dbus_new (gid_t, buf_count);
2065  if (buf == NULL)
2066  {
2068  goto failed;
2069  }
2070 
2071  if (getgrouplist (username_c,
2072  info->primary_gid,
2073  buf, &buf_count) < 0)
2074  {
2075  gid_t *new;
2076  /* Presumed cause of negative return code: buf has insufficient
2077  entries to hold the entire group list. The Linux behavior in this
2078  case is to pass back the actual number of groups in buf_count, but
2079  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2080  So as a hack, try to help out a bit by guessing a larger
2081  number of groups, within reason.. might still fail, of course,
2082  but we can at least print a more informative message. I looked up
2083  the "right way" to do this by downloading Apple's own source code
2084  for the "id" command, and it turns out that they use an
2085  undocumented library function getgrouplist_2 (!) which is not
2086  declared in any header in /usr/include (!!). That did not seem
2087  like the way to go here.
2088  */
2089  if (buf_count == initial_buf_count)
2090  {
2091  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2092  }
2093  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2094  if (new == NULL)
2095  {
2097  dbus_free (buf);
2098  goto failed;
2099  }
2100 
2101  buf = new;
2102 
2103  errno = 0;
2104  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2105  {
2106  if (errno == 0)
2107  {
2108  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2109  username_c, buf_count, buf_count);
2110  }
2111  else
2112  {
2113  dbus_set_error (error,
2114  _dbus_error_from_errno (errno),
2115  "Failed to get groups for username \"%s\" primary GID "
2116  DBUS_GID_FORMAT ": %s\n",
2117  username_c, info->primary_gid,
2118  _dbus_strerror (errno));
2119  dbus_free (buf);
2120  goto failed;
2121  }
2122  }
2123  }
2124 
2125  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2126  if (info->group_ids == NULL)
2127  {
2129  dbus_free (buf);
2130  goto failed;
2131  }
2132 
2133  for (i = 0; i < buf_count; ++i)
2134  info->group_ids[i] = buf[i];
2135 
2136  info->n_group_ids = buf_count;
2137 
2138  dbus_free (buf);
2139  }
2140 #else /* HAVE_GETGROUPLIST */
2141  {
2142  /* We just get the one group ID */
2143  info->group_ids = dbus_new (dbus_gid_t, 1);
2144  if (info->group_ids == NULL)
2145  {
2147  goto failed;
2148  }
2149 
2150  info->n_group_ids = 1;
2151 
2152  (info->group_ids)[0] = info->primary_gid;
2153  }
2154 #endif /* HAVE_GETGROUPLIST */
2155 
2156  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2157 
2158  return TRUE;
2159 
2160  failed:
2161  _DBUS_ASSERT_ERROR_IS_SET (error);
2162  return FALSE;
2163 }
2164 
2175  const DBusString *username,
2176  DBusError *error)
2177 {
2178  return fill_user_info (info, DBUS_UID_UNSET,
2179  username, error);
2180 }
2181 
2192  dbus_uid_t uid,
2193  DBusError *error)
2194 {
2195  return fill_user_info (info, uid,
2196  NULL, error);
2197 }
2198 
2208 {
2209  /* The POSIX spec certainly doesn't promise this, but
2210  * we need these assertions to fail as soon as we're wrong about
2211  * it so we can do the porting fixups
2212  */
2213  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2214  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2215  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2216 
2217  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2218  return FALSE;
2219  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2220  return FALSE;
2221 
2222  return TRUE;
2223 }
2224 
2238 {
2239  return _dbus_string_append_uint (str,
2240  _dbus_geteuid ());
2241 }
2242 
2247 dbus_pid_t
2249 {
2250  return getpid ();
2251 }
2252 
2256 dbus_uid_t
2258 {
2259  return getuid ();
2260 }
2261 
2265 dbus_uid_t
2267 {
2268  return geteuid ();
2269 }
2270 
2277 unsigned long
2279 {
2280  return getpid ();
2281 }
2282 
2291 _dbus_parse_uid (const DBusString *uid_str,
2292  dbus_uid_t *uid)
2293 {
2294  int end;
2295  long val;
2296 
2297  if (_dbus_string_get_length (uid_str) == 0)
2298  {
2299  _dbus_verbose ("UID string was zero length\n");
2300  return FALSE;
2301  }
2302 
2303  val = -1;
2304  end = 0;
2305  if (!_dbus_string_parse_int (uid_str, 0, &val,
2306  &end))
2307  {
2308  _dbus_verbose ("could not parse string as a UID\n");
2309  return FALSE;
2310  }
2311 
2312  if (end != _dbus_string_get_length (uid_str))
2313  {
2314  _dbus_verbose ("string contained trailing stuff after UID\n");
2315  return FALSE;
2316  }
2317 
2318  *uid = val;
2319 
2320  return TRUE;
2321 }
2322 
2323 #if !DBUS_USE_SYNC
2324 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2325 #endif
2326 
2335 {
2336 #if DBUS_USE_SYNC
2337  return __sync_add_and_fetch(&atomic->value, 1)-1;
2338 #else
2339  dbus_int32_t res;
2340  _DBUS_LOCK (atomic);
2341  res = atomic->value;
2342  atomic->value += 1;
2343  _DBUS_UNLOCK (atomic);
2344  return res;
2345 #endif
2346 }
2347 
2356 {
2357 #if DBUS_USE_SYNC
2358  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2359 #else
2360  dbus_int32_t res;
2361 
2362  _DBUS_LOCK (atomic);
2363  res = atomic->value;
2364  atomic->value -= 1;
2365  _DBUS_UNLOCK (atomic);
2366  return res;
2367 #endif
2368 }
2369 
2370 #ifdef DBUS_BUILD_TESTS
2371 
2374 dbus_gid_t
2375 _dbus_getgid (void)
2376 {
2377  return getgid ();
2378 }
2379 #endif
2380 
2389 int
2391  int n_fds,
2392  int timeout_milliseconds)
2393 {
2394 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2395  /* This big thing is a constant expression and should get optimized
2396  * out of existence. So it's more robust than a configure check at
2397  * no cost.
2398  */
2399  if (_DBUS_POLLIN == POLLIN &&
2400  _DBUS_POLLPRI == POLLPRI &&
2401  _DBUS_POLLOUT == POLLOUT &&
2402  _DBUS_POLLERR == POLLERR &&
2403  _DBUS_POLLHUP == POLLHUP &&
2404  _DBUS_POLLNVAL == POLLNVAL &&
2405  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2406  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2407  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2408  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2409  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2410  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2411  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2412  {
2413  return poll ((struct pollfd*) fds,
2414  n_fds,
2415  timeout_milliseconds);
2416  }
2417  else
2418  {
2419  /* We have to convert the DBusPollFD to an array of
2420  * struct pollfd, poll, and convert back.
2421  */
2422  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2423  return -1;
2424  }
2425 #else /* ! HAVE_POLL */
2426 
2427  fd_set read_set, write_set, err_set;
2428  int max_fd = 0;
2429  int i;
2430  struct timeval tv;
2431  int ready;
2432 
2433  FD_ZERO (&read_set);
2434  FD_ZERO (&write_set);
2435  FD_ZERO (&err_set);
2436 
2437  for (i = 0; i < n_fds; i++)
2438  {
2439  DBusPollFD *fdp = &fds[i];
2440 
2441  if (fdp->events & _DBUS_POLLIN)
2442  FD_SET (fdp->fd, &read_set);
2443 
2444  if (fdp->events & _DBUS_POLLOUT)
2445  FD_SET (fdp->fd, &write_set);
2446 
2447  FD_SET (fdp->fd, &err_set);
2448 
2449  max_fd = MAX (max_fd, fdp->fd);
2450  }
2451 
2452  tv.tv_sec = timeout_milliseconds / 1000;
2453  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2454 
2455  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2456  timeout_milliseconds < 0 ? NULL : &tv);
2457 
2458  if (ready > 0)
2459  {
2460  for (i = 0; i < n_fds; i++)
2461  {
2462  DBusPollFD *fdp = &fds[i];
2463 
2464  fdp->revents = 0;
2465 
2466  if (FD_ISSET (fdp->fd, &read_set))
2467  fdp->revents |= _DBUS_POLLIN;
2468 
2469  if (FD_ISSET (fdp->fd, &write_set))
2470  fdp->revents |= _DBUS_POLLOUT;
2471 
2472  if (FD_ISSET (fdp->fd, &err_set))
2473  fdp->revents |= _DBUS_POLLERR;
2474  }
2475  }
2476 
2477  return ready;
2478 #endif
2479 }
2480 
2488 void
2490  long *tv_usec)
2491 {
2492  struct timeval t;
2493 
2494 #ifdef HAVE_MONOTONIC_CLOCK
2495  struct timespec ts;
2496  clock_gettime (CLOCK_MONOTONIC, &ts);
2497 
2498  if (tv_sec)
2499  *tv_sec = ts.tv_sec;
2500  if (tv_usec)
2501  *tv_usec = ts.tv_nsec / 1000;
2502 #else
2503  gettimeofday (&t, NULL);
2504 
2505  if (tv_sec)
2506  *tv_sec = t.tv_sec;
2507  if (tv_usec)
2508  *tv_usec = t.tv_usec;
2509 #endif
2510 }
2511 
2522  DBusError *error)
2523 {
2524  const char *filename_c;
2525 
2526  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2527 
2528  filename_c = _dbus_string_get_const_data (filename);
2529 
2530  if (mkdir (filename_c, 0700) < 0)
2531  {
2532  if (errno == EEXIST)
2533  return TRUE;
2534 
2536  "Failed to create directory %s: %s\n",
2537  filename_c, _dbus_strerror (errno));
2538  return FALSE;
2539  }
2540  else
2541  return TRUE;
2542 }
2543 
2556  const DBusString *next_component)
2557 {
2558  dbus_bool_t dir_ends_in_slash;
2559  dbus_bool_t file_starts_with_slash;
2560 
2561  if (_dbus_string_get_length (dir) == 0 ||
2562  _dbus_string_get_length (next_component) == 0)
2563  return TRUE;
2564 
2565  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2566  _dbus_string_get_length (dir) - 1);
2567 
2568  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2569 
2570  if (dir_ends_in_slash && file_starts_with_slash)
2571  {
2572  _dbus_string_shorten (dir, 1);
2573  }
2574  else if (!(dir_ends_in_slash || file_starts_with_slash))
2575  {
2576  if (!_dbus_string_append_byte (dir, '/'))
2577  return FALSE;
2578  }
2579 
2580  return _dbus_string_copy (next_component, 0, dir,
2581  _dbus_string_get_length (dir));
2582 }
2583 
2585 #define NANOSECONDS_PER_SECOND 1000000000
2586 
2587 #define MICROSECONDS_PER_SECOND 1000000
2588 
2589 #define MILLISECONDS_PER_SECOND 1000
2590 
2591 #define NANOSECONDS_PER_MILLISECOND 1000000
2592 
2593 #define MICROSECONDS_PER_MILLISECOND 1000
2594 
2599 void
2600 _dbus_sleep_milliseconds (int milliseconds)
2601 {
2602 #ifdef HAVE_NANOSLEEP
2603  struct timespec req;
2604  struct timespec rem;
2605 
2606  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2607  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2608  rem.tv_sec = 0;
2609  rem.tv_nsec = 0;
2610 
2611  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2612  req = rem;
2613 #elif defined (HAVE_USLEEP)
2614  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2615 #else /* ! HAVE_USLEEP */
2616  sleep (MAX (milliseconds / 1000, 1));
2617 #endif
2618 }
2619 
2620 static dbus_bool_t
2621 _dbus_generate_pseudorandom_bytes (DBusString *str,
2622  int n_bytes)
2623 {
2624  int old_len;
2625  char *p;
2626 
2627  old_len = _dbus_string_get_length (str);
2628 
2629  if (!_dbus_string_lengthen (str, n_bytes))
2630  return FALSE;
2631 
2632  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2633 
2635 
2636  return TRUE;
2637 }
2638 
2649  int n_bytes)
2650 {
2651  int old_len;
2652  int fd;
2653 
2654  /* FALSE return means "no memory", if it could
2655  * mean something else then we'd need to return
2656  * a DBusError. So we always fall back to pseudorandom
2657  * if the I/O fails.
2658  */
2659 
2660  old_len = _dbus_string_get_length (str);
2661  fd = -1;
2662 
2663  /* note, urandom on linux will fall back to pseudorandom */
2664  fd = open ("/dev/urandom", O_RDONLY);
2665  if (fd < 0)
2666  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2667 
2668  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2669 
2670  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2671  {
2672  _dbus_close (fd, NULL);
2673  _dbus_string_set_length (str, old_len);
2674  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2675  }
2676 
2677  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2678  n_bytes);
2679 
2680  _dbus_close (fd, NULL);
2681 
2682  return TRUE;
2683 }
2684 
2690 void
2691 _dbus_exit (int code)
2692 {
2693  _exit (code);
2694 }
2695 
2704 const char*
2705 _dbus_strerror (int error_number)
2706 {
2707  const char *msg;
2708 
2709  msg = strerror (error_number);
2710  if (msg == NULL)
2711  msg = "unknown";
2712 
2713  return msg;
2714 }
2715 
2719 void
2721 {
2722  signal (SIGPIPE, SIG_IGN);
2723 }
2724 
2732 void
2734 {
2735  int val;
2736 
2737  val = fcntl (fd, F_GETFD, 0);
2738 
2739  if (val < 0)
2740  return;
2741 
2742  val |= FD_CLOEXEC;
2743 
2744  fcntl (fd, F_SETFD, val);
2745 }
2746 
2755 _dbus_close (int fd,
2756  DBusError *error)
2757 {
2758  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2759 
2760  again:
2761  if (close (fd) < 0)
2762  {
2763  if (errno == EINTR)
2764  goto again;
2765 
2766  dbus_set_error (error, _dbus_error_from_errno (errno),
2767  "Could not close fd %d", fd);
2768  return FALSE;
2769  }
2770 
2771  return TRUE;
2772 }
2773 
2781 int
2782 _dbus_dup(int fd,
2783  DBusError *error)
2784 {
2785  int new_fd;
2786 
2787 #ifdef F_DUPFD_CLOEXEC
2788  dbus_bool_t cloexec_done;
2789 
2790  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2791  cloexec_done = new_fd >= 0;
2792 
2793  if (new_fd < 0 && errno == EINVAL)
2794 #endif
2795  {
2796  new_fd = fcntl(fd, F_DUPFD, 3);
2797  }
2798 
2799  if (new_fd < 0) {
2800 
2801  dbus_set_error (error, _dbus_error_from_errno (errno),
2802  "Could not duplicate fd %d", fd);
2803  return -1;
2804  }
2805 
2806 #ifdef F_DUPFD_CLOEXEC
2807  if (!cloexec_done)
2808 #endif
2809  {
2811  }
2812 
2813  return new_fd;
2814 }
2815 
2824 _dbus_set_fd_nonblocking (int fd,
2825  DBusError *error)
2826 {
2827  int val;
2828 
2829  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2830 
2831  val = fcntl (fd, F_GETFL, 0);
2832  if (val < 0)
2833  {
2834  dbus_set_error (error, _dbus_error_from_errno (errno),
2835  "Failed to get flags from file descriptor %d: %s",
2836  fd, _dbus_strerror (errno));
2837  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2838  _dbus_strerror (errno));
2839  return FALSE;
2840  }
2841 
2842  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2843  {
2844  dbus_set_error (error, _dbus_error_from_errno (errno),
2845  "Failed to set nonblocking flag of file descriptor %d: %s",
2846  fd, _dbus_strerror (errno));
2847  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2848  fd, _dbus_strerror (errno));
2849 
2850  return FALSE;
2851  }
2852 
2853  return TRUE;
2854 }
2855 
2861 void
2863 {
2864 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2865  void *bt[500];
2866  int bt_size;
2867  int i;
2868  char **syms;
2869 
2870  bt_size = backtrace (bt, 500);
2871 
2872  syms = backtrace_symbols (bt, bt_size);
2873 
2874  i = 0;
2875  while (i < bt_size)
2876  {
2877  /* don't use dbus_warn since it can _dbus_abort() */
2878  fprintf (stderr, " %s\n", syms[i]);
2879  ++i;
2880  }
2881  fflush (stderr);
2882 
2883  free (syms);
2884 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2885  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2886 #else
2887  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2888 #endif
2889 }
2890 
2910  int *fd2,
2911  dbus_bool_t blocking,
2912  DBusError *error)
2913 {
2914 #ifdef HAVE_SOCKETPAIR
2915  int fds[2];
2916  int retval;
2917 
2918 #ifdef SOCK_CLOEXEC
2919  dbus_bool_t cloexec_done;
2920 
2921  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2922  cloexec_done = retval >= 0;
2923 
2924  if (retval < 0 && errno == EINVAL)
2925 #endif
2926  {
2927  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2928  }
2929 
2930  if (retval < 0)
2931  {
2932  dbus_set_error (error, _dbus_error_from_errno (errno),
2933  "Could not create full-duplex pipe");
2934  return FALSE;
2935  }
2936 
2937  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2938 
2939 #ifdef SOCK_CLOEXEC
2940  if (!cloexec_done)
2941 #endif
2942  {
2943  _dbus_fd_set_close_on_exec (fds[0]);
2944  _dbus_fd_set_close_on_exec (fds[1]);
2945  }
2946 
2947  if (!blocking &&
2948  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2949  !_dbus_set_fd_nonblocking (fds[1], NULL)))
2950  {
2951  dbus_set_error (error, _dbus_error_from_errno (errno),
2952  "Could not set full-duplex pipe nonblocking");
2953 
2954  _dbus_close (fds[0], NULL);
2955  _dbus_close (fds[1], NULL);
2956 
2957  return FALSE;
2958  }
2959 
2960  *fd1 = fds[0];
2961  *fd2 = fds[1];
2962 
2963  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2964  *fd1, *fd2);
2965 
2966  return TRUE;
2967 #else
2968  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2970  "_dbus_full_duplex_pipe() not implemented on this OS");
2971  return FALSE;
2972 #endif
2973 }
2974 
2983 int
2985  va_list args)
2986 {
2987  char c;
2988  return vsnprintf (&c, 1, format, args);
2989 }
2990 
2997 const char*
2999 {
3000  static const char* tmpdir = NULL;
3001 
3002  if (tmpdir == NULL)
3003  {
3004  /* TMPDIR is what glibc uses, then
3005  * glibc falls back to the P_tmpdir macro which
3006  * just expands to "/tmp"
3007  */
3008  if (tmpdir == NULL)
3009  tmpdir = getenv("TMPDIR");
3010 
3011  /* These two env variables are probably
3012  * broken, but maybe some OS uses them?
3013  */
3014  if (tmpdir == NULL)
3015  tmpdir = getenv("TMP");
3016  if (tmpdir == NULL)
3017  tmpdir = getenv("TEMP");
3018 
3019  /* And this is the sane fallback. */
3020  if (tmpdir == NULL)
3021  tmpdir = "/tmp";
3022  }
3023 
3024  _dbus_assert(tmpdir != NULL);
3025 
3026  return tmpdir;
3027 }
3028 
3048 static dbus_bool_t
3049 _read_subprocess_line_argv (const char *progpath,
3050  dbus_bool_t path_fallback,
3051  char * const *argv,
3052  DBusString *result,
3053  DBusError *error)
3054 {
3055  int result_pipe[2] = { -1, -1 };
3056  int errors_pipe[2] = { -1, -1 };
3057  pid_t pid;
3058  int ret;
3059  int status;
3060  int orig_len;
3061  int i;
3062 
3063  dbus_bool_t retval;
3064  sigset_t new_set, old_set;
3065 
3066  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3067  retval = FALSE;
3068 
3069  /* We need to block any existing handlers for SIGCHLD temporarily; they
3070  * will cause waitpid() below to fail.
3071  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3072  */
3073  sigemptyset (&new_set);
3074  sigaddset (&new_set, SIGCHLD);
3075  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3076 
3077  orig_len = _dbus_string_get_length (result);
3078 
3079 #define READ_END 0
3080 #define WRITE_END 1
3081  if (pipe (result_pipe) < 0)
3082  {
3083  dbus_set_error (error, _dbus_error_from_errno (errno),
3084  "Failed to create a pipe to call %s: %s",
3085  progpath, _dbus_strerror (errno));
3086  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3087  progpath, _dbus_strerror (errno));
3088  goto out;
3089  }
3090  if (pipe (errors_pipe) < 0)
3091  {
3092  dbus_set_error (error, _dbus_error_from_errno (errno),
3093  "Failed to create a pipe to call %s: %s",
3094  progpath, _dbus_strerror (errno));
3095  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3096  progpath, _dbus_strerror (errno));
3097  goto out;
3098  }
3099 
3100  pid = fork ();
3101  if (pid < 0)
3102  {
3103  dbus_set_error (error, _dbus_error_from_errno (errno),
3104  "Failed to fork() to call %s: %s",
3105  progpath, _dbus_strerror (errno));
3106  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3107  progpath, _dbus_strerror (errno));
3108  goto out;
3109  }
3110 
3111  if (pid == 0)
3112  {
3113  /* child process */
3114  int maxfds;
3115  int fd;
3116 
3117  fd = open ("/dev/null", O_RDWR);
3118  if (fd == -1)
3119  /* huh?! can't open /dev/null? */
3120  _exit (1);
3121 
3122  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3123 
3124  /* set-up stdXXX */
3125  close (result_pipe[READ_END]);
3126  close (errors_pipe[READ_END]);
3127  close (0); /* close stdin */
3128  close (1); /* close stdout */
3129  close (2); /* close stderr */
3130 
3131  if (dup2 (fd, 0) == -1)
3132  _exit (1);
3133  if (dup2 (result_pipe[WRITE_END], 1) == -1)
3134  _exit (1);
3135  if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3136  _exit (1);
3137 
3138  maxfds = sysconf (_SC_OPEN_MAX);
3139  /* Pick something reasonable if for some reason sysconf
3140  * says unlimited.
3141  */
3142  if (maxfds < 0)
3143  maxfds = 1024;
3144  /* close all inherited fds */
3145  for (i = 3; i < maxfds; i++)
3146  close (i);
3147 
3148  sigprocmask (SIG_SETMASK, &old_set, NULL);
3149 
3150  /* If it looks fully-qualified, try execv first */
3151  if (progpath[0] == '/')
3152  {
3153  execv (progpath, argv);
3154  /* Ok, that failed. Now if path_fallback is given, let's
3155  * try unqualified. This is mostly a hack to work
3156  * around systems which ship dbus-launch in /usr/bin
3157  * but everything else in /bin (because dbus-launch
3158  * depends on X11).
3159  */
3160  if (path_fallback)
3161  /* We must have a slash, because we checked above */
3162  execvp (strrchr (progpath, '/')+1, argv);
3163  }
3164  else
3165  execvp (progpath, argv);
3166 
3167  /* still nothing, we failed */
3168  _exit (1);
3169  }
3170 
3171  /* parent process */
3172  close (result_pipe[WRITE_END]);
3173  close (errors_pipe[WRITE_END]);
3174  result_pipe[WRITE_END] = -1;
3175  errors_pipe[WRITE_END] = -1;
3176 
3177  ret = 0;
3178  do
3179  {
3180  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3181  }
3182  while (ret > 0);
3183 
3184  /* reap the child process to avoid it lingering as zombie */
3185  do
3186  {
3187  ret = waitpid (pid, &status, 0);
3188  }
3189  while (ret == -1 && errno == EINTR);
3190 
3191  /* We succeeded if the process exited with status 0 and
3192  anything was read */
3193  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3194  {
3195  /* The process ended with error */
3196  DBusString error_message;
3197  if (!_dbus_string_init (&error_message))
3198  {
3199  _DBUS_SET_OOM (error);
3200  goto out;
3201  }
3202 
3203  ret = 0;
3204  do
3205  {
3206  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3207  }
3208  while (ret > 0);
3209 
3210  _dbus_string_set_length (result, orig_len);
3211  if (_dbus_string_get_length (&error_message) > 0)
3213  "%s terminated abnormally with the following error: %s",
3214  progpath, _dbus_string_get_data (&error_message));
3215  else
3217  "%s terminated abnormally without any error message",
3218  progpath);
3219  goto out;
3220  }
3221 
3222  retval = TRUE;
3223 
3224  out:
3225  sigprocmask (SIG_SETMASK, &old_set, NULL);
3226 
3227  if (retval)
3228  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3229  else
3230  _DBUS_ASSERT_ERROR_IS_SET (error);
3231 
3232  if (result_pipe[0] != -1)
3233  close (result_pipe[0]);
3234  if (result_pipe[1] != -1)
3235  close (result_pipe[1]);
3236  if (errors_pipe[0] != -1)
3237  close (errors_pipe[0]);
3238  if (errors_pipe[1] != -1)
3239  close (errors_pipe[1]);
3240 
3241  return retval;
3242 }
3243 
3256 _dbus_get_autolaunch_address (const char *scope,
3257  DBusString *address,
3258  DBusError *error)
3259 {
3260 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3261  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3262  * but that's done elsewhere, and if it worked, this function wouldn't
3263  * be called.) */
3264  const char *display;
3265  static char *argv[6];
3266  int i;
3267  DBusString uuid;
3268  dbus_bool_t retval;
3269 
3270  if (_dbus_check_setuid ())
3271  {
3273  "Unable to autolaunch when setuid");
3274  return FALSE;
3275  }
3276 
3277  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3278  retval = FALSE;
3279 
3280  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3281  * dbus-launch-x11 is just going to fail. Rather than trying to
3282  * run it, we might as well bail out early with a nice error. */
3283  display = _dbus_getenv ("DISPLAY");
3284 
3285  if (display == NULL || display[0] == '\0')
3286  {
3288  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3289  return FALSE;
3290  }
3291 
3292  if (!_dbus_string_init (&uuid))
3293  {
3294  _DBUS_SET_OOM (error);
3295  return FALSE;
3296  }
3297 
3299  {
3300  _DBUS_SET_OOM (error);
3301  goto out;
3302  }
3303 
3304  i = 0;
3305  argv[i] = "dbus-launch";
3306  ++i;
3307  argv[i] = "--autolaunch";
3308  ++i;
3309  argv[i] = _dbus_string_get_data (&uuid);
3310  ++i;
3311  argv[i] = "--binary-syntax";
3312  ++i;
3313  argv[i] = "--close-stderr";
3314  ++i;
3315  argv[i] = NULL;
3316  ++i;
3317 
3318  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3319 
3320  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3321  TRUE,
3322  argv, address, error);
3323 
3324  out:
3325  _dbus_string_free (&uuid);
3326  return retval;
3327 #else
3329  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3330  "set your DBUS_SESSION_BUS_ADDRESS instead");
3331  return FALSE;
3332 #endif
3333 }
3334 
3355  dbus_bool_t create_if_not_found,
3356  DBusError *error)
3357 {
3358  DBusString filename;
3359  dbus_bool_t b;
3360 
3361  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3362 
3363  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3364  if (b)
3365  return TRUE;
3366 
3367  dbus_error_free (error);
3368 
3369  /* Fallback to the system machine ID */
3370  _dbus_string_init_const (&filename, "/etc/machine-id");
3371  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3372 }
3373 
3374 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3375 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3376 
3385  const char *launchd_env_var,
3386  DBusError *error)
3387 {
3388 #ifdef DBUS_ENABLE_LAUNCHD
3389  char *argv[4];
3390  int i;
3391 
3392  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3393 
3394  if (_dbus_check_setuid ())
3395  {
3397  "Unable to find launchd socket when setuid");
3398  return FALSE;
3399  }
3400 
3401  i = 0;
3402  argv[i] = "launchctl";
3403  ++i;
3404  argv[i] = "getenv";
3405  ++i;
3406  argv[i] = (char*)launchd_env_var;
3407  ++i;
3408  argv[i] = NULL;
3409  ++i;
3410 
3411  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3412 
3413  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3414  {
3415  return FALSE;
3416  }
3417 
3418  /* no error, but no result either */
3419  if (_dbus_string_get_length(socket_path) == 0)
3420  {
3421  return FALSE;
3422  }
3423 
3424  /* strip the carriage-return */
3425  _dbus_string_shorten(socket_path, 1);
3426  return TRUE;
3427 #else /* DBUS_ENABLE_LAUNCHD */
3429  "can't lookup socket from launchd; launchd support not compiled in");
3430  return FALSE;
3431 #endif
3432 }
3433 
3434 static dbus_bool_t
3435 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3436 {
3437 #ifdef DBUS_ENABLE_LAUNCHD
3438  dbus_bool_t valid_socket;
3439  DBusString socket_path;
3440 
3441  if (_dbus_check_setuid ())
3442  {
3444  "Unable to find launchd socket when setuid");
3445  return FALSE;
3446  }
3447 
3448  if (!_dbus_string_init (&socket_path))
3449  {
3450  _DBUS_SET_OOM (error);
3451  return FALSE;
3452  }
3453 
3454  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3455 
3456  if (dbus_error_is_set(error))
3457  {
3458  _dbus_string_free(&socket_path);
3459  return FALSE;
3460  }
3461 
3462  if (!valid_socket)
3463  {
3464  dbus_set_error(error, "no socket path",
3465  "launchd did not provide a socket path, "
3466  "verify that org.freedesktop.dbus-session.plist is loaded!");
3467  _dbus_string_free(&socket_path);
3468  return FALSE;
3469  }
3470  if (!_dbus_string_append (address, "unix:path="))
3471  {
3472  _DBUS_SET_OOM (error);
3473  _dbus_string_free(&socket_path);
3474  return FALSE;
3475  }
3476  if (!_dbus_string_copy (&socket_path, 0, address,
3477  _dbus_string_get_length (address)))
3478  {
3479  _DBUS_SET_OOM (error);
3480  _dbus_string_free(&socket_path);
3481  return FALSE;
3482  }
3483 
3484  _dbus_string_free(&socket_path);
3485  return TRUE;
3486 #else
3488  "can't lookup session address from launchd; launchd support not compiled in");
3489  return FALSE;
3490 #endif
3491 }
3492 
3514  DBusString *address,
3515  DBusError *error)
3516 {
3517 #ifdef DBUS_ENABLE_LAUNCHD
3518  *supported = TRUE;
3519  return _dbus_lookup_session_address_launchd (address, error);
3520 #else
3521  /* On non-Mac Unix platforms, if the session address isn't already
3522  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3523  * fall back to the autolaunch: global default; see
3524  * init_session_address in dbus/dbus-bus.c. */
3525  *supported = FALSE;
3526  return TRUE;
3527 #endif
3528 }
3529 
3549 {
3550  const char *xdg_data_home;
3551  const char *xdg_data_dirs;
3552  DBusString servicedir_path;
3553 
3554  if (!_dbus_string_init (&servicedir_path))
3555  return FALSE;
3556 
3557  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3558  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3559 
3560  if (xdg_data_home != NULL)
3561  {
3562  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3563  goto oom;
3564  }
3565  else
3566  {
3567  const DBusString *homedir;
3568  DBusString local_share;
3569 
3570  if (!_dbus_homedir_from_current_process (&homedir))
3571  goto oom;
3572 
3573  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3574  goto oom;
3575 
3576  _dbus_string_init_const (&local_share, "/.local/share");
3577  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3578  goto oom;
3579  }
3580 
3581  if (!_dbus_string_append (&servicedir_path, ":"))
3582  goto oom;
3583 
3584  if (xdg_data_dirs != NULL)
3585  {
3586  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3587  goto oom;
3588 
3589  if (!_dbus_string_append (&servicedir_path, ":"))
3590  goto oom;
3591  }
3592  else
3593  {
3594  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3595  goto oom;
3596  }
3597 
3598  /*
3599  * add configured datadir to defaults
3600  * this may be the same as an xdg dir
3601  * however the config parser should take
3602  * care of duplicates
3603  */
3604  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3605  goto oom;
3606 
3607  if (!_dbus_split_paths_and_append (&servicedir_path,
3608  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3609  dirs))
3610  goto oom;
3611 
3612  _dbus_string_free (&servicedir_path);
3613  return TRUE;
3614 
3615  oom:
3616  _dbus_string_free (&servicedir_path);
3617  return FALSE;
3618 }
3619 
3620 
3641 {
3642  const char *xdg_data_dirs;
3643  DBusString servicedir_path;
3644 
3645  if (!_dbus_string_init (&servicedir_path))
3646  return FALSE;
3647 
3648  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3649 
3650  if (xdg_data_dirs != NULL)
3651  {
3652  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3653  goto oom;
3654 
3655  if (!_dbus_string_append (&servicedir_path, ":"))
3656  goto oom;
3657  }
3658  else
3659  {
3660  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3661  goto oom;
3662  }
3663 
3664  /*
3665  * add configured datadir to defaults
3666  * this may be the same as an xdg dir
3667  * however the config parser should take
3668  * care of duplicates
3669  */
3670  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3671  goto oom;
3672 
3673  if (!_dbus_split_paths_and_append (&servicedir_path,
3674  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3675  dirs))
3676  goto oom;
3677 
3678  _dbus_string_free (&servicedir_path);
3679  return TRUE;
3680 
3681  oom:
3682  _dbus_string_free (&servicedir_path);
3683  return FALSE;
3684 }
3685 
3696 {
3697  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3698 }
3699 
3708 {
3709  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3710 }
3711 
3719 void
3721 {
3723 }
3724 
3740  DBusCredentials *credentials)
3741 {
3742  DBusString homedir;
3743  DBusString dotdir;
3744  dbus_uid_t uid;
3745 
3746  _dbus_assert (credentials != NULL);
3748 
3749  if (!_dbus_string_init (&homedir))
3750  return FALSE;
3751 
3752  uid = _dbus_credentials_get_unix_uid (credentials);
3753  _dbus_assert (uid != DBUS_UID_UNSET);
3754 
3755  if (!_dbus_homedir_from_uid (uid, &homedir))
3756  goto failed;
3757 
3758 #ifdef DBUS_BUILD_TESTS
3759  {
3760  const char *override;
3761 
3762  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3763  if (override != NULL && *override != '\0')
3764  {
3765  _dbus_string_set_length (&homedir, 0);
3766  if (!_dbus_string_append (&homedir, override))
3767  goto failed;
3768 
3769  _dbus_verbose ("Using fake homedir for testing: %s\n",
3770  _dbus_string_get_const_data (&homedir));
3771  }
3772  else
3773  {
3774  static dbus_bool_t already_warned = FALSE;
3775  if (!already_warned)
3776  {
3777  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3778  already_warned = TRUE;
3779  }
3780  }
3781  }
3782 #endif
3783 
3784  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3785  if (!_dbus_concat_dir_and_file (&homedir,
3786  &dotdir))
3787  goto failed;
3788 
3789  if (!_dbus_string_copy (&homedir, 0,
3790  directory, _dbus_string_get_length (directory))) {
3791  goto failed;
3792  }
3793 
3794  _dbus_string_free (&homedir);
3795  return TRUE;
3796 
3797  failed:
3798  _dbus_string_free (&homedir);
3799  return FALSE;
3800 }
3801 
3802 //PENDING(kdab) docs
3804 _dbus_daemon_publish_session_bus_address (const char* addr,
3805  const char *scope)
3806 {
3807  return TRUE;
3808 }
3809 
3810 //PENDING(kdab) docs
3811 void
3812 _dbus_daemon_unpublish_session_bus_address (void)
3813 {
3814 
3815 }
3816 
3825 {
3826  return errno == EAGAIN || errno == EWOULDBLOCK;
3827 }
3828 
3838  DBusError *error)
3839 {
3840  const char *filename_c;
3841 
3842  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3843 
3844  filename_c = _dbus_string_get_const_data (filename);
3845 
3846  if (rmdir (filename_c) != 0)
3847  {
3849  "Failed to remove directory %s: %s\n",
3850  filename_c, _dbus_strerror (errno));
3851  return FALSE;
3852  }
3853 
3854  return TRUE;
3855 }
3856 
3866 
3867 #ifdef SCM_RIGHTS
3868  union {
3869  struct sockaddr sa;
3870  struct sockaddr_storage storage;
3871  struct sockaddr_un un;
3872  } sa_buf;
3873 
3874  socklen_t sa_len = sizeof(sa_buf);
3875 
3876  _DBUS_ZERO(sa_buf);
3877 
3878  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3879  return FALSE;
3880 
3881  return sa_buf.sa.sa_family == AF_UNIX;
3882 
3883 #else
3884  return FALSE;
3885 
3886 #endif
3887 }
3888 
3889 
3890 /*
3891  * replaces the term DBUS_PREFIX in configure_time_path by the
3892  * current dbus installation directory. On unix this function is a noop
3893  *
3894  * @param configure_time_path
3895  * @return real path
3896  */
3897 const char *
3898 _dbus_replace_install_prefix (const char *configure_time_path)
3899 {
3900  return configure_time_path;
3901 }
3902 
3914 {
3915  /* TODO: get __libc_enable_secure exported from glibc.
3916  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
3917  */
3918 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
3919  {
3920  /* See glibc/include/unistd.h */
3921  extern int __libc_enable_secure;
3922  return __libc_enable_secure;
3923  }
3924 #elif defined(HAVE_ISSETUGID)
3925  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
3926  return issetugid ();
3927 #else
3928  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
3929  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
3930 
3931  static dbus_bool_t check_setuid_initialised;
3932  static dbus_bool_t is_setuid;
3933 
3934  if (_DBUS_UNLIKELY (!check_setuid_initialised))
3935  {
3936 #ifdef HAVE_GETRESUID
3937  if (getresuid (&ruid, &euid, &suid) != 0 ||
3938  getresgid (&rgid, &egid, &sgid) != 0)
3939 #endif /* HAVE_GETRESUID */
3940  {
3941  suid = ruid = getuid ();
3942  sgid = rgid = getgid ();
3943  euid = geteuid ();
3944  egid = getegid ();
3945  }
3946 
3947  check_setuid_initialised = TRUE;
3948  is_setuid = (ruid != euid || ruid != suid ||
3949  rgid != egid || rgid != sgid);
3950 
3951  }
3952  return is_setuid;
3953 #endif
3954 }
3955 
3956 /* tests in dbus-sysdeps-util.c */