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,
1889  _dbus_string_get_const_data (&buf));
1890 
1891  /* Remove trailing comma "," if any, BEGIN*/
1892 
1893  char* ss = _dbus_string_get_data (&buf);
1894  ss = strtok (ss, ",");
1895 
1896  /* Remove trailing comma "," if any, END*/
1897 
1899  _dbus_string_get_const_data (&buf)))
1900  {
1901  oom = TRUE;
1902  goto out;
1903  }
1904 
1905 out:
1906  _dbus_string_free (&buf);
1907  return !oom;
1908 #else
1909  /* no error */
1910  return TRUE;
1911 #endif
1912 }
1913 
1956  DBusCredentials *credentials,
1957  DBusError *error)
1958 {
1959  struct msghdr msg;
1960  struct iovec iov;
1961  char buf;
1962  dbus_uid_t uid_read;
1963  dbus_pid_t pid_read;
1964  int bytes_read;
1965 
1966 #ifdef HAVE_CMSGCRED
1967  union {
1968  struct cmsghdr hdr;
1969  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1970  } cmsg;
1971 #endif
1972 
1973  /* The POSIX spec certainly doesn't promise this, but
1974  * we need these assertions to fail as soon as we're wrong about
1975  * it so we can do the porting fixups
1976  */
1977  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1978  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1979  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1980 
1981  uid_read = DBUS_UID_UNSET;
1982  pid_read = DBUS_PID_UNSET;
1983 
1984  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1985 
1986  _dbus_credentials_clear (credentials);
1987 
1988  iov.iov_base = &buf;
1989  iov.iov_len = 1;
1990 
1991  _DBUS_ZERO(msg);
1992  msg.msg_iov = &iov;
1993  msg.msg_iovlen = 1;
1994 
1995 #if defined(HAVE_CMSGCRED)
1996  _DBUS_ZERO(cmsg);
1997  msg.msg_control = (caddr_t) &cmsg;
1998  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1999 #endif
2000 
2001  again:
2002  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2003 
2004  if (bytes_read < 0)
2005  {
2006  if (errno == EINTR)
2007  goto again;
2008 
2009  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2010  * normally only call read_credentials if the socket was ready
2011  * for reading
2012  */
2013 
2014  dbus_set_error (error, _dbus_error_from_errno (errno),
2015  "Failed to read credentials byte: %s",
2016  _dbus_strerror (errno));
2017  return FALSE;
2018  }
2019  else if (bytes_read == 0)
2020  {
2021  /* this should not happen unless we are using recvmsg wrong,
2022  * so is essentially here for paranoia
2023  */
2025  "Failed to read credentials byte (zero-length read)");
2026  return FALSE;
2027  }
2028  else if (buf != '\0')
2029  {
2031  "Credentials byte was not nul");
2032  return FALSE;
2033  }
2034 
2035  _dbus_verbose ("read credentials byte\n");
2036 
2037  {
2038 #ifdef SO_PEERCRED
2039  /* Supported by at least Linux and OpenBSD, with minor differences.
2040  *
2041  * This mechanism passes the process ID through and does not require
2042  * the peer's cooperation, so we prefer it over all others. Notably,
2043  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2044  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2045  * because this is much less fragile.
2046  */
2047 #ifdef __OpenBSD__
2048  struct sockpeercred cr;
2049 #else
2050  struct ucred cr;
2051 #endif
2052  socklen_t cr_len = sizeof (cr);
2053 
2054  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2055  {
2056  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2057  _dbus_strerror (errno));
2058  }
2059  else if (cr_len != sizeof (cr))
2060  {
2061  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2062  cr_len, (int) sizeof (cr));
2063  }
2064  else
2065  {
2066  pid_read = cr.pid;
2067  uid_read = cr.uid;
2068  }
2069 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2070  /* Another variant of the above - used on NetBSD
2071  */
2072  struct unpcbid cr;
2073  socklen_t cr_len = sizeof (cr);
2074 
2075  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2076  {
2077  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2078  _dbus_strerror (errno));
2079  }
2080  else if (cr_len != sizeof (cr))
2081  {
2082  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2083  cr_len, (int) sizeof (cr));
2084  }
2085  else
2086  {
2087  pid_read = cr.unp_pid;
2088  uid_read = cr.unp_euid;
2089  }
2090 #elif defined(HAVE_CMSGCRED)
2091  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2092  * presence of that struct implies SCM_CREDS. Supported by at least
2093  * FreeBSD and DragonflyBSD.
2094  *
2095  * This mechanism requires the peer to help us (it has to send us a
2096  * SCM_CREDS message) but it does pass the process ID through,
2097  * which makes it better than getpeereid().
2098  */
2099  struct cmsgcred *cred;
2100  struct cmsghdr *cmsgp;
2101 
2102  for (cmsgp = CMSG_FIRSTHDR (&msg);
2103  cmsgp != NULL;
2104  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2105  {
2106  if (cmsgp->cmsg_type == SCM_CREDS &&
2107  cmsgp->cmsg_level == SOL_SOCKET &&
2108  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2109  {
2110  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2111  pid_read = cred->cmcred_pid;
2112  uid_read = cred->cmcred_euid;
2113  break;
2114  }
2115  }
2116 
2117 #elif defined(HAVE_GETPEERUCRED)
2118  /* Supported in at least Solaris >= 10. It should probably be higher
2119  * up this list, because it carries the pid and we use this code path
2120  * for audit data. */
2121  ucred_t * ucred = NULL;
2122  if (getpeerucred (client_fd.fd, &ucred) == 0)
2123  {
2124 #ifdef HAVE_ADT
2125  adt_session_data_t *adth = NULL;
2126 #endif
2127  pid_read = ucred_getpid (ucred);
2128  uid_read = ucred_geteuid (ucred);
2129 #ifdef HAVE_ADT
2130  /* generate audit session data based on socket ucred */
2131  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2132  {
2133  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2134  }
2135  else
2136  {
2137  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2138  {
2139  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2140  }
2141  else
2142  {
2143  adt_export_data_t *data = NULL;
2144  size_t size = adt_export_session_data (adth, &data);
2145  if (size <= 0)
2146  {
2147  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2148  }
2149  else
2150  {
2151  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2152  free (data);
2153  }
2154  }
2155  (void) adt_end_session (adth);
2156  }
2157 #endif /* HAVE_ADT */
2158  }
2159  else
2160  {
2161  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2162  }
2163  if (ucred != NULL)
2164  ucred_free (ucred);
2165 
2166  /* ----------------------------------------------------------------
2167  * When adding new mechanisms, please add them above this point
2168  * if they support passing the process ID through, or below if not.
2169  * ---------------------------------------------------------------- */
2170 
2171 #elif defined(HAVE_GETPEEREID)
2172  /* getpeereid() originates from D.J. Bernstein and is fairly
2173  * widely-supported. According to a web search, it might be present in
2174  * any/all of:
2175  *
2176  * - AIX?
2177  * - Blackberry?
2178  * - Cygwin
2179  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2180  * - Mac OS X
2181  * - Minix 3.1.8+
2182  * - MirBSD?
2183  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2184  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2185  * - QNX?
2186  */
2187  uid_t euid;
2188  gid_t egid;
2189  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2190  {
2191  uid_read = euid;
2192  }
2193  else
2194  {
2195  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2196  }
2197 #else /* no supported mechanism */
2198 
2199 #warning Socket credentials not supported on this Unix OS
2200 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2201 
2202  /* Please add other operating systems known to support at least one of
2203  * the mechanisms above to this list, keeping alphabetical order.
2204  * Everything not in this list is best-effort.
2205  */
2206 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2207  defined(__linux__) || \
2208  defined(__OpenBSD__) || \
2209  defined(__NetBSD__)
2210 # error Credentials passing not working on this OS is a regression!
2211 #endif
2212 
2213  _dbus_verbose ("Socket credentials not supported on this OS\n");
2214 #endif
2215  }
2216 
2217  _dbus_verbose ("Credentials:"
2218  " pid "DBUS_PID_FORMAT
2219  " uid "DBUS_UID_FORMAT
2220  "\n",
2221  pid_read,
2222  uid_read);
2223 
2224  if (pid_read != DBUS_PID_UNSET)
2225  {
2226  if (!_dbus_credentials_add_pid (credentials, pid_read))
2227  {
2228  _DBUS_SET_OOM (error);
2229  return FALSE;
2230  }
2231  }
2232 
2233  if (uid_read != DBUS_UID_UNSET)
2234  {
2235  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2236  {
2237  _DBUS_SET_OOM (error);
2238  return FALSE;
2239  }
2240  }
2241 
2242  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2243  {
2244  _DBUS_SET_OOM (error);
2245  return FALSE;
2246  }
2247 
2248  return TRUE;
2249 }
2250 
2270  DBusError *error)
2271 {
2272  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2273 
2274  if (write_credentials_byte (server_fd.fd, error))
2275  return TRUE;
2276  else
2277  return FALSE;
2278 }
2279 
2289 DBusSocket
2291 {
2292  DBusSocket client_fd;
2293  struct sockaddr addr;
2294  socklen_t addrlen;
2295 #ifdef HAVE_ACCEPT4
2296  dbus_bool_t cloexec_done;
2297 #endif
2298 
2299  addrlen = sizeof (addr);
2300 
2301  retry:
2302 
2303 #ifdef HAVE_ACCEPT4
2304  /*
2305  * At compile-time, we assume that if accept4() is available in
2306  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2307  * not necessarily true that either is supported by the running kernel.
2308  */
2309  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2310  cloexec_done = client_fd.fd >= 0;
2311 
2312  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2313 #endif
2314  {
2315  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2316  }
2317 
2318  if (client_fd.fd < 0)
2319  {
2320  if (errno == EINTR)
2321  goto retry;
2322  }
2323 
2324  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2325 
2326 #ifdef HAVE_ACCEPT4
2327  if (!cloexec_done)
2328 #endif
2329  {
2330  _dbus_fd_set_close_on_exec(client_fd.fd);
2331  }
2332 
2333  return client_fd;
2334 }
2335 
2346 {
2347  const char *directory;
2348  struct stat sb;
2349 
2350  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2351 
2352  directory = _dbus_string_get_const_data (dir);
2353 
2354  if (stat (directory, &sb) < 0)
2355  {
2356  dbus_set_error (error, _dbus_error_from_errno (errno),
2357  "%s", _dbus_strerror (errno));
2358 
2359  return FALSE;
2360  }
2361 
2362  if (sb.st_uid != geteuid ())
2363  {
2365  "%s directory is owned by user %lu, not %lu",
2366  directory,
2367  (unsigned long) sb.st_uid,
2368  (unsigned long) geteuid ());
2369  return FALSE;
2370  }
2371 
2372  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2373  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2374  {
2376  "%s directory is not private to the user", directory);
2377  return FALSE;
2378  }
2379 
2380  return TRUE;
2381 }
2382 
2383 static dbus_bool_t
2384 fill_user_info_from_passwd (struct passwd *p,
2385  DBusUserInfo *info,
2386  DBusError *error)
2387 {
2388  _dbus_assert (p->pw_name != NULL);
2389  _dbus_assert (p->pw_dir != NULL);
2390 
2391  info->uid = p->pw_uid;
2392  info->primary_gid = p->pw_gid;
2393  info->username = _dbus_strdup (p->pw_name);
2394  info->homedir = _dbus_strdup (p->pw_dir);
2395 
2396  if (info->username == NULL ||
2397  info->homedir == NULL)
2398  {
2400  return FALSE;
2401  }
2402 
2403  return TRUE;
2404 }
2405 
2406 static dbus_bool_t
2407 fill_user_info (DBusUserInfo *info,
2408  dbus_uid_t uid,
2409  const DBusString *username,
2410  DBusError *error)
2411 {
2412  const char *username_c;
2413 
2414  /* exactly one of username/uid provided */
2415  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2416  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2417 
2418  info->uid = DBUS_UID_UNSET;
2419  info->primary_gid = DBUS_GID_UNSET;
2420  info->group_ids = NULL;
2421  info->n_group_ids = 0;
2422  info->username = NULL;
2423  info->homedir = NULL;
2424 
2425  if (username != NULL)
2426  username_c = _dbus_string_get_const_data (username);
2427  else
2428  username_c = NULL;
2429 
2430  /* For now assuming that the getpwnam() and getpwuid() flavors
2431  * are always symmetrical, if not we have to add more configure
2432  * checks
2433  */
2434 
2435 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2436  {
2437  struct passwd *p;
2438  int result;
2439  size_t buflen;
2440  char *buf;
2441  struct passwd p_str;
2442 
2443  /* retrieve maximum needed size for buf */
2444  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2445 
2446  /* sysconf actually returns a long, but everything else expects size_t,
2447  * so just recast here.
2448  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2449  */
2450  if ((long) buflen <= 0)
2451  buflen = 1024;
2452 
2453  result = -1;
2454  while (1)
2455  {
2456  buf = dbus_malloc (buflen);
2457  if (buf == NULL)
2458  {
2460  return FALSE;
2461  }
2462 
2463  p = NULL;
2464 #ifdef HAVE_POSIX_GETPWNAM_R
2465  if (uid != DBUS_UID_UNSET)
2466  result = getpwuid_r (uid, &p_str, buf, buflen,
2467  &p);
2468  else
2469  result = getpwnam_r (username_c, &p_str, buf, buflen,
2470  &p);
2471 #else
2472  if (uid != DBUS_UID_UNSET)
2473  p = getpwuid_r (uid, &p_str, buf, buflen);
2474  else
2475  p = getpwnam_r (username_c, &p_str, buf, buflen);
2476  result = 0;
2477 #endif /* !HAVE_POSIX_GETPWNAM_R */
2478  //Try a bigger buffer if ERANGE was returned
2479  if (result == ERANGE && buflen < 512 * 1024)
2480  {
2481  dbus_free (buf);
2482  buflen *= 2;
2483  }
2484  else
2485  {
2486  break;
2487  }
2488  }
2489  if (result == 0 && p == &p_str)
2490  {
2491  if (!fill_user_info_from_passwd (p, info, error))
2492  {
2493  dbus_free (buf);
2494  return FALSE;
2495  }
2496  dbus_free (buf);
2497  }
2498  else
2499  {
2500  dbus_set_error (error, _dbus_error_from_errno (errno),
2501  "User \"%s\" unknown or no memory to allocate password entry\n",
2502  username_c ? username_c : "???");
2503  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2504  dbus_free (buf);
2505  return FALSE;
2506  }
2507  }
2508 #else /* ! HAVE_GETPWNAM_R */
2509  {
2510  /* I guess we're screwed on thread safety here */
2511  struct passwd *p;
2512 
2513  if (uid != DBUS_UID_UNSET)
2514  p = getpwuid (uid);
2515  else
2516  p = getpwnam (username_c);
2517 
2518  if (p != NULL)
2519  {
2520  if (!fill_user_info_from_passwd (p, info, error))
2521  {
2522  return FALSE;
2523  }
2524  }
2525  else
2526  {
2527  dbus_set_error (error, _dbus_error_from_errno (errno),
2528  "User \"%s\" unknown or no memory to allocate password entry\n",
2529  username_c ? username_c : "???");
2530  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2531  return FALSE;
2532  }
2533  }
2534 #endif /* ! HAVE_GETPWNAM_R */
2535 
2536  /* Fill this in so we can use it to get groups */
2537  username_c = info->username;
2538 
2539 #ifdef HAVE_GETGROUPLIST
2540  {
2541  gid_t *buf;
2542  int buf_count;
2543  int i;
2544  int initial_buf_count;
2545 
2546  initial_buf_count = 17;
2547  buf_count = initial_buf_count;
2548  buf = dbus_new (gid_t, buf_count);
2549  if (buf == NULL)
2550  {
2552  goto failed;
2553  }
2554 
2555  if (getgrouplist (username_c,
2556  info->primary_gid,
2557  buf, &buf_count) < 0)
2558  {
2559  gid_t *new;
2560  /* Presumed cause of negative return code: buf has insufficient
2561  entries to hold the entire group list. The Linux behavior in this
2562  case is to pass back the actual number of groups in buf_count, but
2563  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2564  So as a hack, try to help out a bit by guessing a larger
2565  number of groups, within reason.. might still fail, of course,
2566  but we can at least print a more informative message. I looked up
2567  the "right way" to do this by downloading Apple's own source code
2568  for the "id" command, and it turns out that they use an
2569  undocumented library function getgrouplist_2 (!) which is not
2570  declared in any header in /usr/include (!!). That did not seem
2571  like the way to go here.
2572  */
2573  if (buf_count == initial_buf_count)
2574  {
2575  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2576  }
2577  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2578  if (new == NULL)
2579  {
2581  dbus_free (buf);
2582  goto failed;
2583  }
2584 
2585  buf = new;
2586 
2587  errno = 0;
2588  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2589  {
2590  if (errno == 0)
2591  {
2592  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2593  username_c, buf_count, buf_count);
2594  }
2595  else
2596  {
2597  dbus_set_error (error,
2598  _dbus_error_from_errno (errno),
2599  "Failed to get groups for username \"%s\" primary GID "
2600  DBUS_GID_FORMAT ": %s\n",
2601  username_c, info->primary_gid,
2602  _dbus_strerror (errno));
2603  dbus_free (buf);
2604  goto failed;
2605  }
2606  }
2607  }
2608 
2609  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2610  if (info->group_ids == NULL)
2611  {
2613  dbus_free (buf);
2614  goto failed;
2615  }
2616 
2617  for (i = 0; i < buf_count; ++i)
2618  info->group_ids[i] = buf[i];
2619 
2620  info->n_group_ids = buf_count;
2621 
2622  dbus_free (buf);
2623  }
2624 #else /* HAVE_GETGROUPLIST */
2625  {
2626  /* We just get the one group ID */
2627  info->group_ids = dbus_new (dbus_gid_t, 1);
2628  if (info->group_ids == NULL)
2629  {
2631  goto failed;
2632  }
2633 
2634  info->n_group_ids = 1;
2635 
2636  (info->group_ids)[0] = info->primary_gid;
2637  }
2638 #endif /* HAVE_GETGROUPLIST */
2639 
2640  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2641 
2642  return TRUE;
2643 
2644  failed:
2645  _DBUS_ASSERT_ERROR_IS_SET (error);
2646  return FALSE;
2647 }
2648 
2659  const DBusString *username,
2660  DBusError *error)
2661 {
2662  return fill_user_info (info, DBUS_UID_UNSET,
2663  username, error);
2664 }
2665 
2676  dbus_uid_t uid,
2677  DBusError *error)
2678 {
2679  return fill_user_info (info, uid,
2680  NULL, error);
2681 }
2682 
2692 {
2693  /* The POSIX spec certainly doesn't promise this, but
2694  * we need these assertions to fail as soon as we're wrong about
2695  * it so we can do the porting fixups
2696  */
2697  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2698  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2699  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2700 
2701  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2702  return FALSE;
2703  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2704  return FALSE;
2705 
2706  return TRUE;
2707 }
2708 
2722 {
2723  return _dbus_string_append_uint (str,
2724  _dbus_geteuid ());
2725 }
2726 
2731 dbus_pid_t
2733 {
2734  return getpid ();
2735 }
2736 
2740 dbus_uid_t
2742 {
2743  return getuid ();
2744 }
2745 
2749 dbus_uid_t
2751 {
2752  return geteuid ();
2753 }
2754 
2761 unsigned long
2763 {
2764  return getpid ();
2765 }
2766 
2775 _dbus_parse_uid (const DBusString *uid_str,
2776  dbus_uid_t *uid)
2777 {
2778  int end;
2779  long val;
2780 
2781  if (_dbus_string_get_length (uid_str) == 0)
2782  {
2783  _dbus_verbose ("UID string was zero length\n");
2784  return FALSE;
2785  }
2786 
2787  val = -1;
2788  end = 0;
2789  if (!_dbus_string_parse_int (uid_str, 0, &val,
2790  &end))
2791  {
2792  _dbus_verbose ("could not parse string as a UID\n");
2793  return FALSE;
2794  }
2795 
2796  if (end != _dbus_string_get_length (uid_str))
2797  {
2798  _dbus_verbose ("string contained trailing stuff after UID\n");
2799  return FALSE;
2800  }
2801 
2802  *uid = val;
2803 
2804  return TRUE;
2805 }
2806 
2807 #if !DBUS_USE_SYNC
2808 /* To be thread-safe by default on platforms that don't necessarily have
2809  * atomic operations (notably Debian armel, which is armv4t), we must
2810  * use a mutex that can be initialized statically, like this.
2811  * GLib >= 2.32 uses a similar system.
2812  */
2813 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2814 #endif
2815 
2824 {
2825 #if DBUS_USE_SYNC
2826  return __sync_add_and_fetch(&atomic->value, 1)-1;
2827 #else
2828  dbus_int32_t res;
2829 
2830  pthread_mutex_lock (&atomic_mutex);
2831  res = atomic->value;
2832  atomic->value += 1;
2833  pthread_mutex_unlock (&atomic_mutex);
2834 
2835  return res;
2836 #endif
2837 }
2838 
2847 {
2848 #if DBUS_USE_SYNC
2849  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2850 #else
2851  dbus_int32_t res;
2852 
2853  pthread_mutex_lock (&atomic_mutex);
2854  res = atomic->value;
2855  atomic->value -= 1;
2856  pthread_mutex_unlock (&atomic_mutex);
2857 
2858  return res;
2859 #endif
2860 }
2861 
2871 {
2872 #if DBUS_USE_SYNC
2873  __sync_synchronize ();
2874  return atomic->value;
2875 #else
2876  dbus_int32_t res;
2877 
2878  pthread_mutex_lock (&atomic_mutex);
2879  res = atomic->value;
2880  pthread_mutex_unlock (&atomic_mutex);
2881 
2882  return res;
2883 #endif
2884 }
2885 
2894 int
2896  int n_fds,
2897  int timeout_milliseconds)
2898 {
2899 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2900  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2901  if (timeout_milliseconds < -1)
2902  {
2903  timeout_milliseconds = -1;
2904  }
2905 
2906  return poll (fds,
2907  n_fds,
2908  timeout_milliseconds);
2909 #else /* ! HAVE_POLL */
2910  /* Emulate poll() in terms of select() */
2911  fd_set read_set, write_set, err_set;
2912  int max_fd = 0;
2913  int i;
2914  struct timeval tv;
2915  int ready;
2916 
2917  FD_ZERO (&read_set);
2918  FD_ZERO (&write_set);
2919  FD_ZERO (&err_set);
2920 
2921  for (i = 0; i < n_fds; i++)
2922  {
2923  DBusPollFD *fdp = &fds[i];
2924 
2925  if (fdp->events & _DBUS_POLLIN)
2926  FD_SET (fdp->fd, &read_set);
2927 
2928  if (fdp->events & _DBUS_POLLOUT)
2929  FD_SET (fdp->fd, &write_set);
2930 
2931  FD_SET (fdp->fd, &err_set);
2932 
2933  max_fd = MAX (max_fd, fdp->fd);
2934  }
2935 
2936  tv.tv_sec = timeout_milliseconds / 1000;
2937  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2938 
2939  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2940  timeout_milliseconds < 0 ? NULL : &tv);
2941 
2942  if (ready > 0)
2943  {
2944  for (i = 0; i < n_fds; i++)
2945  {
2946  DBusPollFD *fdp = &fds[i];
2947 
2948  fdp->revents = 0;
2949 
2950  if (FD_ISSET (fdp->fd, &read_set))
2951  fdp->revents |= _DBUS_POLLIN;
2952 
2953  if (FD_ISSET (fdp->fd, &write_set))
2954  fdp->revents |= _DBUS_POLLOUT;
2955 
2956  if (FD_ISSET (fdp->fd, &err_set))
2957  fdp->revents |= _DBUS_POLLERR;
2958  }
2959  }
2960 
2961  return ready;
2962 #endif
2963 }
2964 
2972 void
2974  long *tv_usec)
2975 {
2976 #ifdef HAVE_MONOTONIC_CLOCK
2977  struct timespec ts;
2978  clock_gettime (CLOCK_MONOTONIC, &ts);
2979 
2980  if (tv_sec)
2981  *tv_sec = ts.tv_sec;
2982  if (tv_usec)
2983  *tv_usec = ts.tv_nsec / 1000;
2984 #else
2985  struct timeval t;
2986 
2987  gettimeofday (&t, NULL);
2988 
2989  if (tv_sec)
2990  *tv_sec = t.tv_sec;
2991  if (tv_usec)
2992  *tv_usec = t.tv_usec;
2993 #endif
2994 }
2995 
3003 void
3004 _dbus_get_real_time (long *tv_sec,
3005  long *tv_usec)
3006 {
3007  struct timeval t;
3008 
3009  gettimeofday (&t, NULL);
3010 
3011  if (tv_sec)
3012  *tv_sec = t.tv_sec;
3013  if (tv_usec)
3014  *tv_usec = t.tv_usec;
3015 }
3016 
3027  DBusError *error)
3028 {
3029  const char *filename_c;
3030 
3031  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3032 
3033  filename_c = _dbus_string_get_const_data (filename);
3034 
3035  if (mkdir (filename_c, 0700) < 0)
3036  {
3037  if (errno == EEXIST)
3038  return TRUE;
3039 
3041  "Failed to create directory %s: %s\n",
3042  filename_c, _dbus_strerror (errno));
3043  return FALSE;
3044  }
3045  else
3046  return TRUE;
3047 }
3048 
3059  DBusError *error)
3060 {
3061  const char *filename_c;
3062 
3063  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3064 
3065  filename_c = _dbus_string_get_const_data (filename);
3066 
3067  if (mkdir (filename_c, 0700) < 0)
3068  {
3070  "Failed to create directory %s: %s\n",
3071  filename_c, _dbus_strerror (errno));
3072  return FALSE;
3073  }
3074  else
3075  return TRUE;
3076 }
3077 
3090  const DBusString *next_component)
3091 {
3092  dbus_bool_t dir_ends_in_slash;
3093  dbus_bool_t file_starts_with_slash;
3094 
3095  if (_dbus_string_get_length (dir) == 0 ||
3096  _dbus_string_get_length (next_component) == 0)
3097  return TRUE;
3098 
3099  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3100  _dbus_string_get_length (dir) - 1);
3101 
3102  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3103 
3104  if (dir_ends_in_slash && file_starts_with_slash)
3105  {
3106  _dbus_string_shorten (dir, 1);
3107  }
3108  else if (!(dir_ends_in_slash || file_starts_with_slash))
3109  {
3110  if (!_dbus_string_append_byte (dir, '/'))
3111  return FALSE;
3112  }
3113 
3114  return _dbus_string_copy (next_component, 0, dir,
3115  _dbus_string_get_length (dir));
3116 }
3117 
3119 #define NANOSECONDS_PER_SECOND 1000000000
3120 
3121 #define MICROSECONDS_PER_SECOND 1000000
3122 
3123 #define MILLISECONDS_PER_SECOND 1000
3124 
3125 #define NANOSECONDS_PER_MILLISECOND 1000000
3126 
3127 #define MICROSECONDS_PER_MILLISECOND 1000
3128 
3133 void
3134 _dbus_sleep_milliseconds (int milliseconds)
3135 {
3136 #ifdef HAVE_NANOSLEEP
3137  struct timespec req;
3138  struct timespec rem;
3139 
3140  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3141  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3142  rem.tv_sec = 0;
3143  rem.tv_nsec = 0;
3144 
3145  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3146  req = rem;
3147 #elif defined (HAVE_USLEEP)
3148  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3149 #else /* ! HAVE_USLEEP */
3150  sleep (MAX (milliseconds / 1000, 1));
3151 #endif
3152 }
3153 
3165  int n_bytes,
3166  DBusError *error)
3167 {
3168  int old_len;
3169  int fd;
3170  int result;
3171 
3172  old_len = _dbus_string_get_length (str);
3173  fd = -1;
3174 
3175  /* note, urandom on linux will fall back to pseudorandom */
3176  fd = open ("/dev/urandom", O_RDONLY);
3177 
3178  if (fd < 0)
3179  {
3180  dbus_set_error (error, _dbus_error_from_errno (errno),
3181  "Could not open /dev/urandom: %s",
3182  _dbus_strerror (errno));
3183  return FALSE;
3184  }
3185 
3186  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3187 
3188  result = _dbus_read (fd, str, n_bytes);
3189 
3190  if (result != n_bytes)
3191  {
3192  if (result < 0)
3193  dbus_set_error (error, _dbus_error_from_errno (errno),
3194  "Could not read /dev/urandom: %s",
3195  _dbus_strerror (errno));
3196  else
3198  "Short read from /dev/urandom");
3199 
3200  _dbus_close (fd, NULL);
3201  _dbus_string_set_length (str, old_len);
3202  return FALSE;
3203  }
3204 
3205  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3206  n_bytes);
3207 
3208  _dbus_close (fd, NULL);
3209 
3210  return TRUE;
3211 }
3212 
3218 void
3219 _dbus_exit (int code)
3220 {
3221  _exit (code);
3222 }
3223 
3232 const char*
3233 _dbus_strerror (int error_number)
3234 {
3235  const char *msg;
3236 
3237  msg = strerror (error_number);
3238  if (msg == NULL)
3239  msg = "unknown";
3240 
3241  return msg;
3242 }
3243 
3247 void
3249 {
3250  signal (SIGPIPE, SIG_IGN);
3251 }
3252 
3260 void
3262 {
3263  int val;
3264 
3265  val = fcntl (fd, F_GETFD, 0);
3266 
3267  if (val < 0)
3268  return;
3269 
3270  val |= FD_CLOEXEC;
3271 
3272  fcntl (fd, F_SETFD, val);
3273 }
3274 
3283 _dbus_close (int fd,
3284  DBusError *error)
3285 {
3286  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3287 
3288  again:
3289  if (close (fd) < 0)
3290  {
3291  if (errno == EINTR)
3292  goto again;
3293 
3294  dbus_set_error (error, _dbus_error_from_errno (errno),
3295  "Could not close fd %d", fd);
3296  return FALSE;
3297  }
3298 
3299  return TRUE;
3300 }
3301 
3310 int
3311 _dbus_dup(int fd,
3312  DBusError *error)
3313 {
3314  int new_fd;
3315 
3316 #ifdef F_DUPFD_CLOEXEC
3317  dbus_bool_t cloexec_done;
3318 
3319  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3320  cloexec_done = new_fd >= 0;
3321 
3322  if (new_fd < 0 && errno == EINVAL)
3323 #endif
3324  {
3325  new_fd = fcntl(fd, F_DUPFD, 3);
3326  }
3327 
3328  if (new_fd < 0) {
3329 
3330  dbus_set_error (error, _dbus_error_from_errno (errno),
3331  "Could not duplicate fd %d", fd);
3332  return -1;
3333  }
3334 
3335 #ifdef F_DUPFD_CLOEXEC
3336  if (!cloexec_done)
3337 #endif
3338  {
3340  }
3341 
3342  return new_fd;
3343 }
3344 
3354  DBusError *error)
3355 {
3356  return _dbus_set_fd_nonblocking (fd.fd, error);
3357 }
3358 
3359 static dbus_bool_t
3360 _dbus_set_fd_nonblocking (int fd,
3361  DBusError *error)
3362 {
3363  int val;
3364 
3365  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3366 
3367  val = fcntl (fd, F_GETFL, 0);
3368  if (val < 0)
3369  {
3370  dbus_set_error (error, _dbus_error_from_errno (errno),
3371  "Failed to get flags from file descriptor %d: %s",
3372  fd, _dbus_strerror (errno));
3373  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3374  _dbus_strerror (errno));
3375  return FALSE;
3376  }
3377 
3378  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3379  {
3380  dbus_set_error (error, _dbus_error_from_errno (errno),
3381  "Failed to set nonblocking flag of file descriptor %d: %s",
3382  fd, _dbus_strerror (errno));
3383  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3384  fd, _dbus_strerror (errno));
3385 
3386  return FALSE;
3387  }
3388 
3389  return TRUE;
3390 }
3391 
3397 void
3399 {
3400 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3401  void *bt[500];
3402  int bt_size;
3403  int i;
3404  char **syms;
3405 
3406  bt_size = backtrace (bt, 500);
3407 
3408  syms = backtrace_symbols (bt, bt_size);
3409 
3410  i = 0;
3411  while (i < bt_size)
3412  {
3413  /* don't use dbus_warn since it can _dbus_abort() */
3414  fprintf (stderr, " %s\n", syms[i]);
3415  ++i;
3416  }
3417  fflush (stderr);
3418 
3419  free (syms);
3420 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3421  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3422 #else
3423  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3424 #endif
3425 }
3426 
3441  DBusSocket *fd2,
3442  dbus_bool_t blocking,
3443  DBusError *error)
3444 {
3445 #ifdef HAVE_SOCKETPAIR
3446  int fds[2];
3447  int retval;
3448 
3449 #ifdef SOCK_CLOEXEC
3450  dbus_bool_t cloexec_done;
3451 
3452  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3453  cloexec_done = retval >= 0;
3454 
3455  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3456 #endif
3457  {
3458  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3459  }
3460 
3461  if (retval < 0)
3462  {
3463  dbus_set_error (error, _dbus_error_from_errno (errno),
3464  "Could not create full-duplex pipe");
3465  return FALSE;
3466  }
3467 
3468  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3469 
3470 #ifdef SOCK_CLOEXEC
3471  if (!cloexec_done)
3472 #endif
3473  {
3474  _dbus_fd_set_close_on_exec (fds[0]);
3475  _dbus_fd_set_close_on_exec (fds[1]);
3476  }
3477 
3478  if (!blocking &&
3479  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3480  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3481  {
3482  dbus_set_error (error, _dbus_error_from_errno (errno),
3483  "Could not set full-duplex pipe nonblocking");
3484 
3485  _dbus_close (fds[0], NULL);
3486  _dbus_close (fds[1], NULL);
3487 
3488  return FALSE;
3489  }
3490 
3491  fd1->fd = fds[0];
3492  fd2->fd = fds[1];
3493 
3494  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3495  fd1->fd, fd2->fd);
3496 
3497  return TRUE;
3498 #else
3499  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3501  "_dbus_socketpair() not implemented on this OS");
3502  return FALSE;
3503 #endif
3504 }
3505 
3514 int
3516  va_list args)
3517 {
3518  char static_buf[1024];
3519  int bufsize = sizeof (static_buf);
3520  int len;
3521  va_list args_copy;
3522 
3523  DBUS_VA_COPY (args_copy, args);
3524  len = vsnprintf (static_buf, bufsize, format, args_copy);
3525  va_end (args_copy);
3526 
3527  /* If vsnprintf() returned non-negative, then either the string fits in
3528  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3529  * returns the number of characters that were needed, or this OS returns the
3530  * truncated length.
3531  *
3532  * We ignore the possibility that snprintf might just ignore the length and
3533  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3534  * If your libc is really that bad, come back when you have a better one. */
3535  if (len == bufsize)
3536  {
3537  /* This could be the truncated length (Tru64 and IRIX have this bug),
3538  * or the real length could be coincidentally the same. Which is it?
3539  * If vsnprintf returns the truncated length, we'll go to the slow
3540  * path. */
3541  DBUS_VA_COPY (args_copy, args);
3542 
3543  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3544  len = -1;
3545 
3546  va_end (args_copy);
3547  }
3548 
3549  /* If vsnprintf() returned negative, we have to do more work.
3550  * HP-UX returns negative. */
3551  while (len < 0)
3552  {
3553  char *buf;
3554 
3555  bufsize *= 2;
3556 
3557  buf = dbus_malloc (bufsize);
3558 
3559  if (buf == NULL)
3560  return -1;
3561 
3562  DBUS_VA_COPY (args_copy, args);
3563  len = vsnprintf (buf, bufsize, format, args_copy);
3564  va_end (args_copy);
3565 
3566  dbus_free (buf);
3567 
3568  /* If the reported length is exactly the buffer size, round up to the
3569  * next size, in case vsnprintf has been returning the truncated
3570  * length */
3571  if (len == bufsize)
3572  len = -1;
3573  }
3574 
3575  return len;
3576 }
3577 
3584 const char*
3586 {
3587  /* Protected by _DBUS_LOCK_sysdeps */
3588  static const char* tmpdir = NULL;
3589 
3590  if (!_DBUS_LOCK (sysdeps))
3591  return NULL;
3592 
3593  if (tmpdir == NULL)
3594  {
3595  /* TMPDIR is what glibc uses, then
3596  * glibc falls back to the P_tmpdir macro which
3597  * just expands to "/tmp"
3598  */
3599  if (tmpdir == NULL)
3600  tmpdir = getenv("TMPDIR");
3601 
3602  /* These two env variables are probably
3603  * broken, but maybe some OS uses them?
3604  */
3605  if (tmpdir == NULL)
3606  tmpdir = getenv("TMP");
3607  if (tmpdir == NULL)
3608  tmpdir = getenv("TEMP");
3609 
3610  /* And this is the sane fallback. */
3611  if (tmpdir == NULL)
3612  tmpdir = "/tmp";
3613  }
3614 
3615  _DBUS_UNLOCK (sysdeps);
3616 
3617  _dbus_assert(tmpdir != NULL);
3618 
3619  return tmpdir;
3620 }
3621 
3622 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3623 
3642 static dbus_bool_t
3643 _read_subprocess_line_argv (const char *progpath,
3644  dbus_bool_t path_fallback,
3645  const char * const *argv,
3646  DBusString *result,
3647  DBusError *error)
3648 {
3649  int result_pipe[2] = { -1, -1 };
3650  int errors_pipe[2] = { -1, -1 };
3651  pid_t pid;
3652  int ret;
3653  int status;
3654  int orig_len;
3655 
3656  dbus_bool_t retval;
3657  sigset_t new_set, old_set;
3658 
3659  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3660  retval = FALSE;
3661 
3662  /* We need to block any existing handlers for SIGCHLD temporarily; they
3663  * will cause waitpid() below to fail.
3664  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3665  */
3666  sigemptyset (&new_set);
3667  sigaddset (&new_set, SIGCHLD);
3668  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3669 
3670  orig_len = _dbus_string_get_length (result);
3671 
3672 #define READ_END 0
3673 #define WRITE_END 1
3674  if (pipe (result_pipe) < 0)
3675  {
3676  dbus_set_error (error, _dbus_error_from_errno (errno),
3677  "Failed to create a pipe to call %s: %s",
3678  progpath, _dbus_strerror (errno));
3679  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3680  progpath, _dbus_strerror (errno));
3681  goto out;
3682  }
3683  if (pipe (errors_pipe) < 0)
3684  {
3685  dbus_set_error (error, _dbus_error_from_errno (errno),
3686  "Failed to create a pipe to call %s: %s",
3687  progpath, _dbus_strerror (errno));
3688  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3689  progpath, _dbus_strerror (errno));
3690  goto out;
3691  }
3692 
3693  pid = fork ();
3694  if (pid < 0)
3695  {
3696  dbus_set_error (error, _dbus_error_from_errno (errno),
3697  "Failed to fork() to call %s: %s",
3698  progpath, _dbus_strerror (errno));
3699  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3700  progpath, _dbus_strerror (errno));
3701  goto out;
3702  }
3703 
3704  if (pid == 0)
3705  {
3706  /* child process */
3707  const char *error_str;
3708 
3709  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3710  {
3711  int saved_errno = errno;
3712 
3713  /* Try to write details into the pipe, but don't bother
3714  * trying too hard (no retry loop). */
3715 
3716  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3717  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3718  {
3719  /* ignore, not much we can do */
3720  }
3721 
3722  error_str = _dbus_strerror (saved_errno);
3723 
3724  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3725  {
3726  /* ignore, not much we can do */
3727  }
3728 
3729  _exit (1);
3730  }
3731 
3732  /* set-up stdXXX */
3733  close (result_pipe[READ_END]);
3734  close (errors_pipe[READ_END]);
3735 
3736  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3737  _exit (1);
3738  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3739  _exit (1);
3740 
3741  _dbus_close_all ();
3742 
3743  sigprocmask (SIG_SETMASK, &old_set, NULL);
3744 
3745  /* If it looks fully-qualified, try execv first */
3746  if (progpath[0] == '/')
3747  {
3748  execv (progpath, (char * const *) argv);
3749  /* Ok, that failed. Now if path_fallback is given, let's
3750  * try unqualified. This is mostly a hack to work
3751  * around systems which ship dbus-launch in /usr/bin
3752  * but everything else in /bin (because dbus-launch
3753  * depends on X11).
3754  */
3755  if (path_fallback)
3756  /* We must have a slash, because we checked above */
3757  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3758  }
3759  else
3760  execvp (progpath, (char * const *) argv);
3761 
3762  /* still nothing, we failed */
3763  _exit (1);
3764  }
3765 
3766  /* parent process */
3767  close (result_pipe[WRITE_END]);
3768  close (errors_pipe[WRITE_END]);
3769  result_pipe[WRITE_END] = -1;
3770  errors_pipe[WRITE_END] = -1;
3771 
3772  ret = 0;
3773  do
3774  {
3775  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3776  }
3777  while (ret > 0);
3778 
3779  /* reap the child process to avoid it lingering as zombie */
3780  do
3781  {
3782  ret = waitpid (pid, &status, 0);
3783  }
3784  while (ret == -1 && errno == EINTR);
3785 
3786  /* We succeeded if the process exited with status 0 and
3787  anything was read */
3788  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3789  {
3790  /* The process ended with error */
3791  DBusString error_message;
3792  if (!_dbus_string_init (&error_message))
3793  {
3794  _DBUS_SET_OOM (error);
3795  goto out;
3796  }
3797 
3798  ret = 0;
3799  do
3800  {
3801  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3802  }
3803  while (ret > 0);
3804 
3805  _dbus_string_set_length (result, orig_len);
3806  if (_dbus_string_get_length (&error_message) > 0)
3808  "%s terminated abnormally with the following error: %s",
3809  progpath, _dbus_string_get_data (&error_message));
3810  else
3812  "%s terminated abnormally without any error message",
3813  progpath);
3814  goto out;
3815  }
3816 
3817  retval = TRUE;
3818 
3819  out:
3820  sigprocmask (SIG_SETMASK, &old_set, NULL);
3821 
3822  if (retval)
3823  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3824  else
3825  _DBUS_ASSERT_ERROR_IS_SET (error);
3826 
3827  if (result_pipe[0] != -1)
3828  close (result_pipe[0]);
3829  if (result_pipe[1] != -1)
3830  close (result_pipe[1]);
3831  if (errors_pipe[0] != -1)
3832  close (errors_pipe[0]);
3833  if (errors_pipe[1] != -1)
3834  close (errors_pipe[1]);
3835 
3836  return retval;
3837 }
3838 #endif
3839 
3853 _dbus_get_autolaunch_address (const char *scope,
3854  DBusString *address,
3855  DBusError *error)
3856 {
3857 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3858  static const char arg_dbus_launch[] = "dbus-launch";
3859  static const char arg_autolaunch[] = "--autolaunch";
3860  static const char arg_binary_syntax[] = "--binary-syntax";
3861  static const char arg_close_stderr[] = "--close-stderr";
3862 
3863  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3864  * but that's done elsewhere, and if it worked, this function wouldn't
3865  * be called.) */
3866  const char *display;
3867  const char *progpath;
3868  const char *argv[6];
3869  int i;
3870  DBusString uuid;
3871  dbus_bool_t retval;
3872 
3873  if (_dbus_check_setuid ())
3874  {
3876  "Unable to autolaunch when setuid");
3877  return FALSE;
3878  }
3879 
3880  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3881  retval = FALSE;
3882 
3883  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3884  * dbus-launch-x11 is just going to fail. Rather than trying to
3885  * run it, we might as well bail out early with a nice error.
3886  *
3887  * This is not strictly true in a world where the user bus exists,
3888  * because dbus-launch --autolaunch knows how to connect to that -
3889  * but if we were going to connect to the user bus, we'd have done
3890  * so before trying autolaunch: in any case. */
3891  display = _dbus_getenv ("DISPLAY");
3892 
3893  if (display == NULL || display[0] == '\0')
3894  {
3896  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3897  return FALSE;
3898  }
3899 
3900  if (!_dbus_string_init (&uuid))
3901  {
3902  _DBUS_SET_OOM (error);
3903  return FALSE;
3904  }
3905 
3906  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3907  {
3908  goto out;
3909  }
3910 
3911 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3912  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
3913 
3914  if (progpath == NULL)
3915 #endif
3916  progpath = DBUS_BINDIR "/dbus-launch";
3917  /*
3918  * argv[0] is always dbus-launch, that's the name what we'll
3919  * get from /proc, or ps(1), regardless what the progpath is,
3920  * see fd.o#69716
3921  */
3922  i = 0;
3923  argv[i] = arg_dbus_launch;
3924  ++i;
3925  argv[i] = arg_autolaunch;
3926  ++i;
3927  argv[i] = _dbus_string_get_data (&uuid);
3928  ++i;
3929  argv[i] = arg_binary_syntax;
3930  ++i;
3931  argv[i] = arg_close_stderr;
3932  ++i;
3933  argv[i] = NULL;
3934  ++i;
3935 
3936  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3937 
3938  retval = _read_subprocess_line_argv (progpath,
3939  TRUE,
3940  argv, address, error);
3941 
3942  out:
3943  _dbus_string_free (&uuid);
3944  return retval;
3945 #else
3947  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3948  "set your DBUS_SESSION_BUS_ADDRESS instead");
3949  return FALSE;
3950 #endif
3951 }
3952 
3973  dbus_bool_t create_if_not_found,
3974  DBusError *error)
3975 {
3976  DBusError our_error = DBUS_ERROR_INIT;
3977  DBusError etc_error = DBUS_ERROR_INIT;
3978  DBusString filename;
3979  dbus_bool_t b;
3980 
3981  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3982 
3983  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
3984  if (b)
3985  return TRUE;
3986 
3987  /* Fallback to the system machine ID */
3988  _dbus_string_init_const (&filename, "/etc/machine-id");
3989  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
3990 
3991  if (b)
3992  {
3993  if (create_if_not_found)
3994  {
3995  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3996  * complain if that isn't possible for whatever reason */
3997  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3998  _dbus_write_uuid_file (&filename, machine_id, NULL);
3999  }
4000 
4001  dbus_error_free (&our_error);
4002  return TRUE;
4003  }
4004 
4005  if (!create_if_not_found)
4006  {
4007  dbus_set_error (error, etc_error.name,
4008  "D-Bus library appears to be incorrectly set up: "
4009  "see the manual page for dbus-uuidgen to correct "
4010  "this issue. (%s; %s)",
4011  our_error.message, etc_error.message);
4012  dbus_error_free (&our_error);
4013  dbus_error_free (&etc_error);
4014  return FALSE;
4015  }
4016 
4017  dbus_error_free (&our_error);
4018  dbus_error_free (&etc_error);
4019 
4020  /* if none found, try to make a new one */
4021  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4022 
4023  if (!_dbus_generate_uuid (machine_id, error))
4024  return FALSE;
4025 
4026  return _dbus_write_uuid_file (&filename, machine_id, error);
4027 }
4028 
4038  const char *launchd_env_var,
4039  DBusError *error)
4040 {
4041 #ifdef DBUS_ENABLE_LAUNCHD
4042  char *argv[4];
4043  int i;
4044 
4045  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4046 
4047  if (_dbus_check_setuid ())
4048  {
4050  "Unable to find launchd socket when setuid");
4051  return FALSE;
4052  }
4053 
4054  i = 0;
4055  argv[i] = "launchctl";
4056  ++i;
4057  argv[i] = "getenv";
4058  ++i;
4059  argv[i] = (char*)launchd_env_var;
4060  ++i;
4061  argv[i] = NULL;
4062  ++i;
4063 
4064  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4065 
4066  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4067  {
4068  return FALSE;
4069  }
4070 
4071  /* no error, but no result either */
4072  if (_dbus_string_get_length(socket_path) == 0)
4073  {
4074  return FALSE;
4075  }
4076 
4077  /* strip the carriage-return */
4078  _dbus_string_shorten(socket_path, 1);
4079  return TRUE;
4080 #else /* DBUS_ENABLE_LAUNCHD */
4082  "can't lookup socket from launchd; launchd support not compiled in");
4083  return FALSE;
4084 #endif
4085 }
4086 
4087 #ifdef DBUS_ENABLE_LAUNCHD
4088 static dbus_bool_t
4089 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4090 {
4091  dbus_bool_t valid_socket;
4092  DBusString socket_path;
4093 
4094  if (_dbus_check_setuid ())
4095  {
4097  "Unable to find launchd socket when setuid");
4098  return FALSE;
4099  }
4100 
4101  if (!_dbus_string_init (&socket_path))
4102  {
4103  _DBUS_SET_OOM (error);
4104  return FALSE;
4105  }
4106 
4107  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4108 
4109  if (dbus_error_is_set(error))
4110  {
4111  _dbus_string_free(&socket_path);
4112  return FALSE;
4113  }
4114 
4115  if (!valid_socket)
4116  {
4117  dbus_set_error(error, "no socket path",
4118  "launchd did not provide a socket path, "
4119  "verify that org.freedesktop.dbus-session.plist is loaded!");
4120  _dbus_string_free(&socket_path);
4121  return FALSE;
4122  }
4123  if (!_dbus_string_append (address, "unix:path="))
4124  {
4125  _DBUS_SET_OOM (error);
4126  _dbus_string_free(&socket_path);
4127  return FALSE;
4128  }
4129  if (!_dbus_string_copy (&socket_path, 0, address,
4130  _dbus_string_get_length (address)))
4131  {
4132  _DBUS_SET_OOM (error);
4133  _dbus_string_free(&socket_path);
4134  return FALSE;
4135  }
4136 
4137  _dbus_string_free(&socket_path);
4138  return TRUE;
4139 }
4140 #endif
4141 
4143 _dbus_lookup_user_bus (dbus_bool_t *supported,
4144  DBusString *address,
4145  DBusError *error)
4146 {
4147  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4148  dbus_bool_t ret = FALSE;
4149  struct stat stbuf;
4150  DBusString user_bus_path;
4151 
4152  if (runtime_dir == NULL)
4153  {
4154  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4155  *supported = FALSE;
4156  return TRUE; /* Cannot use it, but not an error */
4157  }
4158 
4159  if (!_dbus_string_init (&user_bus_path))
4160  {
4161  _DBUS_SET_OOM (error);
4162  return FALSE;
4163  }
4164 
4165  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4166  {
4167  _DBUS_SET_OOM (error);
4168  goto out;
4169  }
4170 
4171  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4172  {
4173  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4174  _dbus_strerror (errno));
4175  *supported = FALSE;
4176  ret = TRUE; /* Cannot use it, but not an error */
4177  goto out;
4178  }
4179 
4180  if (stbuf.st_uid != getuid ())
4181  {
4182  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4183  (long) stbuf.st_uid, (long) getuid ());
4184  *supported = FALSE;
4185  ret = TRUE; /* Cannot use it, but not an error */
4186  goto out;
4187  }
4188 
4189  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4190  {
4191  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4192  (long) stbuf.st_mode);
4193  *supported = FALSE;
4194  ret = TRUE; /* Cannot use it, but not an error */
4195  goto out;
4196  }
4197 
4198  if (!_dbus_string_append (address, "unix:path=") ||
4199  !_dbus_address_append_escaped (address, &user_bus_path))
4200  {
4201  _DBUS_SET_OOM (error);
4202  goto out;
4203  }
4204 
4205  *supported = TRUE;
4206  ret = TRUE;
4207 
4208 out:
4209  _dbus_string_free (&user_bus_path);
4210  return ret;
4211 }
4212 
4234  DBusString *address,
4235  DBusError *error)
4236 {
4237 #ifdef DBUS_ENABLE_LAUNCHD
4238  *supported = TRUE;
4239  return _dbus_lookup_session_address_launchd (address, error);
4240 #else
4241  *supported = FALSE;
4242 
4243  if (!_dbus_lookup_user_bus (supported, address, error))
4244  return FALSE;
4245  else if (*supported)
4246  return TRUE;
4247 
4248  /* On non-Mac Unix platforms, if the session address isn't already
4249  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4250  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4251  * autolaunch: global default; see init_session_address in
4252  * dbus/dbus-bus.c. */
4253  return TRUE;
4254 #endif
4255 }
4256 
4264 void
4266 {
4268 }
4269 
4285  DBusCredentials *credentials)
4286 {
4287  DBusString homedir;
4288  DBusString dotdir;
4289  dbus_uid_t uid;
4290 
4291  _dbus_assert (credentials != NULL);
4293 
4294  if (!_dbus_string_init (&homedir))
4295  return FALSE;
4296 
4297  uid = _dbus_credentials_get_unix_uid (credentials);
4298  _dbus_assert (uid != DBUS_UID_UNSET);
4299 
4300  if (!_dbus_homedir_from_uid (uid, &homedir))
4301  goto failed;
4302 
4303 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4304  {
4305  const char *override;
4306 
4307  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4308  if (override != NULL && *override != '\0')
4309  {
4310  _dbus_string_set_length (&homedir, 0);
4311  if (!_dbus_string_append (&homedir, override))
4312  goto failed;
4313 
4314  _dbus_verbose ("Using fake homedir for testing: %s\n",
4315  _dbus_string_get_const_data (&homedir));
4316  }
4317  else
4318  {
4319  /* Not strictly thread-safe, but if we fail at thread-safety here,
4320  * the worst that will happen is some extra warnings. */
4321  static dbus_bool_t already_warned = FALSE;
4322  if (!already_warned)
4323  {
4324  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4325  _dbus_string_get_const_data (&homedir));
4326  already_warned = TRUE;
4327  }
4328  }
4329  }
4330 #endif
4331 
4332  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4333  if (!_dbus_concat_dir_and_file (&homedir,
4334  &dotdir))
4335  goto failed;
4336 
4337  if (!_dbus_string_copy (&homedir, 0,
4338  directory, _dbus_string_get_length (directory))) {
4339  goto failed;
4340  }
4341 
4342  _dbus_string_free (&homedir);
4343  return TRUE;
4344 
4345  failed:
4346  _dbus_string_free (&homedir);
4347  return FALSE;
4348 }
4349 
4350 //PENDING(kdab) docs
4352 _dbus_daemon_publish_session_bus_address (const char* addr,
4353  const char *scope)
4354 {
4355  return TRUE;
4356 }
4357 
4358 //PENDING(kdab) docs
4359 void
4360 _dbus_daemon_unpublish_session_bus_address (void)
4361 {
4362 
4363 }
4364 
4373 {
4374  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4375  * EWOULDBLOCK are numerically equal, which is permitted as described by
4376  * errno(3).
4377  */
4378 #if EAGAIN == EWOULDBLOCK
4379  return e == EAGAIN;
4380 #else
4381  return e == EAGAIN || e == EWOULDBLOCK;
4382 #endif
4383 }
4384 
4394  DBusError *error)
4395 {
4396  const char *filename_c;
4397 
4398  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4399 
4400  filename_c = _dbus_string_get_const_data (filename);
4401 
4402  if (rmdir (filename_c) != 0)
4403  {
4405  "Failed to remove directory %s: %s\n",
4406  filename_c, _dbus_strerror (errno));
4407  return FALSE;
4408  }
4409 
4410  return TRUE;
4411 }
4412 
4422 {
4423 #ifdef SCM_RIGHTS
4424  union {
4425  struct sockaddr sa;
4426  struct sockaddr_storage storage;
4427  struct sockaddr_un un;
4428  } sa_buf;
4429 
4430  socklen_t sa_len = sizeof(sa_buf);
4431 
4432  _DBUS_ZERO(sa_buf);
4433 
4434  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4435  return FALSE;
4436 
4437  return sa_buf.sa.sa_family == AF_UNIX;
4438 
4439 #else
4440  return FALSE;
4441 
4442 #endif
4443 }
4444 
4449 void
4451 {
4452  int maxfds, i;
4453 
4454 #ifdef __linux__
4455  DIR *d;
4456 
4457  /* On Linux we can optimize this a bit if /proc is available. If it
4458  isn't available, fall back to the brute force way. */
4459 
4460  d = opendir ("/proc/self/fd");
4461  if (d)
4462  {
4463  for (;;)
4464  {
4465  struct dirent *de;
4466  int fd;
4467  long l;
4468  char *e = NULL;
4469 
4470  de = readdir (d);
4471  if (!de)
4472  break;
4473 
4474  if (de->d_name[0] == '.')
4475  continue;
4476 
4477  errno = 0;
4478  l = strtol (de->d_name, &e, 10);
4479  if (errno != 0 || e == NULL || *e != '\0')
4480  continue;
4481 
4482  fd = (int) l;
4483  if (fd < 3)
4484  continue;
4485 
4486  if (fd == dirfd (d))
4487  continue;
4488 
4489  close (fd);
4490  }
4491 
4492  closedir (d);
4493  return;
4494  }
4495 #endif
4496 
4497  maxfds = sysconf (_SC_OPEN_MAX);
4498 
4499  /* Pick something reasonable if for some reason sysconf says
4500  * unlimited.
4501  */
4502  if (maxfds < 0)
4503  maxfds = 1024;
4504 
4505  /* close all inherited fds */
4506  for (i = 3; i < maxfds; i++)
4507  close (i);
4508 }
4509 
4521 {
4522  /* TODO: get __libc_enable_secure exported from glibc.
4523  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4524  */
4525 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4526  {
4527  /* See glibc/include/unistd.h */
4528  extern int __libc_enable_secure;
4529  return __libc_enable_secure;
4530  }
4531 #elif defined(HAVE_ISSETUGID)
4532  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4533  return issetugid ();
4534 #else
4535  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4536  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4537 
4538  /* We call into this function from _dbus_threads_init_platform_specific()
4539  * to make sure these are initialized before we start threading. */
4540  static dbus_bool_t check_setuid_initialised;
4541  static dbus_bool_t is_setuid;
4542 
4543  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4544  {
4545 #ifdef HAVE_GETRESUID
4546  if (getresuid (&ruid, &euid, &suid) != 0 ||
4547  getresgid (&rgid, &egid, &sgid) != 0)
4548 #endif /* HAVE_GETRESUID */
4549  {
4550  suid = ruid = getuid ();
4551  sgid = rgid = getgid ();
4552  euid = geteuid ();
4553  egid = getegid ();
4554  }
4555 
4556  check_setuid_initialised = TRUE;
4557  is_setuid = (ruid != euid || ruid != suid ||
4558  rgid != egid || rgid != sgid);
4559 
4560  }
4561  return is_setuid;
4562 #endif
4563 }
4564 
4574  DBusString *address,
4575  DBusError *error)
4576 {
4577  union {
4578  struct sockaddr sa;
4579  struct sockaddr_storage storage;
4580  struct sockaddr_un un;
4581  struct sockaddr_in ipv4;
4582  struct sockaddr_in6 ipv6;
4583  } socket;
4584  char hostip[INET6_ADDRSTRLEN];
4585  socklen_t size = sizeof (socket);
4586  DBusString path_str;
4587 
4588  if (getsockname (fd.fd, &socket.sa, &size))
4589  goto err;
4590 
4591  switch (socket.sa.sa_family)
4592  {
4593  case AF_UNIX:
4594  if (socket.un.sun_path[0]=='\0')
4595  {
4596  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4597  if (_dbus_string_append (address, "unix:abstract=") &&
4598  _dbus_address_append_escaped (address, &path_str))
4599  return TRUE;
4600  }
4601  else
4602  {
4603  _dbus_string_init_const (&path_str, socket.un.sun_path);
4604  if (_dbus_string_append (address, "unix:path=") &&
4605  _dbus_address_append_escaped (address, &path_str))
4606  return TRUE;
4607  }
4608  break;
4609  case AF_INET:
4610  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4611  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4612  hostip, ntohs (socket.ipv4.sin_port)))
4613  return TRUE;
4614  break;
4615 #ifdef AF_INET6
4616  case AF_INET6:
4617  _dbus_string_init_const (&path_str, hostip);
4618  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4619  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4620  ntohs (socket.ipv6.sin6_port)) &&
4621  _dbus_address_append_escaped (address, &path_str))
4622  return TRUE;
4623  break;
4624 #endif
4625  default:
4626  dbus_set_error (error,
4627  _dbus_error_from_errno (EINVAL),
4628  "Failed to read address from socket: Unknown socket type.");
4629  return FALSE;
4630  }
4631  err:
4632  dbus_set_error (error,
4633  _dbus_error_from_errno (errno),
4634  "Failed to open socket: %s",
4635  _dbus_strerror (errno));
4636  return FALSE;
4637 }
4638 
4639 int
4640 _dbus_save_socket_errno (void)
4641 {
4642  return errno;
4643 }
4644 
4645 void
4646 _dbus_restore_socket_errno (int saved_errno)
4647 {
4648  errno = saved_errno;
4649 }
4650 
4651 static const char *syslog_tag = "dbus";
4652 #ifdef HAVE_SYSLOG_H
4653 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4654 #endif
4655 
4670 void
4671 _dbus_init_system_log (const char *tag,
4672  DBusLogFlags flags)
4673 {
4674  /* We never want to turn off logging completely */
4675  _dbus_assert (
4676  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4677 
4678  syslog_tag = tag;
4679 
4680 #ifdef HAVE_SYSLOG_H
4681  log_flags = flags;
4682 
4683  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4684  openlog (tag, LOG_PID, LOG_DAEMON);
4685 #endif
4686 }
4687 
4695 void
4696 _dbus_logv (DBusSystemLogSeverity severity,
4697  const char *msg,
4698  va_list args)
4699 {
4700  va_list tmp;
4701 #ifdef HAVE_SYSLOG_H
4702  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4703  {
4704  int flags;
4705  switch (severity)
4706  {
4707  case DBUS_SYSTEM_LOG_INFO:
4708  flags = LOG_DAEMON | LOG_INFO;
4709  break;
4710  case DBUS_SYSTEM_LOG_WARNING:
4711  flags = LOG_DAEMON | LOG_WARNING;
4712  break;
4713  case DBUS_SYSTEM_LOG_SECURITY:
4714  flags = LOG_AUTH | LOG_NOTICE;
4715  break;
4716  case DBUS_SYSTEM_LOG_ERROR:
4717  flags = LOG_DAEMON|LOG_CRIT;
4718  break;
4719  default:
4720  _dbus_assert_not_reached ("invalid log severity");
4721  }
4722 
4723  DBUS_VA_COPY (tmp, args);
4724  vsyslog (flags, msg, tmp);
4725  va_end (tmp);
4726  }
4727 
4728  /* If we don't have syslog.h, we always behave as though stderr was in
4729  * the flags */
4730  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4731 #endif
4732  {
4733  DBUS_VA_COPY (tmp, args);
4734  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4735  vfprintf (stderr, msg, tmp);
4736  fputc ('\n', stderr);
4737  va_end (tmp);
4738  }
4739 }
4740 
4741 /* tests in dbus-sysdeps-util.c */
_dbus_listen_tcp_socket
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
Definition: dbus-sysdeps-unix.c:1514
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:2846
_dbus_user_info_fill
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
Definition: dbus-sysdeps-unix.c:2658
_dbus_create_directory
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
Definition: dbus-sysdeps-unix.c:3058
DBusUserInfo::group_ids
dbus_gid_t * group_ids
Groups IDs, including above primary group.
Definition: dbus-sysdeps-unix.h:110
_DBUS_N_ELEMENTS
#define _DBUS_N_ELEMENTS(array)
Definition: dbus-internals.h:188
_dbus_user_info_fill_uid
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
Definition: dbus-sysdeps-unix.c:2675
DBusUserInfo::n_group_ids
int n_group_ids
Size of group IDs array.
Definition: dbus-sysdeps-unix.h:111
_dbus_getuid
dbus_uid_t _dbus_getuid(void)
Gets our UID.
Definition: dbus-sysdeps-unix.c:2741
dbus_realloc
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:602
_dbus_ensure_standard_fds
dbus_bool_t _dbus_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
Definition: dbus-sysdeps-unix.c:155
_dbus_append_address_from_socket
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
Definition: dbus-sysdeps-unix.c:4573
_dbus_concat_dir_and_file
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
Definition: dbus-sysdeps-unix.c:3089
_dbus_read_socket_with_unix_fds
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, unsigned int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
Definition: dbus-sysdeps-unix.c:358
DBusAtomic::value
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:311
_dbus_verbose_bytes_of_string
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
Definition: dbus-marshal-basic.c:1362
DBusPollFD::revents
short revents
Events that occurred.
Definition: dbus-sysdeps.h:401
_dbus_accept
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
Definition: dbus-sysdeps-unix.c:2290
_dbus_credentials_add_from_current_process
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
Definition: dbus-sysdeps-unix.c:2691
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
_dbus_lookup_launchd_socket
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
Definition: dbus-sysdeps-unix.c:4037
_dbus_generate_uuid
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
Definition: dbus-internals.c:667
_dbus_listen_systemd_sockets
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
Definition: dbus-sysdeps-unix.c:1239
_dbus_get_autolaunch_address
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
Definition: dbus-sysdeps-unix.c:3853
_dbus_error_from_errno
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:592
_dbus_set_socket_nonblocking
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
Definition: dbus-sysdeps-unix.c:3353
dbus_set_error_const
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
_dbus_write
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
Definition: dbus-sysdeps-unix.c:764
_dbus_disable_sigpipe
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
Definition: dbus-sysdeps-unix.c:3248
_dbus_string_append_uint
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:394
DBUS_UID_FORMAT
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:148
_dbus_flush_caches
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked.
Definition: dbus-sysdeps-unix.c:4265
_dbus_logv
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
Definition: dbus-sysdeps-unix.c:4696
_dbus_connect_unix_socket
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
Definition: dbus-sysdeps-unix.c:909
DBusPollFD::events
short events
Events to poll for.
Definition: dbus-sysdeps.h:400
_dbus_lookup_session_address
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method.
Definition: dbus-sysdeps-unix.c:4233
_dbus_string_copy
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1283
_dbus_string_lengthen
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
_dbus_append_keyring_directory_for_credentials
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
Definition: dbus-sysdeps-unix.c:4284
_dbus_get_monotonic_time
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Definition: dbus-sysdeps-unix.c:2973
DBusGUID
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
Definition: dbus-internals.h:394
_dbus_string_parse_int
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:437
DBusUserInfo::uid
dbus_uid_t uid
UID.
Definition: dbus-sysdeps-unix.h:108
_dbus_generate_random_bytes
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with.
Definition: dbus-sysdeps-unix.c:3164
_dbus_connect_tcp_socket
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
Definition: dbus-sysdeps-unix.c:1389
_dbus_listen_unix_socket
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
Definition: dbus-sysdeps-unix.c:1112
_dbus_string_append_byte
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1157
dbus_gid_t
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:136
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:2870
_dbus_connect_exec
int _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute.
Definition: dbus-sysdeps-unix.c:1006
_DBUS_LOCK
#define _DBUS_LOCK(name)
Definition: dbus-internals.h:372
dbus_int32_t
int dbus_int32_t
Definition: dbus-arch-deps.h:42
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:3311
TRUE
#define TRUE
WRITE_END
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:890
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-protocol.h:355
DBUS_ERROR_SPAWN_EXEC_FAILED
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
Definition: dbus-protocol.h:416
_dbus_init_system_log
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
Definition: dbus-sysdeps-unix.c:4671
_dbus_write_socket
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
Definition: dbus-sysdeps-unix.c:320
DBusUserInfo::username
char * username
Username.
Definition: dbus-sysdeps-unix.h:112
_dbus_read
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer.
Definition: dbus-sysdeps-unix.c:704
_dbus_credentials_get_unix_uid
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
Definition: dbus-credentials.c:297
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:702
_dbus_socket_can_pass_unix_fd
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
Definition: dbus-sysdeps-unix.c:4421
_DBUS_POLLERR
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:411
_dbus_parse_uid
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
Definition: dbus-sysdeps-unix.c:2775
dbus_malloc
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:462
_dbus_sleep_milliseconds
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
Definition: dbus-sysdeps-unix.c:3134
_dbus_exit
void _dbus_exit(int code)
Exit the process, returning the given value.
Definition: dbus-sysdeps-unix.c:3219
DBUS_ERROR_BAD_ADDRESS
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
Definition: dbus-protocol.h:367
_dbus_string_init_preallocated
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc.
Definition: dbus-string.c:132
DBusString
Definition: dbus-string.h:42
_dbus_check_setuid
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib.
Definition: dbus-sysdeps-unix.c:4520
_dbus_string_append_printf
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
DBusPollFD::fd
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:399
DBusUserInfo::homedir
char * homedir
Home directory.
Definition: dbus-sysdeps-unix.h:113
_dbus_credentials_add_pid
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
Definition: dbus-credentials.c:152
DBusSocket
Socket interface.
Definition: dbus-sysdeps.h:175
DBusError::name
const char * name
public error name field
Definition: dbus-errors.h:50
_dbus_read_uuid_file
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
Definition: dbus-internals.c:846
_dbus_credentials_clear
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
Definition: dbus-credentials.c:503
_dbus_printf_string_upper_bound
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul.
Definition: dbus-sysdeps-unix.c:3515
DBusCredentials
Definition: dbus-credentials.c:48
DBUS_MAXIMUM_MESSAGE_UNIX_FDS
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
Definition: dbus-protocol.h:218
dbus_pid_t
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:132
dbus_uid_t
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:134
DBUS_GID_FORMAT
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:150
FALSE
#define FALSE
DBusPollFD
Definition: dbus-sysdeps.h:397
DBUS_ERROR_NO_MEMORY
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
Definition: dbus-protocol.h:357
_dbus_string_get_data_len
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:490
DBUS_ERROR_INIT
#define DBUS_ERROR_INIT
Definition: dbus-errors.h:62
_dbus_write_two
int _dbus_write_two(int fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write() but will use writev() if possible to write both buffers in sequence.
Definition: dbus-sysdeps-unix.c:810
_dbus_check_dir_is_private_to_user
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
Definition: dbus-sysdeps-unix.c:2345
_dbus_get_tmpdir
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR,...
Definition: dbus-sysdeps-unix.c:3585
DBUS_UID_UNSET
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:141
DBUS_PID_UNSET
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:139
_dbus_send_credentials_socket
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
Definition: dbus-sysdeps-unix.c:2269
_dbus_fd_set_close_on_exec
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
Definition: dbus-sysdeps-unix.c:3261
dbus_error_is_set
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
_dbus_poll
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
Definition: dbus-sysdeps-unix.c:2895
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Definition: dbus-internals.h:163
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
_dbus_read_socket
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Definition: dbus-sysdeps-unix.c:302
DBusAtomic
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:306
dbus_new
#define dbus_new(type, count)
Definition: dbus-memory.h:57
_dbus_close_socket
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
Definition: dbus-sysdeps-unix.c:286
READ_END
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:888
_dbus_address_append_escaped
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
_dbus_get_real_time
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Definition: dbus-sysdeps-unix.c:3004
_dbus_assert
#define _dbus_assert(condition)
Definition: dbus-internals.h:152
dbus_error_free
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
DBusUserInfo
Information about a UNIX user.
Definition: dbus-sysdeps-unix.h:106
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:3283
_dbus_socketpair
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
Definition: dbus-sysdeps-unix.c:3440
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_geteuid
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
Definition: dbus-sysdeps-unix.c:2750
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:536
_dbus_user_database_flush_system
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:349
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:187
_dbus_getpid
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
Definition: dbus-sysdeps-unix.c:2732
_dbus_credentials_are_anonymous
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
Definition: dbus-credentials.c:408
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
_dbus_print_backtrace
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
Definition: dbus-sysdeps-unix.c:3398
_dbus_credentials_add_adt_audit_data
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
Definition: dbus-credentials.c:231
_dbus_append_user_from_current_process
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
Definition: dbus-sysdeps-unix.c:2721
_dbus_ensure_directory
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
Definition: dbus-sysdeps-unix.c:3026
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
DBUS_PID_FORMAT
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:146
_DBUS_POLLIN
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:405
DBusUserInfo::primary_gid
dbus_gid_t primary_gid
GID.
Definition: dbus-sysdeps-unix.h:109
_dbus_write_uuid_file
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
Definition: dbus-internals.c:797
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:2823
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Definition: dbus-internals.h:373
_dbus_read_local_machine_uuid
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
Definition: dbus-sysdeps-unix.c:3972
_dbus_credentials_add_linux_security_label
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials.
Definition: dbus-credentials.c:207
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
_DBUS_ZERO
#define _DBUS_ZERO(object)
Definition: dbus-internals.h:193
_dbus_homedir_from_uid
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:461
_dbus_get_local_machine_uuid_encoded
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
Definition: dbus-internals.c:898
DBUS_GID_UNSET
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:143
_dbus_string_init_const
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
_dbus_delete_directory
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Definition: dbus-sysdeps-unix.c:4393
_dbus_get_is_errno_eagain_or_ewouldblock
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted)
Definition: dbus-sysdeps-unix.c:4372
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:369
_dbus_string_shorten
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
_dbus_close_all
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
Definition: dbus-sysdeps-unix.c:4450
_dbus_string_append
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:935
_dbus_write_socket_two
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
Definition: dbus-sysdeps-unix.c:631
_dbus_pid_for_log
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
Definition: dbus-sysdeps-unix.c:2762
_DBUS_POLLOUT
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:409
DBUS_ERROR_IO_ERROR
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
Definition: dbus-protocol.h:365
_dbus_read_credentials_socket
dbus_bool_t _dbus_read_credentials_socket(DBusSocket client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
Definition: dbus-sysdeps-unix.c:1955
dbus_bool_t
dbus_uint32_t dbus_bool_t
Definition: dbus-types.h:35
NULL
#define NULL
_dbus_credentials_add_unix_uid
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
Definition: dbus-credentials.c:167