D-Bus  1.11.12
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-file.h"
33 #include "dbus-transport.h"
34 #include "dbus-string.h"
35 #include "dbus-userdb.h"
36 #include "dbus-list.h"
37 #include "dbus-credentials.h"
38 #include "dbus-nonce.h"
39 
40 #include <sys/types.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <fcntl.h>
47 #include <sys/socket.h>
48 #include <dirent.h>
49 #include <sys/un.h>
50 #include <pwd.h>
51 #include <time.h>
52 #include <locale.h>
53 #include <sys/time.h>
54 #include <sys/stat.h>
55 #include <sys/wait.h>
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
58 #include <netdb.h>
59 #include <grp.h>
60 #include <arpa/inet.h>
61 
62 #ifdef HAVE_ERRNO_H
63 #include <errno.h>
64 #endif
65 #ifdef HAVE_SYSLOG_H
66 #include <syslog.h>
67 #endif
68 #ifdef HAVE_WRITEV
69 #include <sys/uio.h>
70 #endif
71 #ifdef HAVE_POLL
72 #include <sys/poll.h>
73 #endif
74 #ifdef HAVE_BACKTRACE
75 #include <execinfo.h>
76 #endif
77 #ifdef HAVE_GETPEERUCRED
78 #include <ucred.h>
79 #endif
80 #ifdef HAVE_ALLOCA_H
81 #include <alloca.h>
82 #endif
83 
84 #ifdef HAVE_ADT
85 #include <bsm/adt.h>
86 #endif
87 
88 #ifdef HAVE_SYSTEMD
89 #include <systemd/sd-daemon.h>
90 #endif
91 
92 #if !DBUS_USE_SYNC
93 #include <pthread.h>
94 #endif
95 
96 #ifndef O_BINARY
97 #define O_BINARY 0
98 #endif
99 
100 #ifndef AI_ADDRCONFIG
101 #define AI_ADDRCONFIG 0
102 #endif
103 
104 #ifndef HAVE_SOCKLEN_T
105 #define socklen_t int
106 #endif
107 
108 #if defined (__sun) || defined (__sun__)
109 /*
110  * CMS_SPACE etc. definitions for Solaris < 10, based on
111  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
112  * via
113  * http://wiki.opencsw.org/porting-faq#toc10
114  *
115  * These are only redefined for Solaris, for now: if your OS needs these too,
116  * please file a bug. (Or preferably, improve your OS so they're not needed.)
117  */
118 
119 # ifndef CMSG_ALIGN
120 # ifdef __sun__
121 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
122 # else
123  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
124 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
125  ~(sizeof (long) - 1))
126 # endif
127 # endif
128 
129 # ifndef CMSG_SPACE
130 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
131  CMSG_ALIGN (len))
132 # endif
133 
134 # ifndef CMSG_LEN
135 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
136 # endif
137 
138 #endif /* Solaris */
139 
155 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
156  const char **error_str_p)
157 {
158  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
159  DBUS_FORCE_STDOUT_NULL,
160  DBUS_FORCE_STDERR_NULL };
161  /* Should always get replaced with the real error before use */
162  const char *error_str = "Failed mysteriously";
163  int devnull = -1;
164  int saved_errno;
165  /* This function relies on the standard fds having their POSIX values. */
166  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
167  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
168  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
169  int i;
170 
171  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
172  {
173  /* Because we rely on being single-threaded, and we want the
174  * standard fds to not be close-on-exec, we don't set it
175  * close-on-exec. */
176  if (devnull < i)
177  devnull = open ("/dev/null", O_RDWR);
178 
179  if (devnull < 0)
180  {
181  error_str = "Failed to open /dev/null";
182  goto out;
183  }
184 
185  /* We already opened all fds < i, so the only way this assertion
186  * could fail is if another thread closed one, and we document
187  * this function as not safe for multi-threading. */
188  _dbus_assert (devnull >= i);
189 
190  if (devnull != i && (flags & relevant_flag[i]) != 0)
191  {
192  if (dup2 (devnull, i) < 0)
193  {
194  error_str = "Failed to dup2 /dev/null onto a standard fd";
195  goto out;
196  }
197  }
198  }
199 
200  error_str = NULL;
201 
202 out:
203  saved_errno = errno;
204 
205  if (devnull > STDERR_FILENO)
206  close (devnull);
207 
208  if (error_str_p != NULL)
209  *error_str_p = error_str;
210 
211  errno = saved_errno;
212  return (error_str == NULL);
213 }
214 
215 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
216  DBusError *error);
217 
218 static dbus_bool_t
219 _dbus_open_socket (int *fd_p,
220  int domain,
221  int type,
222  int protocol,
223  DBusError *error)
224 {
225 #ifdef SOCK_CLOEXEC
226  dbus_bool_t cloexec_done;
227 
228  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
229  cloexec_done = *fd_p >= 0;
230 
231  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
232  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
233 #endif
234  {
235  *fd_p = socket (domain, type, protocol);
236  }
237 
238  if (*fd_p >= 0)
239  {
240 #ifdef SOCK_CLOEXEC
241  if (!cloexec_done)
242 #endif
243  {
245  }
246 
247  _dbus_verbose ("socket fd %d opened\n", *fd_p);
248  return TRUE;
249  }
250  else
251  {
252  dbus_set_error(error,
253  _dbus_error_from_errno (errno),
254  "Failed to open socket: %s",
255  _dbus_strerror (errno));
256  return FALSE;
257  }
258 }
259 
270 static dbus_bool_t
271 _dbus_open_unix_socket (int *fd,
272  DBusError *error)
273 {
274  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
275 }
276 
287  DBusError *error)
288 {
289  return _dbus_close (fd.fd, error);
290 }
291 
301 int
303  DBusString *buffer,
304  int count)
305 {
306  return _dbus_read (fd.fd, buffer, count);
307 }
308 
319 int
321  const DBusString *buffer,
322  int start,
323  int len)
324 {
325 #if HAVE_DECL_MSG_NOSIGNAL
326  const char *data;
327  int bytes_written;
328 
329  data = _dbus_string_get_const_data_len (buffer, start, len);
330 
331  again:
332 
333  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
334 
335  if (bytes_written < 0 && errno == EINTR)
336  goto again;
337 
338  return bytes_written;
339 
340 #else
341  return _dbus_write (fd.fd, buffer, start, len);
342 #endif
343 }
344 
357 int
359  DBusString *buffer,
360  int count,
361  int *fds,
362  unsigned int *n_fds) {
363 #ifndef HAVE_UNIX_FD_PASSING
364  int r;
365 
366  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
367  return r;
368 
369  *n_fds = 0;
370  return r;
371 
372 #else
373  int bytes_read;
374  int start;
375  struct msghdr m;
376  struct iovec iov;
377 
378  _dbus_assert (count >= 0);
380 
381  start = _dbus_string_get_length (buffer);
382 
383  if (!_dbus_string_lengthen (buffer, count))
384  {
385  errno = ENOMEM;
386  return -1;
387  }
388 
389  _DBUS_ZERO(iov);
390  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
391  iov.iov_len = count;
392 
393  _DBUS_ZERO(m);
394  m.msg_iov = &iov;
395  m.msg_iovlen = 1;
396 
397  /* Hmm, we have no clue how long the control data will actually be
398  that is queued for us. The least we can do is assume that the
399  caller knows. Hence let's make space for the number of fds that
400  we shall read at max plus the cmsg header. */
401  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
402 
403  /* It's probably safe to assume that systems with SCM_RIGHTS also
404  know alloca() */
405  m.msg_control = alloca(m.msg_controllen);
406  memset(m.msg_control, 0, m.msg_controllen);
407 
408  /* Do not include the padding at the end when we tell the kernel
409  * how much we're willing to receive. This avoids getting
410  * the padding filled with additional fds that we weren't expecting,
411  * if a (potentially malicious) sender included them. (fd.o #83622) */
412  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
413 
414  again:
415 
416  bytes_read = recvmsg (fd.fd, &m, 0
417 #ifdef MSG_CMSG_CLOEXEC
418  |MSG_CMSG_CLOEXEC
419 #endif
420  );
421 
422  if (bytes_read < 0)
423  {
424  if (errno == EINTR)
425  goto again;
426  else
427  {
428  /* put length back (note that this doesn't actually realloc anything) */
429  _dbus_string_set_length (buffer, start);
430  return -1;
431  }
432  }
433  else
434  {
435  struct cmsghdr *cm;
436  dbus_bool_t found = FALSE;
437 
438  if (m.msg_flags & MSG_CTRUNC)
439  {
440  /* Hmm, apparently the control data was truncated. The bad
441  thing is that we might have completely lost a couple of fds
442  without chance to recover them. Hence let's treat this as a
443  serious error. */
444 
445  errno = ENOSPC;
446  _dbus_string_set_length (buffer, start);
447  return -1;
448  }
449 
450  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
451  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
452  {
453  size_t i;
454  int *payload = (int *) CMSG_DATA (cm);
455  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
456  size_t payload_len_fds = payload_len_bytes / sizeof (int);
457  size_t fds_to_use;
458 
459  /* Every unsigned int fits in a size_t without truncation, so
460  * casting (size_t) *n_fds is OK */
461  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
462 
463  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
464  {
465  /* The fds in the payload will fit in our buffer */
466  fds_to_use = payload_len_fds;
467  }
468  else
469  {
470  /* Too many fds in the payload. This shouldn't happen
471  * any more because we're setting m.msg_controllen to
472  * the exact number we can accept, but be safe and
473  * truncate. */
474  fds_to_use = (size_t) *n_fds;
475 
476  /* Close the excess fds to avoid DoS: if they stayed open,
477  * someone could send us an extra fd per message
478  * and we'd eventually run out. */
479  for (i = fds_to_use; i < payload_len_fds; i++)
480  {
481  close (payload[i]);
482  }
483  }
484 
485  memcpy (fds, payload, fds_to_use * sizeof (int));
486  found = TRUE;
487  /* This narrowing cast from size_t to unsigned int cannot
488  * overflow because we have chosen fds_to_use
489  * to be <= *n_fds */
490  *n_fds = (unsigned int) fds_to_use;
491 
492  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
493  worked, hence we need to go through this list and set
494  CLOEXEC everywhere in any case */
495  for (i = 0; i < fds_to_use; i++)
497 
498  break;
499  }
500 
501  if (!found)
502  *n_fds = 0;
503 
504  /* put length back (doesn't actually realloc) */
505  _dbus_string_set_length (buffer, start + bytes_read);
506 
507 #if 0
508  if (bytes_read > 0)
509  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
510 #endif
511 
512  return bytes_read;
513  }
514 #endif
515 }
516 
517 int
518 _dbus_write_socket_with_unix_fds(DBusSocket fd,
519  const DBusString *buffer,
520  int start,
521  int len,
522  const int *fds,
523  int n_fds) {
524 
525 #ifndef HAVE_UNIX_FD_PASSING
526 
527  if (n_fds > 0) {
528  errno = ENOTSUP;
529  return -1;
530  }
531 
532  return _dbus_write_socket(fd, buffer, start, len);
533 #else
534  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
535 #endif
536 }
537 
538 int
539 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
540  const DBusString *buffer1,
541  int start1,
542  int len1,
543  const DBusString *buffer2,
544  int start2,
545  int len2,
546  const int *fds,
547  int n_fds) {
548 
549 #ifndef HAVE_UNIX_FD_PASSING
550 
551  if (n_fds > 0) {
552  errno = ENOTSUP;
553  return -1;
554  }
555 
556  return _dbus_write_socket_two(fd,
557  buffer1, start1, len1,
558  buffer2, start2, len2);
559 #else
560 
561  struct msghdr m;
562  struct cmsghdr *cm;
563  struct iovec iov[2];
564  int bytes_written;
565 
566  _dbus_assert (len1 >= 0);
567  _dbus_assert (len2 >= 0);
568  _dbus_assert (n_fds >= 0);
569 
570  _DBUS_ZERO(iov);
571  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
572  iov[0].iov_len = len1;
573 
574  if (buffer2)
575  {
576  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
577  iov[1].iov_len = len2;
578  }
579 
580  _DBUS_ZERO(m);
581  m.msg_iov = iov;
582  m.msg_iovlen = buffer2 ? 2 : 1;
583 
584  if (n_fds > 0)
585  {
586  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
587  m.msg_control = alloca(m.msg_controllen);
588  memset(m.msg_control, 0, m.msg_controllen);
589 
590  cm = CMSG_FIRSTHDR(&m);
591  cm->cmsg_level = SOL_SOCKET;
592  cm->cmsg_type = SCM_RIGHTS;
593  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
594  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
595  }
596 
597  again:
598 
599  bytes_written = sendmsg (fd.fd, &m, 0
600 #if HAVE_DECL_MSG_NOSIGNAL
601  |MSG_NOSIGNAL
602 #endif
603  );
604 
605  if (bytes_written < 0 && errno == EINTR)
606  goto again;
607 
608 #if 0
609  if (bytes_written > 0)
610  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
611 #endif
612 
613  return bytes_written;
614 #endif
615 }
616 
630 int
632  const DBusString *buffer1,
633  int start1,
634  int len1,
635  const DBusString *buffer2,
636  int start2,
637  int len2)
638 {
639 #if HAVE_DECL_MSG_NOSIGNAL
640  struct iovec vectors[2];
641  const char *data1;
642  const char *data2;
643  int bytes_written;
644  struct msghdr m;
645 
646  _dbus_assert (buffer1 != NULL);
647  _dbus_assert (start1 >= 0);
648  _dbus_assert (start2 >= 0);
649  _dbus_assert (len1 >= 0);
650  _dbus_assert (len2 >= 0);
651 
652  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
653 
654  if (buffer2 != NULL)
655  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
656  else
657  {
658  data2 = NULL;
659  start2 = 0;
660  len2 = 0;
661  }
662 
663  vectors[0].iov_base = (char*) data1;
664  vectors[0].iov_len = len1;
665  vectors[1].iov_base = (char*) data2;
666  vectors[1].iov_len = len2;
667 
668  _DBUS_ZERO(m);
669  m.msg_iov = vectors;
670  m.msg_iovlen = data2 ? 2 : 1;
671 
672  again:
673 
674  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
675 
676  if (bytes_written < 0 && errno == EINTR)
677  goto again;
678 
679  return bytes_written;
680 
681 #else
682  return _dbus_write_two (fd.fd, buffer1, start1, len1,
683  buffer2, start2, len2);
684 #endif
685 }
686 
703 int
704 _dbus_read (int fd,
705  DBusString *buffer,
706  int count)
707 {
708  int bytes_read;
709  int start;
710  char *data;
711 
712  _dbus_assert (count >= 0);
713 
714  start = _dbus_string_get_length (buffer);
715 
716  if (!_dbus_string_lengthen (buffer, count))
717  {
718  errno = ENOMEM;
719  return -1;
720  }
721 
722  data = _dbus_string_get_data_len (buffer, start, count);
723 
724  again:
725 
726  bytes_read = read (fd, data, count);
727 
728  if (bytes_read < 0)
729  {
730  if (errno == EINTR)
731  goto again;
732  else
733  {
734  /* put length back (note that this doesn't actually realloc anything) */
735  _dbus_string_set_length (buffer, start);
736  return -1;
737  }
738  }
739  else
740  {
741  /* put length back (doesn't actually realloc) */
742  _dbus_string_set_length (buffer, start + bytes_read);
743 
744 #if 0
745  if (bytes_read > 0)
746  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
747 #endif
748 
749  return bytes_read;
750  }
751 }
752 
763 int
764 _dbus_write (int fd,
765  const DBusString *buffer,
766  int start,
767  int len)
768 {
769  const char *data;
770  int bytes_written;
771 
772  data = _dbus_string_get_const_data_len (buffer, start, len);
773 
774  again:
775 
776  bytes_written = write (fd, data, len);
777 
778  if (bytes_written < 0 && errno == EINTR)
779  goto again;
780 
781 #if 0
782  if (bytes_written > 0)
783  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
784 #endif
785 
786  return bytes_written;
787 }
788 
809 int
811  const DBusString *buffer1,
812  int start1,
813  int len1,
814  const DBusString *buffer2,
815  int start2,
816  int len2)
817 {
818  _dbus_assert (buffer1 != NULL);
819  _dbus_assert (start1 >= 0);
820  _dbus_assert (start2 >= 0);
821  _dbus_assert (len1 >= 0);
822  _dbus_assert (len2 >= 0);
823 
824 #ifdef HAVE_WRITEV
825  {
826  struct iovec vectors[2];
827  const char *data1;
828  const char *data2;
829  int bytes_written;
830 
831  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
832 
833  if (buffer2 != NULL)
834  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
835  else
836  {
837  data2 = NULL;
838  start2 = 0;
839  len2 = 0;
840  }
841 
842  vectors[0].iov_base = (char*) data1;
843  vectors[0].iov_len = len1;
844  vectors[1].iov_base = (char*) data2;
845  vectors[1].iov_len = len2;
846 
847  again:
848 
849  bytes_written = writev (fd,
850  vectors,
851  data2 ? 2 : 1);
852 
853  if (bytes_written < 0 && errno == EINTR)
854  goto again;
855 
856  return bytes_written;
857  }
858 #else /* HAVE_WRITEV */
859  {
860  int ret1, ret2;
861 
862  ret1 = _dbus_write (fd, buffer1, start1, len1);
863  if (ret1 == len1 && buffer2 != NULL)
864  {
865  ret2 = _dbus_write (fd, buffer2, start2, len2);
866  if (ret2 < 0)
867  ret2 = 0; /* we can't report an error as the first write was OK */
868 
869  return ret1 + ret2;
870  }
871  else
872  return ret1;
873  }
874 #endif /* !HAVE_WRITEV */
875 }
876 
877 #define _DBUS_MAX_SUN_PATH_LENGTH 99
878 
908 int
909 _dbus_connect_unix_socket (const char *path,
910  dbus_bool_t abstract,
911  DBusError *error)
912 {
913  int fd;
914  size_t path_len;
915  struct sockaddr_un addr;
916 
917  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
918 
919  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
920  path, abstract);
921 
922 
923  if (!_dbus_open_unix_socket (&fd, error))
924  {
925  _DBUS_ASSERT_ERROR_IS_SET(error);
926  return -1;
927  }
928  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
929 
930  _DBUS_ZERO (addr);
931  addr.sun_family = AF_UNIX;
932  path_len = strlen (path);
933 
934  if (abstract)
935  {
936 #ifdef HAVE_ABSTRACT_SOCKETS
937  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
938  path_len++; /* Account for the extra nul byte added to the start of sun_path */
939 
940  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
941  {
943  "Abstract socket name too long\n");
944  _dbus_close (fd, NULL);
945  return -1;
946  }
947 
948  strncpy (&addr.sun_path[1], path, path_len);
949  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
950 #else /* HAVE_ABSTRACT_SOCKETS */
952  "Operating system does not support abstract socket namespace\n");
953  _dbus_close (fd, NULL);
954  return -1;
955 #endif /* ! HAVE_ABSTRACT_SOCKETS */
956  }
957  else
958  {
959  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
960  {
962  "Socket name too long\n");
963  _dbus_close (fd, NULL);
964  return -1;
965  }
966 
967  strncpy (addr.sun_path, path, path_len);
968  }
969 
970  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
971  {
972  dbus_set_error (error,
973  _dbus_error_from_errno (errno),
974  "Failed to connect to socket %s: %s",
975  path, _dbus_strerror (errno));
976 
977  _dbus_close (fd, NULL);
978  return -1;
979  }
980 
981  if (!_dbus_set_fd_nonblocking (fd, error))
982  {
983  _DBUS_ASSERT_ERROR_IS_SET (error);
984 
985  _dbus_close (fd, NULL);
986  return -1;
987  }
988 
989  return fd;
990 }
991 
1004 int
1005 _dbus_connect_exec (const char *path,
1006  char *const argv[],
1007  DBusError *error)
1008 {
1009  int fds[2];
1010  pid_t pid;
1011  int retval;
1012  dbus_bool_t cloexec_done = 0;
1013 
1014  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1015 
1016  _dbus_verbose ("connecting to process %s\n", path);
1017 
1018 #ifdef SOCK_CLOEXEC
1019  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1020  cloexec_done = (retval >= 0);
1021 
1022  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1023 #endif
1024  {
1025  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1026  }
1027 
1028  if (retval < 0)
1029  {
1030  dbus_set_error (error,
1031  _dbus_error_from_errno (errno),
1032  "Failed to create socket pair: %s",
1033  _dbus_strerror (errno));
1034  return -1;
1035  }
1036 
1037  if (!cloexec_done)
1038  {
1039  _dbus_fd_set_close_on_exec (fds[0]);
1040  _dbus_fd_set_close_on_exec (fds[1]);
1041  }
1042 
1043  pid = fork ();
1044  if (pid < 0)
1045  {
1046  dbus_set_error (error,
1047  _dbus_error_from_errno (errno),
1048  "Failed to fork() to call %s: %s",
1049  path, _dbus_strerror (errno));
1050  close (fds[0]);
1051  close (fds[1]);
1052  return -1;
1053  }
1054 
1055  if (pid == 0)
1056  {
1057  /* child */
1058  close (fds[0]);
1059 
1060  dup2 (fds[1], STDIN_FILENO);
1061  dup2 (fds[1], STDOUT_FILENO);
1062 
1063  if (fds[1] != STDIN_FILENO &&
1064  fds[1] != STDOUT_FILENO)
1065  close (fds[1]);
1066 
1067  /* Inherit STDERR and the controlling terminal from the
1068  parent */
1069 
1070  _dbus_close_all ();
1071 
1072  execvp (path, (char * const *) argv);
1073 
1074  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1075 
1076  _exit(1);
1077  }
1078 
1079  /* parent */
1080  close (fds[1]);
1081 
1082  if (!_dbus_set_fd_nonblocking (fds[0], error))
1083  {
1084  _DBUS_ASSERT_ERROR_IS_SET (error);
1085 
1086  close (fds[0]);
1087  return -1;
1088  }
1089 
1090  return fds[0];
1091 }
1092 
1110 int
1111 _dbus_listen_unix_socket (const char *path,
1112  dbus_bool_t abstract,
1113  DBusError *error)
1114 {
1115  int listen_fd;
1116  struct sockaddr_un addr;
1117  size_t path_len;
1118 
1119  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1120 
1121  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1122  path, abstract);
1123 
1124  if (!_dbus_open_unix_socket (&listen_fd, error))
1125  {
1126  _DBUS_ASSERT_ERROR_IS_SET(error);
1127  return -1;
1128  }
1129  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1130 
1131  _DBUS_ZERO (addr);
1132  addr.sun_family = AF_UNIX;
1133  path_len = strlen (path);
1134 
1135  if (abstract)
1136  {
1137 #ifdef HAVE_ABSTRACT_SOCKETS
1138  /* remember that abstract names aren't nul-terminated so we rely
1139  * on sun_path being filled in with zeroes above.
1140  */
1141  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1142  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1143 
1144  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1145  {
1147  "Abstract socket name too long\n");
1148  _dbus_close (listen_fd, NULL);
1149  return -1;
1150  }
1151 
1152  strncpy (&addr.sun_path[1], path, path_len);
1153  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1154 #else /* HAVE_ABSTRACT_SOCKETS */
1156  "Operating system does not support abstract socket namespace\n");
1157  _dbus_close (listen_fd, NULL);
1158  return -1;
1159 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1160  }
1161  else
1162  {
1163  /* Discussed security implications of this with Nalin,
1164  * and we couldn't think of where it would kick our ass, but
1165  * it still seems a bit sucky. It also has non-security suckage;
1166  * really we'd prefer to exit if the socket is already in use.
1167  * But there doesn't seem to be a good way to do this.
1168  *
1169  * Just to be extra careful, I threw in the stat() - clearly
1170  * the stat() can't *fix* any security issue, but it at least
1171  * avoids inadvertent/accidental data loss.
1172  */
1173  {
1174  struct stat sb;
1175 
1176  if (stat (path, &sb) == 0 &&
1177  S_ISSOCK (sb.st_mode))
1178  unlink (path);
1179  }
1180 
1181  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1182  {
1184  "Socket name too long\n");
1185  _dbus_close (listen_fd, NULL);
1186  return -1;
1187  }
1188 
1189  strncpy (addr.sun_path, path, path_len);
1190  }
1191 
1192  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1193  {
1194  dbus_set_error (error, _dbus_error_from_errno (errno),
1195  "Failed to bind socket \"%s\": %s",
1196  path, _dbus_strerror (errno));
1197  _dbus_close (listen_fd, NULL);
1198  return -1;
1199  }
1200 
1201  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1202  {
1203  dbus_set_error (error, _dbus_error_from_errno (errno),
1204  "Failed to listen on socket \"%s\": %s",
1205  path, _dbus_strerror (errno));
1206  _dbus_close (listen_fd, NULL);
1207  return -1;
1208  }
1209 
1210  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1211  {
1212  _DBUS_ASSERT_ERROR_IS_SET (error);
1213  _dbus_close (listen_fd, NULL);
1214  return -1;
1215  }
1216 
1217  /* Try opening up the permissions, but if we can't, just go ahead
1218  * and continue, maybe it will be good enough.
1219  */
1220  if (!abstract && chmod (path, 0777) < 0)
1221  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1222 
1223  return listen_fd;
1224 }
1225 
1236 int
1238  DBusError *error)
1239 {
1240 #ifdef HAVE_SYSTEMD
1241  int r, n;
1242  int fd;
1243  DBusSocket *new_fds;
1244 
1245  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1246 
1247  n = sd_listen_fds (TRUE);
1248  if (n < 0)
1249  {
1251  "Failed to acquire systemd socket: %s",
1252  _dbus_strerror (-n));
1253  return -1;
1254  }
1255 
1256  if (n <= 0)
1257  {
1259  "No socket received.");
1260  return -1;
1261  }
1262 
1263  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1264  {
1265  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1266  if (r < 0)
1267  {
1269  "Failed to verify systemd socket type: %s",
1270  _dbus_strerror (-r));
1271  return -1;
1272  }
1273 
1274  if (!r)
1275  {
1277  "Passed socket has wrong type.");
1278  return -1;
1279  }
1280  }
1281 
1282  /* OK, the file descriptors are all good, so let's take posession of
1283  them then. */
1284 
1285  new_fds = dbus_new (DBusSocket, n);
1286  if (!new_fds)
1287  {
1289  "Failed to allocate file handle array.");
1290  goto fail;
1291  }
1292 
1293  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1294  {
1295  if (!_dbus_set_fd_nonblocking (fd, error))
1296  {
1297  _DBUS_ASSERT_ERROR_IS_SET (error);
1298  goto fail;
1299  }
1300 
1301  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1302  }
1303 
1304  *fds = new_fds;
1305  return n;
1306 
1307  fail:
1308 
1309  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1310  {
1311  _dbus_close (fd, NULL);
1312  }
1313 
1314  dbus_free (new_fds);
1315  return -1;
1316 #else
1318  "dbus was compiled without systemd support");
1319  return -1;
1320 #endif
1321 }
1322 
1336 DBusSocket
1337 _dbus_connect_tcp_socket (const char *host,
1338  const char *port,
1339  const char *family,
1340  DBusError *error)
1341 {
1342  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1343 }
1344 
1345 DBusSocket
1346 _dbus_connect_tcp_socket_with_nonce (const char *host,
1347  const char *port,
1348  const char *family,
1349  const char *noncefile,
1350  DBusError *error)
1351 {
1352  int saved_errno = 0;
1353  DBusSocket fd = DBUS_SOCKET_INIT;
1354  int res;
1355  struct addrinfo hints;
1356  struct addrinfo *ai, *tmp;
1357 
1358  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1359 
1360  _DBUS_ZERO (hints);
1361 
1362  if (!family)
1363  hints.ai_family = AF_UNSPEC;
1364  else if (!strcmp(family, "ipv4"))
1365  hints.ai_family = AF_INET;
1366  else if (!strcmp(family, "ipv6"))
1367  hints.ai_family = AF_INET6;
1368  else
1369  {
1370  dbus_set_error (error,
1372  "Unknown address family %s", family);
1373  return _dbus_socket_get_invalid ();
1374  }
1375  hints.ai_protocol = IPPROTO_TCP;
1376  hints.ai_socktype = SOCK_STREAM;
1377  hints.ai_flags = AI_ADDRCONFIG;
1378 
1379  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1380  {
1381  dbus_set_error (error,
1382  _dbus_error_from_errno (errno),
1383  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1384  host, port, gai_strerror(res), res);
1385  return _dbus_socket_get_invalid ();
1386  }
1387 
1388  tmp = ai;
1389  while (tmp)
1390  {
1391  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1392  {
1393  freeaddrinfo(ai);
1394  _DBUS_ASSERT_ERROR_IS_SET(error);
1395  return _dbus_socket_get_invalid ();
1396  }
1397  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1398 
1399  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1400  {
1401  saved_errno = errno;
1402  _dbus_close (fd.fd, NULL);
1403  fd.fd = -1;
1404  tmp = tmp->ai_next;
1405  continue;
1406  }
1407 
1408  break;
1409  }
1410  freeaddrinfo(ai);
1411 
1412  if (fd.fd == -1)
1413  {
1414  dbus_set_error (error,
1415  _dbus_error_from_errno (saved_errno),
1416  "Failed to connect to socket \"%s:%s\" %s",
1417  host, port, _dbus_strerror(saved_errno));
1418  return _dbus_socket_get_invalid ();
1419  }
1420 
1421  if (noncefile != NULL)
1422  {
1423  DBusString noncefileStr;
1424  dbus_bool_t ret;
1425  _dbus_string_init_const (&noncefileStr, noncefile);
1426  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1427  _dbus_string_free (&noncefileStr);
1428 
1429  if (!ret)
1430  {
1431  _dbus_close (fd.fd, NULL);
1432  return _dbus_socket_get_invalid ();
1433  }
1434  }
1435 
1436  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1437  {
1438  _dbus_close (fd.fd, NULL);
1439  return _dbus_socket_get_invalid ();
1440  }
1441 
1442  return fd;
1443 }
1444 
1461 int
1462 _dbus_listen_tcp_socket (const char *host,
1463  const char *port,
1464  const char *family,
1465  DBusString *retport,
1466  DBusSocket **fds_p,
1467  DBusError *error)
1468 {
1469  int saved_errno;
1470  int nlisten_fd = 0, res, i;
1471  DBusSocket *listen_fd = NULL;
1472  struct addrinfo hints;
1473  struct addrinfo *ai, *tmp;
1474  unsigned int reuseaddr;
1475 
1476  *fds_p = NULL;
1477  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1478 
1479  _DBUS_ZERO (hints);
1480 
1481  if (!family)
1482  hints.ai_family = AF_UNSPEC;
1483  else if (!strcmp(family, "ipv4"))
1484  hints.ai_family = AF_INET;
1485  else if (!strcmp(family, "ipv6"))
1486  hints.ai_family = AF_INET6;
1487  else
1488  {
1489  dbus_set_error (error,
1491  "Unknown address family %s", family);
1492  return -1;
1493  }
1494 
1495  hints.ai_protocol = IPPROTO_TCP;
1496  hints.ai_socktype = SOCK_STREAM;
1497  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1498 
1499  redo_lookup_with_port:
1500  ai = NULL;
1501  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1502  {
1503  dbus_set_error (error,
1504  _dbus_error_from_errno (errno),
1505  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1506  host ? host : "*", port, gai_strerror(res), res);
1507  goto failed;
1508  }
1509 
1510  tmp = ai;
1511  while (tmp)
1512  {
1513  int fd = -1, tcp_nodelay_on;
1514  DBusSocket *newlisten_fd;
1515 
1516  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1517  {
1518  _DBUS_ASSERT_ERROR_IS_SET(error);
1519  goto failed;
1520  }
1521  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1522 
1523  reuseaddr = 1;
1524  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1525  {
1526  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1527  host ? host : "*", port, _dbus_strerror (errno));
1528  }
1529 
1530  /* Nagle's algorithm imposes a huge delay on the initial messages
1531  going over TCP. */
1532  tcp_nodelay_on = 1;
1533  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1534  {
1535  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1536  host ? host : "*", port, _dbus_strerror (errno));
1537  }
1538 
1539  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1540  {
1541  saved_errno = errno;
1542  _dbus_close(fd, NULL);
1543  if (saved_errno == EADDRINUSE)
1544  {
1545  /* Depending on kernel policy, binding to an IPv6 address
1546  might implicitly bind to a corresponding IPv4
1547  address or vice versa, resulting in EADDRINUSE for the
1548  other one (e.g. bindv6only=0 on Linux).
1549 
1550  Also, after we "goto redo_lookup_with_port" after binding
1551  a port on one of the possible addresses, we will
1552  try to bind that same port on every address, including the
1553  same address again for a second time; that one will
1554  also fail with EADDRINUSE.
1555 
1556  For both those reasons, ignore EADDRINUSE here */
1557  tmp = tmp->ai_next;
1558  continue;
1559  }
1560  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1561  "Failed to bind socket \"%s:%s\": %s",
1562  host ? host : "*", port, _dbus_strerror (saved_errno));
1563  goto failed;
1564  }
1565 
1566  if (listen (fd, 30 /* backlog */) < 0)
1567  {
1568  saved_errno = errno;
1569  _dbus_close (fd, NULL);
1570  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1571  "Failed to listen on socket \"%s:%s\": %s",
1572  host ? host : "*", port, _dbus_strerror (saved_errno));
1573  goto failed;
1574  }
1575 
1576  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1577  if (!newlisten_fd)
1578  {
1579  saved_errno = errno;
1580  _dbus_close (fd, NULL);
1581  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1582  "Failed to allocate file handle array: %s",
1583  _dbus_strerror (saved_errno));
1584  goto failed;
1585  }
1586  listen_fd = newlisten_fd;
1587  listen_fd[nlisten_fd].fd = fd;
1588  nlisten_fd++;
1589 
1590  if (!_dbus_string_get_length(retport))
1591  {
1592  /* If the user didn't specify a port, or used 0, then
1593  the kernel chooses a port. After the first address
1594  is bound to, we need to force all remaining addresses
1595  to use the same port */
1596  if (!port || !strcmp(port, "0"))
1597  {
1598  int result;
1599  struct sockaddr_storage addr;
1600  socklen_t addrlen;
1601  char portbuf[50];
1602 
1603  addrlen = sizeof(addr);
1604  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1605 
1606  if (result == -1 ||
1607  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1608  portbuf, sizeof(portbuf),
1609  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1610  {
1611  dbus_set_error (error, _dbus_error_from_errno (errno),
1612  "Failed to resolve port \"%s:%s\": %s (%d)",
1613  host ? host : "*", port, gai_strerror(res), res);
1614  goto failed;
1615  }
1616  if (!_dbus_string_append(retport, portbuf))
1617  {
1619  goto failed;
1620  }
1621 
1622  /* Release current address list & redo lookup */
1623  port = _dbus_string_get_const_data(retport);
1624  freeaddrinfo(ai);
1625  goto redo_lookup_with_port;
1626  }
1627  else
1628  {
1629  if (!_dbus_string_append(retport, port))
1630  {
1632  goto failed;
1633  }
1634  }
1635  }
1636 
1637  tmp = tmp->ai_next;
1638  }
1639  freeaddrinfo(ai);
1640  ai = NULL;
1641 
1642  if (!nlisten_fd)
1643  {
1644  errno = EADDRINUSE;
1645  dbus_set_error (error, _dbus_error_from_errno (errno),
1646  "Failed to bind socket \"%s:%s\": %s",
1647  host ? host : "*", port, _dbus_strerror (errno));
1648  goto failed;
1649  }
1650 
1651  for (i = 0 ; i < nlisten_fd ; i++)
1652  {
1653  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1654  {
1655  goto failed;
1656  }
1657  }
1658 
1659  *fds_p = listen_fd;
1660 
1661  return nlisten_fd;
1662 
1663  failed:
1664  if (ai)
1665  freeaddrinfo(ai);
1666  for (i = 0 ; i < nlisten_fd ; i++)
1667  _dbus_close(listen_fd[i].fd, NULL);
1668  dbus_free(listen_fd);
1669  return -1;
1670 }
1671 
1672 static dbus_bool_t
1673 write_credentials_byte (int server_fd,
1674  DBusError *error)
1675 {
1676  int bytes_written;
1677  char buf[1] = { '\0' };
1678 #if defined(HAVE_CMSGCRED)
1679  union {
1680  struct cmsghdr hdr;
1681  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1682  } cmsg;
1683  struct iovec iov;
1684  struct msghdr msg;
1685  iov.iov_base = buf;
1686  iov.iov_len = 1;
1687 
1688  _DBUS_ZERO(msg);
1689  msg.msg_iov = &iov;
1690  msg.msg_iovlen = 1;
1691 
1692  msg.msg_control = (caddr_t) &cmsg;
1693  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1694  _DBUS_ZERO(cmsg);
1695  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1696  cmsg.hdr.cmsg_level = SOL_SOCKET;
1697  cmsg.hdr.cmsg_type = SCM_CREDS;
1698 #endif
1699 
1700  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1701 
1702  again:
1703 
1704 #if defined(HAVE_CMSGCRED)
1705  bytes_written = sendmsg (server_fd, &msg, 0
1706 #if HAVE_DECL_MSG_NOSIGNAL
1707  |MSG_NOSIGNAL
1708 #endif
1709  );
1710 
1711  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1712  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1713  * only allows that on AF_UNIX. Try just doing a send() instead. */
1714  if (bytes_written < 0 && errno == EINVAL)
1715 #endif
1716  {
1717  bytes_written = send (server_fd, buf, 1, 0
1718 #if HAVE_DECL_MSG_NOSIGNAL
1719  |MSG_NOSIGNAL
1720 #endif
1721  );
1722  }
1723 
1724  if (bytes_written < 0 && errno == EINTR)
1725  goto again;
1726 
1727  if (bytes_written < 0)
1728  {
1729  dbus_set_error (error, _dbus_error_from_errno (errno),
1730  "Failed to write credentials byte: %s",
1731  _dbus_strerror (errno));
1732  return FALSE;
1733  }
1734  else if (bytes_written == 0)
1735  {
1737  "wrote zero bytes writing credentials byte");
1738  return FALSE;
1739  }
1740  else
1741  {
1742  _dbus_assert (bytes_written == 1);
1743  _dbus_verbose ("wrote credentials byte\n");
1744  return TRUE;
1745  }
1746 }
1747 
1748 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1749 static dbus_bool_t
1750 add_linux_security_label_to_credentials (int client_fd,
1751  DBusCredentials *credentials)
1752 {
1753 #if defined(__linux__) && defined(SO_PEERSEC)
1754  DBusString buf;
1755  socklen_t len = 1024;
1756  dbus_bool_t oom = FALSE;
1757 
1758  if (!_dbus_string_init_preallocated (&buf, len) ||
1759  !_dbus_string_set_length (&buf, len))
1760  return FALSE;
1761 
1762  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1763  _dbus_string_get_data (&buf), &len) < 0)
1764  {
1765  int e = errno;
1766 
1767  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1768  _dbus_strerror (e), (unsigned long) len);
1769 
1770  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1771  {
1772  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1773  _dbus_strerror (e));
1774  goto out;
1775  }
1776 
1777  /* If not enough space, len is updated to be enough.
1778  * Try again with a large enough buffer. */
1779  if (!_dbus_string_set_length (&buf, len))
1780  {
1781  oom = TRUE;
1782  goto out;
1783  }
1784 
1785  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1786  }
1787 
1788  if (len <= 0)
1789  {
1790  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1791  (unsigned long) len);
1792  goto out;
1793  }
1794 
1795  if (len > _dbus_string_get_length_uint (&buf))
1796  {
1797  _dbus_verbose ("%lu > %u", (unsigned long) len,
1798  _dbus_string_get_length_uint (&buf));
1799  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1800  }
1801 
1802  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1803  {
1804  /* the kernel included the trailing \0 in its count,
1805  * but DBusString always has an extra \0 after the data anyway */
1806  _dbus_verbose ("subtracting trailing \\0\n");
1807  len--;
1808  }
1809 
1810  if (!_dbus_string_set_length (&buf, len))
1811  {
1812  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1813  oom = TRUE;
1814  goto out;
1815  }
1816 
1817  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1818  {
1819  /* LSM people on the linux-security-module@ mailing list say this
1820  * should never happen: the label should be a bytestring with
1821  * an optional trailing \0 */
1822  _dbus_verbose ("security label from kernel had an embedded \\0, "
1823  "ignoring it\n");
1824  goto out;
1825  }
1826 
1827  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1828  (unsigned long) len,
1829  _dbus_string_get_const_data (&buf));
1830 
1832  _dbus_string_get_const_data (&buf)))
1833  {
1834  oom = TRUE;
1835  goto out;
1836  }
1837 
1838 out:
1839  _dbus_string_free (&buf);
1840  return !oom;
1841 #else
1842  /* no error */
1843  return TRUE;
1844 #endif
1845 }
1846 
1889  DBusCredentials *credentials,
1890  DBusError *error)
1891 {
1892  struct msghdr msg;
1893  struct iovec iov;
1894  char buf;
1895  dbus_uid_t uid_read;
1896  dbus_pid_t pid_read;
1897  int bytes_read;
1898 
1899 #ifdef HAVE_CMSGCRED
1900  union {
1901  struct cmsghdr hdr;
1902  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1903  } cmsg;
1904 #endif
1905 
1906  /* The POSIX spec certainly doesn't promise this, but
1907  * we need these assertions to fail as soon as we're wrong about
1908  * it so we can do the porting fixups
1909  */
1910  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1911  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1912  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1913 
1914  uid_read = DBUS_UID_UNSET;
1915  pid_read = DBUS_PID_UNSET;
1916 
1917  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1918 
1919  _dbus_credentials_clear (credentials);
1920 
1921  iov.iov_base = &buf;
1922  iov.iov_len = 1;
1923 
1924  _DBUS_ZERO(msg);
1925  msg.msg_iov = &iov;
1926  msg.msg_iovlen = 1;
1927 
1928 #if defined(HAVE_CMSGCRED)
1929  _DBUS_ZERO(cmsg);
1930  msg.msg_control = (caddr_t) &cmsg;
1931  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1932 #endif
1933 
1934  again:
1935  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1936 
1937  if (bytes_read < 0)
1938  {
1939  if (errno == EINTR)
1940  goto again;
1941 
1942  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1943  * normally only call read_credentials if the socket was ready
1944  * for reading
1945  */
1946 
1947  dbus_set_error (error, _dbus_error_from_errno (errno),
1948  "Failed to read credentials byte: %s",
1949  _dbus_strerror (errno));
1950  return FALSE;
1951  }
1952  else if (bytes_read == 0)
1953  {
1954  /* this should not happen unless we are using recvmsg wrong,
1955  * so is essentially here for paranoia
1956  */
1958  "Failed to read credentials byte (zero-length read)");
1959  return FALSE;
1960  }
1961  else if (buf != '\0')
1962  {
1964  "Credentials byte was not nul");
1965  return FALSE;
1966  }
1967 
1968  _dbus_verbose ("read credentials byte\n");
1969 
1970  {
1971 #ifdef SO_PEERCRED
1972  /* Supported by at least Linux and OpenBSD, with minor differences.
1973  *
1974  * This mechanism passes the process ID through and does not require
1975  * the peer's cooperation, so we prefer it over all others. Notably,
1976  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1977  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1978  * because this is much less fragile.
1979  */
1980 #ifdef __OpenBSD__
1981  struct sockpeercred cr;
1982 #else
1983  struct ucred cr;
1984 #endif
1985  socklen_t cr_len = sizeof (cr);
1986 
1987  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
1988  {
1989  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
1990  _dbus_strerror (errno));
1991  }
1992  else if (cr_len != sizeof (cr))
1993  {
1994  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
1995  cr_len, (int) sizeof (cr));
1996  }
1997  else
1998  {
1999  pid_read = cr.pid;
2000  uid_read = cr.uid;
2001  }
2002 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2003  /* Another variant of the above - used on NetBSD
2004  */
2005  struct unpcbid cr;
2006  socklen_t cr_len = sizeof (cr);
2007 
2008  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2009  {
2010  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2011  _dbus_strerror (errno));
2012  }
2013  else if (cr_len != sizeof (cr))
2014  {
2015  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2016  cr_len, (int) sizeof (cr));
2017  }
2018  else
2019  {
2020  pid_read = cr.unp_pid;
2021  uid_read = cr.unp_euid;
2022  }
2023 #elif defined(HAVE_CMSGCRED)
2024  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2025  * presence of that struct implies SCM_CREDS. Supported by at least
2026  * FreeBSD and DragonflyBSD.
2027  *
2028  * This mechanism requires the peer to help us (it has to send us a
2029  * SCM_CREDS message) but it does pass the process ID through,
2030  * which makes it better than getpeereid().
2031  */
2032  struct cmsgcred *cred;
2033  struct cmsghdr *cmsgp;
2034 
2035  for (cmsgp = CMSG_FIRSTHDR (&msg);
2036  cmsgp != NULL;
2037  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2038  {
2039  if (cmsgp->cmsg_type == SCM_CREDS &&
2040  cmsgp->cmsg_level == SOL_SOCKET &&
2041  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2042  {
2043  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2044  pid_read = cred->cmcred_pid;
2045  uid_read = cred->cmcred_euid;
2046  break;
2047  }
2048  }
2049 
2050 #elif defined(HAVE_GETPEERUCRED)
2051  /* Supported in at least Solaris >= 10. It should probably be higher
2052  * up this list, because it carries the pid and we use this code path
2053  * for audit data. */
2054  ucred_t * ucred = NULL;
2055  if (getpeerucred (client_fd.fd, &ucred) == 0)
2056  {
2057  pid_read = ucred_getpid (ucred);
2058  uid_read = ucred_geteuid (ucred);
2059 #ifdef HAVE_ADT
2060  /* generate audit session data based on socket ucred */
2061  adt_session_data_t *adth = NULL;
2062  adt_export_data_t *data = NULL;
2063  size_t size = 0;
2064  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2065  {
2066  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2067  }
2068  else
2069  {
2070  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2071  {
2072  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2073  }
2074  else
2075  {
2076  size = adt_export_session_data (adth, &data);
2077  if (size <= 0)
2078  {
2079  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2080  }
2081  else
2082  {
2083  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2084  free (data);
2085  }
2086  }
2087  (void) adt_end_session (adth);
2088  }
2089 #endif /* HAVE_ADT */
2090  }
2091  else
2092  {
2093  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2094  }
2095  if (ucred != NULL)
2096  ucred_free (ucred);
2097 
2098  /* ----------------------------------------------------------------
2099  * When adding new mechanisms, please add them above this point
2100  * if they support passing the process ID through, or below if not.
2101  * ---------------------------------------------------------------- */
2102 
2103 #elif defined(HAVE_GETPEEREID)
2104  /* getpeereid() originates from D.J. Bernstein and is fairly
2105  * widely-supported. According to a web search, it might be present in
2106  * any/all of:
2107  *
2108  * - AIX?
2109  * - Blackberry?
2110  * - Cygwin
2111  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2112  * - Mac OS X
2113  * - Minix 3.1.8+
2114  * - MirBSD?
2115  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2116  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2117  * - QNX?
2118  */
2119  uid_t euid;
2120  gid_t egid;
2121  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2122  {
2123  uid_read = euid;
2124  }
2125  else
2126  {
2127  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2128  }
2129 #else /* no supported mechanism */
2130 
2131 #warning Socket credentials not supported on this Unix OS
2132 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2133 
2134  /* Please add other operating systems known to support at least one of
2135  * the mechanisms above to this list, keeping alphabetical order.
2136  * Everything not in this list is best-effort.
2137  */
2138 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2139  defined(__linux__) || \
2140  defined(__OpenBSD__) || \
2141  defined(__NetBSD__)
2142 # error Credentials passing not working on this OS is a regression!
2143 #endif
2144 
2145  _dbus_verbose ("Socket credentials not supported on this OS\n");
2146 #endif
2147  }
2148 
2149  _dbus_verbose ("Credentials:"
2150  " pid "DBUS_PID_FORMAT
2151  " uid "DBUS_UID_FORMAT
2152  "\n",
2153  pid_read,
2154  uid_read);
2155 
2156  if (pid_read != DBUS_PID_UNSET)
2157  {
2158  if (!_dbus_credentials_add_pid (credentials, pid_read))
2159  {
2160  _DBUS_SET_OOM (error);
2161  return FALSE;
2162  }
2163  }
2164 
2165  if (uid_read != DBUS_UID_UNSET)
2166  {
2167  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2168  {
2169  _DBUS_SET_OOM (error);
2170  return FALSE;
2171  }
2172  }
2173 
2174  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2175  {
2176  _DBUS_SET_OOM (error);
2177  return FALSE;
2178  }
2179 
2180  return TRUE;
2181 }
2182 
2202  DBusError *error)
2203 {
2204  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2205 
2206  if (write_credentials_byte (server_fd.fd, error))
2207  return TRUE;
2208  else
2209  return FALSE;
2210 }
2211 
2221 DBusSocket
2223 {
2224  DBusSocket client_fd;
2225  struct sockaddr addr;
2226  socklen_t addrlen;
2227 #ifdef HAVE_ACCEPT4
2228  dbus_bool_t cloexec_done;
2229 #endif
2230 
2231  addrlen = sizeof (addr);
2232 
2233  retry:
2234 
2235 #ifdef HAVE_ACCEPT4
2236  /*
2237  * At compile-time, we assume that if accept4() is available in
2238  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2239  * not necessarily true that either is supported by the running kernel.
2240  */
2241  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2242  cloexec_done = client_fd.fd >= 0;
2243 
2244  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2245 #endif
2246  {
2247  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2248  }
2249 
2250  if (client_fd.fd < 0)
2251  {
2252  if (errno == EINTR)
2253  goto retry;
2254  }
2255 
2256  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2257 
2258 #ifdef HAVE_ACCEPT4
2259  if (!cloexec_done)
2260 #endif
2261  {
2262  _dbus_fd_set_close_on_exec(client_fd.fd);
2263  }
2264 
2265  return client_fd;
2266 }
2267 
2278 {
2279  const char *directory;
2280  struct stat sb;
2281 
2282  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2283 
2284  directory = _dbus_string_get_const_data (dir);
2285 
2286  if (stat (directory, &sb) < 0)
2287  {
2288  dbus_set_error (error, _dbus_error_from_errno (errno),
2289  "%s", _dbus_strerror (errno));
2290 
2291  return FALSE;
2292  }
2293 
2294  if (sb.st_uid != geteuid ())
2295  {
2297  "%s directory is owned by user %lu, not %lu",
2298  directory,
2299  (unsigned long) sb.st_uid,
2300  (unsigned long) geteuid ());
2301  return FALSE;
2302  }
2303 
2304  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2305  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2306  {
2308  "%s directory is not private to the user", directory);
2309  return FALSE;
2310  }
2311 
2312  return TRUE;
2313 }
2314 
2315 static dbus_bool_t
2316 fill_user_info_from_passwd (struct passwd *p,
2317  DBusUserInfo *info,
2318  DBusError *error)
2319 {
2320  _dbus_assert (p->pw_name != NULL);
2321  _dbus_assert (p->pw_dir != NULL);
2322 
2323  info->uid = p->pw_uid;
2324  info->primary_gid = p->pw_gid;
2325  info->username = _dbus_strdup (p->pw_name);
2326  info->homedir = _dbus_strdup (p->pw_dir);
2327 
2328  if (info->username == NULL ||
2329  info->homedir == NULL)
2330  {
2332  return FALSE;
2333  }
2334 
2335  return TRUE;
2336 }
2337 
2338 static dbus_bool_t
2339 fill_user_info (DBusUserInfo *info,
2340  dbus_uid_t uid,
2341  const DBusString *username,
2342  DBusError *error)
2343 {
2344  const char *username_c;
2345 
2346  /* exactly one of username/uid provided */
2347  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2348  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2349 
2350  info->uid = DBUS_UID_UNSET;
2351  info->primary_gid = DBUS_GID_UNSET;
2352  info->group_ids = NULL;
2353  info->n_group_ids = 0;
2354  info->username = NULL;
2355  info->homedir = NULL;
2356 
2357  if (username != NULL)
2358  username_c = _dbus_string_get_const_data (username);
2359  else
2360  username_c = NULL;
2361 
2362  /* For now assuming that the getpwnam() and getpwuid() flavors
2363  * are always symmetrical, if not we have to add more configure
2364  * checks
2365  */
2366 
2367 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2368  {
2369  struct passwd *p;
2370  int result;
2371  size_t buflen;
2372  char *buf;
2373  struct passwd p_str;
2374 
2375  /* retrieve maximum needed size for buf */
2376  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2377 
2378  /* sysconf actually returns a long, but everything else expects size_t,
2379  * so just recast here.
2380  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2381  */
2382  if ((long) buflen <= 0)
2383  buflen = 1024;
2384 
2385  result = -1;
2386  while (1)
2387  {
2388  buf = dbus_malloc (buflen);
2389  if (buf == NULL)
2390  {
2392  return FALSE;
2393  }
2394 
2395  p = NULL;
2396 #ifdef HAVE_POSIX_GETPWNAM_R
2397  if (uid != DBUS_UID_UNSET)
2398  result = getpwuid_r (uid, &p_str, buf, buflen,
2399  &p);
2400  else
2401  result = getpwnam_r (username_c, &p_str, buf, buflen,
2402  &p);
2403 #else
2404  if (uid != DBUS_UID_UNSET)
2405  p = getpwuid_r (uid, &p_str, buf, buflen);
2406  else
2407  p = getpwnam_r (username_c, &p_str, buf, buflen);
2408  result = 0;
2409 #endif /* !HAVE_POSIX_GETPWNAM_R */
2410  //Try a bigger buffer if ERANGE was returned
2411  if (result == ERANGE && buflen < 512 * 1024)
2412  {
2413  dbus_free (buf);
2414  buflen *= 2;
2415  }
2416  else
2417  {
2418  break;
2419  }
2420  }
2421  if (result == 0 && p == &p_str)
2422  {
2423  if (!fill_user_info_from_passwd (p, info, error))
2424  {
2425  dbus_free (buf);
2426  return FALSE;
2427  }
2428  dbus_free (buf);
2429  }
2430  else
2431  {
2432  dbus_set_error (error, _dbus_error_from_errno (errno),
2433  "User \"%s\" unknown or no memory to allocate password entry\n",
2434  username_c ? username_c : "???");
2435  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2436  dbus_free (buf);
2437  return FALSE;
2438  }
2439  }
2440 #else /* ! HAVE_GETPWNAM_R */
2441  {
2442  /* I guess we're screwed on thread safety here */
2443  struct passwd *p;
2444 
2445  if (uid != DBUS_UID_UNSET)
2446  p = getpwuid (uid);
2447  else
2448  p = getpwnam (username_c);
2449 
2450  if (p != NULL)
2451  {
2452  if (!fill_user_info_from_passwd (p, info, error))
2453  {
2454  return FALSE;
2455  }
2456  }
2457  else
2458  {
2459  dbus_set_error (error, _dbus_error_from_errno (errno),
2460  "User \"%s\" unknown or no memory to allocate password entry\n",
2461  username_c ? username_c : "???");
2462  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2463  return FALSE;
2464  }
2465  }
2466 #endif /* ! HAVE_GETPWNAM_R */
2467 
2468  /* Fill this in so we can use it to get groups */
2469  username_c = info->username;
2470 
2471 #ifdef HAVE_GETGROUPLIST
2472  {
2473  gid_t *buf;
2474  int buf_count;
2475  int i;
2476  int initial_buf_count;
2477 
2478  initial_buf_count = 17;
2479  buf_count = initial_buf_count;
2480  buf = dbus_new (gid_t, buf_count);
2481  if (buf == NULL)
2482  {
2484  goto failed;
2485  }
2486 
2487  if (getgrouplist (username_c,
2488  info->primary_gid,
2489  buf, &buf_count) < 0)
2490  {
2491  gid_t *new;
2492  /* Presumed cause of negative return code: buf has insufficient
2493  entries to hold the entire group list. The Linux behavior in this
2494  case is to pass back the actual number of groups in buf_count, but
2495  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2496  So as a hack, try to help out a bit by guessing a larger
2497  number of groups, within reason.. might still fail, of course,
2498  but we can at least print a more informative message. I looked up
2499  the "right way" to do this by downloading Apple's own source code
2500  for the "id" command, and it turns out that they use an
2501  undocumented library function getgrouplist_2 (!) which is not
2502  declared in any header in /usr/include (!!). That did not seem
2503  like the way to go here.
2504  */
2505  if (buf_count == initial_buf_count)
2506  {
2507  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2508  }
2509  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2510  if (new == NULL)
2511  {
2513  dbus_free (buf);
2514  goto failed;
2515  }
2516 
2517  buf = new;
2518 
2519  errno = 0;
2520  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2521  {
2522  if (errno == 0)
2523  {
2524  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2525  username_c, buf_count, buf_count);
2526  }
2527  else
2528  {
2529  dbus_set_error (error,
2530  _dbus_error_from_errno (errno),
2531  "Failed to get groups for username \"%s\" primary GID "
2532  DBUS_GID_FORMAT ": %s\n",
2533  username_c, info->primary_gid,
2534  _dbus_strerror (errno));
2535  dbus_free (buf);
2536  goto failed;
2537  }
2538  }
2539  }
2540 
2541  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2542  if (info->group_ids == NULL)
2543  {
2545  dbus_free (buf);
2546  goto failed;
2547  }
2548 
2549  for (i = 0; i < buf_count; ++i)
2550  info->group_ids[i] = buf[i];
2551 
2552  info->n_group_ids = buf_count;
2553 
2554  dbus_free (buf);
2555  }
2556 #else /* HAVE_GETGROUPLIST */
2557  {
2558  /* We just get the one group ID */
2559  info->group_ids = dbus_new (dbus_gid_t, 1);
2560  if (info->group_ids == NULL)
2561  {
2563  goto failed;
2564  }
2565 
2566  info->n_group_ids = 1;
2567 
2568  (info->group_ids)[0] = info->primary_gid;
2569  }
2570 #endif /* HAVE_GETGROUPLIST */
2571 
2572  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2573 
2574  return TRUE;
2575 
2576  failed:
2577  _DBUS_ASSERT_ERROR_IS_SET (error);
2578  return FALSE;
2579 }
2580 
2591  const DBusString *username,
2592  DBusError *error)
2593 {
2594  return fill_user_info (info, DBUS_UID_UNSET,
2595  username, error);
2596 }
2597 
2608  dbus_uid_t uid,
2609  DBusError *error)
2610 {
2611  return fill_user_info (info, uid,
2612  NULL, error);
2613 }
2614 
2624 {
2625  /* The POSIX spec certainly doesn't promise this, but
2626  * we need these assertions to fail as soon as we're wrong about
2627  * it so we can do the porting fixups
2628  */
2629  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2630  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2631  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2632 
2633  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2634  return FALSE;
2635  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2636  return FALSE;
2637 
2638  return TRUE;
2639 }
2640 
2654 {
2655  return _dbus_string_append_uint (str,
2656  _dbus_geteuid ());
2657 }
2658 
2663 dbus_pid_t
2665 {
2666  return getpid ();
2667 }
2668 
2672 dbus_uid_t
2674 {
2675  return getuid ();
2676 }
2677 
2681 dbus_uid_t
2683 {
2684  return geteuid ();
2685 }
2686 
2693 unsigned long
2695 {
2696  return getpid ();
2697 }
2698 
2707 _dbus_parse_uid (const DBusString *uid_str,
2708  dbus_uid_t *uid)
2709 {
2710  int end;
2711  long val;
2712 
2713  if (_dbus_string_get_length (uid_str) == 0)
2714  {
2715  _dbus_verbose ("UID string was zero length\n");
2716  return FALSE;
2717  }
2718 
2719  val = -1;
2720  end = 0;
2721  if (!_dbus_string_parse_int (uid_str, 0, &val,
2722  &end))
2723  {
2724  _dbus_verbose ("could not parse string as a UID\n");
2725  return FALSE;
2726  }
2727 
2728  if (end != _dbus_string_get_length (uid_str))
2729  {
2730  _dbus_verbose ("string contained trailing stuff after UID\n");
2731  return FALSE;
2732  }
2733 
2734  *uid = val;
2735 
2736  return TRUE;
2737 }
2738 
2739 #if !DBUS_USE_SYNC
2740 /* To be thread-safe by default on platforms that don't necessarily have
2741  * atomic operations (notably Debian armel, which is armv4t), we must
2742  * use a mutex that can be initialized statically, like this.
2743  * GLib >= 2.32 uses a similar system.
2744  */
2745 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2746 #endif
2747 
2754 dbus_int32_t
2756 {
2757 #if DBUS_USE_SYNC
2758  return __sync_add_and_fetch(&atomic->value, 1)-1;
2759 #else
2760  dbus_int32_t res;
2761 
2762  pthread_mutex_lock (&atomic_mutex);
2763  res = atomic->value;
2764  atomic->value += 1;
2765  pthread_mutex_unlock (&atomic_mutex);
2766 
2767  return res;
2768 #endif
2769 }
2770 
2777 dbus_int32_t
2779 {
2780 #if DBUS_USE_SYNC
2781  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2782 #else
2783  dbus_int32_t res;
2784 
2785  pthread_mutex_lock (&atomic_mutex);
2786  res = atomic->value;
2787  atomic->value -= 1;
2788  pthread_mutex_unlock (&atomic_mutex);
2789 
2790  return res;
2791 #endif
2792 }
2793 
2801 dbus_int32_t
2803 {
2804 #if DBUS_USE_SYNC
2805  __sync_synchronize ();
2806  return atomic->value;
2807 #else
2808  dbus_int32_t res;
2809 
2810  pthread_mutex_lock (&atomic_mutex);
2811  res = atomic->value;
2812  pthread_mutex_unlock (&atomic_mutex);
2813 
2814  return res;
2815 #endif
2816 }
2817 
2826 int
2828  int n_fds,
2829  int timeout_milliseconds)
2830 {
2831 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2832  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2833  if (timeout_milliseconds < -1)
2834  {
2835  timeout_milliseconds = -1;
2836  }
2837 
2838  return poll (fds,
2839  n_fds,
2840  timeout_milliseconds);
2841 #else /* ! HAVE_POLL */
2842  /* Emulate poll() in terms of select() */
2843  fd_set read_set, write_set, err_set;
2844  int max_fd = 0;
2845  int i;
2846  struct timeval tv;
2847  int ready;
2848 
2849  FD_ZERO (&read_set);
2850  FD_ZERO (&write_set);
2851  FD_ZERO (&err_set);
2852 
2853  for (i = 0; i < n_fds; i++)
2854  {
2855  DBusPollFD *fdp = &fds[i];
2856 
2857  if (fdp->events & _DBUS_POLLIN)
2858  FD_SET (fdp->fd, &read_set);
2859 
2860  if (fdp->events & _DBUS_POLLOUT)
2861  FD_SET (fdp->fd, &write_set);
2862 
2863  FD_SET (fdp->fd, &err_set);
2864 
2865  max_fd = MAX (max_fd, fdp->fd);
2866  }
2867 
2868  tv.tv_sec = timeout_milliseconds / 1000;
2869  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2870 
2871  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2872  timeout_milliseconds < 0 ? NULL : &tv);
2873 
2874  if (ready > 0)
2875  {
2876  for (i = 0; i < n_fds; i++)
2877  {
2878  DBusPollFD *fdp = &fds[i];
2879 
2880  fdp->revents = 0;
2881 
2882  if (FD_ISSET (fdp->fd, &read_set))
2883  fdp->revents |= _DBUS_POLLIN;
2884 
2885  if (FD_ISSET (fdp->fd, &write_set))
2886  fdp->revents |= _DBUS_POLLOUT;
2887 
2888  if (FD_ISSET (fdp->fd, &err_set))
2889  fdp->revents |= _DBUS_POLLERR;
2890  }
2891  }
2892 
2893  return ready;
2894 #endif
2895 }
2896 
2904 void
2906  long *tv_usec)
2907 {
2908 #ifdef HAVE_MONOTONIC_CLOCK
2909  struct timespec ts;
2910  clock_gettime (CLOCK_MONOTONIC, &ts);
2911 
2912  if (tv_sec)
2913  *tv_sec = ts.tv_sec;
2914  if (tv_usec)
2915  *tv_usec = ts.tv_nsec / 1000;
2916 #else
2917  struct timeval t;
2918 
2919  gettimeofday (&t, NULL);
2920 
2921  if (tv_sec)
2922  *tv_sec = t.tv_sec;
2923  if (tv_usec)
2924  *tv_usec = t.tv_usec;
2925 #endif
2926 }
2927 
2935 void
2936 _dbus_get_real_time (long *tv_sec,
2937  long *tv_usec)
2938 {
2939  struct timeval t;
2940 
2941  gettimeofday (&t, NULL);
2942 
2943  if (tv_sec)
2944  *tv_sec = t.tv_sec;
2945  if (tv_usec)
2946  *tv_usec = t.tv_usec;
2947 }
2948 
2959  DBusError *error)
2960 {
2961  const char *filename_c;
2962 
2963  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2964 
2965  filename_c = _dbus_string_get_const_data (filename);
2966 
2967  if (mkdir (filename_c, 0700) < 0)
2968  {
2969  if (errno == EEXIST)
2970  return TRUE;
2971 
2973  "Failed to create directory %s: %s\n",
2974  filename_c, _dbus_strerror (errno));
2975  return FALSE;
2976  }
2977  else
2978  return TRUE;
2979 }
2980 
2991  DBusError *error)
2992 {
2993  const char *filename_c;
2994 
2995  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2996 
2997  filename_c = _dbus_string_get_const_data (filename);
2998 
2999  if (mkdir (filename_c, 0700) < 0)
3000  {
3002  "Failed to create directory %s: %s\n",
3003  filename_c, _dbus_strerror (errno));
3004  return FALSE;
3005  }
3006  else
3007  return TRUE;
3008 }
3009 
3022  const DBusString *next_component)
3023 {
3024  dbus_bool_t dir_ends_in_slash;
3025  dbus_bool_t file_starts_with_slash;
3026 
3027  if (_dbus_string_get_length (dir) == 0 ||
3028  _dbus_string_get_length (next_component) == 0)
3029  return TRUE;
3030 
3031  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3032  _dbus_string_get_length (dir) - 1);
3033 
3034  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3035 
3036  if (dir_ends_in_slash && file_starts_with_slash)
3037  {
3038  _dbus_string_shorten (dir, 1);
3039  }
3040  else if (!(dir_ends_in_slash || file_starts_with_slash))
3041  {
3042  if (!_dbus_string_append_byte (dir, '/'))
3043  return FALSE;
3044  }
3045 
3046  return _dbus_string_copy (next_component, 0, dir,
3047  _dbus_string_get_length (dir));
3048 }
3049 
3051 #define NANOSECONDS_PER_SECOND 1000000000
3052 
3053 #define MICROSECONDS_PER_SECOND 1000000
3054 
3055 #define MILLISECONDS_PER_SECOND 1000
3056 
3057 #define NANOSECONDS_PER_MILLISECOND 1000000
3058 
3059 #define MICROSECONDS_PER_MILLISECOND 1000
3060 
3065 void
3066 _dbus_sleep_milliseconds (int milliseconds)
3067 {
3068 #ifdef HAVE_NANOSLEEP
3069  struct timespec req;
3070  struct timespec rem;
3071 
3072  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3073  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3074  rem.tv_sec = 0;
3075  rem.tv_nsec = 0;
3076 
3077  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3078  req = rem;
3079 #elif defined (HAVE_USLEEP)
3080  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3081 #else /* ! HAVE_USLEEP */
3082  sleep (MAX (milliseconds / 1000, 1));
3083 #endif
3084 }
3085 
3097  int n_bytes,
3098  DBusError *error)
3099 {
3100  int old_len;
3101  int fd;
3102  int result;
3103 
3104  old_len = _dbus_string_get_length (str);
3105  fd = -1;
3106 
3107  /* note, urandom on linux will fall back to pseudorandom */
3108  fd = open ("/dev/urandom", O_RDONLY);
3109 
3110  if (fd < 0)
3111  {
3112  dbus_set_error (error, _dbus_error_from_errno (errno),
3113  "Could not open /dev/urandom: %s",
3114  _dbus_strerror (errno));
3115  return FALSE;
3116  }
3117 
3118  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3119 
3120  result = _dbus_read (fd, str, n_bytes);
3121 
3122  if (result != n_bytes)
3123  {
3124  if (result < 0)
3125  dbus_set_error (error, _dbus_error_from_errno (errno),
3126  "Could not read /dev/urandom: %s",
3127  _dbus_strerror (errno));
3128  else
3130  "Short read from /dev/urandom");
3131 
3132  _dbus_close (fd, NULL);
3133  _dbus_string_set_length (str, old_len);
3134  return FALSE;
3135  }
3136 
3137  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3138  n_bytes);
3139 
3140  _dbus_close (fd, NULL);
3141 
3142  return TRUE;
3143 }
3144 
3150 void
3151 _dbus_exit (int code)
3152 {
3153  _exit (code);
3154 }
3155 
3164 const char*
3165 _dbus_strerror (int error_number)
3166 {
3167  const char *msg;
3168 
3169  msg = strerror (error_number);
3170  if (msg == NULL)
3171  msg = "unknown";
3172 
3173  return msg;
3174 }
3175 
3179 void
3181 {
3182  signal (SIGPIPE, SIG_IGN);
3183 }
3184 
3192 void
3194 {
3195  int val;
3196 
3197  val = fcntl (fd, F_GETFD, 0);
3198 
3199  if (val < 0)
3200  return;
3201 
3202  val |= FD_CLOEXEC;
3203 
3204  fcntl (fd, F_SETFD, val);
3205 }
3206 
3215 _dbus_close (int fd,
3216  DBusError *error)
3217 {
3218  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3219 
3220  again:
3221  if (close (fd) < 0)
3222  {
3223  if (errno == EINTR)
3224  goto again;
3225 
3226  dbus_set_error (error, _dbus_error_from_errno (errno),
3227  "Could not close fd %d", fd);
3228  return FALSE;
3229  }
3230 
3231  return TRUE;
3232 }
3233 
3242 int
3243 _dbus_dup(int fd,
3244  DBusError *error)
3245 {
3246  int new_fd;
3247 
3248 #ifdef F_DUPFD_CLOEXEC
3249  dbus_bool_t cloexec_done;
3250 
3251  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3252  cloexec_done = new_fd >= 0;
3253 
3254  if (new_fd < 0 && errno == EINVAL)
3255 #endif
3256  {
3257  new_fd = fcntl(fd, F_DUPFD, 3);
3258  }
3259 
3260  if (new_fd < 0) {
3261 
3262  dbus_set_error (error, _dbus_error_from_errno (errno),
3263  "Could not duplicate fd %d", fd);
3264  return -1;
3265  }
3266 
3267 #ifdef F_DUPFD_CLOEXEC
3268  if (!cloexec_done)
3269 #endif
3270  {
3272  }
3273 
3274  return new_fd;
3275 }
3276 
3286  DBusError *error)
3287 {
3288  return _dbus_set_fd_nonblocking (fd.fd, error);
3289 }
3290 
3291 static dbus_bool_t
3292 _dbus_set_fd_nonblocking (int fd,
3293  DBusError *error)
3294 {
3295  int val;
3296 
3297  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3298 
3299  val = fcntl (fd, F_GETFL, 0);
3300  if (val < 0)
3301  {
3302  dbus_set_error (error, _dbus_error_from_errno (errno),
3303  "Failed to get flags from file descriptor %d: %s",
3304  fd, _dbus_strerror (errno));
3305  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3306  _dbus_strerror (errno));
3307  return FALSE;
3308  }
3309 
3310  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3311  {
3312  dbus_set_error (error, _dbus_error_from_errno (errno),
3313  "Failed to set nonblocking flag of file descriptor %d: %s",
3314  fd, _dbus_strerror (errno));
3315  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3316  fd, _dbus_strerror (errno));
3317 
3318  return FALSE;
3319  }
3320 
3321  return TRUE;
3322 }
3323 
3329 void
3331 {
3332 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3333  void *bt[500];
3334  int bt_size;
3335  int i;
3336  char **syms;
3337 
3338  bt_size = backtrace (bt, 500);
3339 
3340  syms = backtrace_symbols (bt, bt_size);
3341 
3342  i = 0;
3343  while (i < bt_size)
3344  {
3345  /* don't use dbus_warn since it can _dbus_abort() */
3346  fprintf (stderr, " %s\n", syms[i]);
3347  ++i;
3348  }
3349  fflush (stderr);
3350 
3351  free (syms);
3352 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3353  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3354 #else
3355  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3356 #endif
3357 }
3358 
3373  DBusSocket *fd2,
3374  dbus_bool_t blocking,
3375  DBusError *error)
3376 {
3377 #ifdef HAVE_SOCKETPAIR
3378  int fds[2];
3379  int retval;
3380 
3381 #ifdef SOCK_CLOEXEC
3382  dbus_bool_t cloexec_done;
3383 
3384  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3385  cloexec_done = retval >= 0;
3386 
3387  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3388 #endif
3389  {
3390  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3391  }
3392 
3393  if (retval < 0)
3394  {
3395  dbus_set_error (error, _dbus_error_from_errno (errno),
3396  "Could not create full-duplex pipe");
3397  return FALSE;
3398  }
3399 
3400  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3401 
3402 #ifdef SOCK_CLOEXEC
3403  if (!cloexec_done)
3404 #endif
3405  {
3406  _dbus_fd_set_close_on_exec (fds[0]);
3407  _dbus_fd_set_close_on_exec (fds[1]);
3408  }
3409 
3410  if (!blocking &&
3411  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3412  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3413  {
3414  dbus_set_error (error, _dbus_error_from_errno (errno),
3415  "Could not set full-duplex pipe nonblocking");
3416 
3417  _dbus_close (fds[0], NULL);
3418  _dbus_close (fds[1], NULL);
3419 
3420  return FALSE;
3421  }
3422 
3423  fd1->fd = fds[0];
3424  fd2->fd = fds[1];
3425 
3426  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3427  fd1->fd, fd2->fd);
3428 
3429  return TRUE;
3430 #else
3431  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3433  "_dbus_socketpair() not implemented on this OS");
3434  return FALSE;
3435 #endif
3436 }
3437 
3446 int
3448  va_list args)
3449 {
3450  char static_buf[1024];
3451  int bufsize = sizeof (static_buf);
3452  int len;
3453  va_list args_copy;
3454 
3455  DBUS_VA_COPY (args_copy, args);
3456  len = vsnprintf (static_buf, bufsize, format, args_copy);
3457  va_end (args_copy);
3458 
3459  /* If vsnprintf() returned non-negative, then either the string fits in
3460  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3461  * returns the number of characters that were needed, or this OS returns the
3462  * truncated length.
3463  *
3464  * We ignore the possibility that snprintf might just ignore the length and
3465  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3466  * If your libc is really that bad, come back when you have a better one. */
3467  if (len == bufsize)
3468  {
3469  /* This could be the truncated length (Tru64 and IRIX have this bug),
3470  * or the real length could be coincidentally the same. Which is it?
3471  * If vsnprintf returns the truncated length, we'll go to the slow
3472  * path. */
3473  DBUS_VA_COPY (args_copy, args);
3474 
3475  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3476  len = -1;
3477 
3478  va_end (args_copy);
3479  }
3480 
3481  /* If vsnprintf() returned negative, we have to do more work.
3482  * HP-UX returns negative. */
3483  while (len < 0)
3484  {
3485  char *buf;
3486 
3487  bufsize *= 2;
3488 
3489  buf = dbus_malloc (bufsize);
3490 
3491  if (buf == NULL)
3492  return -1;
3493 
3494  DBUS_VA_COPY (args_copy, args);
3495  len = vsnprintf (buf, bufsize, format, args_copy);
3496  va_end (args_copy);
3497 
3498  dbus_free (buf);
3499 
3500  /* If the reported length is exactly the buffer size, round up to the
3501  * next size, in case vsnprintf has been returning the truncated
3502  * length */
3503  if (len == bufsize)
3504  len = -1;
3505  }
3506 
3507  return len;
3508 }
3509 
3516 const char*
3518 {
3519  /* Protected by _DBUS_LOCK_sysdeps */
3520  static const char* tmpdir = NULL;
3521 
3522  if (!_DBUS_LOCK (sysdeps))
3523  return NULL;
3524 
3525  if (tmpdir == NULL)
3526  {
3527  /* TMPDIR is what glibc uses, then
3528  * glibc falls back to the P_tmpdir macro which
3529  * just expands to "/tmp"
3530  */
3531  if (tmpdir == NULL)
3532  tmpdir = getenv("TMPDIR");
3533 
3534  /* These two env variables are probably
3535  * broken, but maybe some OS uses them?
3536  */
3537  if (tmpdir == NULL)
3538  tmpdir = getenv("TMP");
3539  if (tmpdir == NULL)
3540  tmpdir = getenv("TEMP");
3541 
3542  /* And this is the sane fallback. */
3543  if (tmpdir == NULL)
3544  tmpdir = "/tmp";
3545  }
3546 
3547  _DBUS_UNLOCK (sysdeps);
3548 
3549  _dbus_assert(tmpdir != NULL);
3550 
3551  return tmpdir;
3552 }
3553 
3554 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3555 
3574 static dbus_bool_t
3575 _read_subprocess_line_argv (const char *progpath,
3576  dbus_bool_t path_fallback,
3577  const char * const *argv,
3578  DBusString *result,
3579  DBusError *error)
3580 {
3581  int result_pipe[2] = { -1, -1 };
3582  int errors_pipe[2] = { -1, -1 };
3583  pid_t pid;
3584  int ret;
3585  int status;
3586  int orig_len;
3587 
3588  dbus_bool_t retval;
3589  sigset_t new_set, old_set;
3590 
3591  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3592  retval = FALSE;
3593 
3594  /* We need to block any existing handlers for SIGCHLD temporarily; they
3595  * will cause waitpid() below to fail.
3596  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3597  */
3598  sigemptyset (&new_set);
3599  sigaddset (&new_set, SIGCHLD);
3600  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3601 
3602  orig_len = _dbus_string_get_length (result);
3603 
3604 #define READ_END 0
3605 #define WRITE_END 1
3606  if (pipe (result_pipe) < 0)
3607  {
3608  dbus_set_error (error, _dbus_error_from_errno (errno),
3609  "Failed to create a pipe to call %s: %s",
3610  progpath, _dbus_strerror (errno));
3611  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3612  progpath, _dbus_strerror (errno));
3613  goto out;
3614  }
3615  if (pipe (errors_pipe) < 0)
3616  {
3617  dbus_set_error (error, _dbus_error_from_errno (errno),
3618  "Failed to create a pipe to call %s: %s",
3619  progpath, _dbus_strerror (errno));
3620  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3621  progpath, _dbus_strerror (errno));
3622  goto out;
3623  }
3624 
3625  pid = fork ();
3626  if (pid < 0)
3627  {
3628  dbus_set_error (error, _dbus_error_from_errno (errno),
3629  "Failed to fork() to call %s: %s",
3630  progpath, _dbus_strerror (errno));
3631  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3632  progpath, _dbus_strerror (errno));
3633  goto out;
3634  }
3635 
3636  if (pid == 0)
3637  {
3638  /* child process */
3639  const char *error_str;
3640 
3641  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3642  {
3643  int saved_errno = errno;
3644 
3645  /* Try to write details into the pipe, but don't bother
3646  * trying too hard (no retry loop). */
3647 
3648  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3649  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3650  {
3651  /* ignore, not much we can do */
3652  }
3653 
3654  error_str = _dbus_strerror (saved_errno);
3655 
3656  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3657  {
3658  /* ignore, not much we can do */
3659  }
3660 
3661  _exit (1);
3662  }
3663 
3664  /* set-up stdXXX */
3665  close (result_pipe[READ_END]);
3666  close (errors_pipe[READ_END]);
3667 
3668  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3669  _exit (1);
3670  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3671  _exit (1);
3672 
3673  _dbus_close_all ();
3674 
3675  sigprocmask (SIG_SETMASK, &old_set, NULL);
3676 
3677  /* If it looks fully-qualified, try execv first */
3678  if (progpath[0] == '/')
3679  {
3680  execv (progpath, (char * const *) argv);
3681  /* Ok, that failed. Now if path_fallback is given, let's
3682  * try unqualified. This is mostly a hack to work
3683  * around systems which ship dbus-launch in /usr/bin
3684  * but everything else in /bin (because dbus-launch
3685  * depends on X11).
3686  */
3687  if (path_fallback)
3688  /* We must have a slash, because we checked above */
3689  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3690  }
3691  else
3692  execvp (progpath, (char * const *) argv);
3693 
3694  /* still nothing, we failed */
3695  _exit (1);
3696  }
3697 
3698  /* parent process */
3699  close (result_pipe[WRITE_END]);
3700  close (errors_pipe[WRITE_END]);
3701  result_pipe[WRITE_END] = -1;
3702  errors_pipe[WRITE_END] = -1;
3703 
3704  ret = 0;
3705  do
3706  {
3707  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3708  }
3709  while (ret > 0);
3710 
3711  /* reap the child process to avoid it lingering as zombie */
3712  do
3713  {
3714  ret = waitpid (pid, &status, 0);
3715  }
3716  while (ret == -1 && errno == EINTR);
3717 
3718  /* We succeeded if the process exited with status 0 and
3719  anything was read */
3720  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3721  {
3722  /* The process ended with error */
3723  DBusString error_message;
3724  if (!_dbus_string_init (&error_message))
3725  {
3726  _DBUS_SET_OOM (error);
3727  goto out;
3728  }
3729 
3730  ret = 0;
3731  do
3732  {
3733  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3734  }
3735  while (ret > 0);
3736 
3737  _dbus_string_set_length (result, orig_len);
3738  if (_dbus_string_get_length (&error_message) > 0)
3740  "%s terminated abnormally with the following error: %s",
3741  progpath, _dbus_string_get_data (&error_message));
3742  else
3744  "%s terminated abnormally without any error message",
3745  progpath);
3746  goto out;
3747  }
3748 
3749  retval = TRUE;
3750 
3751  out:
3752  sigprocmask (SIG_SETMASK, &old_set, NULL);
3753 
3754  if (retval)
3755  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3756  else
3757  _DBUS_ASSERT_ERROR_IS_SET (error);
3758 
3759  if (result_pipe[0] != -1)
3760  close (result_pipe[0]);
3761  if (result_pipe[1] != -1)
3762  close (result_pipe[1]);
3763  if (errors_pipe[0] != -1)
3764  close (errors_pipe[0]);
3765  if (errors_pipe[1] != -1)
3766  close (errors_pipe[1]);
3767 
3768  return retval;
3769 }
3770 #endif
3771 
3785 _dbus_get_autolaunch_address (const char *scope,
3786  DBusString *address,
3787  DBusError *error)
3788 {
3789 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3790  static const char arg_dbus_launch[] = "dbus-launch";
3791  static const char arg_autolaunch[] = "--autolaunch";
3792  static const char arg_binary_syntax[] = "--binary-syntax";
3793  static const char arg_close_stderr[] = "--close-stderr";
3794 
3795  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3796  * but that's done elsewhere, and if it worked, this function wouldn't
3797  * be called.) */
3798  const char *display;
3799  const char *progpath;
3800  const char *argv[6];
3801  int i;
3802  DBusString uuid;
3803  dbus_bool_t retval;
3804 
3805  if (_dbus_check_setuid ())
3806  {
3808  "Unable to autolaunch when setuid");
3809  return FALSE;
3810  }
3811 
3812  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3813  retval = FALSE;
3814 
3815  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3816  * dbus-launch-x11 is just going to fail. Rather than trying to
3817  * run it, we might as well bail out early with a nice error.
3818  *
3819  * This is not strictly true in a world where the user bus exists,
3820  * because dbus-launch --autolaunch knows how to connect to that -
3821  * but if we were going to connect to the user bus, we'd have done
3822  * so before trying autolaunch: in any case. */
3823  display = _dbus_getenv ("DISPLAY");
3824 
3825  if (display == NULL || display[0] == '\0')
3826  {
3828  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3829  return FALSE;
3830  }
3831 
3832  if (!_dbus_string_init (&uuid))
3833  {
3834  _DBUS_SET_OOM (error);
3835  return FALSE;
3836  }
3837 
3838  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3839  {
3840  goto out;
3841  }
3842 
3843 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3844  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3845 
3846  if (progpath == NULL)
3847 #endif
3848  progpath = DBUS_BINDIR "/dbus-launch";
3849  /*
3850  * argv[0] is always dbus-launch, that's the name what we'll
3851  * get from /proc, or ps(1), regardless what the progpath is,
3852  * see fd.o#69716
3853  */
3854  i = 0;
3855  argv[i] = arg_dbus_launch;
3856  ++i;
3857  argv[i] = arg_autolaunch;
3858  ++i;
3859  argv[i] = _dbus_string_get_data (&uuid);
3860  ++i;
3861  argv[i] = arg_binary_syntax;
3862  ++i;
3863  argv[i] = arg_close_stderr;
3864  ++i;
3865  argv[i] = NULL;
3866  ++i;
3867 
3868  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3869 
3870  retval = _read_subprocess_line_argv (progpath,
3871  TRUE,
3872  argv, address, error);
3873 
3874  out:
3875  _dbus_string_free (&uuid);
3876  return retval;
3877 #else
3879  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3880  "set your DBUS_SESSION_BUS_ADDRESS instead");
3881  return FALSE;
3882 #endif
3883 }
3884 
3905  dbus_bool_t create_if_not_found,
3906  DBusError *error)
3907 {
3908  DBusString filename;
3909  dbus_bool_t b;
3910 
3911  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3912 
3913  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3914  if (b)
3915  return TRUE;
3916 
3917  dbus_error_free (error);
3918 
3919  /* Fallback to the system machine ID */
3920  _dbus_string_init_const (&filename, "/etc/machine-id");
3921  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3922 
3923  if (b)
3924  {
3925  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3926  * complain if that isn't possible for whatever reason */
3927  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3928  _dbus_write_uuid_file (&filename, machine_id, NULL);
3929 
3930  return TRUE;
3931  }
3932 
3933  if (!create_if_not_found)
3934  return FALSE;
3935 
3936  /* if none found, try to make a new one */
3937  dbus_error_free (error);
3938  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3939 
3940  if (!_dbus_generate_uuid (machine_id, error))
3941  return FALSE;
3942 
3943  return _dbus_write_uuid_file (&filename, machine_id, error);
3944 }
3945 
3955  const char *launchd_env_var,
3956  DBusError *error)
3957 {
3958 #ifdef DBUS_ENABLE_LAUNCHD
3959  char *argv[4];
3960  int i;
3961 
3962  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3963 
3964  if (_dbus_check_setuid ())
3965  {
3967  "Unable to find launchd socket when setuid");
3968  return FALSE;
3969  }
3970 
3971  i = 0;
3972  argv[i] = "launchctl";
3973  ++i;
3974  argv[i] = "getenv";
3975  ++i;
3976  argv[i] = (char*)launchd_env_var;
3977  ++i;
3978  argv[i] = NULL;
3979  ++i;
3980 
3981  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3982 
3983  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3984  {
3985  return FALSE;
3986  }
3987 
3988  /* no error, but no result either */
3989  if (_dbus_string_get_length(socket_path) == 0)
3990  {
3991  return FALSE;
3992  }
3993 
3994  /* strip the carriage-return */
3995  _dbus_string_shorten(socket_path, 1);
3996  return TRUE;
3997 #else /* DBUS_ENABLE_LAUNCHD */
3999  "can't lookup socket from launchd; launchd support not compiled in");
4000  return FALSE;
4001 #endif
4002 }
4003 
4004 #ifdef DBUS_ENABLE_LAUNCHD
4005 static dbus_bool_t
4006 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4007 {
4008  dbus_bool_t valid_socket;
4009  DBusString socket_path;
4010 
4011  if (_dbus_check_setuid ())
4012  {
4014  "Unable to find launchd socket when setuid");
4015  return FALSE;
4016  }
4017 
4018  if (!_dbus_string_init (&socket_path))
4019  {
4020  _DBUS_SET_OOM (error);
4021  return FALSE;
4022  }
4023 
4024  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4025 
4026  if (dbus_error_is_set(error))
4027  {
4028  _dbus_string_free(&socket_path);
4029  return FALSE;
4030  }
4031 
4032  if (!valid_socket)
4033  {
4034  dbus_set_error(error, "no socket path",
4035  "launchd did not provide a socket path, "
4036  "verify that org.freedesktop.dbus-session.plist is loaded!");
4037  _dbus_string_free(&socket_path);
4038  return FALSE;
4039  }
4040  if (!_dbus_string_append (address, "unix:path="))
4041  {
4042  _DBUS_SET_OOM (error);
4043  _dbus_string_free(&socket_path);
4044  return FALSE;
4045  }
4046  if (!_dbus_string_copy (&socket_path, 0, address,
4047  _dbus_string_get_length (address)))
4048  {
4049  _DBUS_SET_OOM (error);
4050  _dbus_string_free(&socket_path);
4051  return FALSE;
4052  }
4053 
4054  _dbus_string_free(&socket_path);
4055  return TRUE;
4056 }
4057 #endif
4058 
4060 _dbus_lookup_user_bus (dbus_bool_t *supported,
4061  DBusString *address,
4062  DBusError *error)
4063 {
4064  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4065  dbus_bool_t ret = FALSE;
4066  struct stat stbuf;
4067  DBusString user_bus_path;
4068 
4069  if (runtime_dir == NULL)
4070  {
4071  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4072  *supported = FALSE;
4073  return TRUE; /* Cannot use it, but not an error */
4074  }
4075 
4076  if (!_dbus_string_init (&user_bus_path))
4077  {
4078  _DBUS_SET_OOM (error);
4079  return FALSE;
4080  }
4081 
4082  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4083  {
4084  _DBUS_SET_OOM (error);
4085  goto out;
4086  }
4087 
4088  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4089  {
4090  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4091  _dbus_strerror (errno));
4092  *supported = FALSE;
4093  ret = TRUE; /* Cannot use it, but not an error */
4094  goto out;
4095  }
4096 
4097  if (stbuf.st_uid != getuid ())
4098  {
4099  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4100  (long) stbuf.st_uid, (long) getuid ());
4101  *supported = FALSE;
4102  ret = TRUE; /* Cannot use it, but not an error */
4103  goto out;
4104  }
4105 
4106  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4107  {
4108  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4109  (long) stbuf.st_mode);
4110  *supported = FALSE;
4111  ret = TRUE; /* Cannot use it, but not an error */
4112  goto out;
4113  }
4114 
4115  if (!_dbus_string_append (address, "unix:path=") ||
4116  !_dbus_address_append_escaped (address, &user_bus_path))
4117  {
4118  _DBUS_SET_OOM (error);
4119  goto out;
4120  }
4121 
4122  *supported = TRUE;
4123  ret = TRUE;
4124 
4125 out:
4126  _dbus_string_free (&user_bus_path);
4127  return ret;
4128 }
4129 
4151  DBusString *address,
4152  DBusError *error)
4153 {
4154 #ifdef DBUS_ENABLE_LAUNCHD
4155  *supported = TRUE;
4156  return _dbus_lookup_session_address_launchd (address, error);
4157 #else
4158  *supported = FALSE;
4159 
4160  if (!_dbus_lookup_user_bus (supported, address, error))
4161  return FALSE;
4162  else if (*supported)
4163  return TRUE;
4164 
4165  /* On non-Mac Unix platforms, if the session address isn't already
4166  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4167  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4168  * autolaunch: global default; see init_session_address in
4169  * dbus/dbus-bus.c. */
4170  return TRUE;
4171 #endif
4172 }
4173 
4181 void
4183 {
4185 }
4186 
4202  DBusCredentials *credentials)
4203 {
4204  DBusString homedir;
4205  DBusString dotdir;
4206  dbus_uid_t uid;
4207 
4208  _dbus_assert (credentials != NULL);
4210 
4211  if (!_dbus_string_init (&homedir))
4212  return FALSE;
4213 
4214  uid = _dbus_credentials_get_unix_uid (credentials);
4215  _dbus_assert (uid != DBUS_UID_UNSET);
4216 
4217  if (!_dbus_homedir_from_uid (uid, &homedir))
4218  goto failed;
4219 
4220 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4221  {
4222  const char *override;
4223 
4224  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4225  if (override != NULL && *override != '\0')
4226  {
4227  _dbus_string_set_length (&homedir, 0);
4228  if (!_dbus_string_append (&homedir, override))
4229  goto failed;
4230 
4231  _dbus_verbose ("Using fake homedir for testing: %s\n",
4232  _dbus_string_get_const_data (&homedir));
4233  }
4234  else
4235  {
4236  /* Not strictly thread-safe, but if we fail at thread-safety here,
4237  * the worst that will happen is some extra warnings. */
4238  static dbus_bool_t already_warned = FALSE;
4239  if (!already_warned)
4240  {
4241  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid");
4242  already_warned = TRUE;
4243  }
4244  }
4245  }
4246 #endif
4247 
4248  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4249  if (!_dbus_concat_dir_and_file (&homedir,
4250  &dotdir))
4251  goto failed;
4252 
4253  if (!_dbus_string_copy (&homedir, 0,
4254  directory, _dbus_string_get_length (directory))) {
4255  goto failed;
4256  }
4257 
4258  _dbus_string_free (&homedir);
4259  return TRUE;
4260 
4261  failed:
4262  _dbus_string_free (&homedir);
4263  return FALSE;
4264 }
4265 
4266 //PENDING(kdab) docs
4268 _dbus_daemon_publish_session_bus_address (const char* addr,
4269  const char *scope)
4270 {
4271  return TRUE;
4272 }
4273 
4274 //PENDING(kdab) docs
4275 void
4276 _dbus_daemon_unpublish_session_bus_address (void)
4277 {
4278 
4279 }
4280 
4289 {
4290  return e == EAGAIN || e == EWOULDBLOCK;
4291 }
4292 
4302  DBusError *error)
4303 {
4304  const char *filename_c;
4305 
4306  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4307 
4308  filename_c = _dbus_string_get_const_data (filename);
4309 
4310  if (rmdir (filename_c) != 0)
4311  {
4313  "Failed to remove directory %s: %s\n",
4314  filename_c, _dbus_strerror (errno));
4315  return FALSE;
4316  }
4317 
4318  return TRUE;
4319 }
4320 
4330 {
4331 #ifdef SCM_RIGHTS
4332  union {
4333  struct sockaddr sa;
4334  struct sockaddr_storage storage;
4335  struct sockaddr_un un;
4336  } sa_buf;
4337 
4338  socklen_t sa_len = sizeof(sa_buf);
4339 
4340  _DBUS_ZERO(sa_buf);
4341 
4342  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4343  return FALSE;
4344 
4345  return sa_buf.sa.sa_family == AF_UNIX;
4346 
4347 #else
4348  return FALSE;
4349 
4350 #endif
4351 }
4352 
4357 void
4359 {
4360  int maxfds, i;
4361 
4362 #ifdef __linux__
4363  DIR *d;
4364 
4365  /* On Linux we can optimize this a bit if /proc is available. If it
4366  isn't available, fall back to the brute force way. */
4367 
4368  d = opendir ("/proc/self/fd");
4369  if (d)
4370  {
4371  for (;;)
4372  {
4373  struct dirent *de;
4374  int fd;
4375  long l;
4376  char *e = NULL;
4377 
4378  de = readdir (d);
4379  if (!de)
4380  break;
4381 
4382  if (de->d_name[0] == '.')
4383  continue;
4384 
4385  errno = 0;
4386  l = strtol (de->d_name, &e, 10);
4387  if (errno != 0 || e == NULL || *e != '\0')
4388  continue;
4389 
4390  fd = (int) l;
4391  if (fd < 3)
4392  continue;
4393 
4394  if (fd == dirfd (d))
4395  continue;
4396 
4397  close (fd);
4398  }
4399 
4400  closedir (d);
4401  return;
4402  }
4403 #endif
4404 
4405  maxfds = sysconf (_SC_OPEN_MAX);
4406 
4407  /* Pick something reasonable if for some reason sysconf says
4408  * unlimited.
4409  */
4410  if (maxfds < 0)
4411  maxfds = 1024;
4412 
4413  /* close all inherited fds */
4414  for (i = 3; i < maxfds; i++)
4415  close (i);
4416 }
4417 
4429 {
4430  /* TODO: get __libc_enable_secure exported from glibc.
4431  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4432  */
4433 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4434  {
4435  /* See glibc/include/unistd.h */
4436  extern int __libc_enable_secure;
4437  return __libc_enable_secure;
4438  }
4439 #elif defined(HAVE_ISSETUGID)
4440  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4441  return issetugid ();
4442 #else
4443  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4444  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4445 
4446  /* We call into this function from _dbus_threads_init_platform_specific()
4447  * to make sure these are initialized before we start threading. */
4448  static dbus_bool_t check_setuid_initialised;
4449  static dbus_bool_t is_setuid;
4450 
4451  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4452  {
4453 #ifdef HAVE_GETRESUID
4454  if (getresuid (&ruid, &euid, &suid) != 0 ||
4455  getresgid (&rgid, &egid, &sgid) != 0)
4456 #endif /* HAVE_GETRESUID */
4457  {
4458  suid = ruid = getuid ();
4459  sgid = rgid = getgid ();
4460  euid = geteuid ();
4461  egid = getegid ();
4462  }
4463 
4464  check_setuid_initialised = TRUE;
4465  is_setuid = (ruid != euid || ruid != suid ||
4466  rgid != egid || rgid != sgid);
4467 
4468  }
4469  return is_setuid;
4470 #endif
4471 }
4472 
4482  DBusString *address,
4483  DBusError *error)
4484 {
4485  union {
4486  struct sockaddr sa;
4487  struct sockaddr_storage storage;
4488  struct sockaddr_un un;
4489  struct sockaddr_in ipv4;
4490  struct sockaddr_in6 ipv6;
4491  } socket;
4492  char hostip[INET6_ADDRSTRLEN];
4493  socklen_t size = sizeof (socket);
4494  DBusString path_str;
4495 
4496  if (getsockname (fd.fd, &socket.sa, &size))
4497  goto err;
4498 
4499  switch (socket.sa.sa_family)
4500  {
4501  case AF_UNIX:
4502  if (socket.un.sun_path[0]=='\0')
4503  {
4504  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4505  if (_dbus_string_append (address, "unix:abstract=") &&
4506  _dbus_address_append_escaped (address, &path_str))
4507  return TRUE;
4508  }
4509  else
4510  {
4511  _dbus_string_init_const (&path_str, socket.un.sun_path);
4512  if (_dbus_string_append (address, "unix:path=") &&
4513  _dbus_address_append_escaped (address, &path_str))
4514  return TRUE;
4515  }
4516  break;
4517  case AF_INET:
4518  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4519  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4520  hostip, ntohs (socket.ipv4.sin_port)))
4521  return TRUE;
4522  break;
4523 #ifdef AF_INET6
4524  case AF_INET6:
4525  _dbus_string_init_const (&path_str, hostip);
4526  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4527  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4528  ntohs (socket.ipv6.sin6_port)) &&
4529  _dbus_address_append_escaped (address, &path_str))
4530  return TRUE;
4531  break;
4532 #endif
4533  default:
4534  dbus_set_error (error,
4535  _dbus_error_from_errno (EINVAL),
4536  "Failed to read address from socket: Unknown socket type.");
4537  return FALSE;
4538  }
4539  err:
4540  dbus_set_error (error,
4541  _dbus_error_from_errno (errno),
4542  "Failed to open socket: %s",
4543  _dbus_strerror (errno));
4544  return FALSE;
4545 }
4546 
4547 int
4548 _dbus_save_socket_errno (void)
4549 {
4550  return errno;
4551 }
4552 
4553 void
4554 _dbus_restore_socket_errno (int saved_errno)
4555 {
4556  errno = saved_errno;
4557 }
4558 
4559 static const char *syslog_tag = "dbus";
4560 #ifdef HAVE_SYSLOG_H
4561 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4562 #endif
4563 
4578 void
4579 _dbus_init_system_log (const char *tag,
4580  DBusLogFlags flags)
4581 {
4582  /* We never want to turn off logging completely */
4583  _dbus_assert (
4584  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4585 
4586  syslog_tag = tag;
4587 
4588 #ifdef HAVE_SYSLOG_H
4589  log_flags = flags;
4590 
4591  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4592  openlog (tag, LOG_PID, LOG_DAEMON);
4593 #endif
4594 }
4595 
4606 void
4607 _dbus_logv (DBusSystemLogSeverity severity,
4608  const char *msg,
4609  va_list args)
4610 {
4611  va_list tmp;
4612 #ifdef HAVE_SYSLOG_H
4613  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4614  {
4615  int flags;
4616  switch (severity)
4617  {
4618  case DBUS_SYSTEM_LOG_INFO:
4619  flags = LOG_DAEMON | LOG_NOTICE;
4620  break;
4621  case DBUS_SYSTEM_LOG_WARNING:
4622  flags = LOG_DAEMON | LOG_WARNING;
4623  break;
4624  case DBUS_SYSTEM_LOG_SECURITY:
4625  flags = LOG_AUTH | LOG_NOTICE;
4626  break;
4627  case DBUS_SYSTEM_LOG_FATAL:
4628  flags = LOG_DAEMON|LOG_CRIT;
4629  break;
4630  default:
4631  _dbus_assert_not_reached ("invalid log severity");
4632  }
4633 
4634  DBUS_VA_COPY (tmp, args);
4635  vsyslog (flags, msg, tmp);
4636  va_end (tmp);
4637  }
4638 
4639  /* If we don't have syslog.h, we always behave as though stderr was in
4640  * the flags */
4641  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4642 #endif
4643  {
4644  DBUS_VA_COPY (tmp, args);
4645  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4646  vfprintf (stderr, msg, tmp);
4647  fputc ('\n', stderr);
4648  va_end (tmp);
4649  }
4650 
4651  if (severity == DBUS_SYSTEM_LOG_FATAL)
4652  exit (1);
4653 }
4654 
4655 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:935
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:437
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:280
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn&#39;t contain...
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:394
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:285
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:602
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:702
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;t supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:124
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:120
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:349
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_gid_t primary_gid
GID.
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials...
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:379
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:490
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
short events
Events to poll for.
Definition: dbus-sysdeps.h:374
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1283
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:113
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:115
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:592
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:461
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:106
Socket interface.
Definition: dbus-sysdeps.h:149
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:462
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:383
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
dbus_uid_t uid
UID.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
dbus_bool_t _dbus_read_credentials_socket(DBusSocket client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, unsigned int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
int _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute. ...
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1157
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:117
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:373
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:888
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:122
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
void _dbus_exit(int code)
Exit the process, returning the given value.
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:890
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:110
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
char * _dbus_strdup(const char *str)
Duplicates a string.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:187
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:108
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:375
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:385