D-Bus  1.12.8
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 __linux__
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 /* !__linux__ */
952  "Operating system does not support abstract socket namespace\n");
953  _dbus_close (fd, NULL);
954  return -1;
955 #endif /* !__linux__ */
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 __linux__
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 /* !__linux__ */
1156  "Operating system does not support abstract socket namespace\n");
1157  _dbus_close (listen_fd, NULL);
1158  return -1;
1159 #endif /* !__linux__ */
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  _dbus_close (fd, NULL);
1581  "Failed to allocate file handle array");
1582  goto failed;
1583  }
1584  listen_fd = newlisten_fd;
1585  listen_fd[nlisten_fd].fd = fd;
1586  nlisten_fd++;
1587 
1588  if (!_dbus_string_get_length(retport))
1589  {
1590  /* If the user didn't specify a port, or used 0, then
1591  the kernel chooses a port. After the first address
1592  is bound to, we need to force all remaining addresses
1593  to use the same port */
1594  if (!port || !strcmp(port, "0"))
1595  {
1596  int result;
1597  struct sockaddr_storage addr;
1598  socklen_t addrlen;
1599  char portbuf[50];
1600 
1601  addrlen = sizeof(addr);
1602  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1603 
1604  if (result == -1 ||
1605  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1606  portbuf, sizeof(portbuf),
1607  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1608  {
1609  dbus_set_error (error, _dbus_error_from_errno (errno),
1610  "Failed to resolve port \"%s:%s\": %s (%d)",
1611  host ? host : "*", port, gai_strerror(res), res);
1612  goto failed;
1613  }
1614  if (!_dbus_string_append(retport, portbuf))
1615  {
1617  goto failed;
1618  }
1619 
1620  /* Release current address list & redo lookup */
1621  port = _dbus_string_get_const_data(retport);
1622  freeaddrinfo(ai);
1623  goto redo_lookup_with_port;
1624  }
1625  else
1626  {
1627  if (!_dbus_string_append(retport, port))
1628  {
1630  goto failed;
1631  }
1632  }
1633  }
1634 
1635  tmp = tmp->ai_next;
1636  }
1637  freeaddrinfo(ai);
1638  ai = NULL;
1639 
1640  if (!nlisten_fd)
1641  {
1642  errno = EADDRINUSE;
1643  dbus_set_error (error, _dbus_error_from_errno (errno),
1644  "Failed to bind socket \"%s:%s\": %s",
1645  host ? host : "*", port, _dbus_strerror (errno));
1646  goto failed;
1647  }
1648 
1649  for (i = 0 ; i < nlisten_fd ; i++)
1650  {
1651  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1652  {
1653  goto failed;
1654  }
1655  }
1656 
1657  *fds_p = listen_fd;
1658 
1659  return nlisten_fd;
1660 
1661  failed:
1662  if (ai)
1663  freeaddrinfo(ai);
1664  for (i = 0 ; i < nlisten_fd ; i++)
1665  _dbus_close(listen_fd[i].fd, NULL);
1666  dbus_free(listen_fd);
1667  return -1;
1668 }
1669 
1670 static dbus_bool_t
1671 write_credentials_byte (int server_fd,
1672  DBusError *error)
1673 {
1674  int bytes_written;
1675  char buf[1] = { '\0' };
1676 #if defined(HAVE_CMSGCRED)
1677  union {
1678  struct cmsghdr hdr;
1679  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1680  } cmsg;
1681  struct iovec iov;
1682  struct msghdr msg;
1683  iov.iov_base = buf;
1684  iov.iov_len = 1;
1685 
1686  _DBUS_ZERO(msg);
1687  msg.msg_iov = &iov;
1688  msg.msg_iovlen = 1;
1689 
1690  msg.msg_control = (caddr_t) &cmsg;
1691  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1692  _DBUS_ZERO(cmsg);
1693  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1694  cmsg.hdr.cmsg_level = SOL_SOCKET;
1695  cmsg.hdr.cmsg_type = SCM_CREDS;
1696 #endif
1697 
1698  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1699 
1700  again:
1701 
1702 #if defined(HAVE_CMSGCRED)
1703  bytes_written = sendmsg (server_fd, &msg, 0
1704 #if HAVE_DECL_MSG_NOSIGNAL
1705  |MSG_NOSIGNAL
1706 #endif
1707  );
1708 
1709  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1710  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1711  * only allows that on AF_UNIX. Try just doing a send() instead. */
1712  if (bytes_written < 0 && errno == EINVAL)
1713 #endif
1714  {
1715  bytes_written = send (server_fd, buf, 1, 0
1716 #if HAVE_DECL_MSG_NOSIGNAL
1717  |MSG_NOSIGNAL
1718 #endif
1719  );
1720  }
1721 
1722  if (bytes_written < 0 && errno == EINTR)
1723  goto again;
1724 
1725  if (bytes_written < 0)
1726  {
1727  dbus_set_error (error, _dbus_error_from_errno (errno),
1728  "Failed to write credentials byte: %s",
1729  _dbus_strerror (errno));
1730  return FALSE;
1731  }
1732  else if (bytes_written == 0)
1733  {
1735  "wrote zero bytes writing credentials byte");
1736  return FALSE;
1737  }
1738  else
1739  {
1740  _dbus_assert (bytes_written == 1);
1741  _dbus_verbose ("wrote credentials byte\n");
1742  return TRUE;
1743  }
1744 }
1745 
1746 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1747 static dbus_bool_t
1748 add_linux_security_label_to_credentials (int client_fd,
1749  DBusCredentials *credentials)
1750 {
1751 #if defined(__linux__) && defined(SO_PEERSEC)
1752  DBusString buf;
1753  socklen_t len = 1024;
1754  dbus_bool_t oom = FALSE;
1755 
1756  if (!_dbus_string_init_preallocated (&buf, len) ||
1757  !_dbus_string_set_length (&buf, len))
1758  return FALSE;
1759 
1760  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1761  _dbus_string_get_data (&buf), &len) < 0)
1762  {
1763  int e = errno;
1764 
1765  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1766  _dbus_strerror (e), (unsigned long) len);
1767 
1768  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1769  {
1770  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1771  _dbus_strerror (e));
1772  goto out;
1773  }
1774 
1775  /* If not enough space, len is updated to be enough.
1776  * Try again with a large enough buffer. */
1777  if (!_dbus_string_set_length (&buf, len))
1778  {
1779  oom = TRUE;
1780  goto out;
1781  }
1782 
1783  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1784  }
1785 
1786  if (len <= 0)
1787  {
1788  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1789  (unsigned long) len);
1790  goto out;
1791  }
1792 
1793  if (len > _dbus_string_get_length_uint (&buf))
1794  {
1795  _dbus_verbose ("%lu > %u", (unsigned long) len,
1796  _dbus_string_get_length_uint (&buf));
1797  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1798  }
1799 
1800  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1801  {
1802  /* the kernel included the trailing \0 in its count,
1803  * but DBusString always has an extra \0 after the data anyway */
1804  _dbus_verbose ("subtracting trailing \\0\n");
1805  len--;
1806  }
1807 
1808  if (!_dbus_string_set_length (&buf, len))
1809  {
1810  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1811  oom = TRUE;
1812  goto out;
1813  }
1814 
1815  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1816  {
1817  /* LSM people on the linux-security-module@ mailing list say this
1818  * should never happen: the label should be a bytestring with
1819  * an optional trailing \0 */
1820  _dbus_verbose ("security label from kernel had an embedded \\0, "
1821  "ignoring it\n");
1822  goto out;
1823  }
1824 
1825  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1826  (unsigned long) len,
1827  _dbus_string_get_const_data (&buf));
1828 
1830  _dbus_string_get_const_data (&buf)))
1831  {
1832  oom = TRUE;
1833  goto out;
1834  }
1835 
1836 out:
1837  _dbus_string_free (&buf);
1838  return !oom;
1839 #else
1840  /* no error */
1841  return TRUE;
1842 #endif
1843 }
1844 
1887  DBusCredentials *credentials,
1888  DBusError *error)
1889 {
1890  struct msghdr msg;
1891  struct iovec iov;
1892  char buf;
1893  dbus_uid_t uid_read;
1894  dbus_pid_t pid_read;
1895  int bytes_read;
1896 
1897 #ifdef HAVE_CMSGCRED
1898  union {
1899  struct cmsghdr hdr;
1900  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1901  } cmsg;
1902 #endif
1903 
1904  /* The POSIX spec certainly doesn't promise this, but
1905  * we need these assertions to fail as soon as we're wrong about
1906  * it so we can do the porting fixups
1907  */
1908  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1909  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1910  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1911 
1912  uid_read = DBUS_UID_UNSET;
1913  pid_read = DBUS_PID_UNSET;
1914 
1915  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1916 
1917  _dbus_credentials_clear (credentials);
1918 
1919  iov.iov_base = &buf;
1920  iov.iov_len = 1;
1921 
1922  _DBUS_ZERO(msg);
1923  msg.msg_iov = &iov;
1924  msg.msg_iovlen = 1;
1925 
1926 #if defined(HAVE_CMSGCRED)
1927  _DBUS_ZERO(cmsg);
1928  msg.msg_control = (caddr_t) &cmsg;
1929  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1930 #endif
1931 
1932  again:
1933  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1934 
1935  if (bytes_read < 0)
1936  {
1937  if (errno == EINTR)
1938  goto again;
1939 
1940  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1941  * normally only call read_credentials if the socket was ready
1942  * for reading
1943  */
1944 
1945  dbus_set_error (error, _dbus_error_from_errno (errno),
1946  "Failed to read credentials byte: %s",
1947  _dbus_strerror (errno));
1948  return FALSE;
1949  }
1950  else if (bytes_read == 0)
1951  {
1952  /* this should not happen unless we are using recvmsg wrong,
1953  * so is essentially here for paranoia
1954  */
1956  "Failed to read credentials byte (zero-length read)");
1957  return FALSE;
1958  }
1959  else if (buf != '\0')
1960  {
1962  "Credentials byte was not nul");
1963  return FALSE;
1964  }
1965 
1966  _dbus_verbose ("read credentials byte\n");
1967 
1968  {
1969 #ifdef SO_PEERCRED
1970  /* Supported by at least Linux and OpenBSD, with minor differences.
1971  *
1972  * This mechanism passes the process ID through and does not require
1973  * the peer's cooperation, so we prefer it over all others. Notably,
1974  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1975  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1976  * because this is much less fragile.
1977  */
1978 #ifdef __OpenBSD__
1979  struct sockpeercred cr;
1980 #else
1981  struct ucred cr;
1982 #endif
1983  socklen_t cr_len = sizeof (cr);
1984 
1985  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
1986  {
1987  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
1988  _dbus_strerror (errno));
1989  }
1990  else if (cr_len != sizeof (cr))
1991  {
1992  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
1993  cr_len, (int) sizeof (cr));
1994  }
1995  else
1996  {
1997  pid_read = cr.pid;
1998  uid_read = cr.uid;
1999  }
2000 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2001  /* Another variant of the above - used on NetBSD
2002  */
2003  struct unpcbid cr;
2004  socklen_t cr_len = sizeof (cr);
2005 
2006  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2007  {
2008  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2009  _dbus_strerror (errno));
2010  }
2011  else if (cr_len != sizeof (cr))
2012  {
2013  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2014  cr_len, (int) sizeof (cr));
2015  }
2016  else
2017  {
2018  pid_read = cr.unp_pid;
2019  uid_read = cr.unp_euid;
2020  }
2021 #elif defined(HAVE_CMSGCRED)
2022  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2023  * presence of that struct implies SCM_CREDS. Supported by at least
2024  * FreeBSD and DragonflyBSD.
2025  *
2026  * This mechanism requires the peer to help us (it has to send us a
2027  * SCM_CREDS message) but it does pass the process ID through,
2028  * which makes it better than getpeereid().
2029  */
2030  struct cmsgcred *cred;
2031  struct cmsghdr *cmsgp;
2032 
2033  for (cmsgp = CMSG_FIRSTHDR (&msg);
2034  cmsgp != NULL;
2035  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2036  {
2037  if (cmsgp->cmsg_type == SCM_CREDS &&
2038  cmsgp->cmsg_level == SOL_SOCKET &&
2039  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2040  {
2041  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2042  pid_read = cred->cmcred_pid;
2043  uid_read = cred->cmcred_euid;
2044  break;
2045  }
2046  }
2047 
2048 #elif defined(HAVE_GETPEERUCRED)
2049  /* Supported in at least Solaris >= 10. It should probably be higher
2050  * up this list, because it carries the pid and we use this code path
2051  * for audit data. */
2052  ucred_t * ucred = NULL;
2053  if (getpeerucred (client_fd.fd, &ucred) == 0)
2054  {
2055 #ifdef HAVE_ADT
2056  adt_session_data_t *adth = NULL;
2057 #endif
2058  pid_read = ucred_getpid (ucred);
2059  uid_read = ucred_geteuid (ucred);
2060 #ifdef HAVE_ADT
2061  /* generate audit session data based on socket ucred */
2062  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2063  {
2064  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2065  }
2066  else
2067  {
2068  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2069  {
2070  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2071  }
2072  else
2073  {
2074  adt_export_data_t *data = NULL;
2075  size_t size = adt_export_session_data (adth, &data);
2076  if (size <= 0)
2077  {
2078  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2079  }
2080  else
2081  {
2082  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2083  free (data);
2084  }
2085  }
2086  (void) adt_end_session (adth);
2087  }
2088 #endif /* HAVE_ADT */
2089  }
2090  else
2091  {
2092  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2093  }
2094  if (ucred != NULL)
2095  ucred_free (ucred);
2096 
2097  /* ----------------------------------------------------------------
2098  * When adding new mechanisms, please add them above this point
2099  * if they support passing the process ID through, or below if not.
2100  * ---------------------------------------------------------------- */
2101 
2102 #elif defined(HAVE_GETPEEREID)
2103  /* getpeereid() originates from D.J. Bernstein and is fairly
2104  * widely-supported. According to a web search, it might be present in
2105  * any/all of:
2106  *
2107  * - AIX?
2108  * - Blackberry?
2109  * - Cygwin
2110  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2111  * - Mac OS X
2112  * - Minix 3.1.8+
2113  * - MirBSD?
2114  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2115  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2116  * - QNX?
2117  */
2118  uid_t euid;
2119  gid_t egid;
2120  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2121  {
2122  uid_read = euid;
2123  }
2124  else
2125  {
2126  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2127  }
2128 #else /* no supported mechanism */
2129 
2130 #warning Socket credentials not supported on this Unix OS
2131 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2132 
2133  /* Please add other operating systems known to support at least one of
2134  * the mechanisms above to this list, keeping alphabetical order.
2135  * Everything not in this list is best-effort.
2136  */
2137 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2138  defined(__linux__) || \
2139  defined(__OpenBSD__) || \
2140  defined(__NetBSD__)
2141 # error Credentials passing not working on this OS is a regression!
2142 #endif
2143 
2144  _dbus_verbose ("Socket credentials not supported on this OS\n");
2145 #endif
2146  }
2147 
2148  _dbus_verbose ("Credentials:"
2149  " pid "DBUS_PID_FORMAT
2150  " uid "DBUS_UID_FORMAT
2151  "\n",
2152  pid_read,
2153  uid_read);
2154 
2155  if (pid_read != DBUS_PID_UNSET)
2156  {
2157  if (!_dbus_credentials_add_pid (credentials, pid_read))
2158  {
2159  _DBUS_SET_OOM (error);
2160  return FALSE;
2161  }
2162  }
2163 
2164  if (uid_read != DBUS_UID_UNSET)
2165  {
2166  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2167  {
2168  _DBUS_SET_OOM (error);
2169  return FALSE;
2170  }
2171  }
2172 
2173  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2174  {
2175  _DBUS_SET_OOM (error);
2176  return FALSE;
2177  }
2178 
2179  return TRUE;
2180 }
2181 
2201  DBusError *error)
2202 {
2203  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2204 
2205  if (write_credentials_byte (server_fd.fd, error))
2206  return TRUE;
2207  else
2208  return FALSE;
2209 }
2210 
2220 DBusSocket
2222 {
2223  DBusSocket client_fd;
2224  struct sockaddr addr;
2225  socklen_t addrlen;
2226 #ifdef HAVE_ACCEPT4
2227  dbus_bool_t cloexec_done;
2228 #endif
2229 
2230  addrlen = sizeof (addr);
2231 
2232  retry:
2233 
2234 #ifdef HAVE_ACCEPT4
2235  /*
2236  * At compile-time, we assume that if accept4() is available in
2237  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2238  * not necessarily true that either is supported by the running kernel.
2239  */
2240  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2241  cloexec_done = client_fd.fd >= 0;
2242 
2243  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2244 #endif
2245  {
2246  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2247  }
2248 
2249  if (client_fd.fd < 0)
2250  {
2251  if (errno == EINTR)
2252  goto retry;
2253  }
2254 
2255  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2256 
2257 #ifdef HAVE_ACCEPT4
2258  if (!cloexec_done)
2259 #endif
2260  {
2261  _dbus_fd_set_close_on_exec(client_fd.fd);
2262  }
2263 
2264  return client_fd;
2265 }
2266 
2277 {
2278  const char *directory;
2279  struct stat sb;
2280 
2281  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2282 
2283  directory = _dbus_string_get_const_data (dir);
2284 
2285  if (stat (directory, &sb) < 0)
2286  {
2287  dbus_set_error (error, _dbus_error_from_errno (errno),
2288  "%s", _dbus_strerror (errno));
2289 
2290  return FALSE;
2291  }
2292 
2293  if (sb.st_uid != geteuid ())
2294  {
2296  "%s directory is owned by user %lu, not %lu",
2297  directory,
2298  (unsigned long) sb.st_uid,
2299  (unsigned long) geteuid ());
2300  return FALSE;
2301  }
2302 
2303  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2304  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2305  {
2307  "%s directory is not private to the user", directory);
2308  return FALSE;
2309  }
2310 
2311  return TRUE;
2312 }
2313 
2314 static dbus_bool_t
2315 fill_user_info_from_passwd (struct passwd *p,
2316  DBusUserInfo *info,
2317  DBusError *error)
2318 {
2319  _dbus_assert (p->pw_name != NULL);
2320  _dbus_assert (p->pw_dir != NULL);
2321 
2322  info->uid = p->pw_uid;
2323  info->primary_gid = p->pw_gid;
2324  info->username = _dbus_strdup (p->pw_name);
2325  info->homedir = _dbus_strdup (p->pw_dir);
2326 
2327  if (info->username == NULL ||
2328  info->homedir == NULL)
2329  {
2331  return FALSE;
2332  }
2333 
2334  return TRUE;
2335 }
2336 
2337 static dbus_bool_t
2338 fill_user_info (DBusUserInfo *info,
2339  dbus_uid_t uid,
2340  const DBusString *username,
2341  DBusError *error)
2342 {
2343  const char *username_c;
2344 
2345  /* exactly one of username/uid provided */
2346  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2347  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2348 
2349  info->uid = DBUS_UID_UNSET;
2350  info->primary_gid = DBUS_GID_UNSET;
2351  info->group_ids = NULL;
2352  info->n_group_ids = 0;
2353  info->username = NULL;
2354  info->homedir = NULL;
2355 
2356  if (username != NULL)
2357  username_c = _dbus_string_get_const_data (username);
2358  else
2359  username_c = NULL;
2360 
2361  /* For now assuming that the getpwnam() and getpwuid() flavors
2362  * are always symmetrical, if not we have to add more configure
2363  * checks
2364  */
2365 
2366 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2367  {
2368  struct passwd *p;
2369  int result;
2370  size_t buflen;
2371  char *buf;
2372  struct passwd p_str;
2373 
2374  /* retrieve maximum needed size for buf */
2375  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2376 
2377  /* sysconf actually returns a long, but everything else expects size_t,
2378  * so just recast here.
2379  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2380  */
2381  if ((long) buflen <= 0)
2382  buflen = 1024;
2383 
2384  result = -1;
2385  while (1)
2386  {
2387  buf = dbus_malloc (buflen);
2388  if (buf == NULL)
2389  {
2391  return FALSE;
2392  }
2393 
2394  p = NULL;
2395 #ifdef HAVE_POSIX_GETPWNAM_R
2396  if (uid != DBUS_UID_UNSET)
2397  result = getpwuid_r (uid, &p_str, buf, buflen,
2398  &p);
2399  else
2400  result = getpwnam_r (username_c, &p_str, buf, buflen,
2401  &p);
2402 #else
2403  if (uid != DBUS_UID_UNSET)
2404  p = getpwuid_r (uid, &p_str, buf, buflen);
2405  else
2406  p = getpwnam_r (username_c, &p_str, buf, buflen);
2407  result = 0;
2408 #endif /* !HAVE_POSIX_GETPWNAM_R */
2409  //Try a bigger buffer if ERANGE was returned
2410  if (result == ERANGE && buflen < 512 * 1024)
2411  {
2412  dbus_free (buf);
2413  buflen *= 2;
2414  }
2415  else
2416  {
2417  break;
2418  }
2419  }
2420  if (result == 0 && p == &p_str)
2421  {
2422  if (!fill_user_info_from_passwd (p, info, error))
2423  {
2424  dbus_free (buf);
2425  return FALSE;
2426  }
2427  dbus_free (buf);
2428  }
2429  else
2430  {
2431  dbus_set_error (error, _dbus_error_from_errno (errno),
2432  "User \"%s\" unknown or no memory to allocate password entry\n",
2433  username_c ? username_c : "???");
2434  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2435  dbus_free (buf);
2436  return FALSE;
2437  }
2438  }
2439 #else /* ! HAVE_GETPWNAM_R */
2440  {
2441  /* I guess we're screwed on thread safety here */
2442  struct passwd *p;
2443 
2444  if (uid != DBUS_UID_UNSET)
2445  p = getpwuid (uid);
2446  else
2447  p = getpwnam (username_c);
2448 
2449  if (p != NULL)
2450  {
2451  if (!fill_user_info_from_passwd (p, info, error))
2452  {
2453  return FALSE;
2454  }
2455  }
2456  else
2457  {
2458  dbus_set_error (error, _dbus_error_from_errno (errno),
2459  "User \"%s\" unknown or no memory to allocate password entry\n",
2460  username_c ? username_c : "???");
2461  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2462  return FALSE;
2463  }
2464  }
2465 #endif /* ! HAVE_GETPWNAM_R */
2466 
2467  /* Fill this in so we can use it to get groups */
2468  username_c = info->username;
2469 
2470 #ifdef HAVE_GETGROUPLIST
2471  {
2472  gid_t *buf;
2473  int buf_count;
2474  int i;
2475  int initial_buf_count;
2476 
2477  initial_buf_count = 17;
2478  buf_count = initial_buf_count;
2479  buf = dbus_new (gid_t, buf_count);
2480  if (buf == NULL)
2481  {
2483  goto failed;
2484  }
2485 
2486  if (getgrouplist (username_c,
2487  info->primary_gid,
2488  buf, &buf_count) < 0)
2489  {
2490  gid_t *new;
2491  /* Presumed cause of negative return code: buf has insufficient
2492  entries to hold the entire group list. The Linux behavior in this
2493  case is to pass back the actual number of groups in buf_count, but
2494  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2495  So as a hack, try to help out a bit by guessing a larger
2496  number of groups, within reason.. might still fail, of course,
2497  but we can at least print a more informative message. I looked up
2498  the "right way" to do this by downloading Apple's own source code
2499  for the "id" command, and it turns out that they use an
2500  undocumented library function getgrouplist_2 (!) which is not
2501  declared in any header in /usr/include (!!). That did not seem
2502  like the way to go here.
2503  */
2504  if (buf_count == initial_buf_count)
2505  {
2506  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2507  }
2508  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2509  if (new == NULL)
2510  {
2512  dbus_free (buf);
2513  goto failed;
2514  }
2515 
2516  buf = new;
2517 
2518  errno = 0;
2519  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2520  {
2521  if (errno == 0)
2522  {
2523  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2524  username_c, buf_count, buf_count);
2525  }
2526  else
2527  {
2528  dbus_set_error (error,
2529  _dbus_error_from_errno (errno),
2530  "Failed to get groups for username \"%s\" primary GID "
2531  DBUS_GID_FORMAT ": %s\n",
2532  username_c, info->primary_gid,
2533  _dbus_strerror (errno));
2534  dbus_free (buf);
2535  goto failed;
2536  }
2537  }
2538  }
2539 
2540  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2541  if (info->group_ids == NULL)
2542  {
2544  dbus_free (buf);
2545  goto failed;
2546  }
2547 
2548  for (i = 0; i < buf_count; ++i)
2549  info->group_ids[i] = buf[i];
2550 
2551  info->n_group_ids = buf_count;
2552 
2553  dbus_free (buf);
2554  }
2555 #else /* HAVE_GETGROUPLIST */
2556  {
2557  /* We just get the one group ID */
2558  info->group_ids = dbus_new (dbus_gid_t, 1);
2559  if (info->group_ids == NULL)
2560  {
2562  goto failed;
2563  }
2564 
2565  info->n_group_ids = 1;
2566 
2567  (info->group_ids)[0] = info->primary_gid;
2568  }
2569 #endif /* HAVE_GETGROUPLIST */
2570 
2571  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2572 
2573  return TRUE;
2574 
2575  failed:
2576  _DBUS_ASSERT_ERROR_IS_SET (error);
2577  return FALSE;
2578 }
2579 
2590  const DBusString *username,
2591  DBusError *error)
2592 {
2593  return fill_user_info (info, DBUS_UID_UNSET,
2594  username, error);
2595 }
2596 
2607  dbus_uid_t uid,
2608  DBusError *error)
2609 {
2610  return fill_user_info (info, uid,
2611  NULL, error);
2612 }
2613 
2623 {
2624  /* The POSIX spec certainly doesn't promise this, but
2625  * we need these assertions to fail as soon as we're wrong about
2626  * it so we can do the porting fixups
2627  */
2628  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2629  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2630  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2631 
2632  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2633  return FALSE;
2634  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2635  return FALSE;
2636 
2637  return TRUE;
2638 }
2639 
2653 {
2654  return _dbus_string_append_uint (str,
2655  _dbus_geteuid ());
2656 }
2657 
2662 dbus_pid_t
2664 {
2665  return getpid ();
2666 }
2667 
2671 dbus_uid_t
2673 {
2674  return getuid ();
2675 }
2676 
2680 dbus_uid_t
2682 {
2683  return geteuid ();
2684 }
2685 
2692 unsigned long
2694 {
2695  return getpid ();
2696 }
2697 
2706 _dbus_parse_uid (const DBusString *uid_str,
2707  dbus_uid_t *uid)
2708 {
2709  int end;
2710  long val;
2711 
2712  if (_dbus_string_get_length (uid_str) == 0)
2713  {
2714  _dbus_verbose ("UID string was zero length\n");
2715  return FALSE;
2716  }
2717 
2718  val = -1;
2719  end = 0;
2720  if (!_dbus_string_parse_int (uid_str, 0, &val,
2721  &end))
2722  {
2723  _dbus_verbose ("could not parse string as a UID\n");
2724  return FALSE;
2725  }
2726 
2727  if (end != _dbus_string_get_length (uid_str))
2728  {
2729  _dbus_verbose ("string contained trailing stuff after UID\n");
2730  return FALSE;
2731  }
2732 
2733  *uid = val;
2734 
2735  return TRUE;
2736 }
2737 
2738 #if !DBUS_USE_SYNC
2739 /* To be thread-safe by default on platforms that don't necessarily have
2740  * atomic operations (notably Debian armel, which is armv4t), we must
2741  * use a mutex that can be initialized statically, like this.
2742  * GLib >= 2.32 uses a similar system.
2743  */
2744 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2745 #endif
2746 
2755 {
2756 #if DBUS_USE_SYNC
2757  return __sync_add_and_fetch(&atomic->value, 1)-1;
2758 #else
2759  dbus_int32_t res;
2760 
2761  pthread_mutex_lock (&atomic_mutex);
2762  res = atomic->value;
2763  atomic->value += 1;
2764  pthread_mutex_unlock (&atomic_mutex);
2765 
2766  return res;
2767 #endif
2768 }
2769 
2778 {
2779 #if DBUS_USE_SYNC
2780  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2781 #else
2782  dbus_int32_t res;
2783 
2784  pthread_mutex_lock (&atomic_mutex);
2785  res = atomic->value;
2786  atomic->value -= 1;
2787  pthread_mutex_unlock (&atomic_mutex);
2788 
2789  return res;
2790 #endif
2791 }
2792 
2802 {
2803 #if DBUS_USE_SYNC
2804  __sync_synchronize ();
2805  return atomic->value;
2806 #else
2807  dbus_int32_t res;
2808 
2809  pthread_mutex_lock (&atomic_mutex);
2810  res = atomic->value;
2811  pthread_mutex_unlock (&atomic_mutex);
2812 
2813  return res;
2814 #endif
2815 }
2816 
2825 int
2827  int n_fds,
2828  int timeout_milliseconds)
2829 {
2830 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2831  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2832  if (timeout_milliseconds < -1)
2833  {
2834  timeout_milliseconds = -1;
2835  }
2836 
2837  return poll (fds,
2838  n_fds,
2839  timeout_milliseconds);
2840 #else /* ! HAVE_POLL */
2841  /* Emulate poll() in terms of select() */
2842  fd_set read_set, write_set, err_set;
2843  int max_fd = 0;
2844  int i;
2845  struct timeval tv;
2846  int ready;
2847 
2848  FD_ZERO (&read_set);
2849  FD_ZERO (&write_set);
2850  FD_ZERO (&err_set);
2851 
2852  for (i = 0; i < n_fds; i++)
2853  {
2854  DBusPollFD *fdp = &fds[i];
2855 
2856  if (fdp->events & _DBUS_POLLIN)
2857  FD_SET (fdp->fd, &read_set);
2858 
2859  if (fdp->events & _DBUS_POLLOUT)
2860  FD_SET (fdp->fd, &write_set);
2861 
2862  FD_SET (fdp->fd, &err_set);
2863 
2864  max_fd = MAX (max_fd, fdp->fd);
2865  }
2866 
2867  tv.tv_sec = timeout_milliseconds / 1000;
2868  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2869 
2870  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2871  timeout_milliseconds < 0 ? NULL : &tv);
2872 
2873  if (ready > 0)
2874  {
2875  for (i = 0; i < n_fds; i++)
2876  {
2877  DBusPollFD *fdp = &fds[i];
2878 
2879  fdp->revents = 0;
2880 
2881  if (FD_ISSET (fdp->fd, &read_set))
2882  fdp->revents |= _DBUS_POLLIN;
2883 
2884  if (FD_ISSET (fdp->fd, &write_set))
2885  fdp->revents |= _DBUS_POLLOUT;
2886 
2887  if (FD_ISSET (fdp->fd, &err_set))
2888  fdp->revents |= _DBUS_POLLERR;
2889  }
2890  }
2891 
2892  return ready;
2893 #endif
2894 }
2895 
2903 void
2905  long *tv_usec)
2906 {
2907 #ifdef HAVE_MONOTONIC_CLOCK
2908  struct timespec ts;
2909  clock_gettime (CLOCK_MONOTONIC, &ts);
2910 
2911  if (tv_sec)
2912  *tv_sec = ts.tv_sec;
2913  if (tv_usec)
2914  *tv_usec = ts.tv_nsec / 1000;
2915 #else
2916  struct timeval t;
2917 
2918  gettimeofday (&t, NULL);
2919 
2920  if (tv_sec)
2921  *tv_sec = t.tv_sec;
2922  if (tv_usec)
2923  *tv_usec = t.tv_usec;
2924 #endif
2925 }
2926 
2934 void
2935 _dbus_get_real_time (long *tv_sec,
2936  long *tv_usec)
2937 {
2938  struct timeval t;
2939 
2940  gettimeofday (&t, NULL);
2941 
2942  if (tv_sec)
2943  *tv_sec = t.tv_sec;
2944  if (tv_usec)
2945  *tv_usec = t.tv_usec;
2946 }
2947 
2958  DBusError *error)
2959 {
2960  const char *filename_c;
2961 
2962  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2963 
2964  filename_c = _dbus_string_get_const_data (filename);
2965 
2966  if (mkdir (filename_c, 0700) < 0)
2967  {
2968  if (errno == EEXIST)
2969  return TRUE;
2970 
2972  "Failed to create directory %s: %s\n",
2973  filename_c, _dbus_strerror (errno));
2974  return FALSE;
2975  }
2976  else
2977  return TRUE;
2978 }
2979 
2990  DBusError *error)
2991 {
2992  const char *filename_c;
2993 
2994  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2995 
2996  filename_c = _dbus_string_get_const_data (filename);
2997 
2998  if (mkdir (filename_c, 0700) < 0)
2999  {
3001  "Failed to create directory %s: %s\n",
3002  filename_c, _dbus_strerror (errno));
3003  return FALSE;
3004  }
3005  else
3006  return TRUE;
3007 }
3008 
3021  const DBusString *next_component)
3022 {
3023  dbus_bool_t dir_ends_in_slash;
3024  dbus_bool_t file_starts_with_slash;
3025 
3026  if (_dbus_string_get_length (dir) == 0 ||
3027  _dbus_string_get_length (next_component) == 0)
3028  return TRUE;
3029 
3030  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3031  _dbus_string_get_length (dir) - 1);
3032 
3033  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3034 
3035  if (dir_ends_in_slash && file_starts_with_slash)
3036  {
3037  _dbus_string_shorten (dir, 1);
3038  }
3039  else if (!(dir_ends_in_slash || file_starts_with_slash))
3040  {
3041  if (!_dbus_string_append_byte (dir, '/'))
3042  return FALSE;
3043  }
3044 
3045  return _dbus_string_copy (next_component, 0, dir,
3046  _dbus_string_get_length (dir));
3047 }
3048 
3050 #define NANOSECONDS_PER_SECOND 1000000000
3051 
3052 #define MICROSECONDS_PER_SECOND 1000000
3053 
3054 #define MILLISECONDS_PER_SECOND 1000
3055 
3056 #define NANOSECONDS_PER_MILLISECOND 1000000
3057 
3058 #define MICROSECONDS_PER_MILLISECOND 1000
3059 
3064 void
3065 _dbus_sleep_milliseconds (int milliseconds)
3066 {
3067 #ifdef HAVE_NANOSLEEP
3068  struct timespec req;
3069  struct timespec rem;
3070 
3071  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3072  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3073  rem.tv_sec = 0;
3074  rem.tv_nsec = 0;
3075 
3076  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3077  req = rem;
3078 #elif defined (HAVE_USLEEP)
3079  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3080 #else /* ! HAVE_USLEEP */
3081  sleep (MAX (milliseconds / 1000, 1));
3082 #endif
3083 }
3084 
3096  int n_bytes,
3097  DBusError *error)
3098 {
3099  int old_len;
3100  int fd;
3101  int result;
3102 
3103  old_len = _dbus_string_get_length (str);
3104  fd = -1;
3105 
3106  /* note, urandom on linux will fall back to pseudorandom */
3107  fd = open ("/dev/urandom", O_RDONLY);
3108 
3109  if (fd < 0)
3110  {
3111  dbus_set_error (error, _dbus_error_from_errno (errno),
3112  "Could not open /dev/urandom: %s",
3113  _dbus_strerror (errno));
3114  return FALSE;
3115  }
3116 
3117  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3118 
3119  result = _dbus_read (fd, str, n_bytes);
3120 
3121  if (result != n_bytes)
3122  {
3123  if (result < 0)
3124  dbus_set_error (error, _dbus_error_from_errno (errno),
3125  "Could not read /dev/urandom: %s",
3126  _dbus_strerror (errno));
3127  else
3129  "Short read from /dev/urandom");
3130 
3131  _dbus_close (fd, NULL);
3132  _dbus_string_set_length (str, old_len);
3133  return FALSE;
3134  }
3135 
3136  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3137  n_bytes);
3138 
3139  _dbus_close (fd, NULL);
3140 
3141  return TRUE;
3142 }
3143 
3149 void
3150 _dbus_exit (int code)
3151 {
3152  _exit (code);
3153 }
3154 
3163 const char*
3164 _dbus_strerror (int error_number)
3165 {
3166  const char *msg;
3167 
3168  msg = strerror (error_number);
3169  if (msg == NULL)
3170  msg = "unknown";
3171 
3172  return msg;
3173 }
3174 
3178 void
3180 {
3181  signal (SIGPIPE, SIG_IGN);
3182 }
3183 
3191 void
3193 {
3194  int val;
3195 
3196  val = fcntl (fd, F_GETFD, 0);
3197 
3198  if (val < 0)
3199  return;
3200 
3201  val |= FD_CLOEXEC;
3202 
3203  fcntl (fd, F_SETFD, val);
3204 }
3205 
3214 _dbus_close (int fd,
3215  DBusError *error)
3216 {
3217  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3218 
3219  again:
3220  if (close (fd) < 0)
3221  {
3222  if (errno == EINTR)
3223  goto again;
3224 
3225  dbus_set_error (error, _dbus_error_from_errno (errno),
3226  "Could not close fd %d", fd);
3227  return FALSE;
3228  }
3229 
3230  return TRUE;
3231 }
3232 
3241 int
3242 _dbus_dup(int fd,
3243  DBusError *error)
3244 {
3245  int new_fd;
3246 
3247 #ifdef F_DUPFD_CLOEXEC
3248  dbus_bool_t cloexec_done;
3249 
3250  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3251  cloexec_done = new_fd >= 0;
3252 
3253  if (new_fd < 0 && errno == EINVAL)
3254 #endif
3255  {
3256  new_fd = fcntl(fd, F_DUPFD, 3);
3257  }
3258 
3259  if (new_fd < 0) {
3260 
3261  dbus_set_error (error, _dbus_error_from_errno (errno),
3262  "Could not duplicate fd %d", fd);
3263  return -1;
3264  }
3265 
3266 #ifdef F_DUPFD_CLOEXEC
3267  if (!cloexec_done)
3268 #endif
3269  {
3271  }
3272 
3273  return new_fd;
3274 }
3275 
3285  DBusError *error)
3286 {
3287  return _dbus_set_fd_nonblocking (fd.fd, error);
3288 }
3289 
3290 static dbus_bool_t
3291 _dbus_set_fd_nonblocking (int fd,
3292  DBusError *error)
3293 {
3294  int val;
3295 
3296  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3297 
3298  val = fcntl (fd, F_GETFL, 0);
3299  if (val < 0)
3300  {
3301  dbus_set_error (error, _dbus_error_from_errno (errno),
3302  "Failed to get flags from file descriptor %d: %s",
3303  fd, _dbus_strerror (errno));
3304  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3305  _dbus_strerror (errno));
3306  return FALSE;
3307  }
3308 
3309  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3310  {
3311  dbus_set_error (error, _dbus_error_from_errno (errno),
3312  "Failed to set nonblocking flag of file descriptor %d: %s",
3313  fd, _dbus_strerror (errno));
3314  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3315  fd, _dbus_strerror (errno));
3316 
3317  return FALSE;
3318  }
3319 
3320  return TRUE;
3321 }
3322 
3328 void
3330 {
3331 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3332  void *bt[500];
3333  int bt_size;
3334  int i;
3335  char **syms;
3336 
3337  bt_size = backtrace (bt, 500);
3338 
3339  syms = backtrace_symbols (bt, bt_size);
3340 
3341  i = 0;
3342  while (i < bt_size)
3343  {
3344  /* don't use dbus_warn since it can _dbus_abort() */
3345  fprintf (stderr, " %s\n", syms[i]);
3346  ++i;
3347  }
3348  fflush (stderr);
3349 
3350  free (syms);
3351 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3352  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3353 #else
3354  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3355 #endif
3356 }
3357 
3372  DBusSocket *fd2,
3373  dbus_bool_t blocking,
3374  DBusError *error)
3375 {
3376 #ifdef HAVE_SOCKETPAIR
3377  int fds[2];
3378  int retval;
3379 
3380 #ifdef SOCK_CLOEXEC
3381  dbus_bool_t cloexec_done;
3382 
3383  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3384  cloexec_done = retval >= 0;
3385 
3386  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3387 #endif
3388  {
3389  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3390  }
3391 
3392  if (retval < 0)
3393  {
3394  dbus_set_error (error, _dbus_error_from_errno (errno),
3395  "Could not create full-duplex pipe");
3396  return FALSE;
3397  }
3398 
3399  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3400 
3401 #ifdef SOCK_CLOEXEC
3402  if (!cloexec_done)
3403 #endif
3404  {
3405  _dbus_fd_set_close_on_exec (fds[0]);
3406  _dbus_fd_set_close_on_exec (fds[1]);
3407  }
3408 
3409  if (!blocking &&
3410  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3411  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3412  {
3413  dbus_set_error (error, _dbus_error_from_errno (errno),
3414  "Could not set full-duplex pipe nonblocking");
3415 
3416  _dbus_close (fds[0], NULL);
3417  _dbus_close (fds[1], NULL);
3418 
3419  return FALSE;
3420  }
3421 
3422  fd1->fd = fds[0];
3423  fd2->fd = fds[1];
3424 
3425  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3426  fd1->fd, fd2->fd);
3427 
3428  return TRUE;
3429 #else
3430  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3432  "_dbus_socketpair() not implemented on this OS");
3433  return FALSE;
3434 #endif
3435 }
3436 
3445 int
3447  va_list args)
3448 {
3449  char static_buf[1024];
3450  int bufsize = sizeof (static_buf);
3451  int len;
3452  va_list args_copy;
3453 
3454  DBUS_VA_COPY (args_copy, args);
3455  len = vsnprintf (static_buf, bufsize, format, args_copy);
3456  va_end (args_copy);
3457 
3458  /* If vsnprintf() returned non-negative, then either the string fits in
3459  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3460  * returns the number of characters that were needed, or this OS returns the
3461  * truncated length.
3462  *
3463  * We ignore the possibility that snprintf might just ignore the length and
3464  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3465  * If your libc is really that bad, come back when you have a better one. */
3466  if (len == bufsize)
3467  {
3468  /* This could be the truncated length (Tru64 and IRIX have this bug),
3469  * or the real length could be coincidentally the same. Which is it?
3470  * If vsnprintf returns the truncated length, we'll go to the slow
3471  * path. */
3472  DBUS_VA_COPY (args_copy, args);
3473 
3474  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3475  len = -1;
3476 
3477  va_end (args_copy);
3478  }
3479 
3480  /* If vsnprintf() returned negative, we have to do more work.
3481  * HP-UX returns negative. */
3482  while (len < 0)
3483  {
3484  char *buf;
3485 
3486  bufsize *= 2;
3487 
3488  buf = dbus_malloc (bufsize);
3489 
3490  if (buf == NULL)
3491  return -1;
3492 
3493  DBUS_VA_COPY (args_copy, args);
3494  len = vsnprintf (buf, bufsize, format, args_copy);
3495  va_end (args_copy);
3496 
3497  dbus_free (buf);
3498 
3499  /* If the reported length is exactly the buffer size, round up to the
3500  * next size, in case vsnprintf has been returning the truncated
3501  * length */
3502  if (len == bufsize)
3503  len = -1;
3504  }
3505 
3506  return len;
3507 }
3508 
3515 const char*
3517 {
3518  /* Protected by _DBUS_LOCK_sysdeps */
3519  static const char* tmpdir = NULL;
3520 
3521  if (!_DBUS_LOCK (sysdeps))
3522  return NULL;
3523 
3524  if (tmpdir == NULL)
3525  {
3526  /* TMPDIR is what glibc uses, then
3527  * glibc falls back to the P_tmpdir macro which
3528  * just expands to "/tmp"
3529  */
3530  if (tmpdir == NULL)
3531  tmpdir = getenv("TMPDIR");
3532 
3533  /* These two env variables are probably
3534  * broken, but maybe some OS uses them?
3535  */
3536  if (tmpdir == NULL)
3537  tmpdir = getenv("TMP");
3538  if (tmpdir == NULL)
3539  tmpdir = getenv("TEMP");
3540 
3541  /* And this is the sane fallback. */
3542  if (tmpdir == NULL)
3543  tmpdir = "/tmp";
3544  }
3545 
3546  _DBUS_UNLOCK (sysdeps);
3547 
3548  _dbus_assert(tmpdir != NULL);
3549 
3550  return tmpdir;
3551 }
3552 
3553 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3554 
3573 static dbus_bool_t
3574 _read_subprocess_line_argv (const char *progpath,
3575  dbus_bool_t path_fallback,
3576  const char * const *argv,
3577  DBusString *result,
3578  DBusError *error)
3579 {
3580  int result_pipe[2] = { -1, -1 };
3581  int errors_pipe[2] = { -1, -1 };
3582  pid_t pid;
3583  int ret;
3584  int status;
3585  int orig_len;
3586 
3587  dbus_bool_t retval;
3588  sigset_t new_set, old_set;
3589 
3590  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3591  retval = FALSE;
3592 
3593  /* We need to block any existing handlers for SIGCHLD temporarily; they
3594  * will cause waitpid() below to fail.
3595  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3596  */
3597  sigemptyset (&new_set);
3598  sigaddset (&new_set, SIGCHLD);
3599  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3600 
3601  orig_len = _dbus_string_get_length (result);
3602 
3603 #define READ_END 0
3604 #define WRITE_END 1
3605  if (pipe (result_pipe) < 0)
3606  {
3607  dbus_set_error (error, _dbus_error_from_errno (errno),
3608  "Failed to create a pipe to call %s: %s",
3609  progpath, _dbus_strerror (errno));
3610  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3611  progpath, _dbus_strerror (errno));
3612  goto out;
3613  }
3614  if (pipe (errors_pipe) < 0)
3615  {
3616  dbus_set_error (error, _dbus_error_from_errno (errno),
3617  "Failed to create a pipe to call %s: %s",
3618  progpath, _dbus_strerror (errno));
3619  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3620  progpath, _dbus_strerror (errno));
3621  goto out;
3622  }
3623 
3624  pid = fork ();
3625  if (pid < 0)
3626  {
3627  dbus_set_error (error, _dbus_error_from_errno (errno),
3628  "Failed to fork() to call %s: %s",
3629  progpath, _dbus_strerror (errno));
3630  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3631  progpath, _dbus_strerror (errno));
3632  goto out;
3633  }
3634 
3635  if (pid == 0)
3636  {
3637  /* child process */
3638  const char *error_str;
3639 
3640  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3641  {
3642  int saved_errno = errno;
3643 
3644  /* Try to write details into the pipe, but don't bother
3645  * trying too hard (no retry loop). */
3646 
3647  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3648  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3649  {
3650  /* ignore, not much we can do */
3651  }
3652 
3653  error_str = _dbus_strerror (saved_errno);
3654 
3655  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3656  {
3657  /* ignore, not much we can do */
3658  }
3659 
3660  _exit (1);
3661  }
3662 
3663  /* set-up stdXXX */
3664  close (result_pipe[READ_END]);
3665  close (errors_pipe[READ_END]);
3666 
3667  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3668  _exit (1);
3669  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3670  _exit (1);
3671 
3672  _dbus_close_all ();
3673 
3674  sigprocmask (SIG_SETMASK, &old_set, NULL);
3675 
3676  /* If it looks fully-qualified, try execv first */
3677  if (progpath[0] == '/')
3678  {
3679  execv (progpath, (char * const *) argv);
3680  /* Ok, that failed. Now if path_fallback is given, let's
3681  * try unqualified. This is mostly a hack to work
3682  * around systems which ship dbus-launch in /usr/bin
3683  * but everything else in /bin (because dbus-launch
3684  * depends on X11).
3685  */
3686  if (path_fallback)
3687  /* We must have a slash, because we checked above */
3688  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3689  }
3690  else
3691  execvp (progpath, (char * const *) argv);
3692 
3693  /* still nothing, we failed */
3694  _exit (1);
3695  }
3696 
3697  /* parent process */
3698  close (result_pipe[WRITE_END]);
3699  close (errors_pipe[WRITE_END]);
3700  result_pipe[WRITE_END] = -1;
3701  errors_pipe[WRITE_END] = -1;
3702 
3703  ret = 0;
3704  do
3705  {
3706  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3707  }
3708  while (ret > 0);
3709 
3710  /* reap the child process to avoid it lingering as zombie */
3711  do
3712  {
3713  ret = waitpid (pid, &status, 0);
3714  }
3715  while (ret == -1 && errno == EINTR);
3716 
3717  /* We succeeded if the process exited with status 0 and
3718  anything was read */
3719  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3720  {
3721  /* The process ended with error */
3722  DBusString error_message;
3723  if (!_dbus_string_init (&error_message))
3724  {
3725  _DBUS_SET_OOM (error);
3726  goto out;
3727  }
3728 
3729  ret = 0;
3730  do
3731  {
3732  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3733  }
3734  while (ret > 0);
3735 
3736  _dbus_string_set_length (result, orig_len);
3737  if (_dbus_string_get_length (&error_message) > 0)
3739  "%s terminated abnormally with the following error: %s",
3740  progpath, _dbus_string_get_data (&error_message));
3741  else
3743  "%s terminated abnormally without any error message",
3744  progpath);
3745  goto out;
3746  }
3747 
3748  retval = TRUE;
3749 
3750  out:
3751  sigprocmask (SIG_SETMASK, &old_set, NULL);
3752 
3753  if (retval)
3754  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3755  else
3756  _DBUS_ASSERT_ERROR_IS_SET (error);
3757 
3758  if (result_pipe[0] != -1)
3759  close (result_pipe[0]);
3760  if (result_pipe[1] != -1)
3761  close (result_pipe[1]);
3762  if (errors_pipe[0] != -1)
3763  close (errors_pipe[0]);
3764  if (errors_pipe[1] != -1)
3765  close (errors_pipe[1]);
3766 
3767  return retval;
3768 }
3769 #endif
3770 
3784 _dbus_get_autolaunch_address (const char *scope,
3785  DBusString *address,
3786  DBusError *error)
3787 {
3788 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3789  static const char arg_dbus_launch[] = "dbus-launch";
3790  static const char arg_autolaunch[] = "--autolaunch";
3791  static const char arg_binary_syntax[] = "--binary-syntax";
3792  static const char arg_close_stderr[] = "--close-stderr";
3793 
3794  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3795  * but that's done elsewhere, and if it worked, this function wouldn't
3796  * be called.) */
3797  const char *display;
3798  const char *progpath;
3799  const char *argv[6];
3800  int i;
3801  DBusString uuid;
3802  dbus_bool_t retval;
3803 
3804  if (_dbus_check_setuid ())
3805  {
3807  "Unable to autolaunch when setuid");
3808  return FALSE;
3809  }
3810 
3811  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3812  retval = FALSE;
3813 
3814  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3815  * dbus-launch-x11 is just going to fail. Rather than trying to
3816  * run it, we might as well bail out early with a nice error.
3817  *
3818  * This is not strictly true in a world where the user bus exists,
3819  * because dbus-launch --autolaunch knows how to connect to that -
3820  * but if we were going to connect to the user bus, we'd have done
3821  * so before trying autolaunch: in any case. */
3822  display = _dbus_getenv ("DISPLAY");
3823 
3824  if (display == NULL || display[0] == '\0')
3825  {
3827  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3828  return FALSE;
3829  }
3830 
3831  if (!_dbus_string_init (&uuid))
3832  {
3833  _DBUS_SET_OOM (error);
3834  return FALSE;
3835  }
3836 
3837  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3838  {
3839  goto out;
3840  }
3841 
3842 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3843  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3844 
3845  if (progpath == NULL)
3846 #endif
3847  progpath = DBUS_BINDIR "/dbus-launch";
3848  /*
3849  * argv[0] is always dbus-launch, that's the name what we'll
3850  * get from /proc, or ps(1), regardless what the progpath is,
3851  * see fd.o#69716
3852  */
3853  i = 0;
3854  argv[i] = arg_dbus_launch;
3855  ++i;
3856  argv[i] = arg_autolaunch;
3857  ++i;
3858  argv[i] = _dbus_string_get_data (&uuid);
3859  ++i;
3860  argv[i] = arg_binary_syntax;
3861  ++i;
3862  argv[i] = arg_close_stderr;
3863  ++i;
3864  argv[i] = NULL;
3865  ++i;
3866 
3867  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3868 
3869  retval = _read_subprocess_line_argv (progpath,
3870  TRUE,
3871  argv, address, error);
3872 
3873  out:
3874  _dbus_string_free (&uuid);
3875  return retval;
3876 #else
3878  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3879  "set your DBUS_SESSION_BUS_ADDRESS instead");
3880  return FALSE;
3881 #endif
3882 }
3883 
3904  dbus_bool_t create_if_not_found,
3905  DBusError *error)
3906 {
3907  DBusError our_error = DBUS_ERROR_INIT;
3908  DBusError etc_error = DBUS_ERROR_INIT;
3909  DBusString filename;
3910  dbus_bool_t b;
3911 
3912  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3913 
3914  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
3915  if (b)
3916  return TRUE;
3917 
3918  /* Fallback to the system machine ID */
3919  _dbus_string_init_const (&filename, "/etc/machine-id");
3920  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
3921 
3922  if (b)
3923  {
3924  if (create_if_not_found)
3925  {
3926  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3927  * complain if that isn't possible for whatever reason */
3928  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3929  _dbus_write_uuid_file (&filename, machine_id, NULL);
3930  }
3931 
3932  dbus_error_free (&our_error);
3933  return TRUE;
3934  }
3935 
3936  if (!create_if_not_found)
3937  {
3938  dbus_set_error (error, etc_error.name,
3939  "D-Bus library appears to be incorrectly set up: "
3940  "see the manual page for dbus-uuidgen to correct "
3941  "this issue. (%s; %s)",
3942  our_error.message, etc_error.message);
3943  dbus_error_free (&our_error);
3944  dbus_error_free (&etc_error);
3945  return FALSE;
3946  }
3947 
3948  dbus_error_free (&our_error);
3949  dbus_error_free (&etc_error);
3950 
3951  /* if none found, try to make a new one */
3952  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3953 
3954  if (!_dbus_generate_uuid (machine_id, error))
3955  return FALSE;
3956 
3957  return _dbus_write_uuid_file (&filename, machine_id, error);
3958 }
3959 
3969  const char *launchd_env_var,
3970  DBusError *error)
3971 {
3972 #ifdef DBUS_ENABLE_LAUNCHD
3973  char *argv[4];
3974  int i;
3975 
3976  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3977 
3978  if (_dbus_check_setuid ())
3979  {
3981  "Unable to find launchd socket when setuid");
3982  return FALSE;
3983  }
3984 
3985  i = 0;
3986  argv[i] = "launchctl";
3987  ++i;
3988  argv[i] = "getenv";
3989  ++i;
3990  argv[i] = (char*)launchd_env_var;
3991  ++i;
3992  argv[i] = NULL;
3993  ++i;
3994 
3995  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3996 
3997  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3998  {
3999  return FALSE;
4000  }
4001 
4002  /* no error, but no result either */
4003  if (_dbus_string_get_length(socket_path) == 0)
4004  {
4005  return FALSE;
4006  }
4007 
4008  /* strip the carriage-return */
4009  _dbus_string_shorten(socket_path, 1);
4010  return TRUE;
4011 #else /* DBUS_ENABLE_LAUNCHD */
4013  "can't lookup socket from launchd; launchd support not compiled in");
4014  return FALSE;
4015 #endif
4016 }
4017 
4018 #ifdef DBUS_ENABLE_LAUNCHD
4019 static dbus_bool_t
4020 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4021 {
4022  dbus_bool_t valid_socket;
4023  DBusString socket_path;
4024 
4025  if (_dbus_check_setuid ())
4026  {
4028  "Unable to find launchd socket when setuid");
4029  return FALSE;
4030  }
4031 
4032  if (!_dbus_string_init (&socket_path))
4033  {
4034  _DBUS_SET_OOM (error);
4035  return FALSE;
4036  }
4037 
4038  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4039 
4040  if (dbus_error_is_set(error))
4041  {
4042  _dbus_string_free(&socket_path);
4043  return FALSE;
4044  }
4045 
4046  if (!valid_socket)
4047  {
4048  dbus_set_error(error, "no socket path",
4049  "launchd did not provide a socket path, "
4050  "verify that org.freedesktop.dbus-session.plist is loaded!");
4051  _dbus_string_free(&socket_path);
4052  return FALSE;
4053  }
4054  if (!_dbus_string_append (address, "unix:path="))
4055  {
4056  _DBUS_SET_OOM (error);
4057  _dbus_string_free(&socket_path);
4058  return FALSE;
4059  }
4060  if (!_dbus_string_copy (&socket_path, 0, address,
4061  _dbus_string_get_length (address)))
4062  {
4063  _DBUS_SET_OOM (error);
4064  _dbus_string_free(&socket_path);
4065  return FALSE;
4066  }
4067 
4068  _dbus_string_free(&socket_path);
4069  return TRUE;
4070 }
4071 #endif
4072 
4074 _dbus_lookup_user_bus (dbus_bool_t *supported,
4075  DBusString *address,
4076  DBusError *error)
4077 {
4078  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4079  dbus_bool_t ret = FALSE;
4080  struct stat stbuf;
4081  DBusString user_bus_path;
4082 
4083  if (runtime_dir == NULL)
4084  {
4085  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4086  *supported = FALSE;
4087  return TRUE; /* Cannot use it, but not an error */
4088  }
4089 
4090  if (!_dbus_string_init (&user_bus_path))
4091  {
4092  _DBUS_SET_OOM (error);
4093  return FALSE;
4094  }
4095 
4096  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4097  {
4098  _DBUS_SET_OOM (error);
4099  goto out;
4100  }
4101 
4102  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4103  {
4104  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4105  _dbus_strerror (errno));
4106  *supported = FALSE;
4107  ret = TRUE; /* Cannot use it, but not an error */
4108  goto out;
4109  }
4110 
4111  if (stbuf.st_uid != getuid ())
4112  {
4113  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4114  (long) stbuf.st_uid, (long) getuid ());
4115  *supported = FALSE;
4116  ret = TRUE; /* Cannot use it, but not an error */
4117  goto out;
4118  }
4119 
4120  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4121  {
4122  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4123  (long) stbuf.st_mode);
4124  *supported = FALSE;
4125  ret = TRUE; /* Cannot use it, but not an error */
4126  goto out;
4127  }
4128 
4129  if (!_dbus_string_append (address, "unix:path=") ||
4130  !_dbus_address_append_escaped (address, &user_bus_path))
4131  {
4132  _DBUS_SET_OOM (error);
4133  goto out;
4134  }
4135 
4136  *supported = TRUE;
4137  ret = TRUE;
4138 
4139 out:
4140  _dbus_string_free (&user_bus_path);
4141  return ret;
4142 }
4143 
4165  DBusString *address,
4166  DBusError *error)
4167 {
4168 #ifdef DBUS_ENABLE_LAUNCHD
4169  *supported = TRUE;
4170  return _dbus_lookup_session_address_launchd (address, error);
4171 #else
4172  *supported = FALSE;
4173 
4174  if (!_dbus_lookup_user_bus (supported, address, error))
4175  return FALSE;
4176  else if (*supported)
4177  return TRUE;
4178 
4179  /* On non-Mac Unix platforms, if the session address isn't already
4180  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4181  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4182  * autolaunch: global default; see init_session_address in
4183  * dbus/dbus-bus.c. */
4184  return TRUE;
4185 #endif
4186 }
4187 
4195 void
4197 {
4199 }
4200 
4216  DBusCredentials *credentials)
4217 {
4218  DBusString homedir;
4219  DBusString dotdir;
4220  dbus_uid_t uid;
4221 
4222  _dbus_assert (credentials != NULL);
4224 
4225  if (!_dbus_string_init (&homedir))
4226  return FALSE;
4227 
4228  uid = _dbus_credentials_get_unix_uid (credentials);
4229  _dbus_assert (uid != DBUS_UID_UNSET);
4230 
4231  if (!_dbus_homedir_from_uid (uid, &homedir))
4232  goto failed;
4233 
4234 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4235  {
4236  const char *override;
4237 
4238  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4239  if (override != NULL && *override != '\0')
4240  {
4241  _dbus_string_set_length (&homedir, 0);
4242  if (!_dbus_string_append (&homedir, override))
4243  goto failed;
4244 
4245  _dbus_verbose ("Using fake homedir for testing: %s\n",
4246  _dbus_string_get_const_data (&homedir));
4247  }
4248  else
4249  {
4250  /* Not strictly thread-safe, but if we fail at thread-safety here,
4251  * the worst that will happen is some extra warnings. */
4252  static dbus_bool_t already_warned = FALSE;
4253  if (!already_warned)
4254  {
4255  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4256  _dbus_string_get_const_data (&homedir));
4257  already_warned = TRUE;
4258  }
4259  }
4260  }
4261 #endif
4262 
4263  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4264  if (!_dbus_concat_dir_and_file (&homedir,
4265  &dotdir))
4266  goto failed;
4267 
4268  if (!_dbus_string_copy (&homedir, 0,
4269  directory, _dbus_string_get_length (directory))) {
4270  goto failed;
4271  }
4272 
4273  _dbus_string_free (&homedir);
4274  return TRUE;
4275 
4276  failed:
4277  _dbus_string_free (&homedir);
4278  return FALSE;
4279 }
4280 
4281 //PENDING(kdab) docs
4283 _dbus_daemon_publish_session_bus_address (const char* addr,
4284  const char *scope)
4285 {
4286  return TRUE;
4287 }
4288 
4289 //PENDING(kdab) docs
4290 void
4291 _dbus_daemon_unpublish_session_bus_address (void)
4292 {
4293 
4294 }
4295 
4304 {
4305  return e == EAGAIN || e == EWOULDBLOCK;
4306 }
4307 
4317  DBusError *error)
4318 {
4319  const char *filename_c;
4320 
4321  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4322 
4323  filename_c = _dbus_string_get_const_data (filename);
4324 
4325  if (rmdir (filename_c) != 0)
4326  {
4328  "Failed to remove directory %s: %s\n",
4329  filename_c, _dbus_strerror (errno));
4330  return FALSE;
4331  }
4332 
4333  return TRUE;
4334 }
4335 
4345 {
4346 #ifdef SCM_RIGHTS
4347  union {
4348  struct sockaddr sa;
4349  struct sockaddr_storage storage;
4350  struct sockaddr_un un;
4351  } sa_buf;
4352 
4353  socklen_t sa_len = sizeof(sa_buf);
4354 
4355  _DBUS_ZERO(sa_buf);
4356 
4357  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4358  return FALSE;
4359 
4360  return sa_buf.sa.sa_family == AF_UNIX;
4361 
4362 #else
4363  return FALSE;
4364 
4365 #endif
4366 }
4367 
4372 void
4374 {
4375  int maxfds, i;
4376 
4377 #ifdef __linux__
4378  DIR *d;
4379 
4380  /* On Linux we can optimize this a bit if /proc is available. If it
4381  isn't available, fall back to the brute force way. */
4382 
4383  d = opendir ("/proc/self/fd");
4384  if (d)
4385  {
4386  for (;;)
4387  {
4388  struct dirent *de;
4389  int fd;
4390  long l;
4391  char *e = NULL;
4392 
4393  de = readdir (d);
4394  if (!de)
4395  break;
4396 
4397  if (de->d_name[0] == '.')
4398  continue;
4399 
4400  errno = 0;
4401  l = strtol (de->d_name, &e, 10);
4402  if (errno != 0 || e == NULL || *e != '\0')
4403  continue;
4404 
4405  fd = (int) l;
4406  if (fd < 3)
4407  continue;
4408 
4409  if (fd == dirfd (d))
4410  continue;
4411 
4412  close (fd);
4413  }
4414 
4415  closedir (d);
4416  return;
4417  }
4418 #endif
4419 
4420  maxfds = sysconf (_SC_OPEN_MAX);
4421 
4422  /* Pick something reasonable if for some reason sysconf says
4423  * unlimited.
4424  */
4425  if (maxfds < 0)
4426  maxfds = 1024;
4427 
4428  /* close all inherited fds */
4429  for (i = 3; i < maxfds; i++)
4430  close (i);
4431 }
4432 
4444 {
4445  /* TODO: get __libc_enable_secure exported from glibc.
4446  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4447  */
4448 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4449  {
4450  /* See glibc/include/unistd.h */
4451  extern int __libc_enable_secure;
4452  return __libc_enable_secure;
4453  }
4454 #elif defined(HAVE_ISSETUGID)
4455  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4456  return issetugid ();
4457 #else
4458  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4459  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4460 
4461  /* We call into this function from _dbus_threads_init_platform_specific()
4462  * to make sure these are initialized before we start threading. */
4463  static dbus_bool_t check_setuid_initialised;
4464  static dbus_bool_t is_setuid;
4465 
4466  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4467  {
4468 #ifdef HAVE_GETRESUID
4469  if (getresuid (&ruid, &euid, &suid) != 0 ||
4470  getresgid (&rgid, &egid, &sgid) != 0)
4471 #endif /* HAVE_GETRESUID */
4472  {
4473  suid = ruid = getuid ();
4474  sgid = rgid = getgid ();
4475  euid = geteuid ();
4476  egid = getegid ();
4477  }
4478 
4479  check_setuid_initialised = TRUE;
4480  is_setuid = (ruid != euid || ruid != suid ||
4481  rgid != egid || rgid != sgid);
4482 
4483  }
4484  return is_setuid;
4485 #endif
4486 }
4487 
4497  DBusString *address,
4498  DBusError *error)
4499 {
4500  union {
4501  struct sockaddr sa;
4502  struct sockaddr_storage storage;
4503  struct sockaddr_un un;
4504  struct sockaddr_in ipv4;
4505  struct sockaddr_in6 ipv6;
4506  } socket;
4507  char hostip[INET6_ADDRSTRLEN];
4508  socklen_t size = sizeof (socket);
4509  DBusString path_str;
4510 
4511  if (getsockname (fd.fd, &socket.sa, &size))
4512  goto err;
4513 
4514  switch (socket.sa.sa_family)
4515  {
4516  case AF_UNIX:
4517  if (socket.un.sun_path[0]=='\0')
4518  {
4519  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4520  if (_dbus_string_append (address, "unix:abstract=") &&
4521  _dbus_address_append_escaped (address, &path_str))
4522  return TRUE;
4523  }
4524  else
4525  {
4526  _dbus_string_init_const (&path_str, socket.un.sun_path);
4527  if (_dbus_string_append (address, "unix:path=") &&
4528  _dbus_address_append_escaped (address, &path_str))
4529  return TRUE;
4530  }
4531  break;
4532  case AF_INET:
4533  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4534  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4535  hostip, ntohs (socket.ipv4.sin_port)))
4536  return TRUE;
4537  break;
4538 #ifdef AF_INET6
4539  case AF_INET6:
4540  _dbus_string_init_const (&path_str, hostip);
4541  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4542  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4543  ntohs (socket.ipv6.sin6_port)) &&
4544  _dbus_address_append_escaped (address, &path_str))
4545  return TRUE;
4546  break;
4547 #endif
4548  default:
4549  dbus_set_error (error,
4550  _dbus_error_from_errno (EINVAL),
4551  "Failed to read address from socket: Unknown socket type.");
4552  return FALSE;
4553  }
4554  err:
4555  dbus_set_error (error,
4556  _dbus_error_from_errno (errno),
4557  "Failed to open socket: %s",
4558  _dbus_strerror (errno));
4559  return FALSE;
4560 }
4561 
4562 int
4563 _dbus_save_socket_errno (void)
4564 {
4565  return errno;
4566 }
4567 
4568 void
4569 _dbus_restore_socket_errno (int saved_errno)
4570 {
4571  errno = saved_errno;
4572 }
4573 
4574 static const char *syslog_tag = "dbus";
4575 #ifdef HAVE_SYSLOG_H
4576 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4577 #endif
4578 
4593 void
4594 _dbus_init_system_log (const char *tag,
4595  DBusLogFlags flags)
4596 {
4597  /* We never want to turn off logging completely */
4598  _dbus_assert (
4599  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4600 
4601  syslog_tag = tag;
4602 
4603 #ifdef HAVE_SYSLOG_H
4604  log_flags = flags;
4605 
4606  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4607  openlog (tag, LOG_PID, LOG_DAEMON);
4608 #endif
4609 }
4610 
4618 void
4619 _dbus_logv (DBusSystemLogSeverity severity,
4620  const char *msg,
4621  va_list args)
4622 {
4623  va_list tmp;
4624 #ifdef HAVE_SYSLOG_H
4625  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4626  {
4627  int flags;
4628  switch (severity)
4629  {
4630  case DBUS_SYSTEM_LOG_INFO:
4631  flags = LOG_DAEMON | LOG_INFO;
4632  break;
4633  case DBUS_SYSTEM_LOG_WARNING:
4634  flags = LOG_DAEMON | LOG_WARNING;
4635  break;
4636  case DBUS_SYSTEM_LOG_SECURITY:
4637  flags = LOG_AUTH | LOG_NOTICE;
4638  break;
4639  case DBUS_SYSTEM_LOG_ERROR:
4640  flags = LOG_DAEMON|LOG_CRIT;
4641  break;
4642  default:
4643  _dbus_assert_not_reached ("invalid log severity");
4644  }
4645 
4646  DBUS_VA_COPY (tmp, args);
4647  vsyslog (flags, msg, tmp);
4648  va_end (tmp);
4649  }
4650 
4651  /* If we don't have syslog.h, we always behave as though stderr was in
4652  * the flags */
4653  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4654 #endif
4655  {
4656  DBUS_VA_COPY (tmp, args);
4657  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4658  vfprintf (stderr, msg, tmp);
4659  fputc ('\n', stderr);
4660  va_end (tmp);
4661  }
4662 }
4663 
4664 /* 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
const char * message
public error message field
Definition: dbus-errors.h:51
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.
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.
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.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
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.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
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().
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
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c: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
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
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.
const char * name
public error name field
Definition: dbus-errors.h:50
#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.
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_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
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
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...
int dbus_int32_t
A 32-bit signed integer on all platforms.
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.
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