D-Bus  1.10.22
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  if (m.msg_flags & MSG_CTRUNC)
436  {
437  /* Hmm, apparently the control data was truncated. The bad
438  thing is that we might have completely lost a couple of fds
439  without chance to recover them. Hence let's treat this as a
440  serious error. */
441 
442  errno = ENOSPC;
443  _dbus_string_set_length (buffer, start);
444  return -1;
445  }
446 
447  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
448  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
449  {
450  size_t i;
451  int *payload = (int *) CMSG_DATA (cm);
452  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
453  size_t payload_len_fds = payload_len_bytes / sizeof (int);
454  size_t fds_to_use;
455 
456  /* Every non-negative int fits in a size_t without truncation,
457  * and we already know that *n_fds is non-negative, so
458  * casting (size_t) *n_fds is OK */
459  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
460 
461  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
462  {
463  /* The fds in the payload will fit in our buffer */
464  fds_to_use = payload_len_fds;
465  }
466  else
467  {
468  /* Too many fds in the payload. This shouldn't happen
469  * any more because we're setting m.msg_controllen to
470  * the exact number we can accept, but be safe and
471  * truncate. */
472  fds_to_use = (size_t) *n_fds;
473 
474  /* Close the excess fds to avoid DoS: if they stayed open,
475  * someone could send us an extra fd per message
476  * and we'd eventually run out. */
477  for (i = fds_to_use; i < payload_len_fds; i++)
478  {
479  close (payload[i]);
480  }
481  }
482 
483  memcpy (fds, payload, fds_to_use * sizeof (int));
484  found = TRUE;
485  /* This cannot overflow because we have chosen fds_to_use
486  * to be <= *n_fds */
487  *n_fds = (int) fds_to_use;
488 
489  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
490  worked, hence we need to go through this list and set
491  CLOEXEC everywhere in any case */
492  for (i = 0; i < fds_to_use; i++)
494 
495  break;
496  }
497 
498  if (!found)
499  *n_fds = 0;
500 
501  /* put length back (doesn't actually realloc) */
502  _dbus_string_set_length (buffer, start + bytes_read);
503 
504 #if 0
505  if (bytes_read > 0)
506  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
507 #endif
508 
509  return bytes_read;
510  }
511 #endif
512 }
513 
514 int
515 _dbus_write_socket_with_unix_fds(DBusSocket fd,
516  const DBusString *buffer,
517  int start,
518  int len,
519  const int *fds,
520  int n_fds) {
521 
522 #ifndef HAVE_UNIX_FD_PASSING
523 
524  if (n_fds > 0) {
525  errno = ENOTSUP;
526  return -1;
527  }
528 
529  return _dbus_write_socket(fd, buffer, start, len);
530 #else
531  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
532 #endif
533 }
534 
535 int
536 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
537  const DBusString *buffer1,
538  int start1,
539  int len1,
540  const DBusString *buffer2,
541  int start2,
542  int len2,
543  const int *fds,
544  int n_fds) {
545 
546 #ifndef HAVE_UNIX_FD_PASSING
547 
548  if (n_fds > 0) {
549  errno = ENOTSUP;
550  return -1;
551  }
552 
553  return _dbus_write_socket_two(fd,
554  buffer1, start1, len1,
555  buffer2, start2, len2);
556 #else
557 
558  struct msghdr m;
559  struct cmsghdr *cm;
560  struct iovec iov[2];
561  int bytes_written;
562 
563  _dbus_assert (len1 >= 0);
564  _dbus_assert (len2 >= 0);
565  _dbus_assert (n_fds >= 0);
566 
567  _DBUS_ZERO(iov);
568  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
569  iov[0].iov_len = len1;
570 
571  if (buffer2)
572  {
573  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
574  iov[1].iov_len = len2;
575  }
576 
577  _DBUS_ZERO(m);
578  m.msg_iov = iov;
579  m.msg_iovlen = buffer2 ? 2 : 1;
580 
581  if (n_fds > 0)
582  {
583  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
584  m.msg_control = alloca(m.msg_controllen);
585  memset(m.msg_control, 0, m.msg_controllen);
586 
587  cm = CMSG_FIRSTHDR(&m);
588  cm->cmsg_level = SOL_SOCKET;
589  cm->cmsg_type = SCM_RIGHTS;
590  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
591  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
592  }
593 
594  again:
595 
596  bytes_written = sendmsg (fd.fd, &m, 0
597 #if HAVE_DECL_MSG_NOSIGNAL
598  |MSG_NOSIGNAL
599 #endif
600  );
601 
602  if (bytes_written < 0 && errno == EINTR)
603  goto again;
604 
605 #if 0
606  if (bytes_written > 0)
607  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
608 #endif
609 
610  return bytes_written;
611 #endif
612 }
613 
627 int
629  const DBusString *buffer1,
630  int start1,
631  int len1,
632  const DBusString *buffer2,
633  int start2,
634  int len2)
635 {
636 #if HAVE_DECL_MSG_NOSIGNAL
637  struct iovec vectors[2];
638  const char *data1;
639  const char *data2;
640  int bytes_written;
641  struct msghdr m;
642 
643  _dbus_assert (buffer1 != NULL);
644  _dbus_assert (start1 >= 0);
645  _dbus_assert (start2 >= 0);
646  _dbus_assert (len1 >= 0);
647  _dbus_assert (len2 >= 0);
648 
649  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
650 
651  if (buffer2 != NULL)
652  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
653  else
654  {
655  data2 = NULL;
656  start2 = 0;
657  len2 = 0;
658  }
659 
660  vectors[0].iov_base = (char*) data1;
661  vectors[0].iov_len = len1;
662  vectors[1].iov_base = (char*) data2;
663  vectors[1].iov_len = len2;
664 
665  _DBUS_ZERO(m);
666  m.msg_iov = vectors;
667  m.msg_iovlen = data2 ? 2 : 1;
668 
669  again:
670 
671  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
672 
673  if (bytes_written < 0 && errno == EINTR)
674  goto again;
675 
676  return bytes_written;
677 
678 #else
679  return _dbus_write_two (fd.fd, buffer1, start1, len1,
680  buffer2, start2, len2);
681 #endif
682 }
683 
700 int
701 _dbus_read (int fd,
702  DBusString *buffer,
703  int count)
704 {
705  int bytes_read;
706  int start;
707  char *data;
708 
709  _dbus_assert (count >= 0);
710 
711  start = _dbus_string_get_length (buffer);
712 
713  if (!_dbus_string_lengthen (buffer, count))
714  {
715  errno = ENOMEM;
716  return -1;
717  }
718 
719  data = _dbus_string_get_data_len (buffer, start, count);
720 
721  again:
722 
723  bytes_read = read (fd, data, count);
724 
725  if (bytes_read < 0)
726  {
727  if (errno == EINTR)
728  goto again;
729  else
730  {
731  /* put length back (note that this doesn't actually realloc anything) */
732  _dbus_string_set_length (buffer, start);
733  return -1;
734  }
735  }
736  else
737  {
738  /* put length back (doesn't actually realloc) */
739  _dbus_string_set_length (buffer, start + bytes_read);
740 
741 #if 0
742  if (bytes_read > 0)
743  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
744 #endif
745 
746  return bytes_read;
747  }
748 }
749 
760 int
761 _dbus_write (int fd,
762  const DBusString *buffer,
763  int start,
764  int len)
765 {
766  const char *data;
767  int bytes_written;
768 
769  data = _dbus_string_get_const_data_len (buffer, start, len);
770 
771  again:
772 
773  bytes_written = write (fd, data, len);
774 
775  if (bytes_written < 0 && errno == EINTR)
776  goto again;
777 
778 #if 0
779  if (bytes_written > 0)
780  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
781 #endif
782 
783  return bytes_written;
784 }
785 
806 int
808  const DBusString *buffer1,
809  int start1,
810  int len1,
811  const DBusString *buffer2,
812  int start2,
813  int len2)
814 {
815  _dbus_assert (buffer1 != NULL);
816  _dbus_assert (start1 >= 0);
817  _dbus_assert (start2 >= 0);
818  _dbus_assert (len1 >= 0);
819  _dbus_assert (len2 >= 0);
820 
821 #ifdef HAVE_WRITEV
822  {
823  struct iovec vectors[2];
824  const char *data1;
825  const char *data2;
826  int bytes_written;
827 
828  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
829 
830  if (buffer2 != NULL)
831  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
832  else
833  {
834  data2 = NULL;
835  start2 = 0;
836  len2 = 0;
837  }
838 
839  vectors[0].iov_base = (char*) data1;
840  vectors[0].iov_len = len1;
841  vectors[1].iov_base = (char*) data2;
842  vectors[1].iov_len = len2;
843 
844  again:
845 
846  bytes_written = writev (fd,
847  vectors,
848  data2 ? 2 : 1);
849 
850  if (bytes_written < 0 && errno == EINTR)
851  goto again;
852 
853  return bytes_written;
854  }
855 #else /* HAVE_WRITEV */
856  {
857  int ret1, ret2;
858 
859  ret1 = _dbus_write (fd, buffer1, start1, len1);
860  if (ret1 == len1 && buffer2 != NULL)
861  {
862  ret2 = _dbus_write (fd, buffer2, start2, len2);
863  if (ret2 < 0)
864  ret2 = 0; /* we can't report an error as the first write was OK */
865 
866  return ret1 + ret2;
867  }
868  else
869  return ret1;
870  }
871 #endif /* !HAVE_WRITEV */
872 }
873 
874 #define _DBUS_MAX_SUN_PATH_LENGTH 99
875 
905 int
906 _dbus_connect_unix_socket (const char *path,
907  dbus_bool_t abstract,
908  DBusError *error)
909 {
910  int fd;
911  size_t path_len;
912  struct sockaddr_un addr;
913 
914  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
915 
916  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
917  path, abstract);
918 
919 
920  if (!_dbus_open_unix_socket (&fd, error))
921  {
922  _DBUS_ASSERT_ERROR_IS_SET(error);
923  return -1;
924  }
925  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
926 
927  _DBUS_ZERO (addr);
928  addr.sun_family = AF_UNIX;
929  path_len = strlen (path);
930 
931  if (abstract)
932  {
933 #ifdef HAVE_ABSTRACT_SOCKETS
934  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
935  path_len++; /* Account for the extra nul byte added to the start of sun_path */
936 
937  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
938  {
940  "Abstract socket name too long\n");
941  _dbus_close (fd, NULL);
942  return -1;
943  }
944 
945  strncpy (&addr.sun_path[1], path, path_len);
946  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
947 #else /* HAVE_ABSTRACT_SOCKETS */
949  "Operating system does not support abstract socket namespace\n");
950  _dbus_close (fd, NULL);
951  return -1;
952 #endif /* ! HAVE_ABSTRACT_SOCKETS */
953  }
954  else
955  {
956  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
957  {
959  "Socket name too long\n");
960  _dbus_close (fd, NULL);
961  return -1;
962  }
963 
964  strncpy (addr.sun_path, path, path_len);
965  }
966 
967  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
968  {
969  dbus_set_error (error,
970  _dbus_error_from_errno (errno),
971  "Failed to connect to socket %s: %s",
972  path, _dbus_strerror (errno));
973 
974  _dbus_close (fd, NULL);
975  return -1;
976  }
977 
978  if (!_dbus_set_fd_nonblocking (fd, error))
979  {
980  _DBUS_ASSERT_ERROR_IS_SET (error);
981 
982  _dbus_close (fd, NULL);
983  return -1;
984  }
985 
986  return fd;
987 }
988 
1001 int
1002 _dbus_connect_exec (const char *path,
1003  char *const argv[],
1004  DBusError *error)
1005 {
1006  int fds[2];
1007  pid_t pid;
1008  int retval;
1009  dbus_bool_t cloexec_done = 0;
1010 
1011  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1012 
1013  _dbus_verbose ("connecting to process %s\n", path);
1014 
1015 #ifdef SOCK_CLOEXEC
1016  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1017  cloexec_done = (retval >= 0);
1018 
1019  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1020 #endif
1021  {
1022  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1023  }
1024 
1025  if (retval < 0)
1026  {
1027  dbus_set_error (error,
1028  _dbus_error_from_errno (errno),
1029  "Failed to create socket pair: %s",
1030  _dbus_strerror (errno));
1031  return -1;
1032  }
1033 
1034  if (!cloexec_done)
1035  {
1036  _dbus_fd_set_close_on_exec (fds[0]);
1037  _dbus_fd_set_close_on_exec (fds[1]);
1038  }
1039 
1040  pid = fork ();
1041  if (pid < 0)
1042  {
1043  dbus_set_error (error,
1044  _dbus_error_from_errno (errno),
1045  "Failed to fork() to call %s: %s",
1046  path, _dbus_strerror (errno));
1047  close (fds[0]);
1048  close (fds[1]);
1049  return -1;
1050  }
1051 
1052  if (pid == 0)
1053  {
1054  /* child */
1055  close (fds[0]);
1056 
1057  dup2 (fds[1], STDIN_FILENO);
1058  dup2 (fds[1], STDOUT_FILENO);
1059 
1060  if (fds[1] != STDIN_FILENO &&
1061  fds[1] != STDOUT_FILENO)
1062  close (fds[1]);
1063 
1064  /* Inherit STDERR and the controlling terminal from the
1065  parent */
1066 
1067  _dbus_close_all ();
1068 
1069  execvp (path, argv);
1070 
1071  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1072 
1073  _exit(1);
1074  }
1075 
1076  /* parent */
1077  close (fds[1]);
1078 
1079  if (!_dbus_set_fd_nonblocking (fds[0], error))
1080  {
1081  _DBUS_ASSERT_ERROR_IS_SET (error);
1082 
1083  close (fds[0]);
1084  return -1;
1085  }
1086 
1087  return fds[0];
1088 }
1089 
1107 int
1108 _dbus_listen_unix_socket (const char *path,
1109  dbus_bool_t abstract,
1110  DBusError *error)
1111 {
1112  int listen_fd;
1113  struct sockaddr_un addr;
1114  size_t path_len;
1115 
1116  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1117 
1118  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1119  path, abstract);
1120 
1121  if (!_dbus_open_unix_socket (&listen_fd, error))
1122  {
1123  _DBUS_ASSERT_ERROR_IS_SET(error);
1124  return -1;
1125  }
1126  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1127 
1128  _DBUS_ZERO (addr);
1129  addr.sun_family = AF_UNIX;
1130  path_len = strlen (path);
1131 
1132  if (abstract)
1133  {
1134 #ifdef HAVE_ABSTRACT_SOCKETS
1135  /* remember that abstract names aren't nul-terminated so we rely
1136  * on sun_path being filled in with zeroes above.
1137  */
1138  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1139  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1140 
1141  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1142  {
1144  "Abstract socket name too long\n");
1145  _dbus_close (listen_fd, NULL);
1146  return -1;
1147  }
1148 
1149  strncpy (&addr.sun_path[1], path, path_len);
1150  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1151 #else /* HAVE_ABSTRACT_SOCKETS */
1153  "Operating system does not support abstract socket namespace\n");
1154  _dbus_close (listen_fd, NULL);
1155  return -1;
1156 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1157  }
1158  else
1159  {
1160  /* Discussed security implications of this with Nalin,
1161  * and we couldn't think of where it would kick our ass, but
1162  * it still seems a bit sucky. It also has non-security suckage;
1163  * really we'd prefer to exit if the socket is already in use.
1164  * But there doesn't seem to be a good way to do this.
1165  *
1166  * Just to be extra careful, I threw in the stat() - clearly
1167  * the stat() can't *fix* any security issue, but it at least
1168  * avoids inadvertent/accidental data loss.
1169  */
1170  {
1171  struct stat sb;
1172 
1173  if (stat (path, &sb) == 0 &&
1174  S_ISSOCK (sb.st_mode))
1175  unlink (path);
1176  }
1177 
1178  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1179  {
1181  "Socket name too long\n");
1182  _dbus_close (listen_fd, NULL);
1183  return -1;
1184  }
1185 
1186  strncpy (addr.sun_path, path, path_len);
1187  }
1188 
1189  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1190  {
1191  dbus_set_error (error, _dbus_error_from_errno (errno),
1192  "Failed to bind socket \"%s\": %s",
1193  path, _dbus_strerror (errno));
1194  _dbus_close (listen_fd, NULL);
1195  return -1;
1196  }
1197 
1198  if (listen (listen_fd, 30 /* backlog */) < 0)
1199  {
1200  dbus_set_error (error, _dbus_error_from_errno (errno),
1201  "Failed to listen on socket \"%s\": %s",
1202  path, _dbus_strerror (errno));
1203  _dbus_close (listen_fd, NULL);
1204  return -1;
1205  }
1206 
1207  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1208  {
1209  _DBUS_ASSERT_ERROR_IS_SET (error);
1210  _dbus_close (listen_fd, NULL);
1211  return -1;
1212  }
1213 
1214  /* Try opening up the permissions, but if we can't, just go ahead
1215  * and continue, maybe it will be good enough.
1216  */
1217  if (!abstract && chmod (path, 0777) < 0)
1218  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1219  path);
1220 
1221  return listen_fd;
1222 }
1223 
1234 int
1236  DBusError *error)
1237 {
1238 #ifdef HAVE_SYSTEMD
1239  int r, n;
1240  int fd;
1241  DBusSocket *new_fds;
1242 
1243  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1244 
1245  n = sd_listen_fds (TRUE);
1246  if (n < 0)
1247  {
1249  "Failed to acquire systemd socket: %s",
1250  _dbus_strerror (-n));
1251  return -1;
1252  }
1253 
1254  if (n <= 0)
1255  {
1257  "No socket received.");
1258  return -1;
1259  }
1260 
1261  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1262  {
1263  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1264  if (r < 0)
1265  {
1267  "Failed to verify systemd socket type: %s",
1268  _dbus_strerror (-r));
1269  return -1;
1270  }
1271 
1272  if (!r)
1273  {
1275  "Passed socket has wrong type.");
1276  return -1;
1277  }
1278  }
1279 
1280  /* OK, the file descriptors are all good, so let's take posession of
1281  them then. */
1282 
1283  new_fds = dbus_new (DBusSocket, n);
1284  if (!new_fds)
1285  {
1287  "Failed to allocate file handle array.");
1288  goto fail;
1289  }
1290 
1291  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1292  {
1293  if (!_dbus_set_fd_nonblocking (fd, error))
1294  {
1295  _DBUS_ASSERT_ERROR_IS_SET (error);
1296  goto fail;
1297  }
1298 
1299  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1300  }
1301 
1302  *fds = new_fds;
1303  return n;
1304 
1305  fail:
1306 
1307  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1308  {
1309  _dbus_close (fd, NULL);
1310  }
1311 
1312  dbus_free (new_fds);
1313  return -1;
1314 #else
1316  "dbus was compiled without systemd support");
1317  return -1;
1318 #endif
1319 }
1320 
1334 DBusSocket
1335 _dbus_connect_tcp_socket (const char *host,
1336  const char *port,
1337  const char *family,
1338  DBusError *error)
1339 {
1340  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1341 }
1342 
1343 DBusSocket
1344 _dbus_connect_tcp_socket_with_nonce (const char *host,
1345  const char *port,
1346  const char *family,
1347  const char *noncefile,
1348  DBusError *error)
1349 {
1350  int saved_errno = 0;
1351  DBusSocket fd = DBUS_SOCKET_INIT;
1352  int res;
1353  struct addrinfo hints;
1354  struct addrinfo *ai, *tmp;
1355 
1356  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1357 
1358  _DBUS_ZERO (hints);
1359 
1360  if (!family)
1361  hints.ai_family = AF_UNSPEC;
1362  else if (!strcmp(family, "ipv4"))
1363  hints.ai_family = AF_INET;
1364  else if (!strcmp(family, "ipv6"))
1365  hints.ai_family = AF_INET6;
1366  else
1367  {
1368  dbus_set_error (error,
1370  "Unknown address family %s", family);
1371  return _dbus_socket_get_invalid ();
1372  }
1373  hints.ai_protocol = IPPROTO_TCP;
1374  hints.ai_socktype = SOCK_STREAM;
1375  hints.ai_flags = AI_ADDRCONFIG;
1376 
1377  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1378  {
1379  dbus_set_error (error,
1380  _dbus_error_from_errno (errno),
1381  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1382  host, port, gai_strerror(res), res);
1383  return _dbus_socket_get_invalid ();
1384  }
1385 
1386  tmp = ai;
1387  while (tmp)
1388  {
1389  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1390  {
1391  freeaddrinfo(ai);
1392  _DBUS_ASSERT_ERROR_IS_SET(error);
1393  return _dbus_socket_get_invalid ();
1394  }
1395  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1396 
1397  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1398  {
1399  saved_errno = errno;
1400  _dbus_close (fd.fd, NULL);
1401  fd.fd = -1;
1402  tmp = tmp->ai_next;
1403  continue;
1404  }
1405 
1406  break;
1407  }
1408  freeaddrinfo(ai);
1409 
1410  if (fd.fd == -1)
1411  {
1412  dbus_set_error (error,
1413  _dbus_error_from_errno (saved_errno),
1414  "Failed to connect to socket \"%s:%s\" %s",
1415  host, port, _dbus_strerror(saved_errno));
1416  return _dbus_socket_get_invalid ();
1417  }
1418 
1419  if (noncefile != NULL)
1420  {
1421  DBusString noncefileStr;
1422  dbus_bool_t ret;
1423  _dbus_string_init_const (&noncefileStr, noncefile);
1424  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1425  _dbus_string_free (&noncefileStr);
1426 
1427  if (!ret)
1428  {
1429  _dbus_close (fd.fd, NULL);
1430  return _dbus_socket_get_invalid ();
1431  }
1432  }
1433 
1434  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1435  {
1436  _dbus_close (fd.fd, NULL);
1437  return _dbus_socket_get_invalid ();
1438  }
1439 
1440  return fd;
1441 }
1442 
1459 int
1460 _dbus_listen_tcp_socket (const char *host,
1461  const char *port,
1462  const char *family,
1463  DBusString *retport,
1464  DBusSocket **fds_p,
1465  DBusError *error)
1466 {
1467  int saved_errno;
1468  int nlisten_fd = 0, res, i;
1469  DBusSocket *listen_fd = NULL;
1470  struct addrinfo hints;
1471  struct addrinfo *ai, *tmp;
1472  unsigned int reuseaddr;
1473 
1474  *fds_p = NULL;
1475  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1476 
1477  _DBUS_ZERO (hints);
1478 
1479  if (!family)
1480  hints.ai_family = AF_UNSPEC;
1481  else if (!strcmp(family, "ipv4"))
1482  hints.ai_family = AF_INET;
1483  else if (!strcmp(family, "ipv6"))
1484  hints.ai_family = AF_INET6;
1485  else
1486  {
1487  dbus_set_error (error,
1489  "Unknown address family %s", family);
1490  return -1;
1491  }
1492 
1493  hints.ai_protocol = IPPROTO_TCP;
1494  hints.ai_socktype = SOCK_STREAM;
1495  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1496 
1497  redo_lookup_with_port:
1498  ai = NULL;
1499  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1500  {
1501  dbus_set_error (error,
1502  _dbus_error_from_errno (errno),
1503  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1504  host ? host : "*", port, gai_strerror(res), res);
1505  goto failed;
1506  }
1507 
1508  tmp = ai;
1509  while (tmp)
1510  {
1511  int fd = -1, tcp_nodelay_on;
1512  DBusSocket *newlisten_fd;
1513 
1514  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1515  {
1516  _DBUS_ASSERT_ERROR_IS_SET(error);
1517  goto failed;
1518  }
1519  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1520 
1521  reuseaddr = 1;
1522  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1523  {
1524  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1525  host ? host : "*", port, _dbus_strerror (errno));
1526  }
1527 
1528  /* Nagle's algorithm imposes a huge delay on the initial messages
1529  going over TCP. */
1530  tcp_nodelay_on = 1;
1531  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1532  {
1533  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1534  host ? host : "*", port, _dbus_strerror (errno));
1535  }
1536 
1537  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1538  {
1539  saved_errno = errno;
1540  _dbus_close(fd, NULL);
1541  if (saved_errno == EADDRINUSE)
1542  {
1543  /* Depending on kernel policy, binding to an IPv6 address
1544  might implicitly bind to a corresponding IPv4
1545  address or vice versa, resulting in EADDRINUSE for the
1546  other one (e.g. bindv6only=0 on Linux).
1547 
1548  Also, after we "goto redo_lookup_with_port" after binding
1549  a port on one of the possible addresses, we will
1550  try to bind that same port on every address, including the
1551  same address again for a second time; that one will
1552  also fail with EADDRINUSE.
1553 
1554  For both those reasons, ignore EADDRINUSE here */
1555  tmp = tmp->ai_next;
1556  continue;
1557  }
1558  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1559  "Failed to bind socket \"%s:%s\": %s",
1560  host ? host : "*", port, _dbus_strerror (saved_errno));
1561  goto failed;
1562  }
1563 
1564  if (listen (fd, 30 /* backlog */) < 0)
1565  {
1566  saved_errno = errno;
1567  _dbus_close (fd, NULL);
1568  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1569  "Failed to listen on socket \"%s:%s\": %s",
1570  host ? host : "*", port, _dbus_strerror (saved_errno));
1571  goto failed;
1572  }
1573 
1574  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1575  if (!newlisten_fd)
1576  {
1577  saved_errno = errno;
1578  _dbus_close (fd, NULL);
1579  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1580  "Failed to allocate file handle array: %s",
1581  _dbus_strerror (saved_errno));
1582  goto failed;
1583  }
1584  listen_fd = newlisten_fd;
1585  listen_fd[nlisten_fd].fd = fd;
1586  nlisten_fd++;
1587 
1588  if (!_dbus_string_get_length(retport))
1589  {
1590  /* If the user didn't specify a port, or used 0, then
1591  the kernel chooses a port. After the first address
1592  is bound to, we need to force all remaining addresses
1593  to use the same port */
1594  if (!port || !strcmp(port, "0"))
1595  {
1596  int result;
1597  struct sockaddr_storage addr;
1598  socklen_t addrlen;
1599  char portbuf[50];
1600 
1601  addrlen = sizeof(addr);
1602  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1603 
1604  if (result == -1 ||
1605  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1606  portbuf, sizeof(portbuf),
1607  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1608  {
1609  dbus_set_error (error, _dbus_error_from_errno (errno),
1610  "Failed to resolve port \"%s:%s\": %s (%s)",
1611  host ? host : "*", port, gai_strerror(res), res);
1612  goto failed;
1613  }
1614  if (!_dbus_string_append(retport, portbuf))
1615  {
1617  goto failed;
1618  }
1619 
1620  /* Release current address list & redo lookup */
1621  port = _dbus_string_get_const_data(retport);
1622  freeaddrinfo(ai);
1623  goto redo_lookup_with_port;
1624  }
1625  else
1626  {
1627  if (!_dbus_string_append(retport, port))
1628  {
1630  goto failed;
1631  }
1632  }
1633  }
1634 
1635  tmp = tmp->ai_next;
1636  }
1637  freeaddrinfo(ai);
1638  ai = NULL;
1639 
1640  if (!nlisten_fd)
1641  {
1642  errno = EADDRINUSE;
1643  dbus_set_error (error, _dbus_error_from_errno (errno),
1644  "Failed to bind socket \"%s:%s\": %s",
1645  host ? host : "*", port, _dbus_strerror (errno));
1646  goto failed;
1647  }
1648 
1649  for (i = 0 ; i < nlisten_fd ; i++)
1650  {
1651  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1652  {
1653  goto failed;
1654  }
1655  }
1656 
1657  *fds_p = listen_fd;
1658 
1659  return nlisten_fd;
1660 
1661  failed:
1662  if (ai)
1663  freeaddrinfo(ai);
1664  for (i = 0 ; i < nlisten_fd ; i++)
1665  _dbus_close(listen_fd[i].fd, NULL);
1666  dbus_free(listen_fd);
1667  return -1;
1668 }
1669 
1670 static dbus_bool_t
1671 write_credentials_byte (int server_fd,
1672  DBusError *error)
1673 {
1674  int bytes_written;
1675  char buf[1] = { '\0' };
1676 #if defined(HAVE_CMSGCRED)
1677  union {
1678  struct cmsghdr hdr;
1679  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1680  } cmsg;
1681  struct iovec iov;
1682  struct msghdr msg;
1683  iov.iov_base = buf;
1684  iov.iov_len = 1;
1685 
1686  _DBUS_ZERO(msg);
1687  msg.msg_iov = &iov;
1688  msg.msg_iovlen = 1;
1689 
1690  msg.msg_control = (caddr_t) &cmsg;
1691  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1692  _DBUS_ZERO(cmsg);
1693  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1694  cmsg.hdr.cmsg_level = SOL_SOCKET;
1695  cmsg.hdr.cmsg_type = SCM_CREDS;
1696 #endif
1697 
1698  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1699 
1700  again:
1701 
1702 #if defined(HAVE_CMSGCRED)
1703  bytes_written = sendmsg (server_fd, &msg, 0
1704 #if HAVE_DECL_MSG_NOSIGNAL
1705  |MSG_NOSIGNAL
1706 #endif
1707  );
1708 
1709  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1710  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1711  * only allows that on AF_UNIX. Try just doing a send() instead. */
1712  if (bytes_written < 0 && errno == EINVAL)
1713 #endif
1714  {
1715  bytes_written = send (server_fd, buf, 1, 0
1716 #if HAVE_DECL_MSG_NOSIGNAL
1717  |MSG_NOSIGNAL
1718 #endif
1719  );
1720  }
1721 
1722  if (bytes_written < 0 && errno == EINTR)
1723  goto again;
1724 
1725  if (bytes_written < 0)
1726  {
1727  dbus_set_error (error, _dbus_error_from_errno (errno),
1728  "Failed to write credentials byte: %s",
1729  _dbus_strerror (errno));
1730  return FALSE;
1731  }
1732  else if (bytes_written == 0)
1733  {
1735  "wrote zero bytes writing credentials byte");
1736  return FALSE;
1737  }
1738  else
1739  {
1740  _dbus_assert (bytes_written == 1);
1741  _dbus_verbose ("wrote credentials byte\n");
1742  return TRUE;
1743  }
1744 }
1745 
1746 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1747 static dbus_bool_t
1748 add_linux_security_label_to_credentials (int client_fd,
1749  DBusCredentials *credentials)
1750 {
1751 #if defined(__linux__) && defined(SO_PEERSEC)
1752  DBusString buf;
1753  socklen_t len = 1024;
1754  dbus_bool_t oom = FALSE;
1755 
1756  if (!_dbus_string_init_preallocated (&buf, len) ||
1757  !_dbus_string_set_length (&buf, len))
1758  return FALSE;
1759 
1760  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1761  _dbus_string_get_data (&buf), &len) < 0)
1762  {
1763  int e = errno;
1764 
1765  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1766  _dbus_strerror (e), (unsigned long) len);
1767 
1768  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1769  {
1770  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1771  _dbus_strerror (e));
1772  goto out;
1773  }
1774 
1775  /* If not enough space, len is updated to be enough.
1776  * Try again with a large enough buffer. */
1777  if (!_dbus_string_set_length (&buf, len))
1778  {
1779  oom = TRUE;
1780  goto out;
1781  }
1782 
1783  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1784  }
1785 
1786  if (len <= 0)
1787  {
1788  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1789  (unsigned long) len);
1790  goto out;
1791  }
1792 
1793  if (len > _dbus_string_get_length_uint (&buf))
1794  {
1795  _dbus_verbose ("%lu > %u", (unsigned long) len,
1796  _dbus_string_get_length_uint (&buf));
1797  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1798  }
1799 
1800  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1801  {
1802  /* the kernel included the trailing \0 in its count,
1803  * but DBusString always has an extra \0 after the data anyway */
1804  _dbus_verbose ("subtracting trailing \\0\n");
1805  len--;
1806  }
1807 
1808  if (!_dbus_string_set_length (&buf, len))
1809  {
1810  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1811  oom = TRUE;
1812  goto out;
1813  }
1814 
1815  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1816  {
1817  /* LSM people on the linux-security-module@ mailing list say this
1818  * should never happen: the label should be a bytestring with
1819  * an optional trailing \0 */
1820  _dbus_verbose ("security label from kernel had an embedded \\0, "
1821  "ignoring it\n");
1822  goto out;
1823  }
1824 
1825  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1826  (unsigned long) len,
1827  _dbus_string_get_const_data (&buf));
1828 
1830  _dbus_string_get_const_data (&buf)))
1831  {
1832  oom = TRUE;
1833  goto out;
1834  }
1835 
1836 out:
1837  _dbus_string_free (&buf);
1838  return !oom;
1839 #else
1840  /* no error */
1841  return TRUE;
1842 #endif
1843 }
1844 
1887  DBusCredentials *credentials,
1888  DBusError *error)
1889 {
1890  struct msghdr msg;
1891  struct iovec iov;
1892  char buf;
1893  dbus_uid_t uid_read;
1894  dbus_pid_t pid_read;
1895  int bytes_read;
1896 
1897 #ifdef HAVE_CMSGCRED
1898  union {
1899  struct cmsghdr hdr;
1900  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1901  } cmsg;
1902 #endif
1903 
1904  /* The POSIX spec certainly doesn't promise this, but
1905  * we need these assertions to fail as soon as we're wrong about
1906  * it so we can do the porting fixups
1907  */
1908  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1909  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1910  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1911 
1912  uid_read = DBUS_UID_UNSET;
1913  pid_read = DBUS_PID_UNSET;
1914 
1915  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1916 
1917  _dbus_credentials_clear (credentials);
1918 
1919  iov.iov_base = &buf;
1920  iov.iov_len = 1;
1921 
1922  _DBUS_ZERO(msg);
1923  msg.msg_iov = &iov;
1924  msg.msg_iovlen = 1;
1925 
1926 #if defined(HAVE_CMSGCRED)
1927  _DBUS_ZERO(cmsg);
1928  msg.msg_control = (caddr_t) &cmsg;
1929  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1930 #endif
1931 
1932  again:
1933  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1934 
1935  if (bytes_read < 0)
1936  {
1937  if (errno == EINTR)
1938  goto again;
1939 
1940  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1941  * normally only call read_credentials if the socket was ready
1942  * for reading
1943  */
1944 
1945  dbus_set_error (error, _dbus_error_from_errno (errno),
1946  "Failed to read credentials byte: %s",
1947  _dbus_strerror (errno));
1948  return FALSE;
1949  }
1950  else if (bytes_read == 0)
1951  {
1952  /* this should not happen unless we are using recvmsg wrong,
1953  * so is essentially here for paranoia
1954  */
1956  "Failed to read credentials byte (zero-length read)");
1957  return FALSE;
1958  }
1959  else if (buf != '\0')
1960  {
1962  "Credentials byte was not nul");
1963  return FALSE;
1964  }
1965 
1966  _dbus_verbose ("read credentials byte\n");
1967 
1968  {
1969 #ifdef SO_PEERCRED
1970  /* Supported by at least Linux and OpenBSD, with minor differences.
1971  *
1972  * This mechanism passes the process ID through and does not require
1973  * the peer's cooperation, so we prefer it over all others. Notably,
1974  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1975  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1976  * because this is much less fragile.
1977  */
1978 #ifdef __OpenBSD__
1979  struct sockpeercred cr;
1980 #else
1981  struct ucred cr;
1982 #endif
1983  int cr_len = sizeof (cr);
1984 
1985  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
1986  {
1987  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
1988  _dbus_strerror (errno));
1989  }
1990  else if (cr_len != sizeof (cr))
1991  {
1992  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
1993  cr_len, (int) sizeof (cr));
1994  }
1995  else
1996  {
1997  pid_read = cr.pid;
1998  uid_read = cr.uid;
1999  }
2000 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2001  /* Another variant of the above - used on NetBSD
2002  */
2003  struct unpcbid cr;
2004  socklen_t cr_len = sizeof (cr);
2005 
2006  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2007  {
2008  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2009  _dbus_strerror (errno));
2010  }
2011  else if (cr_len != sizeof (cr))
2012  {
2013  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2014  cr_len, (int) sizeof (cr));
2015  }
2016  else
2017  {
2018  pid_read = cr.unp_pid;
2019  uid_read = cr.unp_euid;
2020  }
2021 #elif defined(HAVE_CMSGCRED)
2022  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2023  * presence of that struct implies SCM_CREDS. Supported by at least
2024  * FreeBSD and DragonflyBSD.
2025  *
2026  * This mechanism requires the peer to help us (it has to send us a
2027  * SCM_CREDS message) but it does pass the process ID through,
2028  * which makes it better than getpeereid().
2029  */
2030  struct cmsgcred *cred;
2031  struct cmsghdr *cmsgp;
2032 
2033  for (cmsgp = CMSG_FIRSTHDR (&msg);
2034  cmsgp != NULL;
2035  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2036  {
2037  if (cmsgp->cmsg_type == SCM_CREDS &&
2038  cmsgp->cmsg_level == SOL_SOCKET &&
2039  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2040  {
2041  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2042  pid_read = cred->cmcred_pid;
2043  uid_read = cred->cmcred_euid;
2044  break;
2045  }
2046  }
2047 
2048 #elif defined(HAVE_GETPEERUCRED)
2049  /* Supported in at least Solaris >= 10. It should probably be higher
2050  * up this list, because it carries the pid and we use this code path
2051  * for audit data. */
2052  ucred_t * ucred = NULL;
2053  if (getpeerucred (client_fd.fd, &ucred) == 0)
2054  {
2055  pid_read = ucred_getpid (ucred);
2056  uid_read = ucred_geteuid (ucred);
2057 #ifdef HAVE_ADT
2058  /* generate audit session data based on socket ucred */
2059  adt_session_data_t *adth = NULL;
2060  adt_export_data_t *data = NULL;
2061  size_t size = 0;
2062  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2063  {
2064  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2065  }
2066  else
2067  {
2068  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2069  {
2070  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2071  }
2072  else
2073  {
2074  size = adt_export_session_data (adth, &data);
2075  if (size <= 0)
2076  {
2077  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2078  }
2079  else
2080  {
2081  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2082  free (data);
2083  }
2084  }
2085  (void) adt_end_session (adth);
2086  }
2087 #endif /* HAVE_ADT */
2088  }
2089  else
2090  {
2091  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2092  }
2093  if (ucred != NULL)
2094  ucred_free (ucred);
2095 
2096  /* ----------------------------------------------------------------
2097  * When adding new mechanisms, please add them above this point
2098  * if they support passing the process ID through, or below if not.
2099  * ---------------------------------------------------------------- */
2100 
2101 #elif defined(HAVE_GETPEEREID)
2102  /* getpeereid() originates from D.J. Bernstein and is fairly
2103  * widely-supported. According to a web search, it might be present in
2104  * any/all of:
2105  *
2106  * - AIX?
2107  * - Blackberry?
2108  * - Cygwin
2109  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2110  * - Mac OS X
2111  * - Minix 3.1.8+
2112  * - MirBSD?
2113  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2114  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2115  * - QNX?
2116  */
2117  uid_t euid;
2118  gid_t egid;
2119  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2120  {
2121  uid_read = euid;
2122  }
2123  else
2124  {
2125  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2126  }
2127 #else /* no supported mechanism */
2128 
2129 #warning Socket credentials not supported on this Unix OS
2130 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2131 
2132  /* Please add other operating systems known to support at least one of
2133  * the mechanisms above to this list, keeping alphabetical order.
2134  * Everything not in this list is best-effort.
2135  */
2136 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2137  defined(__linux__) || \
2138  defined(__OpenBSD__) || \
2139  defined(__NetBSD__)
2140 # error Credentials passing not working on this OS is a regression!
2141 #endif
2142 
2143  _dbus_verbose ("Socket credentials not supported on this OS\n");
2144 #endif
2145  }
2146 
2147  _dbus_verbose ("Credentials:"
2148  " pid "DBUS_PID_FORMAT
2149  " uid "DBUS_UID_FORMAT
2150  "\n",
2151  pid_read,
2152  uid_read);
2153 
2154  if (pid_read != DBUS_PID_UNSET)
2155  {
2156  if (!_dbus_credentials_add_pid (credentials, pid_read))
2157  {
2158  _DBUS_SET_OOM (error);
2159  return FALSE;
2160  }
2161  }
2162 
2163  if (uid_read != DBUS_UID_UNSET)
2164  {
2165  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2166  {
2167  _DBUS_SET_OOM (error);
2168  return FALSE;
2169  }
2170  }
2171 
2172  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2173  {
2174  _DBUS_SET_OOM (error);
2175  return FALSE;
2176  }
2177 
2178  return TRUE;
2179 }
2180 
2200  DBusError *error)
2201 {
2202  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2203 
2204  if (write_credentials_byte (server_fd.fd, error))
2205  return TRUE;
2206  else
2207  return FALSE;
2208 }
2209 
2219 DBusSocket
2221 {
2222  DBusSocket client_fd;
2223  struct sockaddr addr;
2224  socklen_t addrlen;
2225 #ifdef HAVE_ACCEPT4
2226  dbus_bool_t cloexec_done;
2227 #endif
2228 
2229  addrlen = sizeof (addr);
2230 
2231  retry:
2232 
2233 #ifdef HAVE_ACCEPT4
2234  /*
2235  * At compile-time, we assume that if accept4() is available in
2236  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2237  * not necessarily true that either is supported by the running kernel.
2238  */
2239  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2240  cloexec_done = client_fd.fd >= 0;
2241 
2242  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2243 #endif
2244  {
2245  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2246  }
2247 
2248  if (client_fd.fd < 0)
2249  {
2250  if (errno == EINTR)
2251  goto retry;
2252  }
2253 
2254  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2255 
2256 #ifdef HAVE_ACCEPT4
2257  if (!cloexec_done)
2258 #endif
2259  {
2260  _dbus_fd_set_close_on_exec(client_fd.fd);
2261  }
2262 
2263  return client_fd;
2264 }
2265 
2276 {
2277  const char *directory;
2278  struct stat sb;
2279 
2280  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2281 
2282  directory = _dbus_string_get_const_data (dir);
2283 
2284  if (stat (directory, &sb) < 0)
2285  {
2286  dbus_set_error (error, _dbus_error_from_errno (errno),
2287  "%s", _dbus_strerror (errno));
2288 
2289  return FALSE;
2290  }
2291 
2292  if (sb.st_uid != geteuid ())
2293  {
2295  "%s directory is owned by user %lu, not %lu",
2296  directory,
2297  (unsigned long) sb.st_uid,
2298  (unsigned long) geteuid ());
2299  return FALSE;
2300  }
2301 
2302  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2303  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2304  {
2306  "%s directory is not private to the user", directory);
2307  return FALSE;
2308  }
2309 
2310  return TRUE;
2311 }
2312 
2313 static dbus_bool_t
2314 fill_user_info_from_passwd (struct passwd *p,
2315  DBusUserInfo *info,
2316  DBusError *error)
2317 {
2318  _dbus_assert (p->pw_name != NULL);
2319  _dbus_assert (p->pw_dir != NULL);
2320 
2321  info->uid = p->pw_uid;
2322  info->primary_gid = p->pw_gid;
2323  info->username = _dbus_strdup (p->pw_name);
2324  info->homedir = _dbus_strdup (p->pw_dir);
2325 
2326  if (info->username == NULL ||
2327  info->homedir == NULL)
2328  {
2330  return FALSE;
2331  }
2332 
2333  return TRUE;
2334 }
2335 
2336 static dbus_bool_t
2337 fill_user_info (DBusUserInfo *info,
2338  dbus_uid_t uid,
2339  const DBusString *username,
2340  DBusError *error)
2341 {
2342  const char *username_c;
2343 
2344  /* exactly one of username/uid provided */
2345  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2346  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2347 
2348  info->uid = DBUS_UID_UNSET;
2349  info->primary_gid = DBUS_GID_UNSET;
2350  info->group_ids = NULL;
2351  info->n_group_ids = 0;
2352  info->username = NULL;
2353  info->homedir = NULL;
2354 
2355  if (username != NULL)
2356  username_c = _dbus_string_get_const_data (username);
2357  else
2358  username_c = NULL;
2359 
2360  /* For now assuming that the getpwnam() and getpwuid() flavors
2361  * are always symmetrical, if not we have to add more configure
2362  * checks
2363  */
2364 
2365 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2366  {
2367  struct passwd *p;
2368  int result;
2369  size_t buflen;
2370  char *buf;
2371  struct passwd p_str;
2372 
2373  /* retrieve maximum needed size for buf */
2374  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2375 
2376  /* sysconf actually returns a long, but everything else expects size_t,
2377  * so just recast here.
2378  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2379  */
2380  if ((long) buflen <= 0)
2381  buflen = 1024;
2382 
2383  result = -1;
2384  while (1)
2385  {
2386  buf = dbus_malloc (buflen);
2387  if (buf == NULL)
2388  {
2390  return FALSE;
2391  }
2392 
2393  p = NULL;
2394 #ifdef HAVE_POSIX_GETPWNAM_R
2395  if (uid != DBUS_UID_UNSET)
2396  result = getpwuid_r (uid, &p_str, buf, buflen,
2397  &p);
2398  else
2399  result = getpwnam_r (username_c, &p_str, buf, buflen,
2400  &p);
2401 #else
2402  if (uid != DBUS_UID_UNSET)
2403  p = getpwuid_r (uid, &p_str, buf, buflen);
2404  else
2405  p = getpwnam_r (username_c, &p_str, buf, buflen);
2406  result = 0;
2407 #endif /* !HAVE_POSIX_GETPWNAM_R */
2408  //Try a bigger buffer if ERANGE was returned
2409  if (result == ERANGE && buflen < 512 * 1024)
2410  {
2411  dbus_free (buf);
2412  buflen *= 2;
2413  }
2414  else
2415  {
2416  break;
2417  }
2418  }
2419  if (result == 0 && p == &p_str)
2420  {
2421  if (!fill_user_info_from_passwd (p, info, error))
2422  {
2423  dbus_free (buf);
2424  return FALSE;
2425  }
2426  dbus_free (buf);
2427  }
2428  else
2429  {
2430  dbus_set_error (error, _dbus_error_from_errno (errno),
2431  "User \"%s\" unknown or no memory to allocate password entry\n",
2432  username_c ? username_c : "???");
2433  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2434  dbus_free (buf);
2435  return FALSE;
2436  }
2437  }
2438 #else /* ! HAVE_GETPWNAM_R */
2439  {
2440  /* I guess we're screwed on thread safety here */
2441  struct passwd *p;
2442 
2443  if (uid != DBUS_UID_UNSET)
2444  p = getpwuid (uid);
2445  else
2446  p = getpwnam (username_c);
2447 
2448  if (p != NULL)
2449  {
2450  if (!fill_user_info_from_passwd (p, info, error))
2451  {
2452  return FALSE;
2453  }
2454  }
2455  else
2456  {
2457  dbus_set_error (error, _dbus_error_from_errno (errno),
2458  "User \"%s\" unknown or no memory to allocate password entry\n",
2459  username_c ? username_c : "???");
2460  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2461  return FALSE;
2462  }
2463  }
2464 #endif /* ! HAVE_GETPWNAM_R */
2465 
2466  /* Fill this in so we can use it to get groups */
2467  username_c = info->username;
2468 
2469 #ifdef HAVE_GETGROUPLIST
2470  {
2471  gid_t *buf;
2472  int buf_count;
2473  int i;
2474  int initial_buf_count;
2475 
2476  initial_buf_count = 17;
2477  buf_count = initial_buf_count;
2478  buf = dbus_new (gid_t, buf_count);
2479  if (buf == NULL)
2480  {
2482  goto failed;
2483  }
2484 
2485  if (getgrouplist (username_c,
2486  info->primary_gid,
2487  buf, &buf_count) < 0)
2488  {
2489  gid_t *new;
2490  /* Presumed cause of negative return code: buf has insufficient
2491  entries to hold the entire group list. The Linux behavior in this
2492  case is to pass back the actual number of groups in buf_count, but
2493  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2494  So as a hack, try to help out a bit by guessing a larger
2495  number of groups, within reason.. might still fail, of course,
2496  but we can at least print a more informative message. I looked up
2497  the "right way" to do this by downloading Apple's own source code
2498  for the "id" command, and it turns out that they use an
2499  undocumented library function getgrouplist_2 (!) which is not
2500  declared in any header in /usr/include (!!). That did not seem
2501  like the way to go here.
2502  */
2503  if (buf_count == initial_buf_count)
2504  {
2505  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2506  }
2507  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2508  if (new == NULL)
2509  {
2511  dbus_free (buf);
2512  goto failed;
2513  }
2514 
2515  buf = new;
2516 
2517  errno = 0;
2518  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2519  {
2520  if (errno == 0)
2521  {
2522  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2523  username_c, buf_count, buf_count);
2524  }
2525  else
2526  {
2527  dbus_set_error (error,
2528  _dbus_error_from_errno (errno),
2529  "Failed to get groups for username \"%s\" primary GID "
2530  DBUS_GID_FORMAT ": %s\n",
2531  username_c, info->primary_gid,
2532  _dbus_strerror (errno));
2533  dbus_free (buf);
2534  goto failed;
2535  }
2536  }
2537  }
2538 
2539  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2540  if (info->group_ids == NULL)
2541  {
2543  dbus_free (buf);
2544  goto failed;
2545  }
2546 
2547  for (i = 0; i < buf_count; ++i)
2548  info->group_ids[i] = buf[i];
2549 
2550  info->n_group_ids = buf_count;
2551 
2552  dbus_free (buf);
2553  }
2554 #else /* HAVE_GETGROUPLIST */
2555  {
2556  /* We just get the one group ID */
2557  info->group_ids = dbus_new (dbus_gid_t, 1);
2558  if (info->group_ids == NULL)
2559  {
2561  goto failed;
2562  }
2563 
2564  info->n_group_ids = 1;
2565 
2566  (info->group_ids)[0] = info->primary_gid;
2567  }
2568 #endif /* HAVE_GETGROUPLIST */
2569 
2570  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2571 
2572  return TRUE;
2573 
2574  failed:
2575  _DBUS_ASSERT_ERROR_IS_SET (error);
2576  return FALSE;
2577 }
2578 
2589  const DBusString *username,
2590  DBusError *error)
2591 {
2592  return fill_user_info (info, DBUS_UID_UNSET,
2593  username, error);
2594 }
2595 
2606  dbus_uid_t uid,
2607  DBusError *error)
2608 {
2609  return fill_user_info (info, uid,
2610  NULL, error);
2611 }
2612 
2622 {
2623  /* The POSIX spec certainly doesn't promise this, but
2624  * we need these assertions to fail as soon as we're wrong about
2625  * it so we can do the porting fixups
2626  */
2627  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2628  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2629  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2630 
2631  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2632  return FALSE;
2633  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2634  return FALSE;
2635 
2636  return TRUE;
2637 }
2638 
2652 {
2653  return _dbus_string_append_uint (str,
2654  _dbus_geteuid ());
2655 }
2656 
2661 dbus_pid_t
2663 {
2664  return getpid ();
2665 }
2666 
2670 dbus_uid_t
2672 {
2673  return getuid ();
2674 }
2675 
2679 dbus_uid_t
2681 {
2682  return geteuid ();
2683 }
2684 
2691 unsigned long
2693 {
2694  return getpid ();
2695 }
2696 
2705 _dbus_parse_uid (const DBusString *uid_str,
2706  dbus_uid_t *uid)
2707 {
2708  int end;
2709  long val;
2710 
2711  if (_dbus_string_get_length (uid_str) == 0)
2712  {
2713  _dbus_verbose ("UID string was zero length\n");
2714  return FALSE;
2715  }
2716 
2717  val = -1;
2718  end = 0;
2719  if (!_dbus_string_parse_int (uid_str, 0, &val,
2720  &end))
2721  {
2722  _dbus_verbose ("could not parse string as a UID\n");
2723  return FALSE;
2724  }
2725 
2726  if (end != _dbus_string_get_length (uid_str))
2727  {
2728  _dbus_verbose ("string contained trailing stuff after UID\n");
2729  return FALSE;
2730  }
2731 
2732  *uid = val;
2733 
2734  return TRUE;
2735 }
2736 
2737 #if !DBUS_USE_SYNC
2738 /* To be thread-safe by default on platforms that don't necessarily have
2739  * atomic operations (notably Debian armel, which is armv4t), we must
2740  * use a mutex that can be initialized statically, like this.
2741  * GLib >= 2.32 uses a similar system.
2742  */
2743 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2744 #endif
2745 
2752 dbus_int32_t
2754 {
2755 #if DBUS_USE_SYNC
2756  return __sync_add_and_fetch(&atomic->value, 1)-1;
2757 #else
2758  dbus_int32_t res;
2759 
2760  pthread_mutex_lock (&atomic_mutex);
2761  res = atomic->value;
2762  atomic->value += 1;
2763  pthread_mutex_unlock (&atomic_mutex);
2764 
2765  return res;
2766 #endif
2767 }
2768 
2775 dbus_int32_t
2777 {
2778 #if DBUS_USE_SYNC
2779  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2780 #else
2781  dbus_int32_t res;
2782 
2783  pthread_mutex_lock (&atomic_mutex);
2784  res = atomic->value;
2785  atomic->value -= 1;
2786  pthread_mutex_unlock (&atomic_mutex);
2787 
2788  return res;
2789 #endif
2790 }
2791 
2799 dbus_int32_t
2801 {
2802 #if DBUS_USE_SYNC
2803  __sync_synchronize ();
2804  return atomic->value;
2805 #else
2806  dbus_int32_t res;
2807 
2808  pthread_mutex_lock (&atomic_mutex);
2809  res = atomic->value;
2810  pthread_mutex_unlock (&atomic_mutex);
2811 
2812  return res;
2813 #endif
2814 }
2815 
2824 int
2826  int n_fds,
2827  int timeout_milliseconds)
2828 {
2829 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2830  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2831  if (timeout_milliseconds < -1)
2832  {
2833  timeout_milliseconds = -1;
2834  }
2835 
2836  return poll (fds,
2837  n_fds,
2838  timeout_milliseconds);
2839 #else /* ! HAVE_POLL */
2840  /* Emulate poll() in terms of select() */
2841  fd_set read_set, write_set, err_set;
2842  int max_fd = 0;
2843  int i;
2844  struct timeval tv;
2845  int ready;
2846 
2847  FD_ZERO (&read_set);
2848  FD_ZERO (&write_set);
2849  FD_ZERO (&err_set);
2850 
2851  for (i = 0; i < n_fds; i++)
2852  {
2853  DBusPollFD *fdp = &fds[i];
2854 
2855  if (fdp->events & _DBUS_POLLIN)
2856  FD_SET (fdp->fd, &read_set);
2857 
2858  if (fdp->events & _DBUS_POLLOUT)
2859  FD_SET (fdp->fd, &write_set);
2860 
2861  FD_SET (fdp->fd, &err_set);
2862 
2863  max_fd = MAX (max_fd, fdp->fd);
2864  }
2865 
2866  tv.tv_sec = timeout_milliseconds / 1000;
2867  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2868 
2869  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2870  timeout_milliseconds < 0 ? NULL : &tv);
2871 
2872  if (ready > 0)
2873  {
2874  for (i = 0; i < n_fds; i++)
2875  {
2876  DBusPollFD *fdp = &fds[i];
2877 
2878  fdp->revents = 0;
2879 
2880  if (FD_ISSET (fdp->fd, &read_set))
2881  fdp->revents |= _DBUS_POLLIN;
2882 
2883  if (FD_ISSET (fdp->fd, &write_set))
2884  fdp->revents |= _DBUS_POLLOUT;
2885 
2886  if (FD_ISSET (fdp->fd, &err_set))
2887  fdp->revents |= _DBUS_POLLERR;
2888  }
2889  }
2890 
2891  return ready;
2892 #endif
2893 }
2894 
2902 void
2904  long *tv_usec)
2905 {
2906 #ifdef HAVE_MONOTONIC_CLOCK
2907  struct timespec ts;
2908  clock_gettime (CLOCK_MONOTONIC, &ts);
2909 
2910  if (tv_sec)
2911  *tv_sec = ts.tv_sec;
2912  if (tv_usec)
2913  *tv_usec = ts.tv_nsec / 1000;
2914 #else
2915  struct timeval t;
2916 
2917  gettimeofday (&t, NULL);
2918 
2919  if (tv_sec)
2920  *tv_sec = t.tv_sec;
2921  if (tv_usec)
2922  *tv_usec = t.tv_usec;
2923 #endif
2924 }
2925 
2933 void
2934 _dbus_get_real_time (long *tv_sec,
2935  long *tv_usec)
2936 {
2937  struct timeval t;
2938 
2939  gettimeofday (&t, NULL);
2940 
2941  if (tv_sec)
2942  *tv_sec = t.tv_sec;
2943  if (tv_usec)
2944  *tv_usec = t.tv_usec;
2945 }
2946 
2957  DBusError *error)
2958 {
2959  const char *filename_c;
2960 
2961  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2962 
2963  filename_c = _dbus_string_get_const_data (filename);
2964 
2965  if (mkdir (filename_c, 0700) < 0)
2966  {
2967  if (errno == EEXIST)
2968  return TRUE;
2969 
2971  "Failed to create directory %s: %s\n",
2972  filename_c, _dbus_strerror (errno));
2973  return FALSE;
2974  }
2975  else
2976  return TRUE;
2977 }
2978 
2989  DBusError *error)
2990 {
2991  const char *filename_c;
2992 
2993  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2994 
2995  filename_c = _dbus_string_get_const_data (filename);
2996 
2997  if (mkdir (filename_c, 0700) < 0)
2998  {
3000  "Failed to create directory %s: %s\n",
3001  filename_c, _dbus_strerror (errno));
3002  return FALSE;
3003  }
3004  else
3005  return TRUE;
3006 }
3007 
3020  const DBusString *next_component)
3021 {
3022  dbus_bool_t dir_ends_in_slash;
3023  dbus_bool_t file_starts_with_slash;
3024 
3025  if (_dbus_string_get_length (dir) == 0 ||
3026  _dbus_string_get_length (next_component) == 0)
3027  return TRUE;
3028 
3029  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3030  _dbus_string_get_length (dir) - 1);
3031 
3032  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3033 
3034  if (dir_ends_in_slash && file_starts_with_slash)
3035  {
3036  _dbus_string_shorten (dir, 1);
3037  }
3038  else if (!(dir_ends_in_slash || file_starts_with_slash))
3039  {
3040  if (!_dbus_string_append_byte (dir, '/'))
3041  return FALSE;
3042  }
3043 
3044  return _dbus_string_copy (next_component, 0, dir,
3045  _dbus_string_get_length (dir));
3046 }
3047 
3049 #define NANOSECONDS_PER_SECOND 1000000000
3050 
3051 #define MICROSECONDS_PER_SECOND 1000000
3052 
3053 #define MILLISECONDS_PER_SECOND 1000
3054 
3055 #define NANOSECONDS_PER_MILLISECOND 1000000
3056 
3057 #define MICROSECONDS_PER_MILLISECOND 1000
3058 
3063 void
3064 _dbus_sleep_milliseconds (int milliseconds)
3065 {
3066 #ifdef HAVE_NANOSLEEP
3067  struct timespec req;
3068  struct timespec rem;
3069 
3070  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3071  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3072  rem.tv_sec = 0;
3073  rem.tv_nsec = 0;
3074 
3075  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3076  req = rem;
3077 #elif defined (HAVE_USLEEP)
3078  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3079 #else /* ! HAVE_USLEEP */
3080  sleep (MAX (milliseconds / 1000, 1));
3081 #endif
3082 }
3083 
3095  int n_bytes,
3096  DBusError *error)
3097 {
3098  int old_len;
3099  int fd;
3100  int result;
3101 
3102  old_len = _dbus_string_get_length (str);
3103  fd = -1;
3104 
3105  /* note, urandom on linux will fall back to pseudorandom */
3106  fd = open ("/dev/urandom", O_RDONLY);
3107 
3108  if (fd < 0)
3109  {
3110  dbus_set_error (error, _dbus_error_from_errno (errno),
3111  "Could not open /dev/urandom: %s",
3112  _dbus_strerror (errno));
3113  return FALSE;
3114  }
3115 
3116  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3117 
3118  result = _dbus_read (fd, str, n_bytes);
3119 
3120  if (result != n_bytes)
3121  {
3122  if (result < 0)
3123  dbus_set_error (error, _dbus_error_from_errno (errno),
3124  "Could not read /dev/urandom: %s",
3125  _dbus_strerror (errno));
3126  else
3128  "Short read from /dev/urandom");
3129 
3130  _dbus_close (fd, NULL);
3131  _dbus_string_set_length (str, old_len);
3132  return FALSE;
3133  }
3134 
3135  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3136  n_bytes);
3137 
3138  _dbus_close (fd, NULL);
3139 
3140  return TRUE;
3141 }
3142 
3148 void
3149 _dbus_exit (int code)
3150 {
3151  _exit (code);
3152 }
3153 
3162 const char*
3163 _dbus_strerror (int error_number)
3164 {
3165  const char *msg;
3166 
3167  msg = strerror (error_number);
3168  if (msg == NULL)
3169  msg = "unknown";
3170 
3171  return msg;
3172 }
3173 
3177 void
3179 {
3180  signal (SIGPIPE, SIG_IGN);
3181 }
3182 
3190 void
3192 {
3193  int val;
3194 
3195  val = fcntl (fd, F_GETFD, 0);
3196 
3197  if (val < 0)
3198  return;
3199 
3200  val |= FD_CLOEXEC;
3201 
3202  fcntl (fd, F_SETFD, val);
3203 }
3204 
3213 _dbus_close (int fd,
3214  DBusError *error)
3215 {
3216  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3217 
3218  again:
3219  if (close (fd) < 0)
3220  {
3221  if (errno == EINTR)
3222  goto again;
3223 
3224  dbus_set_error (error, _dbus_error_from_errno (errno),
3225  "Could not close fd %d", fd);
3226  return FALSE;
3227  }
3228 
3229  return TRUE;
3230 }
3231 
3240 int
3241 _dbus_dup(int fd,
3242  DBusError *error)
3243 {
3244  int new_fd;
3245 
3246 #ifdef F_DUPFD_CLOEXEC
3247  dbus_bool_t cloexec_done;
3248 
3249  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3250  cloexec_done = new_fd >= 0;
3251 
3252  if (new_fd < 0 && errno == EINVAL)
3253 #endif
3254  {
3255  new_fd = fcntl(fd, F_DUPFD, 3);
3256  }
3257 
3258  if (new_fd < 0) {
3259 
3260  dbus_set_error (error, _dbus_error_from_errno (errno),
3261  "Could not duplicate fd %d", fd);
3262  return -1;
3263  }
3264 
3265 #ifdef F_DUPFD_CLOEXEC
3266  if (!cloexec_done)
3267 #endif
3268  {
3270  }
3271 
3272  return new_fd;
3273 }
3274 
3284  DBusError *error)
3285 {
3286  return _dbus_set_fd_nonblocking (fd.fd, error);
3287 }
3288 
3289 static dbus_bool_t
3290 _dbus_set_fd_nonblocking (int fd,
3291  DBusError *error)
3292 {
3293  int val;
3294 
3295  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3296 
3297  val = fcntl (fd, F_GETFL, 0);
3298  if (val < 0)
3299  {
3300  dbus_set_error (error, _dbus_error_from_errno (errno),
3301  "Failed to get flags from file descriptor %d: %s",
3302  fd, _dbus_strerror (errno));
3303  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3304  _dbus_strerror (errno));
3305  return FALSE;
3306  }
3307 
3308  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3309  {
3310  dbus_set_error (error, _dbus_error_from_errno (errno),
3311  "Failed to set nonblocking flag of file descriptor %d: %s",
3312  fd, _dbus_strerror (errno));
3313  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3314  fd, _dbus_strerror (errno));
3315 
3316  return FALSE;
3317  }
3318 
3319  return TRUE;
3320 }
3321 
3327 void
3329 {
3330 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3331  void *bt[500];
3332  int bt_size;
3333  int i;
3334  char **syms;
3335 
3336  bt_size = backtrace (bt, 500);
3337 
3338  syms = backtrace_symbols (bt, bt_size);
3339 
3340  i = 0;
3341  while (i < bt_size)
3342  {
3343  /* don't use dbus_warn since it can _dbus_abort() */
3344  fprintf (stderr, " %s\n", syms[i]);
3345  ++i;
3346  }
3347  fflush (stderr);
3348 
3349  free (syms);
3350 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3351  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3352 #else
3353  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3354 #endif
3355 }
3356 
3371  DBusSocket *fd2,
3372  dbus_bool_t blocking,
3373  DBusError *error)
3374 {
3375 #ifdef HAVE_SOCKETPAIR
3376  int fds[2];
3377  int retval;
3378 
3379 #ifdef SOCK_CLOEXEC
3380  dbus_bool_t cloexec_done;
3381 
3382  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3383  cloexec_done = retval >= 0;
3384 
3385  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3386 #endif
3387  {
3388  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3389  }
3390 
3391  if (retval < 0)
3392  {
3393  dbus_set_error (error, _dbus_error_from_errno (errno),
3394  "Could not create full-duplex pipe");
3395  return FALSE;
3396  }
3397 
3398  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3399 
3400 #ifdef SOCK_CLOEXEC
3401  if (!cloexec_done)
3402 #endif
3403  {
3404  _dbus_fd_set_close_on_exec (fds[0]);
3405  _dbus_fd_set_close_on_exec (fds[1]);
3406  }
3407 
3408  if (!blocking &&
3409  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3410  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3411  {
3412  dbus_set_error (error, _dbus_error_from_errno (errno),
3413  "Could not set full-duplex pipe nonblocking");
3414 
3415  _dbus_close (fds[0], NULL);
3416  _dbus_close (fds[1], NULL);
3417 
3418  return FALSE;
3419  }
3420 
3421  fd1->fd = fds[0];
3422  fd2->fd = fds[1];
3423 
3424  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3425  fd1->fd, fd2->fd);
3426 
3427  return TRUE;
3428 #else
3429  _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
3431  "_dbus_socketpair() not implemented on this OS");
3432  return FALSE;
3433 #endif
3434 }
3435 
3444 int
3446  va_list args)
3447 {
3448  char static_buf[1024];
3449  int bufsize = sizeof (static_buf);
3450  int len;
3451  va_list args_copy;
3452 
3453  DBUS_VA_COPY (args_copy, args);
3454  len = vsnprintf (static_buf, bufsize, format, args_copy);
3455  va_end (args_copy);
3456 
3457  /* If vsnprintf() returned non-negative, then either the string fits in
3458  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3459  * returns the number of characters that were needed, or this OS returns the
3460  * truncated length.
3461  *
3462  * We ignore the possibility that snprintf might just ignore the length and
3463  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3464  * If your libc is really that bad, come back when you have a better one. */
3465  if (len == bufsize)
3466  {
3467  /* This could be the truncated length (Tru64 and IRIX have this bug),
3468  * or the real length could be coincidentally the same. Which is it?
3469  * If vsnprintf returns the truncated length, we'll go to the slow
3470  * path. */
3471  DBUS_VA_COPY (args_copy, args);
3472 
3473  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3474  len = -1;
3475 
3476  va_end (args_copy);
3477  }
3478 
3479  /* If vsnprintf() returned negative, we have to do more work.
3480  * HP-UX returns negative. */
3481  while (len < 0)
3482  {
3483  char *buf;
3484 
3485  bufsize *= 2;
3486 
3487  buf = dbus_malloc (bufsize);
3488 
3489  if (buf == NULL)
3490  return -1;
3491 
3492  DBUS_VA_COPY (args_copy, args);
3493  len = vsnprintf (buf, bufsize, format, args_copy);
3494  va_end (args_copy);
3495 
3496  dbus_free (buf);
3497 
3498  /* If the reported length is exactly the buffer size, round up to the
3499  * next size, in case vsnprintf has been returning the truncated
3500  * length */
3501  if (len == bufsize)
3502  len = -1;
3503  }
3504 
3505  return len;
3506 }
3507 
3514 const char*
3516 {
3517  /* Protected by _DBUS_LOCK_sysdeps */
3518  static const char* tmpdir = NULL;
3519 
3520  if (!_DBUS_LOCK (sysdeps))
3521  return NULL;
3522 
3523  if (tmpdir == NULL)
3524  {
3525  /* TMPDIR is what glibc uses, then
3526  * glibc falls back to the P_tmpdir macro which
3527  * just expands to "/tmp"
3528  */
3529  if (tmpdir == NULL)
3530  tmpdir = getenv("TMPDIR");
3531 
3532  /* These two env variables are probably
3533  * broken, but maybe some OS uses them?
3534  */
3535  if (tmpdir == NULL)
3536  tmpdir = getenv("TMP");
3537  if (tmpdir == NULL)
3538  tmpdir = getenv("TEMP");
3539 
3540  /* And this is the sane fallback. */
3541  if (tmpdir == NULL)
3542  tmpdir = "/tmp";
3543  }
3544 
3545  _DBUS_UNLOCK (sysdeps);
3546 
3547  _dbus_assert(tmpdir != NULL);
3548 
3549  return tmpdir;
3550 }
3551 
3552 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3553 
3572 static dbus_bool_t
3573 _read_subprocess_line_argv (const char *progpath,
3574  dbus_bool_t path_fallback,
3575  char * const *argv,
3576  DBusString *result,
3577  DBusError *error)
3578 {
3579  int result_pipe[2] = { -1, -1 };
3580  int errors_pipe[2] = { -1, -1 };
3581  pid_t pid;
3582  int ret;
3583  int status;
3584  int orig_len;
3585 
3586  dbus_bool_t retval;
3587  sigset_t new_set, old_set;
3588 
3589  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3590  retval = FALSE;
3591 
3592  /* We need to block any existing handlers for SIGCHLD temporarily; they
3593  * will cause waitpid() below to fail.
3594  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3595  */
3596  sigemptyset (&new_set);
3597  sigaddset (&new_set, SIGCHLD);
3598  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3599 
3600  orig_len = _dbus_string_get_length (result);
3601 
3602 #define READ_END 0
3603 #define WRITE_END 1
3604  if (pipe (result_pipe) < 0)
3605  {
3606  dbus_set_error (error, _dbus_error_from_errno (errno),
3607  "Failed to create a pipe to call %s: %s",
3608  progpath, _dbus_strerror (errno));
3609  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3610  progpath, _dbus_strerror (errno));
3611  goto out;
3612  }
3613  if (pipe (errors_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 
3623  pid = fork ();
3624  if (pid < 0)
3625  {
3626  dbus_set_error (error, _dbus_error_from_errno (errno),
3627  "Failed to fork() to call %s: %s",
3628  progpath, _dbus_strerror (errno));
3629  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3630  progpath, _dbus_strerror (errno));
3631  goto out;
3632  }
3633 
3634  if (pid == 0)
3635  {
3636  /* child process */
3637  int fd;
3638 
3639  fd = open ("/dev/null", O_RDWR);
3640  if (fd == -1)
3641  /* huh?! can't open /dev/null? */
3642  _exit (1);
3643 
3644  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3645 
3646  /* set-up stdXXX */
3647  close (result_pipe[READ_END]);
3648  close (errors_pipe[READ_END]);
3649 
3650  if (dup2 (fd, 0) == -1) /* setup stdin */
3651  _exit (1);
3652  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3653  _exit (1);
3654  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3655  _exit (1);
3656 
3657  _dbus_close_all ();
3658 
3659  sigprocmask (SIG_SETMASK, &old_set, NULL);
3660 
3661  /* If it looks fully-qualified, try execv first */
3662  if (progpath[0] == '/')
3663  {
3664  execv (progpath, argv);
3665  /* Ok, that failed. Now if path_fallback is given, let's
3666  * try unqualified. This is mostly a hack to work
3667  * around systems which ship dbus-launch in /usr/bin
3668  * but everything else in /bin (because dbus-launch
3669  * depends on X11).
3670  */
3671  if (path_fallback)
3672  /* We must have a slash, because we checked above */
3673  execvp (strrchr (progpath, '/')+1, argv);
3674  }
3675  else
3676  execvp (progpath, argv);
3677 
3678  /* still nothing, we failed */
3679  _exit (1);
3680  }
3681 
3682  /* parent process */
3683  close (result_pipe[WRITE_END]);
3684  close (errors_pipe[WRITE_END]);
3685  result_pipe[WRITE_END] = -1;
3686  errors_pipe[WRITE_END] = -1;
3687 
3688  ret = 0;
3689  do
3690  {
3691  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3692  }
3693  while (ret > 0);
3694 
3695  /* reap the child process to avoid it lingering as zombie */
3696  do
3697  {
3698  ret = waitpid (pid, &status, 0);
3699  }
3700  while (ret == -1 && errno == EINTR);
3701 
3702  /* We succeeded if the process exited with status 0 and
3703  anything was read */
3704  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3705  {
3706  /* The process ended with error */
3707  DBusString error_message;
3708  if (!_dbus_string_init (&error_message))
3709  {
3710  _DBUS_SET_OOM (error);
3711  goto out;
3712  }
3713 
3714  ret = 0;
3715  do
3716  {
3717  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3718  }
3719  while (ret > 0);
3720 
3721  _dbus_string_set_length (result, orig_len);
3722  if (_dbus_string_get_length (&error_message) > 0)
3724  "%s terminated abnormally with the following error: %s",
3725  progpath, _dbus_string_get_data (&error_message));
3726  else
3728  "%s terminated abnormally without any error message",
3729  progpath);
3730  goto out;
3731  }
3732 
3733  retval = TRUE;
3734 
3735  out:
3736  sigprocmask (SIG_SETMASK, &old_set, NULL);
3737 
3738  if (retval)
3739  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3740  else
3741  _DBUS_ASSERT_ERROR_IS_SET (error);
3742 
3743  if (result_pipe[0] != -1)
3744  close (result_pipe[0]);
3745  if (result_pipe[1] != -1)
3746  close (result_pipe[1]);
3747  if (errors_pipe[0] != -1)
3748  close (errors_pipe[0]);
3749  if (errors_pipe[1] != -1)
3750  close (errors_pipe[1]);
3751 
3752  return retval;
3753 }
3754 #endif
3755 
3769 _dbus_get_autolaunch_address (const char *scope,
3770  DBusString *address,
3771  DBusError *error)
3772 {
3773 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3774  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3775  * but that's done elsewhere, and if it worked, this function wouldn't
3776  * be called.) */
3777  const char *display;
3778  char *progpath;
3779  char *argv[6];
3780  int i;
3781  DBusString uuid;
3782  dbus_bool_t retval;
3783 
3784  if (_dbus_check_setuid ())
3785  {
3787  "Unable to autolaunch when setuid");
3788  return FALSE;
3789  }
3790 
3791  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3792  retval = FALSE;
3793 
3794  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3795  * dbus-launch-x11 is just going to fail. Rather than trying to
3796  * run it, we might as well bail out early with a nice error.
3797  *
3798  * This is not strictly true in a world where the user bus exists,
3799  * because dbus-launch --autolaunch knows how to connect to that -
3800  * but if we were going to connect to the user bus, we'd have done
3801  * so before trying autolaunch: in any case. */
3802  display = _dbus_getenv ("DISPLAY");
3803 
3804  if (display == NULL || display[0] == '\0')
3805  {
3807  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3808  return FALSE;
3809  }
3810 
3811  if (!_dbus_string_init (&uuid))
3812  {
3813  _DBUS_SET_OOM (error);
3814  return FALSE;
3815  }
3816 
3817  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3818  {
3819  goto out;
3820  }
3821 
3822 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3823  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3824  progpath = TEST_BUS_LAUNCH_BINARY;
3825  else
3826 #endif
3827  progpath = DBUS_BINDIR "/dbus-launch";
3828  /*
3829  * argv[0] is always dbus-launch, that's the name what we'll
3830  * get from /proc, or ps(1), regardless what the progpath is,
3831  * see fd.o#69716
3832  */
3833  i = 0;
3834  argv[i] = "dbus-launch";
3835  ++i;
3836  argv[i] = "--autolaunch";
3837  ++i;
3838  argv[i] = _dbus_string_get_data (&uuid);
3839  ++i;
3840  argv[i] = "--binary-syntax";
3841  ++i;
3842  argv[i] = "--close-stderr";
3843  ++i;
3844  argv[i] = NULL;
3845  ++i;
3846 
3847  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3848 
3849  retval = _read_subprocess_line_argv (progpath,
3850  TRUE,
3851  argv, address, error);
3852 
3853  out:
3854  _dbus_string_free (&uuid);
3855  return retval;
3856 #else
3858  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3859  "set your DBUS_SESSION_BUS_ADDRESS instead");
3860  return FALSE;
3861 #endif
3862 }
3863 
3884  dbus_bool_t create_if_not_found,
3885  DBusError *error)
3886 {
3887  DBusString filename;
3888  dbus_bool_t b;
3889 
3890  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3891 
3892  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3893  if (b)
3894  return TRUE;
3895 
3896  dbus_error_free (error);
3897 
3898  /* Fallback to the system machine ID */
3899  _dbus_string_init_const (&filename, "/etc/machine-id");
3900  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3901 
3902  if (b)
3903  {
3904  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3905  * complain if that isn't possible for whatever reason */
3906  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3907  _dbus_write_uuid_file (&filename, machine_id, NULL);
3908 
3909  return TRUE;
3910  }
3911 
3912  if (!create_if_not_found)
3913  return FALSE;
3914 
3915  /* if none found, try to make a new one */
3916  dbus_error_free (error);
3917  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3918 
3919  if (!_dbus_generate_uuid (machine_id, error))
3920  return FALSE;
3921 
3922  return _dbus_write_uuid_file (&filename, machine_id, error);
3923 }
3924 
3934  const char *launchd_env_var,
3935  DBusError *error)
3936 {
3937 #ifdef DBUS_ENABLE_LAUNCHD
3938  char *argv[4];
3939  int i;
3940 
3941  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3942 
3943  if (_dbus_check_setuid ())
3944  {
3946  "Unable to find launchd socket when setuid");
3947  return FALSE;
3948  }
3949 
3950  i = 0;
3951  argv[i] = "launchctl";
3952  ++i;
3953  argv[i] = "getenv";
3954  ++i;
3955  argv[i] = (char*)launchd_env_var;
3956  ++i;
3957  argv[i] = NULL;
3958  ++i;
3959 
3960  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3961 
3962  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3963  {
3964  return FALSE;
3965  }
3966 
3967  /* no error, but no result either */
3968  if (_dbus_string_get_length(socket_path) == 0)
3969  {
3970  return FALSE;
3971  }
3972 
3973  /* strip the carriage-return */
3974  _dbus_string_shorten(socket_path, 1);
3975  return TRUE;
3976 #else /* DBUS_ENABLE_LAUNCHD */
3978  "can't lookup socket from launchd; launchd support not compiled in");
3979  return FALSE;
3980 #endif
3981 }
3982 
3983 #ifdef DBUS_ENABLE_LAUNCHD
3984 static dbus_bool_t
3985 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3986 {
3987  dbus_bool_t valid_socket;
3988  DBusString socket_path;
3989 
3990  if (_dbus_check_setuid ())
3991  {
3993  "Unable to find launchd socket when setuid");
3994  return FALSE;
3995  }
3996 
3997  if (!_dbus_string_init (&socket_path))
3998  {
3999  _DBUS_SET_OOM (error);
4000  return FALSE;
4001  }
4002 
4003  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4004 
4005  if (dbus_error_is_set(error))
4006  {
4007  _dbus_string_free(&socket_path);
4008  return FALSE;
4009  }
4010 
4011  if (!valid_socket)
4012  {
4013  dbus_set_error(error, "no socket path",
4014  "launchd did not provide a socket path, "
4015  "verify that org.freedesktop.dbus-session.plist is loaded!");
4016  _dbus_string_free(&socket_path);
4017  return FALSE;
4018  }
4019  if (!_dbus_string_append (address, "unix:path="))
4020  {
4021  _DBUS_SET_OOM (error);
4022  _dbus_string_free(&socket_path);
4023  return FALSE;
4024  }
4025  if (!_dbus_string_copy (&socket_path, 0, address,
4026  _dbus_string_get_length (address)))
4027  {
4028  _DBUS_SET_OOM (error);
4029  _dbus_string_free(&socket_path);
4030  return FALSE;
4031  }
4032 
4033  _dbus_string_free(&socket_path);
4034  return TRUE;
4035 }
4036 #endif
4037 
4039 _dbus_lookup_user_bus (dbus_bool_t *supported,
4040  DBusString *address,
4041  DBusError *error)
4042 {
4043  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4044  dbus_bool_t ret = FALSE;
4045  struct stat stbuf;
4046  DBusString user_bus_path;
4047 
4048  if (runtime_dir == NULL)
4049  {
4050  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4051  *supported = FALSE;
4052  return TRUE; /* Cannot use it, but not an error */
4053  }
4054 
4055  if (!_dbus_string_init (&user_bus_path))
4056  {
4057  _DBUS_SET_OOM (error);
4058  return FALSE;
4059  }
4060 
4061  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4062  {
4063  _DBUS_SET_OOM (error);
4064  goto out;
4065  }
4066 
4067  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4068  {
4069  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4070  _dbus_strerror (errno));
4071  *supported = FALSE;
4072  ret = TRUE; /* Cannot use it, but not an error */
4073  goto out;
4074  }
4075 
4076  if (stbuf.st_uid != getuid ())
4077  {
4078  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4079  (long) stbuf.st_uid, (long) getuid ());
4080  *supported = FALSE;
4081  ret = TRUE; /* Cannot use it, but not an error */
4082  goto out;
4083  }
4084 
4085  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4086  {
4087  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4088  (long) stbuf.st_mode);
4089  *supported = FALSE;
4090  ret = TRUE; /* Cannot use it, but not an error */
4091  goto out;
4092  }
4093 
4094  if (!_dbus_string_append (address, "unix:path=") ||
4095  !_dbus_address_append_escaped (address, &user_bus_path))
4096  {
4097  _DBUS_SET_OOM (error);
4098  goto out;
4099  }
4100 
4101  *supported = TRUE;
4102  ret = TRUE;
4103 
4104 out:
4105  _dbus_string_free (&user_bus_path);
4106  return ret;
4107 }
4108 
4130  DBusString *address,
4131  DBusError *error)
4132 {
4133 #ifdef DBUS_ENABLE_LAUNCHD
4134  *supported = TRUE;
4135  return _dbus_lookup_session_address_launchd (address, error);
4136 #else
4137  *supported = FALSE;
4138 
4139  if (!_dbus_lookup_user_bus (supported, address, error))
4140  return FALSE;
4141  else if (*supported)
4142  return TRUE;
4143 
4144  /* On non-Mac Unix platforms, if the session address isn't already
4145  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4146  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4147  * autolaunch: global default; see init_session_address in
4148  * dbus/dbus-bus.c. */
4149  return TRUE;
4150 #endif
4151 }
4152 
4160 void
4162 {
4164 }
4165 
4181  DBusCredentials *credentials)
4182 {
4183  DBusString homedir;
4184  DBusString dotdir;
4185  dbus_uid_t uid;
4186 
4187  _dbus_assert (credentials != NULL);
4189 
4190  if (!_dbus_string_init (&homedir))
4191  return FALSE;
4192 
4193  uid = _dbus_credentials_get_unix_uid (credentials);
4194  _dbus_assert (uid != DBUS_UID_UNSET);
4195 
4196  if (!_dbus_homedir_from_uid (uid, &homedir))
4197  goto failed;
4198 
4199 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4200  {
4201  const char *override;
4202 
4203  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4204  if (override != NULL && *override != '\0')
4205  {
4206  _dbus_string_set_length (&homedir, 0);
4207  if (!_dbus_string_append (&homedir, override))
4208  goto failed;
4209 
4210  _dbus_verbose ("Using fake homedir for testing: %s\n",
4211  _dbus_string_get_const_data (&homedir));
4212  }
4213  else
4214  {
4215  /* Not strictly thread-safe, but if we fail at thread-safety here,
4216  * the worst that will happen is some extra warnings. */
4217  static dbus_bool_t already_warned = FALSE;
4218  if (!already_warned)
4219  {
4220  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
4221  already_warned = TRUE;
4222  }
4223  }
4224  }
4225 #endif
4226 
4227  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4228  if (!_dbus_concat_dir_and_file (&homedir,
4229  &dotdir))
4230  goto failed;
4231 
4232  if (!_dbus_string_copy (&homedir, 0,
4233  directory, _dbus_string_get_length (directory))) {
4234  goto failed;
4235  }
4236 
4237  _dbus_string_free (&homedir);
4238  return TRUE;
4239 
4240  failed:
4241  _dbus_string_free (&homedir);
4242  return FALSE;
4243 }
4244 
4245 //PENDING(kdab) docs
4247 _dbus_daemon_publish_session_bus_address (const char* addr,
4248  const char *scope)
4249 {
4250  return TRUE;
4251 }
4252 
4253 //PENDING(kdab) docs
4254 void
4255 _dbus_daemon_unpublish_session_bus_address (void)
4256 {
4257 
4258 }
4259 
4268 {
4269  return e == EAGAIN || e == EWOULDBLOCK;
4270 }
4271 
4281  DBusError *error)
4282 {
4283  const char *filename_c;
4284 
4285  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4286 
4287  filename_c = _dbus_string_get_const_data (filename);
4288 
4289  if (rmdir (filename_c) != 0)
4290  {
4292  "Failed to remove directory %s: %s\n",
4293  filename_c, _dbus_strerror (errno));
4294  return FALSE;
4295  }
4296 
4297  return TRUE;
4298 }
4299 
4309 {
4310 #ifdef SCM_RIGHTS
4311  union {
4312  struct sockaddr sa;
4313  struct sockaddr_storage storage;
4314  struct sockaddr_un un;
4315  } sa_buf;
4316 
4317  socklen_t sa_len = sizeof(sa_buf);
4318 
4319  _DBUS_ZERO(sa_buf);
4320 
4321  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4322  return FALSE;
4323 
4324  return sa_buf.sa.sa_family == AF_UNIX;
4325 
4326 #else
4327  return FALSE;
4328 
4329 #endif
4330 }
4331 
4336 void
4338 {
4339  int maxfds, i;
4340 
4341 #ifdef __linux__
4342  DIR *d;
4343 
4344  /* On Linux we can optimize this a bit if /proc is available. If it
4345  isn't available, fall back to the brute force way. */
4346 
4347  d = opendir ("/proc/self/fd");
4348  if (d)
4349  {
4350  for (;;)
4351  {
4352  struct dirent buf, *de;
4353  int k, fd;
4354  long l;
4355  char *e = NULL;
4356 
4357  k = readdir_r (d, &buf, &de);
4358  if (k != 0 || !de)
4359  break;
4360 
4361  if (de->d_name[0] == '.')
4362  continue;
4363 
4364  errno = 0;
4365  l = strtol (de->d_name, &e, 10);
4366  if (errno != 0 || e == NULL || *e != '\0')
4367  continue;
4368 
4369  fd = (int) l;
4370  if (fd < 3)
4371  continue;
4372 
4373  if (fd == dirfd (d))
4374  continue;
4375 
4376  close (fd);
4377  }
4378 
4379  closedir (d);
4380  return;
4381  }
4382 #endif
4383 
4384  maxfds = sysconf (_SC_OPEN_MAX);
4385 
4386  /* Pick something reasonable if for some reason sysconf says
4387  * unlimited.
4388  */
4389  if (maxfds < 0)
4390  maxfds = 1024;
4391 
4392  /* close all inherited fds */
4393  for (i = 3; i < maxfds; i++)
4394  close (i);
4395 }
4396 
4408 {
4409  /* TODO: get __libc_enable_secure exported from glibc.
4410  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4411  */
4412 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4413  {
4414  /* See glibc/include/unistd.h */
4415  extern int __libc_enable_secure;
4416  return __libc_enable_secure;
4417  }
4418 #elif defined(HAVE_ISSETUGID)
4419  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4420  return issetugid ();
4421 #else
4422  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4423  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4424 
4425  /* We call into this function from _dbus_threads_init_platform_specific()
4426  * to make sure these are initialized before we start threading. */
4427  static dbus_bool_t check_setuid_initialised;
4428  static dbus_bool_t is_setuid;
4429 
4430  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4431  {
4432 #ifdef HAVE_GETRESUID
4433  if (getresuid (&ruid, &euid, &suid) != 0 ||
4434  getresgid (&rgid, &egid, &sgid) != 0)
4435 #endif /* HAVE_GETRESUID */
4436  {
4437  suid = ruid = getuid ();
4438  sgid = rgid = getgid ();
4439  euid = geteuid ();
4440  egid = getegid ();
4441  }
4442 
4443  check_setuid_initialised = TRUE;
4444  is_setuid = (ruid != euid || ruid != suid ||
4445  rgid != egid || rgid != sgid);
4446 
4447  }
4448  return is_setuid;
4449 #endif
4450 }
4451 
4461  DBusString *address,
4462  DBusError *error)
4463 {
4464  union {
4465  struct sockaddr sa;
4466  struct sockaddr_storage storage;
4467  struct sockaddr_un un;
4468  struct sockaddr_in ipv4;
4469  struct sockaddr_in6 ipv6;
4470  } socket;
4471  char hostip[INET6_ADDRSTRLEN];
4472  int size = sizeof (socket);
4473  DBusString path_str;
4474 
4475  if (getsockname (fd.fd, &socket.sa, &size))
4476  goto err;
4477 
4478  switch (socket.sa.sa_family)
4479  {
4480  case AF_UNIX:
4481  if (socket.un.sun_path[0]=='\0')
4482  {
4483  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4484  if (_dbus_string_append (address, "unix:abstract=") &&
4485  _dbus_address_append_escaped (address, &path_str))
4486  return TRUE;
4487  }
4488  else
4489  {
4490  _dbus_string_init_const (&path_str, socket.un.sun_path);
4491  if (_dbus_string_append (address, "unix:path=") &&
4492  _dbus_address_append_escaped (address, &path_str))
4493  return TRUE;
4494  }
4495  break;
4496  case AF_INET:
4497  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4498  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4499  hostip, ntohs (socket.ipv4.sin_port)))
4500  return TRUE;
4501  break;
4502 #ifdef AF_INET6
4503  case AF_INET6:
4504  _dbus_string_init_const (&path_str, hostip);
4505  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4506  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4507  ntohs (socket.ipv6.sin6_port)) &&
4508  _dbus_address_append_escaped (address, &path_str))
4509  return TRUE;
4510  break;
4511 #endif
4512  default:
4513  dbus_set_error (error,
4514  _dbus_error_from_errno (EINVAL),
4515  "Failed to read address from socket: Unknown socket type.");
4516  return FALSE;
4517  }
4518  err:
4519  dbus_set_error (error,
4520  _dbus_error_from_errno (errno),
4521  "Failed to open socket: %s",
4522  _dbus_strerror (errno));
4523  return FALSE;
4524 }
4525 
4526 int
4527 _dbus_save_socket_errno (void)
4528 {
4529  return errno;
4530 }
4531 
4532 void
4533 _dbus_restore_socket_errno (int saved_errno)
4534 {
4535  errno = saved_errno;
4536 }
4537 
4538 /* 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 "1".
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; "something went wrong" - 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 "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
void _dbus_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