D-Bus  1.6.12
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)
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;
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 
891  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
892 
893  _dbus_verbose ("connecting to process %s\n", path);
894 
895  if (socketpair (AF_UNIX, SOCK_STREAM
896 #ifdef SOCK_CLOEXEC
897  |SOCK_CLOEXEC
898 #endif
899  , 0, fds) < 0)
900  {
901  dbus_set_error (error,
902  _dbus_error_from_errno (errno),
903  "Failed to create socket pair: %s",
904  _dbus_strerror (errno));
905  return -1;
906  }
907 
910 
911  pid = fork ();
912  if (pid < 0)
913  {
914  dbus_set_error (error,
915  _dbus_error_from_errno (errno),
916  "Failed to fork() to call %s: %s",
917  path, _dbus_strerror (errno));
918  close (fds[0]);
919  close (fds[1]);
920  return -1;
921  }
922 
923  if (pid == 0)
924  {
925  /* child */
926  close (fds[0]);
927 
928  dup2 (fds[1], STDIN_FILENO);
929  dup2 (fds[1], STDOUT_FILENO);
930 
931  if (fds[1] != STDIN_FILENO &&
932  fds[1] != STDOUT_FILENO)
933  close (fds[1]);
934 
935  /* Inherit STDERR and the controlling terminal from the
936  parent */
937 
938  _dbus_close_all ();
939 
940  execvp (path, argv);
941 
942  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
943 
944  _exit(1);
945  }
946 
947  /* parent */
948  close (fds[1]);
949 
950  if (!_dbus_set_fd_nonblocking (fds[0], error))
951  {
952  _DBUS_ASSERT_ERROR_IS_SET (error);
953 
954  close (fds[0]);
955  return -1;
956  }
957 
958  return fds[0];
959 }
960 
970 static dbus_bool_t
971 _dbus_set_local_creds (int fd, dbus_bool_t on)
972 {
973  dbus_bool_t retval = TRUE;
974 
975 #if defined(HAVE_CMSGCRED)
976  /* NOOP just to make sure only one codepath is used
977  * and to prefer CMSGCRED
978  */
979 #elif defined(LOCAL_CREDS)
980  int val = on ? 1 : 0;
981  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
982  {
983  _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
984  retval = FALSE;
985  }
986  else
987  _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
988  on ? "enabled" : "disabled", fd);
989 #endif
990 
991  return retval;
992 }
993 
1011 int
1012 _dbus_listen_unix_socket (const char *path,
1013  dbus_bool_t abstract,
1014  DBusError *error)
1015 {
1016  int listen_fd;
1017  struct sockaddr_un addr;
1018  size_t path_len;
1019  unsigned int reuseaddr;
1020 
1021  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1022 
1023  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1024  path, abstract);
1025 
1026  if (!_dbus_open_unix_socket (&listen_fd, error))
1027  {
1028  _DBUS_ASSERT_ERROR_IS_SET(error);
1029  return -1;
1030  }
1031  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1032 
1033  _DBUS_ZERO (addr);
1034  addr.sun_family = AF_UNIX;
1035  path_len = strlen (path);
1036 
1037  if (abstract)
1038  {
1039 #ifdef HAVE_ABSTRACT_SOCKETS
1040  /* remember that abstract names aren't nul-terminated so we rely
1041  * on sun_path being filled in with zeroes above.
1042  */
1043  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1044  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1045 
1046  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1047  {
1049  "Abstract socket name too long\n");
1050  _dbus_close (listen_fd, NULL);
1051  return -1;
1052  }
1053 
1054  strncpy (&addr.sun_path[1], path, path_len);
1055  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1056 #else /* HAVE_ABSTRACT_SOCKETS */
1058  "Operating system does not support abstract socket namespace\n");
1059  _dbus_close (listen_fd, NULL);
1060  return -1;
1061 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1062  }
1063  else
1064  {
1065  /* Discussed security implications of this with Nalin,
1066  * and we couldn't think of where it would kick our ass, but
1067  * it still seems a bit sucky. It also has non-security suckage;
1068  * really we'd prefer to exit if the socket is already in use.
1069  * But there doesn't seem to be a good way to do this.
1070  *
1071  * Just to be extra careful, I threw in the stat() - clearly
1072  * the stat() can't *fix* any security issue, but it at least
1073  * avoids inadvertent/accidental data loss.
1074  */
1075  {
1076  struct stat sb;
1077 
1078  if (stat (path, &sb) == 0 &&
1079  S_ISSOCK (sb.st_mode))
1080  unlink (path);
1081  }
1082 
1083  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1084  {
1086  "Abstract socket name too long\n");
1087  _dbus_close (listen_fd, NULL);
1088  return -1;
1089  }
1090 
1091  strncpy (addr.sun_path, path, path_len);
1092  }
1093 
1094  reuseaddr = 1;
1095  if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1096  {
1097  _dbus_warn ("Failed to set socket option\"%s\": %s",
1098  path, _dbus_strerror (errno));
1099  }
1100 
1101  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1102  {
1103  dbus_set_error (error, _dbus_error_from_errno (errno),
1104  "Failed to bind socket \"%s\": %s",
1105  path, _dbus_strerror (errno));
1106  _dbus_close (listen_fd, NULL);
1107  return -1;
1108  }
1109 
1110  if (listen (listen_fd, 30 /* backlog */) < 0)
1111  {
1112  dbus_set_error (error, _dbus_error_from_errno (errno),
1113  "Failed to listen on socket \"%s\": %s",
1114  path, _dbus_strerror (errno));
1115  _dbus_close (listen_fd, NULL);
1116  return -1;
1117  }
1118 
1119  if (!_dbus_set_local_creds (listen_fd, TRUE))
1120  {
1121  dbus_set_error (error, _dbus_error_from_errno (errno),
1122  "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1123  path, _dbus_strerror (errno));
1124  close (listen_fd);
1125  return -1;
1126  }
1127 
1128  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1129  {
1130  _DBUS_ASSERT_ERROR_IS_SET (error);
1131  _dbus_close (listen_fd, NULL);
1132  return -1;
1133  }
1134 
1135  /* Try opening up the permissions, but if we can't, just go ahead
1136  * and continue, maybe it will be good enough.
1137  */
1138  if (!abstract && chmod (path, 0777) < 0)
1139  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1140  path);
1141 
1142  return listen_fd;
1143 }
1144 
1155 int
1157  DBusError *error)
1158 {
1159  int r, n;
1160  unsigned fd;
1161  int *new_fds;
1162 
1163  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1164 
1165  n = sd_listen_fds (TRUE);
1166  if (n < 0)
1167  {
1169  "Failed to acquire systemd socket: %s",
1170  _dbus_strerror (-n));
1171  return -1;
1172  }
1173 
1174  if (n <= 0)
1175  {
1177  "No socket received.");
1178  return -1;
1179  }
1180 
1181  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1182  {
1183  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1184  if (r < 0)
1185  {
1187  "Failed to verify systemd socket type: %s",
1188  _dbus_strerror (-r));
1189  return -1;
1190  }
1191 
1192  if (!r)
1193  {
1195  "Passed socket has wrong type.");
1196  return -1;
1197  }
1198  }
1199 
1200  /* OK, the file descriptors are all good, so let's take posession of
1201  them then. */
1202 
1203  new_fds = dbus_new (int, n);
1204  if (!new_fds)
1205  {
1207  "Failed to allocate file handle array.");
1208  goto fail;
1209  }
1210 
1211  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1212  {
1213  if (!_dbus_set_local_creds (fd, TRUE))
1214  {
1215  dbus_set_error (error, _dbus_error_from_errno (errno),
1216  "Failed to enable LOCAL_CREDS on systemd socket: %s",
1217  _dbus_strerror (errno));
1218  goto fail;
1219  }
1220 
1221  if (!_dbus_set_fd_nonblocking (fd, error))
1222  {
1223  _DBUS_ASSERT_ERROR_IS_SET (error);
1224  goto fail;
1225  }
1226 
1227  new_fds[fd - SD_LISTEN_FDS_START] = fd;
1228  }
1229 
1230  *fds = new_fds;
1231  return n;
1232 
1233  fail:
1234 
1235  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1236  {
1237  _dbus_close (fd, NULL);
1238  }
1239 
1240  dbus_free (new_fds);
1241  return -1;
1242 }
1243 
1257 int
1258 _dbus_connect_tcp_socket (const char *host,
1259  const char *port,
1260  const char *family,
1261  DBusError *error)
1262 {
1263  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1264 }
1265 
1266 int
1267 _dbus_connect_tcp_socket_with_nonce (const char *host,
1268  const char *port,
1269  const char *family,
1270  const char *noncefile,
1271  DBusError *error)
1272 {
1273  int saved_errno = 0;
1274  int fd = -1, res;
1275  struct addrinfo hints;
1276  struct addrinfo *ai, *tmp;
1277 
1278  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1279 
1280  _DBUS_ZERO (hints);
1281 
1282  if (!family)
1283  hints.ai_family = AF_UNSPEC;
1284  else if (!strcmp(family, "ipv4"))
1285  hints.ai_family = AF_INET;
1286  else if (!strcmp(family, "ipv6"))
1287  hints.ai_family = AF_INET6;
1288  else
1289  {
1290  dbus_set_error (error,
1292  "Unknown address family %s", family);
1293  return -1;
1294  }
1295  hints.ai_protocol = IPPROTO_TCP;
1296  hints.ai_socktype = SOCK_STREAM;
1297  hints.ai_flags = AI_ADDRCONFIG;
1298 
1299  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1300  {
1301  dbus_set_error (error,
1302  _dbus_error_from_errno (errno),
1303  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1304  host, port, gai_strerror(res), res);
1305  return -1;
1306  }
1307 
1308  tmp = ai;
1309  while (tmp)
1310  {
1311  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1312  {
1313  freeaddrinfo(ai);
1314  _DBUS_ASSERT_ERROR_IS_SET(error);
1315  return -1;
1316  }
1317  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1318 
1319  if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1320  {
1321  saved_errno = errno;
1322  _dbus_close(fd, NULL);
1323  fd = -1;
1324  tmp = tmp->ai_next;
1325  continue;
1326  }
1327 
1328  break;
1329  }
1330  freeaddrinfo(ai);
1331 
1332  if (fd == -1)
1333  {
1334  dbus_set_error (error,
1335  _dbus_error_from_errno (saved_errno),
1336  "Failed to connect to socket \"%s:%s\" %s",
1337  host, port, _dbus_strerror(saved_errno));
1338  return -1;
1339  }
1340 
1341  if (noncefile != NULL)
1342  {
1343  DBusString noncefileStr;
1344  dbus_bool_t ret;
1345  _dbus_string_init_const (&noncefileStr, noncefile);
1346  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1347  _dbus_string_free (&noncefileStr);
1348 
1349  if (!ret)
1350  {
1351  _dbus_close (fd, NULL);
1352  return -1;
1353  }
1354  }
1355 
1356  if (!_dbus_set_fd_nonblocking (fd, error))
1357  {
1358  _dbus_close (fd, NULL);
1359  return -1;
1360  }
1361 
1362  return fd;
1363 }
1364 
1381 int
1382 _dbus_listen_tcp_socket (const char *host,
1383  const char *port,
1384  const char *family,
1385  DBusString *retport,
1386  int **fds_p,
1387  DBusError *error)
1388 {
1389  int saved_errno;
1390  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1391  struct addrinfo hints;
1392  struct addrinfo *ai, *tmp;
1393  unsigned int reuseaddr;
1394 
1395  *fds_p = NULL;
1396  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1397 
1398  _DBUS_ZERO (hints);
1399 
1400  if (!family)
1401  hints.ai_family = AF_UNSPEC;
1402  else if (!strcmp(family, "ipv4"))
1403  hints.ai_family = AF_INET;
1404  else if (!strcmp(family, "ipv6"))
1405  hints.ai_family = AF_INET6;
1406  else
1407  {
1408  dbus_set_error (error,
1410  "Unknown address family %s", family);
1411  return -1;
1412  }
1413 
1414  hints.ai_protocol = IPPROTO_TCP;
1415  hints.ai_socktype = SOCK_STREAM;
1416  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1417 
1418  redo_lookup_with_port:
1419  ai = NULL;
1420  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1421  {
1422  dbus_set_error (error,
1423  _dbus_error_from_errno (errno),
1424  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1425  host ? host : "*", port, gai_strerror(res), res);
1426  goto failed;
1427  }
1428 
1429  tmp = ai;
1430  while (tmp)
1431  {
1432  int fd = -1, *newlisten_fd;
1433  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1434  {
1435  _DBUS_ASSERT_ERROR_IS_SET(error);
1436  goto failed;
1437  }
1438  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1439 
1440  reuseaddr = 1;
1441  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1442  {
1443  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1444  host ? host : "*", port, _dbus_strerror (errno));
1445  }
1446 
1447  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1448  {
1449  saved_errno = errno;
1450  _dbus_close(fd, NULL);
1451  if (saved_errno == EADDRINUSE)
1452  {
1453  /* Depending on kernel policy, it may or may not
1454  be neccessary to bind to both IPv4 & 6 addresses
1455  so ignore EADDRINUSE here */
1456  tmp = tmp->ai_next;
1457  continue;
1458  }
1459  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1460  "Failed to bind socket \"%s:%s\": %s",
1461  host ? host : "*", port, _dbus_strerror (saved_errno));
1462  goto failed;
1463  }
1464 
1465  if (listen (fd, 30 /* backlog */) < 0)
1466  {
1467  saved_errno = errno;
1468  _dbus_close (fd, NULL);
1469  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1470  "Failed to listen on socket \"%s:%s\": %s",
1471  host ? host : "*", port, _dbus_strerror (saved_errno));
1472  goto failed;
1473  }
1474 
1475  newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1476  if (!newlisten_fd)
1477  {
1478  saved_errno = errno;
1479  _dbus_close (fd, NULL);
1480  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1481  "Failed to allocate file handle array: %s",
1482  _dbus_strerror (saved_errno));
1483  goto failed;
1484  }
1485  listen_fd = newlisten_fd;
1486  listen_fd[nlisten_fd] = fd;
1487  nlisten_fd++;
1488 
1489  if (!_dbus_string_get_length(retport))
1490  {
1491  /* If the user didn't specify a port, or used 0, then
1492  the kernel chooses a port. After the first address
1493  is bound to, we need to force all remaining addresses
1494  to use the same port */
1495  if (!port || !strcmp(port, "0"))
1496  {
1497  int result;
1498  struct sockaddr_storage addr;
1499  socklen_t addrlen;
1500  char portbuf[50];
1501 
1502  addrlen = sizeof(addr);
1503  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1504 
1505  if (result == -1 ||
1506  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1507  portbuf, sizeof(portbuf),
1508  NI_NUMERICHOST)) != 0)
1509  {
1510  dbus_set_error (error, _dbus_error_from_errno (errno),
1511  "Failed to resolve port \"%s:%s\": %s (%s)",
1512  host ? host : "*", port, gai_strerror(res), res);
1513  goto failed;
1514  }
1515  if (!_dbus_string_append(retport, portbuf))
1516  {
1518  goto failed;
1519  }
1520 
1521  /* Release current address list & redo lookup */
1522  port = _dbus_string_get_const_data(retport);
1523  freeaddrinfo(ai);
1524  goto redo_lookup_with_port;
1525  }
1526  else
1527  {
1528  if (!_dbus_string_append(retport, port))
1529  {
1531  goto failed;
1532  }
1533  }
1534  }
1535 
1536  tmp = tmp->ai_next;
1537  }
1538  freeaddrinfo(ai);
1539  ai = NULL;
1540 
1541  if (!nlisten_fd)
1542  {
1543  errno = EADDRINUSE;
1544  dbus_set_error (error, _dbus_error_from_errno (errno),
1545  "Failed to bind socket \"%s:%s\": %s",
1546  host ? host : "*", port, _dbus_strerror (errno));
1547  goto failed;
1548  }
1549 
1550  for (i = 0 ; i < nlisten_fd ; i++)
1551  {
1552  if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1553  {
1554  goto failed;
1555  }
1556  }
1557 
1558  *fds_p = listen_fd;
1559 
1560  return nlisten_fd;
1561 
1562  failed:
1563  if (ai)
1564  freeaddrinfo(ai);
1565  for (i = 0 ; i < nlisten_fd ; i++)
1566  _dbus_close(listen_fd[i], NULL);
1567  dbus_free(listen_fd);
1568  return -1;
1569 }
1570 
1571 static dbus_bool_t
1572 write_credentials_byte (int server_fd,
1573  DBusError *error)
1574 {
1575  int bytes_written;
1576  char buf[1] = { '\0' };
1577 #if defined(HAVE_CMSGCRED)
1578  union {
1579  struct cmsghdr hdr;
1580  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1581  } cmsg;
1582  struct iovec iov;
1583  struct msghdr msg;
1584  iov.iov_base = buf;
1585  iov.iov_len = 1;
1586 
1587  _DBUS_ZERO(msg);
1588  msg.msg_iov = &iov;
1589  msg.msg_iovlen = 1;
1590 
1591  msg.msg_control = (caddr_t) &cmsg;
1592  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1593  _DBUS_ZERO(cmsg);
1594  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1595  cmsg.hdr.cmsg_level = SOL_SOCKET;
1596  cmsg.hdr.cmsg_type = SCM_CREDS;
1597 #endif
1598 
1599  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1600 
1601  again:
1602 
1603 #if defined(HAVE_CMSGCRED)
1604  bytes_written = sendmsg (server_fd, &msg, 0
1605 #if HAVE_DECL_MSG_NOSIGNAL
1606  |MSG_NOSIGNAL
1607 #endif
1608  );
1609 #else
1610  bytes_written = send (server_fd, buf, 1, 0
1611 #if HAVE_DECL_MSG_NOSIGNAL
1612  |MSG_NOSIGNAL
1613 #endif
1614  );
1615 #endif
1616 
1617  if (bytes_written < 0 && errno == EINTR)
1618  goto again;
1619 
1620  if (bytes_written < 0)
1621  {
1622  dbus_set_error (error, _dbus_error_from_errno (errno),
1623  "Failed to write credentials byte: %s",
1624  _dbus_strerror (errno));
1625  return FALSE;
1626  }
1627  else if (bytes_written == 0)
1628  {
1630  "wrote zero bytes writing credentials byte");
1631  return FALSE;
1632  }
1633  else
1634  {
1635  _dbus_assert (bytes_written == 1);
1636  _dbus_verbose ("wrote credentials byte\n");
1637  return TRUE;
1638  }
1639 }
1640 
1664  DBusCredentials *credentials,
1665  DBusError *error)
1666 {
1667  struct msghdr msg;
1668  struct iovec iov;
1669  char buf;
1670  dbus_uid_t uid_read;
1671  dbus_pid_t pid_read;
1672  int bytes_read;
1673 
1674 #ifdef HAVE_CMSGCRED
1675  union {
1676  struct cmsghdr hdr;
1677  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1678  } cmsg;
1679 
1680 #elif defined(LOCAL_CREDS)
1681  struct {
1682  struct cmsghdr hdr;
1683  struct sockcred cred;
1684  } cmsg;
1685 #endif
1686 
1687  uid_read = DBUS_UID_UNSET;
1688  pid_read = DBUS_PID_UNSET;
1689 
1690  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1691 
1692  /* The POSIX spec certainly doesn't promise this, but
1693  * we need these assertions to fail as soon as we're wrong about
1694  * it so we can do the porting fixups
1695  */
1696  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1697  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1698  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1699 
1700  _dbus_credentials_clear (credentials);
1701 
1702  /* Systems supporting LOCAL_CREDS are configured to have this feature
1703  * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1704  * the connection. Therefore, the received message must carry the
1705  * credentials information without doing anything special.
1706  */
1707 
1708  iov.iov_base = &buf;
1709  iov.iov_len = 1;
1710 
1711  _DBUS_ZERO(msg);
1712  msg.msg_iov = &iov;
1713  msg.msg_iovlen = 1;
1714 
1715 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1716  _DBUS_ZERO(cmsg);
1717  msg.msg_control = (caddr_t) &cmsg;
1718  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1719 #endif
1720 
1721  again:
1722  bytes_read = recvmsg (client_fd, &msg, 0);
1723 
1724  if (bytes_read < 0)
1725  {
1726  if (errno == EINTR)
1727  goto again;
1728 
1729  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1730  * normally only call read_credentials if the socket was ready
1731  * for reading
1732  */
1733 
1734  dbus_set_error (error, _dbus_error_from_errno (errno),
1735  "Failed to read credentials byte: %s",
1736  _dbus_strerror (errno));
1737  return FALSE;
1738  }
1739  else if (bytes_read == 0)
1740  {
1741  /* this should not happen unless we are using recvmsg wrong,
1742  * so is essentially here for paranoia
1743  */
1745  "Failed to read credentials byte (zero-length read)");
1746  return FALSE;
1747  }
1748  else if (buf != '\0')
1749  {
1751  "Credentials byte was not nul");
1752  return FALSE;
1753  }
1754 
1755 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1756  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1757  || cmsg.hdr.cmsg_type != SCM_CREDS)
1758  {
1760  "Message from recvmsg() was not SCM_CREDS");
1761  return FALSE;
1762  }
1763 #endif
1764 
1765  _dbus_verbose ("read credentials byte\n");
1766 
1767  {
1768 #ifdef SO_PEERCRED
1769 #ifdef __OpenBSD__
1770  struct sockpeercred cr;
1771 #else
1772  struct ucred cr;
1773 #endif
1774  int cr_len = sizeof (cr);
1775 
1776  if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1777  cr_len == sizeof (cr))
1778  {
1779  pid_read = cr.pid;
1780  uid_read = cr.uid;
1781  }
1782  else
1783  {
1784  _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1785  cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1786  }
1787 #elif defined(HAVE_CMSGCRED)
1788  struct cmsgcred *cred;
1789 
1790  cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1791  pid_read = cred->cmcred_pid;
1792  uid_read = cred->cmcred_euid;
1793 #elif defined(LOCAL_CREDS)
1794  pid_read = DBUS_PID_UNSET;
1795  uid_read = cmsg.cred.sc_uid;
1796  /* Since we have already got the credentials from this socket, we can
1797  * disable its LOCAL_CREDS flag if it was ever set. */
1798  _dbus_set_local_creds (client_fd, FALSE);
1799 #elif defined(HAVE_GETPEEREID)
1800  uid_t euid;
1801  gid_t egid;
1802  if (getpeereid (client_fd, &euid, &egid) == 0)
1803  {
1804  uid_read = euid;
1805  }
1806  else
1807  {
1808  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1809  }
1810 #elif defined(HAVE_GETPEERUCRED)
1811  ucred_t * ucred = NULL;
1812  if (getpeerucred (client_fd, &ucred) == 0)
1813  {
1814  pid_read = ucred_getpid (ucred);
1815  uid_read = ucred_geteuid (ucred);
1816 #ifdef HAVE_ADT
1817  /* generate audit session data based on socket ucred */
1818  adt_session_data_t *adth = NULL;
1819  adt_export_data_t *data = NULL;
1820  size_t size = 0;
1821  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1822  {
1823  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1824  }
1825  else
1826  {
1827  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1828  {
1829  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1830  }
1831  else
1832  {
1833  size = adt_export_session_data (adth, &data);
1834  if (size <= 0)
1835  {
1836  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1837  }
1838  else
1839  {
1840  _dbus_credentials_add_adt_audit_data (credentials, data, size);
1841  free (data);
1842  }
1843  }
1844  (void) adt_end_session (adth);
1845  }
1846 #endif /* HAVE_ADT */
1847  }
1848  else
1849  {
1850  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1851  }
1852  if (ucred != NULL)
1853  ucred_free (ucred);
1854 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1855  _dbus_verbose ("Socket credentials not supported on this OS\n");
1856 #endif
1857  }
1858 
1859  _dbus_verbose ("Credentials:"
1860  " pid "DBUS_PID_FORMAT
1861  " uid "DBUS_UID_FORMAT
1862  "\n",
1863  pid_read,
1864  uid_read);
1865 
1866  if (pid_read != DBUS_PID_UNSET)
1867  {
1868  if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1869  {
1870  _DBUS_SET_OOM (error);
1871  return FALSE;
1872  }
1873  }
1874 
1875  if (uid_read != DBUS_UID_UNSET)
1876  {
1877  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1878  {
1879  _DBUS_SET_OOM (error);
1880  return FALSE;
1881  }
1882  }
1883 
1884  return TRUE;
1885 }
1886 
1906  DBusError *error)
1907 {
1908  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1909 
1910  if (write_credentials_byte (server_fd, error))
1911  return TRUE;
1912  else
1913  return FALSE;
1914 }
1915 
1925 int
1926 _dbus_accept (int listen_fd)
1927 {
1928  int client_fd;
1929  struct sockaddr addr;
1930  socklen_t addrlen;
1931 #ifdef HAVE_ACCEPT4
1932  dbus_bool_t cloexec_done;
1933 #endif
1934 
1935  addrlen = sizeof (addr);
1936 
1937  retry:
1938 
1939 #ifdef HAVE_ACCEPT4
1940  /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1941  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1942  cloexec_done = client_fd >= 0;
1943 
1944  if (client_fd < 0 && errno == ENOSYS)
1945 #endif
1946  {
1947  client_fd = accept (listen_fd, &addr, &addrlen);
1948  }
1949 
1950  if (client_fd < 0)
1951  {
1952  if (errno == EINTR)
1953  goto retry;
1954  }
1955 
1956  _dbus_verbose ("client fd %d accepted\n", client_fd);
1957 
1958 #ifdef HAVE_ACCEPT4
1959  if (!cloexec_done)
1960 #endif
1961  {
1962  _dbus_fd_set_close_on_exec(client_fd);
1963  }
1964 
1965  return client_fd;
1966 }
1967 
1978 {
1979  const char *directory;
1980  struct stat sb;
1981 
1982  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1983 
1984  directory = _dbus_string_get_const_data (dir);
1985 
1986  if (stat (directory, &sb) < 0)
1987  {
1988  dbus_set_error (error, _dbus_error_from_errno (errno),
1989  "%s", _dbus_strerror (errno));
1990 
1991  return FALSE;
1992  }
1993 
1994  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1995  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1996  {
1998  "%s directory is not private to the user", directory);
1999  return FALSE;
2000  }
2001 
2002  return TRUE;
2003 }
2004 
2005 static dbus_bool_t
2006 fill_user_info_from_passwd (struct passwd *p,
2007  DBusUserInfo *info,
2008  DBusError *error)
2009 {
2010  _dbus_assert (p->pw_name != NULL);
2011  _dbus_assert (p->pw_dir != NULL);
2012 
2013  info->uid = p->pw_uid;
2014  info->primary_gid = p->pw_gid;
2015  info->username = _dbus_strdup (p->pw_name);
2016  info->homedir = _dbus_strdup (p->pw_dir);
2017 
2018  if (info->username == NULL ||
2019  info->homedir == NULL)
2020  {
2022  return FALSE;
2023  }
2024 
2025  return TRUE;
2026 }
2027 
2028 static dbus_bool_t
2029 fill_user_info (DBusUserInfo *info,
2030  dbus_uid_t uid,
2031  const DBusString *username,
2032  DBusError *error)
2033 {
2034  const char *username_c;
2035 
2036  /* exactly one of username/uid provided */
2037  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2038  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2039 
2040  info->uid = DBUS_UID_UNSET;
2041  info->primary_gid = DBUS_GID_UNSET;
2042  info->group_ids = NULL;
2043  info->n_group_ids = 0;
2044  info->username = NULL;
2045  info->homedir = NULL;
2046 
2047  if (username != NULL)
2048  username_c = _dbus_string_get_const_data (username);
2049  else
2050  username_c = NULL;
2051 
2052  /* For now assuming that the getpwnam() and getpwuid() flavors
2053  * are always symmetrical, if not we have to add more configure
2054  * checks
2055  */
2056 
2057 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2058  {
2059  struct passwd *p;
2060  int result;
2061  size_t buflen;
2062  char *buf;
2063  struct passwd p_str;
2064 
2065  /* retrieve maximum needed size for buf */
2066  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2067 
2068  /* sysconf actually returns a long, but everything else expects size_t,
2069  * so just recast here.
2070  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2071  */
2072  if ((long) buflen <= 0)
2073  buflen = 1024;
2074 
2075  result = -1;
2076  while (1)
2077  {
2078  buf = dbus_malloc (buflen);
2079  if (buf == NULL)
2080  {
2082  return FALSE;
2083  }
2084 
2085  p = NULL;
2086 #ifdef HAVE_POSIX_GETPWNAM_R
2087  if (uid != DBUS_UID_UNSET)
2088  result = getpwuid_r (uid, &p_str, buf, buflen,
2089  &p);
2090  else
2091  result = getpwnam_r (username_c, &p_str, buf, buflen,
2092  &p);
2093 #else
2094  if (uid != DBUS_UID_UNSET)
2095  p = getpwuid_r (uid, &p_str, buf, buflen);
2096  else
2097  p = getpwnam_r (username_c, &p_str, buf, buflen);
2098  result = 0;
2099 #endif /* !HAVE_POSIX_GETPWNAM_R */
2100  //Try a bigger buffer if ERANGE was returned
2101  if (result == ERANGE && buflen < 512 * 1024)
2102  {
2103  dbus_free (buf);
2104  buflen *= 2;
2105  }
2106  else
2107  {
2108  break;
2109  }
2110  }
2111  if (result == 0 && p == &p_str)
2112  {
2113  if (!fill_user_info_from_passwd (p, info, error))
2114  {
2115  dbus_free (buf);
2116  return FALSE;
2117  }
2118  dbus_free (buf);
2119  }
2120  else
2121  {
2122  dbus_set_error (error, _dbus_error_from_errno (errno),
2123  "User \"%s\" unknown or no memory to allocate password entry\n",
2124  username_c ? username_c : "???");
2125  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2126  dbus_free (buf);
2127  return FALSE;
2128  }
2129  }
2130 #else /* ! HAVE_GETPWNAM_R */
2131  {
2132  /* I guess we're screwed on thread safety here */
2133  struct passwd *p;
2134 
2135  if (uid != DBUS_UID_UNSET)
2136  p = getpwuid (uid);
2137  else
2138  p = getpwnam (username_c);
2139 
2140  if (p != NULL)
2141  {
2142  if (!fill_user_info_from_passwd (p, info, error))
2143  {
2144  return FALSE;
2145  }
2146  }
2147  else
2148  {
2149  dbus_set_error (error, _dbus_error_from_errno (errno),
2150  "User \"%s\" unknown or no memory to allocate password entry\n",
2151  username_c ? username_c : "???");
2152  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2153  return FALSE;
2154  }
2155  }
2156 #endif /* ! HAVE_GETPWNAM_R */
2157 
2158  /* Fill this in so we can use it to get groups */
2159  username_c = info->username;
2160 
2161 #ifdef HAVE_GETGROUPLIST
2162  {
2163  gid_t *buf;
2164  int buf_count;
2165  int i;
2166  int initial_buf_count;
2167 
2168  initial_buf_count = 17;
2169  buf_count = initial_buf_count;
2170  buf = dbus_new (gid_t, buf_count);
2171  if (buf == NULL)
2172  {
2174  goto failed;
2175  }
2176 
2177  if (getgrouplist (username_c,
2178  info->primary_gid,
2179  buf, &buf_count) < 0)
2180  {
2181  gid_t *new;
2182  /* Presumed cause of negative return code: buf has insufficient
2183  entries to hold the entire group list. The Linux behavior in this
2184  case is to pass back the actual number of groups in buf_count, but
2185  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2186  So as a hack, try to help out a bit by guessing a larger
2187  number of groups, within reason.. might still fail, of course,
2188  but we can at least print a more informative message. I looked up
2189  the "right way" to do this by downloading Apple's own source code
2190  for the "id" command, and it turns out that they use an
2191  undocumented library function getgrouplist_2 (!) which is not
2192  declared in any header in /usr/include (!!). That did not seem
2193  like the way to go here.
2194  */
2195  if (buf_count == initial_buf_count)
2196  {
2197  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2198  }
2199  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2200  if (new == NULL)
2201  {
2203  dbus_free (buf);
2204  goto failed;
2205  }
2206 
2207  buf = new;
2208 
2209  errno = 0;
2210  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2211  {
2212  if (errno == 0)
2213  {
2214  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2215  username_c, buf_count, buf_count);
2216  }
2217  else
2218  {
2219  dbus_set_error (error,
2220  _dbus_error_from_errno (errno),
2221  "Failed to get groups for username \"%s\" primary GID "
2222  DBUS_GID_FORMAT ": %s\n",
2223  username_c, info->primary_gid,
2224  _dbus_strerror (errno));
2225  dbus_free (buf);
2226  goto failed;
2227  }
2228  }
2229  }
2230 
2231  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2232  if (info->group_ids == NULL)
2233  {
2235  dbus_free (buf);
2236  goto failed;
2237  }
2238 
2239  for (i = 0; i < buf_count; ++i)
2240  info->group_ids[i] = buf[i];
2241 
2242  info->n_group_ids = buf_count;
2243 
2244  dbus_free (buf);
2245  }
2246 #else /* HAVE_GETGROUPLIST */
2247  {
2248  /* We just get the one group ID */
2249  info->group_ids = dbus_new (dbus_gid_t, 1);
2250  if (info->group_ids == NULL)
2251  {
2253  goto failed;
2254  }
2255 
2256  info->n_group_ids = 1;
2257 
2258  (info->group_ids)[0] = info->primary_gid;
2259  }
2260 #endif /* HAVE_GETGROUPLIST */
2261 
2262  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2263 
2264  return TRUE;
2265 
2266  failed:
2267  _DBUS_ASSERT_ERROR_IS_SET (error);
2268  return FALSE;
2269 }
2270 
2281  const DBusString *username,
2282  DBusError *error)
2283 {
2284  return fill_user_info (info, DBUS_UID_UNSET,
2285  username, error);
2286 }
2287 
2298  dbus_uid_t uid,
2299  DBusError *error)
2300 {
2301  return fill_user_info (info, uid,
2302  NULL, error);
2303 }
2304 
2314 {
2315  /* The POSIX spec certainly doesn't promise this, but
2316  * we need these assertions to fail as soon as we're wrong about
2317  * it so we can do the porting fixups
2318  */
2319  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2320  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2321  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2322 
2323  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2324  return FALSE;
2325  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2326  return FALSE;
2327 
2328  return TRUE;
2329 }
2330 
2344 {
2345  return _dbus_string_append_uint (str,
2346  _dbus_geteuid ());
2347 }
2348 
2353 dbus_pid_t
2355 {
2356  return getpid ();
2357 }
2358 
2362 dbus_uid_t
2364 {
2365  return getuid ();
2366 }
2367 
2371 dbus_uid_t
2373 {
2374  return geteuid ();
2375 }
2376 
2383 unsigned long
2385 {
2386  return getpid ();
2387 }
2388 
2397 _dbus_parse_uid (const DBusString *uid_str,
2398  dbus_uid_t *uid)
2399 {
2400  int end;
2401  long val;
2402 
2403  if (_dbus_string_get_length (uid_str) == 0)
2404  {
2405  _dbus_verbose ("UID string was zero length\n");
2406  return FALSE;
2407  }
2408 
2409  val = -1;
2410  end = 0;
2411  if (!_dbus_string_parse_int (uid_str, 0, &val,
2412  &end))
2413  {
2414  _dbus_verbose ("could not parse string as a UID\n");
2415  return FALSE;
2416  }
2417 
2418  if (end != _dbus_string_get_length (uid_str))
2419  {
2420  _dbus_verbose ("string contained trailing stuff after UID\n");
2421  return FALSE;
2422  }
2423 
2424  *uid = val;
2425 
2426  return TRUE;
2427 }
2428 
2429 #if !DBUS_USE_SYNC
2430 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2431 #endif
2432 
2441 {
2442 #if DBUS_USE_SYNC
2443  return __sync_add_and_fetch(&atomic->value, 1)-1;
2444 #else
2445  dbus_int32_t res;
2446  _DBUS_LOCK (atomic);
2447  res = atomic->value;
2448  atomic->value += 1;
2449  _DBUS_UNLOCK (atomic);
2450  return res;
2451 #endif
2452 }
2453 
2462 {
2463 #if DBUS_USE_SYNC
2464  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2465 #else
2466  dbus_int32_t res;
2467 
2468  _DBUS_LOCK (atomic);
2469  res = atomic->value;
2470  atomic->value -= 1;
2471  _DBUS_UNLOCK (atomic);
2472  return res;
2473 #endif
2474 }
2475 
2485 {
2486 #if DBUS_USE_SYNC
2487  __sync_synchronize ();
2488  return atomic->value;
2489 #else
2490  dbus_int32_t res;
2491 
2492  _DBUS_LOCK (atomic);
2493  res = atomic->value;
2494  _DBUS_UNLOCK (atomic);
2495  return res;
2496 #endif
2497 }
2498 
2507 int
2509  int n_fds,
2510  int timeout_milliseconds)
2511 {
2512 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2513  /* This big thing is a constant expression and should get optimized
2514  * out of existence. So it's more robust than a configure check at
2515  * no cost.
2516  */
2517  if (_DBUS_POLLIN == POLLIN &&
2518  _DBUS_POLLPRI == POLLPRI &&
2519  _DBUS_POLLOUT == POLLOUT &&
2520  _DBUS_POLLERR == POLLERR &&
2521  _DBUS_POLLHUP == POLLHUP &&
2522  _DBUS_POLLNVAL == POLLNVAL &&
2523  sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2524  _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2525  _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2526  _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2527  _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2528  _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2529  _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2530  {
2531  return poll ((struct pollfd*) fds,
2532  n_fds,
2533  timeout_milliseconds);
2534  }
2535  else
2536  {
2537  /* We have to convert the DBusPollFD to an array of
2538  * struct pollfd, poll, and convert back.
2539  */
2540  _dbus_warn ("didn't implement poll() properly for this system yet\n");
2541  return -1;
2542  }
2543 #else /* ! HAVE_POLL */
2544 
2545  fd_set read_set, write_set, err_set;
2546  int max_fd = 0;
2547  int i;
2548  struct timeval tv;
2549  int ready;
2550 
2551  FD_ZERO (&read_set);
2552  FD_ZERO (&write_set);
2553  FD_ZERO (&err_set);
2554 
2555  for (i = 0; i < n_fds; i++)
2556  {
2557  DBusPollFD *fdp = &fds[i];
2558 
2559  if (fdp->events & _DBUS_POLLIN)
2560  FD_SET (fdp->fd, &read_set);
2561 
2562  if (fdp->events & _DBUS_POLLOUT)
2563  FD_SET (fdp->fd, &write_set);
2564 
2565  FD_SET (fdp->fd, &err_set);
2566 
2567  max_fd = MAX (max_fd, fdp->fd);
2568  }
2569 
2570  tv.tv_sec = timeout_milliseconds / 1000;
2571  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2572 
2573  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2574  timeout_milliseconds < 0 ? NULL : &tv);
2575 
2576  if (ready > 0)
2577  {
2578  for (i = 0; i < n_fds; i++)
2579  {
2580  DBusPollFD *fdp = &fds[i];
2581 
2582  fdp->revents = 0;
2583 
2584  if (FD_ISSET (fdp->fd, &read_set))
2585  fdp->revents |= _DBUS_POLLIN;
2586 
2587  if (FD_ISSET (fdp->fd, &write_set))
2588  fdp->revents |= _DBUS_POLLOUT;
2589 
2590  if (FD_ISSET (fdp->fd, &err_set))
2591  fdp->revents |= _DBUS_POLLERR;
2592  }
2593  }
2594 
2595  return ready;
2596 #endif
2597 }
2598 
2606 void
2608  long *tv_usec)
2609 {
2610 #ifdef HAVE_MONOTONIC_CLOCK
2611  struct timespec ts;
2612  clock_gettime (CLOCK_MONOTONIC, &ts);
2613 
2614  if (tv_sec)
2615  *tv_sec = ts.tv_sec;
2616  if (tv_usec)
2617  *tv_usec = ts.tv_nsec / 1000;
2618 #else
2619  struct timeval t;
2620 
2621  gettimeofday (&t, NULL);
2622 
2623  if (tv_sec)
2624  *tv_sec = t.tv_sec;
2625  if (tv_usec)
2626  *tv_usec = t.tv_usec;
2627 #endif
2628 }
2629 
2637 void
2638 _dbus_get_real_time (long *tv_sec,
2639  long *tv_usec)
2640 {
2641  struct timeval t;
2642 
2643  gettimeofday (&t, NULL);
2644 
2645  if (tv_sec)
2646  *tv_sec = t.tv_sec;
2647  if (tv_usec)
2648  *tv_usec = t.tv_usec;
2649 }
2650 
2661  DBusError *error)
2662 {
2663  const char *filename_c;
2664 
2665  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2666 
2667  filename_c = _dbus_string_get_const_data (filename);
2668 
2669  if (mkdir (filename_c, 0700) < 0)
2670  {
2671  if (errno == EEXIST)
2672  return TRUE;
2673 
2675  "Failed to create directory %s: %s\n",
2676  filename_c, _dbus_strerror (errno));
2677  return FALSE;
2678  }
2679  else
2680  return TRUE;
2681 }
2682 
2695  const DBusString *next_component)
2696 {
2697  dbus_bool_t dir_ends_in_slash;
2698  dbus_bool_t file_starts_with_slash;
2699 
2700  if (_dbus_string_get_length (dir) == 0 ||
2701  _dbus_string_get_length (next_component) == 0)
2702  return TRUE;
2703 
2704  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2705  _dbus_string_get_length (dir) - 1);
2706 
2707  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2708 
2709  if (dir_ends_in_slash && file_starts_with_slash)
2710  {
2711  _dbus_string_shorten (dir, 1);
2712  }
2713  else if (!(dir_ends_in_slash || file_starts_with_slash))
2714  {
2715  if (!_dbus_string_append_byte (dir, '/'))
2716  return FALSE;
2717  }
2718 
2719  return _dbus_string_copy (next_component, 0, dir,
2720  _dbus_string_get_length (dir));
2721 }
2722 
2724 #define NANOSECONDS_PER_SECOND 1000000000
2725 
2726 #define MICROSECONDS_PER_SECOND 1000000
2727 
2728 #define MILLISECONDS_PER_SECOND 1000
2729 
2730 #define NANOSECONDS_PER_MILLISECOND 1000000
2731 
2732 #define MICROSECONDS_PER_MILLISECOND 1000
2733 
2738 void
2739 _dbus_sleep_milliseconds (int milliseconds)
2740 {
2741 #ifdef HAVE_NANOSLEEP
2742  struct timespec req;
2743  struct timespec rem;
2744 
2745  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2746  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2747  rem.tv_sec = 0;
2748  rem.tv_nsec = 0;
2749 
2750  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2751  req = rem;
2752 #elif defined (HAVE_USLEEP)
2753  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2754 #else /* ! HAVE_USLEEP */
2755  sleep (MAX (milliseconds / 1000, 1));
2756 #endif
2757 }
2758 
2759 static dbus_bool_t
2760 _dbus_generate_pseudorandom_bytes (DBusString *str,
2761  int n_bytes)
2762 {
2763  int old_len;
2764  char *p;
2765 
2766  old_len = _dbus_string_get_length (str);
2767 
2768  if (!_dbus_string_lengthen (str, n_bytes))
2769  return FALSE;
2770 
2771  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2772 
2774 
2775  return TRUE;
2776 }
2777 
2788  int n_bytes)
2789 {
2790  int old_len;
2791  int fd;
2792 
2793  /* FALSE return means "no memory", if it could
2794  * mean something else then we'd need to return
2795  * a DBusError. So we always fall back to pseudorandom
2796  * if the I/O fails.
2797  */
2798 
2799  old_len = _dbus_string_get_length (str);
2800  fd = -1;
2801 
2802  /* note, urandom on linux will fall back to pseudorandom */
2803  fd = open ("/dev/urandom", O_RDONLY);
2804  if (fd < 0)
2805  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2806 
2807  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2808 
2809  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2810  {
2811  _dbus_close (fd, NULL);
2812  _dbus_string_set_length (str, old_len);
2813  return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2814  }
2815 
2816  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2817  n_bytes);
2818 
2819  _dbus_close (fd, NULL);
2820 
2821  return TRUE;
2822 }
2823 
2829 void
2830 _dbus_exit (int code)
2831 {
2832  _exit (code);
2833 }
2834 
2843 const char*
2844 _dbus_strerror (int error_number)
2845 {
2846  const char *msg;
2847 
2848  msg = strerror (error_number);
2849  if (msg == NULL)
2850  msg = "unknown";
2851 
2852  return msg;
2853 }
2854 
2858 void
2860 {
2861  signal (SIGPIPE, SIG_IGN);
2862 }
2863 
2871 void
2873 {
2874  int val;
2875 
2876  val = fcntl (fd, F_GETFD, 0);
2877 
2878  if (val < 0)
2879  return;
2880 
2881  val |= FD_CLOEXEC;
2882 
2883  fcntl (fd, F_SETFD, val);
2884 }
2885 
2894 _dbus_close (int fd,
2895  DBusError *error)
2896 {
2897  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2898 
2899  again:
2900  if (close (fd) < 0)
2901  {
2902  if (errno == EINTR)
2903  goto again;
2904 
2905  dbus_set_error (error, _dbus_error_from_errno (errno),
2906  "Could not close fd %d", fd);
2907  return FALSE;
2908  }
2909 
2910  return TRUE;
2911 }
2912 
2920 int
2921 _dbus_dup(int fd,
2922  DBusError *error)
2923 {
2924  int new_fd;
2925 
2926 #ifdef F_DUPFD_CLOEXEC
2927  dbus_bool_t cloexec_done;
2928 
2929  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2930  cloexec_done = new_fd >= 0;
2931 
2932  if (new_fd < 0 && errno == EINVAL)
2933 #endif
2934  {
2935  new_fd = fcntl(fd, F_DUPFD, 3);
2936  }
2937 
2938  if (new_fd < 0) {
2939 
2940  dbus_set_error (error, _dbus_error_from_errno (errno),
2941  "Could not duplicate fd %d", fd);
2942  return -1;
2943  }
2944 
2945 #ifdef F_DUPFD_CLOEXEC
2946  if (!cloexec_done)
2947 #endif
2948  {
2950  }
2951 
2952  return new_fd;
2953 }
2954 
2963 _dbus_set_fd_nonblocking (int fd,
2964  DBusError *error)
2965 {
2966  int val;
2967 
2968  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2969 
2970  val = fcntl (fd, F_GETFL, 0);
2971  if (val < 0)
2972  {
2973  dbus_set_error (error, _dbus_error_from_errno (errno),
2974  "Failed to get flags from file descriptor %d: %s",
2975  fd, _dbus_strerror (errno));
2976  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2977  _dbus_strerror (errno));
2978  return FALSE;
2979  }
2980 
2981  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2982  {
2983  dbus_set_error (error, _dbus_error_from_errno (errno),
2984  "Failed to set nonblocking flag of file descriptor %d: %s",
2985  fd, _dbus_strerror (errno));
2986  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2987  fd, _dbus_strerror (errno));
2988 
2989  return FALSE;
2990  }
2991 
2992  return TRUE;
2993 }
2994 
3000 void
3002 {
3003 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3004  void *bt[500];
3005  int bt_size;
3006  int i;
3007  char **syms;
3008 
3009  bt_size = backtrace (bt, 500);
3010 
3011  syms = backtrace_symbols (bt, bt_size);
3012 
3013  i = 0;
3014  while (i < bt_size)
3015  {
3016  /* don't use dbus_warn since it can _dbus_abort() */
3017  fprintf (stderr, " %s\n", syms[i]);
3018  ++i;
3019  }
3020  fflush (stderr);
3021 
3022  free (syms);
3023 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3024  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3025 #else
3026  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3027 #endif
3028 }
3029 
3044  int *fd2,
3045  dbus_bool_t blocking,
3046  DBusError *error)
3047 {
3048 #ifdef HAVE_SOCKETPAIR
3049  int fds[2];
3050  int retval;
3051 
3052 #ifdef SOCK_CLOEXEC
3053  dbus_bool_t cloexec_done;
3054 
3055  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3056  cloexec_done = retval >= 0;
3057 
3058  if (retval < 0 && errno == EINVAL)
3059 #endif
3060  {
3061  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3062  }
3063 
3064  if (retval < 0)
3065  {
3066  dbus_set_error (error, _dbus_error_from_errno (errno),
3067  "Could not create full-duplex pipe");
3068  return FALSE;
3069  }
3070 
3071  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3072 
3073 #ifdef SOCK_CLOEXEC
3074  if (!cloexec_done)
3075 #endif
3076  {
3077  _dbus_fd_set_close_on_exec (fds[0]);
3078  _dbus_fd_set_close_on_exec (fds[1]);
3079  }
3080 
3081  if (!blocking &&
3082  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3083  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3084  {
3085  dbus_set_error (error, _dbus_error_from_errno (errno),
3086  "Could not set full-duplex pipe nonblocking");
3087 
3088  _dbus_close (fds[0], NULL);
3089  _dbus_close (fds[1], NULL);
3090 
3091  return FALSE;
3092  }
3093 
3094  *fd1 = fds[0];
3095  *fd2 = fds[1];
3096 
3097  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3098  *fd1, *fd2);
3099 
3100  return TRUE;
3101 #else
3102  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3104  "_dbus_full_duplex_pipe() not implemented on this OS");
3105  return FALSE;
3106 #endif
3107 }
3108 
3117 int
3119  va_list args)
3120 {
3121  char static_buf[1024];
3122  int bufsize = sizeof (static_buf);
3123  int len;
3124  va_list args_copy;
3125 
3126  DBUS_VA_COPY (args_copy, args);
3127  len = vsnprintf (static_buf, bufsize, format, args_copy);
3128  va_end (args_copy);
3129 
3130  /* If vsnprintf() returned non-negative, then either the string fits in
3131  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3132  * returns the number of characters that were needed, or this OS returns the
3133  * truncated length.
3134  *
3135  * We ignore the possibility that snprintf might just ignore the length and
3136  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3137  * If your libc is really that bad, come back when you have a better one. */
3138  if (len == bufsize)
3139  {
3140  /* This could be the truncated length (Tru64 and IRIX have this bug),
3141  * or the real length could be coincidentally the same. Which is it?
3142  * If vsnprintf returns the truncated length, we'll go to the slow
3143  * path. */
3144  DBUS_VA_COPY (args_copy, args);
3145 
3146  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3147  len = -1;
3148 
3149  va_end (args_copy);
3150  }
3151 
3152  /* If vsnprintf() returned negative, we have to do more work.
3153  * HP-UX returns negative. */
3154  while (len < 0)
3155  {
3156  char *buf;
3157 
3158  bufsize *= 2;
3159 
3160  buf = dbus_malloc (bufsize);
3161 
3162  if (buf == NULL)
3163  return -1;
3164 
3165  DBUS_VA_COPY (args_copy, args);
3166  len = vsnprintf (buf, bufsize, format, args_copy);
3167  va_end (args_copy);
3168 
3169  dbus_free (buf);
3170 
3171  /* If the reported length is exactly the buffer size, round up to the
3172  * next size, in case vsnprintf has been returning the truncated
3173  * length */
3174  if (len == bufsize)
3175  len = -1;
3176  }
3177 
3178  return len;
3179 }
3180 
3187 const char*
3189 {
3190  static const char* tmpdir = NULL;
3191 
3192  if (tmpdir == NULL)
3193  {
3194  /* TMPDIR is what glibc uses, then
3195  * glibc falls back to the P_tmpdir macro which
3196  * just expands to "/tmp"
3197  */
3198  if (tmpdir == NULL)
3199  tmpdir = getenv("TMPDIR");
3200 
3201  /* These two env variables are probably
3202  * broken, but maybe some OS uses them?
3203  */
3204  if (tmpdir == NULL)
3205  tmpdir = getenv("TMP");
3206  if (tmpdir == NULL)
3207  tmpdir = getenv("TEMP");
3208 
3209  /* And this is the sane fallback. */
3210  if (tmpdir == NULL)
3211  tmpdir = "/tmp";
3212  }
3213 
3214  _dbus_assert(tmpdir != NULL);
3215 
3216  return tmpdir;
3217 }
3218 
3238 static dbus_bool_t
3239 _read_subprocess_line_argv (const char *progpath,
3240  dbus_bool_t path_fallback,
3241  char * const *argv,
3242  DBusString *result,
3243  DBusError *error)
3244 {
3245  int result_pipe[2] = { -1, -1 };
3246  int errors_pipe[2] = { -1, -1 };
3247  pid_t pid;
3248  int ret;
3249  int status;
3250  int orig_len;
3251 
3252  dbus_bool_t retval;
3253  sigset_t new_set, old_set;
3254 
3255  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3256  retval = FALSE;
3257 
3258  /* We need to block any existing handlers for SIGCHLD temporarily; they
3259  * will cause waitpid() below to fail.
3260  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3261  */
3262  sigemptyset (&new_set);
3263  sigaddset (&new_set, SIGCHLD);
3264  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3265 
3266  orig_len = _dbus_string_get_length (result);
3267 
3268 #define READ_END 0
3269 #define WRITE_END 1
3270  if (pipe (result_pipe) < 0)
3271  {
3272  dbus_set_error (error, _dbus_error_from_errno (errno),
3273  "Failed to create a pipe to call %s: %s",
3274  progpath, _dbus_strerror (errno));
3275  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3276  progpath, _dbus_strerror (errno));
3277  goto out;
3278  }
3279  if (pipe (errors_pipe) < 0)
3280  {
3281  dbus_set_error (error, _dbus_error_from_errno (errno),
3282  "Failed to create a pipe to call %s: %s",
3283  progpath, _dbus_strerror (errno));
3284  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3285  progpath, _dbus_strerror (errno));
3286  goto out;
3287  }
3288 
3289  pid = fork ();
3290  if (pid < 0)
3291  {
3292  dbus_set_error (error, _dbus_error_from_errno (errno),
3293  "Failed to fork() to call %s: %s",
3294  progpath, _dbus_strerror (errno));
3295  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3296  progpath, _dbus_strerror (errno));
3297  goto out;
3298  }
3299 
3300  if (pid == 0)
3301  {
3302  /* child process */
3303  int fd;
3304 
3305  fd = open ("/dev/null", O_RDWR);
3306  if (fd == -1)
3307  /* huh?! can't open /dev/null? */
3308  _exit (1);
3309 
3310  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3311 
3312  /* set-up stdXXX */
3313  close (result_pipe[READ_END]);
3314  close (errors_pipe[READ_END]);
3315  close (0); /* close stdin */
3316  close (1); /* close stdout */
3317  close (2); /* close stderr */
3318 
3319  if (dup2 (fd, 0) == -1)
3320  _exit (1);
3321  if (dup2 (result_pipe[WRITE_END], 1) == -1)
3322  _exit (1);
3323  if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3324  _exit (1);
3325 
3326  _dbus_close_all ();
3327 
3328  sigprocmask (SIG_SETMASK, &old_set, NULL);
3329 
3330  /* If it looks fully-qualified, try execv first */
3331  if (progpath[0] == '/')
3332  {
3333  execv (progpath, argv);
3334  /* Ok, that failed. Now if path_fallback is given, let's
3335  * try unqualified. This is mostly a hack to work
3336  * around systems which ship dbus-launch in /usr/bin
3337  * but everything else in /bin (because dbus-launch
3338  * depends on X11).
3339  */
3340  if (path_fallback)
3341  /* We must have a slash, because we checked above */
3342  execvp (strrchr (progpath, '/')+1, argv);
3343  }
3344  else
3345  execvp (progpath, argv);
3346 
3347  /* still nothing, we failed */
3348  _exit (1);
3349  }
3350 
3351  /* parent process */
3352  close (result_pipe[WRITE_END]);
3353  close (errors_pipe[WRITE_END]);
3354  result_pipe[WRITE_END] = -1;
3355  errors_pipe[WRITE_END] = -1;
3356 
3357  ret = 0;
3358  do
3359  {
3360  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3361  }
3362  while (ret > 0);
3363 
3364  /* reap the child process to avoid it lingering as zombie */
3365  do
3366  {
3367  ret = waitpid (pid, &status, 0);
3368  }
3369  while (ret == -1 && errno == EINTR);
3370 
3371  /* We succeeded if the process exited with status 0 and
3372  anything was read */
3373  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3374  {
3375  /* The process ended with error */
3376  DBusString error_message;
3377  if (!_dbus_string_init (&error_message))
3378  {
3379  _DBUS_SET_OOM (error);
3380  goto out;
3381  }
3382 
3383  ret = 0;
3384  do
3385  {
3386  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3387  }
3388  while (ret > 0);
3389 
3390  _dbus_string_set_length (result, orig_len);
3391  if (_dbus_string_get_length (&error_message) > 0)
3393  "%s terminated abnormally with the following error: %s",
3394  progpath, _dbus_string_get_data (&error_message));
3395  else
3397  "%s terminated abnormally without any error message",
3398  progpath);
3399  goto out;
3400  }
3401 
3402  retval = TRUE;
3403 
3404  out:
3405  sigprocmask (SIG_SETMASK, &old_set, NULL);
3406 
3407  if (retval)
3408  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3409  else
3410  _DBUS_ASSERT_ERROR_IS_SET (error);
3411 
3412  if (result_pipe[0] != -1)
3413  close (result_pipe[0]);
3414  if (result_pipe[1] != -1)
3415  close (result_pipe[1]);
3416  if (errors_pipe[0] != -1)
3417  close (errors_pipe[0]);
3418  if (errors_pipe[1] != -1)
3419  close (errors_pipe[1]);
3420 
3421  return retval;
3422 }
3423 
3436 _dbus_get_autolaunch_address (const char *scope,
3437  DBusString *address,
3438  DBusError *error)
3439 {
3440 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3441  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3442  * but that's done elsewhere, and if it worked, this function wouldn't
3443  * be called.) */
3444  const char *display;
3445  static char *argv[6];
3446  int i;
3447  DBusString uuid;
3448  dbus_bool_t retval;
3449 
3450  if (_dbus_check_setuid ())
3451  {
3453  "Unable to autolaunch when setuid");
3454  return FALSE;
3455  }
3456 
3457  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3458  retval = FALSE;
3459 
3460  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3461  * dbus-launch-x11 is just going to fail. Rather than trying to
3462  * run it, we might as well bail out early with a nice error. */
3463  display = _dbus_getenv ("DISPLAY");
3464 
3465  if (display == NULL || display[0] == '\0')
3466  {
3468  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3469  return FALSE;
3470  }
3471 
3472  if (!_dbus_string_init (&uuid))
3473  {
3474  _DBUS_SET_OOM (error);
3475  return FALSE;
3476  }
3477 
3479  {
3480  _DBUS_SET_OOM (error);
3481  goto out;
3482  }
3483 
3484  i = 0;
3485  argv[i] = "dbus-launch";
3486  ++i;
3487  argv[i] = "--autolaunch";
3488  ++i;
3489  argv[i] = _dbus_string_get_data (&uuid);
3490  ++i;
3491  argv[i] = "--binary-syntax";
3492  ++i;
3493  argv[i] = "--close-stderr";
3494  ++i;
3495  argv[i] = NULL;
3496  ++i;
3497 
3498  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3499 
3500  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3501  TRUE,
3502  argv, address, error);
3503 
3504  out:
3505  _dbus_string_free (&uuid);
3506  return retval;
3507 #else
3509  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3510  "set your DBUS_SESSION_BUS_ADDRESS instead");
3511  return FALSE;
3512 #endif
3513 }
3514 
3535  dbus_bool_t create_if_not_found,
3536  DBusError *error)
3537 {
3538  DBusString filename;
3539  dbus_bool_t b;
3540 
3541  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3542 
3543  b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3544  if (b)
3545  return TRUE;
3546 
3547  dbus_error_free (error);
3548 
3549  /* Fallback to the system machine ID */
3550  _dbus_string_init_const (&filename, "/etc/machine-id");
3551  return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3552 }
3553 
3554 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3555 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3556 
3565  const char *launchd_env_var,
3566  DBusError *error)
3567 {
3568 #ifdef DBUS_ENABLE_LAUNCHD
3569  char *argv[4];
3570  int i;
3571 
3572  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3573 
3574  if (_dbus_check_setuid ())
3575  {
3577  "Unable to find launchd socket when setuid");
3578  return FALSE;
3579  }
3580 
3581  i = 0;
3582  argv[i] = "launchctl";
3583  ++i;
3584  argv[i] = "getenv";
3585  ++i;
3586  argv[i] = (char*)launchd_env_var;
3587  ++i;
3588  argv[i] = NULL;
3589  ++i;
3590 
3591  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3592 
3593  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3594  {
3595  return FALSE;
3596  }
3597 
3598  /* no error, but no result either */
3599  if (_dbus_string_get_length(socket_path) == 0)
3600  {
3601  return FALSE;
3602  }
3603 
3604  /* strip the carriage-return */
3605  _dbus_string_shorten(socket_path, 1);
3606  return TRUE;
3607 #else /* DBUS_ENABLE_LAUNCHD */
3609  "can't lookup socket from launchd; launchd support not compiled in");
3610  return FALSE;
3611 #endif
3612 }
3613 
3614 #ifdef DBUS_ENABLE_LAUNCHD
3615 static dbus_bool_t
3616 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3617 {
3618  dbus_bool_t valid_socket;
3619  DBusString socket_path;
3620 
3621  if (_dbus_check_setuid ())
3622  {
3624  "Unable to find launchd socket when setuid");
3625  return FALSE;
3626  }
3627 
3628  if (!_dbus_string_init (&socket_path))
3629  {
3630  _DBUS_SET_OOM (error);
3631  return FALSE;
3632  }
3633 
3634  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3635 
3636  if (dbus_error_is_set(error))
3637  {
3638  _dbus_string_free(&socket_path);
3639  return FALSE;
3640  }
3641 
3642  if (!valid_socket)
3643  {
3644  dbus_set_error(error, "no socket path",
3645  "launchd did not provide a socket path, "
3646  "verify that org.freedesktop.dbus-session.plist is loaded!");
3647  _dbus_string_free(&socket_path);
3648  return FALSE;
3649  }
3650  if (!_dbus_string_append (address, "unix:path="))
3651  {
3652  _DBUS_SET_OOM (error);
3653  _dbus_string_free(&socket_path);
3654  return FALSE;
3655  }
3656  if (!_dbus_string_copy (&socket_path, 0, address,
3657  _dbus_string_get_length (address)))
3658  {
3659  _DBUS_SET_OOM (error);
3660  _dbus_string_free(&socket_path);
3661  return FALSE;
3662  }
3663 
3664  _dbus_string_free(&socket_path);
3665  return TRUE;
3666 }
3667 #endif
3668 
3690  DBusString *address,
3691  DBusError *error)
3692 {
3693 #ifdef DBUS_ENABLE_LAUNCHD
3694  *supported = TRUE;
3695  return _dbus_lookup_session_address_launchd (address, error);
3696 #else
3697  /* On non-Mac Unix platforms, if the session address isn't already
3698  * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3699  * fall back to the autolaunch: global default; see
3700  * init_session_address in dbus/dbus-bus.c. */
3701  *supported = FALSE;
3702  return TRUE;
3703 #endif
3704 }
3705 
3725 {
3726  const char *xdg_data_home;
3727  const char *xdg_data_dirs;
3728  DBusString servicedir_path;
3729 
3730  if (!_dbus_string_init (&servicedir_path))
3731  return FALSE;
3732 
3733  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3734  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3735 
3736  if (xdg_data_home != NULL)
3737  {
3738  if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3739  goto oom;
3740  }
3741  else
3742  {
3743  const DBusString *homedir;
3744  DBusString local_share;
3745 
3746  if (!_dbus_homedir_from_current_process (&homedir))
3747  goto oom;
3748 
3749  if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3750  goto oom;
3751 
3752  _dbus_string_init_const (&local_share, "/.local/share");
3753  if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3754  goto oom;
3755  }
3756 
3757  if (!_dbus_string_append (&servicedir_path, ":"))
3758  goto oom;
3759 
3760  if (xdg_data_dirs != NULL)
3761  {
3762  if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3763  goto oom;
3764 
3765  if (!_dbus_string_append (&servicedir_path, ":"))
3766  goto oom;
3767  }
3768  else
3769  {
3770  if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3771  goto oom;
3772  }
3773 
3774  /*
3775  * add configured datadir to defaults
3776  * this may be the same as an xdg dir
3777  * however the config parser should take
3778  * care of duplicates
3779  */
3780  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3781  goto oom;
3782 
3783  if (!_dbus_split_paths_and_append (&servicedir_path,
3784  DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3785  dirs))
3786  goto oom;
3787 
3788  _dbus_string_free (&servicedir_path);
3789  return TRUE;
3790 
3791  oom:
3792  _dbus_string_free (&servicedir_path);
3793  return FALSE;
3794 }
3795 
3796 
3817 {
3818  /*
3819  * DBUS_DATADIR may be the same as one of the standard directories. However,
3820  * the config parser should take care of the duplicates.
3821  *
3822  * Also, append /lib as counterpart of /usr/share on the root
3823  * directory (the root directory does not know /share), in order to
3824  * facilitate early boot system bus activation where /usr might not
3825  * be available.
3826  */
3827  static const char standard_search_path[] =
3828  "/usr/local/share:"
3829  "/usr/share:"
3830  DBUS_DATADIR ":"
3831  "/lib";
3832  DBusString servicedir_path;
3833 
3834  _dbus_string_init_const (&servicedir_path, standard_search_path);
3835 
3836  return _dbus_split_paths_and_append (&servicedir_path,
3837  DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3838  dirs);
3839 }
3840 
3851 {
3852  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3853 }
3854 
3863 {
3864  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3865 }
3866 
3874 void
3876 {
3878 }
3879 
3895  DBusCredentials *credentials)
3896 {
3897  DBusString homedir;
3898  DBusString dotdir;
3899  dbus_uid_t uid;
3900 
3901  _dbus_assert (credentials != NULL);
3903 
3904  if (!_dbus_string_init (&homedir))
3905  return FALSE;
3906 
3907  uid = _dbus_credentials_get_unix_uid (credentials);
3908  _dbus_assert (uid != DBUS_UID_UNSET);
3909 
3910  if (!_dbus_homedir_from_uid (uid, &homedir))
3911  goto failed;
3912 
3913 #ifdef DBUS_BUILD_TESTS
3914  {
3915  const char *override;
3916 
3917  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3918  if (override != NULL && *override != '\0')
3919  {
3920  _dbus_string_set_length (&homedir, 0);
3921  if (!_dbus_string_append (&homedir, override))
3922  goto failed;
3923 
3924  _dbus_verbose ("Using fake homedir for testing: %s\n",
3925  _dbus_string_get_const_data (&homedir));
3926  }
3927  else
3928  {
3929  static dbus_bool_t already_warned = FALSE;
3930  if (!already_warned)
3931  {
3932  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3933  already_warned = TRUE;
3934  }
3935  }
3936  }
3937 #endif
3938 
3939  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3940  if (!_dbus_concat_dir_and_file (&homedir,
3941  &dotdir))
3942  goto failed;
3943 
3944  if (!_dbus_string_copy (&homedir, 0,
3945  directory, _dbus_string_get_length (directory))) {
3946  goto failed;
3947  }
3948 
3949  _dbus_string_free (&homedir);
3950  return TRUE;
3951 
3952  failed:
3953  _dbus_string_free (&homedir);
3954  return FALSE;
3955 }
3956 
3957 //PENDING(kdab) docs
3959 _dbus_daemon_publish_session_bus_address (const char* addr,
3960  const char *scope)
3961 {
3962  return TRUE;
3963 }
3964 
3965 //PENDING(kdab) docs
3966 void
3967 _dbus_daemon_unpublish_session_bus_address (void)
3968 {
3969 
3970 }
3971 
3980 {
3981  return errno == EAGAIN || errno == EWOULDBLOCK;
3982 }
3983 
3993  DBusError *error)
3994 {
3995  const char *filename_c;
3996 
3997  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3998 
3999  filename_c = _dbus_string_get_const_data (filename);
4000 
4001  if (rmdir (filename_c) != 0)
4002  {
4004  "Failed to remove directory %s: %s\n",
4005  filename_c, _dbus_strerror (errno));
4006  return FALSE;
4007  }
4008 
4009  return TRUE;
4010 }
4011 
4021 
4022 #ifdef SCM_RIGHTS
4023  union {
4024  struct sockaddr sa;
4025  struct sockaddr_storage storage;
4026  struct sockaddr_un un;
4027  } sa_buf;
4028 
4029  socklen_t sa_len = sizeof(sa_buf);
4030 
4031  _DBUS_ZERO(sa_buf);
4032 
4033  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4034  return FALSE;
4035 
4036  return sa_buf.sa.sa_family == AF_UNIX;
4037 
4038 #else
4039  return FALSE;
4040 
4041 #endif
4042 }
4043 
4044 
4045 /*
4046  * replaces the term DBUS_PREFIX in configure_time_path by the
4047  * current dbus installation directory. On unix this function is a noop
4048  *
4049  * @param configure_time_path
4050  * @return real path
4051  */
4052 const char *
4053 _dbus_replace_install_prefix (const char *configure_time_path)
4054 {
4055  return configure_time_path;
4056 }
4057 
4062 void
4064 {
4065  int maxfds, i;
4066 
4067 #ifdef __linux__
4068  DIR *d;
4069 
4070  /* On Linux we can optimize this a bit if /proc is available. If it
4071  isn't available, fall back to the brute force way. */
4072 
4073  d = opendir ("/proc/self/fd");
4074  if (d)
4075  {
4076  for (;;)
4077  {
4078  struct dirent buf, *de;
4079  int k, fd;
4080  long l;
4081  char *e = NULL;
4082 
4083  k = readdir_r (d, &buf, &de);
4084  if (k != 0 || !de)
4085  break;
4086 
4087  if (de->d_name[0] == '.')
4088  continue;
4089 
4090  errno = 0;
4091  l = strtol (de->d_name, &e, 10);
4092  if (errno != 0 || e == NULL || *e != '\0')
4093  continue;
4094 
4095  fd = (int) l;
4096  if (fd < 3)
4097  continue;
4098 
4099  if (fd == dirfd (d))
4100  continue;
4101 
4102  close (fd);
4103  }
4104 
4105  closedir (d);
4106  return;
4107  }
4108 #endif
4109 
4110  maxfds = sysconf (_SC_OPEN_MAX);
4111 
4112  /* Pick something reasonable if for some reason sysconf says
4113  * unlimited.
4114  */
4115  if (maxfds < 0)
4116  maxfds = 1024;
4117 
4118  /* close all inherited fds */
4119  for (i = 3; i < maxfds; i++)
4120  close (i);
4121 }
4122 
4134 {
4135  /* TODO: get __libc_enable_secure exported from glibc.
4136  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4137  */
4138 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4139  {
4140  /* See glibc/include/unistd.h */
4141  extern int __libc_enable_secure;
4142  return __libc_enable_secure;
4143  }
4144 #elif defined(HAVE_ISSETUGID)
4145  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4146  return issetugid ();
4147 #else
4148  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4149  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4150 
4151  static dbus_bool_t check_setuid_initialised;
4152  static dbus_bool_t is_setuid;
4153 
4154  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4155  {
4156 #ifdef HAVE_GETRESUID
4157  if (getresuid (&ruid, &euid, &suid) != 0 ||
4158  getresgid (&rgid, &egid, &sgid) != 0)
4159 #endif /* HAVE_GETRESUID */
4160  {
4161  suid = ruid = getuid ();
4162  sgid = rgid = getgid ();
4163  euid = geteuid ();
4164  egid = getegid ();
4165  }
4166 
4167  check_setuid_initialised = TRUE;
4168  is_setuid = (ruid != euid || ruid != suid ||
4169  rgid != egid || rgid != sgid);
4170 
4171  }
4172  return is_setuid;
4173 #endif
4174 }
4175 
4176 /* tests in dbus-sysdeps-util.c */
dbus_bool_t _dbus_string_append(DBusString *str, const char *buffer)
Appends a nul-terminated C-style string to a DBusString.
Definition: dbus-string.c:913
dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:433
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:229
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn&#39;t contain...
dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:390
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
char * username
Username.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_append_system_config_file(DBusString *str)
Append the absolute path of the system.conf file (there is no system bus on Windows so this can just ...
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:234
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLHUP
Hung up.
Definition: dbus-sysdeps.h:291
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:600
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:738
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
dbus_bool_t _dbus_socket_can_pass_unix_fd(int fd)
Checks whether file descriptors may be passed via the socket.
#define _DBUS_POLLNVAL
Invalid request: fd not open.
Definition: dbus-sysdeps.h:293
int _dbus_write(int fd, const DBusString *buffer, int start, int len)
Thin wrapper around the write() system call that writes a part of a DBusString and handles EINTR for ...
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn&#39;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&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t _dbus_get_standard_session_servicedirs(DBusList **dirs)
Returns the standard directories for a session bus to look for service activation files...
dbus_gid_t primary_gid
GID.
#define _DBUS_POLLPRI
There is urgent data to read.
Definition: dbus-sysdeps.h: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.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:283
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:468
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_bool_t _dbus_append_user_from_current_process(DBusString *str)
Append to the string the identity we would like to have when we authenticate, on UNIX this is the cur...
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:758
short events
Events to poll for.
Definition: dbus-sysdeps.h:302
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1280
dbus_bool_t _dbus_read_credentials_socket(int client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:105
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:107
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c: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
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:429
int n_group_ids
Size of group IDs array.
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:287
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_uid_t uid
UID.
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
dbus_bool_t _dbus_append_keyring_directory_for_credentials(DBusString *directory, DBusCredentials *credentials)
Appends the directory in which a keyring for the given credentials should be stored.
int _dbus_read_socket(int fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
Object representing an exception.
Definition: dbus-errors.h:48
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_send_credentials_socket(int server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_bool_t _dbus_credentials_add_adt_audit_data(DBusCredentials *credentials, void *audit_data, dbus_int32_t size)
Add ADT audit data to the credentials.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
int fd
File descriptor.
Definition: dbus-sysdeps.h:301
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
int _dbus_connect_exec(const char *path, char *const argv[], DBusError *error)
Creates a UNIX domain socket and connects it to the specified process to execute. ...
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1154
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:109
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to &quot;1&quot;.
#define DBUS_ERROR_FAILED
A generic error; &quot;something went wrong&quot; - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:808
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:114
dbus_bool_t _dbus_read_uuid_file(const DBusString *filename, DBusGUID *uuid, dbus_bool_t create_if_not_found, DBusError *error)
Reads (and optionally writes) a uuid to a file.
char * homedir
Home directory.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
#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.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
A node in a linked list.
Definition: dbus-list.h:34
void _dbus_exit(int code)
Exit the process, returning the given value.
dbus_bool_t _dbus_split_paths_and_append(DBusString *dirs, const char *suffix, DBusList **dir_list)
Split paths into a list of char strings.
Definition: dbus-sysdeps.c: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 &quot;0&quot;.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void dbus_set_error_const(DBusError *error, const char *name, const char *message)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:243
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:780
#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
int dbus_int32_t
A 32-bit signed integer on all platforms.
char * _dbus_strdup(const char *str)
Duplicates a string.
dbus_bool_t _dbus_close_socket(int fd, DBusError *error)
Closes a socket.
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
dbus_bool_t _dbus_credentials_add_unix_uid(DBusCredentials *credentials, dbus_uid_t uid)
Add a UNIX user ID to the credentials.
dbus_bool_t _dbus_append_session_config_file(DBusString *str)
Append the absolute path of the session.conf file.
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:100
short revents
Events that occurred.
Definition: dbus-sysdeps.h:303
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
int _dbus_connect_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and connects it to the UNIX domain socket at the given path.
dbus_bool_t _dbus_get_standard_system_servicedirs(DBusList **dirs)
Returns the standard directories for a system bus to look for service activation files.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
int _dbus_read(int fd, DBusString *buffer, int count)
Thin wrapper around the read() system call that appends the data it reads to the DBusString buffer...
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
int _dbus_listen_unix_socket(const char *path, dbus_bool_t abstract, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
int _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
int _dbus_listen_systemd_sockets(int **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, int **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes)
Generates the given number of random bytes, using the best mechanism we can come up with...
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:289