D-Bus  1.6.8
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-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
38 
39 #include <sys/types.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <signal.h>
43 #include <unistd.h>
44 #include <stdio.h>
45 #include <fcntl.h>
46 #include <sys/socket.h>
47 #include <dirent.h>
48 #include <sys/un.h>
49 #include <pwd.h>
50 #include <time.h>
51 #include <locale.h>
52 #include <sys/time.h>
53 #include <sys/stat.h>
54 #include <sys/wait.h>
55 #include <netinet/in.h>
56 #include <netdb.h>
57 #include <grp.h>
58 
59 #ifdef HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #ifdef HAVE_WRITEV
63 #include <sys/uio.h>
64 #endif
65 #ifdef HAVE_POLL
66 #include <sys/poll.h>
67 #endif
68 #ifdef HAVE_BACKTRACE
69 #include <execinfo.h>
70 #endif
71 #ifdef HAVE_GETPEERUCRED
72 #include <ucred.h>
73 #endif
74 
75 #ifdef HAVE_ADT
76 #include <bsm/adt.h>
77 #endif
78 
79 #include "sd-daemon.h"
80 
81 #ifndef O_BINARY
82 #define O_BINARY 0
83 #endif
84 
85 #ifndef AI_ADDRCONFIG
86 #define AI_ADDRCONFIG 0
87 #endif
88 
89 #ifndef HAVE_SOCKLEN_T
90 #define socklen_t int
91 #endif
92 
93 #if defined (__sun) || defined (__sun__)
94 /*
95  * CMS_SPACE etc. definitions for Solaris < 10, based on
96  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
97  * via
98  * http://wiki.opencsw.org/porting-faq#toc10
99  *
100  * These are only redefined for Solaris, for now: if your OS needs these too,
101  * please file a bug. (Or preferably, improve your OS so they're not needed.)
102  */
103 
104 # ifndef CMSG_ALIGN
105 # ifdef __sun__
106 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
107 # else
108  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
109 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
110  ~(sizeof (long) - 1))
111 # endif
112 # endif
113 
114 # ifndef CMSG_SPACE
115 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
116  CMSG_ALIGN (len))
117 # endif
118 
119 # ifndef CMSG_LEN
120 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
121 # endif
122 
123 #endif /* Solaris */
124 
125 static dbus_bool_t
126 _dbus_open_socket (int *fd_p,
127  int domain,
128  int type,
129  int protocol,
130  DBusError *error)
131 {
132 #ifdef SOCK_CLOEXEC
133  dbus_bool_t cloexec_done;
134 
135  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
136  cloexec_done = *fd_p >= 0;
137 
138  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
139  if (*fd_p < 0 && errno == EINVAL)
140 #endif
141  {
142  *fd_p = socket (domain, type, protocol);
143  }
144 
145  if (*fd_p >= 0)
146  {
147 #ifdef SOCK_CLOEXEC
148  if (!cloexec_done)
149 #endif
150  {
152  }
153 
154  _dbus_verbose ("socket fd %d opened\n", *fd_p);
155  return TRUE;
156  }
157  else
158  {
159  dbus_set_error(error,
160  _dbus_error_from_errno (errno),
161  "Failed to open socket: %s",
162  _dbus_strerror (errno));
163  return FALSE;
164  }
165 }
166 
177 static dbus_bool_t
178 _dbus_open_unix_socket (int *fd,
179  DBusError *error)
180 {
181  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
182 }
183 
194  DBusError *error)
195 {
196  return _dbus_close (fd, error);
197 }
198 
208 int
210  DBusString *buffer,
211  int count)
212 {
213  return _dbus_read (fd, buffer, count);
214 }
215 
226 int
228  const DBusString *buffer,
229  int start,
230  int len)
231 {
232 #if HAVE_DECL_MSG_NOSIGNAL
233  const char *data;
234  int bytes_written;
235 
236  data = _dbus_string_get_const_data_len (buffer, start, len);
237 
238  again:
239 
240  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
241 
242  if (bytes_written < 0 && errno == EINTR)
243  goto again;
244 
245  return bytes_written;
246 
247 #else
248  return _dbus_write (fd, buffer, start, len);
249 #endif
250 }
251 
264 int
266  DBusString *buffer,
267  int count,
268  int *fds,
269  int *n_fds) {
270 #ifndef HAVE_UNIX_FD_PASSING
271  int r;
272 
273  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
274  return r;
275 
276  *n_fds = 0;
277  return r;
278 
279 #else
280  int bytes_read;
281  int start;
282  struct msghdr m;
283  struct iovec iov;
284 
285  _dbus_assert (count >= 0);
286  _dbus_assert (*n_fds >= 0);
287 
288  start = _dbus_string_get_length (buffer);
289 
290  if (!_dbus_string_lengthen (buffer, count))
291  {
292  errno = ENOMEM;
293  return -1;
294  }
295 
296  _DBUS_ZERO(iov);
297  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
298  iov.iov_len = count;
299 
300  _DBUS_ZERO(m);
301  m.msg_iov = &iov;
302  m.msg_iovlen = 1;
303 
304  /* Hmm, we have no clue how long the control data will actually be
305  that is queued for us. The least we can do is assume that the
306  caller knows. Hence let's make space for the number of fds that
307  we shall read at max plus the cmsg header. */
308  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
309 
310  /* It's probably safe to assume that systems with SCM_RIGHTS also
311  know alloca() */
312  m.msg_control = alloca(m.msg_controllen);
313  memset(m.msg_control, 0, m.msg_controllen);
314 
315  /* Do not include the padding at the end when we tell the kernel
316  * how much we're willing to receive. This avoids getting
317  * the padding filled with additional fds that we weren't expecting,
318  * if a (potentially malicious) sender included them. (fd.o #83622) */
319  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
320 
321  again:
322 
323  bytes_read = recvmsg(fd, &m, 0
324 #ifdef MSG_CMSG_CLOEXEC
325  |MSG_CMSG_CLOEXEC
326 #endif
327  );
328 
329  if (bytes_read < 0)
330  {
331  if (errno == EINTR)
332  goto again;
333  else
334  {
335  /* put length back (note that this doesn't actually realloc anything) */
336  _dbus_string_set_length (buffer, start);
337  return -1;
338  }
339  }
340  else
341  {
342  struct cmsghdr *cm;
343  dbus_bool_t found = FALSE;
344 
345  if (m.msg_flags & MSG_CTRUNC)
346  {
347  /* Hmm, apparently the control data was truncated. The bad
348  thing is that we might have completely lost a couple of fds
349  without chance to recover them. Hence let's treat this as a
350  serious error. */
351 
352  errno = ENOSPC;
353  _dbus_string_set_length (buffer, start);
354  return -1;
355  }
356 
357  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
358  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
359  {
360  size_t i;
361  int *payload = (int *) CMSG_DATA (cm);
362  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
363  size_t payload_len_fds = payload_len_bytes / sizeof (int);
364  size_t fds_to_use;
365 
366  /* Every non-negative int fits in a size_t without truncation,
367  * and we already know that *n_fds is non-negative, so
368  * casting (size_t) *n_fds is OK */
369  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
370 
371  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
372  {
373  /* The fds in the payload will fit in our buffer */
374  fds_to_use = payload_len_fds;
375  }
376  else
377  {
378  /* Too many fds in the payload. This shouldn't happen
379  * any more because we're setting m.msg_controllen to
380  * the exact number we can accept, but be safe and
381  * truncate. */
382  fds_to_use = (size_t) *n_fds;
383 
384  /* Close the excess fds to avoid DoS: if they stayed open,
385  * someone could send us an extra fd per message
386  * and we'd eventually run out. */
387  for (i = fds_to_use; i < payload_len_fds; i++)
388  {
389  close (payload[i]);
390  }
391  }
392 
393  memcpy (fds, payload, fds_to_use * sizeof (int));
394  found = TRUE;
395  /* This cannot overflow because we have chosen fds_to_use
396  * to be <= *n_fds */
397  *n_fds = (int) fds_to_use;
398 
399  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
400  worked, hence we need to go through this list and set
401  CLOEXEC everywhere in any case */
402  for (i = 0; i < fds_to_use; i++)
404 
405  break;
406  }
407 
408  if (!found)
409  *n_fds = 0;
410 
411  /* put length back (doesn't actually realloc) */
412  _dbus_string_set_length (buffer, start + bytes_read);
413 
414 #if 0
415  if (bytes_read > 0)
416  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
417 #endif
418 
419  return bytes_read;
420  }
421 #endif
422 }
423 
424 int
425 _dbus_write_socket_with_unix_fds(int fd,
426  const DBusString *buffer,
427  int start,
428  int len,
429  const int *fds,
430  int n_fds) {
431 
432 #ifndef HAVE_UNIX_FD_PASSING
433 
434  if (n_fds > 0) {
435  errno = ENOTSUP;
436  return -1;
437  }
438 
439  return _dbus_write_socket(fd, buffer, start, len);
440 #else
441  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
442 #endif
443 }
444 
445 int
446 _dbus_write_socket_with_unix_fds_two(int fd,
447  const DBusString *buffer1,
448  int start1,
449  int len1,
450  const DBusString *buffer2,
451  int start2,
452  int len2,
453  const int *fds,
454  int n_fds) {
455 
456 #ifndef HAVE_UNIX_FD_PASSING
457 
458  if (n_fds > 0) {
459  errno = ENOTSUP;
460  return -1;
461  }
462 
463  return _dbus_write_socket_two(fd,
464  buffer1, start1, len1,
465  buffer2, start2, len2);
466 #else
467 
468  struct msghdr m;
469  struct cmsghdr *cm;
470  struct iovec iov[2];
471  int bytes_written;
472 
473  _dbus_assert (len1 >= 0);
474  _dbus_assert (len2 >= 0);
475  _dbus_assert (n_fds >= 0);
476 
477  _DBUS_ZERO(iov);
478  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
479  iov[0].iov_len = len1;
480 
481  if (buffer2)
482  {
483  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
484  iov[1].iov_len = len2;
485  }
486 
487  _DBUS_ZERO(m);
488  m.msg_iov = iov;
489  m.msg_iovlen = buffer2 ? 2 : 1;
490 
491  if (n_fds > 0)
492  {
493  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
494  m.msg_control = alloca(m.msg_controllen);
495  memset(m.msg_control, 0, m.msg_controllen);
496 
497  cm = CMSG_FIRSTHDR(&m);
498  cm->cmsg_level = SOL_SOCKET;
499  cm->cmsg_type = SCM_RIGHTS;
500  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
501  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
502  }
503 
504  again:
505 
506  bytes_written = sendmsg (fd, &m, 0
507 #if HAVE_DECL_MSG_NOSIGNAL
508  |MSG_NOSIGNAL
509 #endif
510  );
511 
512  if (bytes_written < 0 && errno == EINTR)
513  goto again;
514 
515 #if 0
516  if (bytes_written > 0)
517  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
518 #endif
519 
520  return bytes_written;
521 #endif
522 }
523 
537 int
539  const DBusString *buffer1,
540  int start1,
541  int len1,
542  const DBusString *buffer2,
543  int start2,
544  int len2)
545 {
546 #if HAVE_DECL_MSG_NOSIGNAL
547  struct iovec vectors[2];
548  const char *data1;
549  const char *data2;
550  int bytes_written;
551  struct msghdr m;
552 
553  _dbus_assert (buffer1 != NULL);
554  _dbus_assert (start1 >= 0);
555  _dbus_assert (start2 >= 0);
556  _dbus_assert (len1 >= 0);
557  _dbus_assert (len2 >= 0);
558 
559  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
560 
561  if (buffer2 != NULL)
562  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
563  else
564  {
565  data2 = NULL;
566  start2 = 0;
567  len2 = 0;
568  }
569 
570  vectors[0].iov_base = (char*) data1;
571  vectors[0].iov_len = len1;
572  vectors[1].iov_base = (char*) data2;
573  vectors[1].iov_len = len2;
574 
575  _DBUS_ZERO(m);
576  m.msg_iov = vectors;
577  m.msg_iovlen = data2 ? 2 : 1;
578 
579  again:
580 
581  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
582 
583  if (bytes_written < 0 && errno == EINTR)
584  goto again;
585 
586  return bytes_written;
587 
588 #else
589  return _dbus_write_two (fd, buffer1, start1, len1,
590  buffer2, start2, len2);
591 #endif
592 }
593 
595 _dbus_socket_is_invalid (int fd)
596 {
597  return fd < 0 ? TRUE : FALSE;
598 }
599 
616 int
617 _dbus_read (int fd,
618  DBusString *buffer,
619  int count)
620 {
621  int bytes_read;
622  int start;
623  char *data;
624 
625  _dbus_assert (count >= 0);
626 
627  start = _dbus_string_get_length (buffer);
628 
629  if (!_dbus_string_lengthen (buffer, count))
630  {
631  errno = ENOMEM;
632  return -1;
633  }
634 
635  data = _dbus_string_get_data_len (buffer, start, count);
636 
637  again:
638 
639  bytes_read = read (fd, data, count);
640 
641  if (bytes_read < 0)
642  {
643  if (errno == EINTR)
644  goto again;
645  else
646  {
647  /* put length back (note that this doesn't actually realloc anything) */
648  _dbus_string_set_length (buffer, start);
649  return -1;
650  }
651  }
652  else
653  {
654  /* put length back (doesn't actually realloc) */
655  _dbus_string_set_length (buffer, start + bytes_read);
656 
657 #if 0
658  if (bytes_read > 0)
659  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
660 #endif
661 
662  return bytes_read;
663  }
664 }
665 
676 int
677 _dbus_write (int fd,
678  const DBusString *buffer,
679  int start,
680  int len)
681 {
682  const char *data;
683  int bytes_written;
684 
685  data = _dbus_string_get_const_data_len (buffer, start, len);
686 
687  again:
688 
689  bytes_written = write (fd, data, len);
690 
691  if (bytes_written < 0 && errno == EINTR)
692  goto again;
693 
694 #if 0
695  if (bytes_written > 0)
696  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
697 #endif
698 
699  return bytes_written;
700 }
701 
722 int
724  const DBusString *buffer1,
725  int start1,
726  int len1,
727  const DBusString *buffer2,
728  int start2,
729  int len2)
730 {
731  _dbus_assert (buffer1 != NULL);
732  _dbus_assert (start1 >= 0);
733  _dbus_assert (start2 >= 0);
734  _dbus_assert (len1 >= 0);
735  _dbus_assert (len2 >= 0);
736 
737 #ifdef HAVE_WRITEV
738  {
739  struct iovec vectors[2];
740  const char *data1;
741  const char *data2;
742  int bytes_written;
743 
744  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
745 
746  if (buffer2 != NULL)
747  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
748  else
749  {
750  data2 = NULL;
751  start2 = 0;
752  len2 = 0;
753  }
754 
755  vectors[0].iov_base = (char*) data1;
756  vectors[0].iov_len = len1;
757  vectors[1].iov_base = (char*) data2;
758  vectors[1].iov_len = len2;
759 
760  again:
761 
762  bytes_written = writev (fd,
763  vectors,
764  data2 ? 2 : 1);
765 
766  if (bytes_written < 0 && errno == EINTR)
767  goto again;
768 
769  return bytes_written;
770  }
771 #else /* HAVE_WRITEV */
772  {
773  int ret1;
774 
775  ret1 = _dbus_write (fd, buffer1, start1, len1);
776  if (ret1 == len1 && buffer2 != NULL)
777  {
778  ret2 = _dbus_write (fd, buffer2, start2, len2);
779  if (ret2 < 0)
780  ret2 = 0; /* we can't report an error as the first write was OK */
781 
782  return ret1 + ret2;
783  }
784  else
785  return ret1;
786  }
787 #endif /* !HAVE_WRITEV */
788 }
789 
790 #define _DBUS_MAX_SUN_PATH_LENGTH 99
791 
821 int
822 _dbus_connect_unix_socket (const char *path,
823  dbus_bool_t abstract,
824  DBusError *error)
825 {
826  int fd;
827  size_t path_len;
828  struct sockaddr_un addr;
829 
830  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
831 
832  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
833  path, abstract);
834 
835 
836  if (!_dbus_open_unix_socket (&fd, error))
837  {
838  _DBUS_ASSERT_ERROR_IS_SET(error);
839  return -1;
840  }
841  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
842 
843  _DBUS_ZERO (addr);
844  addr.sun_family = AF_UNIX;
845  path_len = strlen (path);
846 
847  if (abstract)
848  {
849 #ifdef HAVE_ABSTRACT_SOCKETS
850  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
851  path_len++; /* Account for the extra nul byte added to the start of sun_path */
852 
853  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
854  {
856  "Abstract socket name too long\n");
857  _dbus_close (fd, NULL);
858  return -1;
859  }
860 
861  strncpy (&addr.sun_path[1], path, path_len);
862  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
863 #else /* HAVE_ABSTRACT_SOCKETS */
865  "Operating system does not support abstract socket namespace\n");
866  _dbus_close (fd, NULL);
867  return -1;
868 #endif /* ! HAVE_ABSTRACT_SOCKETS */
869  }
870  else
871  {
872  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
873  {
875  "Socket name too long\n");
876  _dbus_close (fd, NULL);
877  return -1;
878  }
879 
880  strncpy (addr.sun_path, path, path_len);
881  }
882 
883  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
884  {
885  dbus_set_error (error,
886  _dbus_error_from_errno (errno),
887  "Failed to connect to socket %s: %s",
888  path, _dbus_strerror (errno));
889 
890  _dbus_close (fd, NULL);
891  return -1;
892  }
893 
894  if (!_dbus_set_fd_nonblocking (fd, error))
895  {
896  _DBUS_ASSERT_ERROR_IS_SET (error);
897 
898  _dbus_close (fd, NULL);
899  return -1;
900  }
901 
902  return fd;
903 }
904 
917 int
918 _dbus_connect_exec (const char *path,
919  char *const argv[],
920  DBusError *error)
921 {
922  int fds[2];
923  pid_t pid;
924 
925  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
926 
927  _dbus_verbose ("connecting to process %s\n", path);
928 
929  if (socketpair (AF_UNIX, SOCK_STREAM
930 #ifdef SOCK_CLOEXEC
931  |SOCK_CLOEXEC
932 #endif
933  , 0, fds) < 0)
934  {
935  dbus_set_error (error,
936  _dbus_error_from_errno (errno),
937  "Failed to create socket pair: %s",
938  _dbus_strerror (errno));
939  return -1;
940  }
941 
944 
945  pid = fork ();
946  if (pid < 0)
947  {
948  dbus_set_error (error,
949  _dbus_error_from_errno (errno),
950  "Failed to fork() to call %s: %s",
951  path, _dbus_strerror (errno));
952  close (fds[0]);
953  close (fds[1]);
954  return -1;
955  }
956 
957  if (pid == 0)
958  {
959  /* child */
960  close (fds[0]);
961 
962  dup2 (fds[1], STDIN_FILENO);
963  dup2 (fds[1], STDOUT_FILENO);
964 
965  if (fds[1] != STDIN_FILENO &&
966  fds[1] != STDOUT_FILENO)
967  close (fds[1]);
968 
969  /* Inherit STDERR and the controlling terminal from the
970  parent */
971 
972  _dbus_close_all ();
973 
974  execvp (path, argv);
975 
976  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
977 
978  _exit(1);
979  }
980 
981  /* parent */
982  close (fds[1]);
983 
984  if (!_dbus_set_fd_nonblocking (fds[0], error))
985  {
986  _DBUS_ASSERT_ERROR_IS_SET (error);
987 
988  close (fds[0]);
989  return -1;
990  }
991 
992  return fds[0];
993 }
994 
1004 static dbus_bool_t
1005 _dbus_set_local_creds (int fd, dbus_bool_t on)
1006 {
1007  dbus_bool_t retval = TRUE;
1008 
1009 #if defined(HAVE_CMSGCRED)
1010  /* NOOP just to make sure only one codepath is used
1011  * and to prefer CMSGCRED
1012  */
1013 #elif defined(LOCAL_CREDS)
1014  int val = on ? 1 : 0;
1015  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
1016  {
1017  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
1018  retval = FALSE;
1019  }
1020  else
1021  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
1022  on ? "enabled" : "disabled", fd);
1023 #endif
1024 
1025  return retval;
1026 }
1027 
1045 int
1046 _dbus_listen_unix_socket (const char *path,
1047  dbus_bool_t abstract,
1048  DBusError *error)
1049 {
1050  int listen_fd;
1051  struct sockaddr_un addr;
1052  size_t path_len;
1053  unsigned int reuseaddr;
1054 
1055  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1056 
1057  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1058  path, abstract);
1059 
1060  if (!_dbus_open_unix_socket (&listen_fd, error))
1061  {
1062  _DBUS_ASSERT_ERROR_IS_SET(error);
1063  return -1;
1064  }
1065  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1066 
1067  _DBUS_ZERO (addr);
1068  addr.sun_family = AF_UNIX;
1069  path_len = strlen (path);
1070 
1071  if (abstract)
1072  {
1073 #ifdef HAVE_ABSTRACT_SOCKETS
1074  /* remember that abstract names aren't nul-terminated so we rely
1075  * on sun_path being filled in with zeroes above.
1076  */
1077  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1078  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1079 
1080  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1081  {
1083  "Abstract socket name too long\n");
1084  _dbus_close (listen_fd, NULL);
1085  return -1;
1086  }
1087 
1088  strncpy (&addr.sun_path[1], path, path_len);
1089  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1090 #else /* HAVE_ABSTRACT_SOCKETS */
1092  "Operating system does not support abstract socket namespace\n");
1093  _dbus_close (listen_fd, NULL);
1094  return -1;
1095 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1096  }
1097  else
1098  {
1099  /* Discussed security implications of this with Nalin,
1100  * and we couldn't think of where it would kick our ass, but
1101  * it still seems a bit sucky. It also has non-security suckage;
1102  * really we'd prefer to exit if the socket is already in use.
1103  * But there doesn't seem to be a good way to do this.
1104  *
1105  * Just to be extra careful, I threw in the stat() - clearly
1106  * the stat() can't *fix* any security issue, but it at least
1107  * avoids inadvertent/accidental data loss.
1108  */
1109  {
1110  struct stat sb;
1111 
1112  if (stat (path, &sb) == 0 &&
1113  S_ISSOCK (sb.st_mode))
1114  unlink (path);
1115  }
1116 
1117  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1118  {
1120  "Abstract socket name too long\n");
1121  _dbus_close (listen_fd, NULL);
1122  return -1;
1123  }
1124 
1125  strncpy (addr.sun_path, path, path_len);
1126  }
1127 
1128  reuseaddr = 1;
1129  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1130  {
1131  _dbus_warn ("Failed to set socket option\"%s\": %s",
1132  path, _dbus_strerror (errno));
1133  }
1134 
1135  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1136  {
1137  dbus_set_error (error, _dbus_error_from_errno (errno),
1138  "Failed to bind socket \"%s\": %s",
1139  path, _dbus_strerror (errno));
1140  _dbus_close (listen_fd, NULL);
1141  return -1;
1142  }
1143 
1144  if (listen (listen_fd, 30 /* backlog */) < 0)
1145  {
1146  dbus_set_error (error, _dbus_error_from_errno (errno),
1147  "Failed to listen on socket \"%s\": %s",
1148  path, _dbus_strerror (errno));
1149  _dbus_close (listen_fd, NULL);
1150  return -1;
1151  }
1152 
1153  if (!_dbus_set_local_creds (listen_fd, TRUE))
1154  {
1155  dbus_set_error (error, _dbus_error_from_errno (errno),
1156  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1157  path, _dbus_strerror (errno));
1158  close (listen_fd);
1159  return -1;
1160  }
1161 
1162  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1163  {
1164  _DBUS_ASSERT_ERROR_IS_SET (error);
1165  _dbus_close (listen_fd, NULL);
1166  return -1;
1167  }
1168 
1169  /* Try opening up the permissions, but if we can't, just go ahead
1170  * and continue, maybe it will be good enough.
1171  */
1172  if (!abstract && chmod (path, 0777) < 0)
1173  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1174  path);
1175 
1176  return listen_fd;
1177 }
1178 
1189 int
1191  DBusError *error)
1192 {
1193  int r, n;
1194  unsigned fd;
1195  int *new_fds;
1196 
1197  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1198 
1199  n = sd_listen_fds (TRUE);
1200  if (n < 0)
1201  {
1203  "Failed to acquire systemd socket: %s",
1204  _dbus_strerror (-n));
1205  return -1;
1206  }
1207 
1208  if (n <= 0)
1209  {
1211  "No socket received.");
1212  return -1;
1213  }
1214 
1215  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1216  {
1217  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1218  if (r < 0)
1219  {
1221  "Failed to verify systemd socket type: %s",
1222  _dbus_strerror (-r));
1223  return -1;
1224  }
1225 
1226  if (!r)
1227  {
1229  "Passed socket has wrong type.");
1230  return -1;
1231  }
1232  }
1233 
1234  /* OK, the file descriptors are all good, so let's take posession of
1235  them then. */
1236 
1237  new_fds = dbus_new (int, n);
1238  if (!new_fds)
1239  {
1241  "Failed to allocate file handle array.");
1242  goto fail;
1243  }
1244 
1245  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1246  {
1247  if (!_dbus_set_local_creds (fd, TRUE))
1248  {
1249  dbus_set_error (error, _dbus_error_from_errno (errno),
1250  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1251  _dbus_strerror (errno));
1252  goto fail;
1253  }
1254 
1255  if (!_dbus_set_fd_nonblocking (fd, error))
1256  {
1257  _DBUS_ASSERT_ERROR_IS_SET (error);
1258  goto fail;
1259  }
1260 
1261  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1262  }
1263 
1264  *fds = new_fds;
1265  return n;
1266 
1267  fail:
1268 
1269  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1270  {
1271  _dbus_close (fd, NULL);
1272  }
1273 
1274  dbus_free (new_fds);
1275  return -1;
1276 }
1277 
1291 int
1292 _dbus_connect_tcp_socket (const char *host,
1293  const char *port,
1294  const char *family,
1295  DBusError *error)
1296 {
1297  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1298 }
1299 
1300 int
1301 _dbus_connect_tcp_socket_with_nonce (const char *host,
1302  const char *port,
1303  const char *family,
1304  const char *noncefile,
1305  DBusError *error)
1306 {
1307  int saved_errno = 0;
1308  int fd = -1, res;
1309  struct addrinfo hints;
1310  struct addrinfo *ai, *tmp;
1311 
1312  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1313 
1314  _DBUS_ZERO (hints);
1315 
1316  if (!family)
1317  hints.ai_family = AF_UNSPEC;
1318  else if (!strcmp(family, "ipv4"))
1319  hints.ai_family = AF_INET;
1320  else if (!strcmp(family, "ipv6"))
1321  hints.ai_family = AF_INET6;
1322  else
1323  {
1324  dbus_set_error (error,
1326  "Unknown address family %s", family);
1327  return -1;
1328  }
1329  hints.ai_protocol = IPPROTO_TCP;
1330  hints.ai_socktype = SOCK_STREAM;
1331  hints.ai_flags = AI_ADDRCONFIG;
1332 
1333  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1334  {
1335  dbus_set_error (error,
1336  _dbus_error_from_errno (errno),
1337  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1338  host, port, gai_strerror(res), res);
1339  return -1;
1340  }
1341 
1342  tmp = ai;
1343  while (tmp)
1344  {
1345  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1346  {
1347  freeaddrinfo(ai);
1348  _DBUS_ASSERT_ERROR_IS_SET(error);
1349  return -1;
1350  }
1351  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1352 
1353  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1354  {
1355  saved_errno = errno;
1356  _dbus_close(fd, NULL);
1357  fd = -1;
1358  tmp = tmp->ai_next;
1359  continue;
1360  }
1361 
1362  break;
1363  }
1364  freeaddrinfo(ai);
1365 
1366  if (fd == -1)
1367  {
1368  dbus_set_error (error,
1369  _dbus_error_from_errno (saved_errno),
1370  "Failed to connect to socket \"%s:%s\" %s",
1371  host, port, _dbus_strerror(saved_errno));
1372  return -1;
1373  }
1374 
1375  if (noncefile != NULL)
1376  {
1377  DBusString noncefileStr;
1378  dbus_bool_t ret;
1379  _dbus_string_init_const (&noncefileStr, noncefile);
1380  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1381  _dbus_string_free (&noncefileStr);
1382 
1383  if (!ret)
1384  {
1385  _dbus_close (fd, NULL);
1386  return -1;
1387  }
1388  }
1389 
1390  if (!_dbus_set_fd_nonblocking (fd, error))
1391  {
1392  _dbus_close (fd, NULL);
1393  return -1;
1394  }
1395 
1396  return fd;
1397 }
1398 
1415 int
1416 _dbus_listen_tcp_socket (const char *host,
1417  const char *port,
1418  const char *family,
1419  DBusString *retport,
1420  int **fds_p,
1421  DBusError *error)
1422 {
1423  int saved_errno;
1424  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1425  struct addrinfo hints;
1426  struct addrinfo *ai, *tmp;
1427  unsigned int reuseaddr;
1428 
1429  *fds_p = NULL;
1430  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1431 
1432  _DBUS_ZERO (hints);
1433 
1434  if (!family)
1435  hints.ai_family = AF_UNSPEC;
1436  else if (!strcmp(family, "ipv4"))
1437  hints.ai_family = AF_INET;
1438  else if (!strcmp(family, "ipv6"))
1439  hints.ai_family = AF_INET6;
1440  else
1441  {
1442  dbus_set_error (error,
1444  "Unknown address family %s", family);
1445  return -1;
1446  }
1447 
1448  hints.ai_protocol = IPPROTO_TCP;
1449  hints.ai_socktype = SOCK_STREAM;
1450  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1451 
1452  redo_lookup_with_port:
1453  ai = NULL;
1454  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1455  {
1456  dbus_set_error (error,
1457  _dbus_error_from_errno (errno),
1458  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1459  host ? host : "*", port, gai_strerror(res), res);
1460  goto failed;
1461  }
1462 
1463  tmp = ai;
1464  while (tmp)
1465  {
1466  int fd = -1, *newlisten_fd;
1467  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1468  {
1469  _DBUS_ASSERT_ERROR_IS_SET(error);
1470  goto failed;
1471  }
1472  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1473 
1474  reuseaddr = 1;
1475  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1476  {
1477  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1478  host ? host : "*", port, _dbus_strerror (errno));
1479  }
1480 
1481  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1482  {
1483  saved_errno = errno;
1484  _dbus_close(fd, NULL);
1485  if (saved_errno == EADDRINUSE)
1486  {
1487  /* Depending on kernel policy, it may or may not
1488  be neccessary to bind to both IPv4 & 6 addresses
1489  so ignore EADDRINUSE here */
1490  tmp = tmp->ai_next;
1491  continue;
1492  }
1493  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1494  "Failed to bind socket \"%s:%s\": %s",
1495  host ? host : "*", port, _dbus_strerror (saved_errno));
1496  goto failed;
1497  }
1498 
1499  if (listen (fd, 30 /* backlog */) < 0)
1500  {
1501  saved_errno = errno;
1502  _dbus_close (fd, NULL);
1503  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1504  "Failed to listen on socket \"%s:%s\": %s",
1505  host ? host : "*", port, _dbus_strerror (saved_errno));
1506  goto failed;
1507  }
1508 
1509  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1510  if (!newlisten_fd)
1511  {
1512  saved_errno = errno;
1513  _dbus_close (fd, NULL);
1514  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1515  "Failed to allocate file handle array: %s",
1516  _dbus_strerror (saved_errno));
1517  goto failed;
1518  }
1519  listen_fd = newlisten_fd;
1520  listen_fd[nlisten_fd] = fd;
1521  nlisten_fd++;
1522 
1523  if (!_dbus_string_get_length(retport))
1524  {
1525  /* If the user didn't specify a port, or used 0, then
1526  the kernel chooses a port. After the first address
1527  is bound to, we need to force all remaining addresses
1528  to use the same port */
1529  if (!port || !strcmp(port, "0"))
1530  {
1531  int result;
1532  struct sockaddr_storage addr;
1533  socklen_t addrlen;
1534  char portbuf[50];
1535 
1536  addrlen = sizeof(addr);
1537  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1538 
1539  if (result == -1 ||
1540  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1541  portbuf, sizeof(portbuf),
1542  NI_NUMERICHOST)) != 0)
1543  {
1544  dbus_set_error (error, _dbus_error_from_errno (errno),
1545  "Failed to resolve port \"%s:%s\": %s (%s)",
1546  host ? host : "*", port, gai_strerror(res), res);
1547  goto failed;
1548  }
1549  if (!_dbus_string_append(retport, portbuf))
1550  {
1552  goto failed;
1553  }
1554 
1555  /* Release current address list & redo lookup */
1556  port = _dbus_string_get_const_data(retport);
1557  freeaddrinfo(ai);
1558  goto redo_lookup_with_port;
1559  }
1560  else
1561  {
1562  if (!_dbus_string_append(retport, port))
1563  {
1565  goto failed;
1566  }
1567  }
1568  }
1569 
1570  tmp = tmp->ai_next;
1571  }
1572  freeaddrinfo(ai);
1573  ai = NULL;
1574 
1575  if (!nlisten_fd)
1576  {
1577  errno = EADDRINUSE;
1578  dbus_set_error (error, _dbus_error_from_errno (errno),
1579  "Failed to bind socket \"%s:%s\": %s",
1580  host ? host : "*", port, _dbus_strerror (errno));
1581  goto failed;
1582  }
1583 
1584  for (i = 0 ; i < nlisten_fd ; i++)
1585  {
1586  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1587  {
1588  goto failed;
1589  }
1590  }
1591 
1592  *fds_p = listen_fd;
1593 
1594  return nlisten_fd;
1595 
1596  failed:
1597  if (ai)
1598  freeaddrinfo(ai);
1599  for (i = 0 ; i < nlisten_fd ; i++)
1600  _dbus_close(listen_fd[i], NULL);
1601  dbus_free(listen_fd);
1602  return -1;
1603 }
1604 
1605 static dbus_bool_t
1606 write_credentials_byte (int server_fd,
1607  DBusError *error)
1608 {
1609  int bytes_written;
1610  char buf[1] = { '\0' };
1611 #if defined(HAVE_CMSGCRED)
1612  union {
1613  struct cmsghdr hdr;
1614  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1615  } cmsg;
1616  struct iovec iov;
1617  struct msghdr msg;
1618  iov.iov_base = buf;
1619  iov.iov_len = 1;
1620 
1621  _DBUS_ZERO(msg);
1622  msg.msg_iov = &iov;
1623  msg.msg_iovlen = 1;
1624 
1625  msg.msg_control = (caddr_t) &cmsg;
1626  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1627  _DBUS_ZERO(cmsg);
1628  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1629  cmsg.hdr.cmsg_level = SOL_SOCKET;
1630  cmsg.hdr.cmsg_type = SCM_CREDS;
1631 #endif
1632 
1633  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1634 
1635  again:
1636 
1637 #if defined(HAVE_CMSGCRED)
1638  bytes_written = sendmsg (server_fd, &msg, 0
1639 #if HAVE_DECL_MSG_NOSIGNAL
1640  |MSG_NOSIGNAL
1641 #endif
1642  );
1643 #else
1644  bytes_written = send (server_fd, buf, 1, 0
1645 #if HAVE_DECL_MSG_NOSIGNAL
1646  |MSG_NOSIGNAL
1647 #endif
1648  );
1649 #endif
1650 
1651  if (bytes_written < 0 && errno == EINTR)
1652  goto again;
1653 
1654  if (bytes_written < 0)
1655  {
1656  dbus_set_error (error, _dbus_error_from_errno (errno),
1657  "Failed to write credentials byte: %s",
1658  _dbus_strerror (errno));
1659  return FALSE;
1660  }
1661  else if (bytes_written == 0)
1662  {
1664  "wrote zero bytes writing credentials byte");
1665  return FALSE;
1666  }
1667  else
1668  {
1669  _dbus_assert (bytes_written == 1);
1670  _dbus_verbose ("wrote credentials byte\n");
1671  return TRUE;
1672  }
1673 }
1674 
1698  DBusCredentials *credentials,
1699  DBusError *error)
1700 {
1701  struct msghdr msg;
1702  struct iovec iov;
1703  char buf;
1704  dbus_uid_t uid_read;
1705  dbus_pid_t pid_read;
1706  int bytes_read;
1707 
1708 #ifdef HAVE_CMSGCRED
1709  union {
1710  struct cmsghdr hdr;
1711  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1712  } cmsg;
1713 
1714 #elif defined(LOCAL_CREDS)
1715  struct {
1716  struct cmsghdr hdr;
1717  struct sockcred cred;
1718  } cmsg;
1719 #endif
1720 
1721  uid_read = DBUS_UID_UNSET;
1722  pid_read = DBUS_PID_UNSET;
1723 
1724  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1725 
1726  /* The POSIX spec certainly doesn't promise this, but
1727  * we need these assertions to fail as soon as we're wrong about
1728  * it so we can do the porting fixups
1729  */
1730  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1731  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1732  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1733 
1734  _dbus_credentials_clear (credentials);
1735 
1736  /* Systems supporting LOCAL_CREDS are configured to have this feature
1737  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1738  * the connection. Therefore, the received message must carry the
1739  * credentials information without doing anything special.
1740  */
1741 
1742  iov.iov_base = &buf;
1743  iov.iov_len = 1;
1744 
1745  _DBUS_ZERO(msg);
1746  msg.msg_iov = &iov;
1747  msg.msg_iovlen = 1;
1748 
1749 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1750  _DBUS_ZERO(cmsg);
1751  msg.msg_control = (caddr_t) &cmsg;
1752  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1753 #endif
1754 
1755  again:
1756  bytes_read = recvmsg (client_fd, &msg, 0);
1757 
1758  if (bytes_read < 0)
1759  {
1760  if (errno == EINTR)
1761  goto again;
1762 
1763  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1764  * normally only call read_credentials if the socket was ready
1765  * for reading
1766  */
1767 
1768  dbus_set_error (error, _dbus_error_from_errno (errno),
1769  "Failed to read credentials byte: %s",
1770  _dbus_strerror (errno));
1771  return FALSE;
1772  }
1773  else if (bytes_read == 0)
1774  {
1775  /* this should not happen unless we are using recvmsg wrong,
1776  * so is essentially here for paranoia
1777  */
1779  "Failed to read credentials byte (zero-length read)");
1780  return FALSE;
1781  }
1782  else if (buf != '\0')
1783  {
1785  "Credentials byte was not nul");
1786  return FALSE;
1787  }
1788 
1789 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1790  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1791  || cmsg.hdr.cmsg_type != SCM_CREDS)
1792  {
1794  "Message from recvmsg() was not SCM_CREDS");
1795  return FALSE;
1796  }
1797 #endif
1798 
1799  _dbus_verbose ("read credentials byte\n");
1800 
1801  {
1802 #ifdef SO_PEERCRED
1803 #ifdef __OpenBSD__
1804  struct sockpeercred cr;
1805 #else
1806  struct ucred cr;
1807 #endif
1808  int cr_len = sizeof (cr);
1809 
1810  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1811  cr_len == sizeof (cr))
1812  {
1813  pid_read = cr.pid;
1814  uid_read = cr.uid;
1815  }
1816  else
1817  {
1818  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1819  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1820  }
1821 #elif defined(HAVE_CMSGCRED)
1822  struct cmsgcred *cred;
1823 
1824  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1825  pid_read = cred->cmcred_pid;
1826  uid_read = cred->cmcred_euid;
1827 #elif defined(LOCAL_CREDS)
1828  pid_read = DBUS_PID_UNSET;
1829  uid_read = cmsg.cred.sc_uid;
1830  /* Since we have already got the credentials from this socket, we can
1831  * disable its LOCAL_CREDS flag if it was ever set. */
1832  _dbus_set_local_creds (client_fd, FALSE);
1833 #elif defined(HAVE_GETPEEREID)
1834  uid_t euid;
1835  gid_t egid;
1836  if (getpeereid (client_fd, &euid, &egid) == 0)
1837  {
1838  uid_read = euid;
1839  }
1840  else
1841  {
1842  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1843  }
1844 #elif defined(HAVE_GETPEERUCRED)
1845  ucred_t * ucred = NULL;
1846  if (getpeerucred (client_fd, &ucred) == 0)
1847  {
1848  pid_read = ucred_getpid (ucred);
1849  uid_read = ucred_geteuid (ucred);
1850 #ifdef HAVE_ADT
1851  /* generate audit session data based on socket ucred */
1852  adt_session_data_t *adth = NULL;
1853  adt_export_data_t *data = NULL;
1854  size_t size = 0;
1855  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1856  {
1857  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1858  }
1859  else
1860  {
1861  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1862  {
1863  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1864  }
1865  else
1866  {
1867  size = adt_export_session_data (adth, &data);
1868  if (size <= 0)
1869  {
1870  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1871  }
1872  else
1873  {
1874  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1875  free (data);
1876  }
1877  }
1878  (void) adt_end_session (adth);
1879  }
1880 #endif /* HAVE_ADT */
1881  }
1882  else
1883  {
1884  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1885  }
1886  if (ucred != NULL)
1887  ucred_free (ucred);
1888 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1889  _dbus_verbose ("Socket credentials not supported on this OS\n");
1890 #endif
1891  }
1892 
1893  _dbus_verbose ("Credentials:"
1894  " pid "DBUS_PID_FORMAT
1895  " uid "DBUS_UID_FORMAT
1896  "\n",
1897  pid_read,
1898  uid_read);
1899 
1900  if (pid_read != DBUS_PID_UNSET)
1901  {
1902  if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1903  {
1904  _DBUS_SET_OOM (error);
1905  return FALSE;
1906  }
1907  }
1908 
1909  if (uid_read != DBUS_UID_UNSET)
1910  {
1911  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1912  {
1913  _DBUS_SET_OOM (error);
1914  return FALSE;
1915  }
1916  }
1917 
1918  return TRUE;
1919 }
1920 
1940  DBusError *error)
1941 {
1942  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1943 
1944  if (write_credentials_byte (server_fd, error))
1945  return TRUE;
1946  else
1947  return FALSE;
1948 }
1949 
1959 int
1960 _dbus_accept (int listen_fd)
1961 {
1962  int client_fd;
1963  struct sockaddr addr;
1964  socklen_t addrlen;
1965 #ifdef HAVE_ACCEPT4
1966  dbus_bool_t cloexec_done;
1967 #endif
1968 
1969  addrlen = sizeof (addr);
1970 
1971  retry:
1972 
1973 #ifdef HAVE_ACCEPT4
1974  /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1975  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1976  cloexec_done = client_fd >= 0;
1977 
1978  if (client_fd < 0 && errno == ENOSYS)
1979 #endif
1980  {
1981  client_fd = accept (listen_fd, &addr, &addrlen);
1982  }
1983 
1984  if (client_fd < 0)
1985  {
1986  if (errno == EINTR)
1987  goto retry;
1988  }
1989 
1990  _dbus_verbose ("client fd %d accepted\n", client_fd);
1991 
1992 #ifdef HAVE_ACCEPT4
1993  if (!cloexec_done)
1994 #endif
1995  {
1996  _dbus_fd_set_close_on_exec(client_fd);
1997  }
1998 
1999  return client_fd;
2000 }
2001 
2012 {
2013  const char *directory;
2014  struct stat sb;
2015 
2016  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2017 
2018  directory = _dbus_string_get_const_data (dir);
2019 
2020  if (stat (directory, &sb) < 0)
2021  {
2022  dbus_set_error (error, _dbus_error_from_errno (errno),
2023  "%s", _dbus_strerror (errno));
2024 
2025  return FALSE;
2026  }
2027 
2028  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2029  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2030  {
2032  "%s directory is not private to the user", directory);
2033  return FALSE;
2034  }
2035 
2036  return TRUE;
2037 }
2038 
2039 static dbus_bool_t
2040 fill_user_info_from_passwd (struct passwd *p,
2041  DBusUserInfo *info,
2042  DBusError *error)
2043 {
2044  _dbus_assert (p->pw_name != NULL);
2045  _dbus_assert (p->pw_dir != NULL);
2046 
2047  info->uid = p->pw_uid;
2048  info->primary_gid = p->pw_gid;
2049  info->username = _dbus_strdup (p->pw_name);
2050  info->homedir = _dbus_strdup (p->pw_dir);
2051 
2052  if (info->username == NULL ||
2053  info->homedir == NULL)
2054  {
2056  return FALSE;
2057  }
2058 
2059  return TRUE;
2060 }
2061 
2062 static dbus_bool_t
2063 fill_user_info (DBusUserInfo *info,
2064  dbus_uid_t uid,
2065  const DBusString *username,
2066  DBusError *error)
2067 {
2068  const char *username_c;
2069 
2070  /* exactly one of username/uid provided */
2071  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2072  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2073 
2074  info->uid = DBUS_UID_UNSET;
2075  info->primary_gid = DBUS_GID_UNSET;
2076  info->group_ids = NULL;
2077  info->n_group_ids = 0;
2078  info->username = NULL;
2079  info->homedir = NULL;
2080 
2081  if (username != NULL)
2082  username_c = _dbus_string_get_const_data (username);
2083  else
2084  username_c = NULL;
2085 
2086  /* For now assuming that the getpwnam() and getpwuid() flavors
2087  * are always symmetrical, if not we have to add more configure
2088  * checks
2089  */
2090 
2091 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2092  {
2093  struct passwd *p;
2094  int result;
2095  size_t buflen;
2096  char *buf;
2097  struct passwd p_str;
2098 
2099  /* retrieve maximum needed size for buf */
2100  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2101 
2102  /* sysconf actually returns a long, but everything else expects size_t,
2103  * so just recast here.
2104  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2105  */
2106  if ((long) buflen <= 0)
2107  buflen = 1024;
2108 
2109  result = -1;
2110  while (1)
2111  {
2112  buf = dbus_malloc (buflen);
2113  if (buf == NULL)
2114  {
2116  return FALSE;
2117  }
2118 
2119  p = NULL;
2120 #ifdef HAVE_POSIX_GETPWNAM_R
2121  if (uid != DBUS_UID_UNSET)
2122  result = getpwuid_r (uid, &p_str, buf, buflen,
2123  &p);
2124  else
2125  result = getpwnam_r (username_c, &p_str, buf, buflen,
2126  &p);
2127 #else
2128  if (uid != DBUS_UID_UNSET)
2129  p = getpwuid_r (uid, &p_str, buf, buflen);
2130  else
2131  p = getpwnam_r (username_c, &p_str, buf, buflen);
2132  result = 0;
2133 #endif /* !HAVE_POSIX_GETPWNAM_R */
2134  //Try a bigger buffer if ERANGE was returned
2135  if (result == ERANGE && buflen < 512 * 1024)
2136  {
2137  dbus_free (buf);
2138  buflen *= 2;
2139  }
2140  else
2141  {
2142  break;
2143  }
2144  }
2145  if (result == 0 && p == &p_str)
2146  {
2147  if (!fill_user_info_from_passwd (p, info, error))
2148  {
2149  dbus_free (buf);
2150  return FALSE;
2151  }
2152  dbus_free (buf);
2153  }
2154  else
2155  {
2156  dbus_set_error (error, _dbus_error_from_errno (errno),
2157  "User \"%s\" unknown or no memory to allocate password entry\n",
2158  username_c ? username_c : "???");
2159  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2160  dbus_free (buf);
2161  return FALSE;
2162  }
2163  }
2164 #else /* ! HAVE_GETPWNAM_R */
2165  {
2166  /* I guess we're screwed on thread safety here */
2167  struct passwd *p;
2168 
2169  if (uid != DBUS_UID_UNSET)
2170  p = getpwuid (uid);
2171  else
2172  p = getpwnam (username_c);
2173 
2174  if (p != NULL)
2175  {
2176  if (!fill_user_info_from_passwd (p, info, error))
2177  {
2178  return FALSE;
2179  }
2180  }
2181  else
2182  {
2183  dbus_set_error (error, _dbus_error_from_errno (errno),
2184  "User \"%s\" unknown or no memory to allocate password entry\n",
2185  username_c ? username_c : "???");
2186  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2187  return FALSE;
2188  }
2189  }
2190 #endif /* ! HAVE_GETPWNAM_R */
2191 
2192  /* Fill this in so we can use it to get groups */
2193  username_c = info->username;
2194 
2195 #ifdef HAVE_GETGROUPLIST
2196  {
2197  gid_t *buf;
2198  int buf_count;
2199  int i;
2200  int initial_buf_count;
2201 
2202  initial_buf_count = 17;
2203  buf_count = initial_buf_count;
2204  buf = dbus_new (gid_t, buf_count);
2205  if (buf == NULL)
2206  {
2208  goto failed;
2209  }
2210 
2211  if (getgrouplist (username_c,
2212  info->primary_gid,
2213  buf, &buf_count) < 0)
2214  {
2215  gid_t *new;
2216  /* Presumed cause of negative return code: buf has insufficient
2217  entries to hold the entire group list. The Linux behavior in this
2218  case is to pass back the actual number of groups in buf_count, but
2219  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2220  So as a hack, try to help out a bit by guessing a larger
2221  number of groups, within reason.. might still fail, of course,
2222  but we can at least print a more informative message. I looked up
2223  the "right way" to do this by downloading Apple's own source code
2224  for the "id" command, and it turns out that they use an
2225  undocumented library function getgrouplist_2 (!) which is not
2226  declared in any header in /usr/include (!!). That did not seem
2227  like the way to go here.
2228  */
2229  if (buf_count == initial_buf_count)
2230  {
2231  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2232  }
2233  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2234  if (new == NULL)
2235  {
2237  dbus_free (buf);
2238  goto failed;
2239  }
2240 
2241  buf = new;
2242 
2243  errno = 0;
2244  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2245  {
2246  if (errno == 0)
2247  {
2248  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2249  username_c, buf_count, buf_count);
2250  }
2251  else
2252  {
2253  dbus_set_error (error,
2254  _dbus_error_from_errno (errno),
2255  "Failed to get groups for username \"%s\" primary GID "
2256  DBUS_GID_FORMAT ": %s\n",
2257  username_c, info->primary_gid,
2258  _dbus_strerror (errno));
2259  dbus_free (buf);
2260  goto failed;
2261  }
2262  }
2263  }
2264 
2265  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2266  if (info->group_ids == NULL)
2267  {
2269  dbus_free (buf);
2270  goto failed;
2271  }
2272 
2273  for (i = 0; i < buf_count; ++i)
2274  info->group_ids[i] = buf[i];
2275 
2276  info->n_group_ids = buf_count;
2277 
2278  dbus_free (buf);
2279  }
2280 #else /* HAVE_GETGROUPLIST */
2281  {
2282  /* We just get the one group ID */
2283  info->group_ids = dbus_new (dbus_gid_t, 1);
2284  if (info->group_ids == NULL)
2285  {
2287  goto failed;
2288  }
2289 
2290  info->n_group_ids = 1;
2291 
2292  (info->group_ids)[0] = info->primary_gid;
2293  }
2294 #endif /* HAVE_GETGROUPLIST */
2295 
2296  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2297 
2298  return TRUE;
2299 
2300  failed:
2301  _DBUS_ASSERT_ERROR_IS_SET (error);
2302  return FALSE;
2303 }
2304 
2315  const DBusString *username,
2316  DBusError *error)
2317 {
2318  return fill_user_info (info, DBUS_UID_UNSET,
2319  username, error);
2320 }
2321 
2332  dbus_uid_t uid,
2333  DBusError *error)
2334 {
2335  return fill_user_info (info, uid,
2336  NULL, error);
2337 }
2338 
2348 {
2349  /* The POSIX spec certainly doesn't promise this, but
2350  * we need these assertions to fail as soon as we're wrong about
2351  * it so we can do the porting fixups
2352  */
2353  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2354  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2355  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2356 
2357  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2358  return FALSE;
2359  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2360  return FALSE;
2361 
2362  return TRUE;
2363 }
2364 
2378 {
2379  return _dbus_string_append_uint (str,
2380  _dbus_geteuid ());
2381 }
2382 
2387 dbus_pid_t
2389 {
2390  return getpid ();
2391 }
2392 
2396 dbus_uid_t
2398 {
2399  return getuid ();
2400 }
2401 
2405 dbus_uid_t
2407 {
2408  return geteuid ();
2409 }
2410 
2417 unsigned long
2419 {
2420  return getpid ();
2421 }
2422 
2431 _dbus_parse_uid (const DBusString *uid_str,
2432  dbus_uid_t *uid)
2433 {
2434  int end;
2435  long val;
2436 
2437  if (_dbus_string_get_length (uid_str) == 0)
2438  {
2439  _dbus_verbose ("UID string was zero length\n");
2440  return FALSE;
2441  }
2442 
2443  val = -1;
2444  end = 0;
2445  if (!_dbus_string_parse_int (uid_str, 0, &val,
2446  &end))
2447  {
2448  _dbus_verbose ("could not parse string as a UID\n");
2449  return FALSE;
2450  }
2451 
2452  if (end != _dbus_string_get_length (uid_str))
2453  {
2454  _dbus_verbose ("string contained trailing stuff after UID\n");
2455  return FALSE;
2456  }
2457 
2458  *uid = val;
2459 
2460  return TRUE;
2461 }
2462 
2463 #if !DBUS_USE_SYNC
2464 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2465 #endif
2466 
2473 dbus_int32_t
2475 {
2476 #if DBUS_USE_SYNC
2477  return __sync_add_and_fetch(&atomic->value, 1)-1;
2478 #else
2479  dbus_int32_t res;
2480  _DBUS_LOCK (atomic);
2481  res = atomic->value;
2482  atomic->value += 1;
2483  _DBUS_UNLOCK (atomic);
2484  return res;
2485 #endif
2486 }
2487 
2494 dbus_int32_t
2496 {
2497 #if DBUS_USE_SYNC
2498  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2499 #else
2500  dbus_int32_t res;
2501 
2502  _DBUS_LOCK (atomic);
2503  res = atomic->value;
2504  atomic->value -= 1;
2505  _DBUS_UNLOCK (atomic);
2506  return res;
2507 #endif
2508 }
2509 
2517 dbus_int32_t
2519 {
2520 #if DBUS_USE_SYNC
2521  __sync_synchronize ();
2522  return atomic->value;
2523 #else
2524  dbus_int32_t res;
2525 
2526  _DBUS_LOCK (atomic);
2527  res = atomic->value;
2528  _DBUS_UNLOCK (atomic);
2529  return res;
2530 #endif
2531 }
2532 
2541 int
2543  int n_fds,
2544  int timeout_milliseconds)
2545 {
2546 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2547  /* This big thing is a constant expression and should get optimized
2548  * out of existence. So it's more robust than a configure check at
2549  * no cost.
2550  */
2551  if (_DBUS_POLLIN == POLLIN &&
2552  _DBUS_POLLPRI == POLLPRI &&
2553  _DBUS_POLLOUT == POLLOUT &&
2554  _DBUS_POLLERR == POLLERR &&
2555  _DBUS_POLLHUP == POLLHUP &&
2556  _DBUS_POLLNVAL == POLLNVAL &&
2557  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2558  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2559  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2560  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2561  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2562  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2563  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2564  {
2565  return poll ((struct pollfd*) fds,
2566  n_fds,
2567  timeout_milliseconds);
2568  }
2569  else
2570  {
2571  /* We have to convert the DBusPollFD to an array of
2572  * struct pollfd, poll, and convert back.
2573  */
2574  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2575  return -1;
2576  }
2577 #else /* ! HAVE_POLL */
2578 
2579  fd_set read_set, write_set, err_set;
2580  int max_fd = 0;
2581  int i;
2582  struct timeval tv;
2583  int ready;
2584 
2585  FD_ZERO (&read_set);
2586  FD_ZERO (&write_set);
2587  FD_ZERO (&err_set);
2588 
2589  for (i = 0; i < n_fds; i++)
2590  {
2591  DBusPollFD *fdp = &fds[i];
2592 
2593  if (fdp->events & _DBUS_POLLIN)
2594  FD_SET (fdp->fd, &read_set);
2595 
2596  if (fdp->events & _DBUS_POLLOUT)
2597  FD_SET (fdp->fd, &write_set);
2598 
2599  FD_SET (fdp->fd, &err_set);
2600 
2601  max_fd = MAX (max_fd, fdp->fd);
2602  }
2603 
2604  tv.tv_sec = timeout_milliseconds / 1000;
2605  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2606 
2607  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2608  timeout_milliseconds < 0 ? NULL : &tv);
2609 
2610  if (ready > 0)
2611  {
2612  for (i = 0; i < n_fds; i++)
2613  {
2614  DBusPollFD *fdp = &fds[i];
2615 
2616  fdp->revents = 0;
2617 
2618  if (FD_ISSET (fdp->fd, &read_set))
2619  fdp->revents |= _DBUS_POLLIN;
2620 
2621  if (FD_ISSET (fdp->fd, &write_set))
2622  fdp->revents |= _DBUS_POLLOUT;
2623 
2624  if (FD_ISSET (fdp->fd, &err_set))
2625  fdp->revents |= _DBUS_POLLERR;
2626  }
2627  }
2628 
2629  return ready;
2630 #endif
2631 }
2632 
2640 void
2642  long *tv_usec)
2643 {
2644 #ifdef HAVE_MONOTONIC_CLOCK
2645  struct timespec ts;
2646  clock_gettime (CLOCK_MONOTONIC, &ts);
2647 
2648  if (tv_sec)
2649  *tv_sec = ts.tv_sec;
2650  if (tv_usec)
2651  *tv_usec = ts.tv_nsec / 1000;
2652 #else
2653  struct timeval t;
2654 
2655  gettimeofday (&t, NULL);
2656 
2657  if (tv_sec)
2658  *tv_sec = t.tv_sec;
2659  if (tv_usec)
2660  *tv_usec = t.tv_usec;
2661 #endif
2662 }
2663 
2671 void
2672 _dbus_get_real_time (long *tv_sec,
2673  long *tv_usec)
2674 {
2675  struct timeval t;
2676 
2677  gettimeofday (&t, NULL);
2678 
2679  if (tv_sec)
2680  *tv_sec = t.tv_sec;
2681  if (tv_usec)
2682  *tv_usec = t.tv_usec;
2683 }
2684 
2695  DBusError *error)
2696 {
2697  const char *filename_c;
2698 
2699  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2700 
2701  filename_c = _dbus_string_get_const_data (filename);
2702 
2703  if (mkdir (filename_c, 0700) < 0)
2704  {
2705  if (errno == EEXIST)
2706  return TRUE;
2707 
2709  "Failed to create directory %s: %s\n",
2710  filename_c, _dbus_strerror (errno));
2711  return FALSE;
2712  }
2713  else
2714  return TRUE;
2715 }
2716 
2729  const DBusString *next_component)
2730 {
2731  dbus_bool_t dir_ends_in_slash;
2732  dbus_bool_t file_starts_with_slash;
2733 
2734  if (_dbus_string_get_length (dir) == 0 ||
2735  _dbus_string_get_length (next_component) == 0)
2736  return TRUE;
2737 
2738  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2739  _dbus_string_get_length (dir) - 1);
2740 
2741  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2742 
2743  if (dir_ends_in_slash && file_starts_with_slash)
2744  {
2745  _dbus_string_shorten (dir, 1);
2746  }
2747  else if (!(dir_ends_in_slash || file_starts_with_slash))
2748  {
2749  if (!_dbus_string_append_byte (dir, '/'))
2750  return FALSE;
2751  }
2752 
2753  return _dbus_string_copy (next_component, 0, dir,
2754  _dbus_string_get_length (dir));
2755 }
2756 
2758 #define NANOSECONDS_PER_SECOND 1000000000
2759 
2760 #define MICROSECONDS_PER_SECOND 1000000
2761 
2762 #define MILLISECONDS_PER_SECOND 1000
2763 
2764 #define NANOSECONDS_PER_MILLISECOND 1000000
2765 
2766 #define MICROSECONDS_PER_MILLISECOND 1000
2767 
2772 void
2773 _dbus_sleep_milliseconds (int milliseconds)
2774 {
2775 #ifdef HAVE_NANOSLEEP
2776  struct timespec req;
2777  struct timespec rem;
2778 
2779  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2780  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2781  rem.tv_sec = 0;
2782  rem.tv_nsec = 0;
2783 
2784  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2785  req = rem;
2786 #elif defined (HAVE_USLEEP)
2787  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2788 #else /* ! HAVE_USLEEP */
2789  sleep (MAX (milliseconds / 1000, 1));
2790 #endif
2791 }
2792 
2793 static dbus_bool_t
2794 _dbus_generate_pseudorandom_bytes (DBusString *str,
2795  int n_bytes)
2796 {
2797  int old_len;
2798  char *p;
2799 
2800  old_len = _dbus_string_get_length (str);
2801 
2802  if (!_dbus_string_lengthen (str, n_bytes))
2803  return FALSE;
2804 
2805  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2806 
2808 
2809  return TRUE;
2810 }
2811 
2822  int n_bytes)
2823 {
2824  int old_len;
2825  int fd;
2826 
2827  /* FALSE return means "no memory", if it could
2828  * mean something else then we'd need to return
2829  * a DBusError. So we always fall back to pseudorandom
2830  * if the I/O fails.
2831  */
2832 
2833  old_len = _dbus_string_get_length (str);
2834  fd = -1;
2835 
2836  /* note, urandom on linux will fall back to pseudorandom */
2837  fd = open ("/dev/urandom", O_RDONLY);
2838  if (fd < 0)
2839  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2840 
2841  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2842 
2843  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2844  {
2845  _dbus_close (fd, NULL);
2846  _dbus_string_set_length (str, old_len);
2847  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2848  }
2849 
2850  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2851  n_bytes);
2852 
2853  _dbus_close (fd, NULL);
2854 
2855  return TRUE;
2856 }
2857 
2863 void
2864 _dbus_exit (int code)
2865 {
2866  _exit (code);
2867 }
2868 
2877 const char*
2878 _dbus_strerror (int error_number)
2879 {
2880  const char *msg;
2881 
2882  msg = strerror (error_number);
2883  if (msg == NULL)
2884  msg = "unknown";
2885 
2886  return msg;
2887 }
2888 
2892 void
2894 {
2895  signal (SIGPIPE, SIG_IGN);
2896 }
2897 
2905 void
2907 {
2908  int val;
2909 
2910  val = fcntl (fd, F_GETFD, 0);
2911 
2912  if (val < 0)
2913  return;
2914 
2915  val |= FD_CLOEXEC;
2916 
2917  fcntl (fd, F_SETFD, val);
2918 }
2919 
2928 _dbus_close (int fd,
2929  DBusError *error)
2930 {
2931  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2932 
2933  again:
2934  if (close (fd) < 0)
2935  {
2936  if (errno == EINTR)
2937  goto again;
2938 
2939  dbus_set_error (error, _dbus_error_from_errno (errno),
2940  "Could not close fd %d", fd);
2941  return FALSE;
2942  }
2943 
2944  return TRUE;
2945 }
2946 
2954 int
2955 _dbus_dup(int fd,
2956  DBusError *error)
2957 {
2958  int new_fd;
2959 
2960 #ifdef F_DUPFD_CLOEXEC
2961  dbus_bool_t cloexec_done;
2962 
2963  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2964  cloexec_done = new_fd >= 0;
2965 
2966  if (new_fd < 0 && errno == EINVAL)
2967 #endif
2968  {
2969  new_fd = fcntl(fd, F_DUPFD, 3);
2970  }
2971 
2972  if (new_fd < 0) {
2973 
2974  dbus_set_error (error, _dbus_error_from_errno (errno),
2975  "Could not duplicate fd %d", fd);
2976  return -1;
2977  }
2978 
2979 #ifdef F_DUPFD_CLOEXEC
2980  if (!cloexec_done)
2981 #endif
2982  {
2984  }
2985 
2986  return new_fd;
2987 }
2988 
2997 _dbus_set_fd_nonblocking (int fd,
2998  DBusError *error)
2999 {
3000  int val;
3001 
3002  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3003 
3004  val = fcntl (fd, F_GETFL, 0);
3005  if (val < 0)
3006  {
3007  dbus_set_error (error, _dbus_error_from_errno (errno),
3008  "Failed to get flags from file descriptor %d: %s",
3009  fd, _dbus_strerror (errno));
3010  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3011  _dbus_strerror (errno));
3012  return FALSE;
3013  }
3014 
3015  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3016  {
3017  dbus_set_error (error, _dbus_error_from_errno (errno),
3018  "Failed to set nonblocking flag of file descriptor %d: %s",
3019  fd, _dbus_strerror (errno));
3020  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3021  fd, _dbus_strerror (errno));
3022 
3023  return FALSE;
3024  }
3025 
3026  return TRUE;
3027 }
3028 
3034 void
3036 {
3037 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3038  void *bt[500];
3039  int bt_size;
3040  int i;
3041  char **syms;
3042 
3043  bt_size = backtrace (bt, 500);
3044 
3045  syms = backtrace_symbols (bt, bt_size);
3046 
3047  i = 0;
3048  while (i < bt_size)
3049  {
3050  /* don't use dbus_warn since it can _dbus_abort() */
3051  fprintf (stderr, " %s\n", syms[i]);
3052  ++i;
3053  }
3054  fflush (stderr);
3055 
3056  free (syms);
3057 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3058  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3059 #else
3060  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3061 #endif
3062 }
3063 
3078  int *fd2,
3079  dbus_bool_t blocking,
3080  DBusError *error)
3081 {
3082 #ifdef HAVE_SOCKETPAIR
3083  int fds[2];
3084  int retval;
3085 
3086 #ifdef SOCK_CLOEXEC
3087  dbus_bool_t cloexec_done;
3088 
3089  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3090  cloexec_done = retval >= 0;
3091 
3092  if (retval < 0 && errno == EINVAL)
3093 #endif
3094  {
3095  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3096  }
3097 
3098  if (retval < 0)
3099  {
3100  dbus_set_error (error, _dbus_error_from_errno (errno),
3101  "Could not create full-duplex pipe");
3102  return FALSE;
3103  }
3104 
3105  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3106 
3107 #ifdef SOCK_CLOEXEC
3108  if (!cloexec_done)
3109 #endif
3110  {
3111  _dbus_fd_set_close_on_exec (fds[0]);
3112  _dbus_fd_set_close_on_exec (fds[1]);
3113  }
3114 
3115  if (!blocking &&
3116  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3117  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3118  {
3119  dbus_set_error (error, _dbus_error_from_errno (errno),
3120  "Could not set full-duplex pipe nonblocking");
3121 
3122  _dbus_close (fds[0], NULL);
3123  _dbus_close (fds[1], NULL);
3124 
3125  return FALSE;
3126  }
3127 
3128  *fd1 = fds[0];
3129  *fd2 = fds[1];
3130 
3131  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3132  *fd1, *fd2);
3133 
3134  return TRUE;
3135 #else
3136  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3138  "_dbus_full_duplex_pipe() not implemented on this OS");
3139  return FALSE;
3140 #endif
3141 }
3142 
3151 int
3153  va_list args)
3154 {
3155  char static_buf[1024];
3156  int bufsize = sizeof (static_buf);
3157  int len;
3158  va_list args_copy;
3159 
3160  DBUS_VA_COPY (args_copy, args);
3161  len = vsnprintf (static_buf, bufsize, format, args_copy);
3162  va_end (args_copy);
3163 
3164  /* If vsnprintf() returned non-negative, then either the string fits in
3165  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3166  * returns the number of characters that were needed, or this OS returns the
3167  * truncated length.
3168  *
3169  * We ignore the possibility that snprintf might just ignore the length and
3170  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3171  * If your libc is really that bad, come back when you have a better one. */
3172  if (len == bufsize)
3173  {
3174  /* This could be the truncated length (Tru64 and IRIX have this bug),
3175  * or the real length could be coincidentally the same. Which is it?
3176  * If vsnprintf returns the truncated length, we'll go to the slow
3177  * path. */
3178  DBUS_VA_COPY (args_copy, args);
3179 
3180  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3181  len = -1;
3182 
3183  va_end (args_copy);
3184  }
3185 
3186  /* If vsnprintf() returned negative, we have to do more work.
3187  * HP-UX returns negative. */
3188  while (len < 0)
3189  {
3190  char *buf;
3191 
3192  bufsize *= 2;
3193 
3194  buf = dbus_malloc (bufsize);
3195 
3196  if (buf == NULL)
3197  return -1;
3198 
3199  DBUS_VA_COPY (args_copy, args);
3200  len = vsnprintf (buf, bufsize, format, args_copy);
3201  va_end (args_copy);
3202 
3203  dbus_free (buf);
3204 
3205  /* If the reported length is exactly the buffer size, round up to the
3206  * next size, in case vsnprintf has been returning the truncated
3207  * length */
3208  if (len == bufsize)
3209  len = -1;
3210  }
3211 
3212  return len;
3213 }
3214 
3221 const char*
3223 {
3224  static const char* tmpdir = NULL;
3225 
3226  if (tmpdir == NULL)
3227  {
3228  /* TMPDIR is what glibc uses, then
3229  * glibc falls back to the P_tmpdir macro which
3230  * just expands to "/tmp"
3231  */
3232  if (tmpdir == NULL)
3233  tmpdir = getenv("TMPDIR");
3234 
3235  /* These two env variables are probably
3236  * broken, but maybe some OS uses them?
3237  */
3238  if (tmpdir == NULL)
3239  tmpdir = getenv("TMP");
3240  if (tmpdir == NULL)
3241  tmpdir = getenv("TEMP");
3242 
3243  /* And this is the sane fallback. */
3244  if (tmpdir == NULL)
3245  tmpdir = "/tmp";
3246  }
3247 
3248  _dbus_assert(tmpdir != NULL);
3249 
3250  return tmpdir;
3251 }
3252 
3272 static dbus_bool_t
3273 _read_subprocess_line_argv (const char *progpath,
3274  dbus_bool_t path_fallback,
3275  char * const *argv,
3276  DBusString *result,
3277  DBusError *error)
3278 {
3279  int result_pipe[2] = { -1, -1 };
3280  int errors_pipe[2] = { -1, -1 };
3281  pid_t pid;
3282  int ret;
3283  int status;
3284  int orig_len;
3285 
3286  dbus_bool_t retval;
3287  sigset_t new_set, old_set;
3288 
3289  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3290  retval = FALSE;
3291 
3292  /* We need to block any existing handlers for SIGCHLD temporarily; they
3293  * will cause waitpid() below to fail.
3294  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3295  */
3296  sigemptyset (&new_set);
3297  sigaddset (&new_set, SIGCHLD);
3298  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3299 
3300  orig_len = _dbus_string_get_length (result);
3301 
3302 #define READ_END 0
3303 #define WRITE_END 1
3304  if (pipe (result_pipe) < 0)
3305  {
3306  dbus_set_error (error, _dbus_error_from_errno (errno),
3307  "Failed to create a pipe to call %s: %s",
3308  progpath, _dbus_strerror (errno));
3309  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3310  progpath, _dbus_strerror (errno));
3311  goto out;
3312  }
3313  if (pipe (errors_pipe) < 0)
3314  {
3315  dbus_set_error (error, _dbus_error_from_errno (errno),
3316  "Failed to create a pipe to call %s: %s",
3317  progpath, _dbus_strerror (errno));
3318  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3319  progpath, _dbus_strerror (errno));
3320  goto out;
3321  }
3322 
3323  pid = fork ();
3324  if (pid < 0)
3325  {
3326  dbus_set_error (error, _dbus_error_from_errno (errno),
3327  "Failed to fork() to call %s: %s",
3328  progpath, _dbus_strerror (errno));
3329  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3330  progpath, _dbus_strerror (errno));
3331  goto out;
3332  }
3333 
3334  if (pid == 0)
3335  {
3336  /* child process */
3337  int fd;
3338 
3339  fd = open ("/dev/null", O_RDWR);
3340  if (fd == -1)
3341  /* huh?! can't open /dev/null? */
3342  _exit (1);
3343 
3344  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3345 
3346  /* set-up stdXXX */
3347  close (result_pipe[READ_END]);
3348  close (errors_pipe[READ_END]);
3349  close (0); /* close stdin */
3350  close (1); /* close stdout */
3351  close (2); /* close stderr */
3352 
3353  if (dup2 (fd, 0) == -1)
3354  _exit (1);
3355  if (dup2 (result_pipe[WRITE_END], 1) == -1)
3356  _exit (1);
3357  if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3358  _exit (1);
3359 
3360  _dbus_close_all ();
3361 
3362  sigprocmask (SIG_SETMASK, &old_set, NULL);
3363 
3364  /* If it looks fully-qualified, try execv first */
3365  if (progpath[0] == '/')
3366  {
3367  execv (progpath, argv);
3368  /* Ok, that failed. Now if path_fallback is given, let's
3369  * try unqualified. This is mostly a hack to work
3370  * around systems which ship dbus-launch in /usr/bin
3371  * but everything else in /bin (because dbus-launch
3372  * depends on X11).
3373  */
3374  if (path_fallback)
3375  /* We must have a slash, because we checked above */
3376  execvp (strrchr (progpath, '/')+1, argv);
3377  }
3378  else
3379  execvp (progpath, argv);
3380 
3381  /* still nothing, we failed */
3382  _exit (1);
3383  }
3384 
3385  /* parent process */
3386  close (result_pipe[WRITE_END]);
3387  close (errors_pipe[WRITE_END]);
3388  result_pipe[WRITE_END] = -1;
3389  errors_pipe[WRITE_END] = -1;
3390 
3391  ret = 0;
3392  do
3393  {
3394  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3395  }
3396  while (ret > 0);
3397 
3398  /* reap the child process to avoid it lingering as zombie */
3399  do
3400  {
3401  ret = waitpid (pid, &status, 0);
3402  }
3403  while (ret == -1 && errno == EINTR);
3404 
3405  /* We succeeded if the process exited with status 0 and
3406  anything was read */
3407  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3408  {
3409  /* The process ended with error */
3410  DBusString error_message;
3411  if (!_dbus_string_init (&error_message))
3412  {
3413  _DBUS_SET_OOM (error);
3414  goto out;
3415  }
3416 
3417  ret = 0;
3418  do
3419  {
3420  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3421  }
3422  while (ret > 0);
3423 
3424  _dbus_string_set_length (result, orig_len);
3425  if (_dbus_string_get_length (&error_message) > 0)
3427  "%s terminated abnormally with the following error: %s",
3428  progpath, _dbus_string_get_data (&error_message));
3429  else
3431  "%s terminated abnormally without any error message",
3432  progpath);
3433  goto out;
3434  }
3435 
3436  retval = TRUE;
3437 
3438  out:
3439  sigprocmask (SIG_SETMASK, &old_set, NULL);
3440 
3441  if (retval)
3442  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3443  else
3444  _DBUS_ASSERT_ERROR_IS_SET (error);
3445 
3446  if (result_pipe[0] != -1)
3447  close (result_pipe[0]);
3448  if (result_pipe[1] != -1)
3449  close (result_pipe[1]);
3450  if (errors_pipe[0] != -1)
3451  close (errors_pipe[0]);
3452  if (errors_pipe[1] != -1)
3453  close (errors_pipe[1]);
3454 
3455  return retval;
3456 }
3457 
3470 _dbus_get_autolaunch_address (const char *scope,
3471  DBusString *address,
3472  DBusError *error)
3473 {
3474 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3475  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3476  * but that's done elsewhere, and if it worked, this function wouldn't
3477  * be called.) */
3478  const char *display;
3479  static char *argv[6];
3480  int i;
3481  DBusString uuid;
3482  dbus_bool_t retval;
3483 
3484  if (_dbus_check_setuid ())
3485  {
3487  "Unable to autolaunch when setuid");
3488  return FALSE;
3489  }
3490 
3491  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3492  retval = FALSE;
3493 
3494  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3495  * dbus-launch-x11 is just going to fail. Rather than trying to
3496  * run it, we might as well bail out early with a nice error. */
3497  display = _dbus_getenv ("DISPLAY");
3498 
3499  if (display == NULL || display[0] == '\0')
3500  {
3502  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3503  return FALSE;
3504  }
3505 
3506  if (!_dbus_string_init (&uuid))
3507  {
3508  _DBUS_SET_OOM (error);
3509  return FALSE;
3510  }
3511 
3513  {
3514  _DBUS_SET_OOM (error);
3515  goto out;
3516  }
3517 
3518  i = 0;
3519  argv[i] = "dbus-launch";
3520  ++i;
3521  argv[i] = "--autolaunch";
3522  ++i;
3523  argv[i] = _dbus_string_get_data (&uuid);
3524  ++i;
3525  argv[i] = "--binary-syntax";
3526  ++i;
3527  argv[i] = "--close-stderr";
3528  ++i;
3529  argv[i] = NULL;
3530  ++i;
3531 
3532  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3533 
3534  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3535  TRUE,
3536  argv, address, error);
3537 
3538  out:
3539  _dbus_string_free (&uuid);
3540  return retval;
3541 #else
3543  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3544  "set your DBUS_SESSION_BUS_ADDRESS instead");
3545  return FALSE;
3546 #endif
3547 }
3548 
3569  dbus_bool_t create_if_not_found,
3570  DBusError *error)
3571 {
3572  DBusString filename;
3573  dbus_bool_t b;
3574 
3575  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3576 
3577  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3578  if (b)
3579  return TRUE;
3580 
3581  dbus_error_free (error);
3582 
3583  /* Fallback to the system machine ID */
3584  _dbus_string_init_const (&filename, "/etc/machine-id");
3585  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3586 }
3587 
3588 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3589 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3590 
3599  const char *launchd_env_var,
3600  DBusError *error)
3601 {
3602 #ifdef DBUS_ENABLE_LAUNCHD
3603  char *argv[4];
3604  int i;
3605 
3606  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3607 
3608  if (_dbus_check_setuid ())
3609  {
3611  "Unable to find launchd socket when setuid");
3612  return FALSE;
3613  }
3614 
3615  i = 0;
3616  argv[i] = "launchctl";
3617  ++i;
3618  argv[i] = "getenv";
3619  ++i;
3620  argv[i] = (char*)launchd_env_var;
3621  ++i;
3622  argv[i] = NULL;
3623  ++i;
3624 
3625  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3626 
3627  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3628  {
3629  return FALSE;
3630  }
3631 
3632  /* no error, but no result either */
3633  if (_dbus_string_get_length(socket_path) == 0)
3634  {
3635  return FALSE;
3636  }
3637 
3638  /* strip the carriage-return */
3639  _dbus_string_shorten(socket_path, 1);
3640  return TRUE;
3641 #else /* DBUS_ENABLE_LAUNCHD */
3643  "can't lookup socket from launchd; launchd support not compiled in");
3644  return FALSE;
3645 #endif
3646 }
3647 
3648 #ifdef DBUS_ENABLE_LAUNCHD
3649 static dbus_bool_t
3650 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3651 {
3652  dbus_bool_t valid_socket;
3653  DBusString socket_path;
3654 
3655  if (_dbus_check_setuid ())
3656  {
3658  "Unable to find launchd socket when setuid");
3659  return FALSE;
3660  }
3661 
3662  if (!_dbus_string_init (&socket_path))
3663  {
3664  _DBUS_SET_OOM (error);
3665  return FALSE;
3666  }
3667 
3668  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3669 
3670  if (dbus_error_is_set(error))
3671  {
3672  _dbus_string_free(&socket_path);
3673  return FALSE;
3674  }
3675 
3676  if (!valid_socket)
3677  {
3678  dbus_set_error(error, "no socket path",
3679  "launchd did not provide a socket path, "
3680  "verify that org.freedesktop.dbus-session.plist is loaded!");
3681  _dbus_string_free(&socket_path);
3682  return FALSE;
3683  }
3684  if (!_dbus_string_append (address, "unix:path="))
3685  {
3686  _DBUS_SET_OOM (error);
3687  _dbus_string_free(&socket_path);
3688  return FALSE;
3689  }
3690  if (!_dbus_string_copy (&socket_path, 0, address,
3691  _dbus_string_get_length (address)))
3692  {
3693  _DBUS_SET_OOM (error);
3694  _dbus_string_free(&socket_path);
3695  return FALSE;
3696  }
3697 
3698  _dbus_string_free(&socket_path);
3699  return TRUE;
3700 }
3701 #endif
3702 
3724  DBusString *address,
3725  DBusError *error)
3726 {
3727 #ifdef DBUS_ENABLE_LAUNCHD
3728  *supported = TRUE;
3729  return _dbus_lookup_session_address_launchd (address, error);
3730 #else
3731  /* On non-Mac Unix platforms, if the session address isn't already
3732  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3733  * fall back to the autolaunch: global default; see
3734  * init_session_address in dbus/dbus-bus.c. */
3735  *supported = FALSE;
3736  return TRUE;
3737 #endif
3738 }
3739 
3759 {
3760  const char *xdg_data_home;
3761  const char *xdg_data_dirs;
3762  DBusString servicedir_path;
3763 
3764  if (!_dbus_string_init (&servicedir_path))
3765  return FALSE;
3766 
3767  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3768  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3769 
3770  if (xdg_data_home != NULL)
3771  {
3772  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3773  goto oom;
3774  }
3775  else
3776  {
3777  const DBusString *homedir;
3778  DBusString local_share;
3779 
3780  if (!_dbus_homedir_from_current_process (&homedir))
3781  goto oom;
3782 
3783  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3784  goto oom;
3785 
3786  _dbus_string_init_const (&local_share, "/.local/share");
3787  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3788  goto oom;
3789  }
3790 
3791  if (!_dbus_string_append (&servicedir_path, ":"))
3792  goto oom;
3793 
3794  if (xdg_data_dirs != NULL)
3795  {
3796  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3797  goto oom;
3798 
3799  if (!_dbus_string_append (&servicedir_path, ":"))
3800  goto oom;
3801  }
3802  else
3803  {
3804  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3805  goto oom;
3806  }
3807 
3808  /*
3809  * add configured datadir to defaults
3810  * this may be the same as an xdg dir
3811  * however the config parser should take
3812  * care of duplicates
3813  */
3814  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3815  goto oom;
3816 
3817  if (!_dbus_split_paths_and_append (&servicedir_path,
3818  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3819  dirs))
3820  goto oom;
3821 
3822  _dbus_string_free (&servicedir_path);
3823  return TRUE;
3824 
3825  oom:
3826  _dbus_string_free (&servicedir_path);
3827  return FALSE;
3828 }
3829 
3830 
3851 {
3852  /*
3853  * DBUS_DATADIR may be the same as one of the standard directories. However,
3854  * the config parser should take care of the duplicates.
3855  *
3856  * Also, append /lib as counterpart of /usr/share on the root
3857  * directory (the root directory does not know /share), in order to
3858  * facilitate early boot system bus activation where /usr might not
3859  * be available.
3860  */
3861  static const char standard_search_path[] =
3862  "/usr/local/share:"
3863  "/usr/share:"
3864  DBUS_DATADIR ":"
3865  "/lib";
3866  DBusString servicedir_path;
3867 
3868  _dbus_string_init_const (&servicedir_path, standard_search_path);
3869 
3870  return _dbus_split_paths_and_append (&servicedir_path,
3871  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3872  dirs);
3873 }
3874 
3885 {
3886  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3887 }
3888 
3897 {
3898  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3899 }
3900 
3908 void
3910 {
3912 }
3913 
3929  DBusCredentials *credentials)
3930 {
3931  DBusString homedir;
3932  DBusString dotdir;
3933  dbus_uid_t uid;
3934 
3935  _dbus_assert (credentials != NULL);
3937 
3938  if (!_dbus_string_init (&homedir))
3939  return FALSE;
3940 
3941  uid = _dbus_credentials_get_unix_uid (credentials);
3942  _dbus_assert (uid != DBUS_UID_UNSET);
3943 
3944  if (!_dbus_homedir_from_uid (uid, &homedir))
3945  goto failed;
3946 
3947 #ifdef DBUS_BUILD_TESTS
3948  {
3949  const char *override;
3950 
3951  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3952  if (override != NULL && *override != '\0')
3953  {
3954  _dbus_string_set_length (&homedir, 0);
3955  if (!_dbus_string_append (&homedir, override))
3956  goto failed;
3957 
3958  _dbus_verbose ("Using fake homedir for testing: %s\n",
3959  _dbus_string_get_const_data (&homedir));
3960  }
3961  else
3962  {
3963  static dbus_bool_t already_warned = FALSE;
3964  if (!already_warned)
3965  {
3966  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3967  already_warned = TRUE;
3968  }
3969  }
3970  }
3971 #endif
3972 
3973  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3974  if (!_dbus_concat_dir_and_file (&homedir,
3975  &dotdir))
3976  goto failed;
3977 
3978  if (!_dbus_string_copy (&homedir, 0,
3979  directory, _dbus_string_get_length (directory))) {
3980  goto failed;
3981  }
3982 
3983  _dbus_string_free (&homedir);
3984  return TRUE;
3985 
3986  failed:
3987  _dbus_string_free (&homedir);
3988  return FALSE;
3989 }
3990 
3991 //PENDING(kdab) docs
3993 _dbus_daemon_publish_session_bus_address (const char* addr,
3994  const char *scope)
3995 {
3996  return TRUE;
3997 }
3998 
3999 //PENDING(kdab) docs
4000 void
4001 _dbus_daemon_unpublish_session_bus_address (void)
4002 {
4003 
4004 }
4005 
4014 {
4015  return errno == EAGAIN || errno == EWOULDBLOCK;
4016 }
4017 
4027  DBusError *error)
4028 {
4029  const char *filename_c;
4030 
4031  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4032 
4033  filename_c = _dbus_string_get_const_data (filename);
4034 
4035  if (rmdir (filename_c) != 0)
4036  {
4038  "Failed to remove directory %s: %s\n",
4039  filename_c, _dbus_strerror (errno));
4040  return FALSE;
4041  }
4042 
4043  return TRUE;
4044 }
4045 
4055 
4056 #ifdef SCM_RIGHTS
4057  union {
4058  struct sockaddr sa;
4059  struct sockaddr_storage storage;
4060  struct sockaddr_un un;
4061  } sa_buf;
4062 
4063  socklen_t sa_len = sizeof(sa_buf);
4064 
4065  _DBUS_ZERO(sa_buf);
4066 
4067  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4068  return FALSE;
4069 
4070  return sa_buf.sa.sa_family == AF_UNIX;
4071 
4072 #else
4073  return FALSE;
4074 
4075 #endif
4076 }
4077 
4078 
4079 /*
4080  * replaces the term DBUS_PREFIX in configure_time_path by the
4081  * current dbus installation directory. On unix this function is a noop
4082  *
4083  * @param configure_time_path
4084  * @return real path
4085  */
4086 const char *
4087 _dbus_replace_install_prefix (const char *configure_time_path)
4088 {
4089  return configure_time_path;
4090 }
4091 
4096 void
4098 {
4099  int maxfds, i;
4100 
4101 #ifdef __linux__
4102  DIR *d;
4103 
4104  /* On Linux we can optimize this a bit if /proc is available. If it
4105  isn't available, fall back to the brute force way. */
4106 
4107  d = opendir ("/proc/self/fd");
4108  if (d)
4109  {
4110  for (;;)
4111  {
4112  struct dirent buf, *de;
4113  int k, fd;
4114  long l;
4115  char *e = NULL;
4116 
4117  k = readdir_r (d, &buf, &de);
4118  if (k != 0 || !de)
4119  break;
4120 
4121  if (de->d_name[0] == '.')
4122  continue;
4123 
4124  errno = 0;
4125  l = strtol (de->d_name, &e, 10);
4126  if (errno != 0 || e == NULL || *e != '\0')
4127  continue;
4128 
4129  fd = (int) l;
4130  if (fd < 3)
4131  continue;
4132 
4133  if (fd == dirfd (d))
4134  continue;
4135 
4136  close (fd);
4137  }
4138 
4139  closedir (d);
4140  return;
4141  }
4142 #endif
4143 
4144  maxfds = sysconf (_SC_OPEN_MAX);
4145 
4146  /* Pick something reasonable if for some reason sysconf says
4147  * unlimited.
4148  */
4149  if (maxfds < 0)
4150  maxfds = 1024;
4151 
4152  /* close all inherited fds */
4153  for (i = 3; i < maxfds; i++)
4154  close (i);
4155 }
4156 
4168 {
4169  /* TODO: get __libc_enable_secure exported from glibc.
4170  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4171  */
4172 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4173  {
4174  /* See glibc/include/unistd.h */
4175  extern int __libc_enable_secure;
4176  return __libc_enable_secure;
4177  }
4178 #elif defined(HAVE_ISSETUGID)
4179  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4180  return issetugid ();
4181 #else
4182  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4183  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4184 
4185  static dbus_bool_t check_setuid_initialised;
4186  static dbus_bool_t is_setuid;
4187 
4188  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4189  {
4190 #ifdef HAVE_GETRESUID
4191  if (getresuid (&ruid, &euid, &suid) != 0 ||
4192  getresgid (&rgid, &egid, &sgid) != 0)
4193 #endif /* HAVE_GETRESUID */
4194  {
4195  suid = ruid = getuid ();
4196  sgid = rgid = getgid ();
4197  euid = geteuid ();
4198  egid = getegid ();
4199  }
4200 
4201  check_setuid_initialised = TRUE;
4202  is_setuid = (ruid != euid || ruid != suid ||
4203  rgid != egid || rgid != sgid);
4204 
4205  }
4206  return is_setuid;
4207 #endif
4208 }
4209 
4210 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:913
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:433
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:229
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...
dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:390
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_append_system_config_file(DBusString *str)
Append the absolute path of the system.conf file (there is no system bus on Windows so this can just ...
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:234
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.
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:291
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:600
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:738
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd)
Checks whether file descriptors may be passed via the socket.
#define _DBUS_POLLNVAL
Invalid request: fd not open.
Definition: dbus-sysdeps.h:293
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 ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:116
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:112
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_full_duplex_pipe(int *fd1, int *fd2, dbus_bool_t blocking, DBusError *error)
Creates a full-duplex pipe (as in socketpair()).
int _dbus_write_socket_two(int 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.
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib...
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:346
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
dbus_bool_t _dbus_get_standard_session_servicedirs(DBusList **dirs)
Returns the standard directories for a session bus to look for service activation files...
dbus_gid_t primary_gid
GID.
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h:285
int _dbus_read_socket_with_unix_fds(int fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
A portable struct pollfd wrapper.
Definition: dbus-sysdeps.h:299
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
int _dbus_accept(int listen_fd)
Accepts a connection on a listening socket.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:283
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:468
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
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...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:758
short events
Events to poll for.
Definition: dbus-sysdeps.h:302
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:1280
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:105
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:107
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:183
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str)
Gets the hex-encoded UUID of the machine this function is executed on.
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
const char * _dbus_error_from_errno(int error_number)
Converts a UNIX errno, or Windows errno or WinSock error value into a DBusError name.
Definition: dbus-sysdeps.c:612
dbus_bool_t _dbus_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
dbus_bool_t _dbus_homedir_from_uid(dbus_uid_t uid, DBusString *homedir)
Gets the home directory for the given user.
Definition: dbus-userdb.c:447
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:98
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
void _dbus_fd_set_close_on_exec(intptr_t fd)
Sets the file descriptor to be close on exec.
dbus_bool_t _dbus_lookup_launchd_socket(DBusString *socket_path, const char *launchd_env_var, DBusError *error)
quries launchd for a specific env var which holds the socket path.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:460
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:287
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
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.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int fd
File descriptor.
Definition: dbus-sysdeps.h:301
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
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. ...
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:1154
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:109
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:805
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:114
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
#define _DBUS_DEFINE_GLOBAL_LOCK(name)
Defines a global lock variable with the given name.
dbus_bool_t _dbus_homedir_from_current_process(const DBusString **homedir)
Gets homedir of user owning current process.
Definition: dbus-userdb.c:386
unsigned long _dbus_pid_for_log(void)
The only reason this is separate from _dbus_getpid() is to allow it on Windows for logging but not fo...
void _dbus_generate_pseudorandom_bytes_buffer(char *buffer, int n_bytes)
Random numbers.
Definition: dbus-sysdeps.c:506
int _dbus_write_socket(int fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
A node in a linked list.
Definition: dbus-list.h:34
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_split_paths_and_append(DBusString *dirs, const char *suffix, DBusList **dir_list)
Split paths into a list of char strings.
Definition: dbus-sysdeps.c:224
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(void)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method. ...
dbus_bool_t _dbus_credentials_add_unix_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:780
#define _DBUS_LOCK(name)
Locks a global lock.
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.
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...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:807
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:102
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_append_session_config_file(DBusString *str)
Append the absolute path of the session.conf file.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:100
short revents
Events that occurred.
Definition: dbus-sysdeps.h:303
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
dbus_bool_t _dbus_get_standard_system_servicedirs(DBusList **dirs)
Returns the standard directories for a system bus to look for service activation files.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
int _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.
int _dbus_listen_systemd_sockets(int **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:289