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