D-Bus  1.12.20
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 #ifdef HAVE_PDPLINUX
62 #include <parsec/pdp.h>
63 #include <parsec/parsec_cap.h>
64 #endif
65 
66 #ifdef HAVE_ERRNO_H
67 #include <errno.h>
68 #endif
69 #ifdef HAVE_SYSLOG_H
70 #include <syslog.h>
71 #endif
72 #ifdef HAVE_WRITEV
73 #include <sys/uio.h>
74 #endif
75 #ifdef HAVE_POLL
76 #include <sys/poll.h>
77 #endif
78 #ifdef HAVE_BACKTRACE
79 #include <execinfo.h>
80 #endif
81 #ifdef HAVE_GETPEERUCRED
82 #include <ucred.h>
83 #endif
84 #ifdef HAVE_ALLOCA_H
85 #include <alloca.h>
86 #endif
87 
88 #ifdef HAVE_ADT
89 #include <bsm/adt.h>
90 #endif
91 
92 #ifdef HAVE_SYSTEMD
93 #include <systemd/sd-daemon.h>
94 #endif
95 
96 #if !DBUS_USE_SYNC
97 #include <pthread.h>
98 #endif
99 
100 #ifndef O_BINARY
101 #define O_BINARY 0
102 #endif
103 
104 #ifndef AI_ADDRCONFIG
105 #define AI_ADDRCONFIG 0
106 #endif
107 
108 #ifndef HAVE_SOCKLEN_T
109 #define socklen_t int
110 #endif
111 
112 #if defined (__sun) || defined (__sun__)
113 /*
114  * CMS_SPACE etc. definitions for Solaris < 10, based on
115  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
116  * via
117  * http://wiki.opencsw.org/porting-faq#toc10
118  *
119  * These are only redefined for Solaris, for now: if your OS needs these too,
120  * please file a bug. (Or preferably, improve your OS so they're not needed.)
121  */
122 
123 # ifndef CMSG_ALIGN
124 # ifdef __sun__
125 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
126 # else
127  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
128 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
129  ~(sizeof (long) - 1))
130 # endif
131 # endif
132 
133 # ifndef CMSG_SPACE
134 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
135  CMSG_ALIGN (len))
136 # endif
137 
138 # ifndef CMSG_LEN
139 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
140 # endif
141 
142 #endif /* Solaris */
143 
159 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
160  const char **error_str_p)
161 {
162  static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
163  DBUS_FORCE_STDOUT_NULL,
164  DBUS_FORCE_STDERR_NULL };
165  /* Should always get replaced with the real error before use */
166  const char *error_str = "Failed mysteriously";
167  int devnull = -1;
168  int saved_errno;
169  /* This function relies on the standard fds having their POSIX values. */
170  _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
171  _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
172  _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
173  int i;
174 
175  for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
176  {
177  /* Because we rely on being single-threaded, and we want the
178  * standard fds to not be close-on-exec, we don't set it
179  * close-on-exec. */
180  if (devnull < i)
181  devnull = open ("/dev/null", O_RDWR);
182 
183  if (devnull < 0)
184  {
185  error_str = "Failed to open /dev/null";
186  goto out;
187  }
188 
189  /* We already opened all fds < i, so the only way this assertion
190  * could fail is if another thread closed one, and we document
191  * this function as not safe for multi-threading. */
192  _dbus_assert (devnull >= i);
193 
194  if (devnull != i && (flags & relevant_flag[i]) != 0)
195  {
196  if (dup2 (devnull, i) < 0)
197  {
198  error_str = "Failed to dup2 /dev/null onto a standard fd";
199  goto out;
200  }
201  }
202  }
203 
204  error_str = NULL;
205 
206 out:
207  saved_errno = errno;
208 
209  if (devnull > STDERR_FILENO)
210  close (devnull);
211 
212  if (error_str_p != NULL)
213  *error_str_p = error_str;
214 
215  errno = saved_errno;
216  return (error_str == NULL);
217 }
218 
219 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
220  DBusError *error);
221 
222 static dbus_bool_t
223 _dbus_open_socket (int *fd_p,
224  int domain,
225  int type,
226  int protocol,
227  DBusError *error)
228 {
229 #ifdef SOCK_CLOEXEC
230  dbus_bool_t cloexec_done;
231 
232  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
233  cloexec_done = *fd_p >= 0;
234 
235  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
236  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
237 #endif
238  {
239  *fd_p = socket (domain, type, protocol);
240  }
241 
242  if (*fd_p >= 0)
243  {
244 #ifdef SOCK_CLOEXEC
245  if (!cloexec_done)
246 #endif
247  {
249  }
250 
251  _dbus_verbose ("socket fd %d opened\n", *fd_p);
252  return TRUE;
253  }
254  else
255  {
256  dbus_set_error(error,
257  _dbus_error_from_errno (errno),
258  "Failed to open socket: %s",
259  _dbus_strerror (errno));
260  return FALSE;
261  }
262 }
263 
274 static dbus_bool_t
275 _dbus_open_unix_socket (int *fd,
276  DBusError *error)
277 {
278  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
279 }
280 
291  DBusError *error)
292 {
293  return _dbus_close (fd.fd, error);
294 }
295 
305 int
307  DBusString *buffer,
308  int count)
309 {
310  return _dbus_read (fd.fd, buffer, count);
311 }
312 
323 int
325  const DBusString *buffer,
326  int start,
327  int len)
328 {
329 #if HAVE_DECL_MSG_NOSIGNAL
330  const char *data;
331  int bytes_written;
332 
333  data = _dbus_string_get_const_data_len (buffer, start, len);
334 
335  again:
336 
337  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
338 
339  if (bytes_written < 0 && errno == EINTR)
340  goto again;
341 
342  return bytes_written;
343 
344 #else
345  return _dbus_write (fd.fd, buffer, start, len);
346 #endif
347 }
348 
361 int
363  DBusString *buffer,
364  int count,
365  int *fds,
366  unsigned int *n_fds) {
367 #ifndef HAVE_UNIX_FD_PASSING
368  int r;
369 
370  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
371  return r;
372 
373  *n_fds = 0;
374  return r;
375 
376 #else
377  int bytes_read;
378  int start;
379  struct msghdr m;
380  struct iovec iov;
381 
382  _dbus_assert (count >= 0);
384 
385  start = _dbus_string_get_length (buffer);
386 
387  if (!_dbus_string_lengthen (buffer, count))
388  {
389  errno = ENOMEM;
390  return -1;
391  }
392 
393  _DBUS_ZERO(iov);
394  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
395  iov.iov_len = count;
396 
397  _DBUS_ZERO(m);
398  m.msg_iov = &iov;
399  m.msg_iovlen = 1;
400 
401  /* Hmm, we have no clue how long the control data will actually be
402  that is queued for us. The least we can do is assume that the
403  caller knows. Hence let's make space for the number of fds that
404  we shall read at max plus the cmsg header. */
405  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
406 
407  /* It's probably safe to assume that systems with SCM_RIGHTS also
408  know alloca() */
409  m.msg_control = alloca(m.msg_controllen);
410  memset(m.msg_control, 0, m.msg_controllen);
411 
412  /* Do not include the padding at the end when we tell the kernel
413  * how much we're willing to receive. This avoids getting
414  * the padding filled with additional fds that we weren't expecting,
415  * if a (potentially malicious) sender included them. (fd.o #83622) */
416  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
417 
418  again:
419 
420  bytes_read = recvmsg (fd.fd, &m, 0
421 #ifdef MSG_CMSG_CLOEXEC
422  |MSG_CMSG_CLOEXEC
423 #endif
424  );
425 
426  if (bytes_read < 0)
427  {
428  if (errno == EINTR)
429  goto again;
430  else
431  {
432  /* put length back (note that this doesn't actually realloc anything) */
433  _dbus_string_set_length (buffer, start);
434  return -1;
435  }
436  }
437  else
438  {
439  struct cmsghdr *cm;
440  dbus_bool_t found = FALSE;
441 
442  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
443  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
444  {
445  size_t i;
446  int *payload = (int *) CMSG_DATA (cm);
447  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
448  size_t payload_len_fds;
449  size_t fds_to_use;
450 
451  /* Every unsigned int fits in a size_t without truncation, so
452  * casting (size_t) *n_fds is OK */
453  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
454 
455  if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
456  (char *) payload + payload_len_bytes >
457  (char *) m.msg_control + m.msg_controllen)
458  {
459  /* This is the last cmsg in a truncated message and using
460  * cmsg_len would apparently overrun the allocated buffer.
461  * Some operating systems (illumos and Solaris are known) do
462  * not adjust cmsg_len in the last cmsg when truncation occurs.
463  * Adjust the payload length here. The calculation for
464  * payload_len_fds below will discard any trailing bytes that
465  * belong to an incomplete file descriptor - the kernel will
466  * have already closed that (at least for illumos and Solaris)
467  */
468  payload_len_bytes = m.msg_controllen -
469  ((char *) payload - (char *) m.msg_control);
470  }
471 
472  payload_len_fds = payload_len_bytes / sizeof (int);
473 
474  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
475  {
476  /* The fds in the payload will fit in our buffer */
477  fds_to_use = payload_len_fds;
478  }
479  else
480  {
481  /* Too many fds in the payload. This shouldn't happen
482  * any more because we're setting m.msg_controllen to
483  * the exact number we can accept, but be safe and
484  * truncate. */
485  fds_to_use = (size_t) *n_fds;
486 
487  /* Close the excess fds to avoid DoS: if they stayed open,
488  * someone could send us an extra fd per message
489  * and we'd eventually run out. */
490  for (i = fds_to_use; i < payload_len_fds; i++)
491  {
492  close (payload[i]);
493  }
494  }
495 
496  memcpy (fds, payload, fds_to_use * sizeof (int));
497  found = TRUE;
498  /* This narrowing cast from size_t to unsigned int cannot
499  * overflow because we have chosen fds_to_use
500  * to be <= *n_fds */
501  *n_fds = (unsigned int) fds_to_use;
502 
503  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
504  worked, hence we need to go through this list and set
505  CLOEXEC everywhere in any case */
506  for (i = 0; i < fds_to_use; i++)
508 
509  break;
510  }
511 
512  if (!found)
513  *n_fds = 0;
514 
515  if (m.msg_flags & MSG_CTRUNC)
516  {
517  unsigned int i;
518 
519  /* Hmm, apparently the control data was truncated. The bad
520  thing is that we might have completely lost a couple of fds
521  without chance to recover them. Hence let's treat this as a
522  serious error. */
523 
524  /* We still need to close whatever fds we *did* receive,
525  * otherwise they'll never get closed. (CVE-2020-12049) */
526  for (i = 0; i < *n_fds; i++)
527  close (fds[i]);
528 
529  *n_fds = 0;
530  errno = ENOSPC;
531  _dbus_string_set_length (buffer, start);
532  return -1;
533  }
534 
535  /* put length back (doesn't actually realloc) */
536  _dbus_string_set_length (buffer, start + bytes_read);
537 
538 #if 0
539  if (bytes_read > 0)
540  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
541 #endif
542 
543  return bytes_read;
544  }
545 #endif
546 }
547 
548 int
549 _dbus_write_socket_with_unix_fds(DBusSocket fd,
550  const DBusString *buffer,
551  int start,
552  int len,
553  const int *fds,
554  int n_fds) {
555 
556 #ifndef HAVE_UNIX_FD_PASSING
557 
558  if (n_fds > 0) {
559  errno = ENOTSUP;
560  return -1;
561  }
562 
563  return _dbus_write_socket(fd, buffer, start, len);
564 #else
565  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
566 #endif
567 }
568 
569 int
570 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
571  const DBusString *buffer1,
572  int start1,
573  int len1,
574  const DBusString *buffer2,
575  int start2,
576  int len2,
577  const int *fds,
578  int n_fds) {
579 
580 #ifndef HAVE_UNIX_FD_PASSING
581 
582  if (n_fds > 0) {
583  errno = ENOTSUP;
584  return -1;
585  }
586 
587  return _dbus_write_socket_two(fd,
588  buffer1, start1, len1,
589  buffer2, start2, len2);
590 #else
591 
592  struct msghdr m;
593  struct cmsghdr *cm;
594  struct iovec iov[2];
595  int bytes_written;
596 
597  _dbus_assert (len1 >= 0);
598  _dbus_assert (len2 >= 0);
599  _dbus_assert (n_fds >= 0);
600 
601  _DBUS_ZERO(iov);
602  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
603  iov[0].iov_len = len1;
604 
605  if (buffer2)
606  {
607  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
608  iov[1].iov_len = len2;
609  }
610 
611  _DBUS_ZERO(m);
612  m.msg_iov = iov;
613  m.msg_iovlen = buffer2 ? 2 : 1;
614 
615  if (n_fds > 0)
616  {
617  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
618  m.msg_control = alloca(m.msg_controllen);
619  memset(m.msg_control, 0, m.msg_controllen);
620 
621  cm = CMSG_FIRSTHDR(&m);
622  cm->cmsg_level = SOL_SOCKET;
623  cm->cmsg_type = SCM_RIGHTS;
624  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
625  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
626  }
627 
628  again:
629 
630  bytes_written = sendmsg (fd.fd, &m, 0
631 #if HAVE_DECL_MSG_NOSIGNAL
632  |MSG_NOSIGNAL
633 #endif
634  );
635 
636  if (bytes_written < 0 && errno == EINTR)
637  goto again;
638 
639 #if 0
640  if (bytes_written > 0)
641  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
642 #endif
643 
644  return bytes_written;
645 #endif
646 }
647 
661 int
663  const DBusString *buffer1,
664  int start1,
665  int len1,
666  const DBusString *buffer2,
667  int start2,
668  int len2)
669 {
670 #if HAVE_DECL_MSG_NOSIGNAL
671  struct iovec vectors[2];
672  const char *data1;
673  const char *data2;
674  int bytes_written;
675  struct msghdr m;
676 
677  _dbus_assert (buffer1 != NULL);
678  _dbus_assert (start1 >= 0);
679  _dbus_assert (start2 >= 0);
680  _dbus_assert (len1 >= 0);
681  _dbus_assert (len2 >= 0);
682 
683  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
684 
685  if (buffer2 != NULL)
686  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
687  else
688  {
689  data2 = NULL;
690  start2 = 0;
691  len2 = 0;
692  }
693 
694  vectors[0].iov_base = (char*) data1;
695  vectors[0].iov_len = len1;
696  vectors[1].iov_base = (char*) data2;
697  vectors[1].iov_len = len2;
698 
699  _DBUS_ZERO(m);
700  m.msg_iov = vectors;
701  m.msg_iovlen = data2 ? 2 : 1;
702 
703  again:
704 
705  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
706 
707  if (bytes_written < 0 && errno == EINTR)
708  goto again;
709 
710  return bytes_written;
711 
712 #else
713  return _dbus_write_two (fd.fd, buffer1, start1, len1,
714  buffer2, start2, len2);
715 #endif
716 }
717 
734 int
735 _dbus_read (int fd,
736  DBusString *buffer,
737  int count)
738 {
739  int bytes_read;
740  int start;
741  char *data;
742 
743  _dbus_assert (count >= 0);
744 
745  start = _dbus_string_get_length (buffer);
746 
747  if (!_dbus_string_lengthen (buffer, count))
748  {
749  errno = ENOMEM;
750  return -1;
751  }
752 
753  data = _dbus_string_get_data_len (buffer, start, count);
754 
755  again:
756 
757  bytes_read = read (fd, data, count);
758 
759  if (bytes_read < 0)
760  {
761  if (errno == EINTR)
762  goto again;
763  else
764  {
765  /* put length back (note that this doesn't actually realloc anything) */
766  _dbus_string_set_length (buffer, start);
767  return -1;
768  }
769  }
770  else
771  {
772  /* put length back (doesn't actually realloc) */
773  _dbus_string_set_length (buffer, start + bytes_read);
774 
775 #if 0
776  if (bytes_read > 0)
777  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
778 #endif
779 
780  return bytes_read;
781  }
782 }
783 
794 int
795 _dbus_write (int fd,
796  const DBusString *buffer,
797  int start,
798  int len)
799 {
800  const char *data;
801  int bytes_written;
802 
803  data = _dbus_string_get_const_data_len (buffer, start, len);
804 
805  again:
806 
807  bytes_written = write (fd, data, len);
808 
809  if (bytes_written < 0 && errno == EINTR)
810  goto again;
811 
812 #if 0
813  if (bytes_written > 0)
814  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
815 #endif
816 
817  return bytes_written;
818 }
819 
840 int
842  const DBusString *buffer1,
843  int start1,
844  int len1,
845  const DBusString *buffer2,
846  int start2,
847  int len2)
848 {
849  _dbus_assert (buffer1 != NULL);
850  _dbus_assert (start1 >= 0);
851  _dbus_assert (start2 >= 0);
852  _dbus_assert (len1 >= 0);
853  _dbus_assert (len2 >= 0);
854 
855 #ifdef HAVE_WRITEV
856  {
857  struct iovec vectors[2];
858  const char *data1;
859  const char *data2;
860  int bytes_written;
861 
862  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
863 
864  if (buffer2 != NULL)
865  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
866  else
867  {
868  data2 = NULL;
869  start2 = 0;
870  len2 = 0;
871  }
872 
873  vectors[0].iov_base = (char*) data1;
874  vectors[0].iov_len = len1;
875  vectors[1].iov_base = (char*) data2;
876  vectors[1].iov_len = len2;
877 
878  again:
879 
880  bytes_written = writev (fd,
881  vectors,
882  data2 ? 2 : 1);
883 
884  if (bytes_written < 0 && errno == EINTR)
885  goto again;
886 
887  return bytes_written;
888  }
889 #else /* HAVE_WRITEV */
890  {
891  int ret1, ret2;
892 
893  ret1 = _dbus_write (fd, buffer1, start1, len1);
894  if (ret1 == len1 && buffer2 != NULL)
895  {
896  ret2 = _dbus_write (fd, buffer2, start2, len2);
897  if (ret2 < 0)
898  ret2 = 0; /* we can't report an error as the first write was OK */
899 
900  return ret1 + ret2;
901  }
902  else
903  return ret1;
904  }
905 #endif /* !HAVE_WRITEV */
906 }
907 
908 #define _DBUS_MAX_SUN_PATH_LENGTH 99
909 
939 int
940 _dbus_connect_unix_socket (const char *path,
941  dbus_bool_t abstract,
942  DBusError *error)
943 {
944  int fd;
945  size_t path_len;
946  struct sockaddr_un addr;
947  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
948 
949  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
950 
951  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
952  path, abstract);
953 
954 
955  if (!_dbus_open_unix_socket (&fd, error))
956  {
957  _DBUS_ASSERT_ERROR_IS_SET(error);
958  return -1;
959  }
960  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
961 
962  _DBUS_ZERO (addr);
963  addr.sun_family = AF_UNIX;
964  path_len = strlen (path);
965 
966  if (abstract)
967  {
968 #ifdef __linux__
969  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
970  path_len++; /* Account for the extra nul byte added to the start of sun_path */
971 
972  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
973  {
975  "Abstract socket name too long\n");
976  _dbus_close (fd, NULL);
977  return -1;
978  }
979 
980  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
981  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
982 #else /* !__linux__ */
984  "Operating system does not support abstract socket namespace\n");
985  _dbus_close (fd, NULL);
986  return -1;
987 #endif /* !__linux__ */
988  }
989  else
990  {
991  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
992  {
994  "Socket name too long\n");
995  _dbus_close (fd, NULL);
996  return -1;
997  }
998 
999  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1000  }
1001 
1002  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1003  {
1004  dbus_set_error (error,
1005  _dbus_error_from_errno (errno),
1006  "Failed to connect to socket %s: %s",
1007  path, _dbus_strerror (errno));
1008 
1009  _dbus_close (fd, NULL);
1010  return -1;
1011  }
1012 
1013  if (!_dbus_set_fd_nonblocking (fd, error))
1014  {
1015  _DBUS_ASSERT_ERROR_IS_SET (error);
1016 
1017  _dbus_close (fd, NULL);
1018  return -1;
1019  }
1020 
1021  return fd;
1022 }
1023 
1036 int
1037 _dbus_connect_exec (const char *path,
1038  char *const argv[],
1039  DBusError *error)
1040 {
1041  int fds[2];
1042  pid_t pid;
1043  int retval;
1044  dbus_bool_t cloexec_done = 0;
1045 
1046  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1047 
1048  _dbus_verbose ("connecting to process %s\n", path);
1049 
1050 #ifdef SOCK_CLOEXEC
1051  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1052  cloexec_done = (retval >= 0);
1053 
1054  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1055 #endif
1056  {
1057  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1058  }
1059 
1060  if (retval < 0)
1061  {
1062  dbus_set_error (error,
1063  _dbus_error_from_errno (errno),
1064  "Failed to create socket pair: %s",
1065  _dbus_strerror (errno));
1066  return -1;
1067  }
1068 
1069  if (!cloexec_done)
1070  {
1071  _dbus_fd_set_close_on_exec (fds[0]);
1072  _dbus_fd_set_close_on_exec (fds[1]);
1073  }
1074 
1075  pid = fork ();
1076  if (pid < 0)
1077  {
1078  dbus_set_error (error,
1079  _dbus_error_from_errno (errno),
1080  "Failed to fork() to call %s: %s",
1081  path, _dbus_strerror (errno));
1082  close (fds[0]);
1083  close (fds[1]);
1084  return -1;
1085  }
1086 
1087  if (pid == 0)
1088  {
1089  /* child */
1090  close (fds[0]);
1091 
1092  dup2 (fds[1], STDIN_FILENO);
1093  dup2 (fds[1], STDOUT_FILENO);
1094 
1095  if (fds[1] != STDIN_FILENO &&
1096  fds[1] != STDOUT_FILENO)
1097  close (fds[1]);
1098 
1099  /* Inherit STDERR and the controlling terminal from the
1100  parent */
1101 
1102  _dbus_close_all ();
1103 
1104  execvp (path, (char * const *) argv);
1105 
1106  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1107 
1108  _exit(1);
1109  }
1110 
1111  /* parent */
1112  close (fds[1]);
1113 
1114  if (!_dbus_set_fd_nonblocking (fds[0], error))
1115  {
1116  _DBUS_ASSERT_ERROR_IS_SET (error);
1117 
1118  close (fds[0]);
1119  return -1;
1120  }
1121 
1122  return fds[0];
1123 }
1124 
1142 int
1143 _dbus_listen_unix_socket (const char *path,
1144  dbus_bool_t abstract,
1145  DBusError *error)
1146 {
1147  int listen_fd;
1148  struct sockaddr_un addr;
1149  size_t path_len;
1150  _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1151 
1152  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1153 
1154  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1155  path, abstract);
1156 
1157  if (!_dbus_open_unix_socket (&listen_fd, error))
1158  {
1159  _DBUS_ASSERT_ERROR_IS_SET(error);
1160  return -1;
1161  }
1162  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1163 
1164  _DBUS_ZERO (addr);
1165  addr.sun_family = AF_UNIX;
1166  path_len = strlen (path);
1167 
1168  if (abstract)
1169  {
1170 #ifdef __linux__
1171  /* remember that abstract names aren't nul-terminated so we rely
1172  * on sun_path being filled in with zeroes above.
1173  */
1174  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1175  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1176 
1177  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1178  {
1180  "Abstract socket name too long\n");
1181  _dbus_close (listen_fd, NULL);
1182  return -1;
1183  }
1184 
1185  strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1186  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1187 #else /* !__linux__ */
1189  "Operating system does not support abstract socket namespace\n");
1190  _dbus_close (listen_fd, NULL);
1191  return -1;
1192 #endif /* !__linux__ */
1193  }
1194  else
1195  {
1196  /* Discussed security implications of this with Nalin,
1197  * and we couldn't think of where it would kick our ass, but
1198  * it still seems a bit sucky. It also has non-security suckage;
1199  * really we'd prefer to exit if the socket is already in use.
1200  * But there doesn't seem to be a good way to do this.
1201  *
1202  * Just to be extra careful, I threw in the stat() - clearly
1203  * the stat() can't *fix* any security issue, but it at least
1204  * avoids inadvertent/accidental data loss.
1205  */
1206  {
1207  struct stat sb;
1208 
1209  if (stat (path, &sb) == 0 &&
1210  S_ISSOCK (sb.st_mode))
1211  unlink (path);
1212  }
1213 
1214  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1215  {
1217  "Socket name too long\n");
1218  _dbus_close (listen_fd, NULL);
1219  return -1;
1220  }
1221 
1222  strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1223  }
1224 
1225  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1226  {
1227  dbus_set_error (error, _dbus_error_from_errno (errno),
1228  "Failed to bind socket \"%s\": %s",
1229  path, _dbus_strerror (errno));
1230  _dbus_close (listen_fd, NULL);
1231  return -1;
1232  }
1233 
1234  if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1235  {
1236  dbus_set_error (error, _dbus_error_from_errno (errno),
1237  "Failed to listen on socket \"%s\": %s",
1238  path, _dbus_strerror (errno));
1239  _dbus_close (listen_fd, NULL);
1240  return -1;
1241  }
1242 
1243  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1244  {
1245  _DBUS_ASSERT_ERROR_IS_SET (error);
1246  _dbus_close (listen_fd, NULL);
1247  return -1;
1248  }
1249 
1250  /* Try opening up the permissions, but if we can't, just go ahead
1251  * and continue, maybe it will be good enough.
1252  */
1253  if (!abstract && chmod (path, 0777) < 0)
1254  _dbus_warn ("Could not set mode 0777 on socket %s", path);
1255 
1256  return listen_fd;
1257 }
1258 
1269 int
1271  DBusError *error)
1272 {
1273 #ifdef HAVE_SYSTEMD
1274  int r, n;
1275  int fd;
1276  DBusSocket *new_fds;
1277 
1278 #ifdef HAVE_PDPLINUX
1279  _dbus_verbose("Entry (new socket processing NSP)\n");
1280 #endif
1281 
1282  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1283 
1284  n = sd_listen_fds (TRUE);
1285  if (n < 0)
1286  {
1288  "Failed to acquire systemd socket: %s",
1289  _dbus_strerror (-n));
1290  return -1;
1291  }
1292 
1293  if (n <= 0)
1294  {
1296  "No socket received.");
1297  return -1;
1298  }
1299 
1300  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1301  {
1302  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1303  if (r < 0)
1304  {
1306  "Failed to verify systemd socket type: %s",
1307  _dbus_strerror (-r));
1308  return -1;
1309  }
1310 
1311  if (!r)
1312  {
1314  "Passed socket has wrong type.");
1315  return -1;
1316  }
1317  }
1318 
1319  /* OK, the file descriptors are all good, so let's take posession of
1320  them then. */
1321 
1322  new_fds = dbus_new (DBusSocket, n);
1323  if (!new_fds)
1324  {
1326  "Failed to allocate file handle array.");
1327  goto fail;
1328  }
1329 
1330  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1331  {
1332  if (!_dbus_set_fd_nonblocking (fd, error))
1333  {
1334  _DBUS_ASSERT_ERROR_IS_SET (error);
1335  goto fail;
1336  }
1337 
1338  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1339  }
1340 
1341  *fds = new_fds;
1342  return n;
1343 
1344  fail:
1345 
1346  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1347  {
1348  _dbus_close (fd, NULL);
1349  }
1350 
1351  dbus_free (new_fds);
1352  return -1;
1353 #else
1355  "dbus was compiled without systemd support");
1356  return -1;
1357 #endif
1358 }
1359 
1360 /* Convert an error code from getaddrinfo() or getnameinfo() into
1361  * a D-Bus error name. */
1362 static const char *
1363 _dbus_error_from_gai (int gai_res,
1364  int saved_errno)
1365 {
1366  switch (gai_res)
1367  {
1368 #ifdef EAI_FAMILY
1369  case EAI_FAMILY:
1370  /* ai_family not supported (at all) */
1371  return DBUS_ERROR_NOT_SUPPORTED;
1372 #endif
1373 
1374 #ifdef EAI_SOCKTYPE
1375  case EAI_SOCKTYPE:
1376  /* ai_socktype not supported (at all) */
1377  return DBUS_ERROR_NOT_SUPPORTED;
1378 #endif
1379 
1380 #ifdef EAI_MEMORY
1381  case EAI_MEMORY:
1382  /* Out of memory */
1383  return DBUS_ERROR_NO_MEMORY;
1384 #endif
1385 
1386 #ifdef EAI_SYSTEM
1387  case EAI_SYSTEM:
1388  /* Unspecified system error, details in errno */
1389  return _dbus_error_from_errno (saved_errno);
1390 #endif
1391 
1392  case 0:
1393  /* It succeeded, but we didn't get any addresses? */
1394  return DBUS_ERROR_FAILED;
1395 
1396  /* EAI_AGAIN: Transient failure */
1397  /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1398  /* EAI_FAIL: Non-recoverable failure */
1399  /* EAI_NODATA: host exists but has no addresses */
1400  /* EAI_NONAME: host does not exist */
1401  /* EAI_OVERFLOW: argument buffer overflow */
1402  /* EAI_SERVICE: service not available for specified socket
1403  * type (we should never see this because we use numeric
1404  * ports) */
1405  default:
1406  return DBUS_ERROR_FAILED;
1407  }
1408 }
1409 
1423 DBusSocket
1424 _dbus_connect_tcp_socket (const char *host,
1425  const char *port,
1426  const char *family,
1427  DBusError *error)
1428 {
1429  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1430 }
1431 
1432 DBusSocket
1433 _dbus_connect_tcp_socket_with_nonce (const char *host,
1434  const char *port,
1435  const char *family,
1436  const char *noncefile,
1437  DBusError *error)
1438 {
1439  int saved_errno = 0;
1440  DBusSocket fd = DBUS_SOCKET_INIT;
1441  int res;
1442  struct addrinfo hints;
1443  struct addrinfo *ai, *tmp;
1444 
1445  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1446 
1447  _DBUS_ZERO (hints);
1448 
1449  if (!family)
1450  hints.ai_family = AF_UNSPEC;
1451  else if (!strcmp(family, "ipv4"))
1452  hints.ai_family = AF_INET;
1453  else if (!strcmp(family, "ipv6"))
1454  hints.ai_family = AF_INET6;
1455  else
1456  {
1457  dbus_set_error (error,
1459  "Unknown address family %s", family);
1460  return _dbus_socket_get_invalid ();
1461  }
1462  hints.ai_protocol = IPPROTO_TCP;
1463  hints.ai_socktype = SOCK_STREAM;
1464  hints.ai_flags = AI_ADDRCONFIG;
1465 
1466  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1467  {
1468  dbus_set_error (error,
1469  _dbus_error_from_gai (res, errno),
1470  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1471  host, port, gai_strerror(res), res);
1472  return _dbus_socket_get_invalid ();
1473  }
1474 
1475  tmp = ai;
1476  while (tmp)
1477  {
1478  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1479  {
1480  freeaddrinfo(ai);
1481  _DBUS_ASSERT_ERROR_IS_SET(error);
1482  return _dbus_socket_get_invalid ();
1483  }
1484  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1485 
1486  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1487  {
1488  saved_errno = errno;
1489  _dbus_close (fd.fd, NULL);
1490  fd.fd = -1;
1491  tmp = tmp->ai_next;
1492  continue;
1493  }
1494 
1495  break;
1496  }
1497  freeaddrinfo(ai);
1498 
1499  if (fd.fd == -1)
1500  {
1501  dbus_set_error (error,
1502  _dbus_error_from_errno (saved_errno),
1503  "Failed to connect to socket \"%s:%s\" %s",
1504  host, port, _dbus_strerror(saved_errno));
1505  return _dbus_socket_get_invalid ();
1506  }
1507 
1508  if (noncefile != NULL)
1509  {
1510  DBusString noncefileStr;
1511  dbus_bool_t ret;
1512  _dbus_string_init_const (&noncefileStr, noncefile);
1513  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1514  _dbus_string_free (&noncefileStr);
1515 
1516  if (!ret)
1517  {
1518  _dbus_close (fd.fd, NULL);
1519  return _dbus_socket_get_invalid ();
1520  }
1521  }
1522 
1523  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1524  {
1525  _dbus_close (fd.fd, NULL);
1526  return _dbus_socket_get_invalid ();
1527  }
1528 
1529  return fd;
1530 }
1531 
1548 int
1549 _dbus_listen_tcp_socket (const char *host,
1550  const char *port,
1551  const char *family,
1552  DBusString *retport,
1553  DBusSocket **fds_p,
1554  DBusError *error)
1555 {
1556  int saved_errno;
1557  int nlisten_fd = 0, res, i;
1558  DBusSocket *listen_fd = NULL;
1559  struct addrinfo hints;
1560  struct addrinfo *ai, *tmp;
1561  unsigned int reuseaddr;
1562 
1563  *fds_p = NULL;
1564  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1565 
1566  _DBUS_ZERO (hints);
1567 
1568  if (!family)
1569  hints.ai_family = AF_UNSPEC;
1570  else if (!strcmp(family, "ipv4"))
1571  hints.ai_family = AF_INET;
1572  else if (!strcmp(family, "ipv6"))
1573  hints.ai_family = AF_INET6;
1574  else
1575  {
1576  dbus_set_error (error,
1578  "Unknown address family %s", family);
1579  return -1;
1580  }
1581 
1582  hints.ai_protocol = IPPROTO_TCP;
1583  hints.ai_socktype = SOCK_STREAM;
1584  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1585 
1586  redo_lookup_with_port:
1587  ai = NULL;
1588  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1589  {
1590  dbus_set_error (error,
1591  _dbus_error_from_gai (res, errno),
1592  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1593  host ? host : "*", port, gai_strerror(res), res);
1594  goto failed;
1595  }
1596 
1597  tmp = ai;
1598  while (tmp)
1599  {
1600  int fd = -1, tcp_nodelay_on;
1601  DBusSocket *newlisten_fd;
1602 
1603  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1604  {
1605  _DBUS_ASSERT_ERROR_IS_SET(error);
1606  goto failed;
1607  }
1608  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1609 
1610  reuseaddr = 1;
1611  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1612  {
1613  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1614  host ? host : "*", port, _dbus_strerror (errno));
1615  }
1616 
1617  /* Nagle's algorithm imposes a huge delay on the initial messages
1618  going over TCP. */
1619  tcp_nodelay_on = 1;
1620  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1621  {
1622  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1623  host ? host : "*", port, _dbus_strerror (errno));
1624  }
1625 
1626  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1627  {
1628  saved_errno = errno;
1629  _dbus_close(fd, NULL);
1630  if (saved_errno == EADDRINUSE)
1631  {
1632  /* Depending on kernel policy, binding to an IPv6 address
1633  might implicitly bind to a corresponding IPv4
1634  address or vice versa, resulting in EADDRINUSE for the
1635  other one (e.g. bindv6only=0 on Linux).
1636 
1637  Also, after we "goto redo_lookup_with_port" after binding
1638  a port on one of the possible addresses, we will
1639  try to bind that same port on every address, including the
1640  same address again for a second time; that one will
1641  also fail with EADDRINUSE.
1642 
1643  For both those reasons, ignore EADDRINUSE here */
1644  tmp = tmp->ai_next;
1645  continue;
1646  }
1647  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1648  "Failed to bind socket \"%s:%s\": %s",
1649  host ? host : "*", port, _dbus_strerror (saved_errno));
1650  goto failed;
1651  }
1652 
1653  if (listen (fd, 30 /* backlog */) < 0)
1654  {
1655  saved_errno = errno;
1656  _dbus_close (fd, NULL);
1657  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1658  "Failed to listen on socket \"%s:%s\": %s",
1659  host ? host : "*", port, _dbus_strerror (saved_errno));
1660  goto failed;
1661  }
1662 
1663  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1664  if (!newlisten_fd)
1665  {
1666  _dbus_close (fd, NULL);
1668  "Failed to allocate file handle array");
1669  goto failed;
1670  }
1671  listen_fd = newlisten_fd;
1672  listen_fd[nlisten_fd].fd = fd;
1673  nlisten_fd++;
1674 
1675  if (!_dbus_string_get_length(retport))
1676  {
1677  /* If the user didn't specify a port, or used 0, then
1678  the kernel chooses a port. After the first address
1679  is bound to, we need to force all remaining addresses
1680  to use the same port */
1681  if (!port || !strcmp(port, "0"))
1682  {
1683  int result;
1684  struct sockaddr_storage addr;
1685  socklen_t addrlen;
1686  char portbuf[50];
1687 
1688  addrlen = sizeof(addr);
1689  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1690 
1691  if (result == -1)
1692  {
1693  saved_errno = errno;
1694  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1695  "Failed to retrieve socket name for \"%s:%s\": %s",
1696  host ? host : "*", port, _dbus_strerror (saved_errno));
1697  goto failed;
1698  }
1699 
1700  if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1701  portbuf, sizeof(portbuf),
1702  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1703  {
1704  saved_errno = errno;
1705  dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1706  "Failed to resolve port \"%s:%s\": %s (%d)",
1707  host ? host : "*", port, gai_strerror(res), res);
1708  goto failed;
1709  }
1710 
1711  if (!_dbus_string_append(retport, portbuf))
1712  {
1714  goto failed;
1715  }
1716 
1717  /* Release current address list & redo lookup */
1718  port = _dbus_string_get_const_data(retport);
1719  freeaddrinfo(ai);
1720  goto redo_lookup_with_port;
1721  }
1722  else
1723  {
1724  if (!_dbus_string_append(retport, port))
1725  {
1727  goto failed;
1728  }
1729  }
1730  }
1731 
1732  tmp = tmp->ai_next;
1733  }
1734  freeaddrinfo(ai);
1735  ai = NULL;
1736 
1737  if (!nlisten_fd)
1738  {
1739  errno = EADDRINUSE;
1740  dbus_set_error (error, _dbus_error_from_errno (errno),
1741  "Failed to bind socket \"%s:%s\": %s",
1742  host ? host : "*", port, _dbus_strerror (errno));
1743  goto failed;
1744  }
1745 
1746  for (i = 0 ; i < nlisten_fd ; i++)
1747  {
1748  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1749  {
1750  goto failed;
1751  }
1752  }
1753 
1754  *fds_p = listen_fd;
1755 
1756  return nlisten_fd;
1757 
1758  failed:
1759  if (ai)
1760  freeaddrinfo(ai);
1761  for (i = 0 ; i < nlisten_fd ; i++)
1762  _dbus_close(listen_fd[i].fd, NULL);
1763  dbus_free(listen_fd);
1764  return -1;
1765 }
1766 
1767 static dbus_bool_t
1768 write_credentials_byte (int server_fd,
1769  DBusError *error)
1770 {
1771  int bytes_written;
1772  char buf[1] = { '\0' };
1773 #if defined(HAVE_CMSGCRED)
1774  union {
1775  struct cmsghdr hdr;
1776  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1777  } cmsg;
1778  struct iovec iov;
1779  struct msghdr msg;
1780  iov.iov_base = buf;
1781  iov.iov_len = 1;
1782 
1783  _DBUS_ZERO(msg);
1784  msg.msg_iov = &iov;
1785  msg.msg_iovlen = 1;
1786 
1787  msg.msg_control = (caddr_t) &cmsg;
1788  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1789  _DBUS_ZERO(cmsg);
1790  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1791  cmsg.hdr.cmsg_level = SOL_SOCKET;
1792  cmsg.hdr.cmsg_type = SCM_CREDS;
1793 #endif
1794 
1795  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1796 
1797  again:
1798 
1799 #if defined(HAVE_CMSGCRED)
1800  bytes_written = sendmsg (server_fd, &msg, 0
1801 #if HAVE_DECL_MSG_NOSIGNAL
1802  |MSG_NOSIGNAL
1803 #endif
1804  );
1805 
1806  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1807  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1808  * only allows that on AF_UNIX. Try just doing a send() instead. */
1809  if (bytes_written < 0 && errno == EINVAL)
1810 #endif
1811  {
1812  bytes_written = send (server_fd, buf, 1, 0
1813 #if HAVE_DECL_MSG_NOSIGNAL
1814  |MSG_NOSIGNAL
1815 #endif
1816  );
1817  }
1818 
1819  if (bytes_written < 0 && errno == EINTR)
1820  goto again;
1821 
1822  if (bytes_written < 0)
1823  {
1824  dbus_set_error (error, _dbus_error_from_errno (errno),
1825  "Failed to write credentials byte: %s",
1826  _dbus_strerror (errno));
1827  return FALSE;
1828  }
1829  else if (bytes_written == 0)
1830  {
1832  "wrote zero bytes writing credentials byte");
1833  return FALSE;
1834  }
1835  else
1836  {
1837  _dbus_assert (bytes_written == 1);
1838  _dbus_verbose ("wrote credentials byte\n");
1839  return TRUE;
1840  }
1841 }
1842 
1843 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1844 static dbus_bool_t
1845 add_linux_security_label_to_credentials (int client_fd,
1846  DBusCredentials *credentials)
1847 {
1848 #if defined(__linux__) && defined(SO_PEERSEC)
1849  DBusString buf;
1850  socklen_t len = 1024;
1851  dbus_bool_t oom = FALSE;
1852 
1853  if (!_dbus_string_init_preallocated (&buf, len) ||
1854  !_dbus_string_set_length (&buf, len))
1855  return FALSE;
1856 
1857  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1858  _dbus_string_get_data (&buf), &len) < 0)
1859  {
1860  int e = errno;
1861 
1862  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1863  _dbus_strerror (e), (unsigned long) len);
1864 
1865  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1866  {
1867  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1868  _dbus_strerror (e));
1869  goto out;
1870  }
1871 
1872  /* If not enough space, len is updated to be enough.
1873  * Try again with a large enough buffer. */
1874  if (!_dbus_string_set_length (&buf, len))
1875  {
1876  oom = TRUE;
1877  goto out;
1878  }
1879 
1880  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1881  }
1882 
1883  if (len <= 0)
1884  {
1885  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1886  (unsigned long) len);
1887  goto out;
1888  }
1889 
1890  if (len > _dbus_string_get_length_uint (&buf))
1891  {
1892  _dbus_verbose ("%lu > %u", (unsigned long) len,
1893  _dbus_string_get_length_uint (&buf));
1894  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1895  }
1896 
1897  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1898  {
1899  /* the kernel included the trailing \0 in its count,
1900  * but DBusString always has an extra \0 after the data anyway */
1901  _dbus_verbose ("subtracting trailing \\0\n");
1902  len--;
1903  }
1904 
1905  if (!_dbus_string_set_length (&buf, len))
1906  {
1907  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1908  oom = TRUE;
1909  goto out;
1910  }
1911 
1912  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1913  {
1914  /* LSM people on the linux-security-module@ mailing list say this
1915  * should never happen: the label should be a bytestring with
1916  * an optional trailing \0 */
1917  _dbus_verbose ("security label from kernel had an embedded \\0, "
1918  "ignoring it\n");
1919  goto out;
1920  }
1921 
1922  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1923  (unsigned long) len,
1924  _dbus_string_get_const_data (&buf));
1925 
1927  _dbus_string_get_const_data (&buf)))
1928  {
1929  oom = TRUE;
1930  goto out;
1931  }
1932 
1933 out:
1934  _dbus_string_free (&buf);
1935  return !oom;
1936 #else
1937  /* no error */
1938  return TRUE;
1939 #endif
1940 }
1941 
1984  DBusCredentials *credentials,
1985  DBusError *error)
1986 {
1987  struct msghdr msg;
1988  struct iovec iov;
1989  char buf;
1990 
1991 #ifdef HAVE_PDPLINUX
1992  parsec_caps_t caps;
1993  int res_cap=0;
1994  PDPL_T* pdpl=NULL;
1995  BusPDPLinuxID* read_parsecid=NULL;
1996  dbus_uid_t uid_read=0;//added
1997  dbus_pid_t pid_read=0;
1998  int bytes_read=0;
1999 #else
2000  dbus_uid_t uid_read;
2001  dbus_pid_t pid_read;
2002  int bytes_read;
2003 #endif
2004 
2005 #ifdef HAVE_CMSGCRED
2006  union {
2007  struct cmsghdr hdr;
2008  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2009  } cmsg;
2010 #endif
2011 
2012  /* The POSIX spec certainly doesn't promise this, but
2013  * we need these assertions to fail as soon as we're wrong about
2014  * it so we can do the porting fixups
2015  */
2016  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2017  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2018  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2019 
2020  uid_read = DBUS_UID_UNSET;
2021  pid_read = DBUS_PID_UNSET;
2022 
2023  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2024 
2025  _dbus_credentials_clear (credentials);
2026 
2027  iov.iov_base = &buf;
2028  iov.iov_len = 1;
2029 
2030  _DBUS_ZERO(msg);
2031  msg.msg_iov = &iov;
2032  msg.msg_iovlen = 1;
2033 
2034 #if defined(HAVE_CMSGCRED)
2035  _DBUS_ZERO(cmsg);
2036  msg.msg_control = (caddr_t) &cmsg;
2037  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2038 #endif
2039 
2040  again:
2041  bytes_read = recvmsg (client_fd.fd, &msg, 0);
2042 
2043  if (bytes_read < 0)
2044  {
2045  if (errno == EINTR)
2046  goto again;
2047 
2048  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2049  * normally only call read_credentials if the socket was ready
2050  * for reading
2051  */
2052 
2053  dbus_set_error (error, _dbus_error_from_errno (errno),
2054  "Failed to read credentials byte: %s",
2055  _dbus_strerror (errno));
2056  return FALSE;
2057  }
2058  else if (bytes_read == 0)
2059  {
2060  /* this should not happen unless we are using recvmsg wrong,
2061  * so is essentially here for paranoia
2062  */
2064  "Failed to read credentials byte (zero-length read)");
2065  return FALSE;
2066  }
2067  else if (buf != '\0')
2068  {
2070  "Credentials byte was not nul");
2071  return FALSE;
2072  }
2073 
2074  _dbus_verbose ("read credentials byte\n");
2075 
2076  {
2077 #ifdef SO_PEERCRED
2078  /* Supported by at least Linux and OpenBSD, with minor differences.
2079  *
2080  * This mechanism passes the process ID through and does not require
2081  * the peer's cooperation, so we prefer it over all others. Notably,
2082  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2083  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2084  * because this is much less fragile.
2085  */
2086 #ifdef __OpenBSD__
2087  struct sockpeercred cr;
2088 #else
2089  struct ucred cr;
2090 #endif
2091  socklen_t cr_len = sizeof (cr);
2092 
2093  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2094  {
2095  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2096  _dbus_strerror (errno));
2097  }
2098  else if (cr_len != sizeof (cr))
2099  {
2100  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2101  cr_len, (int) sizeof (cr));
2102  }
2103  else
2104  {
2105  pid_read = cr.pid;
2106  uid_read = cr.uid;
2107 
2108 #ifdef HAVE_PDPLINUX
2109 
2110  memset(&caps,0xCC,sizeof(caps));
2111 
2112  res_cap=parsec_capget(pid_read,&caps);
2113  if (0!=res_cap){
2114  _dbus_verbose("parsec_capget: %m\n");
2115 
2116  _dbus_verbose("So: set caps=0\n");
2117  res_cap=0;// Set caps readed
2118  memset(&caps,0,sizeof(caps));
2119  }
2120  else{
2121  _dbus_verbose("parsec_capget: success\n");
2122  }
2123 
2124  pdpl=pdp_get_peer_label(client_fd.fd);
2125  if (!pdpl){
2126  _dbus_verbose("pdp_get_peer_label: %m\n");
2127  }
2128  else{
2129  _dbus_verbose("pdp_get_peer_label: success\n");
2130  }
2131 
2132  if (pid_read && (0==res_cap) && pdpl ){
2133  size_t sz=0;
2134  void* rawlabel=NULL;
2135 
2136  _dbus_verbose("call pdpl_get_raw\n");
2137  rawlabel=pdpl_get_raw(pdpl,&sz);
2138 
2139  if (rawlabel){
2140  read_parsecid=dbus_malloc0(sizeof(*read_parsecid)+sz);
2141 
2142  if (read_parsecid){
2143  memcpy(&read_parsecid->caps,&caps,sizeof(caps));
2144 
2145  read_parsecid->sz_pdplinux_context=sz;
2146 
2147  memcpy(read_parsecid->pdplinux_context,rawlabel,sz);
2148 
2149  if (!_dbus_credentials_pdplinux_add_unix_parsec(credentials, read_parsecid)){
2150  _dbus_verbose("_dbus_credentials_add_unix_parsec failed!\n");
2151  }
2152  else{
2153  _dbus_verbose("_dbus_credentials_add_unix_parsec OK!\n");
2154 
2155  _dbus_pdplinux_show_text_label_info3("Label to process", read_parsecid);
2156  }
2157  dbus_free(read_parsecid);
2158  read_parsecid=NULL;
2159  }
2160  else{
2161  _dbus_verbose("No memory\n");
2162  }
2163 
2164  free(rawlabel);
2165  }
2166  else{
2167  _dbus_verbose("pdpl_get_raw failed so no caps/no pdpl: %m\n");
2168  }
2169 
2170  }
2171  else{
2172  _dbus_verbose("Get process label and caps for pid=%ld (current pid is %ld) failed: caps - %s, pdp_get_pid - %s\n",
2173  pid_read,_dbus_getpid(),
2174  0==res_cap ? "OK" : "Failed",
2175  pdpl ? "OK" : "Failed");
2176  }
2177 
2178  if (pdpl) pdpl_put(pdpl);
2179  pdpl=NULL;
2180 #endif
2181  }
2182 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2183  /* Another variant of the above - used on NetBSD
2184  */
2185  struct unpcbid cr;
2186  socklen_t cr_len = sizeof (cr);
2187 
2188  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2189  {
2190  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2191  _dbus_strerror (errno));
2192  }
2193  else if (cr_len != sizeof (cr))
2194  {
2195  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2196  cr_len, (int) sizeof (cr));
2197  }
2198  else
2199  {
2200  pid_read = cr.unp_pid;
2201  uid_read = cr.unp_euid;
2202  }
2203 #elif defined(HAVE_CMSGCRED)
2204  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2205  * presence of that struct implies SCM_CREDS. Supported by at least
2206  * FreeBSD and DragonflyBSD.
2207  *
2208  * This mechanism requires the peer to help us (it has to send us a
2209  * SCM_CREDS message) but it does pass the process ID through,
2210  * which makes it better than getpeereid().
2211  */
2212  struct cmsgcred *cred;
2213  struct cmsghdr *cmsgp;
2214 
2215  for (cmsgp = CMSG_FIRSTHDR (&msg);
2216  cmsgp != NULL;
2217  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2218  {
2219  if (cmsgp->cmsg_type == SCM_CREDS &&
2220  cmsgp->cmsg_level == SOL_SOCKET &&
2221  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2222  {
2223  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
2224  pid_read = cred->cmcred_pid;
2225  uid_read = cred->cmcred_euid;
2226  break;
2227  }
2228  }
2229 
2230 #elif defined(HAVE_GETPEERUCRED)
2231  /* Supported in at least Solaris >= 10. It should probably be higher
2232  * up this list, because it carries the pid and we use this code path
2233  * for audit data. */
2234  ucred_t * ucred = NULL;
2235  if (getpeerucred (client_fd.fd, &ucred) == 0)
2236  {
2237 #ifdef HAVE_ADT
2238  adt_session_data_t *adth = NULL;
2239 #endif
2240  pid_read = ucred_getpid (ucred);
2241  uid_read = ucred_geteuid (ucred);
2242 #ifdef HAVE_ADT
2243  /* generate audit session data based on socket ucred */
2244  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2245  {
2246  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2247  }
2248  else
2249  {
2250  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2251  {
2252  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2253  }
2254  else
2255  {
2256  adt_export_data_t *data = NULL;
2257  size_t size = adt_export_session_data (adth, &data);
2258  if (size <= 0)
2259  {
2260  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2261  }
2262  else
2263  {
2264  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2265  free (data);
2266  }
2267  }
2268  (void) adt_end_session (adth);
2269  }
2270 #endif /* HAVE_ADT */
2271  }
2272  else
2273  {
2274  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2275  }
2276  if (ucred != NULL)
2277  ucred_free (ucred);
2278 
2279  /* ----------------------------------------------------------------
2280  * When adding new mechanisms, please add them above this point
2281  * if they support passing the process ID through, or below if not.
2282  * ---------------------------------------------------------------- */
2283 
2284 #elif defined(HAVE_GETPEEREID)
2285  /* getpeereid() originates from D.J. Bernstein and is fairly
2286  * widely-supported. According to a web search, it might be present in
2287  * any/all of:
2288  *
2289  * - AIX?
2290  * - Blackberry?
2291  * - Cygwin
2292  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2293  * - Mac OS X
2294  * - Minix 3.1.8+
2295  * - MirBSD?
2296  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2297  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2298  * - QNX?
2299  */
2300  uid_t euid;
2301  gid_t egid;
2302  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2303  {
2304  uid_read = euid;
2305  }
2306  else
2307  {
2308  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2309  }
2310 #else /* no supported mechanism */
2311 
2312 #warning Socket credentials not supported on this Unix OS
2313 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2314 
2315  /* Please add other operating systems known to support at least one of
2316  * the mechanisms above to this list, keeping alphabetical order.
2317  * Everything not in this list is best-effort.
2318  */
2319 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2320  defined(__linux__) || \
2321  defined(__OpenBSD__) || \
2322  defined(__NetBSD__)
2323 # error Credentials passing not working on this OS is a regression!
2324 #endif
2325 
2326  _dbus_verbose ("Socket credentials not supported on this OS\n");
2327 #endif
2328  }
2329 
2330  _dbus_verbose ("Credentials:"
2331  " pid "DBUS_PID_FORMAT
2332  " uid "DBUS_UID_FORMAT
2333  "\n",
2334  pid_read,
2335  uid_read);
2336 
2337  if (pid_read != DBUS_PID_UNSET)
2338  {
2339  if (!_dbus_credentials_add_pid (credentials, pid_read))
2340  {
2341  _DBUS_SET_OOM (error);
2342  return FALSE;
2343  }
2344  }
2345 
2346  if (uid_read != DBUS_UID_UNSET)
2347  {
2348  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2349  {
2350  _DBUS_SET_OOM (error);
2351  return FALSE;
2352  }
2353  }
2354 
2355  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2356  {
2357  _DBUS_SET_OOM (error);
2358  return FALSE;
2359  }
2360 
2361 #ifdef HAVE_PDPLINUX
2362  if (read_parsecid)
2363  {
2364  if (!_dbus_credentials_pdplinux_add_unix_parsec (credentials, read_parsecid))
2365  {
2366  _dbus_verbose ("_dbus_credentials_add_unix_parsec: failed\n");
2367  _DBUS_SET_OOM (error);
2368  return FALSE;
2369  }
2370  else{
2371  _dbus_verbose ("_dbus_credentials_add_unix_parsec: OK\n");
2372  }
2373  dbus_free(read_parsecid);
2374  }
2375 #endif
2376  return TRUE;
2377 }
2378 
2398  DBusError *error)
2399 {
2400  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2401 
2402  if (write_credentials_byte (server_fd.fd, error))
2403  return TRUE;
2404  else
2405  return FALSE;
2406 }
2407 
2417 DBusSocket
2419 {
2420  DBusSocket client_fd;
2421  struct sockaddr addr;
2422  socklen_t addrlen;
2423 #ifdef HAVE_ACCEPT4
2424  dbus_bool_t cloexec_done;
2425 #endif
2426 
2427  addrlen = sizeof (addr);
2428 
2429  retry:
2430 
2431 #ifdef HAVE_ACCEPT4
2432  /*
2433  * At compile-time, we assume that if accept4() is available in
2434  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2435  * not necessarily true that either is supported by the running kernel.
2436  */
2437  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2438  cloexec_done = client_fd.fd >= 0;
2439 
2440  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2441 #endif
2442  {
2443  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2444  }
2445 
2446  if (client_fd.fd < 0)
2447  {
2448  if (errno == EINTR)
2449  goto retry;
2450  }
2451 
2452  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2453 
2454 #ifdef HAVE_ACCEPT4
2455  if (!cloexec_done)
2456 #endif
2457  {
2458  _dbus_fd_set_close_on_exec(client_fd.fd);
2459  }
2460 
2461  return client_fd;
2462 }
2463 
2474 {
2475  const char *directory;
2476  struct stat sb;
2477 
2478  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2479 
2480  directory = _dbus_string_get_const_data (dir);
2481 
2482  if (stat (directory, &sb) < 0)
2483  {
2484  dbus_set_error (error, _dbus_error_from_errno (errno),
2485  "%s", _dbus_strerror (errno));
2486 
2487  return FALSE;
2488  }
2489 
2490  if (sb.st_uid != geteuid ())
2491  {
2493  "%s directory is owned by user %lu, not %lu",
2494  directory,
2495  (unsigned long) sb.st_uid,
2496  (unsigned long) geteuid ());
2497  return FALSE;
2498  }
2499 
2500  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2501  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2502  {
2504  "%s directory is not private to the user", directory);
2505  return FALSE;
2506  }
2507 
2508  return TRUE;
2509 }
2510 
2511 static dbus_bool_t
2512 fill_user_info_from_passwd (struct passwd *p,
2513  DBusUserInfo *info,
2514  DBusError *error)
2515 {
2516  _dbus_assert (p->pw_name != NULL);
2517  _dbus_assert (p->pw_dir != NULL);
2518 
2519  info->uid = p->pw_uid;
2520  info->primary_gid = p->pw_gid;
2521  info->username = _dbus_strdup (p->pw_name);
2522  info->homedir = _dbus_strdup (p->pw_dir);
2523 
2524  if (info->username == NULL ||
2525  info->homedir == NULL)
2526  {
2528  return FALSE;
2529  }
2530 
2531  return TRUE;
2532 }
2533 
2534 static dbus_bool_t
2535 fill_user_info (DBusUserInfo *info,
2536  dbus_uid_t uid,
2537  const DBusString *username,
2538  DBusError *error)
2539 {
2540  const char *username_c;
2541 
2542  /* exactly one of username/uid provided */
2543  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2544  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2545 
2546  info->uid = DBUS_UID_UNSET;
2547  info->primary_gid = DBUS_GID_UNSET;
2548  info->group_ids = NULL;
2549  info->n_group_ids = 0;
2550  info->username = NULL;
2551  info->homedir = NULL;
2552 
2553  if (username != NULL)
2554  username_c = _dbus_string_get_const_data (username);
2555  else
2556  username_c = NULL;
2557 
2558  /* For now assuming that the getpwnam() and getpwuid() flavors
2559  * are always symmetrical, if not we have to add more configure
2560  * checks
2561  */
2562 
2563 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2564  {
2565  struct passwd *p;
2566  int result;
2567  size_t buflen;
2568  char *buf;
2569  struct passwd p_str;
2570 
2571  /* retrieve maximum needed size for buf */
2572  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2573 
2574  /* sysconf actually returns a long, but everything else expects size_t,
2575  * so just recast here.
2576  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2577  */
2578  if ((long) buflen <= 0)
2579  buflen = 1024;
2580 
2581  result = -1;
2582  while (1)
2583  {
2584  buf = dbus_malloc (buflen);
2585  if (buf == NULL)
2586  {
2588  return FALSE;
2589  }
2590 
2591  p = NULL;
2592 #ifdef HAVE_POSIX_GETPWNAM_R
2593  if (uid != DBUS_UID_UNSET)
2594  result = getpwuid_r (uid, &p_str, buf, buflen,
2595  &p);
2596  else
2597  result = getpwnam_r (username_c, &p_str, buf, buflen,
2598  &p);
2599 #else
2600  if (uid != DBUS_UID_UNSET)
2601  p = getpwuid_r (uid, &p_str, buf, buflen);
2602  else
2603  p = getpwnam_r (username_c, &p_str, buf, buflen);
2604  result = 0;
2605 #endif /* !HAVE_POSIX_GETPWNAM_R */
2606  //Try a bigger buffer if ERANGE was returned
2607  if (result == ERANGE && buflen < 512 * 1024)
2608  {
2609  dbus_free (buf);
2610  buflen *= 2;
2611  }
2612  else
2613  {
2614  break;
2615  }
2616  }
2617  if (result == 0 && p == &p_str)
2618  {
2619  if (!fill_user_info_from_passwd (p, info, error))
2620  {
2621  dbus_free (buf);
2622  return FALSE;
2623  }
2624  dbus_free (buf);
2625  }
2626  else
2627  {
2628  dbus_set_error (error, _dbus_error_from_errno (errno),
2629  "User \"%s\" unknown or no memory to allocate password entry\n",
2630  username_c ? username_c : "???");
2631  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2632  dbus_free (buf);
2633  return FALSE;
2634  }
2635  }
2636 #else /* ! HAVE_GETPWNAM_R */
2637  {
2638  /* I guess we're screwed on thread safety here */
2639  struct passwd *p;
2640 
2641  if (uid != DBUS_UID_UNSET)
2642  p = getpwuid (uid);
2643  else
2644  p = getpwnam (username_c);
2645 
2646  if (p != NULL)
2647  {
2648  if (!fill_user_info_from_passwd (p, info, error))
2649  {
2650  return FALSE;
2651  }
2652  }
2653  else
2654  {
2655  dbus_set_error (error, _dbus_error_from_errno (errno),
2656  "User \"%s\" unknown or no memory to allocate password entry\n",
2657  username_c ? username_c : "???");
2658  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2659  return FALSE;
2660  }
2661  }
2662 #endif /* ! HAVE_GETPWNAM_R */
2663 
2664  /* Fill this in so we can use it to get groups */
2665  username_c = info->username;
2666 
2667 #ifdef HAVE_GETGROUPLIST
2668  {
2669  gid_t *buf;
2670  int buf_count;
2671  int i;
2672  int initial_buf_count;
2673 
2674  initial_buf_count = 17;
2675  buf_count = initial_buf_count;
2676  buf = dbus_new (gid_t, buf_count);
2677  if (buf == NULL)
2678  {
2680  goto failed;
2681  }
2682 
2683  if (getgrouplist (username_c,
2684  info->primary_gid,
2685  buf, &buf_count) < 0)
2686  {
2687  gid_t *new;
2688  /* Presumed cause of negative return code: buf has insufficient
2689  entries to hold the entire group list. The Linux behavior in this
2690  case is to pass back the actual number of groups in buf_count, but
2691  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2692  So as a hack, try to help out a bit by guessing a larger
2693  number of groups, within reason.. might still fail, of course,
2694  but we can at least print a more informative message. I looked up
2695  the "right way" to do this by downloading Apple's own source code
2696  for the "id" command, and it turns out that they use an
2697  undocumented library function getgrouplist_2 (!) which is not
2698  declared in any header in /usr/include (!!). That did not seem
2699  like the way to go here.
2700  */
2701  if (buf_count == initial_buf_count)
2702  {
2703  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2704  }
2705  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2706  if (new == NULL)
2707  {
2709  dbus_free (buf);
2710  goto failed;
2711  }
2712 
2713  buf = new;
2714 
2715  errno = 0;
2716  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2717  {
2718  if (errno == 0)
2719  {
2720  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2721  username_c, buf_count, buf_count);
2722  }
2723  else
2724  {
2725  dbus_set_error (error,
2726  _dbus_error_from_errno (errno),
2727  "Failed to get groups for username \"%s\" primary GID "
2728  DBUS_GID_FORMAT ": %s\n",
2729  username_c, info->primary_gid,
2730  _dbus_strerror (errno));
2731  dbus_free (buf);
2732  goto failed;
2733  }
2734  }
2735  }
2736 
2737  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2738  if (info->group_ids == NULL)
2739  {
2741  dbus_free (buf);
2742  goto failed;
2743  }
2744 
2745  for (i = 0; i < buf_count; ++i)
2746  info->group_ids[i] = buf[i];
2747 
2748  info->n_group_ids = buf_count;
2749 
2750  dbus_free (buf);
2751  }
2752 #else /* HAVE_GETGROUPLIST */
2753  {
2754  /* We just get the one group ID */
2755  info->group_ids = dbus_new (dbus_gid_t, 1);
2756  if (info->group_ids == NULL)
2757  {
2759  goto failed;
2760  }
2761 
2762  info->n_group_ids = 1;
2763 
2764  (info->group_ids)[0] = info->primary_gid;
2765  }
2766 #endif /* HAVE_GETGROUPLIST */
2767 
2768  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2769 
2770  return TRUE;
2771 
2772  failed:
2773  _DBUS_ASSERT_ERROR_IS_SET (error);
2774  return FALSE;
2775 }
2776 
2787  const DBusString *username,
2788  DBusError *error)
2789 {
2790  return fill_user_info (info, DBUS_UID_UNSET,
2791  username, error);
2792 }
2793 
2804  dbus_uid_t uid,
2805  DBusError *error)
2806 {
2807  return fill_user_info (info, uid,
2808  NULL, error);
2809 }
2810 
2820 {
2821 #ifdef HAVE_PDPLINUX
2822  dbus_bool_t res=TRUE;
2823  int res_cap;
2824  parsec_caps_t caps={0,0,0};
2825  PDPL_T* pdpl;
2826  BusPDPLinuxID* parsecid=NULL;
2827  dbus_pid_t curpid;
2828 #endif
2829  /* The POSIX spec certainly doesn't promise this, but
2830  * we need these assertions to fail as soon as we're wrong about
2831  * it so we can do the porting fixups
2832  */
2833  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2834  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2835  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2836 
2837  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2838  return FALSE;
2839  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2840  return FALSE;
2841 
2842 #ifdef HAVE_PDPLINUX
2843  memset(&caps,0,sizeof(caps));
2844  curpid=_dbus_getpid();
2845 
2846  res_cap=parsec_capget(0,&caps);
2847  if (0!=res_cap) _dbus_verbose("parsec_capget: %m\n");
2848 
2849  pdpl=pdp_get_current();
2850  if (!pdpl) _dbus_verbose("pdp_get_current: %m\n");
2851 
2852  if ( 0==res_cap && pdpl ){
2853  size_t sz;
2854  void* rawlabel;
2855 
2856  _dbus_verbose("Get caps and label to process pid=%ld\n",curpid);
2857 
2858  rawlabel=pdpl_get_raw(pdpl,&sz);
2859 
2860  if (rawlabel){
2861  parsecid=dbus_malloc0(sizeof(*parsecid)+sz);
2862 
2863  if (parsecid){
2864  parsecid->caps=caps;
2865  parsecid->sz_pdplinux_context=sz;
2866 
2867  memcpy(parsecid->pdplinux_context,rawlabel,sz);
2868 
2869  if (!_dbus_credentials_pdplinux_add_unix_parsec(credentials, parsecid)){
2870  _dbus_verbose("_dbus_credentials_add_unix_parsec failed so no caps and label\n");
2871  res=FALSE;
2872  }
2873 
2874  dbus_free(parsecid);
2875  }
2876  else{
2877  _dbus_verbose("No memory\n");
2878  res=FALSE;
2879  }
2880 
2881  free(rawlabel);
2882  }
2883  else{
2884  _dbus_verbose("pdpl_get_raw failed so no caps and label: %m\n");
2885  res=FALSE;
2886  }
2887  }
2888  else{
2889  _dbus_verbose("Get process label and caps for pid=%ld (this is current process) failed: caps - %s, pdp_get_pid - %s\n",
2890  curpid,
2891  0==res_cap ? "OK" : "Failed",
2892  pdpl ? "OK" : "Failed");
2893  // FIXME: here status must be FALSE
2894  // res=FALSE;
2895  }
2896 
2897  if (pdpl) pdpl_put(pdpl);
2898 
2899  return res;
2900 #else
2901  return TRUE;
2902 #endif
2903 
2904 
2905 }
2906 
2920 {
2921  return _dbus_string_append_uint (str,
2922  _dbus_geteuid ());
2923 }
2924 
2929 dbus_pid_t
2931 {
2932  return getpid ();
2933 }
2934 
2938 dbus_uid_t
2940 {
2941  return getuid ();
2942 }
2943 
2947 dbus_uid_t
2949 {
2950  return geteuid ();
2951 }
2952 
2959 unsigned long
2961 {
2962  return getpid ();
2963 }
2964 
2973 _dbus_parse_uid (const DBusString *uid_str,
2974  dbus_uid_t *uid)
2975 {
2976  int end;
2977  long val;
2978 
2979  if (_dbus_string_get_length (uid_str) == 0)
2980  {
2981  _dbus_verbose ("UID string was zero length\n");
2982  return FALSE;
2983  }
2984 
2985  val = -1;
2986  end = 0;
2987  if (!_dbus_string_parse_int (uid_str, 0, &val,
2988  &end))
2989  {
2990  _dbus_verbose ("could not parse string as a UID\n");
2991  return FALSE;
2992  }
2993 
2994  if (end != _dbus_string_get_length (uid_str))
2995  {
2996  _dbus_verbose ("string contained trailing stuff after UID\n");
2997  return FALSE;
2998  }
2999 
3000  *uid = val;
3001 
3002  return TRUE;
3003 }
3004 
3005 #if !DBUS_USE_SYNC
3006 /* To be thread-safe by default on platforms that don't necessarily have
3007  * atomic operations (notably Debian armel, which is armv4t), we must
3008  * use a mutex that can be initialized statically, like this.
3009  * GLib >= 2.32 uses a similar system.
3010  */
3011 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3012 #endif
3013 
3020 dbus_int32_t
3022 {
3023 #if DBUS_USE_SYNC
3024  return __sync_add_and_fetch(&atomic->value, 1)-1;
3025 #else
3026  dbus_int32_t res;
3027 
3028  pthread_mutex_lock (&atomic_mutex);
3029  res = atomic->value;
3030  atomic->value += 1;
3031  pthread_mutex_unlock (&atomic_mutex);
3032 
3033  return res;
3034 #endif
3035 }
3036 
3043 dbus_int32_t
3045 {
3046 #if DBUS_USE_SYNC
3047  return __sync_sub_and_fetch(&atomic->value, 1)+1;
3048 #else
3049  dbus_int32_t res;
3050 
3051  pthread_mutex_lock (&atomic_mutex);
3052  res = atomic->value;
3053  atomic->value -= 1;
3054  pthread_mutex_unlock (&atomic_mutex);
3055 
3056  return res;
3057 #endif
3058 }
3059 
3067 dbus_int32_t
3069 {
3070 #if DBUS_USE_SYNC
3071  __sync_synchronize ();
3072  return atomic->value;
3073 #else
3074  dbus_int32_t res;
3075 
3076  pthread_mutex_lock (&atomic_mutex);
3077  res = atomic->value;
3078  pthread_mutex_unlock (&atomic_mutex);
3079 
3080  return res;
3081 #endif
3082 }
3083 
3092 int
3094  int n_fds,
3095  int timeout_milliseconds)
3096 {
3097 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3098  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3099  if (timeout_milliseconds < -1)
3100  {
3101  timeout_milliseconds = -1;
3102  }
3103 
3104  return poll (fds,
3105  n_fds,
3106  timeout_milliseconds);
3107 #else /* ! HAVE_POLL */
3108  /* Emulate poll() in terms of select() */
3109  fd_set read_set, write_set, err_set;
3110  int max_fd = 0;
3111  int i;
3112  struct timeval tv;
3113  int ready;
3114 
3115  FD_ZERO (&read_set);
3116  FD_ZERO (&write_set);
3117  FD_ZERO (&err_set);
3118 
3119  for (i = 0; i < n_fds; i++)
3120  {
3121  DBusPollFD *fdp = &fds[i];
3122 
3123  if (fdp->events & _DBUS_POLLIN)
3124  FD_SET (fdp->fd, &read_set);
3125 
3126  if (fdp->events & _DBUS_POLLOUT)
3127  FD_SET (fdp->fd, &write_set);
3128 
3129  FD_SET (fdp->fd, &err_set);
3130 
3131  max_fd = MAX (max_fd, fdp->fd);
3132  }
3133 
3134  tv.tv_sec = timeout_milliseconds / 1000;
3135  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3136 
3137  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3138  timeout_milliseconds < 0 ? NULL : &tv);
3139 
3140  if (ready > 0)
3141  {
3142  for (i = 0; i < n_fds; i++)
3143  {
3144  DBusPollFD *fdp = &fds[i];
3145 
3146  fdp->revents = 0;
3147 
3148  if (FD_ISSET (fdp->fd, &read_set))
3149  fdp->revents |= _DBUS_POLLIN;
3150 
3151  if (FD_ISSET (fdp->fd, &write_set))
3152  fdp->revents |= _DBUS_POLLOUT;
3153 
3154  if (FD_ISSET (fdp->fd, &err_set))
3155  fdp->revents |= _DBUS_POLLERR;
3156  }
3157  }
3158 
3159  return ready;
3160 #endif
3161 }
3162 
3170 void
3172  long *tv_usec)
3173 {
3174 #ifdef HAVE_MONOTONIC_CLOCK
3175  struct timespec ts;
3176  clock_gettime (CLOCK_MONOTONIC, &ts);
3177 
3178  if (tv_sec)
3179  *tv_sec = ts.tv_sec;
3180  if (tv_usec)
3181  *tv_usec = ts.tv_nsec / 1000;
3182 #else
3183  struct timeval t;
3184 
3185  gettimeofday (&t, NULL);
3186 
3187  if (tv_sec)
3188  *tv_sec = t.tv_sec;
3189  if (tv_usec)
3190  *tv_usec = t.tv_usec;
3191 #endif
3192 }
3193 
3201 void
3202 _dbus_get_real_time (long *tv_sec,
3203  long *tv_usec)
3204 {
3205  struct timeval t;
3206 
3207  gettimeofday (&t, NULL);
3208 
3209  if (tv_sec)
3210  *tv_sec = t.tv_sec;
3211  if (tv_usec)
3212  *tv_usec = t.tv_usec;
3213 }
3214 
3225  DBusError *error)
3226 {
3227  const char *filename_c;
3228 
3229  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3230 
3231  filename_c = _dbus_string_get_const_data (filename);
3232 
3233  if (mkdir (filename_c, 0700) < 0)
3234  {
3235  if (errno == EEXIST)
3236  return TRUE;
3237 
3239  "Failed to create directory %s: %s\n",
3240  filename_c, _dbus_strerror (errno));
3241  return FALSE;
3242  }
3243  else
3244  return TRUE;
3245 }
3246 
3257  DBusError *error)
3258 {
3259  const char *filename_c;
3260 
3261  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3262 
3263  filename_c = _dbus_string_get_const_data (filename);
3264 
3265  if (mkdir (filename_c, 0700) < 0)
3266  {
3268  "Failed to create directory %s: %s\n",
3269  filename_c, _dbus_strerror (errno));
3270  return FALSE;
3271  }
3272  else
3273  return TRUE;
3274 }
3275 
3288  const DBusString *next_component)
3289 {
3290  dbus_bool_t dir_ends_in_slash;
3291  dbus_bool_t file_starts_with_slash;
3292 
3293  if (_dbus_string_get_length (dir) == 0 ||
3294  _dbus_string_get_length (next_component) == 0)
3295  return TRUE;
3296 
3297  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3298  _dbus_string_get_length (dir) - 1);
3299 
3300  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3301 
3302  if (dir_ends_in_slash && file_starts_with_slash)
3303  {
3304  _dbus_string_shorten (dir, 1);
3305  }
3306  else if (!(dir_ends_in_slash || file_starts_with_slash))
3307  {
3308  if (!_dbus_string_append_byte (dir, '/'))
3309  return FALSE;
3310  }
3311 
3312  return _dbus_string_copy (next_component, 0, dir,
3313  _dbus_string_get_length (dir));
3314 }
3315 
3317 #define NANOSECONDS_PER_SECOND 1000000000
3318 
3319 #define MICROSECONDS_PER_SECOND 1000000
3320 
3321 #define MILLISECONDS_PER_SECOND 1000
3322 
3323 #define NANOSECONDS_PER_MILLISECOND 1000000
3324 
3325 #define MICROSECONDS_PER_MILLISECOND 1000
3326 
3331 void
3332 _dbus_sleep_milliseconds (int milliseconds)
3333 {
3334 #ifdef HAVE_NANOSLEEP
3335  struct timespec req;
3336  struct timespec rem;
3337 
3338  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3339  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3340  rem.tv_sec = 0;
3341  rem.tv_nsec = 0;
3342 
3343  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3344  req = rem;
3345 #elif defined (HAVE_USLEEP)
3346  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3347 #else /* ! HAVE_USLEEP */
3348  sleep (MAX (milliseconds / 1000, 1));
3349 #endif
3350 }
3351 
3363  int n_bytes,
3364  DBusError *error)
3365 {
3366  int old_len;
3367  int fd;
3368  int result;
3369 
3370  old_len = _dbus_string_get_length (str);
3371  fd = -1;
3372 
3373  /* note, urandom on linux will fall back to pseudorandom */
3374  fd = open ("/dev/urandom", O_RDONLY);
3375 
3376  if (fd < 0)
3377  {
3378  dbus_set_error (error, _dbus_error_from_errno (errno),
3379  "Could not open /dev/urandom: %s",
3380  _dbus_strerror (errno));
3381  return FALSE;
3382  }
3383 
3384  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3385 
3386  result = _dbus_read (fd, str, n_bytes);
3387 
3388  if (result != n_bytes)
3389  {
3390  if (result < 0)
3391  dbus_set_error (error, _dbus_error_from_errno (errno),
3392  "Could not read /dev/urandom: %s",
3393  _dbus_strerror (errno));
3394  else
3396  "Short read from /dev/urandom");
3397 
3398  _dbus_close (fd, NULL);
3399  _dbus_string_set_length (str, old_len);
3400  return FALSE;
3401  }
3402 
3403  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3404  n_bytes);
3405 
3406  _dbus_close (fd, NULL);
3407 
3408  return TRUE;
3409 }
3410 
3416 void
3417 _dbus_exit (int code)
3418 {
3419  _exit (code);
3420 }
3421 
3430 const char*
3431 _dbus_strerror (int error_number)
3432 {
3433  const char *msg;
3434 
3435  msg = strerror (error_number);
3436  if (msg == NULL)
3437  msg = "unknown";
3438 
3439  return msg;
3440 }
3441 
3445 void
3447 {
3448  signal (SIGPIPE, SIG_IGN);
3449 }
3450 
3458 void
3460 {
3461  int val;
3462 
3463  val = fcntl (fd, F_GETFD, 0);
3464 
3465  if (val < 0)
3466  return;
3467 
3468  val |= FD_CLOEXEC;
3469 
3470  fcntl (fd, F_SETFD, val);
3471 }
3472 
3481 _dbus_close (int fd,
3482  DBusError *error)
3483 {
3484  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3485 
3486  again:
3487  if (close (fd) < 0)
3488  {
3489  if (errno == EINTR)
3490  goto again;
3491 
3492  dbus_set_error (error, _dbus_error_from_errno (errno),
3493  "Could not close fd %d", fd);
3494  return FALSE;
3495  }
3496 
3497  return TRUE;
3498 }
3499 
3508 int
3509 _dbus_dup(int fd,
3510  DBusError *error)
3511 {
3512  int new_fd;
3513 
3514 #ifdef F_DUPFD_CLOEXEC
3515  dbus_bool_t cloexec_done;
3516 
3517  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3518  cloexec_done = new_fd >= 0;
3519 
3520  if (new_fd < 0 && errno == EINVAL)
3521 #endif
3522  {
3523  new_fd = fcntl(fd, F_DUPFD, 3);
3524  }
3525 
3526  if (new_fd < 0) {
3527 
3528  dbus_set_error (error, _dbus_error_from_errno (errno),
3529  "Could not duplicate fd %d", fd);
3530  return -1;
3531  }
3532 
3533 #ifdef F_DUPFD_CLOEXEC
3534  if (!cloexec_done)
3535 #endif
3536  {
3538  }
3539 
3540  return new_fd;
3541 }
3542 
3552  DBusError *error)
3553 {
3554  return _dbus_set_fd_nonblocking (fd.fd, error);
3555 }
3556 
3557 static dbus_bool_t
3558 _dbus_set_fd_nonblocking (int fd,
3559  DBusError *error)
3560 {
3561  int val;
3562 
3563  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3564 
3565  val = fcntl (fd, F_GETFL, 0);
3566  if (val < 0)
3567  {
3568  dbus_set_error (error, _dbus_error_from_errno (errno),
3569  "Failed to get flags from file descriptor %d: %s",
3570  fd, _dbus_strerror (errno));
3571  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3572  _dbus_strerror (errno));
3573  return FALSE;
3574  }
3575 
3576  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3577  {
3578  dbus_set_error (error, _dbus_error_from_errno (errno),
3579  "Failed to set nonblocking flag of file descriptor %d: %s",
3580  fd, _dbus_strerror (errno));
3581  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3582  fd, _dbus_strerror (errno));
3583 
3584  return FALSE;
3585  }
3586 
3587  return TRUE;
3588 }
3589 
3595 void
3597 {
3598 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3599  void *bt[500];
3600  int bt_size;
3601  int i;
3602  char **syms;
3603 
3604  bt_size = backtrace (bt, 500);
3605 
3606  syms = backtrace_symbols (bt, bt_size);
3607 
3608  i = 0;
3609  while (i < bt_size)
3610  {
3611  /* don't use dbus_warn since it can _dbus_abort() */
3612  fprintf (stderr, " %s\n", syms[i]);
3613  ++i;
3614  }
3615  fflush (stderr);
3616 
3617  free (syms);
3618 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3619  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3620 #else
3621  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3622 #endif
3623 }
3624 
3639  DBusSocket *fd2,
3640  dbus_bool_t blocking,
3641  DBusError *error)
3642 {
3643 #ifdef HAVE_SOCKETPAIR
3644  int fds[2];
3645  int retval;
3646 
3647 #ifdef SOCK_CLOEXEC
3648  dbus_bool_t cloexec_done;
3649 
3650  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3651  cloexec_done = retval >= 0;
3652 
3653  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3654 #endif
3655  {
3656  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3657  }
3658 
3659  if (retval < 0)
3660  {
3661  dbus_set_error (error, _dbus_error_from_errno (errno),
3662  "Could not create full-duplex pipe");
3663  return FALSE;
3664  }
3665 
3666  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3667 
3668 #ifdef SOCK_CLOEXEC
3669  if (!cloexec_done)
3670 #endif
3671  {
3672  _dbus_fd_set_close_on_exec (fds[0]);
3673  _dbus_fd_set_close_on_exec (fds[1]);
3674  }
3675 
3676  if (!blocking &&
3677  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3678  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3679  {
3680  dbus_set_error (error, _dbus_error_from_errno (errno),
3681  "Could not set full-duplex pipe nonblocking");
3682 
3683  _dbus_close (fds[0], NULL);
3684  _dbus_close (fds[1], NULL);
3685 
3686  return FALSE;
3687  }
3688 
3689  fd1->fd = fds[0];
3690  fd2->fd = fds[1];
3691 
3692  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3693  fd1->fd, fd2->fd);
3694 
3695  return TRUE;
3696 #else
3697  _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3699  "_dbus_socketpair() not implemented on this OS");
3700  return FALSE;
3701 #endif
3702 }
3703 
3712 int
3714  va_list args)
3715 {
3716  char static_buf[1024];
3717  int bufsize = sizeof (static_buf);
3718  int len;
3719  va_list args_copy;
3720 
3721  DBUS_VA_COPY (args_copy, args);
3722  len = vsnprintf (static_buf, bufsize, format, args_copy);
3723  va_end (args_copy);
3724 
3725  /* If vsnprintf() returned non-negative, then either the string fits in
3726  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3727  * returns the number of characters that were needed, or this OS returns the
3728  * truncated length.
3729  *
3730  * We ignore the possibility that snprintf might just ignore the length and
3731  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3732  * If your libc is really that bad, come back when you have a better one. */
3733  if (len == bufsize)
3734  {
3735  /* This could be the truncated length (Tru64 and IRIX have this bug),
3736  * or the real length could be coincidentally the same. Which is it?
3737  * If vsnprintf returns the truncated length, we'll go to the slow
3738  * path. */
3739  DBUS_VA_COPY (args_copy, args);
3740 
3741  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3742  len = -1;
3743 
3744  va_end (args_copy);
3745  }
3746 
3747  /* If vsnprintf() returned negative, we have to do more work.
3748  * HP-UX returns negative. */
3749  while (len < 0)
3750  {
3751  char *buf;
3752 
3753  bufsize *= 2;
3754 
3755  buf = dbus_malloc (bufsize);
3756 
3757  if (buf == NULL)
3758  return -1;
3759 
3760  DBUS_VA_COPY (args_copy, args);
3761  len = vsnprintf (buf, bufsize, format, args_copy);
3762  va_end (args_copy);
3763 
3764  dbus_free (buf);
3765 
3766  /* If the reported length is exactly the buffer size, round up to the
3767  * next size, in case vsnprintf has been returning the truncated
3768  * length */
3769  if (len == bufsize)
3770  len = -1;
3771  }
3772 
3773  return len;
3774 }
3775 
3782 const char*
3784 {
3785  /* Protected by _DBUS_LOCK_sysdeps */
3786  static const char* tmpdir = NULL;
3787 
3788  if (!_DBUS_LOCK (sysdeps))
3789  return NULL;
3790 
3791  if (tmpdir == NULL)
3792  {
3793  /* TMPDIR is what glibc uses, then
3794  * glibc falls back to the P_tmpdir macro which
3795  * just expands to "/tmp"
3796  */
3797  if (tmpdir == NULL)
3798  tmpdir = getenv("TMPDIR");
3799 
3800  /* These two env variables are probably
3801  * broken, but maybe some OS uses them?
3802  */
3803  if (tmpdir == NULL)
3804  tmpdir = getenv("TMP");
3805  if (tmpdir == NULL)
3806  tmpdir = getenv("TEMP");
3807 
3808  /* And this is the sane fallback. */
3809  if (tmpdir == NULL)
3810  tmpdir = "/tmp";
3811  }
3812 
3813  _DBUS_UNLOCK (sysdeps);
3814 
3815  _dbus_assert(tmpdir != NULL);
3816 
3817  return tmpdir;
3818 }
3819 
3820 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3821 
3840 static dbus_bool_t
3841 _read_subprocess_line_argv (const char *progpath,
3842  dbus_bool_t path_fallback,
3843  const char * const *argv,
3844  DBusString *result,
3845  DBusError *error)
3846 {
3847  int result_pipe[2] = { -1, -1 };
3848  int errors_pipe[2] = { -1, -1 };
3849  pid_t pid;
3850  int ret;
3851  int status;
3852  int orig_len;
3853 
3854  dbus_bool_t retval;
3855  sigset_t new_set, old_set;
3856 
3857  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3858  retval = FALSE;
3859 
3860  /* We need to block any existing handlers for SIGCHLD temporarily; they
3861  * will cause waitpid() below to fail.
3862  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3863  */
3864  sigemptyset (&new_set);
3865  sigaddset (&new_set, SIGCHLD);
3866  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3867 
3868  orig_len = _dbus_string_get_length (result);
3869 
3870 #define READ_END 0
3871 #define WRITE_END 1
3872  if (pipe (result_pipe) < 0)
3873  {
3874  dbus_set_error (error, _dbus_error_from_errno (errno),
3875  "Failed to create a pipe to call %s: %s",
3876  progpath, _dbus_strerror (errno));
3877  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3878  progpath, _dbus_strerror (errno));
3879  goto out;
3880  }
3881  if (pipe (errors_pipe) < 0)
3882  {
3883  dbus_set_error (error, _dbus_error_from_errno (errno),
3884  "Failed to create a pipe to call %s: %s",
3885  progpath, _dbus_strerror (errno));
3886  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3887  progpath, _dbus_strerror (errno));
3888  goto out;
3889  }
3890 
3891  pid = fork ();
3892  if (pid < 0)
3893  {
3894  dbus_set_error (error, _dbus_error_from_errno (errno),
3895  "Failed to fork() to call %s: %s",
3896  progpath, _dbus_strerror (errno));
3897  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3898  progpath, _dbus_strerror (errno));
3899  goto out;
3900  }
3901 
3902  if (pid == 0)
3903  {
3904  /* child process */
3905  const char *error_str;
3906 
3907  if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
3908  {
3909  int saved_errno = errno;
3910 
3911  /* Try to write details into the pipe, but don't bother
3912  * trying too hard (no retry loop). */
3913 
3914  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
3915  write (errors_pipe[WRITE_END], ": ", 2) < 0)
3916  {
3917  /* ignore, not much we can do */
3918  }
3919 
3920  error_str = _dbus_strerror (saved_errno);
3921 
3922  if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
3923  {
3924  /* ignore, not much we can do */
3925  }
3926 
3927  _exit (1);
3928  }
3929 
3930  /* set-up stdXXX */
3931  close (result_pipe[READ_END]);
3932  close (errors_pipe[READ_END]);
3933 
3934  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3935  _exit (1);
3936  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3937  _exit (1);
3938 
3939  _dbus_close_all ();
3940 
3941  sigprocmask (SIG_SETMASK, &old_set, NULL);
3942 
3943  /* If it looks fully-qualified, try execv first */
3944  if (progpath[0] == '/')
3945  {
3946  execv (progpath, (char * const *) argv);
3947  /* Ok, that failed. Now if path_fallback is given, let's
3948  * try unqualified. This is mostly a hack to work
3949  * around systems which ship dbus-launch in /usr/bin
3950  * but everything else in /bin (because dbus-launch
3951  * depends on X11).
3952  */
3953  if (path_fallback)
3954  /* We must have a slash, because we checked above */
3955  execvp (strrchr (progpath, '/')+1, (char * const *) argv);
3956  }
3957  else
3958  execvp (progpath, (char * const *) argv);
3959 
3960  /* still nothing, we failed */
3961  _exit (1);
3962  }
3963 
3964  /* parent process */
3965  close (result_pipe[WRITE_END]);
3966  close (errors_pipe[WRITE_END]);
3967  result_pipe[WRITE_END] = -1;
3968  errors_pipe[WRITE_END] = -1;
3969 
3970  ret = 0;
3971  do
3972  {
3973  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3974  }
3975  while (ret > 0);
3976 
3977  /* reap the child process to avoid it lingering as zombie */
3978  do
3979  {
3980  ret = waitpid (pid, &status, 0);
3981  }
3982  while (ret == -1 && errno == EINTR);
3983 
3984  /* We succeeded if the process exited with status 0 and
3985  anything was read */
3986  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3987  {
3988  /* The process ended with error */
3989  DBusString error_message;
3990  if (!_dbus_string_init (&error_message))
3991  {
3992  _DBUS_SET_OOM (error);
3993  goto out;
3994  }
3995 
3996  ret = 0;
3997  do
3998  {
3999  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4000  }
4001  while (ret > 0);
4002 
4003  _dbus_string_set_length (result, orig_len);
4004  if (_dbus_string_get_length (&error_message) > 0)
4006  "%s terminated abnormally with the following error: %s",
4007  progpath, _dbus_string_get_data (&error_message));
4008  else
4010  "%s terminated abnormally without any error message",
4011  progpath);
4012  goto out;
4013  }
4014 
4015  retval = TRUE;
4016 
4017  out:
4018  sigprocmask (SIG_SETMASK, &old_set, NULL);
4019 
4020  if (retval)
4021  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4022  else
4023  _DBUS_ASSERT_ERROR_IS_SET (error);
4024 
4025  if (result_pipe[0] != -1)
4026  close (result_pipe[0]);
4027  if (result_pipe[1] != -1)
4028  close (result_pipe[1]);
4029  if (errors_pipe[0] != -1)
4030  close (errors_pipe[0]);
4031  if (errors_pipe[1] != -1)
4032  close (errors_pipe[1]);
4033 
4034  return retval;
4035 }
4036 #endif
4037 
4051 _dbus_get_autolaunch_address (const char *scope,
4052  DBusString *address,
4053  DBusError *error)
4054 {
4055 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4056  static const char arg_dbus_launch[] = "dbus-launch";
4057  static const char arg_autolaunch[] = "--autolaunch";
4058  static const char arg_binary_syntax[] = "--binary-syntax";
4059  static const char arg_close_stderr[] = "--close-stderr";
4060 
4061  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4062  * but that's done elsewhere, and if it worked, this function wouldn't
4063  * be called.) */
4064  const char *display;
4065  const char *progpath;
4066  const char *argv[6];
4067  int i;
4068  DBusString uuid;
4069  dbus_bool_t retval;
4070 
4071  if (_dbus_check_setuid ())
4072  {
4074  "Unable to autolaunch when setuid");
4075  return FALSE;
4076  }
4077 
4078  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4079  retval = FALSE;
4080 
4081  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4082  * dbus-launch-x11 is just going to fail. Rather than trying to
4083  * run it, we might as well bail out early with a nice error.
4084  *
4085  * This is not strictly true in a world where the user bus exists,
4086  * because dbus-launch --autolaunch knows how to connect to that -
4087  * but if we were going to connect to the user bus, we'd have done
4088  * so before trying autolaunch: in any case. */
4089  display = _dbus_getenv ("DISPLAY");
4090 
4091  if (display == NULL || display[0] == '\0')
4092  {
4094  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4095  return FALSE;
4096  }
4097 
4098  if (!_dbus_string_init (&uuid))
4099  {
4100  _DBUS_SET_OOM (error);
4101  return FALSE;
4102  }
4103 
4104  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4105  {
4106  goto out;
4107  }
4108 
4109 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4110  progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4111 
4112  if (progpath == NULL)
4113 #endif
4114  progpath = DBUS_BINDIR "/dbus-launch";
4115  /*
4116  * argv[0] is always dbus-launch, that's the name what we'll
4117  * get from /proc, or ps(1), regardless what the progpath is,
4118  * see fd.o#69716
4119  */
4120  i = 0;
4121  argv[i] = arg_dbus_launch;
4122  ++i;
4123  argv[i] = arg_autolaunch;
4124  ++i;
4125  argv[i] = _dbus_string_get_data (&uuid);
4126  ++i;
4127  argv[i] = arg_binary_syntax;
4128  ++i;
4129  argv[i] = arg_close_stderr;
4130  ++i;
4131  argv[i] = NULL;
4132  ++i;
4133 
4134  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4135 
4136  retval = _read_subprocess_line_argv (progpath,
4137  TRUE,
4138  argv, address, error);
4139 
4140  out:
4141  _dbus_string_free (&uuid);
4142  return retval;
4143 #else
4145  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4146  "set your DBUS_SESSION_BUS_ADDRESS instead");
4147  return FALSE;
4148 #endif
4149 }
4150 
4171  dbus_bool_t create_if_not_found,
4172  DBusError *error)
4173 {
4174  DBusError our_error = DBUS_ERROR_INIT;
4175  DBusError etc_error = DBUS_ERROR_INIT;
4176  DBusString filename;
4177  dbus_bool_t b;
4178 
4179  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4180 
4181  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4182  if (b)
4183  return TRUE;
4184 
4185  /* Fallback to the system machine ID */
4186  _dbus_string_init_const (&filename, "/etc/machine-id");
4187  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4188 
4189  if (b)
4190  {
4191  if (create_if_not_found)
4192  {
4193  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4194  * complain if that isn't possible for whatever reason */
4195  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4196  _dbus_write_uuid_file (&filename, machine_id, NULL);
4197  }
4198 
4199  dbus_error_free (&our_error);
4200  return TRUE;
4201  }
4202 
4203  if (!create_if_not_found)
4204  {
4205  dbus_set_error (error, etc_error.name,
4206  "D-Bus library appears to be incorrectly set up: "
4207  "see the manual page for dbus-uuidgen to correct "
4208  "this issue. (%s; %s)",
4209  our_error.message, etc_error.message);
4210  dbus_error_free (&our_error);
4211  dbus_error_free (&etc_error);
4212  return FALSE;
4213  }
4214 
4215  dbus_error_free (&our_error);
4216  dbus_error_free (&etc_error);
4217 
4218  /* if none found, try to make a new one */
4219  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4220 
4221  if (!_dbus_generate_uuid (machine_id, error))
4222  return FALSE;
4223 
4224  return _dbus_write_uuid_file (&filename, machine_id, error);
4225 }
4226 
4236  const char *launchd_env_var,
4237  DBusError *error)
4238 {
4239 #ifdef DBUS_ENABLE_LAUNCHD
4240  char *argv[4];
4241  int i;
4242 
4243  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4244 
4245  if (_dbus_check_setuid ())
4246  {
4248  "Unable to find launchd socket when setuid");
4249  return FALSE;
4250  }
4251 
4252  i = 0;
4253  argv[i] = "launchctl";
4254  ++i;
4255  argv[i] = "getenv";
4256  ++i;
4257  argv[i] = (char*)launchd_env_var;
4258  ++i;
4259  argv[i] = NULL;
4260  ++i;
4261 
4262  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4263 
4264  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4265  {
4266  return FALSE;
4267  }
4268 
4269  /* no error, but no result either */
4270  if (_dbus_string_get_length(socket_path) == 0)
4271  {
4272  return FALSE;
4273  }
4274 
4275  /* strip the carriage-return */
4276  _dbus_string_shorten(socket_path, 1);
4277  return TRUE;
4278 #else /* DBUS_ENABLE_LAUNCHD */
4280  "can't lookup socket from launchd; launchd support not compiled in");
4281  return FALSE;
4282 #endif
4283 }
4284 
4285 #ifdef DBUS_ENABLE_LAUNCHD
4286 static dbus_bool_t
4287 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4288 {
4289  dbus_bool_t valid_socket;
4290  DBusString socket_path;
4291 
4292  if (_dbus_check_setuid ())
4293  {
4295  "Unable to find launchd socket when setuid");
4296  return FALSE;
4297  }
4298 
4299  if (!_dbus_string_init (&socket_path))
4300  {
4301  _DBUS_SET_OOM (error);
4302  return FALSE;
4303  }
4304 
4305  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4306 
4307  if (dbus_error_is_set(error))
4308  {
4309  _dbus_string_free(&socket_path);
4310  return FALSE;
4311  }
4312 
4313  if (!valid_socket)
4314  {
4315  dbus_set_error(error, "no socket path",
4316  "launchd did not provide a socket path, "
4317  "verify that org.freedesktop.dbus-session.plist is loaded!");
4318  _dbus_string_free(&socket_path);
4319  return FALSE;
4320  }
4321  if (!_dbus_string_append (address, "unix:path="))
4322  {
4323  _DBUS_SET_OOM (error);
4324  _dbus_string_free(&socket_path);
4325  return FALSE;
4326  }
4327  if (!_dbus_string_copy (&socket_path, 0, address,
4328  _dbus_string_get_length (address)))
4329  {
4330  _DBUS_SET_OOM (error);
4331  _dbus_string_free(&socket_path);
4332  return FALSE;
4333  }
4334 
4335  _dbus_string_free(&socket_path);
4336  return TRUE;
4337 }
4338 #endif
4339 
4341 _dbus_lookup_user_bus (dbus_bool_t *supported,
4342  DBusString *address,
4343  DBusError *error)
4344 {
4345  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4346  dbus_bool_t ret = FALSE;
4347  struct stat stbuf;
4348  DBusString user_bus_path;
4349 
4350  if (runtime_dir == NULL)
4351  {
4352  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4353  *supported = FALSE;
4354  return TRUE; /* Cannot use it, but not an error */
4355  }
4356 
4357  if (!_dbus_string_init (&user_bus_path))
4358  {
4359  _DBUS_SET_OOM (error);
4360  return FALSE;
4361  }
4362 
4363  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4364  {
4365  _DBUS_SET_OOM (error);
4366  goto out;
4367  }
4368 
4369  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4370  {
4371  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4372  _dbus_strerror (errno));
4373  *supported = FALSE;
4374  ret = TRUE; /* Cannot use it, but not an error */
4375  goto out;
4376  }
4377 
4378  if (stbuf.st_uid != getuid ())
4379  {
4380  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4381  (long) stbuf.st_uid, (long) getuid ());
4382  *supported = FALSE;
4383  ret = TRUE; /* Cannot use it, but not an error */
4384  goto out;
4385  }
4386 
4387  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4388  {
4389  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4390  (long) stbuf.st_mode);
4391  *supported = FALSE;
4392  ret = TRUE; /* Cannot use it, but not an error */
4393  goto out;
4394  }
4395 
4396  if (!_dbus_string_append (address, "unix:path=") ||
4397  !_dbus_address_append_escaped (address, &user_bus_path))
4398  {
4399  _DBUS_SET_OOM (error);
4400  goto out;
4401  }
4402 
4403  *supported = TRUE;
4404  ret = TRUE;
4405 
4406 out:
4407  _dbus_string_free (&user_bus_path);
4408  return ret;
4409 }
4410 
4432  DBusString *address,
4433  DBusError *error)
4434 {
4435 #ifdef DBUS_ENABLE_LAUNCHD
4436  *supported = TRUE;
4437  return _dbus_lookup_session_address_launchd (address, error);
4438 #else
4439  *supported = FALSE;
4440 
4441  if (!_dbus_lookup_user_bus (supported, address, error))
4442  return FALSE;
4443  else if (*supported)
4444  return TRUE;
4445 
4446  /* On non-Mac Unix platforms, if the session address isn't already
4447  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4448  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4449  * autolaunch: global default; see init_session_address in
4450  * dbus/dbus-bus.c. */
4451  return TRUE;
4452 #endif
4453 }
4454 
4462 void
4464 {
4466 }
4467 
4483  DBusCredentials *credentials)
4484 {
4485  DBusString homedir;
4486  DBusString dotdir;
4487  dbus_uid_t uid;
4488 
4489  _dbus_assert (credentials != NULL);
4491 
4492  if (!_dbus_string_init (&homedir))
4493  return FALSE;
4494 
4495  uid = _dbus_credentials_get_unix_uid (credentials);
4496  _dbus_assert (uid != DBUS_UID_UNSET);
4497 
4498  if (!_dbus_homedir_from_uid (uid, &homedir))
4499  goto failed;
4500 
4501 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4502  {
4503  const char *override;
4504 
4505  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4506  if (override != NULL && *override != '\0')
4507  {
4508  _dbus_string_set_length (&homedir, 0);
4509  if (!_dbus_string_append (&homedir, override))
4510  goto failed;
4511 
4512  _dbus_verbose ("Using fake homedir for testing: %s\n",
4513  _dbus_string_get_const_data (&homedir));
4514  }
4515  else
4516  {
4517  /* Not strictly thread-safe, but if we fail at thread-safety here,
4518  * the worst that will happen is some extra warnings. */
4519  static dbus_bool_t already_warned = FALSE;
4520  if (!already_warned)
4521  {
4522  _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4523  _dbus_string_get_const_data (&homedir));
4524  already_warned = TRUE;
4525  }
4526  }
4527  }
4528 #endif
4529 
4530  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4531  if (!_dbus_concat_dir_and_file (&homedir,
4532  &dotdir))
4533  goto failed;
4534 
4535  if (!_dbus_string_copy (&homedir, 0,
4536  directory, _dbus_string_get_length (directory))) {
4537  goto failed;
4538  }
4539 
4540  _dbus_string_free (&homedir);
4541  return TRUE;
4542 
4543  failed:
4544  _dbus_string_free (&homedir);
4545  return FALSE;
4546 }
4547 
4548 //PENDING(kdab) docs
4550 _dbus_daemon_publish_session_bus_address (const char* addr,
4551  const char *scope)
4552 {
4553  return TRUE;
4554 }
4555 
4556 //PENDING(kdab) docs
4557 void
4558 _dbus_daemon_unpublish_session_bus_address (void)
4559 {
4560 
4561 }
4562 
4571 {
4572  /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4573  * EWOULDBLOCK are numerically equal, which is permitted as described by
4574  * errno(3).
4575  */
4576 #if EAGAIN == EWOULDBLOCK
4577  return e == EAGAIN;
4578 #else
4579  return e == EAGAIN || e == EWOULDBLOCK;
4580 #endif
4581 }
4582 
4592  DBusError *error)
4593 {
4594  const char *filename_c;
4595 
4596  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4597 
4598  filename_c = _dbus_string_get_const_data (filename);
4599 
4600  if (rmdir (filename_c) != 0)
4601  {
4603  "Failed to remove directory %s: %s\n",
4604  filename_c, _dbus_strerror (errno));
4605  return FALSE;
4606  }
4607 
4608  return TRUE;
4609 }
4610 
4620 {
4621 #ifdef SCM_RIGHTS
4622  union {
4623  struct sockaddr sa;
4624  struct sockaddr_storage storage;
4625  struct sockaddr_un un;
4626  } sa_buf;
4627 
4628  socklen_t sa_len = sizeof(sa_buf);
4629 
4630  _DBUS_ZERO(sa_buf);
4631 
4632  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4633  return FALSE;
4634 
4635  return sa_buf.sa.sa_family == AF_UNIX;
4636 
4637 #else
4638  return FALSE;
4639 
4640 #endif
4641 }
4642 
4647 void
4649 {
4650  int maxfds, i;
4651 
4652 #ifdef __linux__
4653  DIR *d;
4654 
4655  /* On Linux we can optimize this a bit if /proc is available. If it
4656  isn't available, fall back to the brute force way. */
4657 
4658  d = opendir ("/proc/self/fd");
4659  if (d)
4660  {
4661  for (;;)
4662  {
4663  struct dirent *de;
4664  int fd;
4665  long l;
4666  char *e = NULL;
4667 
4668  de = readdir (d);
4669  if (!de)
4670  break;
4671 
4672  if (de->d_name[0] == '.')
4673  continue;
4674 
4675  errno = 0;
4676  l = strtol (de->d_name, &e, 10);
4677  if (errno != 0 || e == NULL || *e != '\0')
4678  continue;
4679 
4680  fd = (int) l;
4681  if (fd < 3)
4682  continue;
4683 
4684  if (fd == dirfd (d))
4685  continue;
4686 
4687  close (fd);
4688  }
4689 
4690  closedir (d);
4691  return;
4692  }
4693 #endif
4694 
4695  maxfds = sysconf (_SC_OPEN_MAX);
4696 
4697  /* Pick something reasonable if for some reason sysconf says
4698  * unlimited.
4699  */
4700  if (maxfds < 0)
4701  maxfds = 1024;
4702 
4703  /* close all inherited fds */
4704  for (i = 3; i < maxfds; i++)
4705  close (i);
4706 }
4707 
4719 {
4720  /* TODO: get __libc_enable_secure exported from glibc.
4721  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4722  */
4723 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4724  {
4725  /* See glibc/include/unistd.h */
4726  extern int __libc_enable_secure;
4727  return __libc_enable_secure;
4728  }
4729 #elif defined(HAVE_ISSETUGID)
4730  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4731  return issetugid ();
4732 #else
4733  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4734  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4735 
4736  /* We call into this function from _dbus_threads_init_platform_specific()
4737  * to make sure these are initialized before we start threading. */
4738  static dbus_bool_t check_setuid_initialised;
4739  static dbus_bool_t is_setuid;
4740 
4741  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4742  {
4743 #ifdef HAVE_GETRESUID
4744  if (getresuid (&ruid, &euid, &suid) != 0 ||
4745  getresgid (&rgid, &egid, &sgid) != 0)
4746 #endif /* HAVE_GETRESUID */
4747  {
4748  suid = ruid = getuid ();
4749  sgid = rgid = getgid ();
4750  euid = geteuid ();
4751  egid = getegid ();
4752  }
4753 
4754  check_setuid_initialised = TRUE;
4755  is_setuid = (ruid != euid || ruid != suid ||
4756  rgid != egid || rgid != sgid);
4757 
4758  }
4759  return is_setuid;
4760 #endif
4761 }
4762 
4772  DBusString *address,
4773  DBusError *error)
4774 {
4775  union {
4776  struct sockaddr sa;
4777  struct sockaddr_storage storage;
4778  struct sockaddr_un un;
4779  struct sockaddr_in ipv4;
4780  struct sockaddr_in6 ipv6;
4781  } socket;
4782  char hostip[INET6_ADDRSTRLEN];
4783  socklen_t size = sizeof (socket);
4784  DBusString path_str;
4785 
4786  if (getsockname (fd.fd, &socket.sa, &size))
4787  goto err;
4788 
4789  switch (socket.sa.sa_family)
4790  {
4791  case AF_UNIX:
4792  if (socket.un.sun_path[0]=='\0')
4793  {
4794  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4795  if (_dbus_string_append (address, "unix:abstract=") &&
4796  _dbus_address_append_escaped (address, &path_str))
4797  return TRUE;
4798  }
4799  else
4800  {
4801  _dbus_string_init_const (&path_str, socket.un.sun_path);
4802  if (_dbus_string_append (address, "unix:path=") &&
4803  _dbus_address_append_escaped (address, &path_str))
4804  return TRUE;
4805  }
4806  break;
4807  case AF_INET:
4808  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4809  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4810  hostip, ntohs (socket.ipv4.sin_port)))
4811  return TRUE;
4812  break;
4813 #ifdef AF_INET6
4814  case AF_INET6:
4815  _dbus_string_init_const (&path_str, hostip);
4816  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4817  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4818  ntohs (socket.ipv6.sin6_port)) &&
4819  _dbus_address_append_escaped (address, &path_str))
4820  return TRUE;
4821  break;
4822 #endif
4823  default:
4824  dbus_set_error (error,
4825  _dbus_error_from_errno (EINVAL),
4826  "Failed to read address from socket: Unknown socket type.");
4827  return FALSE;
4828  }
4829  err:
4830  dbus_set_error (error,
4831  _dbus_error_from_errno (errno),
4832  "Failed to open socket: %s",
4833  _dbus_strerror (errno));
4834  return FALSE;
4835 }
4836 
4837 int
4838 _dbus_save_socket_errno (void)
4839 {
4840  return errno;
4841 }
4842 
4843 void
4844 _dbus_restore_socket_errno (int saved_errno)
4845 {
4846  errno = saved_errno;
4847 }
4848 
4849 static const char *syslog_tag = "dbus";
4850 #ifdef HAVE_SYSLOG_H
4851 static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
4852 #endif
4853 
4868 void
4869 _dbus_init_system_log (const char *tag,
4870  DBusLogFlags flags)
4871 {
4872  /* We never want to turn off logging completely */
4873  _dbus_assert (
4874  (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
4875 
4876  syslog_tag = tag;
4877 
4878 #ifdef HAVE_SYSLOG_H
4879  log_flags = flags;
4880 
4881  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4882  openlog (tag, LOG_PID, LOG_DAEMON);
4883 #endif
4884 }
4885 
4893 void
4894 _dbus_logv (DBusSystemLogSeverity severity,
4895  const char *msg,
4896  va_list args)
4897 {
4898  va_list tmp;
4899 #ifdef HAVE_SYSLOG_H
4900  if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
4901  {
4902  int flags;
4903  switch (severity)
4904  {
4905  case DBUS_SYSTEM_LOG_INFO:
4906  flags = LOG_DAEMON | LOG_INFO;
4907  break;
4908  case DBUS_SYSTEM_LOG_WARNING:
4909  flags = LOG_DAEMON | LOG_WARNING;
4910  break;
4911  case DBUS_SYSTEM_LOG_SECURITY:
4912  flags = LOG_AUTH | LOG_NOTICE;
4913  break;
4914  case DBUS_SYSTEM_LOG_ERROR:
4915  flags = LOG_DAEMON|LOG_CRIT;
4916  break;
4917  default:
4918  _dbus_assert_not_reached ("invalid log severity");
4919  }
4920 
4921  DBUS_VA_COPY (tmp, args);
4922  vsyslog (flags, msg, tmp);
4923  va_end (tmp);
4924  }
4925 
4926  /* If we don't have syslog.h, we always behave as though stderr was in
4927  * the flags */
4928  if (log_flags & DBUS_LOG_FLAGS_STDERR)
4929 #endif
4930  {
4931  DBUS_VA_COPY (tmp, args);
4932  fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
4933  vfprintf (stderr, msg, tmp);
4934  fputc ('\n', stderr);
4935  va_end (tmp);
4936  }
4937 }
4938 
4939 /* 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:1549
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:3044
_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:2786
_dbus_create_directory
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
Definition: dbus-sysdeps-unix.c:3256
DBusUserInfo::group_ids
dbus_gid_t * group_ids
Groups IDs, including above primary group.
Definition: dbus-sysdeps-unix.h:111
_DBUS_N_ELEMENTS
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
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:2803
DBusUserInfo::n_group_ids
int n_group_ids
Size of group IDs array.
Definition: dbus-sysdeps-unix.h:112
_dbus_getuid
dbus_uid_t _dbus_getuid(void)
Gets our UID.
Definition: dbus-sysdeps-unix.c:2939
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:159
_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:4771
_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:3287
_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:362
DBusAtomic::value
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:317
_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:407
_dbus_accept
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
Definition: dbus-sysdeps-unix.c:2418
_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:2819
_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:4235
_dbus_generate_uuid
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
Definition: dbus-internals.c:775
_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:1270
_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:4051
_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:3551
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:795
_dbus_disable_sigpipe
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
Definition: dbus-sysdeps-unix.c:3446
_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:154
_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:4463
_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:4894
_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:940
DBusPollFD::events
short events
Events to poll for.
Definition: dbus-sysdeps.h:406
_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:4431
_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:4482
_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:3171
DBusGUID
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
Definition: dbus-internals.h:395
_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:109
_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:3362
_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:1424
_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:1143
_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:3068
_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:1037
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition: dbus-internals.h:372
_dbus_dup
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
Definition: dbus-sysdeps-unix.c:3509
TRUE
#define TRUE
Expands to "1".
WRITE_END
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:894
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-protocol.h:368
DBUS_ERROR_SPAWN_EXEC_FAILED
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
Definition: dbus-protocol.h:429
_dbus_init_system_log
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
Definition: dbus-sysdeps-unix.c:4869
_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:324
dbus_malloc0
void * dbus_malloc0(size_t bytes)
Allocates the given number of bytes, as with standard malloc(), but all bytes are initialized to zero...
Definition: dbus-memory.c:532
DBusUserInfo::username
char * username
Username.
Definition: dbus-sysdeps-unix.h:113
_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:735
_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:316
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:4619
_DBUS_POLLERR
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:417
_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:2973
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:3332
_dbus_exit
void _dbus_exit(int code)
Exit the process, returning the given value.
Definition: dbus-sysdeps-unix.c:3417
DBUS_ERROR_BAD_ADDRESS
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
Definition: dbus-protocol.h:380
_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:43
_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:4718
_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:405
DBusUserInfo::homedir
char * homedir
Home directory.
Definition: dbus-sysdeps-unix.h:114
_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:163
DBusSocket
Socket interface.
Definition: dbus-sysdeps.h:181
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:954
_dbus_credentials_clear
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
Definition: dbus-credentials.c:563
_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:3713
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:156
FALSE
#define FALSE
Expands to "0".
DBusPollFD
Definition: dbus-sysdeps.h:404
DBUS_ERROR_NO_MEMORY
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
Definition: dbus-protocol.h:370
_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
Expands to a suitable initializer for a DBusError on the stack.
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:841
_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:2473
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_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:187
_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:2397
_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:3459
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:3093
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
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:306
DBusAtomic
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:313
dbus_new
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
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:290
READ_END
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:892
_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:3202
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
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:107
_dbus_close
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
Definition: dbus-sysdeps-unix.c:3481
_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:3638
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:263
_dbus_geteuid
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
Definition: dbus-sysdeps-unix.c:2948
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:644
_dbus_user_database_flush_system
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:401
_dbus_getpid
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
Definition: dbus-sysdeps-unix.c:2930
_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:437
DBusError
Object representing an exception.
Definition: dbus-errors.h:49
_dbus_print_backtrace
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
Definition: dbus-sysdeps-unix.c:3596
_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:246
_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:2919
_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:3224
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:152
_DBUS_POLLIN
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:411
DBusUserInfo::primary_gid
dbus_gid_t primary_gid
GID.
Definition: dbus-sysdeps-unix.h:110
_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:905
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:3021
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
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:4170
_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:222
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
_DBUS_ZERO
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
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:513
_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:1006
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:4591
_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:4570
DBUS_ERROR_NOT_SUPPORTED
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
Definition: dbus-protocol.h:382
_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:4648
_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:662
_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:2960
_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:3783
_DBUS_POLLOUT
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:415
DBUS_ERROR_IO_ERROR
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
Definition: dbus-protocol.h:378
_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:1983
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
_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:182