D-Bus  1.7.4
dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-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 #include <arpa/inet.h>
59 
60 #ifdef HAVE_ERRNO_H
61 #include <errno.h>
62 #endif
63 #ifdef HAVE_WRITEV
64 #include <sys/uio.h>
65 #endif
66 #ifdef HAVE_POLL
67 #include <sys/poll.h>
68 #endif
69 #ifdef HAVE_BACKTRACE
70 #include <execinfo.h>
71 #endif
72 #ifdef HAVE_GETPEERUCRED
73 #include <ucred.h>
74 #endif
75 #ifdef HAVE_ALLOCA_H
76 #include <alloca.h>
77 #endif
78 
79 #ifdef HAVE_ADT
80 #include <bsm/adt.h>
81 #endif
82 
83 #include "sd-daemon.h"
84 
85 #if !DBUS_USE_SYNC
86 #include <pthread.h>
87 #endif
88 
89 #ifndef O_BINARY
90 #define O_BINARY 0
91 #endif
92 
93 #ifndef AI_ADDRCONFIG
94 #define AI_ADDRCONFIG 0
95 #endif
96 
97 #ifndef HAVE_SOCKLEN_T
98 #define socklen_t int
99 #endif
100 
101 #if defined (__sun) || defined (__sun__)
102 /*
103  * CMS_SPACE etc. definitions for Solaris < 10, based on
104  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
105  * via
106  * http://wiki.opencsw.org/porting-faq#toc10
107  *
108  * These are only redefined for Solaris, for now: if your OS needs these too,
109  * please file a bug. (Or preferably, improve your OS so they're not needed.)
110  */
111 
112 # ifndef CMSG_ALIGN
113 # ifdef __sun__
114 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
115 # else
116  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
117 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
118  ~(sizeof (long) - 1))
119 # endif
120 # endif
121 
122 # ifndef CMSG_SPACE
123 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
124  CMSG_ALIGN (len))
125 # endif
126 
127 # ifndef CMSG_LEN
128 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
129 # endif
130 
131 #endif /* Solaris */
132 
133 static dbus_bool_t
134 _dbus_open_socket (int *fd_p,
135  int domain,
136  int type,
137  int protocol,
138  DBusError *error)
139 {
140 #ifdef SOCK_CLOEXEC
141  dbus_bool_t cloexec_done;
142 
143  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
144  cloexec_done = *fd_p >= 0;
145 
146  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
147  if (*fd_p < 0 && errno == EINVAL)
148 #endif
149  {
150  *fd_p = socket (domain, type, protocol);
151  }
152 
153  if (*fd_p >= 0)
154  {
155 #ifdef SOCK_CLOEXEC
156  if (!cloexec_done)
157 #endif
158  {
160  }
161 
162  _dbus_verbose ("socket fd %d opened\n", *fd_p);
163  return TRUE;
164  }
165  else
166  {
167  dbus_set_error(error,
168  _dbus_error_from_errno (errno),
169  "Failed to open socket: %s",
170  _dbus_strerror (errno));
171  return FALSE;
172  }
173 }
174 
185 static dbus_bool_t
186 _dbus_open_unix_socket (int *fd,
187  DBusError *error)
188 {
189  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
190 }
191 
202  DBusError *error)
203 {
204  return _dbus_close (fd, error);
205 }
206 
216 int
218  DBusString *buffer,
219  int count)
220 {
221  return _dbus_read (fd, buffer, count);
222 }
223 
234 int
236  const DBusString *buffer,
237  int start,
238  int len)
239 {
240 #if HAVE_DECL_MSG_NOSIGNAL
241  const char *data;
242  int bytes_written;
243 
244  data = _dbus_string_get_const_data_len (buffer, start, len);
245 
246  again:
247 
248  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
249 
250  if (bytes_written < 0 && errno == EINTR)
251  goto again;
252 
253  return bytes_written;
254 
255 #else
256  return _dbus_write (fd, buffer, start, len);
257 #endif
258 }
259 
272 int
274  DBusString *buffer,
275  int count,
276  int *fds,
277  int *n_fds) {
278 #ifndef HAVE_UNIX_FD_PASSING
279  int r;
280 
281  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
282  return r;
283 
284  *n_fds = 0;
285  return r;
286 
287 #else
288  int bytes_read;
289  int start;
290  struct msghdr m;
291  struct iovec iov;
292 
293  _dbus_assert (count >= 0);
294  _dbus_assert (*n_fds >= 0);
295 
296  start = _dbus_string_get_length (buffer);
297 
298  if (!_dbus_string_lengthen (buffer, count))
299  {
300  errno = ENOMEM;
301  return -1;
302  }
303 
304  _DBUS_ZERO(iov);
305  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
306  iov.iov_len = count;
307 
308  _DBUS_ZERO(m);
309  m.msg_iov = &iov;
310  m.msg_iovlen = 1;
311 
312  /* Hmm, we have no clue how long the control data will actually be
313  that is queued for us. The least we can do is assume that the
314  caller knows. Hence let's make space for the number of fds that
315  we shall read at max plus the cmsg header. */
316  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
317 
318  /* It's probably safe to assume that systems with SCM_RIGHTS also
319  know alloca() */
320  m.msg_control = alloca(m.msg_controllen);
321  memset(m.msg_control, 0, m.msg_controllen);
322 
323  again:
324 
325  bytes_read = recvmsg(fd, &m, 0
326 #ifdef MSG_CMSG_CLOEXEC
327  |MSG_CMSG_CLOEXEC
328 #endif
329  );
330 
331  if (bytes_read < 0)
332  {
333  if (errno == EINTR)
334  goto again;
335  else
336  {
337  /* put length back (note that this doesn't actually realloc anything) */
338  _dbus_string_set_length (buffer, start);
339  return -1;
340  }
341  }
342  else
343  {
344  struct cmsghdr *cm;
345  dbus_bool_t found = FALSE;
346 
347  if (m.msg_flags & MSG_CTRUNC)
348  {
349  /* Hmm, apparently the control data was truncated. The bad
350  thing is that we might have completely lost a couple of fds
351  without chance to recover them. Hence let's treat this as a
352  serious error. */
353 
354  errno = ENOSPC;
355  _dbus_string_set_length (buffer, start);
356  return -1;
357  }
358 
359  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
360  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
361  {
362  unsigned i;
363 
364  _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
365  *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
366 
367  memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
368  found = TRUE;
369 
370  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
371  worked, hence we need to go through this list and set
372  CLOEXEC everywhere in any case */
373  for (i = 0; i < *n_fds; i++)
375 
376  break;
377  }
378 
379  if (!found)
380  *n_fds = 0;
381 
382  /* put length back (doesn't actually realloc) */
383  _dbus_string_set_length (buffer, start + bytes_read);
384 
385 #if 0
386  if (bytes_read > 0)
387  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
388 #endif
389 
390  return bytes_read;
391  }
392 #endif
393 }
394 
395 int
396 _dbus_write_socket_with_unix_fds(int fd,
397  const DBusString *buffer,
398  int start,
399  int len,
400  const int *fds,
401  int n_fds) {
402 
403 #ifndef HAVE_UNIX_FD_PASSING
404 
405  if (n_fds > 0) {
406  errno = ENOTSUP;
407  return -1;
408  }
409 
410  return _dbus_write_socket(fd, buffer, start, len);
411 #else
412  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
413 #endif
414 }
415 
416 int
417 _dbus_write_socket_with_unix_fds_two(int fd,
418  const DBusString *buffer1,
419  int start1,
420  int len1,
421  const DBusString *buffer2,
422  int start2,
423  int len2,
424  const int *fds,
425  int n_fds) {
426 
427 #ifndef HAVE_UNIX_FD_PASSING
428 
429  if (n_fds > 0) {
430  errno = ENOTSUP;
431  return -1;
432  }
433 
434  return _dbus_write_socket_two(fd,
435  buffer1, start1, len1,
436  buffer2, start2, len2);
437 #else
438 
439  struct msghdr m;
440  struct cmsghdr *cm;
441  struct iovec iov[2];
442  int bytes_written;
443 
444  _dbus_assert (len1 >= 0);
445  _dbus_assert (len2 >= 0);
446  _dbus_assert (n_fds >= 0);
447 
448  _DBUS_ZERO(iov);
449  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
450  iov[0].iov_len = len1;
451 
452  if (buffer2)
453  {
454  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
455  iov[1].iov_len = len2;
456  }
457 
458  _DBUS_ZERO(m);
459  m.msg_iov = iov;
460  m.msg_iovlen = buffer2 ? 2 : 1;
461 
462  if (n_fds > 0)
463  {
464  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
465  m.msg_control = alloca(m.msg_controllen);
466  memset(m.msg_control, 0, m.msg_controllen);
467 
468  cm = CMSG_FIRSTHDR(&m);
469  cm->cmsg_level = SOL_SOCKET;
470  cm->cmsg_type = SCM_RIGHTS;
471  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
472  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
473  }
474 
475  again:
476 
477  bytes_written = sendmsg (fd, &m, 0
478 #if HAVE_DECL_MSG_NOSIGNAL
479  |MSG_NOSIGNAL
480 #endif
481  );
482 
483  if (bytes_written < 0 && errno == EINTR)
484  goto again;
485 
486 #if 0
487  if (bytes_written > 0)
488  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
489 #endif
490 
491  return bytes_written;
492 #endif
493 }
494 
508 int
510  const DBusString *buffer1,
511  int start1,
512  int len1,
513  const DBusString *buffer2,
514  int start2,
515  int len2)
516 {
517 #if HAVE_DECL_MSG_NOSIGNAL
518  struct iovec vectors[2];
519  const char *data1;
520  const char *data2;
521  int bytes_written;
522  struct msghdr m;
523 
524  _dbus_assert (buffer1 != NULL);
525  _dbus_assert (start1 >= 0);
526  _dbus_assert (start2 >= 0);
527  _dbus_assert (len1 >= 0);
528  _dbus_assert (len2 >= 0);
529 
530  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
531 
532  if (buffer2 != NULL)
533  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
534  else
535  {
536  data2 = NULL;
537  start2 = 0;
538  len2 = 0;
539  }
540 
541  vectors[0].iov_base = (char*) data1;
542  vectors[0].iov_len = len1;
543  vectors[1].iov_base = (char*) data2;
544  vectors[1].iov_len = len2;
545 
546  _DBUS_ZERO(m);
547  m.msg_iov = vectors;
548  m.msg_iovlen = data2 ? 2 : 1;
549 
550  again:
551 
552  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
553 
554  if (bytes_written < 0 && errno == EINTR)
555  goto again;
556 
557  return bytes_written;
558 
559 #else
560  return _dbus_write_two (fd, buffer1, start1, len1,
561  buffer2, start2, len2);
562 #endif
563 }
564 
566 _dbus_socket_is_invalid (int fd)
567 {
568  return fd < 0 ? TRUE : FALSE;
569 }
570 
587 int
588 _dbus_read (int fd,
589  DBusString *buffer,
590  int count)
591 {
592  int bytes_read;
593  int start;
594  char *data;
595 
596  _dbus_assert (count >= 0);
597 
598  start = _dbus_string_get_length (buffer);
599 
600  if (!_dbus_string_lengthen (buffer, count))
601  {
602  errno = ENOMEM;
603  return -1;
604  }
605 
606  data = _dbus_string_get_data_len (buffer, start, count);
607 
608  again:
609 
610  bytes_read = read (fd, data, count);
611 
612  if (bytes_read < 0)
613  {
614  if (errno == EINTR)
615  goto again;
616  else
617  {
618  /* put length back (note that this doesn't actually realloc anything) */
619  _dbus_string_set_length (buffer, start);
620  return -1;
621  }
622  }
623  else
624  {
625  /* put length back (doesn't actually realloc) */
626  _dbus_string_set_length (buffer, start + bytes_read);
627 
628 #if 0
629  if (bytes_read > 0)
630  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
631 #endif
632 
633  return bytes_read;
634  }
635 }
636 
647 int
648 _dbus_write (int fd,
649  const DBusString *buffer,
650  int start,
651  int len)
652 {
653  const char *data;
654  int bytes_written;
655 
656  data = _dbus_string_get_const_data_len (buffer, start, len);
657 
658  again:
659 
660  bytes_written = write (fd, data, len);
661 
662  if (bytes_written < 0 && errno == EINTR)
663  goto again;
664 
665 #if 0
666  if (bytes_written > 0)
667  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
668 #endif
669 
670  return bytes_written;
671 }
672 
693 int
695  const DBusString *buffer1,
696  int start1,
697  int len1,
698  const DBusString *buffer2,
699  int start2,
700  int len2)
701 {
702  _dbus_assert (buffer1 != NULL);
703  _dbus_assert (start1 >= 0);
704  _dbus_assert (start2 >= 0);
705  _dbus_assert (len1 >= 0);
706  _dbus_assert (len2 >= 0);
707 
708 #ifdef HAVE_WRITEV
709  {
710  struct iovec vectors[2];
711  const char *data1;
712  const char *data2;
713  int bytes_written;
714 
715  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
716 
717  if (buffer2 != NULL)
718  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
719  else
720  {
721  data2 = NULL;
722  start2 = 0;
723  len2 = 0;
724  }
725 
726  vectors[0].iov_base = (char*) data1;
727  vectors[0].iov_len = len1;
728  vectors[1].iov_base = (char*) data2;
729  vectors[1].iov_len = len2;
730 
731  again:
732 
733  bytes_written = writev (fd,
734  vectors,
735  data2 ? 2 : 1);
736 
737  if (bytes_written < 0 && errno == EINTR)
738  goto again;
739 
740  return bytes_written;
741  }
742 #else /* HAVE_WRITEV */
743  {
744  int ret1;
745 
746  ret1 = _dbus_write (fd, buffer1, start1, len1);
747  if (ret1 == len1 && buffer2 != NULL)
748  {
749  ret2 = _dbus_write (fd, buffer2, start2, len2);
750  if (ret2 < 0)
751  ret2 = 0; /* we can't report an error as the first write was OK */
752 
753  return ret1 + ret2;
754  }
755  else
756  return ret1;
757  }
758 #endif /* !HAVE_WRITEV */
759 }
760 
761 #define _DBUS_MAX_SUN_PATH_LENGTH 99
762 
792 int
793 _dbus_connect_unix_socket (const char *path,
794  dbus_bool_t abstract,
795  DBusError *error)
796 {
797  int fd;
798  size_t path_len;
799  struct sockaddr_un addr;
800 
801  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
802 
803  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
804  path, abstract);
805 
806 
807  if (!_dbus_open_unix_socket (&fd, error))
808  {
809  _DBUS_ASSERT_ERROR_IS_SET(error);
810  return -1;
811  }
812  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
813 
814  _DBUS_ZERO (addr);
815  addr.sun_family = AF_UNIX;
816  path_len = strlen (path);
817 
818  if (abstract)
819  {
820 #ifdef HAVE_ABSTRACT_SOCKETS
821  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
822  path_len++; /* Account for the extra nul byte added to the start of sun_path */
823 
824  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
825  {
827  "Abstract socket name too long\n");
828  _dbus_close (fd, NULL);
829  return -1;
830  }
831 
832  strncpy (&addr.sun_path[1], path, path_len);
833  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
834 #else /* HAVE_ABSTRACT_SOCKETS */
836  "Operating system does not support abstract socket namespace\n");
837  _dbus_close (fd, NULL);
838  return -1;
839 #endif /* ! HAVE_ABSTRACT_SOCKETS */
840  }
841  else
842  {
843  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
844  {
846  "Socket name too long\n");
847  _dbus_close (fd, NULL);
848  return -1;
849  }
850 
851  strncpy (addr.sun_path, path, path_len);
852  }
853 
854  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
855  {
856  dbus_set_error (error,
857  _dbus_error_from_errno (errno),
858  "Failed to connect to socket %s: %s",
859  path, _dbus_strerror (errno));
860 
861  _dbus_close (fd, NULL);
862  return -1;
863  }
864 
865  if (!_dbus_set_fd_nonblocking (fd, error))
866  {
867  _DBUS_ASSERT_ERROR_IS_SET (error);
868 
869  _dbus_close (fd, NULL);
870  return -1;
871  }
872 
873  return fd;
874 }
875 
888 int
889 _dbus_connect_exec (const char *path,
890  char *const argv[],
891  DBusError *error)
892 {
893  int fds[2];
894  pid_t pid;
895 
896  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
897 
898  _dbus_verbose ("connecting to process %s\n", path);
899 
900  if (socketpair (AF_UNIX, SOCK_STREAM
901 #ifdef SOCK_CLOEXEC
902  |SOCK_CLOEXEC
903 #endif
904  , 0, fds) < 0)
905  {
906  dbus_set_error (error,
907  _dbus_error_from_errno (errno),
908  "Failed to create socket pair: %s",
909  _dbus_strerror (errno));
910  return -1;
911  }
912 
915 
916  pid = fork ();
917  if (pid < 0)
918  {
919  dbus_set_error (error,
920  _dbus_error_from_errno (errno),
921  "Failed to fork() to call %s: %s",
922  path, _dbus_strerror (errno));
923  close (fds[0]);
924  close (fds[1]);
925  return -1;
926  }
927 
928  if (pid == 0)
929  {
930  /* child */
931  close (fds[0]);
932 
933  dup2 (fds[1], STDIN_FILENO);
934  dup2 (fds[1], STDOUT_FILENO);
935 
936  if (fds[1] != STDIN_FILENO &&
937  fds[1] != STDOUT_FILENO)
938  close (fds[1]);
939 
940  /* Inherit STDERR and the controlling terminal from the
941  parent */
942 
943  _dbus_close_all ();
944 
945  execvp (path, argv);
946 
947  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
948 
949  _exit(1);
950  }
951 
952  /* parent */
953  close (fds[1]);
954 
955  if (!_dbus_set_fd_nonblocking (fds[0], error))
956  {
957  _DBUS_ASSERT_ERROR_IS_SET (error);
958 
959  close (fds[0]);
960  return -1;
961  }
962 
963  return fds[0];
964 }
965 
975 static dbus_bool_t
976 _dbus_set_local_creds (int fd, dbus_bool_t on)
977 {
978  dbus_bool_t retval = TRUE;
979 
980 #if defined(HAVE_CMSGCRED)
981  /* NOOP just to make sure only one codepath is used
982  * and to prefer CMSGCRED
983  */
984 #elif defined(LOCAL_CREDS)
985  int val = on ? 1 : 0;
986  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
987  {
988  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
989  retval = FALSE;
990  }
991  else
992  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
993  on ? "enabled" : "disabled", fd);
994 #endif
995 
996  return retval;
997 }
998 
1016 int
1017 _dbus_listen_unix_socket (const char *path,
1018  dbus_bool_t abstract,
1019  DBusError *error)
1020 {
1021  int listen_fd;
1022  struct sockaddr_un addr;
1023  size_t path_len;
1024  unsigned int reuseaddr;
1025 
1026  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1027 
1028  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1029  path, abstract);
1030 
1031  if (!_dbus_open_unix_socket (&listen_fd, error))
1032  {
1033  _DBUS_ASSERT_ERROR_IS_SET(error);
1034  return -1;
1035  }
1036  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1037 
1038  _DBUS_ZERO (addr);
1039  addr.sun_family = AF_UNIX;
1040  path_len = strlen (path);
1041 
1042  if (abstract)
1043  {
1044 #ifdef HAVE_ABSTRACT_SOCKETS
1045  /* remember that abstract names aren't nul-terminated so we rely
1046  * on sun_path being filled in with zeroes above.
1047  */
1048  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1049  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1050 
1051  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1052  {
1054  "Abstract socket name too long\n");
1055  _dbus_close (listen_fd, NULL);
1056  return -1;
1057  }
1058 
1059  strncpy (&addr.sun_path[1], path, path_len);
1060  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1061 #else /* HAVE_ABSTRACT_SOCKETS */
1063  "Operating system does not support abstract socket namespace\n");
1064  _dbus_close (listen_fd, NULL);
1065  return -1;
1066 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1067  }
1068  else
1069  {
1070  /* Discussed security implications of this with Nalin,
1071  * and we couldn't think of where it would kick our ass, but
1072  * it still seems a bit sucky. It also has non-security suckage;
1073  * really we'd prefer to exit if the socket is already in use.
1074  * But there doesn't seem to be a good way to do this.
1075  *
1076  * Just to be extra careful, I threw in the stat() - clearly
1077  * the stat() can't *fix* any security issue, but it at least
1078  * avoids inadvertent/accidental data loss.
1079  */
1080  {
1081  struct stat sb;
1082 
1083  if (stat (path, &sb) == 0 &&
1084  S_ISSOCK (sb.st_mode))
1085  unlink (path);
1086  }
1087 
1088  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1089  {
1091  "Abstract socket name too long\n");
1092  _dbus_close (listen_fd, NULL);
1093  return -1;
1094  }
1095 
1096  strncpy (addr.sun_path, path, path_len);
1097  }
1098 
1099  reuseaddr = 1;
1100  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1101  {
1102  _dbus_warn ("Failed to set socket option\"%s\": %s",
1103  path, _dbus_strerror (errno));
1104  }
1105 
1106  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1107  {
1108  dbus_set_error (error, _dbus_error_from_errno (errno),
1109  "Failed to bind socket \"%s\": %s",
1110  path, _dbus_strerror (errno));
1111  _dbus_close (listen_fd, NULL);
1112  return -1;
1113  }
1114 
1115  if (listen (listen_fd, 30 /* backlog */) < 0)
1116  {
1117  dbus_set_error (error, _dbus_error_from_errno (errno),
1118  "Failed to listen on socket \"%s\": %s",
1119  path, _dbus_strerror (errno));
1120  _dbus_close (listen_fd, NULL);
1121  return -1;
1122  }
1123 
1124  if (!_dbus_set_local_creds (listen_fd, TRUE))
1125  {
1126  dbus_set_error (error, _dbus_error_from_errno (errno),
1127  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1128  path, _dbus_strerror (errno));
1129  close (listen_fd);
1130  return -1;
1131  }
1132 
1133  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1134  {
1135  _DBUS_ASSERT_ERROR_IS_SET (error);
1136  _dbus_close (listen_fd, NULL);
1137  return -1;
1138  }
1139 
1140  /* Try opening up the permissions, but if we can't, just go ahead
1141  * and continue, maybe it will be good enough.
1142  */
1143  if (!abstract && chmod (path, 0777) < 0)
1144  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1145  path);
1146 
1147  return listen_fd;
1148 }
1149 
1160 int
1162  DBusError *error)
1163 {
1164  int r, n;
1165  unsigned fd;
1166  int *new_fds;
1167 
1168  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1169 
1170  n = sd_listen_fds (TRUE);
1171  if (n < 0)
1172  {
1174  "Failed to acquire systemd socket: %s",
1175  _dbus_strerror (-n));
1176  return -1;
1177  }
1178 
1179  if (n <= 0)
1180  {
1182  "No socket received.");
1183  return -1;
1184  }
1185 
1186  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1187  {
1188  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1189  if (r < 0)
1190  {
1192  "Failed to verify systemd socket type: %s",
1193  _dbus_strerror (-r));
1194  return -1;
1195  }
1196 
1197  if (!r)
1198  {
1200  "Passed socket has wrong type.");
1201  return -1;
1202  }
1203  }
1204 
1205  /* OK, the file descriptors are all good, so let's take posession of
1206  them then. */
1207 
1208  new_fds = dbus_new (int, n);
1209  if (!new_fds)
1210  {
1212  "Failed to allocate file handle array.");
1213  goto fail;
1214  }
1215 
1216  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1217  {
1218  if (!_dbus_set_local_creds (fd, TRUE))
1219  {
1220  dbus_set_error (error, _dbus_error_from_errno (errno),
1221  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1222  _dbus_strerror (errno));
1223  goto fail;
1224  }
1225 
1226  if (!_dbus_set_fd_nonblocking (fd, error))
1227  {
1228  _DBUS_ASSERT_ERROR_IS_SET (error);
1229  goto fail;
1230  }
1231 
1232  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1233  }
1234 
1235  *fds = new_fds;
1236  return n;
1237 
1238  fail:
1239 
1240  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1241  {
1242  _dbus_close (fd, NULL);
1243  }
1244 
1245  dbus_free (new_fds);
1246  return -1;
1247 }
1248 
1262 int
1263 _dbus_connect_tcp_socket (const char *host,
1264  const char *port,
1265  const char *family,
1266  DBusError *error)
1267 {
1268  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1269 }
1270 
1271 int
1272 _dbus_connect_tcp_socket_with_nonce (const char *host,
1273  const char *port,
1274  const char *family,
1275  const char *noncefile,
1276  DBusError *error)
1277 {
1278  int saved_errno = 0;
1279  int fd = -1, res;
1280  struct addrinfo hints;
1281  struct addrinfo *ai, *tmp;
1282 
1283  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1284 
1285  _DBUS_ZERO (hints);
1286 
1287  if (!family)
1288  hints.ai_family = AF_UNSPEC;
1289  else if (!strcmp(family, "ipv4"))
1290  hints.ai_family = AF_INET;
1291  else if (!strcmp(family, "ipv6"))
1292  hints.ai_family = AF_INET6;
1293  else
1294  {
1295  dbus_set_error (error,
1297  "Unknown address family %s", family);
1298  return -1;
1299  }
1300  hints.ai_protocol = IPPROTO_TCP;
1301  hints.ai_socktype = SOCK_STREAM;
1302  hints.ai_flags = AI_ADDRCONFIG;
1303 
1304  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1305  {
1306  dbus_set_error (error,
1307  _dbus_error_from_errno (errno),
1308  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1309  host, port, gai_strerror(res), res);
1310  return -1;
1311  }
1312 
1313  tmp = ai;
1314  while (tmp)
1315  {
1316  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1317  {
1318  freeaddrinfo(ai);
1319  _DBUS_ASSERT_ERROR_IS_SET(error);
1320  return -1;
1321  }
1322  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1323 
1324  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1325  {
1326  saved_errno = errno;
1327  _dbus_close(fd, NULL);
1328  fd = -1;
1329  tmp = tmp->ai_next;
1330  continue;
1331  }
1332 
1333  break;
1334  }
1335  freeaddrinfo(ai);
1336 
1337  if (fd == -1)
1338  {
1339  dbus_set_error (error,
1340  _dbus_error_from_errno (saved_errno),
1341  "Failed to connect to socket \"%s:%s\" %s",
1342  host, port, _dbus_strerror(saved_errno));
1343  return -1;
1344  }
1345 
1346  if (noncefile != NULL)
1347  {
1348  DBusString noncefileStr;
1349  dbus_bool_t ret;
1350  _dbus_string_init_const (&noncefileStr, noncefile);
1351  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1352  _dbus_string_free (&noncefileStr);
1353 
1354  if (!ret)
1355  {
1356  _dbus_close (fd, NULL);
1357  return -1;
1358  }
1359  }
1360 
1361  if (!_dbus_set_fd_nonblocking (fd, error))
1362  {
1363  _dbus_close (fd, NULL);
1364  return -1;
1365  }
1366 
1367  return fd;
1368 }
1369 
1386 int
1387 _dbus_listen_tcp_socket (const char *host,
1388  const char *port,
1389  const char *family,
1390  DBusString *retport,
1391  int **fds_p,
1392  DBusError *error)
1393 {
1394  int saved_errno;
1395  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1396  struct addrinfo hints;
1397  struct addrinfo *ai, *tmp;
1398  unsigned int reuseaddr;
1399 
1400  *fds_p = NULL;
1401  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1402 
1403  _DBUS_ZERO (hints);
1404 
1405  if (!family)
1406  hints.ai_family = AF_UNSPEC;
1407  else if (!strcmp(family, "ipv4"))
1408  hints.ai_family = AF_INET;
1409  else if (!strcmp(family, "ipv6"))
1410  hints.ai_family = AF_INET6;
1411  else
1412  {
1413  dbus_set_error (error,
1415  "Unknown address family %s", family);
1416  return -1;
1417  }
1418 
1419  hints.ai_protocol = IPPROTO_TCP;
1420  hints.ai_socktype = SOCK_STREAM;
1421  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1422 
1423  redo_lookup_with_port:
1424  ai = NULL;
1425  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1426  {
1427  dbus_set_error (error,
1428  _dbus_error_from_errno (errno),
1429  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1430  host ? host : "*", port, gai_strerror(res), res);
1431  goto failed;
1432  }
1433 
1434  tmp = ai;
1435  while (tmp)
1436  {
1437  int fd = -1, *newlisten_fd;
1438  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1439  {
1440  _DBUS_ASSERT_ERROR_IS_SET(error);
1441  goto failed;
1442  }
1443  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1444 
1445  reuseaddr = 1;
1446  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1447  {
1448  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1449  host ? host : "*", port, _dbus_strerror (errno));
1450  }
1451 
1452  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1453  {
1454  saved_errno = errno;
1455  _dbus_close(fd, NULL);
1456  if (saved_errno == EADDRINUSE)
1457  {
1458  /* Depending on kernel policy, it may or may not
1459  be neccessary to bind to both IPv4 & 6 addresses
1460  so ignore EADDRINUSE here */
1461  tmp = tmp->ai_next;
1462  continue;
1463  }
1464  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1465  "Failed to bind socket \"%s:%s\": %s",
1466  host ? host : "*", port, _dbus_strerror (saved_errno));
1467  goto failed;
1468  }
1469 
1470  if (listen (fd, 30 /* backlog */) < 0)
1471  {
1472  saved_errno = errno;
1473  _dbus_close (fd, NULL);
1474  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1475  "Failed to listen on socket \"%s:%s\": %s",
1476  host ? host : "*", port, _dbus_strerror (saved_errno));
1477  goto failed;
1478  }
1479 
1480  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1481  if (!newlisten_fd)
1482  {
1483  saved_errno = errno;
1484  _dbus_close (fd, NULL);
1485  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1486  "Failed to allocate file handle array: %s",
1487  _dbus_strerror (saved_errno));
1488  goto failed;
1489  }
1490  listen_fd = newlisten_fd;
1491  listen_fd[nlisten_fd] = fd;
1492  nlisten_fd++;
1493 
1494  if (!_dbus_string_get_length(retport))
1495  {
1496  /* If the user didn't specify a port, or used 0, then
1497  the kernel chooses a port. After the first address
1498  is bound to, we need to force all remaining addresses
1499  to use the same port */
1500  if (!port || !strcmp(port, "0"))
1501  {
1502  int result;
1503  struct sockaddr_storage addr;
1504  socklen_t addrlen;
1505  char portbuf[50];
1506 
1507  addrlen = sizeof(addr);
1508  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1509 
1510  if (result == -1 ||
1511  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1512  portbuf, sizeof(portbuf),
1513  NI_NUMERICHOST)) != 0)
1514  {
1515  dbus_set_error (error, _dbus_error_from_errno (errno),
1516  "Failed to resolve port \"%s:%s\": %s (%s)",
1517  host ? host : "*", port, gai_strerror(res), res);
1518  goto failed;
1519  }
1520  if (!_dbus_string_append(retport, portbuf))
1521  {
1523  goto failed;
1524  }
1525 
1526  /* Release current address list & redo lookup */
1527  port = _dbus_string_get_const_data(retport);
1528  freeaddrinfo(ai);
1529  goto redo_lookup_with_port;
1530  }
1531  else
1532  {
1533  if (!_dbus_string_append(retport, port))
1534  {
1536  goto failed;
1537  }
1538  }
1539  }
1540 
1541  tmp = tmp->ai_next;
1542  }
1543  freeaddrinfo(ai);
1544  ai = NULL;
1545 
1546  if (!nlisten_fd)
1547  {
1548  errno = EADDRINUSE;
1549  dbus_set_error (error, _dbus_error_from_errno (errno),
1550  "Failed to bind socket \"%s:%s\": %s",
1551  host ? host : "*", port, _dbus_strerror (errno));
1552  goto failed;
1553  }
1554 
1555  for (i = 0 ; i < nlisten_fd ; i++)
1556  {
1557  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1558  {
1559  goto failed;
1560  }
1561  }
1562 
1563  *fds_p = listen_fd;
1564 
1565  return nlisten_fd;
1566 
1567  failed:
1568  if (ai)
1569  freeaddrinfo(ai);
1570  for (i = 0 ; i < nlisten_fd ; i++)
1571  _dbus_close(listen_fd[i], NULL);
1572  dbus_free(listen_fd);
1573  return -1;
1574 }
1575 
1576 static dbus_bool_t
1577 write_credentials_byte (int server_fd,
1578  DBusError *error)
1579 {
1580  int bytes_written;
1581  char buf[1] = { '\0' };
1582 #if defined(HAVE_CMSGCRED)
1583  union {
1584  struct cmsghdr hdr;
1585  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1586  } cmsg;
1587  struct iovec iov;
1588  struct msghdr msg;
1589  iov.iov_base = buf;
1590  iov.iov_len = 1;
1591 
1592  _DBUS_ZERO(msg);
1593  msg.msg_iov = &iov;
1594  msg.msg_iovlen = 1;
1595 
1596  msg.msg_control = (caddr_t) &cmsg;
1597  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1598  _DBUS_ZERO(cmsg);
1599  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1600  cmsg.hdr.cmsg_level = SOL_SOCKET;
1601  cmsg.hdr.cmsg_type = SCM_CREDS;
1602 #endif
1603 
1604  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1605 
1606  again:
1607 
1608 #if defined(HAVE_CMSGCRED)
1609  bytes_written = sendmsg (server_fd, &msg, 0
1610 #if HAVE_DECL_MSG_NOSIGNAL
1611  |MSG_NOSIGNAL
1612 #endif
1613  );
1614 #else
1615  bytes_written = send (server_fd, buf, 1, 0
1616 #if HAVE_DECL_MSG_NOSIGNAL
1617  |MSG_NOSIGNAL
1618 #endif
1619  );
1620 #endif
1621 
1622  if (bytes_written < 0 && errno == EINTR)
1623  goto again;
1624 
1625  if (bytes_written < 0)
1626  {
1627  dbus_set_error (error, _dbus_error_from_errno (errno),
1628  "Failed to write credentials byte: %s",
1629  _dbus_strerror (errno));
1630  return FALSE;
1631  }
1632  else if (bytes_written == 0)
1633  {
1635  "wrote zero bytes writing credentials byte");
1636  return FALSE;
1637  }
1638  else
1639  {
1640  _dbus_assert (bytes_written == 1);
1641  _dbus_verbose ("wrote credentials byte\n");
1642  return TRUE;
1643  }
1644 }
1645 
1669  DBusCredentials *credentials,
1670  DBusError *error)
1671 {
1672  struct msghdr msg;
1673  struct iovec iov;
1674  char buf;
1675  dbus_uid_t uid_read;
1676  dbus_pid_t pid_read;
1677  int bytes_read;
1678 
1679 #ifdef HAVE_CMSGCRED
1680  union {
1681  struct cmsghdr hdr;
1682  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1683  } cmsg;
1684 
1685 #elif defined(LOCAL_CREDS)
1686  struct {
1687  struct cmsghdr hdr;
1688  struct sockcred cred;
1689  } cmsg;
1690 #endif
1691 
1692  uid_read = DBUS_UID_UNSET;
1693  pid_read = DBUS_PID_UNSET;
1694 
1695  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1696 
1697  /* The POSIX spec certainly doesn't promise this, but
1698  * we need these assertions to fail as soon as we're wrong about
1699  * it so we can do the porting fixups
1700  */
1701  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1702  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1703  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1704 
1705  _dbus_credentials_clear (credentials);
1706 
1707  /* Systems supporting LOCAL_CREDS are configured to have this feature
1708  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1709  * the connection. Therefore, the received message must carry the
1710  * credentials information without doing anything special.
1711  */
1712 
1713  iov.iov_base = &buf;
1714  iov.iov_len = 1;
1715 
1716  _DBUS_ZERO(msg);
1717  msg.msg_iov = &iov;
1718  msg.msg_iovlen = 1;
1719 
1720 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1721  _DBUS_ZERO(cmsg);
1722  msg.msg_control = (caddr_t) &cmsg;
1723  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1724 #endif
1725 
1726  again:
1727  bytes_read = recvmsg (client_fd, &msg, 0);
1728 
1729  if (bytes_read < 0)
1730  {
1731  if (errno == EINTR)
1732  goto again;
1733 
1734  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1735  * normally only call read_credentials if the socket was ready
1736  * for reading
1737  */
1738 
1739  dbus_set_error (error, _dbus_error_from_errno (errno),
1740  "Failed to read credentials byte: %s",
1741  _dbus_strerror (errno));
1742  return FALSE;
1743  }
1744  else if (bytes_read == 0)
1745  {
1746  /* this should not happen unless we are using recvmsg wrong,
1747  * so is essentially here for paranoia
1748  */
1750  "Failed to read credentials byte (zero-length read)");
1751  return FALSE;
1752  }
1753  else if (buf != '\0')
1754  {
1756  "Credentials byte was not nul");
1757  return FALSE;
1758  }
1759 
1760 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1761  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1762  || cmsg.hdr.cmsg_type != SCM_CREDS)
1763  {
1765  "Message from recvmsg() was not SCM_CREDS");
1766  return FALSE;
1767  }
1768 #endif
1769 
1770  _dbus_verbose ("read credentials byte\n");
1771 
1772  {
1773 #ifdef SO_PEERCRED
1774 #ifdef __OpenBSD__
1775  struct sockpeercred cr;
1776 #else
1777  struct ucred cr;
1778 #endif
1779  int cr_len = sizeof (cr);
1780 
1781  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1782  cr_len == sizeof (cr))
1783  {
1784  pid_read = cr.pid;
1785  uid_read = cr.uid;
1786  }
1787  else
1788  {
1789  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1790  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1791  }
1792 #elif defined(HAVE_CMSGCRED)
1793  struct cmsgcred *cred;
1794 
1795  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1796  pid_read = cred->cmcred_pid;
1797  uid_read = cred->cmcred_euid;
1798 #elif defined(LOCAL_CREDS)
1799  pid_read = DBUS_PID_UNSET;
1800  uid_read = cmsg.cred.sc_uid;
1801  /* Since we have already got the credentials from this socket, we can
1802  * disable its LOCAL_CREDS flag if it was ever set. */
1803  _dbus_set_local_creds (client_fd, FALSE);
1804 #elif defined(HAVE_GETPEEREID)
1805  uid_t euid;
1806  gid_t egid;
1807  if (getpeereid (client_fd, &euid, &egid) == 0)
1808  {
1809  uid_read = euid;
1810  }
1811  else
1812  {
1813  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1814  }
1815 #elif defined(HAVE_GETPEERUCRED)
1816  ucred_t * ucred = NULL;
1817  if (getpeerucred (client_fd, &ucred) == 0)
1818  {
1819  pid_read = ucred_getpid (ucred);
1820  uid_read = ucred_geteuid (ucred);
1821 #ifdef HAVE_ADT
1822  /* generate audit session data based on socket ucred */
1823  adt_session_data_t *adth = NULL;
1824  adt_export_data_t *data = NULL;
1825  size_t size = 0;
1826  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1827  {
1828  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1829  }
1830  else
1831  {
1832  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1833  {
1834  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1835  }
1836  else
1837  {
1838  size = adt_export_session_data (adth, &data);
1839  if (size <= 0)
1840  {
1841  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1842  }
1843  else
1844  {
1845  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1846  free (data);
1847  }
1848  }
1849  (void) adt_end_session (adth);
1850  }
1851 #endif /* HAVE_ADT */
1852  }
1853  else
1854  {
1855  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1856  }
1857  if (ucred != NULL)
1858  ucred_free (ucred);
1859 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1860  _dbus_verbose ("Socket credentials not supported on this OS\n");
1861 #endif
1862  }
1863 
1864  _dbus_verbose ("Credentials:"
1865  " pid "DBUS_PID_FORMAT
1866  " uid "DBUS_UID_FORMAT
1867  "\n",
1868  pid_read,
1869  uid_read);
1870 
1871  if (pid_read != DBUS_PID_UNSET)
1872  {
1873  if (!_dbus_credentials_add_pid (credentials, pid_read))
1874  {
1875  _DBUS_SET_OOM (error);
1876  return FALSE;
1877  }
1878  }
1879 
1880  if (uid_read != DBUS_UID_UNSET)
1881  {
1882  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1883  {
1884  _DBUS_SET_OOM (error);
1885  return FALSE;
1886  }
1887  }
1888 
1889  return TRUE;
1890 }
1891 
1911  DBusError *error)
1912 {
1913  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1914 
1915  if (write_credentials_byte (server_fd, error))
1916  return TRUE;
1917  else
1918  return FALSE;
1919 }
1920 
1930 int
1931 _dbus_accept (int listen_fd)
1932 {
1933  int client_fd;
1934  struct sockaddr addr;
1935  socklen_t addrlen;
1936 #ifdef HAVE_ACCEPT4
1937  dbus_bool_t cloexec_done;
1938 #endif
1939 
1940  addrlen = sizeof (addr);
1941 
1942  retry:
1943 
1944 #ifdef HAVE_ACCEPT4
1945  /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1946  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1947  cloexec_done = client_fd >= 0;
1948 
1949  if (client_fd < 0 && errno == ENOSYS)
1950 #endif
1951  {
1952  client_fd = accept (listen_fd, &addr, &addrlen);
1953  }
1954 
1955  if (client_fd < 0)
1956  {
1957  if (errno == EINTR)
1958  goto retry;
1959  }
1960 
1961  _dbus_verbose ("client fd %d accepted\n", client_fd);
1962 
1963 #ifdef HAVE_ACCEPT4
1964  if (!cloexec_done)
1965 #endif
1966  {
1967  _dbus_fd_set_close_on_exec(client_fd);
1968  }
1969 
1970  return client_fd;
1971 }
1972 
1983 {
1984  const char *directory;
1985  struct stat sb;
1986 
1987  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1988 
1989  directory = _dbus_string_get_const_data (dir);
1990 
1991  if (stat (directory, &sb) < 0)
1992  {
1993  dbus_set_error (error, _dbus_error_from_errno (errno),
1994  "%s", _dbus_strerror (errno));
1995 
1996  return FALSE;
1997  }
1998 
1999  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2000  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2001  {
2003  "%s directory is not private to the user", directory);
2004  return FALSE;
2005  }
2006 
2007  return TRUE;
2008 }
2009 
2010 static dbus_bool_t
2011 fill_user_info_from_passwd (struct passwd *p,
2012  DBusUserInfo *info,
2013  DBusError *error)
2014 {
2015  _dbus_assert (p->pw_name != NULL);
2016  _dbus_assert (p->pw_dir != NULL);
2017 
2018  info->uid = p->pw_uid;
2019  info->primary_gid = p->pw_gid;
2020  info->username = _dbus_strdup (p->pw_name);
2021  info->homedir = _dbus_strdup (p->pw_dir);
2022 
2023  if (info->username == NULL ||
2024  info->homedir == NULL)
2025  {
2027  return FALSE;
2028  }
2029 
2030  return TRUE;
2031 }
2032 
2033 static dbus_bool_t
2034 fill_user_info (DBusUserInfo *info,
2035  dbus_uid_t uid,
2036  const DBusString *username,
2037  DBusError *error)
2038 {
2039  const char *username_c;
2040 
2041  /* exactly one of username/uid provided */
2042  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2043  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2044 
2045  info->uid = DBUS_UID_UNSET;
2046  info->primary_gid = DBUS_GID_UNSET;
2047  info->group_ids = NULL;
2048  info->n_group_ids = 0;
2049  info->username = NULL;
2050  info->homedir = NULL;
2051 
2052  if (username != NULL)
2053  username_c = _dbus_string_get_const_data (username);
2054  else
2055  username_c = NULL;
2056 
2057  /* For now assuming that the getpwnam() and getpwuid() flavors
2058  * are always symmetrical, if not we have to add more configure
2059  * checks
2060  */
2061 
2062 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2063  {
2064  struct passwd *p;
2065  int result;
2066  size_t buflen;
2067  char *buf;
2068  struct passwd p_str;
2069 
2070  /* retrieve maximum needed size for buf */
2071  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2072 
2073  /* sysconf actually returns a long, but everything else expects size_t,
2074  * so just recast here.
2075  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2076  */
2077  if ((long) buflen <= 0)
2078  buflen = 1024;
2079 
2080  result = -1;
2081  while (1)
2082  {
2083  buf = dbus_malloc (buflen);
2084  if (buf == NULL)
2085  {
2087  return FALSE;
2088  }
2089 
2090  p = NULL;
2091 #ifdef HAVE_POSIX_GETPWNAM_R
2092  if (uid != DBUS_UID_UNSET)
2093  result = getpwuid_r (uid, &p_str, buf, buflen,
2094  &p);
2095  else
2096  result = getpwnam_r (username_c, &p_str, buf, buflen,
2097  &p);
2098 #else
2099  if (uid != DBUS_UID_UNSET)
2100  p = getpwuid_r (uid, &p_str, buf, buflen);
2101  else
2102  p = getpwnam_r (username_c, &p_str, buf, buflen);
2103  result = 0;
2104 #endif /* !HAVE_POSIX_GETPWNAM_R */
2105  //Try a bigger buffer if ERANGE was returned
2106  if (result == ERANGE && buflen < 512 * 1024)
2107  {
2108  dbus_free (buf);
2109  buflen *= 2;
2110  }
2111  else
2112  {
2113  break;
2114  }
2115  }
2116  if (result == 0 && p == &p_str)
2117  {
2118  if (!fill_user_info_from_passwd (p, info, error))
2119  {
2120  dbus_free (buf);
2121  return FALSE;
2122  }
2123  dbus_free (buf);
2124  }
2125  else
2126  {
2127  dbus_set_error (error, _dbus_error_from_errno (errno),
2128  "User \"%s\" unknown or no memory to allocate password entry\n",
2129  username_c ? username_c : "???");
2130  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2131  dbus_free (buf);
2132  return FALSE;
2133  }
2134  }
2135 #else /* ! HAVE_GETPWNAM_R */
2136  {
2137  /* I guess we're screwed on thread safety here */
2138  struct passwd *p;
2139 
2140  if (uid != DBUS_UID_UNSET)
2141  p = getpwuid (uid);
2142  else
2143  p = getpwnam (username_c);
2144 
2145  if (p != NULL)
2146  {
2147  if (!fill_user_info_from_passwd (p, info, error))
2148  {
2149  return FALSE;
2150  }
2151  }
2152  else
2153  {
2154  dbus_set_error (error, _dbus_error_from_errno (errno),
2155  "User \"%s\" unknown or no memory to allocate password entry\n",
2156  username_c ? username_c : "???");
2157  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2158  return FALSE;
2159  }
2160  }
2161 #endif /* ! HAVE_GETPWNAM_R */
2162 
2163  /* Fill this in so we can use it to get groups */
2164  username_c = info->username;
2165 
2166 #ifdef HAVE_GETGROUPLIST
2167  {
2168  gid_t *buf;
2169  int buf_count;
2170  int i;
2171  int initial_buf_count;
2172 
2173  initial_buf_count = 17;
2174  buf_count = initial_buf_count;
2175  buf = dbus_new (gid_t, buf_count);
2176  if (buf == NULL)
2177  {
2179  goto failed;
2180  }
2181 
2182  if (getgrouplist (username_c,
2183  info->primary_gid,
2184  buf, &buf_count) < 0)
2185  {
2186  gid_t *new;
2187  /* Presumed cause of negative return code: buf has insufficient
2188  entries to hold the entire group list. The Linux behavior in this
2189  case is to pass back the actual number of groups in buf_count, but
2190  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2191  So as a hack, try to help out a bit by guessing a larger
2192  number of groups, within reason.. might still fail, of course,
2193  but we can at least print a more informative message. I looked up
2194  the "right way" to do this by downloading Apple's own source code
2195  for the "id" command, and it turns out that they use an
2196  undocumented library function getgrouplist_2 (!) which is not
2197  declared in any header in /usr/include (!!). That did not seem
2198  like the way to go here.
2199  */
2200  if (buf_count == initial_buf_count)
2201  {
2202  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2203  }
2204  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2205  if (new == NULL)
2206  {
2208  dbus_free (buf);
2209  goto failed;
2210  }
2211 
2212  buf = new;
2213 
2214  errno = 0;
2215  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2216  {
2217  if (errno == 0)
2218  {
2219  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2220  username_c, buf_count, buf_count);
2221  }
2222  else
2223  {
2224  dbus_set_error (error,
2225  _dbus_error_from_errno (errno),
2226  "Failed to get groups for username \"%s\" primary GID "
2227  DBUS_GID_FORMAT ": %s\n",
2228  username_c, info->primary_gid,
2229  _dbus_strerror (errno));
2230  dbus_free (buf);
2231  goto failed;
2232  }
2233  }
2234  }
2235 
2236  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2237  if (info->group_ids == NULL)
2238  {
2240  dbus_free (buf);
2241  goto failed;
2242  }
2243 
2244  for (i = 0; i < buf_count; ++i)
2245  info->group_ids[i] = buf[i];
2246 
2247  info->n_group_ids = buf_count;
2248 
2249  dbus_free (buf);
2250  }
2251 #else /* HAVE_GETGROUPLIST */
2252  {
2253  /* We just get the one group ID */
2254  info->group_ids = dbus_new (dbus_gid_t, 1);
2255  if (info->group_ids == NULL)
2256  {
2258  goto failed;
2259  }
2260 
2261  info->n_group_ids = 1;
2262 
2263  (info->group_ids)[0] = info->primary_gid;
2264  }
2265 #endif /* HAVE_GETGROUPLIST */
2266 
2267  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2268 
2269  return TRUE;
2270 
2271  failed:
2272  _DBUS_ASSERT_ERROR_IS_SET (error);
2273  return FALSE;
2274 }
2275 
2286  const DBusString *username,
2287  DBusError *error)
2288 {
2289  return fill_user_info (info, DBUS_UID_UNSET,
2290  username, error);
2291 }
2292 
2303  dbus_uid_t uid,
2304  DBusError *error)
2305 {
2306  return fill_user_info (info, uid,
2307  NULL, error);
2308 }
2309 
2319 {
2320  /* The POSIX spec certainly doesn't promise this, but
2321  * we need these assertions to fail as soon as we're wrong about
2322  * it so we can do the porting fixups
2323  */
2324  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2325  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2326  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2327 
2328  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2329  return FALSE;
2330  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2331  return FALSE;
2332 
2333  return TRUE;
2334 }
2335 
2349 {
2350  return _dbus_string_append_uint (str,
2351  _dbus_geteuid ());
2352 }
2353 
2358 dbus_pid_t
2360 {
2361  return getpid ();
2362 }
2363 
2367 dbus_uid_t
2369 {
2370  return getuid ();
2371 }
2372 
2376 dbus_uid_t
2378 {
2379  return geteuid ();
2380 }
2381 
2388 unsigned long
2390 {
2391  return getpid ();
2392 }
2393 
2402 _dbus_parse_uid (const DBusString *uid_str,
2403  dbus_uid_t *uid)
2404 {
2405  int end;
2406  long val;
2407 
2408  if (_dbus_string_get_length (uid_str) == 0)
2409  {
2410  _dbus_verbose ("UID string was zero length\n");
2411  return FALSE;
2412  }
2413 
2414  val = -1;
2415  end = 0;
2416  if (!_dbus_string_parse_int (uid_str, 0, &val,
2417  &end))
2418  {
2419  _dbus_verbose ("could not parse string as a UID\n");
2420  return FALSE;
2421  }
2422 
2423  if (end != _dbus_string_get_length (uid_str))
2424  {
2425  _dbus_verbose ("string contained trailing stuff after UID\n");
2426  return FALSE;
2427  }
2428 
2429  *uid = val;
2430 
2431  return TRUE;
2432 }
2433 
2434 #if !DBUS_USE_SYNC
2435 /* To be thread-safe by default on platforms that don't necessarily have
2436  * atomic operations (notably Debian armel, which is armv4t), we must
2437  * use a mutex that can be initialized statically, like this.
2438  * GLib >= 2.32 uses a similar system.
2439  */
2440 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2441 #endif
2442 
2451 {
2452 #if DBUS_USE_SYNC
2453  return __sync_add_and_fetch(&atomic->value, 1)-1;
2454 #else
2455  dbus_int32_t res;
2456 
2457  pthread_mutex_lock (&atomic_mutex);
2458  res = atomic->value;
2459  atomic->value += 1;
2460  pthread_mutex_unlock (&atomic_mutex);
2461 
2462  return res;
2463 #endif
2464 }
2465 
2474 {
2475 #if DBUS_USE_SYNC
2476  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2477 #else
2478  dbus_int32_t res;
2479 
2480  pthread_mutex_lock (&atomic_mutex);
2481  res = atomic->value;
2482  atomic->value -= 1;
2483  pthread_mutex_unlock (&atomic_mutex);
2484 
2485  return res;
2486 #endif
2487 }
2488 
2498 {
2499 #if DBUS_USE_SYNC
2500  __sync_synchronize ();
2501  return atomic->value;
2502 #else
2503  dbus_int32_t res;
2504 
2505  pthread_mutex_lock (&atomic_mutex);
2506  res = atomic->value;
2507  pthread_mutex_unlock (&atomic_mutex);
2508 
2509  return res;
2510 #endif
2511 }
2512 
2521 int
2523  int n_fds,
2524  int timeout_milliseconds)
2525 {
2526 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2527  /* This big thing is a constant expression and should get optimized
2528  * out of existence. So it's more robust than a configure check at
2529  * no cost.
2530  */
2531  if (_DBUS_POLLIN == POLLIN &&
2532  _DBUS_POLLPRI == POLLPRI &&
2533  _DBUS_POLLOUT == POLLOUT &&
2534  _DBUS_POLLERR == POLLERR &&
2535  _DBUS_POLLHUP == POLLHUP &&
2536  _DBUS_POLLNVAL == POLLNVAL &&
2537  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2538  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2539  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2540  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2541  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2542  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2543  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2544  {
2545  return poll ((struct pollfd*) fds,
2546  n_fds,
2547  timeout_milliseconds);
2548  }
2549  else
2550  {
2551  /* We have to convert the DBusPollFD to an array of
2552  * struct pollfd, poll, and convert back.
2553  */
2554  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2555  return -1;
2556  }
2557 #else /* ! HAVE_POLL */
2558 
2559  fd_set read_set, write_set, err_set;
2560  int max_fd = 0;
2561  int i;
2562  struct timeval tv;
2563  int ready;
2564 
2565  FD_ZERO (&read_set);
2566  FD_ZERO (&write_set);
2567  FD_ZERO (&err_set);
2568 
2569  for (i = 0; i < n_fds; i++)
2570  {
2571  DBusPollFD *fdp = &fds[i];
2572 
2573  if (fdp->events & _DBUS_POLLIN)
2574  FD_SET (fdp->fd, &read_set);
2575 
2576  if (fdp->events & _DBUS_POLLOUT)
2577  FD_SET (fdp->fd, &write_set);
2578 
2579  FD_SET (fdp->fd, &err_set);
2580 
2581  max_fd = MAX (max_fd, fdp->fd);
2582  }
2583 
2584  tv.tv_sec = timeout_milliseconds / 1000;
2585  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2586 
2587  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2588  timeout_milliseconds < 0 ? NULL : &tv);
2589 
2590  if (ready > 0)
2591  {
2592  for (i = 0; i < n_fds; i++)
2593  {
2594  DBusPollFD *fdp = &fds[i];
2595 
2596  fdp->revents = 0;
2597 
2598  if (FD_ISSET (fdp->fd, &read_set))
2599  fdp->revents |= _DBUS_POLLIN;
2600 
2601  if (FD_ISSET (fdp->fd, &write_set))
2602  fdp->revents |= _DBUS_POLLOUT;
2603 
2604  if (FD_ISSET (fdp->fd, &err_set))
2605  fdp->revents |= _DBUS_POLLERR;
2606  }
2607  }
2608 
2609  return ready;
2610 #endif
2611 }
2612 
2620 void
2622  long *tv_usec)
2623 {
2624 #ifdef HAVE_MONOTONIC_CLOCK
2625  struct timespec ts;
2626  clock_gettime (CLOCK_MONOTONIC, &ts);
2627 
2628  if (tv_sec)
2629  *tv_sec = ts.tv_sec;
2630  if (tv_usec)
2631  *tv_usec = ts.tv_nsec / 1000;
2632 #else
2633  struct timeval t;
2634 
2635  gettimeofday (&t, NULL);
2636 
2637  if (tv_sec)
2638  *tv_sec = t.tv_sec;
2639  if (tv_usec)
2640  *tv_usec = t.tv_usec;
2641 #endif
2642 }
2643 
2651 void
2652 _dbus_get_real_time (long *tv_sec,
2653  long *tv_usec)
2654 {
2655  struct timeval t;
2656 
2657  gettimeofday (&t, NULL);
2658 
2659  if (tv_sec)
2660  *tv_sec = t.tv_sec;
2661  if (tv_usec)
2662  *tv_usec = t.tv_usec;
2663 }
2664 
2675  DBusError *error)
2676 {
2677  const char *filename_c;
2678 
2679  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2680 
2681  filename_c = _dbus_string_get_const_data (filename);
2682 
2683  if (mkdir (filename_c, 0700) < 0)
2684  {
2685  if (errno == EEXIST)
2686  return TRUE;
2687 
2689  "Failed to create directory %s: %s\n",
2690  filename_c, _dbus_strerror (errno));
2691  return FALSE;
2692  }
2693  else
2694  return TRUE;
2695 }
2696 
2709  const DBusString *next_component)
2710 {
2711  dbus_bool_t dir_ends_in_slash;
2712  dbus_bool_t file_starts_with_slash;
2713 
2714  if (_dbus_string_get_length (dir) == 0 ||
2715  _dbus_string_get_length (next_component) == 0)
2716  return TRUE;
2717 
2718  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2719  _dbus_string_get_length (dir) - 1);
2720 
2721  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2722 
2723  if (dir_ends_in_slash && file_starts_with_slash)
2724  {
2725  _dbus_string_shorten (dir, 1);
2726  }
2727  else if (!(dir_ends_in_slash || file_starts_with_slash))
2728  {
2729  if (!_dbus_string_append_byte (dir, '/'))
2730  return FALSE;
2731  }
2732 
2733  return _dbus_string_copy (next_component, 0, dir,
2734  _dbus_string_get_length (dir));
2735 }
2736 
2738 #define NANOSECONDS_PER_SECOND 1000000000
2739 
2740 #define MICROSECONDS_PER_SECOND 1000000
2741 
2742 #define MILLISECONDS_PER_SECOND 1000
2743 
2744 #define NANOSECONDS_PER_MILLISECOND 1000000
2745 
2746 #define MICROSECONDS_PER_MILLISECOND 1000
2747 
2752 void
2753 _dbus_sleep_milliseconds (int milliseconds)
2754 {
2755 #ifdef HAVE_NANOSLEEP
2756  struct timespec req;
2757  struct timespec rem;
2758 
2759  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2760  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2761  rem.tv_sec = 0;
2762  rem.tv_nsec = 0;
2763 
2764  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2765  req = rem;
2766 #elif defined (HAVE_USLEEP)
2767  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2768 #else /* ! HAVE_USLEEP */
2769  sleep (MAX (milliseconds / 1000, 1));
2770 #endif
2771 }
2772 
2773 static dbus_bool_t
2774 _dbus_generate_pseudorandom_bytes (DBusString *str,
2775  int n_bytes)
2776 {
2777  int old_len;
2778  char *p;
2779 
2780  old_len = _dbus_string_get_length (str);
2781 
2782  if (!_dbus_string_lengthen (str, n_bytes))
2783  return FALSE;
2784 
2785  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2786 
2788 
2789  return TRUE;
2790 }
2791 
2802  int n_bytes)
2803 {
2804  int old_len;
2805  int fd;
2806 
2807  /* FALSE return means "no memory", if it could
2808  * mean something else then we'd need to return
2809  * a DBusError. So we always fall back to pseudorandom
2810  * if the I/O fails.
2811  */
2812 
2813  old_len = _dbus_string_get_length (str);
2814  fd = -1;
2815 
2816  /* note, urandom on linux will fall back to pseudorandom */
2817  fd = open ("/dev/urandom", O_RDONLY);
2818  if (fd < 0)
2819  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2820 
2821  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2822 
2823  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2824  {
2825  _dbus_close (fd, NULL);
2826  _dbus_string_set_length (str, old_len);
2827  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2828  }
2829 
2830  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2831  n_bytes);
2832 
2833  _dbus_close (fd, NULL);
2834 
2835  return TRUE;
2836 }
2837 
2843 void
2844 _dbus_exit (int code)
2845 {
2846  _exit (code);
2847 }
2848 
2857 const char*
2858 _dbus_strerror (int error_number)
2859 {
2860  const char *msg;
2861 
2862  msg = strerror (error_number);
2863  if (msg == NULL)
2864  msg = "unknown";
2865 
2866  return msg;
2867 }
2868 
2872 void
2874 {
2875  signal (SIGPIPE, SIG_IGN);
2876 }
2877 
2885 void
2887 {
2888  int val;
2889 
2890  val = fcntl (fd, F_GETFD, 0);
2891 
2892  if (val < 0)
2893  return;
2894 
2895  val |= FD_CLOEXEC;
2896 
2897  fcntl (fd, F_SETFD, val);
2898 }
2899 
2908 _dbus_close (int fd,
2909  DBusError *error)
2910 {
2911  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2912 
2913  again:
2914  if (close (fd) < 0)
2915  {
2916  if (errno == EINTR)
2917  goto again;
2918 
2919  dbus_set_error (error, _dbus_error_from_errno (errno),
2920  "Could not close fd %d", fd);
2921  return FALSE;
2922  }
2923 
2924  return TRUE;
2925 }
2926 
2934 int
2935 _dbus_dup(int fd,
2936  DBusError *error)
2937 {
2938  int new_fd;
2939 
2940 #ifdef F_DUPFD_CLOEXEC
2941  dbus_bool_t cloexec_done;
2942 
2943  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2944  cloexec_done = new_fd >= 0;
2945 
2946  if (new_fd < 0 && errno == EINVAL)
2947 #endif
2948  {
2949  new_fd = fcntl(fd, F_DUPFD, 3);
2950  }
2951 
2952  if (new_fd < 0) {
2953 
2954  dbus_set_error (error, _dbus_error_from_errno (errno),
2955  "Could not duplicate fd %d", fd);
2956  return -1;
2957  }
2958 
2959 #ifdef F_DUPFD_CLOEXEC
2960  if (!cloexec_done)
2961 #endif
2962  {
2964  }
2965 
2966  return new_fd;
2967 }
2968 
2977 _dbus_set_fd_nonblocking (int fd,
2978  DBusError *error)
2979 {
2980  int val;
2981 
2982  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2983 
2984  val = fcntl (fd, F_GETFL, 0);
2985  if (val < 0)
2986  {
2987  dbus_set_error (error, _dbus_error_from_errno (errno),
2988  "Failed to get flags from file descriptor %d: %s",
2989  fd, _dbus_strerror (errno));
2990  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2991  _dbus_strerror (errno));
2992  return FALSE;
2993  }
2994 
2995  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2996  {
2997  dbus_set_error (error, _dbus_error_from_errno (errno),
2998  "Failed to set nonblocking flag of file descriptor %d: %s",
2999  fd, _dbus_strerror (errno));
3000  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3001  fd, _dbus_strerror (errno));
3002 
3003  return FALSE;
3004  }
3005 
3006  return TRUE;
3007 }
3008 
3014 void
3016 {
3017 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3018  void *bt[500];
3019  int bt_size;
3020  int i;
3021  char **syms;
3022 
3023  bt_size = backtrace (bt, 500);
3024 
3025  syms = backtrace_symbols (bt, bt_size);
3026 
3027  i = 0;
3028  while (i < bt_size)
3029  {
3030  /* don't use dbus_warn since it can _dbus_abort() */
3031  fprintf (stderr, " %s\n", syms[i]);
3032  ++i;
3033  }
3034  fflush (stderr);
3035 
3036  free (syms);
3037 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3038  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3039 #else
3040  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3041 #endif
3042 }
3043 
3058  int *fd2,
3059  dbus_bool_t blocking,
3060  DBusError *error)
3061 {
3062 #ifdef HAVE_SOCKETPAIR
3063  int fds[2];
3064  int retval;
3065 
3066 #ifdef SOCK_CLOEXEC
3067  dbus_bool_t cloexec_done;
3068 
3069  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3070  cloexec_done = retval >= 0;
3071 
3072  if (retval < 0 && errno == EINVAL)
3073 #endif
3074  {
3075  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3076  }
3077 
3078  if (retval < 0)
3079  {
3080  dbus_set_error (error, _dbus_error_from_errno (errno),
3081  "Could not create full-duplex pipe");
3082  return FALSE;
3083  }
3084 
3085  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3086 
3087 #ifdef SOCK_CLOEXEC
3088  if (!cloexec_done)
3089 #endif
3090  {
3091  _dbus_fd_set_close_on_exec (fds[0]);
3092  _dbus_fd_set_close_on_exec (fds[1]);
3093  }
3094 
3095  if (!blocking &&
3096  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3097  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3098  {
3099  dbus_set_error (error, _dbus_error_from_errno (errno),
3100  "Could not set full-duplex pipe nonblocking");
3101 
3102  _dbus_close (fds[0], NULL);
3103  _dbus_close (fds[1], NULL);
3104 
3105  return FALSE;
3106  }
3107 
3108  *fd1 = fds[0];
3109  *fd2 = fds[1];
3110 
3111  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3112  *fd1, *fd2);
3113 
3114  return TRUE;
3115 #else
3116  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3118  "_dbus_full_duplex_pipe() not implemented on this OS");
3119  return FALSE;
3120 #endif
3121 }
3122 
3131 int
3133  va_list args)
3134 {
3135  char static_buf[1024];
3136  int bufsize = sizeof (static_buf);
3137  int len;
3138  va_list args_copy;
3139 
3140  DBUS_VA_COPY (args_copy, args);
3141  len = vsnprintf (static_buf, bufsize, format, args_copy);
3142  va_end (args_copy);
3143 
3144  /* If vsnprintf() returned non-negative, then either the string fits in
3145  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3146  * returns the number of characters that were needed, or this OS returns the
3147  * truncated length.
3148  *
3149  * We ignore the possibility that snprintf might just ignore the length and
3150  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3151  * If your libc is really that bad, come back when you have a better one. */
3152  if (len == bufsize)
3153  {
3154  /* This could be the truncated length (Tru64 and IRIX have this bug),
3155  * or the real length could be coincidentally the same. Which is it?
3156  * If vsnprintf returns the truncated length, we'll go to the slow
3157  * path. */
3158  DBUS_VA_COPY (args_copy, args);
3159 
3160  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3161  len = -1;
3162 
3163  va_end (args_copy);
3164  }
3165 
3166  /* If vsnprintf() returned negative, we have to do more work.
3167  * HP-UX returns negative. */
3168  while (len < 0)
3169  {
3170  char *buf;
3171 
3172  bufsize *= 2;
3173 
3174  buf = dbus_malloc (bufsize);
3175 
3176  if (buf == NULL)
3177  return -1;
3178 
3179  DBUS_VA_COPY (args_copy, args);
3180  len = vsnprintf (buf, bufsize, format, args_copy);
3181  va_end (args_copy);
3182 
3183  dbus_free (buf);
3184 
3185  /* If the reported length is exactly the buffer size, round up to the
3186  * next size, in case vsnprintf has been returning the truncated
3187  * length */
3188  if (len == bufsize)
3189  len = -1;
3190  }
3191 
3192  return len;
3193 }
3194 
3201 const char*
3203 {
3204  static const char* tmpdir = NULL;
3205 
3206  if (tmpdir == NULL)
3207  {
3208  /* TMPDIR is what glibc uses, then
3209  * glibc falls back to the P_tmpdir macro which
3210  * just expands to "/tmp"
3211  */
3212  if (tmpdir == NULL)
3213  tmpdir = getenv("TMPDIR");
3214 
3215  /* These two env variables are probably
3216  * broken, but maybe some OS uses them?
3217  */
3218  if (tmpdir == NULL)
3219  tmpdir = getenv("TMP");
3220  if (tmpdir == NULL)
3221  tmpdir = getenv("TEMP");
3222 
3223  /* And this is the sane fallback. */
3224  if (tmpdir == NULL)
3225  tmpdir = "/tmp";
3226  }
3227 
3228  _dbus_assert(tmpdir != NULL);
3229 
3230  return tmpdir;
3231 }
3232 
3233 #if 1
3234 
3253 static dbus_bool_t
3254 _read_subprocess_line_argv (const char *progpath,
3255  dbus_bool_t path_fallback,
3256  char * const *argv,
3257  DBusString *result,
3258  DBusError *error)
3259 {
3260  int result_pipe[2] = { -1, -1 };
3261  int errors_pipe[2] = { -1, -1 };
3262  pid_t pid;
3263  int ret;
3264  int status;
3265  int orig_len;
3266 
3267  dbus_bool_t retval;
3268  sigset_t new_set, old_set;
3269 
3270  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3271  retval = FALSE;
3272 
3273  /* We need to block any existing handlers for SIGCHLD temporarily; they
3274  * will cause waitpid() below to fail.
3275  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3276  */
3277  sigemptyset (&new_set);
3278  sigaddset (&new_set, SIGCHLD);
3279  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3280 
3281  orig_len = _dbus_string_get_length (result);
3282 
3283 #define READ_END 0
3284 #define WRITE_END 1
3285  if (pipe (result_pipe) < 0)
3286  {
3287  dbus_set_error (error, _dbus_error_from_errno (errno),
3288  "Failed to create a pipe to call %s: %s",
3289  progpath, _dbus_strerror (errno));
3290  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3291  progpath, _dbus_strerror (errno));
3292  goto out;
3293  }
3294  if (pipe (errors_pipe) < 0)
3295  {
3296  dbus_set_error (error, _dbus_error_from_errno (errno),
3297  "Failed to create a pipe to call %s: %s",
3298  progpath, _dbus_strerror (errno));
3299  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3300  progpath, _dbus_strerror (errno));
3301  goto out;
3302  }
3303 
3304  pid = fork ();
3305  if (pid < 0)
3306  {
3307  dbus_set_error (error, _dbus_error_from_errno (errno),
3308  "Failed to fork() to call %s: %s",
3309  progpath, _dbus_strerror (errno));
3310  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3311  progpath, _dbus_strerror (errno));
3312  goto out;
3313  }
3314 
3315  if (pid == 0)
3316  {
3317  /* child process */
3318  int fd;
3319 
3320  fd = open ("/dev/null", O_RDWR);
3321  if (fd == -1)
3322  /* huh?! can't open /dev/null? */
3323  _exit (1);
3324 
3325  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3326 
3327  /* set-up stdXXX */
3328  close (result_pipe[READ_END]);
3329  close (errors_pipe[READ_END]);
3330 
3331  if (dup2 (fd, 0) == -1) /* setup stdin */
3332  _exit (1);
3333  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3334  _exit (1);
3335  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3336  _exit (1);
3337 
3338  _dbus_close_all ();
3339 
3340  sigprocmask (SIG_SETMASK, &old_set, NULL);
3341 
3342  /* If it looks fully-qualified, try execv first */
3343  if (progpath[0] == '/')
3344  {
3345  execv (progpath, argv);
3346  /* Ok, that failed. Now if path_fallback is given, let's
3347  * try unqualified. This is mostly a hack to work
3348  * around systems which ship dbus-launch in /usr/bin
3349  * but everything else in /bin (because dbus-launch
3350  * depends on X11).
3351  */
3352  if (path_fallback)
3353  /* We must have a slash, because we checked above */
3354  execvp (strrchr (progpath, '/')+1, argv);
3355  }
3356  else
3357  execvp (progpath, argv);
3358 
3359  /* still nothing, we failed */
3360  _exit (1);
3361  }
3362 
3363  /* parent process */
3364  close (result_pipe[WRITE_END]);
3365  close (errors_pipe[WRITE_END]);
3366  result_pipe[WRITE_END] = -1;
3367  errors_pipe[WRITE_END] = -1;
3368 
3369  ret = 0;
3370  do
3371  {
3372  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3373  }
3374  while (ret > 0);
3375 
3376  /* reap the child process to avoid it lingering as zombie */
3377  do
3378  {
3379  ret = waitpid (pid, &status, 0);
3380  }
3381  while (ret == -1 && errno == EINTR);
3382 
3383  /* We succeeded if the process exited with status 0 and
3384  anything was read */
3385  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3386  {
3387  /* The process ended with error */
3388  DBusString error_message;
3389  if (!_dbus_string_init (&error_message))
3390  {
3391  _DBUS_SET_OOM (error);
3392  goto out;
3393  }
3394 
3395  ret = 0;
3396  do
3397  {
3398  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3399  }
3400  while (ret > 0);
3401 
3402  _dbus_string_set_length (result, orig_len);
3403  if (_dbus_string_get_length (&error_message) > 0)
3405  "%s terminated abnormally with the following error: %s",
3406  progpath, _dbus_string_get_data (&error_message));
3407  else
3409  "%s terminated abnormally without any error message",
3410  progpath);
3411  goto out;
3412  }
3413 
3414  retval = TRUE;
3415 
3416  out:
3417  sigprocmask (SIG_SETMASK, &old_set, NULL);
3418 
3419  if (retval)
3420  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3421  else
3422  _DBUS_ASSERT_ERROR_IS_SET (error);
3423 
3424  if (result_pipe[0] != -1)
3425  close (result_pipe[0]);
3426  if (result_pipe[1] != -1)
3427  close (result_pipe[1]);
3428  if (errors_pipe[0] != -1)
3429  close (errors_pipe[0]);
3430  if (errors_pipe[1] != -1)
3431  close (errors_pipe[1]);
3432 
3433  return retval;
3434 }
3435 #endif
3436 
3449 _dbus_get_autolaunch_address (const char *scope,
3450  DBusString *address,
3451  DBusError *error)
3452 {
3453 #if 1
3454  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3455  * but that's done elsewhere, and if it worked, this function wouldn't
3456  * be called.) */
3457  const char *display;
3458  static char *argv[6];
3459  int i;
3460  DBusString uuid;
3461  dbus_bool_t retval;
3462 
3463  if (_dbus_check_setuid ())
3464  {
3466  "Unable to autolaunch when setuid");
3467  return FALSE;
3468  }
3469 
3470  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3471  retval = FALSE;
3472 
3473  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3474  * dbus-launch-x11 is just going to fail. Rather than trying to
3475  * run it, we might as well bail out early with a nice error. */
3476  display = _dbus_getenv ("DISPLAY");
3477 
3478  if (display == NULL || display[0] == '\0')
3479  {
3481  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3482  return FALSE;
3483  }
3484 
3485  if (!_dbus_string_init (&uuid))
3486  {
3487  _DBUS_SET_OOM (error);
3488  return FALSE;
3489  }
3490 
3492  {
3493  _DBUS_SET_OOM (error);
3494  goto out;
3495  }
3496 
3497  i = 0;
3498  argv[i] = "dbus-launch";
3499  ++i;
3500  argv[i] = "--autolaunch";
3501  ++i;
3502  argv[i] = _dbus_string_get_data (&uuid);
3503  ++i;
3504  argv[i] = "--binary-syntax";
3505  ++i;
3506  argv[i] = "--close-stderr";
3507  ++i;
3508  argv[i] = NULL;
3509  ++i;
3510 
3511  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3512 
3513  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3514  TRUE,
3515  argv, address, error);
3516 
3517  out:
3518  _dbus_string_free (&uuid);
3519  return retval;
3520 #else
3522  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3523  "set your DBUS_SESSION_BUS_ADDRESS instead");
3524  return FALSE;
3525 #endif
3526 }
3527 
3548  dbus_bool_t create_if_not_found,
3549  DBusError *error)
3550 {
3551  DBusString filename;
3552  dbus_bool_t b;
3553 
3554  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3555 
3556  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3557  if (b)
3558  return TRUE;
3559 
3560  dbus_error_free (error);
3561 
3562  /* Fallback to the system machine ID */
3563  _dbus_string_init_const (&filename, "/etc/machine-id");
3564  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3565 }
3566 
3567 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3568 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3569 
3578  const char *launchd_env_var,
3579  DBusError *error)
3580 {
3581 #ifdef DBUS_ENABLE_LAUNCHD
3582  char *argv[4];
3583  int i;
3584 
3585  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3586 
3587  if (_dbus_check_setuid ())
3588  {
3590  "Unable to find launchd socket when setuid");
3591  return FALSE;
3592  }
3593 
3594  i = 0;
3595  argv[i] = "launchctl";
3596  ++i;
3597  argv[i] = "getenv";
3598  ++i;
3599  argv[i] = (char*)launchd_env_var;
3600  ++i;
3601  argv[i] = NULL;
3602  ++i;
3603 
3604  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3605 
3606  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3607  {
3608  return FALSE;
3609  }
3610 
3611  /* no error, but no result either */
3612  if (_dbus_string_get_length(socket_path) == 0)
3613  {
3614  return FALSE;
3615  }
3616 
3617  /* strip the carriage-return */
3618  _dbus_string_shorten(socket_path, 1);
3619  return TRUE;
3620 #else /* DBUS_ENABLE_LAUNCHD */
3622  "can't lookup socket from launchd; launchd support not compiled in");
3623  return FALSE;
3624 #endif
3625 }
3626 
3627 #ifdef DBUS_ENABLE_LAUNCHD
3628 static dbus_bool_t
3629 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3630 {
3631  dbus_bool_t valid_socket;
3632  DBusString socket_path;
3633 
3634  if (_dbus_check_setuid ())
3635  {
3637  "Unable to find launchd socket when setuid");
3638  return FALSE;
3639  }
3640 
3641  if (!_dbus_string_init (&socket_path))
3642  {
3643  _DBUS_SET_OOM (error);
3644  return FALSE;
3645  }
3646 
3647  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3648 
3649  if (dbus_error_is_set(error))
3650  {
3651  _dbus_string_free(&socket_path);
3652  return FALSE;
3653  }
3654 
3655  if (!valid_socket)
3656  {
3657  dbus_set_error(error, "no socket path",
3658  "launchd did not provide a socket path, "
3659  "verify that org.freedesktop.dbus-session.plist is loaded!");
3660  _dbus_string_free(&socket_path);
3661  return FALSE;
3662  }
3663  if (!_dbus_string_append (address, "unix:path="))
3664  {
3665  _DBUS_SET_OOM (error);
3666  _dbus_string_free(&socket_path);
3667  return FALSE;
3668  }
3669  if (!_dbus_string_copy (&socket_path, 0, address,
3670  _dbus_string_get_length (address)))
3671  {
3672  _DBUS_SET_OOM (error);
3673  _dbus_string_free(&socket_path);
3674  return FALSE;
3675  }
3676 
3677  _dbus_string_free(&socket_path);
3678  return TRUE;
3679 }
3680 #endif
3681 
3703  DBusString *address,
3704  DBusError *error)
3705 {
3706 #ifdef DBUS_ENABLE_LAUNCHD
3707  *supported = TRUE;
3708  return _dbus_lookup_session_address_launchd (address, error);
3709 #else
3710  /* On non-Mac Unix platforms, if the session address isn't already
3711  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3712  * fall back to the autolaunch: global default; see
3713  * init_session_address in dbus/dbus-bus.c. */
3714  *supported = FALSE;
3715  return TRUE;
3716 #endif
3717 }
3718 
3738 {
3739  const char *xdg_data_home;
3740  const char *xdg_data_dirs;
3741  DBusString servicedir_path;
3742 
3743  if (!_dbus_string_init (&servicedir_path))
3744  return FALSE;
3745 
3746  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3747  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3748 
3749  if (xdg_data_home != NULL)
3750  {
3751  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3752  goto oom;
3753  }
3754  else
3755  {
3756  const DBusString *homedir;
3757  DBusString local_share;
3758 
3759  if (!_dbus_homedir_from_current_process (&homedir))
3760  goto oom;
3761 
3762  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3763  goto oom;
3764 
3765  _dbus_string_init_const (&local_share, "/.local/share");
3766  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3767  goto oom;
3768  }
3769 
3770  if (!_dbus_string_append (&servicedir_path, ":"))
3771  goto oom;
3772 
3773  if (xdg_data_dirs != NULL)
3774  {
3775  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3776  goto oom;
3777 
3778  if (!_dbus_string_append (&servicedir_path, ":"))
3779  goto oom;
3780  }
3781  else
3782  {
3783  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3784  goto oom;
3785  }
3786 
3787  /*
3788  * add configured datadir to defaults
3789  * this may be the same as an xdg dir
3790  * however the config parser should take
3791  * care of duplicates
3792  */
3793  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3794  goto oom;
3795 
3796  if (!_dbus_split_paths_and_append (&servicedir_path,
3797  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3798  dirs))
3799  goto oom;
3800 
3801  _dbus_string_free (&servicedir_path);
3802  return TRUE;
3803 
3804  oom:
3805  _dbus_string_free (&servicedir_path);
3806  return FALSE;
3807 }
3808 
3809 
3830 {
3831  /*
3832  * DBUS_DATADIR may be the same as one of the standard directories. However,
3833  * the config parser should take care of the duplicates.
3834  *
3835  * Also, append /lib as counterpart of /usr/share on the root
3836  * directory (the root directory does not know /share), in order to
3837  * facilitate early boot system bus activation where /usr might not
3838  * be available.
3839  */
3840  static const char standard_search_path[] =
3841  "/usr/local/share:"
3842  "/usr/share:"
3843  DBUS_DATADIR ":"
3844  "/lib";
3845  DBusString servicedir_path;
3846 
3847  _dbus_string_init_const (&servicedir_path, standard_search_path);
3848 
3849  return _dbus_split_paths_and_append (&servicedir_path,
3850  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3851  dirs);
3852 }
3853 
3864 {
3865  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3866 }
3867 
3876 {
3877  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3878 }
3879 
3887 void
3889 {
3891 }
3892 
3908  DBusCredentials *credentials)
3909 {
3910  DBusString homedir;
3911  DBusString dotdir;
3912  dbus_uid_t uid;
3913 
3914  _dbus_assert (credentials != NULL);
3916 
3917  if (!_dbus_string_init (&homedir))
3918  return FALSE;
3919 
3920  uid = _dbus_credentials_get_unix_uid (credentials);
3921  _dbus_assert (uid != DBUS_UID_UNSET);
3922 
3923  if (!_dbus_homedir_from_uid (uid, &homedir))
3924  goto failed;
3925 
3926 #ifdef DBUS_BUILD_TESTS
3927  {
3928  const char *override;
3929 
3930  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3931  if (override != NULL && *override != '\0')
3932  {
3933  _dbus_string_set_length (&homedir, 0);
3934  if (!_dbus_string_append (&homedir, override))
3935  goto failed;
3936 
3937  _dbus_verbose ("Using fake homedir for testing: %s\n",
3938  _dbus_string_get_const_data (&homedir));
3939  }
3940  else
3941  {
3942  static dbus_bool_t already_warned = FALSE;
3943  if (!already_warned)
3944  {
3945  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3946  already_warned = TRUE;
3947  }
3948  }
3949  }
3950 #endif
3951 
3952  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3953  if (!_dbus_concat_dir_and_file (&homedir,
3954  &dotdir))
3955  goto failed;
3956 
3957  if (!_dbus_string_copy (&homedir, 0,
3958  directory, _dbus_string_get_length (directory))) {
3959  goto failed;
3960  }
3961 
3962  _dbus_string_free (&homedir);
3963  return TRUE;
3964 
3965  failed:
3966  _dbus_string_free (&homedir);
3967  return FALSE;
3968 }
3969 
3970 //PENDING(kdab) docs
3972 _dbus_daemon_publish_session_bus_address (const char* addr,
3973  const char *scope)
3974 {
3975  return TRUE;
3976 }
3977 
3978 //PENDING(kdab) docs
3979 void
3980 _dbus_daemon_unpublish_session_bus_address (void)
3981 {
3982 
3983 }
3984 
3993 {
3994  return errno == EAGAIN || errno == EWOULDBLOCK;
3995 }
3996 
4006  DBusError *error)
4007 {
4008  const char *filename_c;
4009 
4010  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4011 
4012  filename_c = _dbus_string_get_const_data (filename);
4013 
4014  if (rmdir (filename_c) != 0)
4015  {
4017  "Failed to remove directory %s: %s\n",
4018  filename_c, _dbus_strerror (errno));
4019  return FALSE;
4020  }
4021 
4022  return TRUE;
4023 }
4024 
4034 
4035 #ifdef SCM_RIGHTS
4036  union {
4037  struct sockaddr sa;
4038  struct sockaddr_storage storage;
4039  struct sockaddr_un un;
4040  } sa_buf;
4041 
4042  socklen_t sa_len = sizeof(sa_buf);
4043 
4044  _DBUS_ZERO(sa_buf);
4045 
4046  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4047  return FALSE;
4048 
4049  return sa_buf.sa.sa_family == AF_UNIX;
4050 
4051 #else
4052  return FALSE;
4053 
4054 #endif
4055 }
4056 
4057 
4058 /*
4059  * replaces the term DBUS_PREFIX in configure_time_path by the
4060  * current dbus installation directory. On unix this function is a noop
4061  *
4062  * @param configure_time_path
4063  * @return real path
4064  */
4065 const char *
4066 _dbus_replace_install_prefix (const char *configure_time_path)
4067 {
4068  return configure_time_path;
4069 }
4070 
4075 void
4077 {
4078  int maxfds, i;
4079 
4080 #ifdef __linux__
4081  DIR *d;
4082 
4083  /* On Linux we can optimize this a bit if /proc is available. If it
4084  isn't available, fall back to the brute force way. */
4085 
4086  d = opendir ("/proc/self/fd");
4087  if (d)
4088  {
4089  for (;;)
4090  {
4091  struct dirent buf, *de;
4092  int k, fd;
4093  long l;
4094  char *e = NULL;
4095 
4096  k = readdir_r (d, &buf, &de);
4097  if (k != 0 || !de)
4098  break;
4099 
4100  if (de->d_name[0] == '.')
4101  continue;
4102 
4103  errno = 0;
4104  l = strtol (de->d_name, &e, 10);
4105  if (errno != 0 || e == NULL || *e != '\0')
4106  continue;
4107 
4108  fd = (int) l;
4109  if (fd < 3)
4110  continue;
4111 
4112  if (fd == dirfd (d))
4113  continue;
4114 
4115  close (fd);
4116  }
4117 
4118  closedir (d);
4119  return;
4120  }
4121 #endif
4122 
4123  maxfds = sysconf (_SC_OPEN_MAX);
4124 
4125  /* Pick something reasonable if for some reason sysconf says
4126  * unlimited.
4127  */
4128  if (maxfds < 0)
4129  maxfds = 1024;
4130 
4131  /* close all inherited fds */
4132  for (i = 3; i < maxfds; i++)
4133  close (i);
4134 }
4135 
4147 {
4148  /* TODO: get __libc_enable_secure exported from glibc.
4149  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4150  */
4151 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4152  {
4153  /* See glibc/include/unistd.h */
4154  extern int __libc_enable_secure;
4155  return __libc_enable_secure;
4156  }
4157 #elif defined(HAVE_ISSETUGID)
4158  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4159  return issetugid ();
4160 #else
4161  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4162  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4163 
4164  static dbus_bool_t check_setuid_initialised;
4165  static dbus_bool_t is_setuid;
4166 
4167  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4168  {
4169 #ifdef HAVE_GETRESUID
4170  if (getresuid (&ruid, &euid, &suid) != 0 ||
4171  getresgid (&rgid, &egid, &sgid) != 0)
4172 #endif /* HAVE_GETRESUID */
4173  {
4174  suid = ruid = getuid ();
4175  sgid = rgid = getgid ();
4176  euid = geteuid ();
4177  egid = getegid ();
4178  }
4179 
4180  check_setuid_initialised = TRUE;
4181  is_setuid = (ruid != euid || ruid != suid ||
4182  rgid != egid || rgid != sgid);
4183 
4184  }
4185  return is_setuid;
4186 #endif
4187 }
4188 
4198  DBusString *address,
4199  DBusError *error)
4200 {
4201  union {
4202  struct sockaddr sa;
4203  struct sockaddr_storage storage;
4204  struct sockaddr_un un;
4205  struct sockaddr_in ipv4;
4206  struct sockaddr_in6 ipv6;
4207  } socket;
4208  char hostip[INET6_ADDRSTRLEN];
4209  int size = sizeof (socket);
4210 
4211  if (getsockname (fd, &socket.sa, &size))
4212  goto err;
4213 
4214  switch (socket.sa.sa_family)
4215  {
4216  case AF_UNIX:
4217  if (socket.un.sun_path[0]=='\0')
4218  {
4219  if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1])))
4220  return TRUE;
4221  }
4222  else
4223  {
4224  if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path))
4225  return TRUE;
4226  }
4227  break;
4228  case AF_INET:
4229  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4230  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4231  hostip, ntohs (socket.ipv4.sin_port)))
4232  return TRUE;
4233  break;
4234 #ifdef AF_INET6
4235  case AF_INET6:
4236  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4237  if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u",
4238  hostip, ntohs (socket.ipv6.sin6_port)))
4239  return TRUE;
4240  break;
4241 #endif
4242  default:
4243  dbus_set_error (error,
4244  _dbus_error_from_errno (EINVAL),
4245  "Failed to read address from socket: Unknown socket type.");
4246  return FALSE;
4247  }
4248  err:
4249  dbus_set_error (error,
4250  _dbus_error_from_errno (errno),
4251  "Failed to open socket: %s",
4252  _dbus_strerror (errno));
4253  return FALSE;
4254 }
4255 
4256 /* 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:431
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&#39;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:388
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:304
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:738
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
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:306
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&#39;t supported (like ENOSYS on UNIX).
dbus_bool_t _dbus_append_address_from_socket(int fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
#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&#39;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:298
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:312
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.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:296
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:315
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c: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:181
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:610
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:461
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
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:429
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:300
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1111
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
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:314
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
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 &quot;1&quot;.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; &quot;something went wrong&quot; - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:808
#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.
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:504
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.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
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:222
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. ...
#define FALSE
Expands to &quot;0&quot;.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
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
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:810
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:102
int dbus_int32_t
A 32-bit signed integer on all platforms.
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:316
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
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:302