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