D-Bus  1.12.16
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  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
917 
918  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
919 
920  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
921  path, abstract);
922 
923 
924  if (!_dbus_open_unix_socket (&fd, error))
925  {
926  _DBUS_ASSERT_ERROR_IS_SET(error);
927  return -1;
928  }
929  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
930 
931  _DBUS_ZERO (addr);
932  addr.sun_family = AF_UNIX;
933  path_len = strlen (path);
934 
935  if (abstract)
936  {
937 #ifdef __linux__
938  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
939  path_len++; /* Account for the extra nul byte added to the start of sun_path */
940 
941  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
942  {
944  "Abstract socket name too long\n");
945  _dbus_close (fd, NULL);
946  return -1;
947  }
948 
949  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
950  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
951 #else /* !__linux__ */
953  "Operating system does not support abstract socket namespace\n");
954  _dbus_close (fd, NULL);
955  return -1;
956 #endif /* !__linux__ */
957  }
958  else
959  {
960  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
961  {
963  "Socket name too long\n");
964  _dbus_close (fd, NULL);
965  return -1;
966  }
967 
968  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
969  }
970 
971  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
972  {
973  dbus_set_error (error,
974  _dbus_error_from_errno (errno),
975  "Failed to connect to socket %s: %s",
976  path, _dbus_strerror (errno));
977 
978  _dbus_close (fd, NULL);
979  return -1;
980  }
981 
982  if (!_dbus_set_fd_nonblocking (fd, error))
983  {
984  _DBUS_ASSERT_ERROR_IS_SET (error);
985 
986  _dbus_close (fd, NULL);
987  return -1;
988  }
989 
990  return fd;
991 }
992 
1005 int
1006 _dbus_connect_exec (const char *path,
1007  char *const argv[],
1008  DBusError *error)
1009 {
1010  int fds[2];
1011  pid_t pid;
1012  int retval;
1013  dbus_bool_t cloexec_done = 0;
1014 
1015  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1016 
1017  _dbus_verbose ("connecting to process %s\n", path);
1018 
1019 #ifdef SOCK_CLOEXEC
1020  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1021  cloexec_done = (retval >= 0);
1022 
1023  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1024 #endif
1025  {
1026  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1027  }
1028 
1029  if (retval < 0)
1030  {
1031  dbus_set_error (error,
1032  _dbus_error_from_errno (errno),
1033  "Failed to create socket pair: %s",
1034  _dbus_strerror (errno));
1035  return -1;
1036  }
1037 
1038  if (!cloexec_done)
1039  {
1040  _dbus_fd_set_close_on_exec (fds[0]);
1041  _dbus_fd_set_close_on_exec (fds[1]);
1042  }
1043 
1044  pid = fork ();
1045  if (pid < 0)
1046  {
1047  dbus_set_error (error,
1048  _dbus_error_from_errno (errno),
1049  "Failed to fork() to call %s: %s",
1050  path, _dbus_strerror (errno));
1051  close (fds[0]);
1052  close (fds[1]);
1053  return -1;
1054  }
1055 
1056  if (pid == 0)
1057  {
1058  /* child */
1059  close (fds[0]);
1060 
1061  dup2 (fds[1], STDIN_FILENO);
1062  dup2 (fds[1], STDOUT_FILENO);
1063 
1064  if (fds[1] != STDIN_FILENO &&
1065  fds[1] != STDOUT_FILENO)
1066  close (fds[1]);
1067 
1068  /* Inherit STDERR and the controlling terminal from the
1069  parent */
1070 
1071  _dbus_close_all ();
1072 
1073  execvp (path, (char * const *) argv);
1074 
1075  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1076 
1077  _exit(1);
1078  }
1079 
1080  /* parent */
1081  close (fds[1]);
1082 
1083  if (!_dbus_set_fd_nonblocking (fds[0], error))
1084  {
1085  _DBUS_ASSERT_ERROR_IS_SET (error);
1086 
1087  close (fds[0]);
1088  return -1;
1089  }
1090 
1091  return fds[0];
1092 }
1093 
1111 int
1112 _dbus_listen_unix_socket (const char *path,
1113  dbus_bool_t abstract,
1114  DBusError *error)
1115 {
1116  int listen_fd;
1117  struct sockaddr_un addr;
1118  size_t path_len;
1119  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1120 
1121  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1122 
1123  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1124  path, abstract);
1125 
1126  if (!_dbus_open_unix_socket (&listen_fd, error))
1127  {
1128  _DBUS_ASSERT_ERROR_IS_SET(error);
1129  return -1;
1130  }
1131  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1132 
1133  _DBUS_ZERO (addr);
1134  addr.sun_family = AF_UNIX;
1135  path_len = strlen (path);
1136 
1137  if (abstract)
1138  {
1139 #ifdef __linux__
1140  /* remember that abstract names aren't nul-terminated so we rely
1141  * on sun_path being filled in with zeroes above.
1142  */
1143  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1144  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1145 
1146  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1147  {
1149  "Abstract socket name too long\n");
1150  _dbus_close (listen_fd, NULL);
1151  return -1;
1152  }
1153 
1154  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1155  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1156 #else /* !__linux__ */
1158  "Operating system does not support abstract socket namespace\n");
1159  _dbus_close (listen_fd, NULL);
1160  return -1;
1161 #endif /* !__linux__ */
1162  }
1163  else
1164  {
1165  /* Discussed security implications of this with Nalin,
1166  * and we couldn't think of where it would kick our ass, but
1167  * it still seems a bit sucky. It also has non-security suckage;
1168  * really we'd prefer to exit if the socket is already in use.
1169  * But there doesn't seem to be a good way to do this.
1170  *
1171  * Just to be extra careful, I threw in the stat() - clearly
1172  * the stat() can't *fix* any security issue, but it at least
1173  * avoids inadvertent/accidental data loss.
1174  */
1175  {
1176  struct stat sb;
1177 
1178  if (stat (path, &sb) == 0 &&
1179  S_ISSOCK (sb.st_mode))
1180  unlink (path);
1181  }
1182 
1183  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1184  {
1186  "Socket name too long\n");
1187  _dbus_close (listen_fd, NULL);
1188  return -1;
1189  }
1190 
1191  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1192  }
1193 
1194  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1195  {
1196  dbus_set_error (error, _dbus_error_from_errno (errno),
1197  "Failed to bind socket \"%s\": %s",
1198  path, _dbus_strerror (errno));
1199  _dbus_close (listen_fd, NULL);
1200  return -1;
1201  }
1202 
1203  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1204  {
1205  dbus_set_error (error, _dbus_error_from_errno (errno),
1206  "Failed to listen on socket \"%s\": %s",
1207  path, _dbus_strerror (errno));
1208  _dbus_close (listen_fd, NULL);
1209  return -1;
1210  }
1211 
1212  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1213  {
1214  _DBUS_ASSERT_ERROR_IS_SET (error);
1215  _dbus_close (listen_fd, NULL);
1216  return -1;
1217  }
1218 
1219  /* Try opening up the permissions, but if we can't, just go ahead
1220  * and continue, maybe it will be good enough.
1221  */
1222  if (!abstract && chmod (path, 0777) < 0)
1223  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1224 
1225  return listen_fd;
1226 }
1227 
1238 int
1240  DBusError *error)
1241 {
1242 #ifdef HAVE_SYSTEMD
1243  int r, n;
1244  int fd;
1245  DBusSocket *new_fds;
1246 
1247  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1248 
1249  n = sd_listen_fds (TRUE);
1250  if (n < 0)
1251  {
1253  "Failed to acquire systemd socket: %s",
1254  _dbus_strerror (-n));
1255  return -1;
1256  }
1257 
1258  if (n <= 0)
1259  {
1261  "No socket received.");
1262  return -1;
1263  }
1264 
1265  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1266  {
1267  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1268  if (r < 0)
1269  {
1271  "Failed to verify systemd socket type: %s",
1272  _dbus_strerror (-r));
1273  return -1;
1274  }
1275 
1276  if (!r)
1277  {
1279  "Passed socket has wrong type.");
1280  return -1;
1281  }
1282  }
1283 
1284  /* OK, the file descriptors are all good, so let's take posession of
1285  them then. */
1286 
1287  new_fds = dbus_new (DBusSocket, n);
1288  if (!new_fds)
1289  {
1291  "Failed to allocate file handle array.");
1292  goto fail;
1293  }
1294 
1295  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1296  {
1297  if (!_dbus_set_fd_nonblocking (fd, error))
1298  {
1299  _DBUS_ASSERT_ERROR_IS_SET (error);
1300  goto fail;
1301  }
1302 
1303  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1304  }
1305 
1306  *fds = new_fds;
1307  return n;
1308 
1309  fail:
1310 
1311  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1312  {
1313  _dbus_close (fd, NULL);
1314  }
1315 
1316  dbus_free (new_fds);
1317  return -1;
1318 #else
1320  "dbus was compiled without systemd support");
1321  return -1;
1322 #endif
1323 }
1324 
1325 /* Convert an error code from getaddrinfo() or getnameinfo() into
1326  * a D-Bus error name. */
1327 static const char *
1328 _dbus_error_from_gai (int gai_res,
1329  int saved_errno)
1330 {
1331  switch (gai_res)
1332  {
1333 #ifdef EAI_FAMILY
1334  case EAI_FAMILY:
1335  /* ai_family not supported (at all) */
1336  return DBUS_ERROR_NOT_SUPPORTED;
1337 #endif
1338 
1339 #ifdef EAI_SOCKTYPE
1340  case EAI_SOCKTYPE:
1341  /* ai_socktype not supported (at all) */
1342  return DBUS_ERROR_NOT_SUPPORTED;
1343 #endif
1344 
1345 #ifdef EAI_MEMORY
1346  case EAI_MEMORY:
1347  /* Out of memory */
1348  return DBUS_ERROR_NO_MEMORY;
1349 #endif
1350 
1351 #ifdef EAI_SYSTEM
1352  case EAI_SYSTEM:
1353  /* Unspecified system error, details in errno */
1354  return _dbus_error_from_errno (saved_errno);
1355 #endif
1356 
1357  case 0:
1358  /* It succeeded, but we didn't get any addresses? */
1359  return DBUS_ERROR_FAILED;
1360 
1361  /* EAI_AGAIN: Transient failure */
1362  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1363  /* EAI_FAIL: Non-recoverable failure */
1364  /* EAI_NODATA: host exists but has no addresses */
1365  /* EAI_NONAME: host does not exist */
1366  /* EAI_OVERFLOW: argument buffer overflow */
1367  /* EAI_SERVICE: service not available for specified socket
1368  * type (we should never see this because we use numeric
1369  * ports) */
1370  default:
1371  return DBUS_ERROR_FAILED;
1372  }
1373 }
1374 
1388 DBusSocket
1389 _dbus_connect_tcp_socket (const char *host,
1390  const char *port,
1391  const char *family,
1392  DBusError *error)
1393 {
1394  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1395 }
1396 
1397 DBusSocket
1398 _dbus_connect_tcp_socket_with_nonce (const char *host,
1399  const char *port,
1400  const char *family,
1401  const char *noncefile,
1402  DBusError *error)
1403 {
1404  int saved_errno = 0;
1405  DBusSocket fd = DBUS_SOCKET_INIT;
1406  int res;
1407  struct addrinfo hints;
1408  struct addrinfo *ai, *tmp;
1409 
1410  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1411 
1412  _DBUS_ZERO (hints);
1413 
1414  if (!family)
1415  hints.ai_family = AF_UNSPEC;
1416  else if (!strcmp(family, "ipv4"))
1417  hints.ai_family = AF_INET;
1418  else if (!strcmp(family, "ipv6"))
1419  hints.ai_family = AF_INET6;
1420  else
1421  {
1422  dbus_set_error (error,
1424  "Unknown address family %s", family);
1425  return _dbus_socket_get_invalid ();
1426  }
1427  hints.ai_protocol = IPPROTO_TCP;
1428  hints.ai_socktype = SOCK_STREAM;
1429  hints.ai_flags = AI_ADDRCONFIG;
1430 
1431  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1432  {
1433  dbus_set_error (error,
1434  _dbus_error_from_gai (res, errno),
1435  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1436  host, port, gai_strerror(res), res);
1437  return _dbus_socket_get_invalid ();
1438  }
1439 
1440  tmp = ai;
1441  while (tmp)
1442  {
1443  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1444  {
1445  freeaddrinfo(ai);
1446  _DBUS_ASSERT_ERROR_IS_SET(error);
1447  return _dbus_socket_get_invalid ();
1448  }
1449  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1450 
1451  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1452  {
1453  saved_errno = errno;
1454  _dbus_close (fd.fd, NULL);
1455  fd.fd = -1;
1456  tmp = tmp->ai_next;
1457  continue;
1458  }
1459 
1460  break;
1461  }
1462  freeaddrinfo(ai);
1463 
1464  if (fd.fd == -1)
1465  {
1466  dbus_set_error (error,
1467  _dbus_error_from_errno (saved_errno),
1468  "Failed to connect to socket \"%s:%s\" %s",
1469  host, port, _dbus_strerror(saved_errno));
1470  return _dbus_socket_get_invalid ();
1471  }
1472 
1473  if (noncefile != NULL)
1474  {
1475  DBusString noncefileStr;
1476  dbus_bool_t ret;
1477  _dbus_string_init_const (&noncefileStr, noncefile);
1478  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1479  _dbus_string_free (&noncefileStr);
1480 
1481  if (!ret)
1482  {
1483  _dbus_close (fd.fd, NULL);
1484  return _dbus_socket_get_invalid ();
1485  }
1486  }
1487 
1488  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1489  {
1490  _dbus_close (fd.fd, NULL);
1491  return _dbus_socket_get_invalid ();
1492  }
1493 
1494  return fd;
1495 }
1496 
1513 int
1514 _dbus_listen_tcp_socket (const char *host,
1515  const char *port,
1516  const char *family,
1517  DBusString *retport,
1518  DBusSocket **fds_p,
1519  DBusError *error)
1520 {
1521  int saved_errno;
1522  int nlisten_fd = 0, res, i;
1523  DBusSocket *listen_fd = NULL;
1524  struct addrinfo hints;
1525  struct addrinfo *ai, *tmp;
1526  unsigned int reuseaddr;
1527 
1528  *fds_p = NULL;
1529  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1530 
1531  _DBUS_ZERO (hints);
1532 
1533  if (!family)
1534  hints.ai_family = AF_UNSPEC;
1535  else if (!strcmp(family, "ipv4"))
1536  hints.ai_family = AF_INET;
1537  else if (!strcmp(family, "ipv6"))
1538  hints.ai_family = AF_INET6;
1539  else
1540  {
1541  dbus_set_error (error,
1543  "Unknown address family %s", family);
1544  return -1;
1545  }
1546 
1547  hints.ai_protocol = IPPROTO_TCP;
1548  hints.ai_socktype = SOCK_STREAM;
1549  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1550 
1551  redo_lookup_with_port:
1552  ai = NULL;
1553  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1554  {
1555  dbus_set_error (error,
1556  _dbus_error_from_gai (res, errno),
1557  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1558  host ? host : "*", port, gai_strerror(res), res);
1559  goto failed;
1560  }
1561 
1562  tmp = ai;
1563  while (tmp)
1564  {
1565  int fd = -1, tcp_nodelay_on;
1566  DBusSocket *newlisten_fd;
1567 
1568  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1569  {
1570  _DBUS_ASSERT_ERROR_IS_SET(error);
1571  goto failed;
1572  }
1573  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1574 
1575  reuseaddr = 1;
1576  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1577  {
1578  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1579  host ? host : "*", port, _dbus_strerror (errno));
1580  }
1581 
1582  /* Nagle's algorithm imposes a huge delay on the initial messages
1583  going over TCP. */
1584  tcp_nodelay_on = 1;
1585  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1586  {
1587  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1588  host ? host : "*", port, _dbus_strerror (errno));
1589  }
1590 
1591  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1592  {
1593  saved_errno = errno;
1594  _dbus_close(fd, NULL);
1595  if (saved_errno == EADDRINUSE)
1596  {
1597  /* Depending on kernel policy, binding to an IPv6 address
1598  might implicitly bind to a corresponding IPv4
1599  address or vice versa, resulting in EADDRINUSE for the
1600  other one (e.g. bindv6only=0 on Linux).
1601 
1602  Also, after we "goto redo_lookup_with_port" after binding
1603  a port on one of the possible addresses, we will
1604  try to bind that same port on every address, including the
1605  same address again for a second time; that one will
1606  also fail with EADDRINUSE.
1607 
1608  For both those reasons, ignore EADDRINUSE here */
1609  tmp = tmp->ai_next;
1610  continue;
1611  }
1612  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1613  "Failed to bind socket \"%s:%s\": %s",
1614  host ? host : "*", port, _dbus_strerror (saved_errno));
1615  goto failed;
1616  }
1617 
1618  if (listen (fd, 30 /* backlog */) < 0)
1619  {
1620  saved_errno = errno;
1621  _dbus_close (fd, NULL);
1622  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1623  "Failed to listen on socket \"%s:%s\": %s",
1624  host ? host : "*", port, _dbus_strerror (saved_errno));
1625  goto failed;
1626  }
1627 
1628  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1629  if (!newlisten_fd)
1630  {
1631  _dbus_close (fd, NULL);
1633  "Failed to allocate file handle array");
1634  goto failed;
1635  }
1636  listen_fd = newlisten_fd;
1637  listen_fd[nlisten_fd].fd = fd;
1638  nlisten_fd++;
1639 
1640  if (!_dbus_string_get_length(retport))
1641  {
1642  /* If the user didn't specify a port, or used 0, then
1643  the kernel chooses a port. After the first address
1644  is bound to, we need to force all remaining addresses
1645  to use the same port */
1646  if (!port || !strcmp(port, "0"))
1647  {
1648  int result;
1649  struct sockaddr_storage addr;
1650  socklen_t addrlen;
1651  char portbuf[50];
1652 
1653  addrlen = sizeof(addr);
1654  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1655 
1656  if (result == -1)
1657  {
1658  saved_errno = errno;
1659  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1660  "Failed to retrieve socket name for \"%s:%s\": %s",
1661  host ? host : "*", port, _dbus_strerror (saved_errno));
1662  goto failed;
1663  }
1664 
1665  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1666  portbuf, sizeof(portbuf),
1667  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1668  {
1669  saved_errno = errno;
1670  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1671  "Failed to resolve port \"%s:%s\": %s (%d)",
1672  host ? host : "*", port, gai_strerror(res), res);
1673  goto failed;
1674  }
1675 
1676  if (!_dbus_string_append(retport, portbuf))
1677  {
1679  goto failed;
1680  }
1681 
1682  /* Release current address list & redo lookup */
1683  port = _dbus_string_get_const_data(retport);
1684  freeaddrinfo(ai);
1685  goto redo_lookup_with_port;
1686  }
1687  else
1688  {
1689  if (!_dbus_string_append(retport, port))
1690  {
1692  goto failed;
1693  }
1694  }
1695  }
1696 
1697  tmp = tmp->ai_next;
1698  }
1699  freeaddrinfo(ai);
1700  ai = NULL;
1701 
1702  if (!nlisten_fd)
1703  {
1704  errno = EADDRINUSE;
1705  dbus_set_error (error, _dbus_error_from_errno (errno),
1706  "Failed to bind socket \"%s:%s\": %s",
1707  host ? host : "*", port, _dbus_strerror (errno));
1708  goto failed;
1709  }
1710 
1711  for (i = 0 ; i < nlisten_fd ; i++)
1712  {
1713  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1714  {
1715  goto failed;
1716  }
1717  }
1718 
1719  *fds_p = listen_fd;
1720 
1721  return nlisten_fd;
1722 
1723  failed:
1724  if (ai)
1725  freeaddrinfo(ai);
1726  for (i = 0 ; i < nlisten_fd ; i++)
1727  _dbus_close(listen_fd[i].fd, NULL);
1728  dbus_free(listen_fd);
1729  return -1;
1730 }
1731 
1732 static dbus_bool_t
1733 write_credentials_byte (int server_fd,
1734  DBusError *error)
1735 {
1736  int bytes_written;
1737  char buf[1] = { '\0' };
1738 #if defined(HAVE_CMSGCRED)
1739  union {
1740  struct cmsghdr hdr;
1741  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1742  } cmsg;
1743  struct iovec iov;
1744  struct msghdr msg;
1745  iov.iov_base = buf;
1746  iov.iov_len = 1;
1747 
1748  _DBUS_ZERO(msg);
1749  msg.msg_iov = &iov;
1750  msg.msg_iovlen = 1;
1751 
1752  msg.msg_control = (caddr_t) &cmsg;
1753  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1754  _DBUS_ZERO(cmsg);
1755  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1756  cmsg.hdr.cmsg_level = SOL_SOCKET;
1757  cmsg.hdr.cmsg_type = SCM_CREDS;
1758 #endif
1759 
1760  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1761 
1762  again:
1763 
1764 #if defined(HAVE_CMSGCRED)
1765  bytes_written = sendmsg (server_fd, &msg, 0
1766 #if HAVE_DECL_MSG_NOSIGNAL
1767  |MSG_NOSIGNAL
1768 #endif
1769  );
1770 
1771  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1772  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1773  * only allows that on AF_UNIX. Try just doing a send() instead. */
1774  if (bytes_written < 0 && errno == EINVAL)
1775 #endif
1776  {
1777  bytes_written = send (server_fd, buf, 1, 0
1778 #if HAVE_DECL_MSG_NOSIGNAL
1779  |MSG_NOSIGNAL
1780 #endif
1781  );
1782  }
1783 
1784  if (bytes_written < 0 && errno == EINTR)
1785  goto again;
1786 
1787  if (bytes_written < 0)
1788  {
1789  dbus_set_error (error, _dbus_error_from_errno (errno),
1790  "Failed to write credentials byte: %s",
1791  _dbus_strerror (errno));
1792  return FALSE;
1793  }
1794  else if (bytes_written == 0)
1795  {
1797  "wrote zero bytes writing credentials byte");
1798  return FALSE;
1799  }
1800  else
1801  {
1802  _dbus_assert (bytes_written == 1);
1803  _dbus_verbose ("wrote credentials byte\n");
1804  return TRUE;
1805  }
1806 }
1807 
1808 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1809 static dbus_bool_t
1810 add_linux_security_label_to_credentials (int client_fd,
1811  DBusCredentials *credentials)
1812 {
1813 #if defined(__linux__) && defined(SO_PEERSEC)
1814  DBusString buf;
1815  socklen_t len = 1024;
1816  dbus_bool_t oom = FALSE;
1817 
1818  if (!_dbus_string_init_preallocated (&buf, len) ||
1819  !_dbus_string_set_length (&buf, len))
1820  return FALSE;
1821 
1822  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1823  _dbus_string_get_data (&buf), &len) < 0)
1824  {
1825  int e = errno;
1826 
1827  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1828  _dbus_strerror (e), (unsigned long) len);
1829 
1830  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1831  {
1832  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1833  _dbus_strerror (e));
1834  goto out;
1835  }
1836 
1837  /* If not enough space, len is updated to be enough.
1838  * Try again with a large enough buffer. */
1839  if (!_dbus_string_set_length (&buf, len))
1840  {
1841  oom = TRUE;
1842  goto out;
1843  }
1844 
1845  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1846  }
1847 
1848  if (len <= 0)
1849  {
1850  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1851  (unsigned long) len);
1852  goto out;
1853  }
1854 
1855  if (len > _dbus_string_get_length_uint (&buf))
1856  {
1857  _dbus_verbose ("%lu > %u", (unsigned long) len,
1858  _dbus_string_get_length_uint (&buf));
1859  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1860  }
1861 
1862  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1863  {
1864  /* the kernel included the trailing \0 in its count,
1865  * but DBusString always has an extra \0 after the data anyway */
1866  _dbus_verbose ("subtracting trailing \\0\n");
1867  len--;
1868  }
1869 
1870  if (!_dbus_string_set_length (&buf, len))
1871  {
1872  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1873  oom = TRUE;
1874  goto out;
1875  }
1876 
1877  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1878  {
1879  /* LSM people on the linux-security-module@ mailing list say this
1880  * should never happen: the label should be a bytestring with
1881  * an optional trailing \0 */
1882  _dbus_verbose ("security label from kernel had an embedded \\0, "
1883  "ignoring it\n");
1884  goto out;
1885  }
1886 
1887  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1888  (unsigned long) len,
1890 
1893  {
1894  oom = TRUE;
1895  goto out;
1896  }
1897 
1898 out:
1899  _dbus_string_free (&buf);
1900  return !oom;
1901 #else
1902  /* no error */
1903  return TRUE;
1904 #endif
1905 }
1906 
1949  DBusCredentials *credentials,
1950  DBusError *error)
1951 {
1952  struct msghdr msg;
1953  struct iovec iov;
1954  char buf;
1955  dbus_uid_t uid_read;
1956  dbus_pid_t pid_read;
1957  int bytes_read;
1958 
1959 #ifdef HAVE_CMSGCRED
1960  union {
1961  struct cmsghdr hdr;
1962  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1963  } cmsg;
1964 #endif
1965 
1966  /* The POSIX spec certainly doesn't promise this, but
1967  * we need these assertions to fail as soon as we're wrong about
1968  * it so we can do the porting fixups
1969  */
1970  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1971  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1972  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1973 
1974  uid_read = DBUS_UID_UNSET;
1975  pid_read = DBUS_PID_UNSET;
1976 
1977  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1978 
1979  _dbus_credentials_clear (credentials);
1980 
1981  iov.iov_base = &buf;
1982  iov.iov_len = 1;
1983 
1984  _DBUS_ZERO(msg);
1985  msg.msg_iov = &iov;
1986  msg.msg_iovlen = 1;
1987 
1988 #if defined(HAVE_CMSGCRED)
1989  _DBUS_ZERO(cmsg);
1990  msg.msg_control = (caddr_t) &cmsg;
1991  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1992 #endif
1993 
1994  again:
1995  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1996 
1997  if (bytes_read < 0)
1998  {
1999  if (errno == EINTR)
2000  goto again;
2001 
2002  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2003  * normally only call read_credentials if the socket was ready
2004  * for reading
2005  */
2006 
2007  dbus_set_error (error, _dbus_error_from_errno (errno),
2008  "Failed to read credentials byte: %s",
2009  _dbus_strerror (errno));
2010  return FALSE;
2011  }
2012  else if (bytes_read == 0)
2013  {
2014  /* this should not happen unless we are using recvmsg wrong,
2015  * so is essentially here for paranoia
2016  */
2018  "Failed to read credentials byte (zero-length read)");
2019  return FALSE;
2020  }
2021  else if (buf != '\0')
2022  {
2024  "Credentials byte was not nul");
2025  return FALSE;
2026  }
2027 
2028  _dbus_verbose ("read credentials byte\n");
2029 
2030  {
2031 #ifdef SO_PEERCRED
2032  /* Supported by at least Linux and OpenBSD, with minor differences.
2033  *
2034  * This mechanism passes the process ID through and does not require
2035  * the peer's cooperation, so we prefer it over all others. Notably,
2036  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2037  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2038  * because this is much less fragile.
2039  */
2040 #ifdef __OpenBSD__
2041  struct sockpeercred cr;
2042 #else
2043  struct ucred cr;
2044 #endif
2045  socklen_t cr_len = sizeof (cr);
2046 
2047  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2048  {
2049  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2050  _dbus_strerror (errno));
2051  }
2052  else if (cr_len != sizeof (cr))
2053  {
2054  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2055  cr_len, (int) sizeof (cr));
2056  }
2057  else
2058  {
2059  pid_read = cr.pid;
2060  uid_read = cr.uid;
2061  }
2062 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2063  /* Another variant of the above - used on NetBSD
2064  */
2065  struct unpcbid cr;
2066  socklen_t cr_len = sizeof (cr);
2067 
2068  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2069  {
2070  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2071  _dbus_strerror (errno));
2072  }
2073  else if (cr_len != sizeof (cr))
2074  {
2075  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2076  cr_len, (int) sizeof (cr));
2077  }
2078  else
2079  {
2080  pid_read = cr.unp_pid;
2081  uid_read = cr.unp_euid;
2082  }
2083 #elif defined(HAVE_CMSGCRED)
2084  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2085  * presence of that struct implies SCM_CREDS. Supported by at least
2086  * FreeBSD and DragonflyBSD.
2087  *
2088  * This mechanism requires the peer to help us (it has to send us a
2089  * SCM_CREDS message) but it does pass the process ID through,
2090  * which makes it better than getpeereid().
2091  */
2092  struct cmsgcred *cred;
2093  struct cmsghdr *cmsgp;
2094 
2095  for (cmsgp = CMSG_FIRSTHDR (&msg);
2096  cmsgp != NULL;
2097  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2098  {
2099  if (cmsgp->cmsg_type == SCM_CREDS &&
2100  cmsgp->cmsg_level == SOL_SOCKET &&
2101  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2102  {
2103  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2104  pid_read = cred->cmcred_pid;
2105  uid_read = cred->cmcred_euid;
2106  break;
2107  }
2108  }
2109 
2110 #elif defined(HAVE_GETPEERUCRED)
2111  /* Supported in at least Solaris >= 10. It should probably be higher
2112  * up this list, because it carries the pid and we use this code path
2113  * for audit data. */
2114  ucred_t * ucred = NULL;
2115  if (getpeerucred (client_fd.fd, &ucred) == 0)
2116  {
2117 #ifdef HAVE_ADT
2118  adt_session_data_t *adth = NULL;
2119 #endif
2120  pid_read = ucred_getpid (ucred);
2121  uid_read = ucred_geteuid (ucred);
2122 #ifdef HAVE_ADT
2123  /* generate audit session data based on socket ucred */
2124  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2125  {
2126  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2127  }
2128  else
2129  {
2130  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2131  {
2132  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2133  }
2134  else
2135  {
2136  adt_export_data_t *data = NULL;
2137  size_t size = adt_export_session_data (adth, &data);
2138  if (size <= 0)
2139  {
2140  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2141  }
2142  else
2143  {
2144  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2145  free (data);
2146  }
2147  }
2148  (void) adt_end_session (adth);
2149  }
2150 #endif /* HAVE_ADT */
2151  }
2152  else
2153  {
2154  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2155  }
2156  if (ucred != NULL)
2157  ucred_free (ucred);
2158 
2159  /* ----------------------------------------------------------------
2160  * When adding new mechanisms, please add them above this point
2161  * if they support passing the process ID through, or below if not.
2162  * ---------------------------------------------------------------- */
2163 
2164 #elif defined(HAVE_GETPEEREID)
2165  /* getpeereid() originates from D.J. Bernstein and is fairly
2166  * widely-supported. According to a web search, it might be present in
2167  * any/all of:
2168  *
2169  * - AIX?
2170  * - Blackberry?
2171  * - Cygwin
2172  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2173  * - Mac OS X
2174  * - Minix 3.1.8+
2175  * - MirBSD?
2176  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2177  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2178  * - QNX?
2179  */
2180  uid_t euid;
2181  gid_t egid;
2182  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2183  {
2184  uid_read = euid;
2185  }
2186  else
2187  {
2188  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2189  }
2190 #else /* no supported mechanism */
2191 
2192 #warning Socket credentials not supported on this Unix OS
2193 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2194 
2195  /* Please add other operating systems known to support at least one of
2196  * the mechanisms above to this list, keeping alphabetical order.
2197  * Everything not in this list is best-effort.
2198  */
2199 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2200  defined(__linux__) || \
2201  defined(__OpenBSD__) || \
2202  defined(__NetBSD__)
2203 # error Credentials passing not working on this OS is a regression!
2204 #endif
2205 
2206  _dbus_verbose ("Socket credentials not supported on this OS\n");
2207 #endif
2208  }
2209 
2210  _dbus_verbose ("Credentials:"
2211  " pid "DBUS_PID_FORMAT
2212  " uid "DBUS_UID_FORMAT
2213  "\n",
2214  pid_read,
2215  uid_read);
2216 
2217  if (pid_read != DBUS_PID_UNSET)
2218  {
2219  if (!_dbus_credentials_add_pid (credentials, pid_read))
2220  {
2221  _DBUS_SET_OOM (error);
2222  return FALSE;
2223  }
2224  }
2225 
2226  if (uid_read != DBUS_UID_UNSET)
2227  {
2228  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2229  {
2230  _DBUS_SET_OOM (error);
2231  return FALSE;
2232  }
2233  }
2234 
2235  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2236  {
2237  _DBUS_SET_OOM (error);
2238  return FALSE;
2239  }
2240 
2241  return TRUE;
2242 }
2243 
2263  DBusError *error)
2264 {
2265  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2266 
2267  if (write_credentials_byte (server_fd.fd, error))
2268  return TRUE;
2269  else
2270  return FALSE;
2271 }
2272 
2282 DBusSocket
2284 {
2285  DBusSocket client_fd;
2286  struct sockaddr addr;
2287  socklen_t addrlen;
2288 #ifdef HAVE_ACCEPT4
2289  dbus_bool_t cloexec_done;
2290 #endif
2291 
2292  addrlen = sizeof (addr);
2293 
2294  retry:
2295 
2296 #ifdef HAVE_ACCEPT4
2297  /*
2298  * At compile-time, we assume that if accept4() is available in
2299  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2300  * not necessarily true that either is supported by the running kernel.
2301  */
2302  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2303  cloexec_done = client_fd.fd >= 0;
2304 
2305  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2306 #endif
2307  {
2308  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2309  }
2310 
2311  if (client_fd.fd < 0)
2312  {
2313  if (errno == EINTR)
2314  goto retry;
2315  }
2316 
2317  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2318 
2319 #ifdef HAVE_ACCEPT4
2320  if (!cloexec_done)
2321 #endif
2322  {
2323  _dbus_fd_set_close_on_exec(client_fd.fd);
2324  }
2325 
2326  return client_fd;
2327 }
2328 
2339 {
2340  const char *directory;
2341  struct stat sb;
2342 
2343  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2344 
2345  directory = _dbus_string_get_const_data (dir);
2346 
2347  if (stat (directory, &sb) < 0)
2348  {
2349  dbus_set_error (error, _dbus_error_from_errno (errno),
2350  "%s", _dbus_strerror (errno));
2351 
2352  return FALSE;
2353  }
2354 
2355  if (sb.st_uid != geteuid ())
2356  {
2358  "%s directory is owned by user %lu, not %lu",
2359  directory,
2360  (unsigned long) sb.st_uid,
2361  (unsigned long) geteuid ());
2362  return FALSE;
2363  }
2364 
2365  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2366  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2367  {
2369  "%s directory is not private to the user", directory);
2370  return FALSE;
2371  }
2372 
2373  return TRUE;
2374 }
2375 
2376 static dbus_bool_t
2377 fill_user_info_from_passwd (struct passwd *p,
2378  DBusUserInfo *info,
2379  DBusError *error)
2380 {
2381  _dbus_assert (p->pw_name != NULL);
2382  _dbus_assert (p->pw_dir != NULL);
2383 
2384  info->uid = p->pw_uid;
2385  info->primary_gid = p->pw_gid;
2386  info->username = _dbus_strdup (p->pw_name);
2387  info->homedir = _dbus_strdup (p->pw_dir);
2388 
2389  if (info->username == NULL ||
2390  info->homedir == NULL)
2391  {
2393  return FALSE;
2394  }
2395 
2396  return TRUE;
2397 }
2398 
2399 static dbus_bool_t
2400 fill_user_info (DBusUserInfo *info,
2401  dbus_uid_t uid,
2402  const DBusString *username,
2403  DBusError *error)
2404 {
2405  const char *username_c;
2406 
2407  /* exactly one of username/uid provided */
2408  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2409  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2410 
2411  info->uid = DBUS_UID_UNSET;
2412  info->primary_gid = DBUS_GID_UNSET;
2413  info->group_ids = NULL;
2414  info->n_group_ids = 0;
2415  info->username = NULL;
2416  info->homedir = NULL;
2417 
2418  if (username != NULL)
2419  username_c = _dbus_string_get_const_data (username);
2420  else
2421  username_c = NULL;
2422 
2423  /* For now assuming that the getpwnam() and getpwuid() flavors
2424  * are always symmetrical, if not we have to add more configure
2425  * checks
2426  */
2427 
2428 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2429  {
2430  struct passwd *p;
2431  int result;
2432  size_t buflen;
2433  char *buf;
2434  struct passwd p_str;
2435 
2436  /* retrieve maximum needed size for buf */
2437  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2438 
2439  /* sysconf actually returns a long, but everything else expects size_t,
2440  * so just recast here.
2441  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2442  */
2443  if ((long) buflen <= 0)
2444  buflen = 1024;
2445 
2446  result = -1;
2447  while (1)
2448  {
2449  buf = dbus_malloc (buflen);
2450  if (buf == NULL)
2451  {
2453  return FALSE;
2454  }
2455 
2456  p = NULL;
2457 #ifdef HAVE_POSIX_GETPWNAM_R
2458  if (uid != DBUS_UID_UNSET)
2459  result = getpwuid_r (uid, &p_str, buf, buflen,
2460  &p);
2461  else
2462  result = getpwnam_r (username_c, &p_str, buf, buflen,
2463  &p);
2464 #else
2465  if (uid != DBUS_UID_UNSET)
2466  p = getpwuid_r (uid, &p_str, buf, buflen);
2467  else
2468  p = getpwnam_r (username_c, &p_str, buf, buflen);
2469  result = 0;
2470 #endif /* !HAVE_POSIX_GETPWNAM_R */
2471  //Try a bigger buffer if ERANGE was returned
2472  if (result == ERANGE && buflen < 512 * 1024)
2473  {
2474  dbus_free (buf);
2475  buflen *= 2;
2476  }
2477  else
2478  {
2479  break;
2480  }
2481  }
2482  if (result == 0 && p == &p_str)
2483  {
2484  if (!fill_user_info_from_passwd (p, info, error))
2485  {
2486  dbus_free (buf);
2487  return FALSE;
2488  }
2489  dbus_free (buf);
2490  }
2491  else
2492  {
2493  dbus_set_error (error, _dbus_error_from_errno (errno),
2494  "User \"%s\" unknown or no memory to allocate password entry\n",
2495  username_c ? username_c : "???");
2496  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2497  dbus_free (buf);
2498  return FALSE;
2499  }
2500  }
2501 #else /* ! HAVE_GETPWNAM_R */
2502  {
2503  /* I guess we're screwed on thread safety here */
2504  struct passwd *p;
2505 
2506  if (uid != DBUS_UID_UNSET)
2507  p = getpwuid (uid);
2508  else
2509  p = getpwnam (username_c);
2510 
2511  if (p != NULL)
2512  {
2513  if (!fill_user_info_from_passwd (p, info, error))
2514  {
2515  return FALSE;
2516  }
2517  }
2518  else
2519  {
2520  dbus_set_error (error, _dbus_error_from_errno (errno),
2521  "User \"%s\" unknown or no memory to allocate password entry\n",
2522  username_c ? username_c : "???");
2523  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2524  return FALSE;
2525  }
2526  }
2527 #endif /* ! HAVE_GETPWNAM_R */
2528 
2529  /* Fill this in so we can use it to get groups */
2530  username_c = info->username;
2531 
2532 #ifdef HAVE_GETGROUPLIST
2533  {
2534  gid_t *buf;
2535  int buf_count;
2536  int i;
2537  int initial_buf_count;
2538 
2539  initial_buf_count = 17;
2540  buf_count = initial_buf_count;
2541  buf = dbus_new (gid_t, buf_count);
2542  if (buf == NULL)
2543  {
2545  goto failed;
2546  }
2547 
2548  if (getgrouplist (username_c,
2549  info->primary_gid,
2550  buf, &buf_count) < 0)
2551  {
2552  gid_t *new;
2553  /* Presumed cause of negative return code: buf has insufficient
2554  entries to hold the entire group list. The Linux behavior in this
2555  case is to pass back the actual number of groups in buf_count, but
2556  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2557  So as a hack, try to help out a bit by guessing a larger
2558  number of groups, within reason.. might still fail, of course,
2559  but we can at least print a more informative message. I looked up
2560  the "right way" to do this by downloading Apple's own source code
2561  for the "id" command, and it turns out that they use an
2562  undocumented library function getgrouplist_2 (!) which is not
2563  declared in any header in /usr/include (!!). That did not seem
2564  like the way to go here.
2565  */
2566  if (buf_count == initial_buf_count)
2567  {
2568  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2569  }
2570  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2571  if (new == NULL)
2572  {
2574  dbus_free (buf);
2575  goto failed;
2576  }
2577 
2578  buf = new;
2579 
2580  errno = 0;
2581  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2582  {
2583  if (errno == 0)
2584  {
2585  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2586  username_c, buf_count, buf_count);
2587  }
2588  else
2589  {
2590  dbus_set_error (error,
2591  _dbus_error_from_errno (errno),
2592  "Failed to get groups for username \"%s\" primary GID "
2593  DBUS_GID_FORMAT ": %s\n",
2594  username_c, info->primary_gid,
2595  _dbus_strerror (errno));
2596  dbus_free (buf);
2597  goto failed;
2598  }
2599  }
2600  }
2601 
2602  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2603  if (info->group_ids == NULL)
2604  {
2606  dbus_free (buf);
2607  goto failed;
2608  }
2609 
2610  for (i = 0; i < buf_count; ++i)
2611  info->group_ids[i] = buf[i];
2612 
2613  info->n_group_ids = buf_count;
2614 
2615  dbus_free (buf);
2616  }
2617 #else /* HAVE_GETGROUPLIST */
2618  {
2619  /* We just get the one group ID */
2620  info->group_ids = dbus_new (dbus_gid_t, 1);
2621  if (info->group_ids == NULL)
2622  {
2624  goto failed;
2625  }
2626 
2627  info->n_group_ids = 1;
2628 
2629  (info->group_ids)[0] = info->primary_gid;
2630  }
2631 #endif /* HAVE_GETGROUPLIST */
2632 
2633  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2634 
2635  return TRUE;
2636 
2637  failed:
2638  _DBUS_ASSERT_ERROR_IS_SET (error);
2639  return FALSE;
2640 }
2641 
2652  const DBusString *username,
2653  DBusError *error)
2654 {
2655  return fill_user_info (info, DBUS_UID_UNSET,
2656  username, error);
2657 }
2658 
2669  dbus_uid_t uid,
2670  DBusError *error)
2671 {
2672  return fill_user_info (info, uid,
2673  NULL, error);
2674 }
2675 
2685 {
2686  /* The POSIX spec certainly doesn't promise this, but
2687  * we need these assertions to fail as soon as we're wrong about
2688  * it so we can do the porting fixups
2689  */
2690  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2691  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2692  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2693 
2694  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2695  return FALSE;
2696  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2697  return FALSE;
2698 
2699  return TRUE;
2700 }
2701 
2715 {
2716  return _dbus_string_append_uint (str,
2717  _dbus_geteuid ());
2718 }
2719 
2724 dbus_pid_t
2726 {
2727  return getpid ();
2728 }
2729 
2733 dbus_uid_t
2735 {
2736  return getuid ();
2737 }
2738 
2742 dbus_uid_t
2744 {
2745  return geteuid ();
2746 }
2747 
2754 unsigned long
2756 {
2757  return getpid ();
2758 }
2759 
2768 _dbus_parse_uid (const DBusString *uid_str,
2769  dbus_uid_t *uid)
2770 {
2771  int end;
2772  long val;
2773 
2774  if (_dbus_string_get_length (uid_str) == 0)
2775  {
2776  _dbus_verbose ("UID string was zero length\n");
2777  return FALSE;
2778  }
2779 
2780  val = -1;
2781  end = 0;
2782  if (!_dbus_string_parse_int (uid_str, 0, &val,
2783  &end))
2784  {
2785  _dbus_verbose ("could not parse string as a UID\n");
2786  return FALSE;
2787  }
2788 
2789  if (end != _dbus_string_get_length (uid_str))
2790  {
2791  _dbus_verbose ("string contained trailing stuff after UID\n");
2792  return FALSE;
2793  }
2794 
2795  *uid = val;
2796 
2797  return TRUE;
2798 }
2799 
2800 #if !DBUS_USE_SYNC
2801 /* To be thread-safe by default on platforms that don't necessarily have
2802  * atomic operations (notably Debian armel, which is armv4t), we must
2803  * use a mutex that can be initialized statically, like this.
2804  * GLib >= 2.32 uses a similar system.
2805  */
2806 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2807 #endif
2808 
2817 {
2818 #if DBUS_USE_SYNC
2819  return __sync_add_and_fetch(&atomic->value, 1)-1;
2820 #else
2821  dbus_int32_t res;
2822 
2823  pthread_mutex_lock (&atomic_mutex);
2824  res = atomic->value;
2825  atomic->value += 1;
2826  pthread_mutex_unlock (&atomic_mutex);
2827 
2828  return res;
2829 #endif
2830 }
2831 
2840 {
2841 #if DBUS_USE_SYNC
2842  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2843 #else
2844  dbus_int32_t res;
2845 
2846  pthread_mutex_lock (&atomic_mutex);
2847  res = atomic->value;
2848  atomic->value -= 1;
2849  pthread_mutex_unlock (&atomic_mutex);
2850 
2851  return res;
2852 #endif
2853 }
2854 
2864 {
2865 #if DBUS_USE_SYNC
2866  __sync_synchronize ();
2867  return atomic->value;
2868 #else
2869  dbus_int32_t res;
2870 
2871  pthread_mutex_lock (&atomic_mutex);
2872  res = atomic->value;
2873  pthread_mutex_unlock (&atomic_mutex);
2874 
2875  return res;
2876 #endif
2877 }
2878 
2887 int
2889  int n_fds,
2890  int timeout_milliseconds)
2891 {
2892 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2893  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2894  if (timeout_milliseconds < -1)
2895  {
2896  timeout_milliseconds = -1;
2897  }
2898 
2899  return poll (fds,
2900  n_fds,
2901  timeout_milliseconds);
2902 #else /* ! HAVE_POLL */
2903  /* Emulate poll() in terms of select() */
2904  fd_set read_set, write_set, err_set;
2905  int max_fd = 0;
2906  int i;
2907  struct timeval tv;
2908  int ready;
2909 
2910  FD_ZERO (&read_set);
2911  FD_ZERO (&write_set);
2912  FD_ZERO (&err_set);
2913 
2914  for (i = 0; i < n_fds; i++)
2915  {
2916  DBusPollFD *fdp = &fds[i];
2917 
2918  if (fdp->events & _DBUS_POLLIN)
2919  FD_SET (fdp->fd, &read_set);
2920 
2921  if (fdp->events & _DBUS_POLLOUT)
2922  FD_SET (fdp->fd, &write_set);
2923 
2924  FD_SET (fdp->fd, &err_set);
2925 
2926  max_fd = MAX (max_fd, fdp->fd);
2927  }
2928 
2929  tv.tv_sec = timeout_milliseconds / 1000;
2930  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2931 
2932  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2933  timeout_milliseconds < 0 ? NULL : &tv);
2934 
2935  if (ready > 0)
2936  {
2937  for (i = 0; i < n_fds; i++)
2938  {
2939  DBusPollFD *fdp = &fds[i];
2940 
2941  fdp->revents = 0;
2942 
2943  if (FD_ISSET (fdp->fd, &read_set))
2944  fdp->revents |= _DBUS_POLLIN;
2945 
2946  if (FD_ISSET (fdp->fd, &write_set))
2947  fdp->revents |= _DBUS_POLLOUT;
2948 
2949  if (FD_ISSET (fdp->fd, &err_set))
2950  fdp->revents |= _DBUS_POLLERR;
2951  }
2952  }
2953 
2954  return ready;
2955 #endif
2956 }
2957 
2965 void
2967  long *tv_usec)
2968 {
2969 #ifdef HAVE_MONOTONIC_CLOCK
2970  struct timespec ts;
2971  clock_gettime (CLOCK_MONOTONIC, &ts);
2972 
2973  if (tv_sec)
2974  *tv_sec = ts.tv_sec;
2975  if (tv_usec)
2976  *tv_usec = ts.tv_nsec / 1000;
2977 #else
2978  struct timeval t;
2979 
2980  gettimeofday (&t, NULL);
2981 
2982  if (tv_sec)
2983  *tv_sec = t.tv_sec;
2984  if (tv_usec)
2985  *tv_usec = t.tv_usec;
2986 #endif
2987 }
2988 
2996 void
2997 _dbus_get_real_time (long *tv_sec,
2998  long *tv_usec)
2999 {
3000  struct timeval t;
3001 
3002  gettimeofday (&t, NULL);
3003 
3004  if (tv_sec)
3005  *tv_sec = t.tv_sec;
3006  if (tv_usec)
3007  *tv_usec = t.tv_usec;
3008 }
3009 
3020  DBusError *error)
3021 {
3022  const char *filename_c;
3023 
3024  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3025 
3026  filename_c = _dbus_string_get_const_data (filename);
3027 
3028  if (mkdir (filename_c, 0700) < 0)
3029  {
3030  if (errno == EEXIST)
3031  return TRUE;
3032 
3034  "Failed to create directory %s: %s\n",
3035  filename_c, _dbus_strerror (errno));
3036  return FALSE;
3037  }
3038  else
3039  return TRUE;
3040 }
3041 
3052  DBusError *error)
3053 {
3054  const char *filename_c;
3055 
3056  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3057 
3058  filename_c = _dbus_string_get_const_data (filename);
3059 
3060  if (mkdir (filename_c, 0700) < 0)
3061  {
3063  "Failed to create directory %s: %s\n",
3064  filename_c, _dbus_strerror (errno));
3065  return FALSE;
3066  }
3067  else
3068  return TRUE;
3069 }
3070 
3083  const DBusString *next_component)
3084 {
3085  dbus_bool_t dir_ends_in_slash;
3086  dbus_bool_t file_starts_with_slash;
3087 
3088  if (_dbus_string_get_length (dir) == 0 ||
3089  _dbus_string_get_length (next_component) == 0)
3090  return TRUE;
3091 
3092  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3093  _dbus_string_get_length (dir) - 1);
3094 
3095  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3096 
3097  if (dir_ends_in_slash && file_starts_with_slash)
3098  {
3099  _dbus_string_shorten (dir, 1);
3100  }
3101  else if (!(dir_ends_in_slash || file_starts_with_slash))
3102  {
3103  if (!_dbus_string_append_byte (dir, '/'))
3104  return FALSE;
3105  }
3106 
3107  return _dbus_string_copy (next_component, 0, dir,
3108  _dbus_string_get_length (dir));
3109 }
3110 
3112 #define NANOSECONDS_PER_SECOND 1000000000
3113 
3114 #define MICROSECONDS_PER_SECOND 1000000
3115 
3116 #define MILLISECONDS_PER_SECOND 1000
3117 
3118 #define NANOSECONDS_PER_MILLISECOND 1000000
3119 
3120 #define MICROSECONDS_PER_MILLISECOND 1000
3121 
3126 void
3127 _dbus_sleep_milliseconds (int milliseconds)
3128 {
3129 #ifdef HAVE_NANOSLEEP
3130  struct timespec req;
3131  struct timespec rem;
3132 
3133  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3134  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3135  rem.tv_sec = 0;
3136  rem.tv_nsec = 0;
3137 
3138  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3139  req = rem;
3140 #elif defined (HAVE_USLEEP)
3141  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3142 #else /* ! HAVE_USLEEP */
3143  sleep (MAX (milliseconds / 1000, 1));
3144 #endif
3145 }
3146 
3158  int n_bytes,
3159  DBusError *error)
3160 {
3161  int old_len;
3162  int fd;
3163  int result;
3164 
3165  old_len = _dbus_string_get_length (str);
3166  fd = -1;
3167 
3168  /* note, urandom on linux will fall back to pseudorandom */
3169  fd = open ("/dev/urandom", O_RDONLY);
3170 
3171  if (fd < 0)
3172  {
3173  dbus_set_error (error, _dbus_error_from_errno (errno),
3174  "Could not open /dev/urandom: %s",
3175  _dbus_strerror (errno));
3176  return FALSE;
3177  }
3178 
3179  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3180 
3181  result = _dbus_read (fd, str, n_bytes);
3182 
3183  if (result != n_bytes)
3184  {
3185  if (result < 0)
3186  dbus_set_error (error, _dbus_error_from_errno (errno),
3187  "Could not read /dev/urandom: %s",
3188  _dbus_strerror (errno));
3189  else
3191  "Short read from /dev/urandom");
3192 
3193  _dbus_close (fd, NULL);
3194  _dbus_string_set_length (str, old_len);
3195  return FALSE;
3196  }
3197 
3198  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3199  n_bytes);
3200 
3201  _dbus_close (fd, NULL);
3202 
3203  return TRUE;
3204 }
3205 
3211 void
3212 _dbus_exit (int code)
3213 {
3214  _exit (code);
3215 }
3216 
3225 const char*
3226 _dbus_strerror (int error_number)
3227 {
3228  const char *msg;
3229 
3230  msg = strerror (error_number);
3231  if (msg == NULL)
3232  msg = "unknown";
3233 
3234  return msg;
3235 }
3236 
3240 void
3242 {
3243  signal (SIGPIPE, SIG_IGN);
3244 }
3245 
3253 void
3255 {
3256  int val;
3257 
3258  val = fcntl (fd, F_GETFD, 0);
3259 
3260  if (val < 0)
3261  return;
3262 
3263  val |= FD_CLOEXEC;
3264 
3265  fcntl (fd, F_SETFD, val);
3266 }
3267 
3276 _dbus_close (int fd,
3277  DBusError *error)
3278 {
3279  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3280 
3281  again:
3282  if (close (fd) < 0)
3283  {
3284  if (errno == EINTR)
3285  goto again;
3286 
3287  dbus_set_error (error, _dbus_error_from_errno (errno),
3288  "Could not close fd %d", fd);
3289  return FALSE;
3290  }
3291 
3292  return TRUE;
3293 }
3294 
3303 int
3304 _dbus_dup(int fd,
3305  DBusError *error)
3306 {
3307  int new_fd;
3308 
3309 #ifdef F_DUPFD_CLOEXEC
3310  dbus_bool_t cloexec_done;
3311 
3312  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3313  cloexec_done = new_fd >= 0;
3314 
3315  if (new_fd < 0 && errno == EINVAL)
3316 #endif
3317  {
3318  new_fd = fcntl(fd, F_DUPFD, 3);
3319  }
3320 
3321  if (new_fd < 0) {
3322 
3323  dbus_set_error (error, _dbus_error_from_errno (errno),
3324  "Could not duplicate fd %d", fd);
3325  return -1;
3326  }
3327 
3328 #ifdef F_DUPFD_CLOEXEC
3329  if (!cloexec_done)
3330 #endif
3331  {
3333  }
3334 
3335  return new_fd;
3336 }
3337 
3347  DBusError *error)
3348 {
3349  return _dbus_set_fd_nonblocking (fd.fd, error);
3350 }
3351 
3352 static dbus_bool_t
3353 _dbus_set_fd_nonblocking (int fd,
3354  DBusError *error)
3355 {
3356  int val;
3357 
3358  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3359 
3360  val = fcntl (fd, F_GETFL, 0);
3361  if (val < 0)
3362  {
3363  dbus_set_error (error, _dbus_error_from_errno (errno),
3364  "Failed to get flags from file descriptor %d: %s",
3365  fd, _dbus_strerror (errno));
3366  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3367  _dbus_strerror (errno));
3368  return FALSE;
3369  }
3370 
3371  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3372  {
3373  dbus_set_error (error, _dbus_error_from_errno (errno),
3374  "Failed to set nonblocking flag of file descriptor %d: %s",
3375  fd, _dbus_strerror (errno));
3376  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3377  fd, _dbus_strerror (errno));
3378 
3379  return FALSE;
3380  }
3381 
3382  return TRUE;
3383 }
3384 
3390 void
3392 {
3393 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3394  void *bt[500];
3395  int bt_size;
3396  int i;
3397  char **syms;
3398 
3399  bt_size = backtrace (bt, 500);
3400 
3401  syms = backtrace_symbols (bt, bt_size);
3402 
3403  i = 0;
3404  while (i < bt_size)
3405  {
3406  /* don't use dbus_warn since it can _dbus_abort() */
3407  fprintf (stderr, " %s\n", syms[i]);
3408  ++i;
3409  }
3410  fflush (stderr);
3411 
3412  free (syms);
3413 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3414  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3415 #else
3416  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3417 #endif
3418 }
3419 
3434  DBusSocket *fd2,
3435  dbus_bool_t blocking,
3436  DBusError *error)
3437 {
3438 #ifdef HAVE_SOCKETPAIR
3439  int fds[2];
3440  int retval;
3441 
3442 #ifdef SOCK_CLOEXEC
3443  dbus_bool_t cloexec_done;
3444 
3445  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3446  cloexec_done = retval >= 0;
3447 
3448  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3449 #endif
3450  {
3451  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3452  }
3453 
3454  if (retval < 0)
3455  {
3456  dbus_set_error (error, _dbus_error_from_errno (errno),
3457  "Could not create full-duplex pipe");
3458  return FALSE;
3459  }
3460 
3461  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3462 
3463 #ifdef SOCK_CLOEXEC
3464  if (!cloexec_done)
3465 #endif
3466  {
3467  _dbus_fd_set_close_on_exec (fds[0]);
3468  _dbus_fd_set_close_on_exec (fds[1]);
3469  }
3470 
3471  if (!blocking &&
3472  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3473  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3474  {
3475  dbus_set_error (error, _dbus_error_from_errno (errno),
3476  "Could not set full-duplex pipe nonblocking");
3477 
3478  _dbus_close (fds[0], NULL);
3479  _dbus_close (fds[1], NULL);
3480 
3481  return FALSE;
3482  }
3483 
3484  fd1->fd = fds[0];
3485  fd2->fd = fds[1];
3486 
3487  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3488  fd1->fd, fd2->fd);
3489 
3490  return TRUE;
3491 #else
3492  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3494  "_dbus_socketpair() not implemented on this OS");
3495  return FALSE;
3496 #endif
3497 }
3498 
3507 int
3509  va_list args)
3510 {
3511  char static_buf[1024];
3512  int bufsize = sizeof (static_buf);
3513  int len;
3514  va_list args_copy;
3515 
3516  DBUS_VA_COPY (args_copy, args);
3517  len = vsnprintf (static_buf, bufsize, format, args_copy);
3518  va_end (args_copy);
3519 
3520  /* If vsnprintf() returned non-negative, then either the string fits in
3521  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3522  * returns the number of characters that were needed, or this OS returns the
3523  * truncated length.
3524  *
3525  * We ignore the possibility that snprintf might just ignore the length and
3526  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3527  * If your libc is really that bad, come back when you have a better one. */
3528  if (len == bufsize)
3529  {
3530  /* This could be the truncated length (Tru64 and IRIX have this bug),
3531  * or the real length could be coincidentally the same. Which is it?
3532  * If vsnprintf returns the truncated length, we'll go to the slow
3533  * path. */
3534  DBUS_VA_COPY (args_copy, args);
3535 
3536  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3537  len = -1;
3538 
3539  va_end (args_copy);
3540  }
3541 
3542  /* If vsnprintf() returned negative, we have to do more work.
3543  * HP-UX returns negative. */
3544  while (len < 0)
3545  {
3546  char *buf;
3547 
3548  bufsize *= 2;
3549 
3550  buf = dbus_malloc (bufsize);
3551 
3552  if (buf == NULL)
3553  return -1;
3554 
3555  DBUS_VA_COPY (args_copy, args);
3556  len = vsnprintf (buf, bufsize, format, args_copy);
3557  va_end (args_copy);
3558 
3559  dbus_free (buf);
3560 
3561  /* If the reported length is exactly the buffer size, round up to the
3562  * next size, in case vsnprintf has been returning the truncated
3563  * length */
3564  if (len == bufsize)
3565  len = -1;
3566  }
3567 
3568  return len;
3569 }
3570 
3577 const char*
3579 {
3580  /* Protected by _DBUS_LOCK_sysdeps */
3581  static const char* tmpdir = NULL;
3582 
3583  if (!_DBUS_LOCK (sysdeps))
3584  return NULL;
3585 
3586  if (tmpdir == NULL)
3587  {
3588  /* TMPDIR is what glibc uses, then
3589  * glibc falls back to the P_tmpdir macro which
3590  * just expands to "/tmp"
3591  */
3592  if (tmpdir == NULL)
3593  tmpdir = getenv("TMPDIR");
3594 
3595  /* These two env variables are probably
3596  * broken, but maybe some OS uses them?
3597  */
3598  if (tmpdir == NULL)
3599  tmpdir = getenv("TMP");
3600  if (tmpdir == NULL)
3601  tmpdir = getenv("TEMP");
3602 
3603  /* And this is the sane fallback. */
3604  if (tmpdir == NULL)
3605  tmpdir = "/tmp";
3606  }
3607 
3608  _DBUS_UNLOCK (sysdeps);
3609 
3610  _dbus_assert(tmpdir != NULL);
3611 
3612  return tmpdir;
3613 }
3614 
3615 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3616 
3635 static dbus_bool_t
3636 _read_subprocess_line_argv (const char *progpath,
3637  dbus_bool_t path_fallback,
3638  const char * const *argv,
3639  DBusString *result,
3640  DBusError *error)
3641 {
3642  int result_pipe[2] = { -1, -1 };
3643  int errors_pipe[2] = { -1, -1 };
3644  pid_t pid;
3645  int ret;
3646  int status;
3647  int orig_len;
3648 
3649  dbus_bool_t retval;
3650  sigset_t new_set, old_set;
3651 
3652  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3653  retval = FALSE;
3654 
3655  /* We need to block any existing handlers for SIGCHLD temporarily; they
3656  * will cause waitpid() below to fail.
3657  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3658  */
3659  sigemptyset (&new_set);
3660  sigaddset (&new_set, SIGCHLD);
3661  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3662 
3663  orig_len = _dbus_string_get_length (result);
3664 
3665 #define READ_END 0
3666 #define WRITE_END 1
3667  if (pipe (result_pipe) < 0)
3668  {
3669  dbus_set_error (error, _dbus_error_from_errno (errno),
3670  "Failed to create a pipe to call %s: %s",
3671  progpath, _dbus_strerror (errno));
3672  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3673  progpath, _dbus_strerror (errno));
3674  goto out;
3675  }
3676  if (pipe (errors_pipe) < 0)
3677  {
3678  dbus_set_error (error, _dbus_error_from_errno (errno),
3679  "Failed to create a pipe to call %s: %s",
3680  progpath, _dbus_strerror (errno));
3681  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3682  progpath, _dbus_strerror (errno));
3683  goto out;
3684  }
3685 
3686  pid = fork ();
3687  if (pid < 0)
3688  {
3689  dbus_set_error (error, _dbus_error_from_errno (errno),
3690  "Failed to fork() to call %s: %s",
3691  progpath, _dbus_strerror (errno));
3692  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3693  progpath, _dbus_strerror (errno));
3694  goto out;
3695  }
3696 
3697  if (pid == 0)
3698  {
3699  /* child process */
3700  const char *error_str;
3701 
3702  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3703  {
3704  int saved_errno = errno;
3705 
3706  /* Try to write details into the pipe, but don't bother
3707  * trying too hard (no retry loop). */
3708 
3709  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3710  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3711  {
3712  /* ignore, not much we can do */
3713  }
3714 
3715  error_str = _dbus_strerror (saved_errno);
3716 
3717  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3718  {
3719  /* ignore, not much we can do */
3720  }
3721 
3722  _exit (1);
3723  }
3724 
3725  /* set-up stdXXX */
3726  close (result_pipe[READ_END]);
3727  close (errors_pipe[READ_END]);
3728 
3729  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3730  _exit (1);
3731  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3732  _exit (1);
3733 
3734  _dbus_close_all ();
3735 
3736  sigprocmask (SIG_SETMASK, &old_set, NULL);
3737 
3738  /* If it looks fully-qualified, try execv first */
3739  if (progpath[0] == '/')
3740  {
3741  execv (progpath, (char * const *) argv);
3742  /* Ok, that failed. Now if path_fallback is given, let's
3743  * try unqualified. This is mostly a hack to work
3744  * around systems which ship dbus-launch in /usr/bin
3745  * but everything else in /bin (because dbus-launch
3746  * depends on X11).
3747  */
3748  if (path_fallback)
3749  /* We must have a slash, because we checked above */
3750  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3751  }
3752  else
3753  execvp (progpath, (char * const *) argv);
3754 
3755  /* still nothing, we failed */
3756  _exit (1);
3757  }
3758 
3759  /* parent process */
3760  close (result_pipe[WRITE_END]);
3761  close (errors_pipe[WRITE_END]);
3762  result_pipe[WRITE_END] = -1;
3763  errors_pipe[WRITE_END] = -1;
3764 
3765  ret = 0;
3766  do
3767  {
3768  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3769  }
3770  while (ret > 0);
3771 
3772  /* reap the child process to avoid it lingering as zombie */
3773  do
3774  {
3775  ret = waitpid (pid, &status, 0);
3776  }
3777  while (ret == -1 && errno == EINTR);
3778 
3779  /* We succeeded if the process exited with status 0 and
3780  anything was read */
3781  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3782  {
3783  /* The process ended with error */
3784  DBusString error_message;
3785  if (!_dbus_string_init (&error_message))
3786  {
3787  _DBUS_SET_OOM (error);
3788  goto out;
3789  }
3790 
3791  ret = 0;
3792  do
3793  {
3794  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3795  }
3796  while (ret > 0);
3797 
3798  _dbus_string_set_length (result, orig_len);
3799  if (_dbus_string_get_length (&error_message) > 0)
3801  "%s terminated abnormally with the following error: %s",
3802  progpath, _dbus_string_get_data (&error_message));
3803  else
3805  "%s terminated abnormally without any error message",
3806  progpath);
3807  goto out;
3808  }
3809 
3810  retval = TRUE;
3811 
3812  out:
3813  sigprocmask (SIG_SETMASK, &old_set, NULL);
3814 
3815  if (retval)
3816  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3817  else
3818  _DBUS_ASSERT_ERROR_IS_SET (error);
3819 
3820  if (result_pipe[0] != -1)
3821  close (result_pipe[0]);
3822  if (result_pipe[1] != -1)
3823  close (result_pipe[1]);
3824  if (errors_pipe[0] != -1)
3825  close (errors_pipe[0]);
3826  if (errors_pipe[1] != -1)
3827  close (errors_pipe[1]);
3828 
3829  return retval;
3830 }
3831 #endif
3832 
3846 _dbus_get_autolaunch_address (const char *scope,
3847  DBusString *address,
3848  DBusError *error)
3849 {
3850 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3851  static const char arg_dbus_launch[] = "dbus-launch";
3852  static const char arg_autolaunch[] = "--autolaunch";
3853  static const char arg_binary_syntax[] = "--binary-syntax";
3854  static const char arg_close_stderr[] = "--close-stderr";
3855 
3856  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3857  * but that's done elsewhere, and if it worked, this function wouldn't
3858  * be called.) */
3859  const char *display;
3860  const char *progpath;
3861  const char *argv[6];
3862  int i;
3863  DBusString uuid;
3864  dbus_bool_t retval;
3865 
3866  if (_dbus_check_setuid ())
3867  {
3869  "Unable to autolaunch when setuid");
3870  return FALSE;
3871  }
3872 
3873  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3874  retval = FALSE;
3875 
3876  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3877  * dbus-launch-x11 is just going to fail. Rather than trying to
3878  * run it, we might as well bail out early with a nice error.
3879  *
3880  * This is not strictly true in a world where the user bus exists,
3881  * because dbus-launch --autolaunch knows how to connect to that -
3882  * but if we were going to connect to the user bus, we'd have done
3883  * so before trying autolaunch: in any case. */
3884  display = _dbus_getenv ("DISPLAY");
3885 
3886  if (display == NULL || display[0] == '\0')
3887  {
3889  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3890  return FALSE;
3891  }
3892 
3893  if (!_dbus_string_init (&uuid))
3894  {
3895  _DBUS_SET_OOM (error);
3896  return FALSE;
3897  }
3898 
3899  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3900  {
3901  goto out;
3902  }
3903 
3904 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3905  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3906 
3907  if (progpath == NULL)
3908 #endif
3909  progpath = DBUS_BINDIR "/dbus-launch";
3910  /*
3911  * argv[0] is always dbus-launch, that's the name what we'll
3912  * get from /proc, or ps(1), regardless what the progpath is,
3913  * see fd.o#69716
3914  */
3915  i = 0;
3916  argv[i] = arg_dbus_launch;
3917  ++i;
3918  argv[i] = arg_autolaunch;
3919  ++i;
3920  argv[i] = _dbus_string_get_data (&uuid);
3921  ++i;
3922  argv[i] = arg_binary_syntax;
3923  ++i;
3924  argv[i] = arg_close_stderr;
3925  ++i;
3926  argv[i] = NULL;
3927  ++i;
3928 
3929  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3930 
3931  retval = _read_subprocess_line_argv (progpath,
3932  TRUE,
3933  argv, address, error);
3934 
3935  out:
3936  _dbus_string_free (&uuid);
3937  return retval;
3938 #else
3940  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3941  "set your DBUS_SESSION_BUS_ADDRESS instead");
3942  return FALSE;
3943 #endif
3944 }
3945 
3966  dbus_bool_t create_if_not_found,
3967  DBusError *error)
3968 {
3969  DBusError our_error = DBUS_ERROR_INIT;
3970  DBusError etc_error = DBUS_ERROR_INIT;
3971  DBusString filename;
3972  dbus_bool_t b;
3973 
3974  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3975 
3976  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
3977  if (b)
3978  return TRUE;
3979 
3980  /* Fallback to the system machine ID */
3981  _dbus_string_init_const (&filename, "/etc/machine-id");
3982  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
3983 
3984  if (b)
3985  {
3986  if (create_if_not_found)
3987  {
3988  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3989  * complain if that isn't possible for whatever reason */
3990  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3991  _dbus_write_uuid_file (&filename, machine_id, NULL);
3992  }
3993 
3994  dbus_error_free (&our_error);
3995  return TRUE;
3996  }
3997 
3998  if (!create_if_not_found)
3999  {
4000  dbus_set_error (error, etc_error.name,
4001  "D-Bus library appears to be incorrectly set up: "
4002  "see the manual page for dbus-uuidgen to correct "
4003  "this issue. (%s; %s)",
4004  our_error.message, etc_error.message);
4005  dbus_error_free (&our_error);
4006  dbus_error_free (&etc_error);
4007  return FALSE;
4008  }
4009 
4010  dbus_error_free (&our_error);
4011  dbus_error_free (&etc_error);
4012 
4013  /* if none found, try to make a new one */
4014  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4015 
4016  if (!_dbus_generate_uuid (machine_id, error))
4017  return FALSE;
4018 
4019  return _dbus_write_uuid_file (&filename, machine_id, error);
4020 }
4021 
4031  const char *launchd_env_var,
4032  DBusError *error)
4033 {
4034 #ifdef DBUS_ENABLE_LAUNCHD
4035  char *argv[4];
4036  int i;
4037 
4038  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4039 
4040  if (_dbus_check_setuid ())
4041  {
4043  "Unable to find launchd socket when setuid");
4044  return FALSE;
4045  }
4046 
4047  i = 0;
4048  argv[i] = "launchctl";
4049  ++i;
4050  argv[i] = "getenv";
4051  ++i;
4052  argv[i] = (char*)launchd_env_var;
4053  ++i;
4054  argv[i] = NULL;
4055  ++i;
4056 
4057  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4058 
4059  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4060  {
4061  return FALSE;
4062  }
4063 
4064  /* no error, but no result either */
4065  if (_dbus_string_get_length(socket_path) == 0)
4066  {
4067  return FALSE;
4068  }
4069 
4070  /* strip the carriage-return */
4071  _dbus_string_shorten(socket_path, 1);
4072  return TRUE;
4073 #else /* DBUS_ENABLE_LAUNCHD */
4075  "can't lookup socket from launchd; launchd support not compiled in");
4076  return FALSE;
4077 #endif
4078 }
4079 
4080 #ifdef DBUS_ENABLE_LAUNCHD
4081 static dbus_bool_t
4082 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4083 {
4084  dbus_bool_t valid_socket;
4085  DBusString socket_path;
4086 
4087  if (_dbus_check_setuid ())
4088  {
4090  "Unable to find launchd socket when setuid");
4091  return FALSE;
4092  }
4093 
4094  if (!_dbus_string_init (&socket_path))
4095  {
4096  _DBUS_SET_OOM (error);
4097  return FALSE;
4098  }
4099 
4100  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4101 
4102  if (dbus_error_is_set(error))
4103  {
4104  _dbus_string_free(&socket_path);
4105  return FALSE;
4106  }
4107 
4108  if (!valid_socket)
4109  {
4110  dbus_set_error(error, "no socket path",
4111  "launchd did not provide a socket path, "
4112  "verify that org.freedesktop.dbus-session.plist is loaded!");
4113  _dbus_string_free(&socket_path);
4114  return FALSE;
4115  }
4116  if (!_dbus_string_append (address, "unix:path="))
4117  {
4118  _DBUS_SET_OOM (error);
4119  _dbus_string_free(&socket_path);
4120  return FALSE;
4121  }
4122  if (!_dbus_string_copy (&socket_path, 0, address,
4123  _dbus_string_get_length (address)))
4124  {
4125  _DBUS_SET_OOM (error);
4126  _dbus_string_free(&socket_path);
4127  return FALSE;
4128  }
4129 
4130  _dbus_string_free(&socket_path);
4131  return TRUE;
4132 }
4133 #endif
4134 
4136 _dbus_lookup_user_bus (dbus_bool_t *supported,
4137  DBusString *address,
4138  DBusError *error)
4139 {
4140  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4141  dbus_bool_t ret = FALSE;
4142  struct stat stbuf;
4143  DBusString user_bus_path;
4144 
4145  if (runtime_dir == NULL)
4146  {
4147  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4148  *supported = FALSE;
4149  return TRUE; /* Cannot use it, but not an error */
4150  }
4151 
4152  if (!_dbus_string_init (&user_bus_path))
4153  {
4154  _DBUS_SET_OOM (error);
4155  return FALSE;
4156  }
4157 
4158  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4159  {
4160  _DBUS_SET_OOM (error);
4161  goto out;
4162  }
4163 
4164  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4165  {
4166  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4167  _dbus_strerror (errno));
4168  *supported = FALSE;
4169  ret = TRUE; /* Cannot use it, but not an error */
4170  goto out;
4171  }
4172 
4173  if (stbuf.st_uid != getuid ())
4174  {
4175  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4176  (long) stbuf.st_uid, (long) getuid ());
4177  *supported = FALSE;
4178  ret = TRUE; /* Cannot use it, but not an error */
4179  goto out;
4180  }
4181 
4182  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4183  {
4184  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4185  (long) stbuf.st_mode);
4186  *supported = FALSE;
4187  ret = TRUE; /* Cannot use it, but not an error */
4188  goto out;
4189  }
4190 
4191  if (!_dbus_string_append (address, "unix:path=") ||
4192  !_dbus_address_append_escaped (address, &user_bus_path))
4193  {
4194  _DBUS_SET_OOM (error);
4195  goto out;
4196  }
4197 
4198  *supported = TRUE;
4199  ret = TRUE;
4200 
4201 out:
4202  _dbus_string_free (&user_bus_path);
4203  return ret;
4204 }
4205 
4227  DBusString *address,
4228  DBusError *error)
4229 {
4230 #ifdef DBUS_ENABLE_LAUNCHD
4231  *supported = TRUE;
4232  return _dbus_lookup_session_address_launchd (address, error);
4233 #else
4234  *supported = FALSE;
4235 
4236  if (!_dbus_lookup_user_bus (supported, address, error))
4237  return FALSE;
4238  else if (*supported)
4239  return TRUE;
4240 
4241  /* On non-Mac Unix platforms, if the session address isn't already
4242  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4243  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4244  * autolaunch: global default; see init_session_address in
4245  * dbus/dbus-bus.c. */
4246  return TRUE;
4247 #endif
4248 }
4249 
4257 void
4259 {
4261 }
4262 
4278  DBusCredentials *credentials)
4279 {
4280  DBusString homedir;
4281  DBusString dotdir;
4282  dbus_uid_t uid;
4283 
4284  _dbus_assert (credentials != NULL);
4286 
4287  if (!_dbus_string_init (&homedir))
4288  return FALSE;
4289 
4290  uid = _dbus_credentials_get_unix_uid (credentials);
4291  _dbus_assert (uid != DBUS_UID_UNSET);
4292 
4293  if (!_dbus_homedir_from_uid (uid, &homedir))
4294  goto failed;
4295 
4296 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4297  {
4298  const char *override;
4299 
4300  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4301  if (override != NULL && *override != '\0')
4302  {
4303  _dbus_string_set_length (&homedir, 0);
4304  if (!_dbus_string_append (&homedir, override))
4305  goto failed;
4306 
4307  _dbus_verbose ("Using fake homedir for testing: %s\n",
4308  _dbus_string_get_const_data (&homedir));
4309  }
4310  else
4311  {
4312  /* Not strictly thread-safe, but if we fail at thread-safety here,
4313  * the worst that will happen is some extra warnings. */
4314  static dbus_bool_t already_warned = FALSE;
4315  if (!already_warned)
4316  {
4317  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4318  _dbus_string_get_const_data (&homedir));
4319  already_warned = TRUE;
4320  }
4321  }
4322  }
4323 #endif
4324 
4325  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4326  if (!_dbus_concat_dir_and_file (&homedir,
4327  &dotdir))
4328  goto failed;
4329 
4330  if (!_dbus_string_copy (&homedir, 0,
4331  directory, _dbus_string_get_length (directory))) {
4332  goto failed;
4333  }
4334 
4335  _dbus_string_free (&homedir);
4336  return TRUE;
4337 
4338  failed:
4339  _dbus_string_free (&homedir);
4340  return FALSE;
4341 }
4342 
4343 //PENDING(kdab) docs
4345 _dbus_daemon_publish_session_bus_address (const char* addr,
4346  const char *scope)
4347 {
4348  return TRUE;
4349 }
4350 
4351 //PENDING(kdab) docs
4352 void
4353 _dbus_daemon_unpublish_session_bus_address (void)
4354 {
4355 
4356 }
4357 
4366 {
4367  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4368  * EWOULDBLOCK are numerically equal, which is permitted as described by
4369  * errno(3).
4370  */
4371 #if EAGAIN == EWOULDBLOCK
4372  return e == EAGAIN;
4373 #else
4374  return e == EAGAIN || e == EWOULDBLOCK;
4375 #endif
4376 }
4377 
4387  DBusError *error)
4388 {
4389  const char *filename_c;
4390 
4391  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4392 
4393  filename_c = _dbus_string_get_const_data (filename);
4394 
4395  if (rmdir (filename_c) != 0)
4396  {
4398  "Failed to remove directory %s: %s\n",
4399  filename_c, _dbus_strerror (errno));
4400  return FALSE;
4401  }
4402 
4403  return TRUE;
4404 }
4405 
4415 {
4416 #ifdef SCM_RIGHTS
4417  union {
4418  struct sockaddr sa;
4419  struct sockaddr_storage storage;
4420  struct sockaddr_un un;
4421  } sa_buf;
4422 
4423  socklen_t sa_len = sizeof(sa_buf);
4424 
4425  _DBUS_ZERO(sa_buf);
4426 
4427  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4428  return FALSE;
4429 
4430  return sa_buf.sa.sa_family == AF_UNIX;
4431 
4432 #else
4433  return FALSE;
4434 
4435 #endif
4436 }
4437 
4442 void
4444 {
4445  int maxfds, i;
4446 
4447 #ifdef __linux__
4448  DIR *d;
4449 
4450  /* On Linux we can optimize this a bit if /proc is available. If it
4451  isn't available, fall back to the brute force way. */
4452 
4453  d = opendir ("/proc/self/fd");
4454  if (d)
4455  {
4456  for (;;)
4457  {
4458  struct dirent *de;
4459  int fd;
4460  long l;
4461  char *e = NULL;
4462 
4463  de = readdir (d);
4464  if (!de)
4465  break;
4466 
4467  if (de->d_name[0] == '.')
4468  continue;
4469 
4470  errno = 0;
4471  l = strtol (de->d_name, &e, 10);
4472  if (errno != 0 || e == NULL || *e != '\0')
4473  continue;
4474 
4475  fd = (int) l;
4476  if (fd < 3)
4477  continue;
4478 
4479  if (fd == dirfd (d))
4480  continue;
4481 
4482  close (fd);
4483  }
4484 
4485  closedir (d);
4486  return;
4487  }
4488 #endif
4489 
4490  maxfds = sysconf (_SC_OPEN_MAX);
4491 
4492  /* Pick something reasonable if for some reason sysconf says
4493  * unlimited.
4494  */
4495  if (maxfds < 0)
4496  maxfds = 1024;
4497 
4498  /* close all inherited fds */
4499  for (i = 3; i < maxfds; i++)
4500  close (i);
4501 }
4502 
4514 {
4515  /* TODO: get __libc_enable_secure exported from glibc.
4516  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4517  */
4518 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4519  {
4520  /* See glibc/include/unistd.h */
4521  extern int __libc_enable_secure;
4522  return __libc_enable_secure;
4523  }
4524 #elif defined(HAVE_ISSETUGID)
4525  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4526  return issetugid ();
4527 #else
4528  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4529  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4530 
4531  /* We call into this function from _dbus_threads_init_platform_specific()
4532  * to make sure these are initialized before we start threading. */
4533  static dbus_bool_t check_setuid_initialised;
4534  static dbus_bool_t is_setuid;
4535 
4536  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4537  {
4538 #ifdef HAVE_GETRESUID
4539  if (getresuid (&ruid, &euid, &suid) != 0 ||
4540  getresgid (&rgid, &egid, &sgid) != 0)
4541 #endif /* HAVE_GETRESUID */
4542  {
4543  suid = ruid = getuid ();
4544  sgid = rgid = getgid ();
4545  euid = geteuid ();
4546  egid = getegid ();
4547  }
4548 
4549  check_setuid_initialised = TRUE;
4550  is_setuid = (ruid != euid || ruid != suid ||
4551  rgid != egid || rgid != sgid);
4552 
4553  }
4554  return is_setuid;
4555 #endif
4556 }
4557 
4567  DBusString *address,
4568  DBusError *error)
4569 {
4570  union {
4571  struct sockaddr sa;
4572  struct sockaddr_storage storage;
4573  struct sockaddr_un un;
4574  struct sockaddr_in ipv4;
4575  struct sockaddr_in6 ipv6;
4576  } socket;
4577  char hostip[INET6_ADDRSTRLEN];
4578  socklen_t size = sizeof (socket);
4579  DBusString path_str;
4580 
4581  if (getsockname (fd.fd, &socket.sa, &size))
4582  goto err;
4583 
4584  switch (socket.sa.sa_family)
4585  {
4586  case AF_UNIX:
4587  if (socket.un.sun_path[0]=='\0')
4588  {
4589  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4590  if (_dbus_string_append (address, "unix:abstract=") &&
4591  _dbus_address_append_escaped (address, &path_str))
4592  return TRUE;
4593  }
4594  else
4595  {
4596  _dbus_string_init_const (&path_str, socket.un.sun_path);
4597  if (_dbus_string_append (address, "unix:path=") &&
4598  _dbus_address_append_escaped (address, &path_str))
4599  return TRUE;
4600  }
4601  break;
4602  case AF_INET:
4603  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4604  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4605  hostip, ntohs (socket.ipv4.sin_port)))
4606  return TRUE;
4607  break;
4608 #ifdef AF_INET6
4609  case AF_INET6:
4610  _dbus_string_init_const (&path_str, hostip);
4611  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4612  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4613  ntohs (socket.ipv6.sin6_port)) &&
4614  _dbus_address_append_escaped (address, &path_str))
4615  return TRUE;
4616  break;
4617 #endif
4618  default:
4619  dbus_set_error (error,
4620  _dbus_error_from_errno (EINVAL),
4621  "Failed to read address from socket: Unknown socket type.");
4622  return FALSE;
4623  }
4624  err:
4625  dbus_set_error (error,
4626  _dbus_error_from_errno (errno),
4627  "Failed to open socket: %s",
4628  _dbus_strerror (errno));
4629  return FALSE;
4630 }
4631 
4632 int
4633 _dbus_save_socket_errno (void)
4634 {
4635  return errno;
4636 }
4637 
4638 void
4639 _dbus_restore_socket_errno (int saved_errno)
4640 {
4641  errno = saved_errno;
4642 }
4643 
4644 static const char *syslog_tag = "dbus";
4645 #ifdef HAVE_SYSLOG_H
4646 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4647 #endif
4648 
4663 void
4664 _dbus_init_system_log (const char *tag,
4665  DBusLogFlags flags)
4666 {
4667  /* We never want to turn off logging completely */
4668  _dbus_assert (
4669  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4670 
4671  syslog_tag = tag;
4672 
4673 #ifdef HAVE_SYSLOG_H
4674  log_flags = flags;
4675 
4676  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4677  openlog (tag, LOG_PID, LOG_DAEMON);
4678 #endif
4679 }
4680 
4688 void
4689 _dbus_logv (DBusSystemLogSeverity severity,
4690  const char *msg,
4691  va_list args)
4692 {
4693  va_list tmp;
4694 #ifdef HAVE_SYSLOG_H
4695  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4696  {
4697  int flags;
4698  switch (severity)
4699  {
4700  case DBUS_SYSTEM_LOG_INFO:
4701  flags = LOG_DAEMON | LOG_INFO;
4702  break;
4703  case DBUS_SYSTEM_LOG_WARNING:
4704  flags = LOG_DAEMON | LOG_WARNING;
4705  break;
4706  case DBUS_SYSTEM_LOG_SECURITY:
4707  flags = LOG_AUTH | LOG_NOTICE;
4708  break;
4709  case DBUS_SYSTEM_LOG_ERROR:
4710  flags = LOG_DAEMON|LOG_CRIT;
4711  break;
4712  default:
4713  _dbus_assert_not_reached ("invalid log severity");
4714  }
4715 
4716  DBUS_VA_COPY (tmp, args);
4717  vsyslog (flags, msg, tmp);
4718  va_end (tmp);
4719  }
4720 
4721  /* If we don't have syslog.h, we always behave as though stderr was in
4722  * the flags */
4723  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4724 #endif
4725  {
4726  DBUS_VA_COPY (tmp, args);
4727  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4728  vfprintf (stderr, msg, tmp);
4729  fputc ('\n', stderr);
4730  va_end (tmp);
4731  }
4732 }
4733 
4734 /* tests in dbus-sysdeps-util.c */