D-Bus  1.10.24
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_WRITEV
66 #include <sys/uio.h>
67 #endif
68 #ifdef HAVE_POLL
69 #include <sys/poll.h>
70 #endif
71 #ifdef HAVE_BACKTRACE
72 #include <execinfo.h>
73 #endif
74 #ifdef HAVE_GETPEERUCRED
75 #include <ucred.h>
76 #endif
77 #ifdef HAVE_ALLOCA_H
78 #include <alloca.h>
79 #endif
80 
81 #ifdef HAVE_ADT
82 #include <bsm/adt.h>
83 #endif
84 
85 #ifdef HAVE_SYSTEMD
86 #include <systemd/sd-daemon.h>
87 #endif
88 
89 #if !DBUS_USE_SYNC
90 #include <pthread.h>
91 #endif
92 
93 #ifndef O_BINARY
94 #define O_BINARY 0
95 #endif
96 
97 #ifndef AI_ADDRCONFIG
98 #define AI_ADDRCONFIG 0
99 #endif
100 
101 #ifndef HAVE_SOCKLEN_T
102 #define socklen_t int
103 #endif
104 
105 #if defined (__sun) || defined (__sun__)
106 /*
107  * CMS_SPACE etc. definitions for Solaris < 10, based on
108  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
109  * via
110  * http://wiki.opencsw.org/porting-faq#toc10
111  *
112  * These are only redefined for Solaris, for now: if your OS needs these too,
113  * please file a bug. (Or preferably, improve your OS so they're not needed.)
114  */
115 
116 # ifndef CMSG_ALIGN
117 # ifdef __sun__
118 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
119 # else
120  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
121 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
122  ~(sizeof (long) - 1))
123 # endif
124 # endif
125 
126 # ifndef CMSG_SPACE
127 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
128  CMSG_ALIGN (len))
129 # endif
130 
131 # ifndef CMSG_LEN
132 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
133 # endif
134 
135 #endif /* Solaris */
136 
152 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
153  const char **error_str_p)
154 {
155  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
156  DBUS_FORCE_STDOUT_NULL,
157  DBUS_FORCE_STDERR_NULL };
158  /* Should always get replaced with the real error before use */
159  const char *error_str = "Failed mysteriously";
160  int devnull = -1;
161  int saved_errno;
162  /* This function relies on the standard fds having their POSIX values. */
163  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
164  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
165  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
166  int i;
167 
168  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
169  {
170  /* Because we rely on being single-threaded, and we want the
171  * standard fds to not be close-on-exec, we don't set it
172  * close-on-exec. */
173  if (devnull < i)
174  devnull = open ("/dev/null", O_RDWR);
175 
176  if (devnull < 0)
177  {
178  error_str = "Failed to open /dev/null";
179  goto out;
180  }
181 
182  /* We already opened all fds < i, so the only way this assertion
183  * could fail is if another thread closed one, and we document
184  * this function as not safe for multi-threading. */
185  _dbus_assert (devnull >= i);
186 
187  if (devnull != i && (flags & relevant_flag[i]) != 0)
188  {
189  if (dup2 (devnull, i) < 0)
190  {
191  error_str = "Failed to dup2 /dev/null onto a standard fd";
192  goto out;
193  }
194  }
195  }
196 
197  error_str = NULL;
198 
199 out:
200  saved_errno = errno;
201 
202  if (devnull > STDERR_FILENO)
203  close (devnull);
204 
205  if (error_str_p != NULL)
206  *error_str_p = error_str;
207 
208  errno = saved_errno;
209  return (error_str == NULL);
210 }
211 
212 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
213  DBusError *error);
214 
215 static dbus_bool_t
216 _dbus_open_socket (int *fd_p,
217  int domain,
218  int type,
219  int protocol,
220  DBusError *error)
221 {
222 #ifdef SOCK_CLOEXEC
223  dbus_bool_t cloexec_done;
224 
225  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
226  cloexec_done = *fd_p >= 0;
227 
228  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
229  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
230 #endif
231  {
232  *fd_p = socket (domain, type, protocol);
233  }
234 
235  if (*fd_p >= 0)
236  {
237 #ifdef SOCK_CLOEXEC
238  if (!cloexec_done)
239 #endif
240  {
242  }
243 
244  _dbus_verbose ("socket fd %d opened\n", *fd_p);
245  return TRUE;
246  }
247  else
248  {
249  dbus_set_error(error,
250  _dbus_error_from_errno (errno),
251  "Failed to open socket: %s",
252  _dbus_strerror (errno));
253  return FALSE;
254  }
255 }
256 
267 static dbus_bool_t
268 _dbus_open_unix_socket (int *fd,
269  DBusError *error)
270 {
271  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
272 }
273 
284  DBusError *error)
285 {
286  return _dbus_close (fd.fd, error);
287 }
288 
298 int
300  DBusString *buffer,
301  int count)
302 {
303  return _dbus_read (fd.fd, buffer, count);
304 }
305 
316 int
318  const DBusString *buffer,
319  int start,
320  int len)
321 {
322 #if HAVE_DECL_MSG_NOSIGNAL
323  const char *data;
324  int bytes_written;
325 
326  data = _dbus_string_get_const_data_len (buffer, start, len);
327 
328  again:
329 
330  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
331 
332  if (bytes_written < 0 && errno == EINTR)
333  goto again;
334 
335  return bytes_written;
336 
337 #else
338  return _dbus_write (fd.fd, buffer, start, len);
339 #endif
340 }
341 
354 int
356  DBusString *buffer,
357  int count,
358  int *fds,
359  int *n_fds) {
360 #ifndef HAVE_UNIX_FD_PASSING
361  int r;
362 
363  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
364  return r;
365 
366  *n_fds = 0;
367  return r;
368 
369 #else
370  int bytes_read;
371  int start;
372  struct msghdr m;
373  struct iovec iov;
374 
375  _dbus_assert (count >= 0);
376  _dbus_assert (*n_fds >= 0);
377 
378  start = _dbus_string_get_length (buffer);
379 
380  if (!_dbus_string_lengthen (buffer, count))
381  {
382  errno = ENOMEM;
383  return -1;
384  }
385 
386  _DBUS_ZERO(iov);
387  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
388  iov.iov_len = count;
389 
390  _DBUS_ZERO(m);
391  m.msg_iov = &iov;
392  m.msg_iovlen = 1;
393 
394  /* Hmm, we have no clue how long the control data will actually be
395  that is queued for us. The least we can do is assume that the
396  caller knows. Hence let's make space for the number of fds that
397  we shall read at max plus the cmsg header. */
398  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
399 
400  /* It's probably safe to assume that systems with SCM_RIGHTS also
401  know alloca() */
402  m.msg_control = alloca(m.msg_controllen);
403  memset(m.msg_control, 0, m.msg_controllen);
404 
405  /* Do not include the padding at the end when we tell the kernel
406  * how much we're willing to receive. This avoids getting
407  * the padding filled with additional fds that we weren't expecting,
408  * if a (potentially malicious) sender included them. (fd.o #83622) */
409  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
410 
411  again:
412 
413  bytes_read = recvmsg (fd.fd, &m, 0
414 #ifdef MSG_CMSG_CLOEXEC
415  |MSG_CMSG_CLOEXEC
416 #endif
417  );
418 
419  if (bytes_read < 0)
420  {
421  if (errno == EINTR)
422  goto again;
423  else
424  {
425  /* put length back (note that this doesn't actually realloc anything) */
426  _dbus_string_set_length (buffer, start);
427  return -1;
428  }
429  }
430  else
431  {
432  struct cmsghdr *cm;
433  dbus_bool_t found = FALSE;
434 
435  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
436  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
437  {
438  size_t i;
439  int *payload = (int *) CMSG_DATA (cm);
440  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
441  size_t payload_len_fds = payload_len_bytes / sizeof (int);
442  size_t fds_to_use;
443 
444  /* Every non-negative int fits in a size_t without truncation,
445  * and we already know that *n_fds is non-negative, so
446  * casting (size_t) *n_fds is OK */
447  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
448 
449  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
450  {
451  /* The fds in the payload will fit in our buffer */
452  fds_to_use = payload_len_fds;
453  }
454  else
455  {
456  /* Too many fds in the payload. This shouldn't happen
457  * any more because we're setting m.msg_controllen to
458  * the exact number we can accept, but be safe and
459  * truncate. */
460  fds_to_use = (size_t) *n_fds;
461 
462  /* Close the excess fds to avoid DoS: if they stayed open,
463  * someone could send us an extra fd per message
464  * and we'd eventually run out. */
465  for (i = fds_to_use; i < payload_len_fds; i++)
466  {
467  close (payload[i]);
468  }
469  }
470 
471  memcpy (fds, payload, fds_to_use * sizeof (int));
472  found = TRUE;
473  /* This cannot overflow because we have chosen fds_to_use
474  * to be <= *n_fds */
475  *n_fds = (int) fds_to_use;
476 
477  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
478  worked, hence we need to go through this list and set
479  CLOEXEC everywhere in any case */
480  for (i = 0; i < fds_to_use; i++)
482 
483  break;
484  }
485 
486  if (!found)
487  *n_fds = 0;
488 
489  if (m.msg_flags & MSG_CTRUNC)
490  {
491  int i;
492 
493  /* Hmm, apparently the control data was truncated. The bad
494  thing is that we might have completely lost a couple of fds
495  without chance to recover them. Hence let's treat this as a
496  serious error. */
497 
498  /* We still need to close whatever fds we *did* receive,
499  * otherwise they'll never get closed. (CVE-2020-12049) */
500  for (i = 0; i < *n_fds; i++)
501  close (fds[i]);
502 
503  *n_fds = 0;
504  errno = ENOSPC;
505  _dbus_string_set_length (buffer, start);
506  return -1;
507  }
508 
509  /* put length back (doesn't actually realloc) */
510  _dbus_string_set_length (buffer, start + bytes_read);
511 
512 #if 0
513  if (bytes_read > 0)
514  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
515 #endif
516 
517  return bytes_read;
518  }
519 #endif
520 }
521 
522 int
523 _dbus_write_socket_with_unix_fds(DBusSocket fd,
524  const DBusString *buffer,
525  int start,
526  int len,
527  const int *fds,
528  int n_fds) {
529 
530 #ifndef HAVE_UNIX_FD_PASSING
531 
532  if (n_fds > 0) {
533  errno = ENOTSUP;
534  return -1;
535  }
536 
537  return _dbus_write_socket(fd, buffer, start, len);
538 #else
539  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
540 #endif
541 }
542 
543 int
544 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
545  const DBusString *buffer1,
546  int start1,
547  int len1,
548  const DBusString *buffer2,
549  int start2,
550  int len2,
551  const int *fds,
552  int n_fds) {
553 
554 #ifndef HAVE_UNIX_FD_PASSING
555 
556  if (n_fds > 0) {
557  errno = ENOTSUP;
558  return -1;
559  }
560 
561  return _dbus_write_socket_two(fd,
562  buffer1, start1, len1,
563  buffer2, start2, len2);
564 #else
565 
566  struct msghdr m;
567  struct cmsghdr *cm;
568  struct iovec iov[2];
569  int bytes_written;
570 
571  _dbus_assert (len1 >= 0);
572  _dbus_assert (len2 >= 0);
573  _dbus_assert (n_fds >= 0);
574 
575  _DBUS_ZERO(iov);
576  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
577  iov[0].iov_len = len1;
578 
579  if (buffer2)
580  {
581  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
582  iov[1].iov_len = len2;
583  }
584 
585  _DBUS_ZERO(m);
586  m.msg_iov = iov;
587  m.msg_iovlen = buffer2 ? 2 : 1;
588 
589  if (n_fds > 0)
590  {
591  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
592  m.msg_control = alloca(m.msg_controllen);
593  memset(m.msg_control, 0, m.msg_controllen);
594 
595  cm = CMSG_FIRSTHDR(&m);
596  cm->cmsg_level = SOL_SOCKET;
597  cm->cmsg_type = SCM_RIGHTS;
598  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
599  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
600  }
601 
602  again:
603 
604  bytes_written = sendmsg (fd.fd, &m, 0
605 #if HAVE_DECL_MSG_NOSIGNAL
606  |MSG_NOSIGNAL
607 #endif
608  );
609 
610  if (bytes_written < 0 && errno == EINTR)
611  goto again;
612 
613 #if 0
614  if (bytes_written > 0)
615  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
616 #endif
617 
618  return bytes_written;
619 #endif
620 }
621 
635 int
637  const DBusString *buffer1,
638  int start1,
639  int len1,
640  const DBusString *buffer2,
641  int start2,
642  int len2)
643 {
644 #if HAVE_DECL_MSG_NOSIGNAL
645  struct iovec vectors[2];
646  const char *data1;
647  const char *data2;
648  int bytes_written;
649  struct msghdr m;
650 
651  _dbus_assert (buffer1 != NULL);
652  _dbus_assert (start1 >= 0);
653  _dbus_assert (start2 >= 0);
654  _dbus_assert (len1 >= 0);
655  _dbus_assert (len2 >= 0);
656 
657  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
658 
659  if (buffer2 != NULL)
660  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
661  else
662  {
663  data2 = NULL;
664  start2 = 0;
665  len2 = 0;
666  }
667 
668  vectors[0].iov_base = (char*) data1;
669  vectors[0].iov_len = len1;
670  vectors[1].iov_base = (char*) data2;
671  vectors[1].iov_len = len2;
672 
673  _DBUS_ZERO(m);
674  m.msg_iov = vectors;
675  m.msg_iovlen = data2 ? 2 : 1;
676 
677  again:
678 
679  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
680 
681  if (bytes_written < 0 && errno == EINTR)
682  goto again;
683 
684  return bytes_written;
685 
686 #else
687  return _dbus_write_two (fd.fd, buffer1, start1, len1,
688  buffer2, start2, len2);
689 #endif
690 }
691 
708 int
709 _dbus_read (int fd,
710  DBusString *buffer,
711  int count)
712 {
713  int bytes_read;
714  int start;
715  char *data;
716 
717  _dbus_assert (count >= 0);
718 
719  start = _dbus_string_get_length (buffer);
720 
721  if (!_dbus_string_lengthen (buffer, count))
722  {
723  errno = ENOMEM;
724  return -1;
725  }
726 
727  data = _dbus_string_get_data_len (buffer, start, count);
728 
729  again:
730 
731  bytes_read = read (fd, data, count);
732 
733  if (bytes_read < 0)
734  {
735  if (errno == EINTR)
736  goto again;
737  else
738  {
739  /* put length back (note that this doesn't actually realloc anything) */
740  _dbus_string_set_length (buffer, start);
741  return -1;
742  }
743  }
744  else
745  {
746  /* put length back (doesn't actually realloc) */
747  _dbus_string_set_length (buffer, start + bytes_read);
748 
749 #if 0
750  if (bytes_read > 0)
751  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
752 #endif
753 
754  return bytes_read;
755  }
756 }
757 
768 int
769 _dbus_write (int fd,
770  const DBusString *buffer,
771  int start,
772  int len)
773 {
774  const char *data;
775  int bytes_written;
776 
777  data = _dbus_string_get_const_data_len (buffer, start, len);
778 
779  again:
780 
781  bytes_written = write (fd, data, len);
782 
783  if (bytes_written < 0 && errno == EINTR)
784  goto again;
785 
786 #if 0
787  if (bytes_written > 0)
788  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
789 #endif
790 
791  return bytes_written;
792 }
793 
814 int
816  const DBusString *buffer1,
817  int start1,
818  int len1,
819  const DBusString *buffer2,
820  int start2,
821  int len2)
822 {
823  _dbus_assert (buffer1 != NULL);
824  _dbus_assert (start1 >= 0);
825  _dbus_assert (start2 >= 0);
826  _dbus_assert (len1 >= 0);
827  _dbus_assert (len2 >= 0);
828 
829 #ifdef HAVE_WRITEV
830  {
831  struct iovec vectors[2];
832  const char *data1;
833  const char *data2;
834  int bytes_written;
835 
836  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
837 
838  if (buffer2 != NULL)
839  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
840  else
841  {
842  data2 = NULL;
843  start2 = 0;
844  len2 = 0;
845  }
846 
847  vectors[0].iov_base = (char*) data1;
848  vectors[0].iov_len = len1;
849  vectors[1].iov_base = (char*) data2;
850  vectors[1].iov_len = len2;
851 
852  again:
853 
854  bytes_written = writev (fd,
855  vectors,
856  data2 ? 2 : 1);
857 
858  if (bytes_written < 0 && errno == EINTR)
859  goto again;
860 
861  return bytes_written;
862  }
863 #else /* HAVE_WRITEV */
864  {
865  int ret1, ret2;
866 
867  ret1 = _dbus_write (fd, buffer1, start1, len1);
868  if (ret1 == len1 && buffer2 != NULL)
869  {
870  ret2 = _dbus_write (fd, buffer2, start2, len2);
871  if (ret2 < 0)
872  ret2 = 0; /* we can't report an error as the first write was OK */
873 
874  return ret1 + ret2;
875  }
876  else
877  return ret1;
878  }
879 #endif /* !HAVE_WRITEV */
880 }
881 
882 #define _DBUS_MAX_SUN_PATH_LENGTH 99
883 
913 int
914 _dbus_connect_unix_socket (const char *path,
915  dbus_bool_t abstract,
916  DBusError *error)
917 {
918  int fd;
919  size_t path_len;
920  struct sockaddr_un addr;
921 
922  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
923 
924  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
925  path, abstract);
926 
927 
928  if (!_dbus_open_unix_socket (&fd, error))
929  {
930  _DBUS_ASSERT_ERROR_IS_SET(error);
931  return -1;
932  }
933  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
934 
935  _DBUS_ZERO (addr);
936  addr.sun_family = AF_UNIX;
937  path_len = strlen (path);
938 
939  if (abstract)
940  {
941 #ifdef HAVE_ABSTRACT_SOCKETS
942  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
943  path_len++; /* Account for the extra nul byte added to the start of sun_path */
944 
945  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
946  {
948  "Abstract socket name too long\n");
949  _dbus_close (fd, NULL);
950  return -1;
951  }
952 
953  strncpy (&addr.sun_path[1], path, path_len);
954  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
955 #else /* HAVE_ABSTRACT_SOCKETS */
957  "Operating system does not support abstract socket namespace\n");
958  _dbus_close (fd, NULL);
959  return -1;
960 #endif /* ! HAVE_ABSTRACT_SOCKETS */
961  }
962  else
963  {
964  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
965  {
967  "Socket name too long\n");
968  _dbus_close (fd, NULL);
969  return -1;
970  }
971 
972  strncpy (addr.sun_path, path, path_len);
973  }
974 
975  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
976  {
977  dbus_set_error (error,
978  _dbus_error_from_errno (errno),
979  "Failed to connect to socket %s: %s",
980  path, _dbus_strerror (errno));
981 
982  _dbus_close (fd, NULL);
983  return -1;
984  }
985 
986  if (!_dbus_set_fd_nonblocking (fd, error))
987  {
988  _DBUS_ASSERT_ERROR_IS_SET (error);
989 
990  _dbus_close (fd, NULL);
991  return -1;
992  }
993 
994  return fd;
995 }
996 
1009 int
1010 _dbus_connect_exec (const char *path,
1011  char *const argv[],
1012  DBusError *error)
1013 {
1014  int fds[2];
1015  pid_t pid;
1016  int retval;
1017  dbus_bool_t cloexec_done = 0;
1018 
1019  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1020 
1021  _dbus_verbose ("connecting to process %s\n", path);
1022 
1023 #ifdef SOCK_CLOEXEC
1024  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1025  cloexec_done = (retval >= 0);
1026 
1027  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1028 #endif
1029  {
1030  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1031  }
1032 
1033  if (retval < 0)
1034  {
1035  dbus_set_error (error,
1036  _dbus_error_from_errno (errno),
1037  "Failed to create socket pair: %s",
1038  _dbus_strerror (errno));
1039  return -1;
1040  }
1041 
1042  if (!cloexec_done)
1043  {
1044  _dbus_fd_set_close_on_exec (fds[0]);
1045  _dbus_fd_set_close_on_exec (fds[1]);
1046  }
1047 
1048  pid = fork ();
1049  if (pid < 0)
1050  {
1051  dbus_set_error (error,
1052  _dbus_error_from_errno (errno),
1053  "Failed to fork() to call %s: %s",
1054  path, _dbus_strerror (errno));
1055  close (fds[0]);
1056  close (fds[1]);
1057  return -1;
1058  }
1059 
1060  if (pid == 0)
1061  {
1062  /* child */
1063  close (fds[0]);
1064 
1065  dup2 (fds[1], STDIN_FILENO);
1066  dup2 (fds[1], STDOUT_FILENO);
1067 
1068  if (fds[1] != STDIN_FILENO &&
1069  fds[1] != STDOUT_FILENO)
1070  close (fds[1]);
1071 
1072  /* Inherit STDERR and the controlling terminal from the
1073  parent */
1074 
1075  _dbus_close_all ();
1076 
1077  execvp (path, argv);
1078 
1079  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1080 
1081  _exit(1);
1082  }
1083 
1084  /* parent */
1085  close (fds[1]);
1086 
1087  if (!_dbus_set_fd_nonblocking (fds[0], error))
1088  {
1089  _DBUS_ASSERT_ERROR_IS_SET (error);
1090 
1091  close (fds[0]);
1092  return -1;
1093  }
1094 
1095  return fds[0];
1096 }
1097 
1115 int
1116 _dbus_listen_unix_socket (const char *path,
1117  dbus_bool_t abstract,
1118  DBusError *error)
1119 {
1120  int listen_fd;
1121  struct sockaddr_un addr;
1122  size_t path_len;
1123 
1124  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1125 
1126  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1127  path, abstract);
1128 
1129  if (!_dbus_open_unix_socket (&listen_fd, error))
1130  {
1131  _DBUS_ASSERT_ERROR_IS_SET(error);
1132  return -1;
1133  }
1134  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1135 
1136  _DBUS_ZERO (addr);
1137  addr.sun_family = AF_UNIX;
1138  path_len = strlen (path);
1139 
1140  if (abstract)
1141  {
1142 #ifdef HAVE_ABSTRACT_SOCKETS
1143  /* remember that abstract names aren't nul-terminated so we rely
1144  * on sun_path being filled in with zeroes above.
1145  */
1146  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1147  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1148 
1149  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1150  {
1152  "Abstract socket name too long\n");
1153  _dbus_close (listen_fd, NULL);
1154  return -1;
1155  }
1156 
1157  strncpy (&addr.sun_path[1], path, path_len);
1158  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1159 #else /* HAVE_ABSTRACT_SOCKETS */
1161  "Operating system does not support abstract socket namespace\n");
1162  _dbus_close (listen_fd, NULL);
1163  return -1;
1164 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1165  }
1166  else
1167  {
1168  /* Discussed security implications of this with Nalin,
1169  * and we couldn't think of where it would kick our ass, but
1170  * it still seems a bit sucky. It also has non-security suckage;
1171  * really we'd prefer to exit if the socket is already in use.
1172  * But there doesn't seem to be a good way to do this.
1173  *
1174  * Just to be extra careful, I threw in the stat() - clearly
1175  * the stat() can't *fix* any security issue, but it at least
1176  * avoids inadvertent/accidental data loss.
1177  */
1178  {
1179  struct stat sb;
1180 
1181  if (stat (path, &sb) == 0 &&
1182  S_ISSOCK (sb.st_mode))
1183  unlink (path);
1184  }
1185 
1186  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1187  {
1189  "Socket name too long\n");
1190  _dbus_close (listen_fd, NULL);
1191  return -1;
1192  }
1193 
1194  strncpy (addr.sun_path, path, path_len);
1195  }
1196 
1197  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1198  {
1199  dbus_set_error (error, _dbus_error_from_errno (errno),
1200  "Failed to bind socket \"%s\": %s",
1201  path, _dbus_strerror (errno));
1202  _dbus_close (listen_fd, NULL);
1203  return -1;
1204  }
1205 
1206  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1207  {
1208  dbus_set_error (error, _dbus_error_from_errno (errno),
1209  "Failed to listen on socket \"%s\": %s",
1210  path, _dbus_strerror (errno));
1211  _dbus_close (listen_fd, NULL);
1212  return -1;
1213  }
1214 
1215  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1216  {
1217  _DBUS_ASSERT_ERROR_IS_SET (error);
1218  _dbus_close (listen_fd, NULL);
1219  return -1;
1220  }
1221 
1222  /* Try opening up the permissions, but if we can't, just go ahead
1223  * and continue, maybe it will be good enough.
1224  */
1225  if (!abstract && chmod (path, 0777) < 0)
1226  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1227  path);
1228 
1229  return listen_fd;
1230 }
1231 
1242 int
1244  DBusError *error)
1245 {
1246 #ifdef HAVE_SYSTEMD
1247  int r, n;
1248  int fd;
1249  DBusSocket *new_fds;
1250 
1251  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1252 
1253  n = sd_listen_fds (TRUE);
1254  if (n < 0)
1255  {
1257  "Failed to acquire systemd socket: %s",
1258  _dbus_strerror (-n));
1259  return -1;
1260  }
1261 
1262  if (n <= 0)
1263  {
1265  "No socket received.");
1266  return -1;
1267  }
1268 
1269  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1270  {
1271  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1272  if (r < 0)
1273  {
1275  "Failed to verify systemd socket type: %s",
1276  _dbus_strerror (-r));
1277  return -1;
1278  }
1279 
1280  if (!r)
1281  {
1283  "Passed socket has wrong type.");
1284  return -1;
1285  }
1286  }
1287 
1288  /* OK, the file descriptors are all good, so let's take posession of
1289  them then. */
1290 
1291  new_fds = dbus_new (DBusSocket, n);
1292  if (!new_fds)
1293  {
1295  "Failed to allocate file handle array.");
1296  goto fail;
1297  }
1298 
1299  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1300  {
1301  if (!_dbus_set_fd_nonblocking (fd, error))
1302  {
1303  _DBUS_ASSERT_ERROR_IS_SET (error);
1304  goto fail;
1305  }
1306 
1307  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1308  }
1309 
1310  *fds = new_fds;
1311  return n;
1312 
1313  fail:
1314 
1315  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1316  {
1317  _dbus_close (fd, NULL);
1318  }
1319 
1320  dbus_free (new_fds);
1321  return -1;
1322 #else
1324  "dbus was compiled without systemd support");
1325  return -1;
1326 #endif
1327 }
1328 
1342 DBusSocket
1343 _dbus_connect_tcp_socket (const char *host,
1344  const char *port,
1345  const char *family,
1346  DBusError *error)
1347 {
1348  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1349 }
1350 
1351 DBusSocket
1352 _dbus_connect_tcp_socket_with_nonce (const char *host,
1353  const char *port,
1354  const char *family,
1355  const char *noncefile,
1356  DBusError *error)
1357 {
1358  int saved_errno = 0;
1359  DBusSocket fd = DBUS_SOCKET_INIT;
1360  int res;
1361  struct addrinfo hints;
1362  struct addrinfo *ai, *tmp;
1363 
1364  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1365 
1366  _DBUS_ZERO (hints);
1367 
1368  if (!family)
1369  hints.ai_family = AF_UNSPEC;
1370  else if (!strcmp(family, "ipv4"))
1371  hints.ai_family = AF_INET;
1372  else if (!strcmp(family, "ipv6"))
1373  hints.ai_family = AF_INET6;
1374  else
1375  {
1376  dbus_set_error (error,
1378  "Unknown address family %s", family);
1379  return _dbus_socket_get_invalid ();
1380  }
1381  hints.ai_protocol = IPPROTO_TCP;
1382  hints.ai_socktype = SOCK_STREAM;
1383  hints.ai_flags = AI_ADDRCONFIG;
1384 
1385  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1386  {
1387  dbus_set_error (error,
1388  _dbus_error_from_errno (errno),
1389  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1390  host, port, gai_strerror(res), res);
1391  return _dbus_socket_get_invalid ();
1392  }
1393 
1394  tmp = ai;
1395  while (tmp)
1396  {
1397  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1398  {
1399  freeaddrinfo(ai);
1400  _DBUS_ASSERT_ERROR_IS_SET(error);
1401  return _dbus_socket_get_invalid ();
1402  }
1403  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1404 
1405  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1406  {
1407  saved_errno = errno;
1408  _dbus_close (fd.fd, NULL);
1409  fd.fd = -1;
1410  tmp = tmp->ai_next;
1411  continue;
1412  }
1413 
1414  break;
1415  }
1416  freeaddrinfo(ai);
1417 
1418  if (fd.fd == -1)
1419  {
1420  dbus_set_error (error,
1421  _dbus_error_from_errno (saved_errno),
1422  "Failed to connect to socket \"%s:%s\" %s",
1423  host, port, _dbus_strerror(saved_errno));
1424  return _dbus_socket_get_invalid ();
1425  }
1426 
1427  if (noncefile != NULL)
1428  {
1429  DBusString noncefileStr;
1430  dbus_bool_t ret;
1431  _dbus_string_init_const (&noncefileStr, noncefile);
1432  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1433  _dbus_string_free (&noncefileStr);
1434 
1435  if (!ret)
1436  {
1437  _dbus_close (fd.fd, NULL);
1438  return _dbus_socket_get_invalid ();
1439  }
1440  }
1441 
1442  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1443  {
1444  _dbus_close (fd.fd, NULL);
1445  return _dbus_socket_get_invalid ();
1446  }
1447 
1448  return fd;
1449 }
1450 
1467 int
1468 _dbus_listen_tcp_socket (const char *host,
1469  const char *port,
1470  const char *family,
1471  DBusString *retport,
1472  DBusSocket **fds_p,
1473  DBusError *error)
1474 {
1475  int saved_errno;
1476  int nlisten_fd = 0, res, i;
1477  DBusSocket *listen_fd = NULL;
1478  struct addrinfo hints;
1479  struct addrinfo *ai, *tmp;
1480  unsigned int reuseaddr;
1481 
1482  *fds_p = NULL;
1483  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1484 
1485  _DBUS_ZERO (hints);
1486 
1487  if (!family)
1488  hints.ai_family = AF_UNSPEC;
1489  else if (!strcmp(family, "ipv4"))
1490  hints.ai_family = AF_INET;
1491  else if (!strcmp(family, "ipv6"))
1492  hints.ai_family = AF_INET6;
1493  else
1494  {
1495  dbus_set_error (error,
1497  "Unknown address family %s", family);
1498  return -1;
1499  }
1500 
1501  hints.ai_protocol = IPPROTO_TCP;
1502  hints.ai_socktype = SOCK_STREAM;
1503  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1504 
1505  redo_lookup_with_port:
1506  ai = NULL;
1507  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1508  {
1509  dbus_set_error (error,
1510  _dbus_error_from_errno (errno),
1511  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1512  host ? host : "*", port, gai_strerror(res), res);
1513  goto failed;
1514  }
1515 
1516  tmp = ai;
1517  while (tmp)
1518  {
1519  int fd = -1, tcp_nodelay_on;
1520  DBusSocket *newlisten_fd;
1521 
1522  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1523  {
1524  _DBUS_ASSERT_ERROR_IS_SET(error);
1525  goto failed;
1526  }
1527  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1528 
1529  reuseaddr = 1;
1530  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1531  {
1532  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1533  host ? host : "*", port, _dbus_strerror (errno));
1534  }
1535 
1536  /* Nagle's algorithm imposes a huge delay on the initial messages
1537  going over TCP. */
1538  tcp_nodelay_on = 1;
1539  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1540  {
1541  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1542  host ? host : "*", port, _dbus_strerror (errno));
1543  }
1544 
1545  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1546  {
1547  saved_errno = errno;
1548  _dbus_close(fd, NULL);
1549  if (saved_errno == EADDRINUSE)
1550  {
1551  /* Depending on kernel policy, binding to an IPv6 address
1552  might implicitly bind to a corresponding IPv4
1553  address or vice versa, resulting in EADDRINUSE for the
1554  other one (e.g. bindv6only=0 on Linux).
1555 
1556  Also, after we "goto redo_lookup_with_port" after binding
1557  a port on one of the possible addresses, we will
1558  try to bind that same port on every address, including the
1559  same address again for a second time; that one will
1560  also fail with EADDRINUSE.
1561 
1562  For both those reasons, ignore EADDRINUSE here */
1563  tmp = tmp->ai_next;
1564  continue;
1565  }
1566  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1567  "Failed to bind socket \"%s:%s\": %s",
1568  host ? host : "*", port, _dbus_strerror (saved_errno));
1569  goto failed;
1570  }
1571 
1572  if (listen (fd, 30 /* backlog */) < 0)
1573  {
1574  saved_errno = errno;
1575  _dbus_close (fd, NULL);
1576  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1577  "Failed to listen on socket \"%s:%s\": %s",
1578  host ? host : "*", port, _dbus_strerror (saved_errno));
1579  goto failed;
1580  }
1581 
1582  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1583  if (!newlisten_fd)
1584  {
1585  saved_errno = errno;
1586  _dbus_close (fd, NULL);
1587  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1588  "Failed to allocate file handle array: %s",
1589  _dbus_strerror (saved_errno));
1590  goto failed;
1591  }
1592  listen_fd = newlisten_fd;
1593  listen_fd[nlisten_fd].fd = fd;
1594  nlisten_fd++;
1595 
1596  if (!_dbus_string_get_length(retport))
1597  {
1598  /* If the user didn't specify a port, or used 0, then
1599  the kernel chooses a port. After the first address
1600  is bound to, we need to force all remaining addresses
1601  to use the same port */
1602  if (!port || !strcmp(port, "0"))
1603  {
1604  int result;
1605  struct sockaddr_storage addr;
1606  socklen_t addrlen;
1607  char portbuf[50];
1608 
1609  addrlen = sizeof(addr);
1610  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1611 
1612  if (result == -1 ||
1613  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1614  portbuf, sizeof(portbuf),
1615  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1616  {
1617  dbus_set_error (error, _dbus_error_from_errno (errno),
1618  "Failed to resolve port \"%s:%s\": %s (%s)",
1619  host ? host : "*", port, gai_strerror(res), res);
1620  goto failed;
1621  }
1622  if (!_dbus_string_append(retport, portbuf))
1623  {
1625  goto failed;
1626  }
1627 
1628  /* Release current address list & redo lookup */
1629  port = _dbus_string_get_const_data(retport);
1630  freeaddrinfo(ai);
1631  goto redo_lookup_with_port;
1632  }
1633  else
1634  {
1635  if (!_dbus_string_append(retport, port))
1636  {
1638  goto failed;
1639  }
1640  }
1641  }
1642 
1643  tmp = tmp->ai_next;
1644  }
1645  freeaddrinfo(ai);
1646  ai = NULL;
1647 
1648  if (!nlisten_fd)
1649  {
1650  errno = EADDRINUSE;
1651  dbus_set_error (error, _dbus_error_from_errno (errno),
1652  "Failed to bind socket \"%s:%s\": %s",
1653  host ? host : "*", port, _dbus_strerror (errno));
1654  goto failed;
1655  }
1656 
1657  for (i = 0 ; i < nlisten_fd ; i++)
1658  {
1659  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1660  {
1661  goto failed;
1662  }
1663  }
1664 
1665  *fds_p = listen_fd;
1666 
1667  return nlisten_fd;
1668 
1669  failed:
1670  if (ai)
1671  freeaddrinfo(ai);
1672  for (i = 0 ; i < nlisten_fd ; i++)
1673  _dbus_close(listen_fd[i].fd, NULL);
1674  dbus_free(listen_fd);
1675  return -1;
1676 }
1677 
1678 static dbus_bool_t
1679 write_credentials_byte (int server_fd,
1680  DBusError *error)
1681 {
1682  int bytes_written;
1683  char buf[1] = { '\0' };
1684 #if defined(HAVE_CMSGCRED)
1685  union {
1686  struct cmsghdr hdr;
1687  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1688  } cmsg;
1689  struct iovec iov;
1690  struct msghdr msg;
1691  iov.iov_base = buf;
1692  iov.iov_len = 1;
1693 
1694  _DBUS_ZERO(msg);
1695  msg.msg_iov = &iov;
1696  msg.msg_iovlen = 1;
1697 
1698  msg.msg_control = (caddr_t) &cmsg;
1699  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1700  _DBUS_ZERO(cmsg);
1701  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1702  cmsg.hdr.cmsg_level = SOL_SOCKET;
1703  cmsg.hdr.cmsg_type = SCM_CREDS;
1704 #endif
1705 
1706  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1707 
1708  again:
1709 
1710 #if defined(HAVE_CMSGCRED)
1711  bytes_written = sendmsg (server_fd, &msg, 0
1712 #if HAVE_DECL_MSG_NOSIGNAL
1713  |MSG_NOSIGNAL
1714 #endif
1715  );
1716 
1717  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1718  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1719  * only allows that on AF_UNIX. Try just doing a send() instead. */
1720  if (bytes_written < 0 && errno == EINVAL)
1721 #endif
1722  {
1723  bytes_written = send (server_fd, buf, 1, 0
1724 #if HAVE_DECL_MSG_NOSIGNAL
1725  |MSG_NOSIGNAL
1726 #endif
1727  );
1728  }
1729 
1730  if (bytes_written < 0 && errno == EINTR)
1731  goto again;
1732 
1733  if (bytes_written < 0)
1734  {
1735  dbus_set_error (error, _dbus_error_from_errno (errno),
1736  "Failed to write credentials byte: %s",
1737  _dbus_strerror (errno));
1738  return FALSE;
1739  }
1740  else if (bytes_written == 0)
1741  {
1743  "wrote zero bytes writing credentials byte");
1744  return FALSE;
1745  }
1746  else
1747  {
1748  _dbus_assert (bytes_written == 1);
1749  _dbus_verbose ("wrote credentials byte\n");
1750  return TRUE;
1751  }
1752 }
1753 
1754 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1755 static dbus_bool_t
1756 add_linux_security_label_to_credentials (int client_fd,
1757  DBusCredentials *credentials)
1758 {
1759 #if defined(__linux__) && defined(SO_PEERSEC)
1760  DBusString buf;
1761  socklen_t len = 1024;
1762  dbus_bool_t oom = FALSE;
1763 
1764  if (!_dbus_string_init_preallocated (&buf, len) ||
1765  !_dbus_string_set_length (&buf, len))
1766  return FALSE;
1767 
1768  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1769  _dbus_string_get_data (&buf), &len) < 0)
1770  {
1771  int e = errno;
1772 
1773  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1774  _dbus_strerror (e), (unsigned long) len);
1775 
1776  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1777  {
1778  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1779  _dbus_strerror (e));
1780  goto out;
1781  }
1782 
1783  /* If not enough space, len is updated to be enough.
1784  * Try again with a large enough buffer. */
1785  if (!_dbus_string_set_length (&buf, len))
1786  {
1787  oom = TRUE;
1788  goto out;
1789  }
1790 
1791  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1792  }
1793 
1794  if (len <= 0)
1795  {
1796  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1797  (unsigned long) len);
1798  goto out;
1799  }
1800 
1801  if (len > _dbus_string_get_length_uint (&buf))
1802  {
1803  _dbus_verbose ("%lu > %u", (unsigned long) len,
1804  _dbus_string_get_length_uint (&buf));
1805  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1806  }
1807 
1808  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1809  {
1810  /* the kernel included the trailing \0 in its count,
1811  * but DBusString always has an extra \0 after the data anyway */
1812  _dbus_verbose ("subtracting trailing \\0\n");
1813  len--;
1814  }
1815 
1816  if (!_dbus_string_set_length (&buf, len))
1817  {
1818  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1819  oom = TRUE;
1820  goto out;
1821  }
1822 
1823  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1824  {
1825  /* LSM people on the linux-security-module@ mailing list say this
1826  * should never happen: the label should be a bytestring with
1827  * an optional trailing \0 */
1828  _dbus_verbose ("security label from kernel had an embedded \\0, "
1829  "ignoring it\n");
1830  goto out;
1831  }
1832 
1833  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1834  (unsigned long) len,
1835  _dbus_string_get_const_data (&buf));
1836 
1838  _dbus_string_get_const_data (&buf)))
1839  {
1840  oom = TRUE;
1841  goto out;
1842  }
1843 
1844 out:
1845  _dbus_string_free (&buf);
1846  return !oom;
1847 #else
1848  /* no error */
1849  return TRUE;
1850 #endif
1851 }
1852 
1895  DBusCredentials *credentials,
1896  DBusError *error)
1897 {
1898  struct msghdr msg;
1899  struct iovec iov;
1900  char buf;
1901  dbus_uid_t uid_read;
1902  dbus_pid_t pid_read;
1903  int bytes_read;
1904 
1905 #ifdef HAVE_CMSGCRED
1906  union {
1907  struct cmsghdr hdr;
1908  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1909  } cmsg;
1910 #endif
1911 
1912  /* The POSIX spec certainly doesn't promise this, but
1913  * we need these assertions to fail as soon as we're wrong about
1914  * it so we can do the porting fixups
1915  */
1916  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1917  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1918  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1919 
1920  uid_read = DBUS_UID_UNSET;
1921  pid_read = DBUS_PID_UNSET;
1922 
1923  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1924 
1925  _dbus_credentials_clear (credentials);
1926 
1927  iov.iov_base = &buf;
1928  iov.iov_len = 1;
1929 
1930  _DBUS_ZERO(msg);
1931  msg.msg_iov = &iov;
1932  msg.msg_iovlen = 1;
1933 
1934 #if defined(HAVE_CMSGCRED)
1935  _DBUS_ZERO(cmsg);
1936  msg.msg_control = (caddr_t) &cmsg;
1937  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1938 #endif
1939 
1940  again:
1941  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1942 
1943  if (bytes_read < 0)
1944  {
1945  if (errno == EINTR)
1946  goto again;
1947 
1948  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1949  * normally only call read_credentials if the socket was ready
1950  * for reading
1951  */
1952 
1953  dbus_set_error (error, _dbus_error_from_errno (errno),
1954  "Failed to read credentials byte: %s",
1955  _dbus_strerror (errno));
1956  return FALSE;
1957  }
1958  else if (bytes_read == 0)
1959  {
1960  /* this should not happen unless we are using recvmsg wrong,
1961  * so is essentially here for paranoia
1962  */
1964  "Failed to read credentials byte (zero-length read)");
1965  return FALSE;
1966  }
1967  else if (buf != '\0')
1968  {
1970  "Credentials byte was not nul");
1971  return FALSE;
1972  }
1973 
1974  _dbus_verbose ("read credentials byte\n");
1975 
1976  {
1977 #ifdef SO_PEERCRED
1978  /* Supported by at least Linux and OpenBSD, with minor differences.
1979  *
1980  * This mechanism passes the process ID through and does not require
1981  * the peer's cooperation, so we prefer it over all others. Notably,
1982  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1983  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1984  * because this is much less fragile.
1985  */
1986 #ifdef __OpenBSD__
1987  struct sockpeercred cr;
1988 #else
1989  struct ucred cr;
1990 #endif
1991  int cr_len = sizeof (cr);
1992 
1993  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
1994  {
1995  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
1996  _dbus_strerror (errno));
1997  }
1998  else if (cr_len != sizeof (cr))
1999  {
2000  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2001  cr_len, (int) sizeof (cr));
2002  }
2003  else
2004  {
2005  pid_read = cr.pid;
2006  uid_read = cr.uid;
2007  }
2008 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2009  /* Another variant of the above - used on NetBSD
2010  */
2011  struct unpcbid cr;
2012  socklen_t cr_len = sizeof (cr);
2013 
2014  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2015  {
2016  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2017  _dbus_strerror (errno));
2018  }
2019  else if (cr_len != sizeof (cr))
2020  {
2021  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2022  cr_len, (int) sizeof (cr));
2023  }
2024  else
2025  {
2026  pid_read = cr.unp_pid;
2027  uid_read = cr.unp_euid;
2028  }
2029 #elif defined(HAVE_CMSGCRED)
2030  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2031  * presence of that struct implies SCM_CREDS. Supported by at least
2032  * FreeBSD and DragonflyBSD.
2033  *
2034  * This mechanism requires the peer to help us (it has to send us a
2035  * SCM_CREDS message) but it does pass the process ID through,
2036  * which makes it better than getpeereid().
2037  */
2038  struct cmsgcred *cred;
2039  struct cmsghdr *cmsgp;
2040 
2041  for (cmsgp = CMSG_FIRSTHDR (&msg);
2042  cmsgp != NULL;
2043  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2044  {
2045  if (cmsgp->cmsg_type == SCM_CREDS &&
2046  cmsgp->cmsg_level == SOL_SOCKET &&
2047  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2048  {
2049  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2050  pid_read = cred->cmcred_pid;
2051  uid_read = cred->cmcred_euid;
2052  break;
2053  }
2054  }
2055 
2056 #elif defined(HAVE_GETPEERUCRED)
2057  /* Supported in at least Solaris >= 10. It should probably be higher
2058  * up this list, because it carries the pid and we use this code path
2059  * for audit data. */
2060  ucred_t * ucred = NULL;
2061  if (getpeerucred (client_fd.fd, &ucred) == 0)
2062  {
2063 #ifdef HAVE_ADT
2064  adt_session_data_t *adth = NULL;
2065 #endif
2066  pid_read = ucred_getpid (ucred);
2067  uid_read = ucred_geteuid (ucred);
2068 #ifdef HAVE_ADT
2069  /* generate audit session data based on socket ucred */
2070  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2071  {
2072  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2073  }
2074  else
2075  {
2076  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2077  {
2078  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2079  }
2080  else
2081  {
2082  adt_export_data_t *data = NULL;
2083  size_t size = adt_export_session_data (adth, &data);
2084  if (size <= 0)
2085  {
2086  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2087  }
2088  else
2089  {
2090  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2091  free (data);
2092  }
2093  }
2094  (void) adt_end_session (adth);
2095  }
2096 #endif /* HAVE_ADT */
2097  }
2098  else
2099  {
2100  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2101  }
2102  if (ucred != NULL)
2103  ucred_free (ucred);
2104 
2105  /* ----------------------------------------------------------------
2106  * When adding new mechanisms, please add them above this point
2107  * if they support passing the process ID through, or below if not.
2108  * ---------------------------------------------------------------- */
2109 
2110 #elif defined(HAVE_GETPEEREID)
2111  /* getpeereid() originates from D.J. Bernstein and is fairly
2112  * widely-supported. According to a web search, it might be present in
2113  * any/all of:
2114  *
2115  * - AIX?
2116  * - Blackberry?
2117  * - Cygwin
2118  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2119  * - Mac OS X
2120  * - Minix 3.1.8+
2121  * - MirBSD?
2122  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2123  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2124  * - QNX?
2125  */
2126  uid_t euid;
2127  gid_t egid;
2128  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2129  {
2130  uid_read = euid;
2131  }
2132  else
2133  {
2134  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2135  }
2136 #else /* no supported mechanism */
2137 
2138 #warning Socket credentials not supported on this Unix OS
2139 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2140 
2141  /* Please add other operating systems known to support at least one of
2142  * the mechanisms above to this list, keeping alphabetical order.
2143  * Everything not in this list is best-effort.
2144  */
2145 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2146  defined(__linux__) || \
2147  defined(__OpenBSD__) || \
2148  defined(__NetBSD__)
2149 # error Credentials passing not working on this OS is a regression!
2150 #endif
2151 
2152  _dbus_verbose ("Socket credentials not supported on this OS\n");
2153 #endif
2154  }
2155 
2156  _dbus_verbose ("Credentials:"
2157  " pid "DBUS_PID_FORMAT
2158  " uid "DBUS_UID_FORMAT
2159  "\n",
2160  pid_read,
2161  uid_read);
2162 
2163  if (pid_read != DBUS_PID_UNSET)
2164  {
2165  if (!_dbus_credentials_add_pid (credentials, pid_read))
2166  {
2167  _DBUS_SET_OOM (error);
2168  return FALSE;
2169  }
2170  }
2171 
2172  if (uid_read != DBUS_UID_UNSET)
2173  {
2174  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2175  {
2176  _DBUS_SET_OOM (error);
2177  return FALSE;
2178  }
2179  }
2180 
2181  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2182  {
2183  _DBUS_SET_OOM (error);
2184  return FALSE;
2185  }
2186 
2187  return TRUE;
2188 }
2189 
2209  DBusError *error)
2210 {
2211  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2212 
2213  if (write_credentials_byte (server_fd.fd, error))
2214  return TRUE;
2215  else
2216  return FALSE;
2217 }
2218 
2228 DBusSocket
2230 {
2231  DBusSocket client_fd;
2232  struct sockaddr addr;
2233  socklen_t addrlen;
2234 #ifdef HAVE_ACCEPT4
2235  dbus_bool_t cloexec_done;
2236 #endif
2237 
2238  addrlen = sizeof (addr);
2239 
2240  retry:
2241 
2242 #ifdef HAVE_ACCEPT4
2243  /*
2244  * At compile-time, we assume that if accept4() is available in
2245  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2246  * not necessarily true that either is supported by the running kernel.
2247  */
2248  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2249  cloexec_done = client_fd.fd >= 0;
2250 
2251  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2252 #endif
2253  {
2254  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2255  }
2256 
2257  if (client_fd.fd < 0)
2258  {
2259  if (errno == EINTR)
2260  goto retry;
2261  }
2262 
2263  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2264 
2265 #ifdef HAVE_ACCEPT4
2266  if (!cloexec_done)
2267 #endif
2268  {
2269  _dbus_fd_set_close_on_exec(client_fd.fd);
2270  }
2271 
2272  return client_fd;
2273 }
2274 
2285 {
2286  const char *directory;
2287  struct stat sb;
2288 
2289  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2290 
2291  directory = _dbus_string_get_const_data (dir);
2292 
2293  if (stat (directory, &sb) < 0)
2294  {
2295  dbus_set_error (error, _dbus_error_from_errno (errno),
2296  "%s", _dbus_strerror (errno));
2297 
2298  return FALSE;
2299  }
2300 
2301  if (sb.st_uid != geteuid ())
2302  {
2304  "%s directory is owned by user %lu, not %lu",
2305  directory,
2306  (unsigned long) sb.st_uid,
2307  (unsigned long) geteuid ());
2308  return FALSE;
2309  }
2310 
2311  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2312  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2313  {
2315  "%s directory is not private to the user", directory);
2316  return FALSE;
2317  }
2318 
2319  return TRUE;
2320 }
2321 
2322 static dbus_bool_t
2323 fill_user_info_from_passwd (struct passwd *p,
2324  DBusUserInfo *info,
2325  DBusError *error)
2326 {
2327  _dbus_assert (p->pw_name != NULL);
2328  _dbus_assert (p->pw_dir != NULL);
2329 
2330  info->uid = p->pw_uid;
2331  info->primary_gid = p->pw_gid;
2332  info->username = _dbus_strdup (p->pw_name);
2333  info->homedir = _dbus_strdup (p->pw_dir);
2334 
2335  if (info->username == NULL ||
2336  info->homedir == NULL)
2337  {
2339  return FALSE;
2340  }
2341 
2342  return TRUE;
2343 }
2344 
2345 static dbus_bool_t
2346 fill_user_info (DBusUserInfo *info,
2347  dbus_uid_t uid,
2348  const DBusString *username,
2349  DBusError *error)
2350 {
2351  const char *username_c;
2352 
2353  /* exactly one of username/uid provided */
2354  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2355  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2356 
2357  info->uid = DBUS_UID_UNSET;
2358  info->primary_gid = DBUS_GID_UNSET;
2359  info->group_ids = NULL;
2360  info->n_group_ids = 0;
2361  info->username = NULL;
2362  info->homedir = NULL;
2363 
2364  if (username != NULL)
2365  username_c = _dbus_string_get_const_data (username);
2366  else
2367  username_c = NULL;
2368 
2369  /* For now assuming that the getpwnam() and getpwuid() flavors
2370  * are always symmetrical, if not we have to add more configure
2371  * checks
2372  */
2373 
2374 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2375  {
2376  struct passwd *p;
2377  int result;
2378  size_t buflen;
2379  char *buf;
2380  struct passwd p_str;
2381 
2382  /* retrieve maximum needed size for buf */
2383  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2384 
2385  /* sysconf actually returns a long, but everything else expects size_t,
2386  * so just recast here.
2387  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2388  */
2389  if ((long) buflen <= 0)
2390  buflen = 1024;
2391 
2392  result = -1;
2393  while (1)
2394  {
2395  buf = dbus_malloc (buflen);
2396  if (buf == NULL)
2397  {
2399  return FALSE;
2400  }
2401 
2402  p = NULL;
2403 #ifdef HAVE_POSIX_GETPWNAM_R
2404  if (uid != DBUS_UID_UNSET)
2405  result = getpwuid_r (uid, &p_str, buf, buflen,
2406  &p);
2407  else
2408  result = getpwnam_r (username_c, &p_str, buf, buflen,
2409  &p);
2410 #else
2411  if (uid != DBUS_UID_UNSET)
2412  p = getpwuid_r (uid, &p_str, buf, buflen);
2413  else
2414  p = getpwnam_r (username_c, &p_str, buf, buflen);
2415  result = 0;
2416 #endif /* !HAVE_POSIX_GETPWNAM_R */
2417  //Try a bigger buffer if ERANGE was returned
2418  if (result == ERANGE && buflen < 512 * 1024)
2419  {
2420  dbus_free (buf);
2421  buflen *= 2;
2422  }
2423  else
2424  {
2425  break;
2426  }
2427  }
2428  if (result == 0 && p == &p_str)
2429  {
2430  if (!fill_user_info_from_passwd (p, info, error))
2431  {
2432  dbus_free (buf);
2433  return FALSE;
2434  }
2435  dbus_free (buf);
2436  }
2437  else
2438  {
2439  dbus_set_error (error, _dbus_error_from_errno (errno),
2440  "User \"%s\" unknown or no memory to allocate password entry\n",
2441  username_c ? username_c : "???");
2442  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2443  dbus_free (buf);
2444  return FALSE;
2445  }
2446  }
2447 #else /* ! HAVE_GETPWNAM_R */
2448  {
2449  /* I guess we're screwed on thread safety here */
2450  struct passwd *p;
2451 
2452  if (uid != DBUS_UID_UNSET)
2453  p = getpwuid (uid);
2454  else
2455  p = getpwnam (username_c);
2456 
2457  if (p != NULL)
2458  {
2459  if (!fill_user_info_from_passwd (p, info, error))
2460  {
2461  return FALSE;
2462  }
2463  }
2464  else
2465  {
2466  dbus_set_error (error, _dbus_error_from_errno (errno),
2467  "User \"%s\" unknown or no memory to allocate password entry\n",
2468  username_c ? username_c : "???");
2469  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2470  return FALSE;
2471  }
2472  }
2473 #endif /* ! HAVE_GETPWNAM_R */
2474 
2475  /* Fill this in so we can use it to get groups */
2476  username_c = info->username;
2477 
2478 #ifdef HAVE_GETGROUPLIST
2479  {
2480  gid_t *buf;
2481  int buf_count;
2482  int i;
2483  int initial_buf_count;
2484 
2485  initial_buf_count = 17;
2486  buf_count = initial_buf_count;
2487  buf = dbus_new (gid_t, buf_count);
2488  if (buf == NULL)
2489  {
2491  goto failed;
2492  }
2493 
2494  if (getgrouplist (username_c,
2495  info->primary_gid,
2496  buf, &buf_count) < 0)
2497  {
2498  gid_t *new;
2499  /* Presumed cause of negative return code: buf has insufficient
2500  entries to hold the entire group list. The Linux behavior in this
2501  case is to pass back the actual number of groups in buf_count, but
2502  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2503  So as a hack, try to help out a bit by guessing a larger
2504  number of groups, within reason.. might still fail, of course,
2505  but we can at least print a more informative message. I looked up
2506  the "right way" to do this by downloading Apple's own source code
2507  for the "id" command, and it turns out that they use an
2508  undocumented library function getgrouplist_2 (!) which is not
2509  declared in any header in /usr/include (!!). That did not seem
2510  like the way to go here.
2511  */
2512  if (buf_count == initial_buf_count)
2513  {
2514  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2515  }
2516  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2517  if (new == NULL)
2518  {
2520  dbus_free (buf);
2521  goto failed;
2522  }
2523 
2524  buf = new;
2525 
2526  errno = 0;
2527  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2528  {
2529  if (errno == 0)
2530  {
2531  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2532  username_c, buf_count, buf_count);
2533  }
2534  else
2535  {
2536  dbus_set_error (error,
2537  _dbus_error_from_errno (errno),
2538  "Failed to get groups for username \"%s\" primary GID "
2539  DBUS_GID_FORMAT ": %s\n",
2540  username_c, info->primary_gid,
2541  _dbus_strerror (errno));
2542  dbus_free (buf);
2543  goto failed;
2544  }
2545  }
2546  }
2547 
2548  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2549  if (info->group_ids == NULL)
2550  {
2552  dbus_free (buf);
2553  goto failed;
2554  }
2555 
2556  for (i = 0; i < buf_count; ++i)
2557  info->group_ids[i] = buf[i];
2558 
2559  info->n_group_ids = buf_count;
2560 
2561  dbus_free (buf);
2562  }
2563 #else /* HAVE_GETGROUPLIST */
2564  {
2565  /* We just get the one group ID */
2566  info->group_ids = dbus_new (dbus_gid_t, 1);
2567  if (info->group_ids == NULL)
2568  {
2570  goto failed;
2571  }
2572 
2573  info->n_group_ids = 1;
2574 
2575  (info->group_ids)[0] = info->primary_gid;
2576  }
2577 #endif /* HAVE_GETGROUPLIST */
2578 
2579  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2580 
2581  return TRUE;
2582 
2583  failed:
2584  _DBUS_ASSERT_ERROR_IS_SET (error);
2585  return FALSE;
2586 }
2587 
2598  const DBusString *username,
2599  DBusError *error)
2600 {
2601  return fill_user_info (info, DBUS_UID_UNSET,
2602  username, error);
2603 }
2604 
2615  dbus_uid_t uid,
2616  DBusError *error)
2617 {
2618  return fill_user_info (info, uid,
2619  NULL, error);
2620 }
2621 
2631 {
2632  /* The POSIX spec certainly doesn't promise this, but
2633  * we need these assertions to fail as soon as we're wrong about
2634  * it so we can do the porting fixups
2635  */
2636  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2637  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2638  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2639 
2640  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2641  return FALSE;
2642  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2643  return FALSE;
2644 
2645  return TRUE;
2646 }
2647 
2661 {
2662  return _dbus_string_append_uint (str,
2663  _dbus_geteuid ());
2664 }
2665 
2670 dbus_pid_t
2672 {
2673  return getpid ();
2674 }
2675 
2679 dbus_uid_t
2681 {
2682  return getuid ();
2683 }
2684 
2688 dbus_uid_t
2690 {
2691  return geteuid ();
2692 }
2693 
2700 unsigned long
2702 {
2703  return getpid ();
2704 }
2705 
2714 _dbus_parse_uid (const DBusString *uid_str,
2715  dbus_uid_t *uid)
2716 {
2717  int end;
2718  long val;
2719 
2720  if (_dbus_string_get_length (uid_str) == 0)
2721  {
2722  _dbus_verbose ("UID string was zero length\n");
2723  return FALSE;
2724  }
2725 
2726  val = -1;
2727  end = 0;
2728  if (!_dbus_string_parse_int (uid_str, 0, &val,
2729  &end))
2730  {
2731  _dbus_verbose ("could not parse string as a UID\n");
2732  return FALSE;
2733  }
2734 
2735  if (end != _dbus_string_get_length (uid_str))
2736  {
2737  _dbus_verbose ("string contained trailing stuff after UID\n");
2738  return FALSE;
2739  }
2740 
2741  *uid = val;
2742 
2743  return TRUE;
2744 }
2745 
2746 #if !DBUS_USE_SYNC
2747 /* To be thread-safe by default on platforms that don't necessarily have
2748  * atomic operations (notably Debian armel, which is armv4t), we must
2749  * use a mutex that can be initialized statically, like this.
2750  * GLib >= 2.32 uses a similar system.
2751  */
2752 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2753 #endif
2754 
2761 dbus_int32_t
2763 {
2764 #if DBUS_USE_SYNC
2765  return __sync_add_and_fetch(&atomic->value, 1)-1;
2766 #else
2767  dbus_int32_t res;
2768 
2769  pthread_mutex_lock (&atomic_mutex);
2770  res = atomic->value;
2771  atomic->value += 1;
2772  pthread_mutex_unlock (&atomic_mutex);
2773 
2774  return res;
2775 #endif
2776 }
2777 
2784 dbus_int32_t
2786 {
2787 #if DBUS_USE_SYNC
2788  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2789 #else
2790  dbus_int32_t res;
2791 
2792  pthread_mutex_lock (&atomic_mutex);
2793  res = atomic->value;
2794  atomic->value -= 1;
2795  pthread_mutex_unlock (&atomic_mutex);
2796 
2797  return res;
2798 #endif
2799 }
2800 
2808 dbus_int32_t
2810 {
2811 #if DBUS_USE_SYNC
2812  __sync_synchronize ();
2813  return atomic->value;
2814 #else
2815  dbus_int32_t res;
2816 
2817  pthread_mutex_lock (&atomic_mutex);
2818  res = atomic->value;
2819  pthread_mutex_unlock (&atomic_mutex);
2820 
2821  return res;
2822 #endif
2823 }
2824 
2833 int
2835  int n_fds,
2836  int timeout_milliseconds)
2837 {
2838 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2839  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2840  if (timeout_milliseconds < -1)
2841  {
2842  timeout_milliseconds = -1;
2843  }
2844 
2845  return poll (fds,
2846  n_fds,
2847  timeout_milliseconds);
2848 #else /* ! HAVE_POLL */
2849  /* Emulate poll() in terms of select() */
2850  fd_set read_set, write_set, err_set;
2851  int max_fd = 0;
2852  int i;
2853  struct timeval tv;
2854  int ready;
2855 
2856  FD_ZERO (&read_set);
2857  FD_ZERO (&write_set);
2858  FD_ZERO (&err_set);
2859 
2860  for (i = 0; i < n_fds; i++)
2861  {
2862  DBusPollFD *fdp = &fds[i];
2863 
2864  if (fdp->events & _DBUS_POLLIN)
2865  FD_SET (fdp->fd, &read_set);
2866 
2867  if (fdp->events & _DBUS_POLLOUT)
2868  FD_SET (fdp->fd, &write_set);
2869 
2870  FD_SET (fdp->fd, &err_set);
2871 
2872  max_fd = MAX (max_fd, fdp->fd);
2873  }
2874 
2875  tv.tv_sec = timeout_milliseconds / 1000;
2876  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2877 
2878  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2879  timeout_milliseconds < 0 ? NULL : &tv);
2880 
2881  if (ready > 0)
2882  {
2883  for (i = 0; i < n_fds; i++)
2884  {
2885  DBusPollFD *fdp = &fds[i];
2886 
2887  fdp->revents = 0;
2888 
2889  if (FD_ISSET (fdp->fd, &read_set))
2890  fdp->revents |= _DBUS_POLLIN;
2891 
2892  if (FD_ISSET (fdp->fd, &write_set))
2893  fdp->revents |= _DBUS_POLLOUT;
2894 
2895  if (FD_ISSET (fdp->fd, &err_set))
2896  fdp->revents |= _DBUS_POLLERR;
2897  }
2898  }
2899 
2900  return ready;
2901 #endif
2902 }
2903 
2911 void
2913  long *tv_usec)
2914 {
2915 #ifdef HAVE_MONOTONIC_CLOCK
2916  struct timespec ts;
2917  clock_gettime (CLOCK_MONOTONIC, &ts);
2918 
2919  if (tv_sec)
2920  *tv_sec = ts.tv_sec;
2921  if (tv_usec)
2922  *tv_usec = ts.tv_nsec / 1000;
2923 #else
2924  struct timeval t;
2925 
2926  gettimeofday (&t, NULL);
2927 
2928  if (tv_sec)
2929  *tv_sec = t.tv_sec;
2930  if (tv_usec)
2931  *tv_usec = t.tv_usec;
2932 #endif
2933 }
2934 
2942 void
2943 _dbus_get_real_time (long *tv_sec,
2944  long *tv_usec)
2945 {
2946  struct timeval t;
2947 
2948  gettimeofday (&t, NULL);
2949 
2950  if (tv_sec)
2951  *tv_sec = t.tv_sec;
2952  if (tv_usec)
2953  *tv_usec = t.tv_usec;
2954 }
2955 
2966  DBusError *error)
2967 {
2968  const char *filename_c;
2969 
2970  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2971 
2972  filename_c = _dbus_string_get_const_data (filename);
2973 
2974  if (mkdir (filename_c, 0700) < 0)
2975  {
2976  if (errno == EEXIST)
2977  return TRUE;
2978 
2980  "Failed to create directory %s: %s\n",
2981  filename_c, _dbus_strerror (errno));
2982  return FALSE;
2983  }
2984  else
2985  return TRUE;
2986 }
2987 
2998  DBusError *error)
2999 {
3000  const char *filename_c;
3001 
3002  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3003 
3004  filename_c = _dbus_string_get_const_data (filename);
3005 
3006  if (mkdir (filename_c, 0700) < 0)
3007  {
3009  "Failed to create directory %s: %s\n",
3010  filename_c, _dbus_strerror (errno));
3011  return FALSE;
3012  }
3013  else
3014  return TRUE;
3015 }
3016 
3029  const DBusString *next_component)
3030 {
3031  dbus_bool_t dir_ends_in_slash;
3032  dbus_bool_t file_starts_with_slash;
3033 
3034  if (_dbus_string_get_length (dir) == 0 ||
3035  _dbus_string_get_length (next_component) == 0)
3036  return TRUE;
3037 
3038  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3039  _dbus_string_get_length (dir) - 1);
3040 
3041  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3042 
3043  if (dir_ends_in_slash && file_starts_with_slash)
3044  {
3045  _dbus_string_shorten (dir, 1);
3046  }
3047  else if (!(dir_ends_in_slash || file_starts_with_slash))
3048  {
3049  if (!_dbus_string_append_byte (dir, '/'))
3050  return FALSE;
3051  }
3052 
3053  return _dbus_string_copy (next_component, 0, dir,
3054  _dbus_string_get_length (dir));
3055 }
3056 
3058 #define NANOSECONDS_PER_SECOND 1000000000
3059 
3060 #define MICROSECONDS_PER_SECOND 1000000
3061 
3062 #define MILLISECONDS_PER_SECOND 1000
3063 
3064 #define NANOSECONDS_PER_MILLISECOND 1000000
3065 
3066 #define MICROSECONDS_PER_MILLISECOND 1000
3067 
3072 void
3073 _dbus_sleep_milliseconds (int milliseconds)
3074 {
3075 #ifdef HAVE_NANOSLEEP
3076  struct timespec req;
3077  struct timespec rem;
3078 
3079  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3080  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3081  rem.tv_sec = 0;
3082  rem.tv_nsec = 0;
3083 
3084  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3085  req = rem;
3086 #elif defined (HAVE_USLEEP)
3087  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3088 #else /* ! HAVE_USLEEP */
3089  sleep (MAX (milliseconds / 1000, 1));
3090 #endif
3091 }
3092 
3104  int n_bytes,
3105  DBusError *error)
3106 {
3107  int old_len;
3108  int fd;
3109  int result;
3110 
3111  old_len = _dbus_string_get_length (str);
3112  fd = -1;
3113 
3114  /* note, urandom on linux will fall back to pseudorandom */
3115  fd = open ("/dev/urandom", O_RDONLY);
3116 
3117  if (fd < 0)
3118  {
3119  dbus_set_error (error, _dbus_error_from_errno (errno),
3120  "Could not open /dev/urandom: %s",
3121  _dbus_strerror (errno));
3122  return FALSE;
3123  }
3124 
3125  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3126 
3127  result = _dbus_read (fd, str, n_bytes);
3128 
3129  if (result != n_bytes)
3130  {
3131  if (result < 0)
3132  dbus_set_error (error, _dbus_error_from_errno (errno),
3133  "Could not read /dev/urandom: %s",
3134  _dbus_strerror (errno));
3135  else
3137  "Short read from /dev/urandom");
3138 
3139  _dbus_close (fd, NULL);
3140  _dbus_string_set_length (str, old_len);
3141  return FALSE;
3142  }
3143 
3144  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3145  n_bytes);
3146 
3147  _dbus_close (fd, NULL);
3148 
3149  return TRUE;
3150 }
3151 
3157 void
3158 _dbus_exit (int code)
3159 {
3160  _exit (code);
3161 }
3162 
3171 const char*
3172 _dbus_strerror (int error_number)
3173 {
3174  const char *msg;
3175 
3176  msg = strerror (error_number);
3177  if (msg == NULL)
3178  msg = "unknown";
3179 
3180  return msg;
3181 }
3182 
3186 void
3188 {
3189  signal (SIGPIPE, SIG_IGN);
3190 }
3191 
3199 void
3201 {
3202  int val;
3203 
3204  val = fcntl (fd, F_GETFD, 0);
3205 
3206  if (val < 0)
3207  return;
3208 
3209  val |= FD_CLOEXEC;
3210 
3211  fcntl (fd, F_SETFD, val);
3212 }
3213 
3222 _dbus_close (int fd,
3223  DBusError *error)
3224 {
3225  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3226 
3227  again:
3228  if (close (fd) < 0)
3229  {
3230  if (errno == EINTR)
3231  goto again;
3232 
3233  dbus_set_error (error, _dbus_error_from_errno (errno),
3234  "Could not close fd %d", fd);
3235  return FALSE;
3236  }
3237 
3238  return TRUE;
3239 }
3240 
3249 int
3250 _dbus_dup(int fd,
3251  DBusError *error)
3252 {
3253  int new_fd;
3254 
3255 #ifdef F_DUPFD_CLOEXEC
3256  dbus_bool_t cloexec_done;
3257 
3258  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3259  cloexec_done = new_fd >= 0;
3260 
3261  if (new_fd < 0 && errno == EINVAL)
3262 #endif
3263  {
3264  new_fd = fcntl(fd, F_DUPFD, 3);
3265  }
3266 
3267  if (new_fd < 0) {
3268 
3269  dbus_set_error (error, _dbus_error_from_errno (errno),
3270  "Could not duplicate fd %d", fd);
3271  return -1;
3272  }
3273 
3274 #ifdef F_DUPFD_CLOEXEC
3275  if (!cloexec_done)
3276 #endif
3277  {
3279  }
3280 
3281  return new_fd;
3282 }
3283 
3293  DBusError *error)
3294 {
3295  return _dbus_set_fd_nonblocking (fd.fd, error);
3296 }
3297 
3298 static dbus_bool_t
3299 _dbus_set_fd_nonblocking (int fd,
3300  DBusError *error)
3301 {
3302  int val;
3303 
3304  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3305 
3306  val = fcntl (fd, F_GETFL, 0);
3307  if (val < 0)
3308  {
3309  dbus_set_error (error, _dbus_error_from_errno (errno),
3310  "Failed to get flags from file descriptor %d: %s",
3311  fd, _dbus_strerror (errno));
3312  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3313  _dbus_strerror (errno));
3314  return FALSE;
3315  }
3316 
3317  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3318  {
3319  dbus_set_error (error, _dbus_error_from_errno (errno),
3320  "Failed to set nonblocking flag of file descriptor %d: %s",
3321  fd, _dbus_strerror (errno));
3322  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3323  fd, _dbus_strerror (errno));
3324 
3325  return FALSE;
3326  }
3327 
3328  return TRUE;
3329 }
3330 
3336 void
3338 {
3339 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3340  void *bt[500];
3341  int bt_size;
3342  int i;
3343  char **syms;
3344 
3345  bt_size = backtrace (bt, 500);
3346 
3347  syms = backtrace_symbols (bt, bt_size);
3348 
3349  i = 0;
3350  while (i < bt_size)
3351  {
3352  /* don't use dbus_warn since it can _dbus_abort() */
3353  fprintf (stderr, " %s\n", syms[i]);
3354  ++i;
3355  }
3356  fflush (stderr);
3357 
3358  free (syms);
3359 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3360  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3361 #else
3362  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3363 #endif
3364 }
3365 
3380  DBusSocket *fd2,
3381  dbus_bool_t blocking,
3382  DBusError *error)
3383 {
3384 #ifdef HAVE_SOCKETPAIR
3385  int fds[2];
3386  int retval;
3387 
3388 #ifdef SOCK_CLOEXEC
3389  dbus_bool_t cloexec_done;
3390 
3391  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3392  cloexec_done = retval >= 0;
3393 
3394  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3395 #endif
3396  {
3397  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3398  }
3399 
3400  if (retval < 0)
3401  {
3402  dbus_set_error (error, _dbus_error_from_errno (errno),
3403  "Could not create full-duplex pipe");
3404  return FALSE;
3405  }
3406 
3407  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3408 
3409 #ifdef SOCK_CLOEXEC
3410  if (!cloexec_done)
3411 #endif
3412  {
3413  _dbus_fd_set_close_on_exec (fds[0]);
3414  _dbus_fd_set_close_on_exec (fds[1]);
3415  }
3416 
3417  if (!blocking &&
3418  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3419  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3420  {
3421  dbus_set_error (error, _dbus_error_from_errno (errno),
3422  "Could not set full-duplex pipe nonblocking");
3423 
3424  _dbus_close (fds[0], NULL);
3425  _dbus_close (fds[1], NULL);
3426 
3427  return FALSE;
3428  }
3429 
3430  fd1->fd = fds[0];
3431  fd2->fd = fds[1];
3432 
3433  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3434  fd1->fd, fd2->fd);
3435 
3436  return TRUE;
3437 #else
3438  _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
3440  "_dbus_socketpair() not implemented on this OS");
3441  return FALSE;
3442 #endif
3443 }
3444 
3453 int
3455  va_list args)
3456 {
3457  char static_buf[1024];
3458  int bufsize = sizeof (static_buf);
3459  int len;
3460  va_list args_copy;
3461 
3462  DBUS_VA_COPY (args_copy, args);
3463  len = vsnprintf (static_buf, bufsize, format, args_copy);
3464  va_end (args_copy);
3465 
3466  /* If vsnprintf() returned non-negative, then either the string fits in
3467  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3468  * returns the number of characters that were needed, or this OS returns the
3469  * truncated length.
3470  *
3471  * We ignore the possibility that snprintf might just ignore the length and
3472  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3473  * If your libc is really that bad, come back when you have a better one. */
3474  if (len == bufsize)
3475  {
3476  /* This could be the truncated length (Tru64 and IRIX have this bug),
3477  * or the real length could be coincidentally the same. Which is it?
3478  * If vsnprintf returns the truncated length, we'll go to the slow
3479  * path. */
3480  DBUS_VA_COPY (args_copy, args);
3481 
3482  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3483  len = -1;
3484 
3485  va_end (args_copy);
3486  }
3487 
3488  /* If vsnprintf() returned negative, we have to do more work.
3489  * HP-UX returns negative. */
3490  while (len < 0)
3491  {
3492  char *buf;
3493 
3494  bufsize *= 2;
3495 
3496  buf = dbus_malloc (bufsize);
3497 
3498  if (buf == NULL)
3499  return -1;
3500 
3501  DBUS_VA_COPY (args_copy, args);
3502  len = vsnprintf (buf, bufsize, format, args_copy);
3503  va_end (args_copy);
3504 
3505  dbus_free (buf);
3506 
3507  /* If the reported length is exactly the buffer size, round up to the
3508  * next size, in case vsnprintf has been returning the truncated
3509  * length */
3510  if (len == bufsize)
3511  len = -1;
3512  }
3513 
3514  return len;
3515 }
3516 
3523 const char*
3525 {
3526  /* Protected by _DBUS_LOCK_sysdeps */
3527  static const char* tmpdir = NULL;
3528 
3529  if (!_DBUS_LOCK (sysdeps))
3530  return NULL;
3531 
3532  if (tmpdir == NULL)
3533  {
3534  /* TMPDIR is what glibc uses, then
3535  * glibc falls back to the P_tmpdir macro which
3536  * just expands to "/tmp"
3537  */
3538  if (tmpdir == NULL)
3539  tmpdir = getenv("TMPDIR");
3540 
3541  /* These two env variables are probably
3542  * broken, but maybe some OS uses them?
3543  */
3544  if (tmpdir == NULL)
3545  tmpdir = getenv("TMP");
3546  if (tmpdir == NULL)
3547  tmpdir = getenv("TEMP");
3548 
3549  /* And this is the sane fallback. */
3550  if (tmpdir == NULL)
3551  tmpdir = "/tmp";
3552  }
3553 
3554  _DBUS_UNLOCK (sysdeps);
3555 
3556  _dbus_assert(tmpdir != NULL);
3557 
3558  return tmpdir;
3559 }
3560 
3561 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3562 
3581 static dbus_bool_t
3582 _read_subprocess_line_argv (const char *progpath,
3583  dbus_bool_t path_fallback,
3584  char * const *argv,
3585  DBusString *result,
3586  DBusError *error)
3587 {
3588  int result_pipe[2] = { -1, -1 };
3589  int errors_pipe[2] = { -1, -1 };
3590  pid_t pid;
3591  int ret;
3592  int status;
3593  int orig_len;
3594 
3595  dbus_bool_t retval;
3596  sigset_t new_set, old_set;
3597 
3598  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3599  retval = FALSE;
3600 
3601  /* We need to block any existing handlers for SIGCHLD temporarily; they
3602  * will cause waitpid() below to fail.
3603  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3604  */
3605  sigemptyset (&new_set);
3606  sigaddset (&new_set, SIGCHLD);
3607  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3608 
3609  orig_len = _dbus_string_get_length (result);
3610 
3611 #define READ_END 0
3612 #define WRITE_END 1
3613  if (pipe (result_pipe) < 0)
3614  {
3615  dbus_set_error (error, _dbus_error_from_errno (errno),
3616  "Failed to create a pipe to call %s: %s",
3617  progpath, _dbus_strerror (errno));
3618  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3619  progpath, _dbus_strerror (errno));
3620  goto out;
3621  }
3622  if (pipe (errors_pipe) < 0)
3623  {
3624  dbus_set_error (error, _dbus_error_from_errno (errno),
3625  "Failed to create a pipe to call %s: %s",
3626  progpath, _dbus_strerror (errno));
3627  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3628  progpath, _dbus_strerror (errno));
3629  goto out;
3630  }
3631 
3632  pid = fork ();
3633  if (pid < 0)
3634  {
3635  dbus_set_error (error, _dbus_error_from_errno (errno),
3636  "Failed to fork() to call %s: %s",
3637  progpath, _dbus_strerror (errno));
3638  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3639  progpath, _dbus_strerror (errno));
3640  goto out;
3641  }
3642 
3643  if (pid == 0)
3644  {
3645  /* child process */
3646  int fd;
3647 
3648  fd = open ("/dev/null", O_RDWR);
3649  if (fd == -1)
3650  /* huh?! can't open /dev/null? */
3651  _exit (1);
3652 
3653  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3654 
3655  /* set-up stdXXX */
3656  close (result_pipe[READ_END]);
3657  close (errors_pipe[READ_END]);
3658 
3659  if (dup2 (fd, 0) == -1) /* setup stdin */
3660  _exit (1);
3661  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3662  _exit (1);
3663  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3664  _exit (1);
3665 
3666  _dbus_close_all ();
3667 
3668  sigprocmask (SIG_SETMASK, &old_set, NULL);
3669 
3670  /* If it looks fully-qualified, try execv first */
3671  if (progpath[0] == '/')
3672  {
3673  execv (progpath, argv);
3674  /* Ok, that failed. Now if path_fallback is given, let's
3675  * try unqualified. This is mostly a hack to work
3676  * around systems which ship dbus-launch in /usr/bin
3677  * but everything else in /bin (because dbus-launch
3678  * depends on X11).
3679  */
3680  if (path_fallback)
3681  /* We must have a slash, because we checked above */
3682  execvp (strrchr (progpath, '/')+1, argv);
3683  }
3684  else
3685  execvp (progpath, argv);
3686 
3687  /* still nothing, we failed */
3688  _exit (1);
3689  }
3690 
3691  /* parent process */
3692  close (result_pipe[WRITE_END]);
3693  close (errors_pipe[WRITE_END]);
3694  result_pipe[WRITE_END] = -1;
3695  errors_pipe[WRITE_END] = -1;
3696 
3697  ret = 0;
3698  do
3699  {
3700  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3701  }
3702  while (ret > 0);
3703 
3704  /* reap the child process to avoid it lingering as zombie */
3705  do
3706  {
3707  ret = waitpid (pid, &status, 0);
3708  }
3709  while (ret == -1 && errno == EINTR);
3710 
3711  /* We succeeded if the process exited with status 0 and
3712  anything was read */
3713  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3714  {
3715  /* The process ended with error */
3716  DBusString error_message;
3717  if (!_dbus_string_init (&error_message))
3718  {
3719  _DBUS_SET_OOM (error);
3720  goto out;
3721  }
3722 
3723  ret = 0;
3724  do
3725  {
3726  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3727  }
3728  while (ret > 0);
3729 
3730  _dbus_string_set_length (result, orig_len);
3731  if (_dbus_string_get_length (&error_message) > 0)
3733  "%s terminated abnormally with the following error: %s",
3734  progpath, _dbus_string_get_data (&error_message));
3735  else
3737  "%s terminated abnormally without any error message",
3738  progpath);
3739  goto out;
3740  }
3741 
3742  retval = TRUE;
3743 
3744  out:
3745  sigprocmask (SIG_SETMASK, &old_set, NULL);
3746 
3747  if (retval)
3748  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3749  else
3750  _DBUS_ASSERT_ERROR_IS_SET (error);
3751 
3752  if (result_pipe[0] != -1)
3753  close (result_pipe[0]);
3754  if (result_pipe[1] != -1)
3755  close (result_pipe[1]);
3756  if (errors_pipe[0] != -1)
3757  close (errors_pipe[0]);
3758  if (errors_pipe[1] != -1)
3759  close (errors_pipe[1]);
3760 
3761  return retval;
3762 }
3763 #endif
3764 
3778 _dbus_get_autolaunch_address (const char *scope,
3779  DBusString *address,
3780  DBusError *error)
3781 {
3782 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3783  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3784  * but that's done elsewhere, and if it worked, this function wouldn't
3785  * be called.) */
3786  const char *display;
3787  char *progpath;
3788  char *argv[6];
3789  int i;
3790  DBusString uuid;
3791  dbus_bool_t retval;
3792 
3793  if (_dbus_check_setuid ())
3794  {
3796  "Unable to autolaunch when setuid");
3797  return FALSE;
3798  }
3799 
3800  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3801  retval = FALSE;
3802 
3803  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3804  * dbus-launch-x11 is just going to fail. Rather than trying to
3805  * run it, we might as well bail out early with a nice error.
3806  *
3807  * This is not strictly true in a world where the user bus exists,
3808  * because dbus-launch --autolaunch knows how to connect to that -
3809  * but if we were going to connect to the user bus, we'd have done
3810  * so before trying autolaunch: in any case. */
3811  display = _dbus_getenv ("DISPLAY");
3812 
3813  if (display == NULL || display[0] == '\0')
3814  {
3816  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3817  return FALSE;
3818  }
3819 
3820  if (!_dbus_string_init (&uuid))
3821  {
3822  _DBUS_SET_OOM (error);
3823  return FALSE;
3824  }
3825 
3826  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3827  {
3828  goto out;
3829  }
3830 
3831 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3832  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3833  progpath = TEST_BUS_LAUNCH_BINARY;
3834  else
3835 #endif
3836  progpath = DBUS_BINDIR "/dbus-launch";
3837  /*
3838  * argv[0] is always dbus-launch, that's the name what we'll
3839  * get from /proc, or ps(1), regardless what the progpath is,
3840  * see fd.o#69716
3841  */
3842  i = 0;
3843  argv[i] = "dbus-launch";
3844  ++i;
3845  argv[i] = "--autolaunch";
3846  ++i;
3847  argv[i] = _dbus_string_get_data (&uuid);
3848  ++i;
3849  argv[i] = "--binary-syntax";
3850  ++i;
3851  argv[i] = "--close-stderr";
3852  ++i;
3853  argv[i] = NULL;
3854  ++i;
3855 
3856  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3857 
3858  retval = _read_subprocess_line_argv (progpath,
3859  TRUE,
3860  argv, address, error);
3861 
3862  out:
3863  _dbus_string_free (&uuid);
3864  return retval;
3865 #else
3867  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3868  "set your DBUS_SESSION_BUS_ADDRESS instead");
3869  return FALSE;
3870 #endif
3871 }
3872 
3893  dbus_bool_t create_if_not_found,
3894  DBusError *error)
3895 {
3896  DBusString filename;
3897  dbus_bool_t b;
3898 
3899  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3900 
3901  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3902  if (b)
3903  return TRUE;
3904 
3905  dbus_error_free (error);
3906 
3907  /* Fallback to the system machine ID */
3908  _dbus_string_init_const (&filename, "/etc/machine-id");
3909  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3910 
3911  if (b)
3912  {
3913  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3914  * complain if that isn't possible for whatever reason */
3915  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3916  _dbus_write_uuid_file (&filename, machine_id, NULL);
3917 
3918  return TRUE;
3919  }
3920 
3921  if (!create_if_not_found)
3922  return FALSE;
3923 
3924  /* if none found, try to make a new one */
3925  dbus_error_free (error);
3926  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3927 
3928  if (!_dbus_generate_uuid (machine_id, error))
3929  return FALSE;
3930 
3931  return _dbus_write_uuid_file (&filename, machine_id, error);
3932 }
3933 
3943  const char *launchd_env_var,
3944  DBusError *error)
3945 {
3946 #ifdef DBUS_ENABLE_LAUNCHD
3947  char *argv[4];
3948  int i;
3949 
3950  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3951 
3952  if (_dbus_check_setuid ())
3953  {
3955  "Unable to find launchd socket when setuid");
3956  return FALSE;
3957  }
3958 
3959  i = 0;
3960  argv[i] = "launchctl";
3961  ++i;
3962  argv[i] = "getenv";
3963  ++i;
3964  argv[i] = (char*)launchd_env_var;
3965  ++i;
3966  argv[i] = NULL;
3967  ++i;
3968 
3969  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3970 
3971  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3972  {
3973  return FALSE;
3974  }
3975 
3976  /* no error, but no result either */
3977  if (_dbus_string_get_length(socket_path) == 0)
3978  {
3979  return FALSE;
3980  }
3981 
3982  /* strip the carriage-return */
3983  _dbus_string_shorten(socket_path, 1);
3984  return TRUE;
3985 #else /* DBUS_ENABLE_LAUNCHD */
3987  "can't lookup socket from launchd; launchd support not compiled in");
3988  return FALSE;
3989 #endif
3990 }
3991 
3992 #ifdef DBUS_ENABLE_LAUNCHD
3993 static dbus_bool_t
3994 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3995 {
3996  dbus_bool_t valid_socket;
3997  DBusString socket_path;
3998 
3999  if (_dbus_check_setuid ())
4000  {
4002  "Unable to find launchd socket when setuid");
4003  return FALSE;
4004  }
4005 
4006  if (!_dbus_string_init (&socket_path))
4007  {
4008  _DBUS_SET_OOM (error);
4009  return FALSE;
4010  }
4011 
4012  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4013 
4014  if (dbus_error_is_set(error))
4015  {
4016  _dbus_string_free(&socket_path);
4017  return FALSE;
4018  }
4019 
4020  if (!valid_socket)
4021  {
4022  dbus_set_error(error, "no socket path",
4023  "launchd did not provide a socket path, "
4024  "verify that org.freedesktop.dbus-session.plist is loaded!");
4025  _dbus_string_free(&socket_path);
4026  return FALSE;
4027  }
4028  if (!_dbus_string_append (address, "unix:path="))
4029  {
4030  _DBUS_SET_OOM (error);
4031  _dbus_string_free(&socket_path);
4032  return FALSE;
4033  }
4034  if (!_dbus_string_copy (&socket_path, 0, address,
4035  _dbus_string_get_length (address)))
4036  {
4037  _DBUS_SET_OOM (error);
4038  _dbus_string_free(&socket_path);
4039  return FALSE;
4040  }
4041 
4042  _dbus_string_free(&socket_path);
4043  return TRUE;
4044 }
4045 #endif
4046 
4048 _dbus_lookup_user_bus (dbus_bool_t *supported,
4049  DBusString *address,
4050  DBusError *error)
4051 {
4052  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4053  dbus_bool_t ret = FALSE;
4054  struct stat stbuf;
4055  DBusString user_bus_path;
4056 
4057  if (runtime_dir == NULL)
4058  {
4059  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4060  *supported = FALSE;
4061  return TRUE; /* Cannot use it, but not an error */
4062  }
4063 
4064  if (!_dbus_string_init (&user_bus_path))
4065  {
4066  _DBUS_SET_OOM (error);
4067  return FALSE;
4068  }
4069 
4070  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4071  {
4072  _DBUS_SET_OOM (error);
4073  goto out;
4074  }
4075 
4076  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4077  {
4078  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4079  _dbus_strerror (errno));
4080  *supported = FALSE;
4081  ret = TRUE; /* Cannot use it, but not an error */
4082  goto out;
4083  }
4084 
4085  if (stbuf.st_uid != getuid ())
4086  {
4087  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4088  (long) stbuf.st_uid, (long) getuid ());
4089  *supported = FALSE;
4090  ret = TRUE; /* Cannot use it, but not an error */
4091  goto out;
4092  }
4093 
4094  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4095  {
4096  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4097  (long) stbuf.st_mode);
4098  *supported = FALSE;
4099  ret = TRUE; /* Cannot use it, but not an error */
4100  goto out;
4101  }
4102 
4103  if (!_dbus_string_append (address, "unix:path=") ||
4104  !_dbus_address_append_escaped (address, &user_bus_path))
4105  {
4106  _DBUS_SET_OOM (error);
4107  goto out;
4108  }
4109 
4110  *supported = TRUE;
4111  ret = TRUE;
4112 
4113 out:
4114  _dbus_string_free (&user_bus_path);
4115  return ret;
4116 }
4117 
4139  DBusString *address,
4140  DBusError *error)
4141 {
4142 #ifdef DBUS_ENABLE_LAUNCHD
4143  *supported = TRUE;
4144  return _dbus_lookup_session_address_launchd (address, error);
4145 #else
4146  *supported = FALSE;
4147 
4148  if (!_dbus_lookup_user_bus (supported, address, error))
4149  return FALSE;
4150  else if (*supported)
4151  return TRUE;
4152 
4153  /* On non-Mac Unix platforms, if the session address isn't already
4154  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4155  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4156  * autolaunch: global default; see init_session_address in
4157  * dbus/dbus-bus.c. */
4158  return TRUE;
4159 #endif
4160 }
4161 
4169 void
4171 {
4173 }
4174 
4190  DBusCredentials *credentials)
4191 {
4192  DBusString homedir;
4193  DBusString dotdir;
4194  dbus_uid_t uid;
4195 
4196  _dbus_assert (credentials != NULL);
4198 
4199  if (!_dbus_string_init (&homedir))
4200  return FALSE;
4201 
4202  uid = _dbus_credentials_get_unix_uid (credentials);
4203  _dbus_assert (uid != DBUS_UID_UNSET);
4204 
4205  if (!_dbus_homedir_from_uid (uid, &homedir))
4206  goto failed;
4207 
4208 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4209  {
4210  const char *override;
4211 
4212  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4213  if (override != NULL && *override != '\0')
4214  {
4215  _dbus_string_set_length (&homedir, 0);
4216  if (!_dbus_string_append (&homedir, override))
4217  goto failed;
4218 
4219  _dbus_verbose ("Using fake homedir for testing: %s\n",
4220  _dbus_string_get_const_data (&homedir));
4221  }
4222  else
4223  {
4224  /* Not strictly thread-safe, but if we fail at thread-safety here,
4225  * the worst that will happen is some extra warnings. */
4226  static dbus_bool_t already_warned = FALSE;
4227  if (!already_warned)
4228  {
4229  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
4230  already_warned = TRUE;
4231  }
4232  }
4233  }
4234 #endif
4235 
4236  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4237  if (!_dbus_concat_dir_and_file (&homedir,
4238  &dotdir))
4239  goto failed;
4240 
4241  if (!_dbus_string_copy (&homedir, 0,
4242  directory, _dbus_string_get_length (directory))) {
4243  goto failed;
4244  }
4245 
4246  _dbus_string_free (&homedir);
4247  return TRUE;
4248 
4249  failed:
4250  _dbus_string_free (&homedir);
4251  return FALSE;
4252 }
4253 
4254 //PENDING(kdab) docs
4256 _dbus_daemon_publish_session_bus_address (const char* addr,
4257  const char *scope)
4258 {
4259  return TRUE;
4260 }
4261 
4262 //PENDING(kdab) docs
4263 void
4264 _dbus_daemon_unpublish_session_bus_address (void)
4265 {
4266 
4267 }
4268 
4277 {
4278  return e == EAGAIN || e == EWOULDBLOCK;
4279 }
4280 
4290  DBusError *error)
4291 {
4292  const char *filename_c;
4293 
4294  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4295 
4296  filename_c = _dbus_string_get_const_data (filename);
4297 
4298  if (rmdir (filename_c) != 0)
4299  {
4301  "Failed to remove directory %s: %s\n",
4302  filename_c, _dbus_strerror (errno));
4303  return FALSE;
4304  }
4305 
4306  return TRUE;
4307 }
4308 
4318 {
4319 #ifdef SCM_RIGHTS
4320  union {
4321  struct sockaddr sa;
4322  struct sockaddr_storage storage;
4323  struct sockaddr_un un;
4324  } sa_buf;
4325 
4326  socklen_t sa_len = sizeof(sa_buf);
4327 
4328  _DBUS_ZERO(sa_buf);
4329 
4330  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4331  return FALSE;
4332 
4333  return sa_buf.sa.sa_family == AF_UNIX;
4334 
4335 #else
4336  return FALSE;
4337 
4338 #endif
4339 }
4340 
4345 void
4347 {
4348  int maxfds, i;
4349 
4350 #ifdef __linux__
4351  DIR *d;
4352 
4353  /* On Linux we can optimize this a bit if /proc is available. If it
4354  isn't available, fall back to the brute force way. */
4355 
4356  d = opendir ("/proc/self/fd");
4357  if (d)
4358  {
4359  for (;;)
4360  {
4361  struct dirent buf, *de;
4362  int k, fd;
4363  long l;
4364  char *e = NULL;
4365 
4366  k = readdir_r (d, &buf, &de);
4367  if (k != 0 || !de)
4368  break;
4369 
4370  if (de->d_name[0] == '.')
4371  continue;
4372 
4373  errno = 0;
4374  l = strtol (de->d_name, &e, 10);
4375  if (errno != 0 || e == NULL || *e != '\0')
4376  continue;
4377 
4378  fd = (int) l;
4379  if (fd < 3)
4380  continue;
4381 
4382  if (fd == dirfd (d))
4383  continue;
4384 
4385  close (fd);
4386  }
4387 
4388  closedir (d);
4389  return;
4390  }
4391 #endif
4392 
4393  maxfds = sysconf (_SC_OPEN_MAX);
4394 
4395  /* Pick something reasonable if for some reason sysconf says
4396  * unlimited.
4397  */
4398  if (maxfds < 0)
4399  maxfds = 1024;
4400 
4401  /* close all inherited fds */
4402  for (i = 3; i < maxfds; i++)
4403  close (i);
4404 }
4405 
4417 {
4418  /* TODO: get __libc_enable_secure exported from glibc.
4419  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4420  */
4421 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4422  {
4423  /* See glibc/include/unistd.h */
4424  extern int __libc_enable_secure;
4425  return __libc_enable_secure;
4426  }
4427 #elif defined(HAVE_ISSETUGID)
4428  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4429  return issetugid ();
4430 #else
4431  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4432  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4433 
4434  /* We call into this function from _dbus_threads_init_platform_specific()
4435  * to make sure these are initialized before we start threading. */
4436  static dbus_bool_t check_setuid_initialised;
4437  static dbus_bool_t is_setuid;
4438 
4439  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4440  {
4441 #ifdef HAVE_GETRESUID
4442  if (getresuid (&ruid, &euid, &suid) != 0 ||
4443  getresgid (&rgid, &egid, &sgid) != 0)
4444 #endif /* HAVE_GETRESUID */
4445  {
4446  suid = ruid = getuid ();
4447  sgid = rgid = getgid ();
4448  euid = geteuid ();
4449  egid = getegid ();
4450  }
4451 
4452  check_setuid_initialised = TRUE;
4453  is_setuid = (ruid != euid || ruid != suid ||
4454  rgid != egid || rgid != sgid);
4455 
4456  }
4457  return is_setuid;
4458 #endif
4459 }
4460 
4470  DBusString *address,
4471  DBusError *error)
4472 {
4473  union {
4474  struct sockaddr sa;
4475  struct sockaddr_storage storage;
4476  struct sockaddr_un un;
4477  struct sockaddr_in ipv4;
4478  struct sockaddr_in6 ipv6;
4479  } socket;
4480  char hostip[INET6_ADDRSTRLEN];
4481  int size = sizeof (socket);
4482  DBusString path_str;
4483 
4484  if (getsockname (fd.fd, &socket.sa, &size))
4485  goto err;
4486 
4487  switch (socket.sa.sa_family)
4488  {
4489  case AF_UNIX:
4490  if (socket.un.sun_path[0]=='\0')
4491  {
4492  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4493  if (_dbus_string_append (address, "unix:abstract=") &&
4494  _dbus_address_append_escaped (address, &path_str))
4495  return TRUE;
4496  }
4497  else
4498  {
4499  _dbus_string_init_const (&path_str, socket.un.sun_path);
4500  if (_dbus_string_append (address, "unix:path=") &&
4501  _dbus_address_append_escaped (address, &path_str))
4502  return TRUE;
4503  }
4504  break;
4505  case AF_INET:
4506  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4507  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4508  hostip, ntohs (socket.ipv4.sin_port)))
4509  return TRUE;
4510  break;
4511 #ifdef AF_INET6
4512  case AF_INET6:
4513  _dbus_string_init_const (&path_str, hostip);
4514  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4515  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4516  ntohs (socket.ipv6.sin6_port)) &&
4517  _dbus_address_append_escaped (address, &path_str))
4518  return TRUE;
4519  break;
4520 #endif
4521  default:
4522  dbus_set_error (error,
4523  _dbus_error_from_errno (EINVAL),
4524  "Failed to read address from socket: Unknown socket type.");
4525  return FALSE;
4526  }
4527  err:
4528  dbus_set_error (error,
4529  _dbus_error_from_errno (errno),
4530  "Failed to open socket: %s",
4531  _dbus_strerror (errno));
4532  return FALSE;
4533 }
4534 
4535 int
4536 _dbus_save_socket_errno (void)
4537 {
4538  return errno;
4539 }
4540 
4541 void
4542 _dbus_restore_socket_errno (int saved_errno)
4543 {
4544  errno = saved_errno;
4545 }
4546 
4547 /* 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:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:279
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:392
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:284
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
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:701
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:123
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:119
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.
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:388
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.
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:383
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:112
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:114
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:590
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:105
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
Socket interface.
Definition: dbus-sysdeps.h:148
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:461
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:392
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.
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().
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:116
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 &quot;1&quot;.
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:382
#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; &quot;something went wrong&quot; - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:873
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:121
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.
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.
#define FALSE
Expands to &quot;0&quot;.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
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:875
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:109
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul...
char * _dbus_strdup(const char *str)
Duplicates a string.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:107
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:384
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:394