D-Bus  1.10.8
dbus-sysdeps-unix.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3  *
4  * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  *
7  * Licensed under the Academic Free License version 2.1
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 #include <config.h>
26 
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-file.h"
33 #include "dbus-transport.h"
34 #include "dbus-string.h"
35 #include "dbus-userdb.h"
36 #include "dbus-list.h"
37 #include "dbus-credentials.h"
38 #include "dbus-nonce.h"
39 
40 #include <sys/types.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <signal.h>
44 #include <unistd.h>
45 #include <stdio.h>
46 #include <fcntl.h>
47 #include <sys/socket.h>
48 #include <dirent.h>
49 #include <sys/un.h>
50 #include <pwd.h>
51 #include <time.h>
52 #include <locale.h>
53 #include <sys/time.h>
54 #include <sys/stat.h>
55 #include <sys/wait.h>
56 #include <netinet/in.h>
57 #include <netinet/tcp.h>
58 #include <netdb.h>
59 #include <grp.h>
60 #include <arpa/inet.h>
61 
62 #ifdef HAVE_ERRNO_H
63 #include <errno.h>
64 #endif
65 #ifdef HAVE_WRITEV
66 #include <sys/uio.h>
67 #endif
68 #ifdef HAVE_POLL
69 #include <sys/poll.h>
70 #endif
71 #ifdef HAVE_BACKTRACE
72 #include <execinfo.h>
73 #endif
74 #ifdef HAVE_GETPEERUCRED
75 #include <ucred.h>
76 #endif
77 #ifdef HAVE_ALLOCA_H
78 #include <alloca.h>
79 #endif
80 
81 #ifdef HAVE_ADT
82 #include <bsm/adt.h>
83 #endif
84 
85 #ifdef HAVE_SYSTEMD
86 #include <systemd/sd-daemon.h>
87 #endif
88 
89 #if !DBUS_USE_SYNC
90 #include <pthread.h>
91 #endif
92 
93 #ifndef O_BINARY
94 #define O_BINARY 0
95 #endif
96 
97 #ifndef AI_ADDRCONFIG
98 #define AI_ADDRCONFIG 0
99 #endif
100 
101 #ifndef HAVE_SOCKLEN_T
102 #define socklen_t int
103 #endif
104 
105 #if defined (__sun) || defined (__sun__)
106 /*
107  * CMS_SPACE etc. definitions for Solaris < 10, based on
108  * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
109  * via
110  * http://wiki.opencsw.org/porting-faq#toc10
111  *
112  * These are only redefined for Solaris, for now: if your OS needs these too,
113  * please file a bug. (Or preferably, improve your OS so they're not needed.)
114  */
115 
116 # ifndef CMSG_ALIGN
117 # ifdef __sun__
118 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
119 # else
120  /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
121 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
122  ~(sizeof (long) - 1))
123 # endif
124 # endif
125 
126 # ifndef CMSG_SPACE
127 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
128  CMSG_ALIGN (len))
129 # endif
130 
131 # ifndef CMSG_LEN
132 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
133 # endif
134 
135 #endif /* Solaris */
136 
137 static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
138  DBusError *error);
139 
140 static dbus_bool_t
141 _dbus_open_socket (int *fd_p,
142  int domain,
143  int type,
144  int protocol,
145  DBusError *error)
146 {
147 #ifdef SOCK_CLOEXEC
148  dbus_bool_t cloexec_done;
149 
150  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
151  cloexec_done = *fd_p >= 0;
152 
153  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
154  if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
155 #endif
156  {
157  *fd_p = socket (domain, type, protocol);
158  }
159 
160  if (*fd_p >= 0)
161  {
162 #ifdef SOCK_CLOEXEC
163  if (!cloexec_done)
164 #endif
165  {
167  }
168 
169  _dbus_verbose ("socket fd %d opened\n", *fd_p);
170  return TRUE;
171  }
172  else
173  {
174  dbus_set_error(error,
175  _dbus_error_from_errno (errno),
176  "Failed to open socket: %s",
177  _dbus_strerror (errno));
178  return FALSE;
179  }
180 }
181 
192 static dbus_bool_t
193 _dbus_open_unix_socket (int *fd,
194  DBusError *error)
195 {
196  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
197 }
198 
209  DBusError *error)
210 {
211  return _dbus_close (fd.fd, error);
212 }
213 
223 int
225  DBusString *buffer,
226  int count)
227 {
228  return _dbus_read (fd.fd, buffer, count);
229 }
230 
241 int
243  const DBusString *buffer,
244  int start,
245  int len)
246 {
247 #if HAVE_DECL_MSG_NOSIGNAL
248  const char *data;
249  int bytes_written;
250 
251  data = _dbus_string_get_const_data_len (buffer, start, len);
252 
253  again:
254 
255  bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
256 
257  if (bytes_written < 0 && errno == EINTR)
258  goto again;
259 
260  return bytes_written;
261 
262 #else
263  return _dbus_write (fd.fd, buffer, start, len);
264 #endif
265 }
266 
279 int
281  DBusString *buffer,
282  int count,
283  int *fds,
284  int *n_fds) {
285 #ifndef HAVE_UNIX_FD_PASSING
286  int r;
287 
288  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
289  return r;
290 
291  *n_fds = 0;
292  return r;
293 
294 #else
295  int bytes_read;
296  int start;
297  struct msghdr m;
298  struct iovec iov;
299 
300  _dbus_assert (count >= 0);
301  _dbus_assert (*n_fds >= 0);
302 
303  start = _dbus_string_get_length (buffer);
304 
305  if (!_dbus_string_lengthen (buffer, count))
306  {
307  errno = ENOMEM;
308  return -1;
309  }
310 
311  _DBUS_ZERO(iov);
312  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
313  iov.iov_len = count;
314 
315  _DBUS_ZERO(m);
316  m.msg_iov = &iov;
317  m.msg_iovlen = 1;
318 
319  /* Hmm, we have no clue how long the control data will actually be
320  that is queued for us. The least we can do is assume that the
321  caller knows. Hence let's make space for the number of fds that
322  we shall read at max plus the cmsg header. */
323  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
324 
325  /* It's probably safe to assume that systems with SCM_RIGHTS also
326  know alloca() */
327  m.msg_control = alloca(m.msg_controllen);
328  memset(m.msg_control, 0, m.msg_controllen);
329 
330  /* Do not include the padding at the end when we tell the kernel
331  * how much we're willing to receive. This avoids getting
332  * the padding filled with additional fds that we weren't expecting,
333  * if a (potentially malicious) sender included them. (fd.o #83622) */
334  m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
335 
336  again:
337 
338  bytes_read = recvmsg (fd.fd, &m, 0
339 #ifdef MSG_CMSG_CLOEXEC
340  |MSG_CMSG_CLOEXEC
341 #endif
342  );
343 
344  if (bytes_read < 0)
345  {
346  if (errno == EINTR)
347  goto again;
348  else
349  {
350  /* put length back (note that this doesn't actually realloc anything) */
351  _dbus_string_set_length (buffer, start);
352  return -1;
353  }
354  }
355  else
356  {
357  struct cmsghdr *cm;
358  dbus_bool_t found = FALSE;
359 
360  if (m.msg_flags & MSG_CTRUNC)
361  {
362  /* Hmm, apparently the control data was truncated. The bad
363  thing is that we might have completely lost a couple of fds
364  without chance to recover them. Hence let's treat this as a
365  serious error. */
366 
367  errno = ENOSPC;
368  _dbus_string_set_length (buffer, start);
369  return -1;
370  }
371 
372  for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
373  if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
374  {
375  size_t i;
376  int *payload = (int *) CMSG_DATA (cm);
377  size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
378  size_t payload_len_fds = payload_len_bytes / sizeof (int);
379  size_t fds_to_use;
380 
381  /* Every non-negative int fits in a size_t without truncation,
382  * and we already know that *n_fds is non-negative, so
383  * casting (size_t) *n_fds is OK */
384  _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
385 
386  if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
387  {
388  /* The fds in the payload will fit in our buffer */
389  fds_to_use = payload_len_fds;
390  }
391  else
392  {
393  /* Too many fds in the payload. This shouldn't happen
394  * any more because we're setting m.msg_controllen to
395  * the exact number we can accept, but be safe and
396  * truncate. */
397  fds_to_use = (size_t) *n_fds;
398 
399  /* Close the excess fds to avoid DoS: if they stayed open,
400  * someone could send us an extra fd per message
401  * and we'd eventually run out. */
402  for (i = fds_to_use; i < payload_len_fds; i++)
403  {
404  close (payload[i]);
405  }
406  }
407 
408  memcpy (fds, payload, fds_to_use * sizeof (int));
409  found = TRUE;
410  /* This cannot overflow because we have chosen fds_to_use
411  * to be <= *n_fds */
412  *n_fds = (int) fds_to_use;
413 
414  /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
415  worked, hence we need to go through this list and set
416  CLOEXEC everywhere in any case */
417  for (i = 0; i < fds_to_use; i++)
419 
420  break;
421  }
422 
423  if (!found)
424  *n_fds = 0;
425 
426  /* put length back (doesn't actually realloc) */
427  _dbus_string_set_length (buffer, start + bytes_read);
428 
429 #if 0
430  if (bytes_read > 0)
431  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
432 #endif
433 
434  return bytes_read;
435  }
436 #endif
437 }
438 
439 int
440 _dbus_write_socket_with_unix_fds(DBusSocket fd,
441  const DBusString *buffer,
442  int start,
443  int len,
444  const int *fds,
445  int n_fds) {
446 
447 #ifndef HAVE_UNIX_FD_PASSING
448 
449  if (n_fds > 0) {
450  errno = ENOTSUP;
451  return -1;
452  }
453 
454  return _dbus_write_socket(fd, buffer, start, len);
455 #else
456  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
457 #endif
458 }
459 
460 int
461 _dbus_write_socket_with_unix_fds_two(DBusSocket fd,
462  const DBusString *buffer1,
463  int start1,
464  int len1,
465  const DBusString *buffer2,
466  int start2,
467  int len2,
468  const int *fds,
469  int n_fds) {
470 
471 #ifndef HAVE_UNIX_FD_PASSING
472 
473  if (n_fds > 0) {
474  errno = ENOTSUP;
475  return -1;
476  }
477 
478  return _dbus_write_socket_two(fd,
479  buffer1, start1, len1,
480  buffer2, start2, len2);
481 #else
482 
483  struct msghdr m;
484  struct cmsghdr *cm;
485  struct iovec iov[2];
486  int bytes_written;
487 
488  _dbus_assert (len1 >= 0);
489  _dbus_assert (len2 >= 0);
490  _dbus_assert (n_fds >= 0);
491 
492  _DBUS_ZERO(iov);
493  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
494  iov[0].iov_len = len1;
495 
496  if (buffer2)
497  {
498  iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
499  iov[1].iov_len = len2;
500  }
501 
502  _DBUS_ZERO(m);
503  m.msg_iov = iov;
504  m.msg_iovlen = buffer2 ? 2 : 1;
505 
506  if (n_fds > 0)
507  {
508  m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
509  m.msg_control = alloca(m.msg_controllen);
510  memset(m.msg_control, 0, m.msg_controllen);
511 
512  cm = CMSG_FIRSTHDR(&m);
513  cm->cmsg_level = SOL_SOCKET;
514  cm->cmsg_type = SCM_RIGHTS;
515  cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
516  memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
517  }
518 
519  again:
520 
521  bytes_written = sendmsg (fd.fd, &m, 0
522 #if HAVE_DECL_MSG_NOSIGNAL
523  |MSG_NOSIGNAL
524 #endif
525  );
526 
527  if (bytes_written < 0 && errno == EINTR)
528  goto again;
529 
530 #if 0
531  if (bytes_written > 0)
532  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
533 #endif
534 
535  return bytes_written;
536 #endif
537 }
538 
552 int
554  const DBusString *buffer1,
555  int start1,
556  int len1,
557  const DBusString *buffer2,
558  int start2,
559  int len2)
560 {
561 #if HAVE_DECL_MSG_NOSIGNAL
562  struct iovec vectors[2];
563  const char *data1;
564  const char *data2;
565  int bytes_written;
566  struct msghdr m;
567 
568  _dbus_assert (buffer1 != NULL);
569  _dbus_assert (start1 >= 0);
570  _dbus_assert (start2 >= 0);
571  _dbus_assert (len1 >= 0);
572  _dbus_assert (len2 >= 0);
573 
574  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
575 
576  if (buffer2 != NULL)
577  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
578  else
579  {
580  data2 = NULL;
581  start2 = 0;
582  len2 = 0;
583  }
584 
585  vectors[0].iov_base = (char*) data1;
586  vectors[0].iov_len = len1;
587  vectors[1].iov_base = (char*) data2;
588  vectors[1].iov_len = len2;
589 
590  _DBUS_ZERO(m);
591  m.msg_iov = vectors;
592  m.msg_iovlen = data2 ? 2 : 1;
593 
594  again:
595 
596  bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
597 
598  if (bytes_written < 0 && errno == EINTR)
599  goto again;
600 
601  return bytes_written;
602 
603 #else
604  return _dbus_write_two (fd.fd, buffer1, start1, len1,
605  buffer2, start2, len2);
606 #endif
607 }
608 
625 int
626 _dbus_read (int fd,
627  DBusString *buffer,
628  int count)
629 {
630  int bytes_read;
631  int start;
632  char *data;
633 
634  _dbus_assert (count >= 0);
635 
636  start = _dbus_string_get_length (buffer);
637 
638  if (!_dbus_string_lengthen (buffer, count))
639  {
640  errno = ENOMEM;
641  return -1;
642  }
643 
644  data = _dbus_string_get_data_len (buffer, start, count);
645 
646  again:
647 
648  bytes_read = read (fd, data, count);
649 
650  if (bytes_read < 0)
651  {
652  if (errno == EINTR)
653  goto again;
654  else
655  {
656  /* put length back (note that this doesn't actually realloc anything) */
657  _dbus_string_set_length (buffer, start);
658  return -1;
659  }
660  }
661  else
662  {
663  /* put length back (doesn't actually realloc) */
664  _dbus_string_set_length (buffer, start + bytes_read);
665 
666 #if 0
667  if (bytes_read > 0)
668  _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
669 #endif
670 
671  return bytes_read;
672  }
673 }
674 
685 int
686 _dbus_write (int fd,
687  const DBusString *buffer,
688  int start,
689  int len)
690 {
691  const char *data;
692  int bytes_written;
693 
694  data = _dbus_string_get_const_data_len (buffer, start, len);
695 
696  again:
697 
698  bytes_written = write (fd, data, len);
699 
700  if (bytes_written < 0 && errno == EINTR)
701  goto again;
702 
703 #if 0
704  if (bytes_written > 0)
705  _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
706 #endif
707 
708  return bytes_written;
709 }
710 
731 int
733  const DBusString *buffer1,
734  int start1,
735  int len1,
736  const DBusString *buffer2,
737  int start2,
738  int len2)
739 {
740  _dbus_assert (buffer1 != NULL);
741  _dbus_assert (start1 >= 0);
742  _dbus_assert (start2 >= 0);
743  _dbus_assert (len1 >= 0);
744  _dbus_assert (len2 >= 0);
745 
746 #ifdef HAVE_WRITEV
747  {
748  struct iovec vectors[2];
749  const char *data1;
750  const char *data2;
751  int bytes_written;
752 
753  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
754 
755  if (buffer2 != NULL)
756  data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
757  else
758  {
759  data2 = NULL;
760  start2 = 0;
761  len2 = 0;
762  }
763 
764  vectors[0].iov_base = (char*) data1;
765  vectors[0].iov_len = len1;
766  vectors[1].iov_base = (char*) data2;
767  vectors[1].iov_len = len2;
768 
769  again:
770 
771  bytes_written = writev (fd,
772  vectors,
773  data2 ? 2 : 1);
774 
775  if (bytes_written < 0 && errno == EINTR)
776  goto again;
777 
778  return bytes_written;
779  }
780 #else /* HAVE_WRITEV */
781  {
782  int ret1, ret2;
783 
784  ret1 = _dbus_write (fd, buffer1, start1, len1);
785  if (ret1 == len1 && buffer2 != NULL)
786  {
787  ret2 = _dbus_write (fd, buffer2, start2, len2);
788  if (ret2 < 0)
789  ret2 = 0; /* we can't report an error as the first write was OK */
790 
791  return ret1 + ret2;
792  }
793  else
794  return ret1;
795  }
796 #endif /* !HAVE_WRITEV */
797 }
798 
799 #define _DBUS_MAX_SUN_PATH_LENGTH 99
800 
830 int
831 _dbus_connect_unix_socket (const char *path,
832  dbus_bool_t abstract,
833  DBusError *error)
834 {
835  int fd;
836  size_t path_len;
837  struct sockaddr_un addr;
838 
839  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
840 
841  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
842  path, abstract);
843 
844 
845  if (!_dbus_open_unix_socket (&fd, error))
846  {
847  _DBUS_ASSERT_ERROR_IS_SET(error);
848  return -1;
849  }
850  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
851 
852  _DBUS_ZERO (addr);
853  addr.sun_family = AF_UNIX;
854  path_len = strlen (path);
855 
856  if (abstract)
857  {
858 #ifdef HAVE_ABSTRACT_SOCKETS
859  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
860  path_len++; /* Account for the extra nul byte added to the start of sun_path */
861 
862  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
863  {
865  "Abstract socket name too long\n");
866  _dbus_close (fd, NULL);
867  return -1;
868  }
869 
870  strncpy (&addr.sun_path[1], path, path_len);
871  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
872 #else /* HAVE_ABSTRACT_SOCKETS */
874  "Operating system does not support abstract socket namespace\n");
875  _dbus_close (fd, NULL);
876  return -1;
877 #endif /* ! HAVE_ABSTRACT_SOCKETS */
878  }
879  else
880  {
881  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
882  {
884  "Socket name too long\n");
885  _dbus_close (fd, NULL);
886  return -1;
887  }
888 
889  strncpy (addr.sun_path, path, path_len);
890  }
891 
892  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
893  {
894  dbus_set_error (error,
895  _dbus_error_from_errno (errno),
896  "Failed to connect to socket %s: %s",
897  path, _dbus_strerror (errno));
898 
899  _dbus_close (fd, NULL);
900  return -1;
901  }
902 
903  if (!_dbus_set_fd_nonblocking (fd, error))
904  {
905  _DBUS_ASSERT_ERROR_IS_SET (error);
906 
907  _dbus_close (fd, NULL);
908  return -1;
909  }
910 
911  return fd;
912 }
913 
926 int
927 _dbus_connect_exec (const char *path,
928  char *const argv[],
929  DBusError *error)
930 {
931  int fds[2];
932  pid_t pid;
933  int retval;
934  dbus_bool_t cloexec_done = 0;
935 
936  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
937 
938  _dbus_verbose ("connecting to process %s\n", path);
939 
940 #ifdef SOCK_CLOEXEC
941  retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
942  cloexec_done = (retval >= 0);
943 
944  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
945 #endif
946  {
947  retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
948  }
949 
950  if (retval < 0)
951  {
952  dbus_set_error (error,
953  _dbus_error_from_errno (errno),
954  "Failed to create socket pair: %s",
955  _dbus_strerror (errno));
956  return -1;
957  }
958 
959  if (!cloexec_done)
960  {
963  }
964 
965  pid = fork ();
966  if (pid < 0)
967  {
968  dbus_set_error (error,
969  _dbus_error_from_errno (errno),
970  "Failed to fork() to call %s: %s",
971  path, _dbus_strerror (errno));
972  close (fds[0]);
973  close (fds[1]);
974  return -1;
975  }
976 
977  if (pid == 0)
978  {
979  /* child */
980  close (fds[0]);
981 
982  dup2 (fds[1], STDIN_FILENO);
983  dup2 (fds[1], STDOUT_FILENO);
984 
985  if (fds[1] != STDIN_FILENO &&
986  fds[1] != STDOUT_FILENO)
987  close (fds[1]);
988 
989  /* Inherit STDERR and the controlling terminal from the
990  parent */
991 
992  _dbus_close_all ();
993 
994  execvp (path, argv);
995 
996  fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
997 
998  _exit(1);
999  }
1000 
1001  /* parent */
1002  close (fds[1]);
1003 
1004  if (!_dbus_set_fd_nonblocking (fds[0], error))
1005  {
1006  _DBUS_ASSERT_ERROR_IS_SET (error);
1007 
1008  close (fds[0]);
1009  return -1;
1010  }
1011 
1012  return fds[0];
1013 }
1014 
1032 int
1033 _dbus_listen_unix_socket (const char *path,
1034  dbus_bool_t abstract,
1035  DBusError *error)
1036 {
1037  int listen_fd;
1038  struct sockaddr_un addr;
1039  size_t path_len;
1040 
1041  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1042 
1043  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1044  path, abstract);
1045 
1046  if (!_dbus_open_unix_socket (&listen_fd, error))
1047  {
1048  _DBUS_ASSERT_ERROR_IS_SET(error);
1049  return -1;
1050  }
1051  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1052 
1053  _DBUS_ZERO (addr);
1054  addr.sun_family = AF_UNIX;
1055  path_len = strlen (path);
1056 
1057  if (abstract)
1058  {
1059 #ifdef HAVE_ABSTRACT_SOCKETS
1060  /* remember that abstract names aren't nul-terminated so we rely
1061  * on sun_path being filled in with zeroes above.
1062  */
1063  addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1064  path_len++; /* Account for the extra nul byte added to the start of sun_path */
1065 
1066  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1067  {
1069  "Abstract socket name too long\n");
1070  _dbus_close (listen_fd, NULL);
1071  return -1;
1072  }
1073 
1074  strncpy (&addr.sun_path[1], path, path_len);
1075  /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1076 #else /* HAVE_ABSTRACT_SOCKETS */
1078  "Operating system does not support abstract socket namespace\n");
1079  _dbus_close (listen_fd, NULL);
1080  return -1;
1081 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1082  }
1083  else
1084  {
1085  /* Discussed security implications of this with Nalin,
1086  * and we couldn't think of where it would kick our ass, but
1087  * it still seems a bit sucky. It also has non-security suckage;
1088  * really we'd prefer to exit if the socket is already in use.
1089  * But there doesn't seem to be a good way to do this.
1090  *
1091  * Just to be extra careful, I threw in the stat() - clearly
1092  * the stat() can't *fix* any security issue, but it at least
1093  * avoids inadvertent/accidental data loss.
1094  */
1095  {
1096  struct stat sb;
1097 
1098  if (stat (path, &sb) == 0 &&
1099  S_ISSOCK (sb.st_mode))
1100  unlink (path);
1101  }
1102 
1103  if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1104  {
1106  "Socket name too long\n");
1107  _dbus_close (listen_fd, NULL);
1108  return -1;
1109  }
1110 
1111  strncpy (addr.sun_path, path, path_len);
1112  }
1113 
1114  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1115  {
1116  dbus_set_error (error, _dbus_error_from_errno (errno),
1117  "Failed to bind socket \"%s\": %s",
1118  path, _dbus_strerror (errno));
1119  _dbus_close (listen_fd, NULL);
1120  return -1;
1121  }
1122 
1123  if (listen (listen_fd, 30 /* backlog */) < 0)
1124  {
1125  dbus_set_error (error, _dbus_error_from_errno (errno),
1126  "Failed to listen on socket \"%s\": %s",
1127  path, _dbus_strerror (errno));
1128  _dbus_close (listen_fd, NULL);
1129  return -1;
1130  }
1131 
1132  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1133  {
1134  _DBUS_ASSERT_ERROR_IS_SET (error);
1135  _dbus_close (listen_fd, NULL);
1136  return -1;
1137  }
1138 
1139  /* Try opening up the permissions, but if we can't, just go ahead
1140  * and continue, maybe it will be good enough.
1141  */
1142  if (!abstract && chmod (path, 0777) < 0)
1143  _dbus_warn ("Could not set mode 0777 on socket %s\n",
1144  path);
1145 
1146  return listen_fd;
1147 }
1148 
1159 int
1161  DBusError *error)
1162 {
1163 #ifdef HAVE_SYSTEMD
1164  int r, n;
1165  int fd;
1166  DBusSocket *new_fds;
1167 
1168  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1169 
1170  n = sd_listen_fds (TRUE);
1171  if (n < 0)
1172  {
1174  "Failed to acquire systemd socket: %s",
1175  _dbus_strerror (-n));
1176  return -1;
1177  }
1178 
1179  if (n <= 0)
1180  {
1182  "No socket received.");
1183  return -1;
1184  }
1185 
1186  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1187  {
1188  r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1189  if (r < 0)
1190  {
1192  "Failed to verify systemd socket type: %s",
1193  _dbus_strerror (-r));
1194  return -1;
1195  }
1196 
1197  if (!r)
1198  {
1200  "Passed socket has wrong type.");
1201  return -1;
1202  }
1203  }
1204 
1205  /* OK, the file descriptors are all good, so let's take posession of
1206  them then. */
1207 
1208  new_fds = dbus_new (DBusSocket, n);
1209  if (!new_fds)
1210  {
1212  "Failed to allocate file handle array.");
1213  goto fail;
1214  }
1215 
1216  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1217  {
1218  if (!_dbus_set_fd_nonblocking (fd, error))
1219  {
1220  _DBUS_ASSERT_ERROR_IS_SET (error);
1221  goto fail;
1222  }
1223 
1224  new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1225  }
1226 
1227  *fds = new_fds;
1228  return n;
1229 
1230  fail:
1231 
1232  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1233  {
1234  _dbus_close (fd, NULL);
1235  }
1236 
1237  dbus_free (new_fds);
1238  return -1;
1239 #else
1241  "dbus was compiled without systemd support");
1242  return -1;
1243 #endif
1244 }
1245 
1259 DBusSocket
1260 _dbus_connect_tcp_socket (const char *host,
1261  const char *port,
1262  const char *family,
1263  DBusError *error)
1264 {
1265  return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1266 }
1267 
1268 DBusSocket
1269 _dbus_connect_tcp_socket_with_nonce (const char *host,
1270  const char *port,
1271  const char *family,
1272  const char *noncefile,
1273  DBusError *error)
1274 {
1275  int saved_errno = 0;
1276  DBusSocket fd = DBUS_SOCKET_INIT;
1277  int res;
1278  struct addrinfo hints;
1279  struct addrinfo *ai, *tmp;
1280 
1281  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1282 
1283  _DBUS_ZERO (hints);
1284 
1285  if (!family)
1286  hints.ai_family = AF_UNSPEC;
1287  else if (!strcmp(family, "ipv4"))
1288  hints.ai_family = AF_INET;
1289  else if (!strcmp(family, "ipv6"))
1290  hints.ai_family = AF_INET6;
1291  else
1292  {
1293  dbus_set_error (error,
1295  "Unknown address family %s", family);
1296  return _dbus_socket_get_invalid ();
1297  }
1298  hints.ai_protocol = IPPROTO_TCP;
1299  hints.ai_socktype = SOCK_STREAM;
1300  hints.ai_flags = AI_ADDRCONFIG;
1301 
1302  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1303  {
1304  dbus_set_error (error,
1305  _dbus_error_from_errno (errno),
1306  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1307  host, port, gai_strerror(res), res);
1308  return _dbus_socket_get_invalid ();
1309  }
1310 
1311  tmp = ai;
1312  while (tmp)
1313  {
1314  if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1315  {
1316  freeaddrinfo(ai);
1317  _DBUS_ASSERT_ERROR_IS_SET(error);
1318  return _dbus_socket_get_invalid ();
1319  }
1320  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1321 
1322  if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1323  {
1324  saved_errno = errno;
1325  _dbus_close (fd.fd, NULL);
1326  fd.fd = -1;
1327  tmp = tmp->ai_next;
1328  continue;
1329  }
1330 
1331  break;
1332  }
1333  freeaddrinfo(ai);
1334 
1335  if (fd.fd == -1)
1336  {
1337  dbus_set_error (error,
1338  _dbus_error_from_errno (saved_errno),
1339  "Failed to connect to socket \"%s:%s\" %s",
1340  host, port, _dbus_strerror(saved_errno));
1341  return _dbus_socket_get_invalid ();
1342  }
1343 
1344  if (noncefile != NULL)
1345  {
1346  DBusString noncefileStr;
1347  dbus_bool_t ret;
1348  _dbus_string_init_const (&noncefileStr, noncefile);
1349  ret = _dbus_send_nonce (fd, &noncefileStr, error);
1350  _dbus_string_free (&noncefileStr);
1351 
1352  if (!ret)
1353  {
1354  _dbus_close (fd.fd, NULL);
1355  return _dbus_socket_get_invalid ();
1356  }
1357  }
1358 
1359  if (!_dbus_set_fd_nonblocking (fd.fd, error))
1360  {
1361  _dbus_close (fd.fd, NULL);
1362  return _dbus_socket_get_invalid ();
1363  }
1364 
1365  return fd;
1366 }
1367 
1384 int
1385 _dbus_listen_tcp_socket (const char *host,
1386  const char *port,
1387  const char *family,
1388  DBusString *retport,
1389  DBusSocket **fds_p,
1390  DBusError *error)
1391 {
1392  int saved_errno;
1393  int nlisten_fd = 0, res, i;
1394  DBusSocket *listen_fd = NULL;
1395  struct addrinfo hints;
1396  struct addrinfo *ai, *tmp;
1397  unsigned int reuseaddr;
1398 
1399  *fds_p = NULL;
1400  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1401 
1402  _DBUS_ZERO (hints);
1403 
1404  if (!family)
1405  hints.ai_family = AF_UNSPEC;
1406  else if (!strcmp(family, "ipv4"))
1407  hints.ai_family = AF_INET;
1408  else if (!strcmp(family, "ipv6"))
1409  hints.ai_family = AF_INET6;
1410  else
1411  {
1412  dbus_set_error (error,
1414  "Unknown address family %s", family);
1415  return -1;
1416  }
1417 
1418  hints.ai_protocol = IPPROTO_TCP;
1419  hints.ai_socktype = SOCK_STREAM;
1420  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1421 
1422  redo_lookup_with_port:
1423  ai = NULL;
1424  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1425  {
1426  dbus_set_error (error,
1427  _dbus_error_from_errno (errno),
1428  "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1429  host ? host : "*", port, gai_strerror(res), res);
1430  goto failed;
1431  }
1432 
1433  tmp = ai;
1434  while (tmp)
1435  {
1436  int fd = -1, tcp_nodelay_on;
1437  DBusSocket *newlisten_fd;
1438 
1439  if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1440  {
1441  _DBUS_ASSERT_ERROR_IS_SET(error);
1442  goto failed;
1443  }
1444  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1445 
1446  reuseaddr = 1;
1447  if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1448  {
1449  _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1450  host ? host : "*", port, _dbus_strerror (errno));
1451  }
1452 
1453  /* Nagle's algorithm imposes a huge delay on the initial messages
1454  going over TCP. */
1455  tcp_nodelay_on = 1;
1456  if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1457  {
1458  _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1459  host ? host : "*", port, _dbus_strerror (errno));
1460  }
1461 
1462  if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1463  {
1464  saved_errno = errno;
1465  _dbus_close(fd, NULL);
1466  if (saved_errno == EADDRINUSE)
1467  {
1468  /* Depending on kernel policy, binding to an IPv6 address
1469  might implicitly bind to a corresponding IPv4
1470  address or vice versa, resulting in EADDRINUSE for the
1471  other one (e.g. bindv6only=0 on Linux).
1472 
1473  Also, after we "goto redo_lookup_with_port" after binding
1474  a port on one of the possible addresses, we will
1475  try to bind that same port on every address, including the
1476  same address again for a second time; that one will
1477  also fail with EADDRINUSE.
1478 
1479  For both those reasons, ignore EADDRINUSE here */
1480  tmp = tmp->ai_next;
1481  continue;
1482  }
1483  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1484  "Failed to bind socket \"%s:%s\": %s",
1485  host ? host : "*", port, _dbus_strerror (saved_errno));
1486  goto failed;
1487  }
1488 
1489  if (listen (fd, 30 /* backlog */) < 0)
1490  {
1491  saved_errno = errno;
1492  _dbus_close (fd, NULL);
1493  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1494  "Failed to listen on socket \"%s:%s\": %s",
1495  host ? host : "*", port, _dbus_strerror (saved_errno));
1496  goto failed;
1497  }
1498 
1499  newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1500  if (!newlisten_fd)
1501  {
1502  saved_errno = errno;
1503  _dbus_close (fd, NULL);
1504  dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1505  "Failed to allocate file handle array: %s",
1506  _dbus_strerror (saved_errno));
1507  goto failed;
1508  }
1509  listen_fd = newlisten_fd;
1510  listen_fd[nlisten_fd].fd = fd;
1511  nlisten_fd++;
1512 
1513  if (!_dbus_string_get_length(retport))
1514  {
1515  /* If the user didn't specify a port, or used 0, then
1516  the kernel chooses a port. After the first address
1517  is bound to, we need to force all remaining addresses
1518  to use the same port */
1519  if (!port || !strcmp(port, "0"))
1520  {
1521  int result;
1522  struct sockaddr_storage addr;
1523  socklen_t addrlen;
1524  char portbuf[50];
1525 
1526  addrlen = sizeof(addr);
1527  result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1528 
1529  if (result == -1 ||
1530  (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1531  portbuf, sizeof(portbuf),
1532  NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1533  {
1534  dbus_set_error (error, _dbus_error_from_errno (errno),
1535  "Failed to resolve port \"%s:%s\": %s (%s)",
1536  host ? host : "*", port, gai_strerror(res), res);
1537  goto failed;
1538  }
1539  if (!_dbus_string_append(retport, portbuf))
1540  {
1542  goto failed;
1543  }
1544 
1545  /* Release current address list & redo lookup */
1546  port = _dbus_string_get_const_data(retport);
1547  freeaddrinfo(ai);
1548  goto redo_lookup_with_port;
1549  }
1550  else
1551  {
1552  if (!_dbus_string_append(retport, port))
1553  {
1555  goto failed;
1556  }
1557  }
1558  }
1559 
1560  tmp = tmp->ai_next;
1561  }
1562  freeaddrinfo(ai);
1563  ai = NULL;
1564 
1565  if (!nlisten_fd)
1566  {
1567  errno = EADDRINUSE;
1568  dbus_set_error (error, _dbus_error_from_errno (errno),
1569  "Failed to bind socket \"%s:%s\": %s",
1570  host ? host : "*", port, _dbus_strerror (errno));
1571  goto failed;
1572  }
1573 
1574  for (i = 0 ; i < nlisten_fd ; i++)
1575  {
1576  if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1577  {
1578  goto failed;
1579  }
1580  }
1581 
1582  *fds_p = listen_fd;
1583 
1584  return nlisten_fd;
1585 
1586  failed:
1587  if (ai)
1588  freeaddrinfo(ai);
1589  for (i = 0 ; i < nlisten_fd ; i++)
1590  _dbus_close(listen_fd[i].fd, NULL);
1591  dbus_free(listen_fd);
1592  return -1;
1593 }
1594 
1595 static dbus_bool_t
1596 write_credentials_byte (int server_fd,
1597  DBusError *error)
1598 {
1599  int bytes_written;
1600  char buf[1] = { '\0' };
1601 #if defined(HAVE_CMSGCRED)
1602  union {
1603  struct cmsghdr hdr;
1604  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1605  } cmsg;
1606  struct iovec iov;
1607  struct msghdr msg;
1608  iov.iov_base = buf;
1609  iov.iov_len = 1;
1610 
1611  _DBUS_ZERO(msg);
1612  msg.msg_iov = &iov;
1613  msg.msg_iovlen = 1;
1614 
1615  msg.msg_control = (caddr_t) &cmsg;
1616  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1617  _DBUS_ZERO(cmsg);
1618  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1619  cmsg.hdr.cmsg_level = SOL_SOCKET;
1620  cmsg.hdr.cmsg_type = SCM_CREDS;
1621 #endif
1622 
1623  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1624 
1625  again:
1626 
1627 #if defined(HAVE_CMSGCRED)
1628  bytes_written = sendmsg (server_fd, &msg, 0
1629 #if HAVE_DECL_MSG_NOSIGNAL
1630  |MSG_NOSIGNAL
1631 #endif
1632  );
1633 
1634  /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1635  * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1636  * only allows that on AF_UNIX. Try just doing a send() instead. */
1637  if (bytes_written < 0 && errno == EINVAL)
1638 #endif
1639  {
1640  bytes_written = send (server_fd, buf, 1, 0
1641 #if HAVE_DECL_MSG_NOSIGNAL
1642  |MSG_NOSIGNAL
1643 #endif
1644  );
1645  }
1646 
1647  if (bytes_written < 0 && errno == EINTR)
1648  goto again;
1649 
1650  if (bytes_written < 0)
1651  {
1652  dbus_set_error (error, _dbus_error_from_errno (errno),
1653  "Failed to write credentials byte: %s",
1654  _dbus_strerror (errno));
1655  return FALSE;
1656  }
1657  else if (bytes_written == 0)
1658  {
1660  "wrote zero bytes writing credentials byte");
1661  return FALSE;
1662  }
1663  else
1664  {
1665  _dbus_assert (bytes_written == 1);
1666  _dbus_verbose ("wrote credentials byte\n");
1667  return TRUE;
1668  }
1669 }
1670 
1671 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
1672 static dbus_bool_t
1673 add_linux_security_label_to_credentials (int client_fd,
1674  DBusCredentials *credentials)
1675 {
1676 #if defined(__linux__) && defined(SO_PEERSEC)
1677  DBusString buf;
1678  socklen_t len = 1024;
1679  dbus_bool_t oom = FALSE;
1680 
1681  if (!_dbus_string_init_preallocated (&buf, len) ||
1682  !_dbus_string_set_length (&buf, len))
1683  return FALSE;
1684 
1685  while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
1686  _dbus_string_get_data (&buf), &len) < 0)
1687  {
1688  int e = errno;
1689 
1690  _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1691  _dbus_strerror (e), (unsigned long) len);
1692 
1693  if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
1694  {
1695  _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
1696  _dbus_strerror (e));
1697  goto out;
1698  }
1699 
1700  /* If not enough space, len is updated to be enough.
1701  * Try again with a large enough buffer. */
1702  if (!_dbus_string_set_length (&buf, len))
1703  {
1704  oom = TRUE;
1705  goto out;
1706  }
1707 
1708  _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
1709  }
1710 
1711  if (len <= 0)
1712  {
1713  _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
1714  (unsigned long) len);
1715  goto out;
1716  }
1717 
1718  if (len > _dbus_string_get_length_uint (&buf))
1719  {
1720  _dbus_verbose ("%lu > %u", (unsigned long) len,
1721  _dbus_string_get_length_uint (&buf));
1722  _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
1723  }
1724 
1725  if (_dbus_string_get_byte (&buf, len - 1) == 0)
1726  {
1727  /* the kernel included the trailing \0 in its count,
1728  * but DBusString always has an extra \0 after the data anyway */
1729  _dbus_verbose ("subtracting trailing \\0\n");
1730  len--;
1731  }
1732 
1733  if (!_dbus_string_set_length (&buf, len))
1734  {
1735  _dbus_assert_not_reached ("shortening string should not lead to OOM");
1736  oom = TRUE;
1737  goto out;
1738  }
1739 
1740  if (strlen (_dbus_string_get_const_data (&buf)) != len)
1741  {
1742  /* LSM people on the linux-security-module@ mailing list say this
1743  * should never happen: the label should be a bytestring with
1744  * an optional trailing \0 */
1745  _dbus_verbose ("security label from kernel had an embedded \\0, "
1746  "ignoring it\n");
1747  goto out;
1748  }
1749 
1750  _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
1751  (unsigned long) len,
1752  _dbus_string_get_const_data (&buf));
1753 
1755  _dbus_string_get_const_data (&buf)))
1756  {
1757  oom = TRUE;
1758  goto out;
1759  }
1760 
1761 out:
1762  _dbus_string_free (&buf);
1763  return !oom;
1764 #else
1765  /* no error */
1766  return TRUE;
1767 #endif
1768 }
1769 
1812  DBusCredentials *credentials,
1813  DBusError *error)
1814 {
1815  struct msghdr msg;
1816  struct iovec iov;
1817  char buf;
1818  dbus_uid_t uid_read;
1819  dbus_pid_t pid_read;
1820  int bytes_read;
1821 
1822 #ifdef HAVE_CMSGCRED
1823  union {
1824  struct cmsghdr hdr;
1825  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1826  } cmsg;
1827 #endif
1828 
1829  /* The POSIX spec certainly doesn't promise this, but
1830  * we need these assertions to fail as soon as we're wrong about
1831  * it so we can do the porting fixups
1832  */
1833  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
1834  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
1835  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1836 
1837  uid_read = DBUS_UID_UNSET;
1838  pid_read = DBUS_PID_UNSET;
1839 
1840  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1841 
1842  _dbus_credentials_clear (credentials);
1843 
1844  iov.iov_base = &buf;
1845  iov.iov_len = 1;
1846 
1847  _DBUS_ZERO(msg);
1848  msg.msg_iov = &iov;
1849  msg.msg_iovlen = 1;
1850 
1851 #if defined(HAVE_CMSGCRED)
1852  _DBUS_ZERO(cmsg);
1853  msg.msg_control = (caddr_t) &cmsg;
1854  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1855 #endif
1856 
1857  again:
1858  bytes_read = recvmsg (client_fd.fd, &msg, 0);
1859 
1860  if (bytes_read < 0)
1861  {
1862  if (errno == EINTR)
1863  goto again;
1864 
1865  /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1866  * normally only call read_credentials if the socket was ready
1867  * for reading
1868  */
1869 
1870  dbus_set_error (error, _dbus_error_from_errno (errno),
1871  "Failed to read credentials byte: %s",
1872  _dbus_strerror (errno));
1873  return FALSE;
1874  }
1875  else if (bytes_read == 0)
1876  {
1877  /* this should not happen unless we are using recvmsg wrong,
1878  * so is essentially here for paranoia
1879  */
1881  "Failed to read credentials byte (zero-length read)");
1882  return FALSE;
1883  }
1884  else if (buf != '\0')
1885  {
1887  "Credentials byte was not nul");
1888  return FALSE;
1889  }
1890 
1891  _dbus_verbose ("read credentials byte\n");
1892 
1893  {
1894 #ifdef SO_PEERCRED
1895  /* Supported by at least Linux and OpenBSD, with minor differences.
1896  *
1897  * This mechanism passes the process ID through and does not require
1898  * the peer's cooperation, so we prefer it over all others. Notably,
1899  * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
1900  * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
1901  * because this is much less fragile.
1902  */
1903 #ifdef __OpenBSD__
1904  struct sockpeercred cr;
1905 #else
1906  struct ucred cr;
1907 #endif
1908  int cr_len = sizeof (cr);
1909 
1910  if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
1911  {
1912  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
1913  _dbus_strerror (errno));
1914  }
1915  else if (cr_len != sizeof (cr))
1916  {
1917  _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
1918  cr_len, (int) sizeof (cr));
1919  }
1920  else
1921  {
1922  pid_read = cr.pid;
1923  uid_read = cr.uid;
1924  }
1925 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
1926  /* Another variant of the above - used on NetBSD
1927  */
1928  struct unpcbid cr;
1929  socklen_t cr_len = sizeof (cr);
1930 
1931  if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
1932  {
1933  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
1934  _dbus_strerror (errno));
1935  }
1936  else if (cr_len != sizeof (cr))
1937  {
1938  _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
1939  cr_len, (int) sizeof (cr));
1940  }
1941  else
1942  {
1943  pid_read = cr.unp_pid;
1944  uid_read = cr.unp_euid;
1945  }
1946 #elif defined(HAVE_CMSGCRED)
1947  /* We only check for HAVE_CMSGCRED, but we're really assuming that the
1948  * presence of that struct implies SCM_CREDS. Supported by at least
1949  * FreeBSD and DragonflyBSD.
1950  *
1951  * This mechanism requires the peer to help us (it has to send us a
1952  * SCM_CREDS message) but it does pass the process ID through,
1953  * which makes it better than getpeereid().
1954  */
1955  struct cmsgcred *cred;
1956  struct cmsghdr *cmsgp;
1957 
1958  for (cmsgp = CMSG_FIRSTHDR (&msg);
1959  cmsgp != NULL;
1960  cmsgp = CMSG_NXTHDR (&msg, cmsgp))
1961  {
1962  if (cmsgp->cmsg_type == SCM_CREDS &&
1963  cmsgp->cmsg_level == SOL_SOCKET &&
1964  cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
1965  {
1966  cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
1967  pid_read = cred->cmcred_pid;
1968  uid_read = cred->cmcred_euid;
1969  break;
1970  }
1971  }
1972 
1973 #elif defined(HAVE_GETPEERUCRED)
1974  /* Supported in at least Solaris >= 10. It should probably be higher
1975  * up this list, because it carries the pid and we use this code path
1976  * for audit data. */
1977  ucred_t * ucred = NULL;
1978  if (getpeerucred (client_fd.fd, &ucred) == 0)
1979  {
1980  pid_read = ucred_getpid (ucred);
1981  uid_read = ucred_geteuid (ucred);
1982 #ifdef HAVE_ADT
1983  /* generate audit session data based on socket ucred */
1984  adt_session_data_t *adth = NULL;
1985  adt_export_data_t *data = NULL;
1986  size_t size = 0;
1987  if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1988  {
1989  _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1990  }
1991  else
1992  {
1993  if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1994  {
1995  _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1996  }
1997  else
1998  {
1999  size = adt_export_session_data (adth, &data);
2000  if (size <= 0)
2001  {
2002  _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2003  }
2004  else
2005  {
2006  _dbus_credentials_add_adt_audit_data (credentials, data, size);
2007  free (data);
2008  }
2009  }
2010  (void) adt_end_session (adth);
2011  }
2012 #endif /* HAVE_ADT */
2013  }
2014  else
2015  {
2016  _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2017  }
2018  if (ucred != NULL)
2019  ucred_free (ucred);
2020 
2021  /* ----------------------------------------------------------------
2022  * When adding new mechanisms, please add them above this point
2023  * if they support passing the process ID through, or below if not.
2024  * ---------------------------------------------------------------- */
2025 
2026 #elif defined(HAVE_GETPEEREID)
2027  /* getpeereid() originates from D.J. Bernstein and is fairly
2028  * widely-supported. According to a web search, it might be present in
2029  * any/all of:
2030  *
2031  * - AIX?
2032  * - Blackberry?
2033  * - Cygwin
2034  * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2035  * - Mac OS X
2036  * - Minix 3.1.8+
2037  * - MirBSD?
2038  * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2039  * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2040  * - QNX?
2041  */
2042  uid_t euid;
2043  gid_t egid;
2044  if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2045  {
2046  uid_read = euid;
2047  }
2048  else
2049  {
2050  _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2051  }
2052 #else /* no supported mechanism */
2053 
2054 #warning Socket credentials not supported on this Unix OS
2055 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2056 
2057  /* Please add other operating systems known to support at least one of
2058  * the mechanisms above to this list, keeping alphabetical order.
2059  * Everything not in this list is best-effort.
2060  */
2061 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2062  defined(__linux__) || \
2063  defined(__OpenBSD__) || \
2064  defined(__NetBSD__)
2065 # error Credentials passing not working on this OS is a regression!
2066 #endif
2067 
2068  _dbus_verbose ("Socket credentials not supported on this OS\n");
2069 #endif
2070  }
2071 
2072  _dbus_verbose ("Credentials:"
2073  " pid "DBUS_PID_FORMAT
2074  " uid "DBUS_UID_FORMAT
2075  "\n",
2076  pid_read,
2077  uid_read);
2078 
2079  if (pid_read != DBUS_PID_UNSET)
2080  {
2081  if (!_dbus_credentials_add_pid (credentials, pid_read))
2082  {
2083  _DBUS_SET_OOM (error);
2084  return FALSE;
2085  }
2086  }
2087 
2088  if (uid_read != DBUS_UID_UNSET)
2089  {
2090  if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2091  {
2092  _DBUS_SET_OOM (error);
2093  return FALSE;
2094  }
2095  }
2096 
2097  if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2098  {
2099  _DBUS_SET_OOM (error);
2100  return FALSE;
2101  }
2102 
2103  return TRUE;
2104 }
2105 
2125  DBusError *error)
2126 {
2127  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2128 
2129  if (write_credentials_byte (server_fd.fd, error))
2130  return TRUE;
2131  else
2132  return FALSE;
2133 }
2134 
2144 DBusSocket
2146 {
2147  DBusSocket client_fd;
2148  struct sockaddr addr;
2149  socklen_t addrlen;
2150 #ifdef HAVE_ACCEPT4
2151  dbus_bool_t cloexec_done;
2152 #endif
2153 
2154  addrlen = sizeof (addr);
2155 
2156  retry:
2157 
2158 #ifdef HAVE_ACCEPT4
2159  /*
2160  * At compile-time, we assume that if accept4() is available in
2161  * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2162  * not necessarily true that either is supported by the running kernel.
2163  */
2164  client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2165  cloexec_done = client_fd.fd >= 0;
2166 
2167  if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2168 #endif
2169  {
2170  client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2171  }
2172 
2173  if (client_fd.fd < 0)
2174  {
2175  if (errno == EINTR)
2176  goto retry;
2177  }
2178 
2179  _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2180 
2181 #ifdef HAVE_ACCEPT4
2182  if (!cloexec_done)
2183 #endif
2184  {
2185  _dbus_fd_set_close_on_exec(client_fd.fd);
2186  }
2187 
2188  return client_fd;
2189 }
2190 
2201 {
2202  const char *directory;
2203  struct stat sb;
2204 
2205  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2206 
2207  directory = _dbus_string_get_const_data (dir);
2208 
2209  if (stat (directory, &sb) < 0)
2210  {
2211  dbus_set_error (error, _dbus_error_from_errno (errno),
2212  "%s", _dbus_strerror (errno));
2213 
2214  return FALSE;
2215  }
2216 
2217  if (sb.st_uid != geteuid ())
2218  {
2220  "%s directory is owned by user %lu, not %lu",
2221  directory,
2222  (unsigned long) sb.st_uid,
2223  (unsigned long) geteuid ());
2224  return FALSE;
2225  }
2226 
2227  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2228  (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2229  {
2231  "%s directory is not private to the user", directory);
2232  return FALSE;
2233  }
2234 
2235  return TRUE;
2236 }
2237 
2238 static dbus_bool_t
2239 fill_user_info_from_passwd (struct passwd *p,
2240  DBusUserInfo *info,
2241  DBusError *error)
2242 {
2243  _dbus_assert (p->pw_name != NULL);
2244  _dbus_assert (p->pw_dir != NULL);
2245 
2246  info->uid = p->pw_uid;
2247  info->primary_gid = p->pw_gid;
2248  info->username = _dbus_strdup (p->pw_name);
2249  info->homedir = _dbus_strdup (p->pw_dir);
2250 
2251  if (info->username == NULL ||
2252  info->homedir == NULL)
2253  {
2255  return FALSE;
2256  }
2257 
2258  return TRUE;
2259 }
2260 
2261 static dbus_bool_t
2262 fill_user_info (DBusUserInfo *info,
2263  dbus_uid_t uid,
2264  const DBusString *username,
2265  DBusError *error)
2266 {
2267  const char *username_c;
2268 
2269  /* exactly one of username/uid provided */
2270  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2271  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2272 
2273  info->uid = DBUS_UID_UNSET;
2274  info->primary_gid = DBUS_GID_UNSET;
2275  info->group_ids = NULL;
2276  info->n_group_ids = 0;
2277  info->username = NULL;
2278  info->homedir = NULL;
2279 
2280  if (username != NULL)
2281  username_c = _dbus_string_get_const_data (username);
2282  else
2283  username_c = NULL;
2284 
2285  /* For now assuming that the getpwnam() and getpwuid() flavors
2286  * are always symmetrical, if not we have to add more configure
2287  * checks
2288  */
2289 
2290 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2291  {
2292  struct passwd *p;
2293  int result;
2294  size_t buflen;
2295  char *buf;
2296  struct passwd p_str;
2297 
2298  /* retrieve maximum needed size for buf */
2299  buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2300 
2301  /* sysconf actually returns a long, but everything else expects size_t,
2302  * so just recast here.
2303  * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2304  */
2305  if ((long) buflen <= 0)
2306  buflen = 1024;
2307 
2308  result = -1;
2309  while (1)
2310  {
2311  buf = dbus_malloc (buflen);
2312  if (buf == NULL)
2313  {
2315  return FALSE;
2316  }
2317 
2318  p = NULL;
2319 #ifdef HAVE_POSIX_GETPWNAM_R
2320  if (uid != DBUS_UID_UNSET)
2321  result = getpwuid_r (uid, &p_str, buf, buflen,
2322  &p);
2323  else
2324  result = getpwnam_r (username_c, &p_str, buf, buflen,
2325  &p);
2326 #else
2327  if (uid != DBUS_UID_UNSET)
2328  p = getpwuid_r (uid, &p_str, buf, buflen);
2329  else
2330  p = getpwnam_r (username_c, &p_str, buf, buflen);
2331  result = 0;
2332 #endif /* !HAVE_POSIX_GETPWNAM_R */
2333  //Try a bigger buffer if ERANGE was returned
2334  if (result == ERANGE && buflen < 512 * 1024)
2335  {
2336  dbus_free (buf);
2337  buflen *= 2;
2338  }
2339  else
2340  {
2341  break;
2342  }
2343  }
2344  if (result == 0 && p == &p_str)
2345  {
2346  if (!fill_user_info_from_passwd (p, info, error))
2347  {
2348  dbus_free (buf);
2349  return FALSE;
2350  }
2351  dbus_free (buf);
2352  }
2353  else
2354  {
2355  dbus_set_error (error, _dbus_error_from_errno (errno),
2356  "User \"%s\" unknown or no memory to allocate password entry\n",
2357  username_c ? username_c : "???");
2358  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2359  dbus_free (buf);
2360  return FALSE;
2361  }
2362  }
2363 #else /* ! HAVE_GETPWNAM_R */
2364  {
2365  /* I guess we're screwed on thread safety here */
2366  struct passwd *p;
2367 
2368  if (uid != DBUS_UID_UNSET)
2369  p = getpwuid (uid);
2370  else
2371  p = getpwnam (username_c);
2372 
2373  if (p != NULL)
2374  {
2375  if (!fill_user_info_from_passwd (p, info, error))
2376  {
2377  return FALSE;
2378  }
2379  }
2380  else
2381  {
2382  dbus_set_error (error, _dbus_error_from_errno (errno),
2383  "User \"%s\" unknown or no memory to allocate password entry\n",
2384  username_c ? username_c : "???");
2385  _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2386  return FALSE;
2387  }
2388  }
2389 #endif /* ! HAVE_GETPWNAM_R */
2390 
2391  /* Fill this in so we can use it to get groups */
2392  username_c = info->username;
2393 
2394 #ifdef HAVE_GETGROUPLIST
2395  {
2396  gid_t *buf;
2397  int buf_count;
2398  int i;
2399  int initial_buf_count;
2400 
2401  initial_buf_count = 17;
2402  buf_count = initial_buf_count;
2403  buf = dbus_new (gid_t, buf_count);
2404  if (buf == NULL)
2405  {
2407  goto failed;
2408  }
2409 
2410  if (getgrouplist (username_c,
2411  info->primary_gid,
2412  buf, &buf_count) < 0)
2413  {
2414  gid_t *new;
2415  /* Presumed cause of negative return code: buf has insufficient
2416  entries to hold the entire group list. The Linux behavior in this
2417  case is to pass back the actual number of groups in buf_count, but
2418  on Mac OS X 10.5, buf_count is unhelpfully left alone.
2419  So as a hack, try to help out a bit by guessing a larger
2420  number of groups, within reason.. might still fail, of course,
2421  but we can at least print a more informative message. I looked up
2422  the "right way" to do this by downloading Apple's own source code
2423  for the "id" command, and it turns out that they use an
2424  undocumented library function getgrouplist_2 (!) which is not
2425  declared in any header in /usr/include (!!). That did not seem
2426  like the way to go here.
2427  */
2428  if (buf_count == initial_buf_count)
2429  {
2430  buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2431  }
2432  new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2433  if (new == NULL)
2434  {
2436  dbus_free (buf);
2437  goto failed;
2438  }
2439 
2440  buf = new;
2441 
2442  errno = 0;
2443  if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2444  {
2445  if (errno == 0)
2446  {
2447  _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2448  username_c, buf_count, buf_count);
2449  }
2450  else
2451  {
2452  dbus_set_error (error,
2453  _dbus_error_from_errno (errno),
2454  "Failed to get groups for username \"%s\" primary GID "
2455  DBUS_GID_FORMAT ": %s\n",
2456  username_c, info->primary_gid,
2457  _dbus_strerror (errno));
2458  dbus_free (buf);
2459  goto failed;
2460  }
2461  }
2462  }
2463 
2464  info->group_ids = dbus_new (dbus_gid_t, buf_count);
2465  if (info->group_ids == NULL)
2466  {
2468  dbus_free (buf);
2469  goto failed;
2470  }
2471 
2472  for (i = 0; i < buf_count; ++i)
2473  info->group_ids[i] = buf[i];
2474 
2475  info->n_group_ids = buf_count;
2476 
2477  dbus_free (buf);
2478  }
2479 #else /* HAVE_GETGROUPLIST */
2480  {
2481  /* We just get the one group ID */
2482  info->group_ids = dbus_new (dbus_gid_t, 1);
2483  if (info->group_ids == NULL)
2484  {
2486  goto failed;
2487  }
2488 
2489  info->n_group_ids = 1;
2490 
2491  (info->group_ids)[0] = info->primary_gid;
2492  }
2493 #endif /* HAVE_GETGROUPLIST */
2494 
2495  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2496 
2497  return TRUE;
2498 
2499  failed:
2500  _DBUS_ASSERT_ERROR_IS_SET (error);
2501  return FALSE;
2502 }
2503 
2514  const DBusString *username,
2515  DBusError *error)
2516 {
2517  return fill_user_info (info, DBUS_UID_UNSET,
2518  username, error);
2519 }
2520 
2531  dbus_uid_t uid,
2532  DBusError *error)
2533 {
2534  return fill_user_info (info, uid,
2535  NULL, error);
2536 }
2537 
2547 {
2548  /* The POSIX spec certainly doesn't promise this, but
2549  * we need these assertions to fail as soon as we're wrong about
2550  * it so we can do the porting fixups
2551  */
2552  _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2553  _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2554  _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2555 
2556  if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2557  return FALSE;
2558  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2559  return FALSE;
2560 
2561  return TRUE;
2562 }
2563 
2577 {
2578  return _dbus_string_append_uint (str,
2579  _dbus_geteuid ());
2580 }
2581 
2586 dbus_pid_t
2588 {
2589  return getpid ();
2590 }
2591 
2595 dbus_uid_t
2597 {
2598  return getuid ();
2599 }
2600 
2604 dbus_uid_t
2606 {
2607  return geteuid ();
2608 }
2609 
2616 unsigned long
2618 {
2619  return getpid ();
2620 }
2621 
2630 _dbus_parse_uid (const DBusString *uid_str,
2631  dbus_uid_t *uid)
2632 {
2633  int end;
2634  long val;
2635 
2636  if (_dbus_string_get_length (uid_str) == 0)
2637  {
2638  _dbus_verbose ("UID string was zero length\n");
2639  return FALSE;
2640  }
2641 
2642  val = -1;
2643  end = 0;
2644  if (!_dbus_string_parse_int (uid_str, 0, &val,
2645  &end))
2646  {
2647  _dbus_verbose ("could not parse string as a UID\n");
2648  return FALSE;
2649  }
2650 
2651  if (end != _dbus_string_get_length (uid_str))
2652  {
2653  _dbus_verbose ("string contained trailing stuff after UID\n");
2654  return FALSE;
2655  }
2656 
2657  *uid = val;
2658 
2659  return TRUE;
2660 }
2661 
2662 #if !DBUS_USE_SYNC
2663 /* To be thread-safe by default on platforms that don't necessarily have
2664  * atomic operations (notably Debian armel, which is armv4t), we must
2665  * use a mutex that can be initialized statically, like this.
2666  * GLib >= 2.32 uses a similar system.
2667  */
2668 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2669 #endif
2670 
2677 dbus_int32_t
2679 {
2680 #if DBUS_USE_SYNC
2681  return __sync_add_and_fetch(&atomic->value, 1)-1;
2682 #else
2683  dbus_int32_t res;
2684 
2685  pthread_mutex_lock (&atomic_mutex);
2686  res = atomic->value;
2687  atomic->value += 1;
2688  pthread_mutex_unlock (&atomic_mutex);
2689 
2690  return res;
2691 #endif
2692 }
2693 
2700 dbus_int32_t
2702 {
2703 #if DBUS_USE_SYNC
2704  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2705 #else
2706  dbus_int32_t res;
2707 
2708  pthread_mutex_lock (&atomic_mutex);
2709  res = atomic->value;
2710  atomic->value -= 1;
2711  pthread_mutex_unlock (&atomic_mutex);
2712 
2713  return res;
2714 #endif
2715 }
2716 
2724 dbus_int32_t
2726 {
2727 #if DBUS_USE_SYNC
2728  __sync_synchronize ();
2729  return atomic->value;
2730 #else
2731  dbus_int32_t res;
2732 
2733  pthread_mutex_lock (&atomic_mutex);
2734  res = atomic->value;
2735  pthread_mutex_unlock (&atomic_mutex);
2736 
2737  return res;
2738 #endif
2739 }
2740 
2749 int
2751  int n_fds,
2752  int timeout_milliseconds)
2753 {
2754 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2755  /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
2756  if (timeout_milliseconds < -1)
2757  {
2758  timeout_milliseconds = -1;
2759  }
2760 
2761  return poll (fds,
2762  n_fds,
2763  timeout_milliseconds);
2764 #else /* ! HAVE_POLL */
2765  /* Emulate poll() in terms of select() */
2766  fd_set read_set, write_set, err_set;
2767  int max_fd = 0;
2768  int i;
2769  struct timeval tv;
2770  int ready;
2771 
2772  FD_ZERO (&read_set);
2773  FD_ZERO (&write_set);
2774  FD_ZERO (&err_set);
2775 
2776  for (i = 0; i < n_fds; i++)
2777  {
2778  DBusPollFD *fdp = &fds[i];
2779 
2780  if (fdp->events & _DBUS_POLLIN)
2781  FD_SET (fdp->fd, &read_set);
2782 
2783  if (fdp->events & _DBUS_POLLOUT)
2784  FD_SET (fdp->fd, &write_set);
2785 
2786  FD_SET (fdp->fd, &err_set);
2787 
2788  max_fd = MAX (max_fd, fdp->fd);
2789  }
2790 
2791  tv.tv_sec = timeout_milliseconds / 1000;
2792  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2793 
2794  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2795  timeout_milliseconds < 0 ? NULL : &tv);
2796 
2797  if (ready > 0)
2798  {
2799  for (i = 0; i < n_fds; i++)
2800  {
2801  DBusPollFD *fdp = &fds[i];
2802 
2803  fdp->revents = 0;
2804 
2805  if (FD_ISSET (fdp->fd, &read_set))
2806  fdp->revents |= _DBUS_POLLIN;
2807 
2808  if (FD_ISSET (fdp->fd, &write_set))
2809  fdp->revents |= _DBUS_POLLOUT;
2810 
2811  if (FD_ISSET (fdp->fd, &err_set))
2812  fdp->revents |= _DBUS_POLLERR;
2813  }
2814  }
2815 
2816  return ready;
2817 #endif
2818 }
2819 
2827 void
2829  long *tv_usec)
2830 {
2831 #ifdef HAVE_MONOTONIC_CLOCK
2832  struct timespec ts;
2833  clock_gettime (CLOCK_MONOTONIC, &ts);
2834 
2835  if (tv_sec)
2836  *tv_sec = ts.tv_sec;
2837  if (tv_usec)
2838  *tv_usec = ts.tv_nsec / 1000;
2839 #else
2840  struct timeval t;
2841 
2842  gettimeofday (&t, NULL);
2843 
2844  if (tv_sec)
2845  *tv_sec = t.tv_sec;
2846  if (tv_usec)
2847  *tv_usec = t.tv_usec;
2848 #endif
2849 }
2850 
2858 void
2859 _dbus_get_real_time (long *tv_sec,
2860  long *tv_usec)
2861 {
2862  struct timeval t;
2863 
2864  gettimeofday (&t, NULL);
2865 
2866  if (tv_sec)
2867  *tv_sec = t.tv_sec;
2868  if (tv_usec)
2869  *tv_usec = t.tv_usec;
2870 }
2871 
2882  DBusError *error)
2883 {
2884  const char *filename_c;
2885 
2886  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2887 
2888  filename_c = _dbus_string_get_const_data (filename);
2889 
2890  if (mkdir (filename_c, 0700) < 0)
2891  {
2892  if (errno == EEXIST)
2893  return TRUE;
2894 
2896  "Failed to create directory %s: %s\n",
2897  filename_c, _dbus_strerror (errno));
2898  return FALSE;
2899  }
2900  else
2901  return TRUE;
2902 }
2903 
2916  const DBusString *next_component)
2917 {
2918  dbus_bool_t dir_ends_in_slash;
2919  dbus_bool_t file_starts_with_slash;
2920 
2921  if (_dbus_string_get_length (dir) == 0 ||
2922  _dbus_string_get_length (next_component) == 0)
2923  return TRUE;
2924 
2925  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2926  _dbus_string_get_length (dir) - 1);
2927 
2928  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2929 
2930  if (dir_ends_in_slash && file_starts_with_slash)
2931  {
2932  _dbus_string_shorten (dir, 1);
2933  }
2934  else if (!(dir_ends_in_slash || file_starts_with_slash))
2935  {
2936  if (!_dbus_string_append_byte (dir, '/'))
2937  return FALSE;
2938  }
2939 
2940  return _dbus_string_copy (next_component, 0, dir,
2941  _dbus_string_get_length (dir));
2942 }
2943 
2945 #define NANOSECONDS_PER_SECOND 1000000000
2946 
2947 #define MICROSECONDS_PER_SECOND 1000000
2948 
2949 #define MILLISECONDS_PER_SECOND 1000
2950 
2951 #define NANOSECONDS_PER_MILLISECOND 1000000
2952 
2953 #define MICROSECONDS_PER_MILLISECOND 1000
2954 
2959 void
2960 _dbus_sleep_milliseconds (int milliseconds)
2961 {
2962 #ifdef HAVE_NANOSLEEP
2963  struct timespec req;
2964  struct timespec rem;
2965 
2966  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2967  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2968  rem.tv_sec = 0;
2969  rem.tv_nsec = 0;
2970 
2971  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2972  req = rem;
2973 #elif defined (HAVE_USLEEP)
2974  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2975 #else /* ! HAVE_USLEEP */
2976  sleep (MAX (milliseconds / 1000, 1));
2977 #endif
2978 }
2979 
2991  int n_bytes,
2992  DBusError *error)
2993 {
2994  int old_len;
2995  int fd;
2996  int result;
2997 
2998  old_len = _dbus_string_get_length (str);
2999  fd = -1;
3000 
3001  /* note, urandom on linux will fall back to pseudorandom */
3002  fd = open ("/dev/urandom", O_RDONLY);
3003 
3004  if (fd < 0)
3005  {
3006  dbus_set_error (error, _dbus_error_from_errno (errno),
3007  "Could not open /dev/urandom: %s",
3008  _dbus_strerror (errno));
3009  return FALSE;
3010  }
3011 
3012  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3013 
3014  result = _dbus_read (fd, str, n_bytes);
3015 
3016  if (result != n_bytes)
3017  {
3018  if (result < 0)
3019  dbus_set_error (error, _dbus_error_from_errno (errno),
3020  "Could not read /dev/urandom: %s",
3021  _dbus_strerror (errno));
3022  else
3024  "Short read from /dev/urandom");
3025 
3026  _dbus_close (fd, NULL);
3027  _dbus_string_set_length (str, old_len);
3028  return FALSE;
3029  }
3030 
3031  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3032  n_bytes);
3033 
3034  _dbus_close (fd, NULL);
3035 
3036  return TRUE;
3037 }
3038 
3044 void
3045 _dbus_exit (int code)
3046 {
3047  _exit (code);
3048 }
3049 
3058 const char*
3059 _dbus_strerror (int error_number)
3060 {
3061  const char *msg;
3062 
3063  msg = strerror (error_number);
3064  if (msg == NULL)
3065  msg = "unknown";
3066 
3067  return msg;
3068 }
3069 
3073 void
3075 {
3076  signal (SIGPIPE, SIG_IGN);
3077 }
3078 
3086 void
3088 {
3089  int val;
3090 
3091  val = fcntl (fd, F_GETFD, 0);
3092 
3093  if (val < 0)
3094  return;
3095 
3096  val |= FD_CLOEXEC;
3097 
3098  fcntl (fd, F_SETFD, val);
3099 }
3100 
3109 _dbus_close (int fd,
3110  DBusError *error)
3111 {
3112  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3113 
3114  again:
3115  if (close (fd) < 0)
3116  {
3117  if (errno == EINTR)
3118  goto again;
3119 
3120  dbus_set_error (error, _dbus_error_from_errno (errno),
3121  "Could not close fd %d", fd);
3122  return FALSE;
3123  }
3124 
3125  return TRUE;
3126 }
3127 
3136 int
3137 _dbus_dup(int fd,
3138  DBusError *error)
3139 {
3140  int new_fd;
3141 
3142 #ifdef F_DUPFD_CLOEXEC
3143  dbus_bool_t cloexec_done;
3144 
3145  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3146  cloexec_done = new_fd >= 0;
3147 
3148  if (new_fd < 0 && errno == EINVAL)
3149 #endif
3150  {
3151  new_fd = fcntl(fd, F_DUPFD, 3);
3152  }
3153 
3154  if (new_fd < 0) {
3155 
3156  dbus_set_error (error, _dbus_error_from_errno (errno),
3157  "Could not duplicate fd %d", fd);
3158  return -1;
3159  }
3160 
3161 #ifdef F_DUPFD_CLOEXEC
3162  if (!cloexec_done)
3163 #endif
3164  {
3166  }
3167 
3168  return new_fd;
3169 }
3170 
3180  DBusError *error)
3181 {
3182  return _dbus_set_fd_nonblocking (fd.fd, error);
3183 }
3184 
3185 static dbus_bool_t
3186 _dbus_set_fd_nonblocking (int fd,
3187  DBusError *error)
3188 {
3189  int val;
3190 
3191  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3192 
3193  val = fcntl (fd, F_GETFL, 0);
3194  if (val < 0)
3195  {
3196  dbus_set_error (error, _dbus_error_from_errno (errno),
3197  "Failed to get flags from file descriptor %d: %s",
3198  fd, _dbus_strerror (errno));
3199  _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3200  _dbus_strerror (errno));
3201  return FALSE;
3202  }
3203 
3204  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3205  {
3206  dbus_set_error (error, _dbus_error_from_errno (errno),
3207  "Failed to set nonblocking flag of file descriptor %d: %s",
3208  fd, _dbus_strerror (errno));
3209  _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3210  fd, _dbus_strerror (errno));
3211 
3212  return FALSE;
3213  }
3214 
3215  return TRUE;
3216 }
3217 
3223 void
3225 {
3226 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3227  void *bt[500];
3228  int bt_size;
3229  int i;
3230  char **syms;
3231 
3232  bt_size = backtrace (bt, 500);
3233 
3234  syms = backtrace_symbols (bt, bt_size);
3235 
3236  i = 0;
3237  while (i < bt_size)
3238  {
3239  /* don't use dbus_warn since it can _dbus_abort() */
3240  fprintf (stderr, " %s\n", syms[i]);
3241  ++i;
3242  }
3243  fflush (stderr);
3244 
3245  free (syms);
3246 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3247  fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3248 #else
3249  fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3250 #endif
3251 }
3252 
3267  DBusSocket *fd2,
3268  dbus_bool_t blocking,
3269  DBusError *error)
3270 {
3271 #ifdef HAVE_SOCKETPAIR
3272  int fds[2];
3273  int retval;
3274 
3275 #ifdef SOCK_CLOEXEC
3276  dbus_bool_t cloexec_done;
3277 
3278  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3279  cloexec_done = retval >= 0;
3280 
3281  if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3282 #endif
3283  {
3284  retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3285  }
3286 
3287  if (retval < 0)
3288  {
3289  dbus_set_error (error, _dbus_error_from_errno (errno),
3290  "Could not create full-duplex pipe");
3291  return FALSE;
3292  }
3293 
3294  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3295 
3296 #ifdef SOCK_CLOEXEC
3297  if (!cloexec_done)
3298 #endif
3299  {
3300  _dbus_fd_set_close_on_exec (fds[0]);
3301  _dbus_fd_set_close_on_exec (fds[1]);
3302  }
3303 
3304  if (!blocking &&
3305  (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3306  !_dbus_set_fd_nonblocking (fds[1], NULL)))
3307  {
3308  dbus_set_error (error, _dbus_error_from_errno (errno),
3309  "Could not set full-duplex pipe nonblocking");
3310 
3311  _dbus_close (fds[0], NULL);
3312  _dbus_close (fds[1], NULL);
3313 
3314  return FALSE;
3315  }
3316 
3317  fd1->fd = fds[0];
3318  fd2->fd = fds[1];
3319 
3320  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3321  fd1->fd, fd2->fd);
3322 
3323  return TRUE;
3324 #else
3325  _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
3327  "_dbus_socketpair() not implemented on this OS");
3328  return FALSE;
3329 #endif
3330 }
3331 
3340 int
3342  va_list args)
3343 {
3344  char static_buf[1024];
3345  int bufsize = sizeof (static_buf);
3346  int len;
3347  va_list args_copy;
3348 
3349  DBUS_VA_COPY (args_copy, args);
3350  len = vsnprintf (static_buf, bufsize, format, args_copy);
3351  va_end (args_copy);
3352 
3353  /* If vsnprintf() returned non-negative, then either the string fits in
3354  * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3355  * returns the number of characters that were needed, or this OS returns the
3356  * truncated length.
3357  *
3358  * We ignore the possibility that snprintf might just ignore the length and
3359  * overrun the buffer (64-bit Solaris 7), because that's pathological.
3360  * If your libc is really that bad, come back when you have a better one. */
3361  if (len == bufsize)
3362  {
3363  /* This could be the truncated length (Tru64 and IRIX have this bug),
3364  * or the real length could be coincidentally the same. Which is it?
3365  * If vsnprintf returns the truncated length, we'll go to the slow
3366  * path. */
3367  DBUS_VA_COPY (args_copy, args);
3368 
3369  if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3370  len = -1;
3371 
3372  va_end (args_copy);
3373  }
3374 
3375  /* If vsnprintf() returned negative, we have to do more work.
3376  * HP-UX returns negative. */
3377  while (len < 0)
3378  {
3379  char *buf;
3380 
3381  bufsize *= 2;
3382 
3383  buf = dbus_malloc (bufsize);
3384 
3385  if (buf == NULL)
3386  return -1;
3387 
3388  DBUS_VA_COPY (args_copy, args);
3389  len = vsnprintf (buf, bufsize, format, args_copy);
3390  va_end (args_copy);
3391 
3392  dbus_free (buf);
3393 
3394  /* If the reported length is exactly the buffer size, round up to the
3395  * next size, in case vsnprintf has been returning the truncated
3396  * length */
3397  if (len == bufsize)
3398  len = -1;
3399  }
3400 
3401  return len;
3402 }
3403 
3410 const char*
3412 {
3413  /* Protected by _DBUS_LOCK_sysdeps */
3414  static const char* tmpdir = NULL;
3415 
3416  if (!_DBUS_LOCK (sysdeps))
3417  return NULL;
3418 
3419  if (tmpdir == NULL)
3420  {
3421  /* TMPDIR is what glibc uses, then
3422  * glibc falls back to the P_tmpdir macro which
3423  * just expands to "/tmp"
3424  */
3425  if (tmpdir == NULL)
3426  tmpdir = getenv("TMPDIR");
3427 
3428  /* These two env variables are probably
3429  * broken, but maybe some OS uses them?
3430  */
3431  if (tmpdir == NULL)
3432  tmpdir = getenv("TMP");
3433  if (tmpdir == NULL)
3434  tmpdir = getenv("TEMP");
3435 
3436  /* And this is the sane fallback. */
3437  if (tmpdir == NULL)
3438  tmpdir = "/tmp";
3439  }
3440 
3441  _DBUS_UNLOCK (sysdeps);
3442 
3443  _dbus_assert(tmpdir != NULL);
3444 
3445  return tmpdir;
3446 }
3447 
3448 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3449 
3468 static dbus_bool_t
3469 _read_subprocess_line_argv (const char *progpath,
3470  dbus_bool_t path_fallback,
3471  char * const *argv,
3472  DBusString *result,
3473  DBusError *error)
3474 {
3475  int result_pipe[2] = { -1, -1 };
3476  int errors_pipe[2] = { -1, -1 };
3477  pid_t pid;
3478  int ret;
3479  int status;
3480  int orig_len;
3481 
3482  dbus_bool_t retval;
3483  sigset_t new_set, old_set;
3484 
3485  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3486  retval = FALSE;
3487 
3488  /* We need to block any existing handlers for SIGCHLD temporarily; they
3489  * will cause waitpid() below to fail.
3490  * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3491  */
3492  sigemptyset (&new_set);
3493  sigaddset (&new_set, SIGCHLD);
3494  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3495 
3496  orig_len = _dbus_string_get_length (result);
3497 
3498 #define READ_END 0
3499 #define WRITE_END 1
3500  if (pipe (result_pipe) < 0)
3501  {
3502  dbus_set_error (error, _dbus_error_from_errno (errno),
3503  "Failed to create a pipe to call %s: %s",
3504  progpath, _dbus_strerror (errno));
3505  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3506  progpath, _dbus_strerror (errno));
3507  goto out;
3508  }
3509  if (pipe (errors_pipe) < 0)
3510  {
3511  dbus_set_error (error, _dbus_error_from_errno (errno),
3512  "Failed to create a pipe to call %s: %s",
3513  progpath, _dbus_strerror (errno));
3514  _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3515  progpath, _dbus_strerror (errno));
3516  goto out;
3517  }
3518 
3519  pid = fork ();
3520  if (pid < 0)
3521  {
3522  dbus_set_error (error, _dbus_error_from_errno (errno),
3523  "Failed to fork() to call %s: %s",
3524  progpath, _dbus_strerror (errno));
3525  _dbus_verbose ("Failed to fork() to call %s: %s\n",
3526  progpath, _dbus_strerror (errno));
3527  goto out;
3528  }
3529 
3530  if (pid == 0)
3531  {
3532  /* child process */
3533  int fd;
3534 
3535  fd = open ("/dev/null", O_RDWR);
3536  if (fd == -1)
3537  /* huh?! can't open /dev/null? */
3538  _exit (1);
3539 
3540  _dbus_verbose ("/dev/null fd %d opened\n", fd);
3541 
3542  /* set-up stdXXX */
3543  close (result_pipe[READ_END]);
3544  close (errors_pipe[READ_END]);
3545 
3546  if (dup2 (fd, 0) == -1) /* setup stdin */
3547  _exit (1);
3548  if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3549  _exit (1);
3550  if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3551  _exit (1);
3552 
3553  _dbus_close_all ();
3554 
3555  sigprocmask (SIG_SETMASK, &old_set, NULL);
3556 
3557  /* If it looks fully-qualified, try execv first */
3558  if (progpath[0] == '/')
3559  {
3560  execv (progpath, argv);
3561  /* Ok, that failed. Now if path_fallback is given, let's
3562  * try unqualified. This is mostly a hack to work
3563  * around systems which ship dbus-launch in /usr/bin
3564  * but everything else in /bin (because dbus-launch
3565  * depends on X11).
3566  */
3567  if (path_fallback)
3568  /* We must have a slash, because we checked above */
3569  execvp (strrchr (progpath, '/')+1, argv);
3570  }
3571  else
3572  execvp (progpath, argv);
3573 
3574  /* still nothing, we failed */
3575  _exit (1);
3576  }
3577 
3578  /* parent process */
3579  close (result_pipe[WRITE_END]);
3580  close (errors_pipe[WRITE_END]);
3581  result_pipe[WRITE_END] = -1;
3582  errors_pipe[WRITE_END] = -1;
3583 
3584  ret = 0;
3585  do
3586  {
3587  ret = _dbus_read (result_pipe[READ_END], result, 1024);
3588  }
3589  while (ret > 0);
3590 
3591  /* reap the child process to avoid it lingering as zombie */
3592  do
3593  {
3594  ret = waitpid (pid, &status, 0);
3595  }
3596  while (ret == -1 && errno == EINTR);
3597 
3598  /* We succeeded if the process exited with status 0 and
3599  anything was read */
3600  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3601  {
3602  /* The process ended with error */
3603  DBusString error_message;
3604  if (!_dbus_string_init (&error_message))
3605  {
3606  _DBUS_SET_OOM (error);
3607  goto out;
3608  }
3609 
3610  ret = 0;
3611  do
3612  {
3613  ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3614  }
3615  while (ret > 0);
3616 
3617  _dbus_string_set_length (result, orig_len);
3618  if (_dbus_string_get_length (&error_message) > 0)
3620  "%s terminated abnormally with the following error: %s",
3621  progpath, _dbus_string_get_data (&error_message));
3622  else
3624  "%s terminated abnormally without any error message",
3625  progpath);
3626  goto out;
3627  }
3628 
3629  retval = TRUE;
3630 
3631  out:
3632  sigprocmask (SIG_SETMASK, &old_set, NULL);
3633 
3634  if (retval)
3635  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3636  else
3637  _DBUS_ASSERT_ERROR_IS_SET (error);
3638 
3639  if (result_pipe[0] != -1)
3640  close (result_pipe[0]);
3641  if (result_pipe[1] != -1)
3642  close (result_pipe[1]);
3643  if (errors_pipe[0] != -1)
3644  close (errors_pipe[0]);
3645  if (errors_pipe[1] != -1)
3646  close (errors_pipe[1]);
3647 
3648  return retval;
3649 }
3650 #endif
3651 
3665 _dbus_get_autolaunch_address (const char *scope,
3666  DBusString *address,
3667  DBusError *error)
3668 {
3669 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3670  /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3671  * but that's done elsewhere, and if it worked, this function wouldn't
3672  * be called.) */
3673  const char *display;
3674  char *progpath;
3675  char *argv[6];
3676  int i;
3677  DBusString uuid;
3678  dbus_bool_t retval;
3679 
3680  if (_dbus_check_setuid ())
3681  {
3683  "Unable to autolaunch when setuid");
3684  return FALSE;
3685  }
3686 
3687  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3688  retval = FALSE;
3689 
3690  /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3691  * dbus-launch-x11 is just going to fail. Rather than trying to
3692  * run it, we might as well bail out early with a nice error.
3693  *
3694  * This is not strictly true in a world where the user bus exists,
3695  * because dbus-launch --autolaunch knows how to connect to that -
3696  * but if we were going to connect to the user bus, we'd have done
3697  * so before trying autolaunch: in any case. */
3698  display = _dbus_getenv ("DISPLAY");
3699 
3700  if (display == NULL || display[0] == '\0')
3701  {
3703  "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3704  return FALSE;
3705  }
3706 
3707  if (!_dbus_string_init (&uuid))
3708  {
3709  _DBUS_SET_OOM (error);
3710  return FALSE;
3711  }
3712 
3713  if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
3714  {
3715  goto out;
3716  }
3717 
3718 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3719  if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
3720  progpath = TEST_BUS_LAUNCH_BINARY;
3721  else
3722 #endif
3723  progpath = DBUS_BINDIR "/dbus-launch";
3724  /*
3725  * argv[0] is always dbus-launch, that's the name what we'll
3726  * get from /proc, or ps(1), regardless what the progpath is,
3727  * see fd.o#69716
3728  */
3729  i = 0;
3730  argv[i] = "dbus-launch";
3731  ++i;
3732  argv[i] = "--autolaunch";
3733  ++i;
3734  argv[i] = _dbus_string_get_data (&uuid);
3735  ++i;
3736  argv[i] = "--binary-syntax";
3737  ++i;
3738  argv[i] = "--close-stderr";
3739  ++i;
3740  argv[i] = NULL;
3741  ++i;
3742 
3743  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3744 
3745  retval = _read_subprocess_line_argv (progpath,
3746  TRUE,
3747  argv, address, error);
3748 
3749  out:
3750  _dbus_string_free (&uuid);
3751  return retval;
3752 #else
3754  "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3755  "set your DBUS_SESSION_BUS_ADDRESS instead");
3756  return FALSE;
3757 #endif
3758 }
3759 
3780  dbus_bool_t create_if_not_found,
3781  DBusError *error)
3782 {
3783  DBusString filename;
3784  dbus_bool_t b;
3785 
3786  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3787 
3788  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3789  if (b)
3790  return TRUE;
3791 
3792  dbus_error_free (error);
3793 
3794  /* Fallback to the system machine ID */
3795  _dbus_string_init_const (&filename, "/etc/machine-id");
3796  b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3797 
3798  if (b)
3799  {
3800  /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
3801  * complain if that isn't possible for whatever reason */
3802  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3803  _dbus_write_uuid_file (&filename, machine_id, NULL);
3804 
3805  return TRUE;
3806  }
3807 
3808  if (!create_if_not_found)
3809  return FALSE;
3810 
3811  /* if none found, try to make a new one */
3812  dbus_error_free (error);
3813  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3814 
3815  if (!_dbus_generate_uuid (machine_id, error))
3816  return FALSE;
3817 
3818  return _dbus_write_uuid_file (&filename, machine_id, error);
3819 }
3820 
3830  const char *launchd_env_var,
3831  DBusError *error)
3832 {
3833 #ifdef DBUS_ENABLE_LAUNCHD
3834  char *argv[4];
3835  int i;
3836 
3837  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3838 
3839  if (_dbus_check_setuid ())
3840  {
3842  "Unable to find launchd socket when setuid");
3843  return FALSE;
3844  }
3845 
3846  i = 0;
3847  argv[i] = "launchctl";
3848  ++i;
3849  argv[i] = "getenv";
3850  ++i;
3851  argv[i] = (char*)launchd_env_var;
3852  ++i;
3853  argv[i] = NULL;
3854  ++i;
3855 
3856  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3857 
3858  if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3859  {
3860  return FALSE;
3861  }
3862 
3863  /* no error, but no result either */
3864  if (_dbus_string_get_length(socket_path) == 0)
3865  {
3866  return FALSE;
3867  }
3868 
3869  /* strip the carriage-return */
3870  _dbus_string_shorten(socket_path, 1);
3871  return TRUE;
3872 #else /* DBUS_ENABLE_LAUNCHD */
3874  "can't lookup socket from launchd; launchd support not compiled in");
3875  return FALSE;
3876 #endif
3877 }
3878 
3879 #ifdef DBUS_ENABLE_LAUNCHD
3880 static dbus_bool_t
3881 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3882 {
3883  dbus_bool_t valid_socket;
3884  DBusString socket_path;
3885 
3886  if (_dbus_check_setuid ())
3887  {
3889  "Unable to find launchd socket when setuid");
3890  return FALSE;
3891  }
3892 
3893  if (!_dbus_string_init (&socket_path))
3894  {
3895  _DBUS_SET_OOM (error);
3896  return FALSE;
3897  }
3898 
3899  valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3900 
3901  if (dbus_error_is_set(error))
3902  {
3903  _dbus_string_free(&socket_path);
3904  return FALSE;
3905  }
3906 
3907  if (!valid_socket)
3908  {
3909  dbus_set_error(error, "no socket path",
3910  "launchd did not provide a socket path, "
3911  "verify that org.freedesktop.dbus-session.plist is loaded!");
3912  _dbus_string_free(&socket_path);
3913  return FALSE;
3914  }
3915  if (!_dbus_string_append (address, "unix:path="))
3916  {
3917  _DBUS_SET_OOM (error);
3918  _dbus_string_free(&socket_path);
3919  return FALSE;
3920  }
3921  if (!_dbus_string_copy (&socket_path, 0, address,
3922  _dbus_string_get_length (address)))
3923  {
3924  _DBUS_SET_OOM (error);
3925  _dbus_string_free(&socket_path);
3926  return FALSE;
3927  }
3928 
3929  _dbus_string_free(&socket_path);
3930  return TRUE;
3931 }
3932 #endif
3933 
3935 _dbus_lookup_user_bus (dbus_bool_t *supported,
3936  DBusString *address,
3937  DBusError *error)
3938 {
3939  const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
3940  dbus_bool_t ret = FALSE;
3941  struct stat stbuf;
3942  DBusString user_bus_path;
3943 
3944  if (runtime_dir == NULL)
3945  {
3946  _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
3947  *supported = FALSE;
3948  return TRUE; /* Cannot use it, but not an error */
3949  }
3950 
3951  if (!_dbus_string_init (&user_bus_path))
3952  {
3953  _DBUS_SET_OOM (error);
3954  return FALSE;
3955  }
3956 
3957  if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
3958  {
3959  _DBUS_SET_OOM (error);
3960  goto out;
3961  }
3962 
3963  if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
3964  {
3965  _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
3966  _dbus_strerror (errno));
3967  *supported = FALSE;
3968  ret = TRUE; /* Cannot use it, but not an error */
3969  goto out;
3970  }
3971 
3972  if (stbuf.st_uid != getuid ())
3973  {
3974  _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
3975  (long) stbuf.st_uid, (long) getuid ());
3976  *supported = FALSE;
3977  ret = TRUE; /* Cannot use it, but not an error */
3978  goto out;
3979  }
3980 
3981  if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
3982  {
3983  _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
3984  (long) stbuf.st_mode);
3985  *supported = FALSE;
3986  ret = TRUE; /* Cannot use it, but not an error */
3987  goto out;
3988  }
3989 
3990  if (!_dbus_string_append (address, "unix:path=") ||
3991  !_dbus_address_append_escaped (address, &user_bus_path))
3992  {
3993  _DBUS_SET_OOM (error);
3994  goto out;
3995  }
3996 
3997  *supported = TRUE;
3998  ret = TRUE;
3999 
4000 out:
4001  _dbus_string_free (&user_bus_path);
4002  return ret;
4003 }
4004 
4026  DBusString *address,
4027  DBusError *error)
4028 {
4029 #ifdef DBUS_ENABLE_LAUNCHD
4030  *supported = TRUE;
4031  return _dbus_lookup_session_address_launchd (address, error);
4032 #else
4033  *supported = FALSE;
4034 
4035  if (!_dbus_lookup_user_bus (supported, address, error))
4036  return FALSE;
4037  else if (*supported)
4038  return TRUE;
4039 
4040  /* On non-Mac Unix platforms, if the session address isn't already
4041  * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4042  * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4043  * autolaunch: global default; see init_session_address in
4044  * dbus/dbus-bus.c. */
4045  return TRUE;
4046 #endif
4047 }
4048 
4056 void
4058 {
4060 }
4061 
4077  DBusCredentials *credentials)
4078 {
4079  DBusString homedir;
4080  DBusString dotdir;
4081  dbus_uid_t uid;
4082 
4083  _dbus_assert (credentials != NULL);
4085 
4086  if (!_dbus_string_init (&homedir))
4087  return FALSE;
4088 
4089  uid = _dbus_credentials_get_unix_uid (credentials);
4090  _dbus_assert (uid != DBUS_UID_UNSET);
4091 
4092  if (!_dbus_homedir_from_uid (uid, &homedir))
4093  goto failed;
4094 
4095 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
4096  {
4097  const char *override;
4098 
4099  override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4100  if (override != NULL && *override != '\0')
4101  {
4102  _dbus_string_set_length (&homedir, 0);
4103  if (!_dbus_string_append (&homedir, override))
4104  goto failed;
4105 
4106  _dbus_verbose ("Using fake homedir for testing: %s\n",
4107  _dbus_string_get_const_data (&homedir));
4108  }
4109  else
4110  {
4111  /* Not strictly thread-safe, but if we fail at thread-safety here,
4112  * the worst that will happen is some extra warnings. */
4113  static dbus_bool_t already_warned = FALSE;
4114  if (!already_warned)
4115  {
4116  _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
4117  already_warned = TRUE;
4118  }
4119  }
4120  }
4121 #endif
4122 
4123  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4124  if (!_dbus_concat_dir_and_file (&homedir,
4125  &dotdir))
4126  goto failed;
4127 
4128  if (!_dbus_string_copy (&homedir, 0,
4129  directory, _dbus_string_get_length (directory))) {
4130  goto failed;
4131  }
4132 
4133  _dbus_string_free (&homedir);
4134  return TRUE;
4135 
4136  failed:
4137  _dbus_string_free (&homedir);
4138  return FALSE;
4139 }
4140 
4141 //PENDING(kdab) docs
4143 _dbus_daemon_publish_session_bus_address (const char* addr,
4144  const char *scope)
4145 {
4146  return TRUE;
4147 }
4148 
4149 //PENDING(kdab) docs
4150 void
4151 _dbus_daemon_unpublish_session_bus_address (void)
4152 {
4153 
4154 }
4155 
4164 {
4165  return e == EAGAIN || e == EWOULDBLOCK;
4166 }
4167 
4177  DBusError *error)
4178 {
4179  const char *filename_c;
4180 
4181  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4182 
4183  filename_c = _dbus_string_get_const_data (filename);
4184 
4185  if (rmdir (filename_c) != 0)
4186  {
4188  "Failed to remove directory %s: %s\n",
4189  filename_c, _dbus_strerror (errno));
4190  return FALSE;
4191  }
4192 
4193  return TRUE;
4194 }
4195 
4205 {
4206 #ifdef SCM_RIGHTS
4207  union {
4208  struct sockaddr sa;
4209  struct sockaddr_storage storage;
4210  struct sockaddr_un un;
4211  } sa_buf;
4212 
4213  socklen_t sa_len = sizeof(sa_buf);
4214 
4215  _DBUS_ZERO(sa_buf);
4216 
4217  if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4218  return FALSE;
4219 
4220  return sa_buf.sa.sa_family == AF_UNIX;
4221 
4222 #else
4223  return FALSE;
4224 
4225 #endif
4226 }
4227 
4232 void
4234 {
4235  int maxfds, i;
4236 
4237 #ifdef __linux__
4238  DIR *d;
4239 
4240  /* On Linux we can optimize this a bit if /proc is available. If it
4241  isn't available, fall back to the brute force way. */
4242 
4243  d = opendir ("/proc/self/fd");
4244  if (d)
4245  {
4246  for (;;)
4247  {
4248  struct dirent buf, *de;
4249  int k, fd;
4250  long l;
4251  char *e = NULL;
4252 
4253  k = readdir_r (d, &buf, &de);
4254  if (k != 0 || !de)
4255  break;
4256 
4257  if (de->d_name[0] == '.')
4258  continue;
4259 
4260  errno = 0;
4261  l = strtol (de->d_name, &e, 10);
4262  if (errno != 0 || e == NULL || *e != '\0')
4263  continue;
4264 
4265  fd = (int) l;
4266  if (fd < 3)
4267  continue;
4268 
4269  if (fd == dirfd (d))
4270  continue;
4271 
4272  close (fd);
4273  }
4274 
4275  closedir (d);
4276  return;
4277  }
4278 #endif
4279 
4280  maxfds = sysconf (_SC_OPEN_MAX);
4281 
4282  /* Pick something reasonable if for some reason sysconf says
4283  * unlimited.
4284  */
4285  if (maxfds < 0)
4286  maxfds = 1024;
4287 
4288  /* close all inherited fds */
4289  for (i = 3; i < maxfds; i++)
4290  close (i);
4291 }
4292 
4304 {
4305  /* TODO: get __libc_enable_secure exported from glibc.
4306  * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4307  */
4308 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4309  {
4310  /* See glibc/include/unistd.h */
4311  extern int __libc_enable_secure;
4312  return __libc_enable_secure;
4313  }
4314 #elif defined(HAVE_ISSETUGID)
4315  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4316  return issetugid ();
4317 #else
4318  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4319  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4320 
4321  /* We call into this function from _dbus_threads_init_platform_specific()
4322  * to make sure these are initialized before we start threading. */
4323  static dbus_bool_t check_setuid_initialised;
4324  static dbus_bool_t is_setuid;
4325 
4326  if (_DBUS_UNLIKELY (!check_setuid_initialised))
4327  {
4328 #ifdef HAVE_GETRESUID
4329  if (getresuid (&ruid, &euid, &suid) != 0 ||
4330  getresgid (&rgid, &egid, &sgid) != 0)
4331 #endif /* HAVE_GETRESUID */
4332  {
4333  suid = ruid = getuid ();
4334  sgid = rgid = getgid ();
4335  euid = geteuid ();
4336  egid = getegid ();
4337  }
4338 
4339  check_setuid_initialised = TRUE;
4340  is_setuid = (ruid != euid || ruid != suid ||
4341  rgid != egid || rgid != sgid);
4342 
4343  }
4344  return is_setuid;
4345 #endif
4346 }
4347 
4357  DBusString *address,
4358  DBusError *error)
4359 {
4360  union {
4361  struct sockaddr sa;
4362  struct sockaddr_storage storage;
4363  struct sockaddr_un un;
4364  struct sockaddr_in ipv4;
4365  struct sockaddr_in6 ipv6;
4366  } socket;
4367  char hostip[INET6_ADDRSTRLEN];
4368  int size = sizeof (socket);
4369  DBusString path_str;
4370 
4371  if (getsockname (fd.fd, &socket.sa, &size))
4372  goto err;
4373 
4374  switch (socket.sa.sa_family)
4375  {
4376  case AF_UNIX:
4377  if (socket.un.sun_path[0]=='\0')
4378  {
4379  _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4380  if (_dbus_string_append (address, "unix:abstract=") &&
4381  _dbus_address_append_escaped (address, &path_str))
4382  return TRUE;
4383  }
4384  else
4385  {
4386  _dbus_string_init_const (&path_str, socket.un.sun_path);
4387  if (_dbus_string_append (address, "unix:path=") &&
4388  _dbus_address_append_escaped (address, &path_str))
4389  return TRUE;
4390  }
4391  break;
4392  case AF_INET:
4393  if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4394  if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4395  hostip, ntohs (socket.ipv4.sin_port)))
4396  return TRUE;
4397  break;
4398 #ifdef AF_INET6
4399  case AF_INET6:
4400  _dbus_string_init_const (&path_str, hostip);
4401  if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4402  if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
4403  ntohs (socket.ipv6.sin6_port)) &&
4404  _dbus_address_append_escaped (address, &path_str))
4405  return TRUE;
4406  break;
4407 #endif
4408  default:
4409  dbus_set_error (error,
4410  _dbus_error_from_errno (EINVAL),
4411  "Failed to read address from socket: Unknown socket type.");
4412  return FALSE;
4413  }
4414  err:
4415  dbus_set_error (error,
4416  _dbus_error_from_errno (errno),
4417  "Failed to open socket: %s",
4418  _dbus_strerror (errno));
4419  return FALSE;
4420 }
4421 
4422 int
4423 _dbus_save_socket_errno (void)
4424 {
4425  return errno;
4426 }
4427 
4428 void
4429 _dbus_restore_socket_errno (int saved_errno)
4430 {
4431  errno = saved_errno;
4432 }
4433 
4434 /* 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:935
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_int(const DBusString *str, int start, long *value_return, int *end_return)
Parses an integer contained in a DBusString.
Definition: dbus-sysdeps.c:435
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:279
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_PRIVATE_EXPORT dbus_bool_t _dbus_string_append_uint(DBusString *str, unsigned long value)
Appends an unsigned integer to a DBusString.
Definition: dbus-sysdeps.c:392
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++.
#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:284
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.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
void * dbus_realloc(void *memory, size_t bytes)
Resizes a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:601
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
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:123
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:119
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_append_address_from_socket(DBusSocket fd, DBusString *address, DBusError *error)
Read the address from the socket and append it to the string.
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:349
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_gid_t primary_gid
GID.
dbus_bool_t _dbus_credentials_add_linux_security_label(DBusCredentials *credentials, const char *label)
Add a Linux security label, as used by LSMs such as SELinux, Smack and AppArmor, to the credentials...
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:385
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:490
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
short events
Events to poll for.
Definition: dbus-sysdeps.h:380
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:1283
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:112
dbus_bool_t _dbus_send_credentials_socket(DBusSocket server_fd, DBusError *error)
Sends a single nul byte with our UNIX credentials as ancillary data.
dbus_bool_t _dbus_close_socket(DBusSocket fd, DBusError *error)
Closes a socket.
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:114
dbus_bool_t _dbus_parse_uid(const DBusString *uid_str, dbus_uid_t *uid)
Gets a UID from a UID string.
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:590
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:461
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:105
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
Socket interface.
Definition: dbus-sysdeps.h:148
dbus_gid_t * group_ids
Groups IDs, including above primary group.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
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_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:461
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...
dbus_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock(int e)
See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently for Winsock so is abstracted) ...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
int n_group_ids
Size of group IDs array.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:389
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
int _dbus_write_socket_two(DBusSocket fd, const DBusString *buffer1, int start1, int len1, const DBusString *buffer2, int start2, int len2)
Like _dbus_write_two() but only works on sockets and is thus available on Windows.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
dbus_uid_t uid
UID.
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_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
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.
dbus_bool_t _dbus_read_credentials_socket(DBusSocket client_fd, DBusCredentials *credentials, DBusError *error)
Reads a single byte which must be nul (an error occurs otherwise), and reads unix credentials if avai...
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
Object representing an exception.
Definition: dbus-errors.h:48
dbus_bool_t _dbus_address_append_escaped(DBusString *escaped, const DBusString *unescaped)
Appends an escaped version of one string to another string, using the D-Bus address escaping mechanis...
Definition: dbus-address.c:104
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
#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().
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked...
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. ...
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR, TMP, and TEMP in that order.
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1157
#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:259
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:116
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the credentials of the current process to the passed-in credentials object.
#define TRUE
Expands to "1".
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:379
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
dbus_bool_t _dbus_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define READ_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:873
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:121
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.
void _dbus_exit(int code)
Exit the process, returning the given value.
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_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
DBusSocket _dbus_connect_tcp_socket(const char *host, const char *port, const char *family, DBusError *error)
Creates a socket and connects to a socket at the given host and port.
dbus_uid_t _dbus_getuid(void)
Gets our UID.
dbus_bool_t _dbus_generate_random_bytes(DBusString *str, int n_bytes, DBusError *error)
Generates the given number of securely random bytes, using the best mechanism we can come up with...
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
#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_close(int fd, DBusError *error)
Closes a file descriptor.
#define FALSE
Expands to "0".
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we&#39;re running on from the dbus configuration.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
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:802
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
int _dbus_write_socket(DBusSocket fd, const DBusString *buffer, int start, int len)
Like _dbus_write(), but only supports sockets and is thus available on Windows.
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.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
DBUS_PRIVATE_EXPORT void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
#define WRITE_END
Helps remember which end of the pipe is which.
Definition: dbus-spawn.c:875
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:109
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...
char * _dbus_strdup(const char *str)
Duplicates a string.
#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_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:185
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:107
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
short revents
Events that occurred.
Definition: dbus-sysdeps.h:381
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_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.
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Information about a UNIX user.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:391