D-Bus 1.15.2
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 <limits.h>
41#include <sys/types.h>
42#include <stdlib.h>
43#include <string.h>
44#include <signal.h>
45#include <unistd.h>
46#include <stdio.h>
47#include <fcntl.h>
48#include <sys/socket.h>
49#include <dirent.h>
50#include <sys/un.h>
51#include <pwd.h>
52#include <time.h>
53#include <locale.h>
54#include <sys/time.h>
55#include <sys/stat.h>
56#include <sys/wait.h>
57#include <netinet/in.h>
58#include <netinet/tcp.h>
59#include <netdb.h>
60#include <grp.h>
61#include <arpa/inet.h>
62
63#ifdef HAVE_ERRNO_H
64#include <errno.h>
65#endif
66#ifdef HAVE_LINUX_CLOSE_RANGE_H
67#include <linux/close_range.h>
68#endif
69#ifdef HAVE_SYSLOG_H
70#include <syslog.h>
71#endif
72#ifdef HAVE_WRITEV
73#include <sys/uio.h>
74#endif
75#ifdef HAVE_BACKTRACE
76#include <execinfo.h>
77#endif
78#ifdef HAVE_GETPEERUCRED
79#include <ucred.h>
80#endif
81#ifdef HAVE_ALLOCA_H
82#include <alloca.h>
83#endif
84#ifdef HAVE_SYS_RANDOM_H
85#include <sys/random.h>
86#endif
87#ifdef HAVE_SYS_SYSCALL_H
88#include <sys/syscall.h>
89#endif
90
91#ifdef HAVE_ADT
92#include <bsm/adt.h>
93#endif
94
95#ifdef HAVE_SYSTEMD
96#include <systemd/sd-daemon.h>
97#endif
98
99#if !DBUS_USE_SYNC
100#include <pthread.h>
101#endif
102
103#ifndef O_BINARY
104#define O_BINARY 0
105#endif
106
107#ifndef AI_ADDRCONFIG
108#define AI_ADDRCONFIG 0
109#endif
110
111#ifndef HAVE_SOCKLEN_T
112#define socklen_t int
113#endif
114
115#if defined (__sun) || defined (__sun__)
116/*
117 * CMS_SPACE etc. definitions for Solaris < 10, based on
118 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
119 * via
120 * http://wiki.opencsw.org/porting-faq#toc10
121 *
122 * These are only redefined for Solaris, for now: if your OS needs these too,
123 * please file a bug. (Or preferably, improve your OS so they're not needed.)
124 */
125
126# ifndef CMSG_ALIGN
127# ifdef __sun__
128# define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
129# else
130 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
131# define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
132 ~(sizeof (long) - 1))
133# endif
134# endif
135
136# ifndef CMSG_SPACE
137# define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
138 CMSG_ALIGN (len))
139# endif
140
141# ifndef CMSG_LEN
142# define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
143# endif
144
145#endif /* Solaris */
146
147#if defined(__linux__) && defined(__NR_close_range) && !defined(HAVE_CLOSE_RANGE)
148/* The kernel headers are new enough to have the close_range syscall,
149 * but glibc isn't new enough to have the syscall wrapper, so call the
150 * syscall directly. */
151static inline int
152close_range (unsigned int first,
153 unsigned int last,
154 unsigned int flags)
155{
156 return syscall (__NR_close_range, first, last, flags);
157}
158/* Now we can call that inline wrapper as though it was provided by glibc. */
159#define HAVE_CLOSE_RANGE
160#endif
161
177_dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
178 const char **error_str_p)
179{
180 static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
181 DBUS_FORCE_STDOUT_NULL,
182 DBUS_FORCE_STDERR_NULL };
183 /* Should always get replaced with the real error before use */
184 const char *error_str = "Failed mysteriously";
185 int devnull = -1;
186 int saved_errno;
187 /* This function relies on the standard fds having their POSIX values. */
188 _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
189 _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
190 _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
191 int i;
192
193 for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
194 {
195 /* Because we rely on being single-threaded, and we want the
196 * standard fds to not be close-on-exec, we don't set it
197 * close-on-exec. */
198 if (devnull < i)
199 devnull = open ("/dev/null", O_RDWR);
200
201 if (devnull < 0)
202 {
203 error_str = "Failed to open /dev/null";
204 goto out;
205 }
206
207 /* We already opened all fds < i, so the only way this assertion
208 * could fail is if another thread closed one, and we document
209 * this function as not safe for multi-threading. */
210 _dbus_assert (devnull >= i);
211
212 if (devnull != i && (flags & relevant_flag[i]) != 0)
213 {
214 if (dup2 (devnull, i) < 0)
215 {
216 error_str = "Failed to dup2 /dev/null onto a standard fd";
217 goto out;
218 }
219 }
220 }
221
222 error_str = NULL;
223
224out:
225 saved_errno = errno;
226
227 if (devnull > STDERR_FILENO)
228 close (devnull);
229
230 if (error_str_p != NULL)
231 *error_str_p = error_str;
232
233 errno = saved_errno;
234 return (error_str == NULL);
235}
236
237static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
238 DBusError *error);
239
240static dbus_bool_t
241_dbus_open_socket (int *fd_p,
242 int domain,
243 int type,
244 int protocol,
245 DBusError *error)
246{
247#ifdef SOCK_CLOEXEC
248 dbus_bool_t cloexec_done;
249
250 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
251 cloexec_done = *fd_p >= 0;
252
253 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
254 if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
255#endif
256 {
257 *fd_p = socket (domain, type, protocol);
258 }
259
260 if (*fd_p >= 0)
261 {
262#ifdef SOCK_CLOEXEC
263 if (!cloexec_done)
264#endif
265 {
267 }
268
269 _dbus_verbose ("socket fd %d opened\n", *fd_p);
270 return TRUE;
271 }
272 else
273 {
274 dbus_set_error(error,
276 "Failed to open socket: %s",
277 _dbus_strerror (errno));
278 return FALSE;
279 }
280}
281
292static dbus_bool_t
293_dbus_open_unix_socket (int *fd,
294 DBusError *error)
295{
296 return _dbus_open_socket(fd, AF_UNIX, SOCK_STREAM, 0, error);
297}
298
313 DBusError *error)
314{
315 dbus_bool_t rv;
316
317 _dbus_assert (fd != NULL);
318 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
319
320 rv = _dbus_close (fd->fd, error);
321 _dbus_socket_invalidate (fd);
322
323 return rv;
324}
325
335int
337 DBusString *buffer,
338 int count)
339{
340 return _dbus_read (fd.fd, buffer, count);
341}
342
353int
355 const DBusString *buffer,
356 int start,
357 int len)
358{
359#if HAVE_DECL_MSG_NOSIGNAL
360 const char *data;
361 int bytes_written;
362
363 data = _dbus_string_get_const_data_len (buffer, start, len);
364
365 again:
366
367 bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
368
369 if (bytes_written < 0 && errno == EINTR)
370 goto again;
371
372 return bytes_written;
373
374#else
375 return _dbus_write (fd.fd, buffer, start, len);
376#endif
377}
378
391int
393 DBusString *buffer,
394 int count,
395 int *fds,
396 unsigned int *n_fds) {
397#ifndef HAVE_UNIX_FD_PASSING
398 int r;
399
400 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
401 return r;
402
403 *n_fds = 0;
404 return r;
405
406#else
407 int bytes_read;
408 int start;
409 struct msghdr m;
410 struct iovec iov;
411
412 _dbus_assert (count >= 0);
414
415 start = _dbus_string_get_length (buffer);
416
417 if (!_dbus_string_lengthen (buffer, count))
418 {
419 errno = ENOMEM;
420 return -1;
421 }
422
423 _DBUS_ZERO(iov);
424 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
425 iov.iov_len = count;
426
427 _DBUS_ZERO(m);
428 m.msg_iov = &iov;
429 m.msg_iovlen = 1;
430
431 /* Hmm, we have no clue how long the control data will actually be
432 that is queued for us. The least we can do is assume that the
433 caller knows. Hence let's make space for the number of fds that
434 we shall read at max plus the cmsg header. */
435 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
436
437 /* It's probably safe to assume that systems with SCM_RIGHTS also
438 know alloca() */
439 m.msg_control = alloca(m.msg_controllen);
440 memset(m.msg_control, 0, m.msg_controllen);
441
442 /* Do not include the padding at the end when we tell the kernel
443 * how much we're willing to receive. This avoids getting
444 * the padding filled with additional fds that we weren't expecting,
445 * if a (potentially malicious) sender included them. (fd.o #83622) */
446 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
447
448 again:
449
450 bytes_read = recvmsg (fd.fd, &m, 0
451#ifdef MSG_CMSG_CLOEXEC
452 |MSG_CMSG_CLOEXEC
453#endif
454 );
455
456 if (bytes_read < 0)
457 {
458 if (errno == EINTR)
459 goto again;
460 else
461 {
462 /* put length back (note that this doesn't actually realloc anything) */
463 _dbus_string_set_length (buffer, start);
464 return -1;
465 }
466 }
467 else
468 {
469 struct cmsghdr *cm;
470 dbus_bool_t found = FALSE;
471
472 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
473 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
474 {
475 size_t i;
476 int *payload = (int *) (void *) CMSG_DATA (cm);
477 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
478 size_t payload_len_fds;
479 size_t fds_to_use;
480
481 /* Every unsigned int fits in a size_t without truncation, so
482 * casting (size_t) *n_fds is OK */
483 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
484
485 if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
486 (char *) payload + payload_len_bytes >
487 (char *) m.msg_control + m.msg_controllen)
488 {
489 /* This is the last cmsg in a truncated message and using
490 * cmsg_len would apparently overrun the allocated buffer.
491 * Some operating systems (illumos and Solaris are known) do
492 * not adjust cmsg_len in the last cmsg when truncation occurs.
493 * Adjust the payload length here. The calculation for
494 * payload_len_fds below will discard any trailing bytes that
495 * belong to an incomplete file descriptor - the kernel will
496 * have already closed that (at least for illumos and Solaris)
497 */
498 payload_len_bytes = m.msg_controllen -
499 ((char *) payload - (char *) m.msg_control);
500 }
501
502 payload_len_fds = payload_len_bytes / sizeof (int);
503
504 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
505 {
506 /* The fds in the payload will fit in our buffer */
507 fds_to_use = payload_len_fds;
508 }
509 else
510 {
511 /* Too many fds in the payload. This shouldn't happen
512 * any more because we're setting m.msg_controllen to
513 * the exact number we can accept, but be safe and
514 * truncate. */
515 fds_to_use = (size_t) *n_fds;
516
517 /* Close the excess fds to avoid DoS: if they stayed open,
518 * someone could send us an extra fd per message
519 * and we'd eventually run out. */
520 for (i = fds_to_use; i < payload_len_fds; i++)
521 {
522 close (payload[i]);
523 }
524 }
525
526 memcpy (fds, payload, fds_to_use * sizeof (int));
527 found = TRUE;
528 /* This narrowing cast from size_t to unsigned int cannot
529 * overflow because we have chosen fds_to_use
530 * to be <= *n_fds */
531 *n_fds = (unsigned int) fds_to_use;
532
533 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
534 worked, hence we need to go through this list and set
535 CLOEXEC everywhere in any case */
536 for (i = 0; i < fds_to_use; i++)
538
539 break;
540 }
541
542 if (!found)
543 *n_fds = 0;
544
545 if (m.msg_flags & MSG_CTRUNC)
546 {
547 unsigned int i;
548
549 /* Hmm, apparently the control data was truncated. The bad
550 thing is that we might have completely lost a couple of fds
551 without chance to recover them. Hence let's treat this as a
552 serious error. */
553
554 /* We still need to close whatever fds we *did* receive,
555 * otherwise they'll never get closed. (CVE-2020-12049) */
556 for (i = 0; i < *n_fds; i++)
557 close (fds[i]);
558
559 *n_fds = 0;
560 errno = ENOSPC;
561 _dbus_string_set_length (buffer, start);
562 return -1;
563 }
564
565 /* put length back (doesn't actually realloc) */
566 _dbus_string_set_length (buffer, start + bytes_read);
567
568#if 0
569 if (bytes_read > 0)
570 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
571#endif
572
573 return bytes_read;
574 }
575#endif
576}
577
578int
579_dbus_write_socket_with_unix_fds(DBusSocket fd,
580 const DBusString *buffer,
581 int start,
582 int len,
583 const int *fds,
584 int n_fds) {
585
586#ifndef HAVE_UNIX_FD_PASSING
587
588 if (n_fds > 0) {
589 errno = ENOTSUP;
590 return -1;
591 }
592
593 return _dbus_write_socket(fd, buffer, start, len);
594#else
595 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
596#endif
597}
598
599int
600_dbus_write_socket_with_unix_fds_two(DBusSocket fd,
601 const DBusString *buffer1,
602 int start1,
603 int len1,
604 const DBusString *buffer2,
605 int start2,
606 int len2,
607 const int *fds,
608 int n_fds) {
609
610#ifndef HAVE_UNIX_FD_PASSING
611
612 if (n_fds > 0) {
613 errno = ENOTSUP;
614 return -1;
615 }
616
617 return _dbus_write_socket_two(fd,
618 buffer1, start1, len1,
619 buffer2, start2, len2);
620#else
621
622 struct msghdr m;
623 struct cmsghdr *cm;
624 struct iovec iov[2];
625 int bytes_written;
626
627 _dbus_assert (len1 >= 0);
628 _dbus_assert (len2 >= 0);
629 _dbus_assert (n_fds >= 0);
630
631 _DBUS_ZERO(iov);
632 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
633 iov[0].iov_len = len1;
634
635 if (buffer2)
636 {
637 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
638 iov[1].iov_len = len2;
639 }
640
641 _DBUS_ZERO(m);
642 m.msg_iov = iov;
643 m.msg_iovlen = buffer2 ? 2 : 1;
644
645 if (n_fds > 0)
646 {
647 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
648 m.msg_control = alloca(m.msg_controllen);
649 memset(m.msg_control, 0, m.msg_controllen);
650
651 cm = CMSG_FIRSTHDR(&m);
652 cm->cmsg_level = SOL_SOCKET;
653 cm->cmsg_type = SCM_RIGHTS;
654 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
655 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
656 }
657
658 again:
659
660 bytes_written = sendmsg (fd.fd, &m, 0
661#if HAVE_DECL_MSG_NOSIGNAL
662 |MSG_NOSIGNAL
663#endif
664 );
665
666 if (bytes_written < 0 && errno == EINTR)
667 goto again;
668
669#if 0
670 if (bytes_written > 0)
671 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
672#endif
673
674 return bytes_written;
675#endif
676}
677
691int
693 const DBusString *buffer1,
694 int start1,
695 int len1,
696 const DBusString *buffer2,
697 int start2,
698 int len2)
699{
700#if HAVE_DECL_MSG_NOSIGNAL
701 struct iovec vectors[2];
702 const char *data1;
703 const char *data2;
704 int bytes_written;
705 struct msghdr m;
706
707 _dbus_assert (buffer1 != NULL);
708 _dbus_assert (start1 >= 0);
709 _dbus_assert (start2 >= 0);
710 _dbus_assert (len1 >= 0);
711 _dbus_assert (len2 >= 0);
712
713 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
714
715 if (buffer2 != NULL)
716 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
717 else
718 {
719 data2 = NULL;
720 start2 = 0;
721 len2 = 0;
722 }
723
724 vectors[0].iov_base = (char*) data1;
725 vectors[0].iov_len = len1;
726 vectors[1].iov_base = (char*) data2;
727 vectors[1].iov_len = len2;
728
729 _DBUS_ZERO(m);
730 m.msg_iov = vectors;
731 m.msg_iovlen = data2 ? 2 : 1;
732
733 again:
734
735 bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
736
737 if (bytes_written < 0 && errno == EINTR)
738 goto again;
739
740 return bytes_written;
741
742#else
743 return _dbus_write_two (fd.fd, buffer1, start1, len1,
744 buffer2, start2, len2);
745#endif
746}
747
764int
766 DBusString *buffer,
767 int count)
768{
769 int bytes_read;
770 int start;
771 char *data;
772
773 _dbus_assert (count >= 0);
774
775 start = _dbus_string_get_length (buffer);
776
777 if (!_dbus_string_lengthen (buffer, count))
778 {
779 errno = ENOMEM;
780 return -1;
781 }
782
783 data = _dbus_string_get_data_len (buffer, start, count);
784
785 again:
786
787 bytes_read = read (fd, data, count);
788
789 if (bytes_read < 0)
790 {
791 if (errno == EINTR)
792 goto again;
793 else
794 {
795 /* put length back (note that this doesn't actually realloc anything) */
796 _dbus_string_set_length (buffer, start);
797 return -1;
798 }
799 }
800 else
801 {
802 /* put length back (doesn't actually realloc) */
803 _dbus_string_set_length (buffer, start + bytes_read);
804
805#if 0
806 if (bytes_read > 0)
807 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
808#endif
809
810 return bytes_read;
811 }
812}
813
824int
826 const DBusString *buffer,
827 int start,
828 int len)
829{
830 const char *data;
831 int bytes_written;
832
833 data = _dbus_string_get_const_data_len (buffer, start, len);
834
835 again:
836
837 bytes_written = write (fd, data, len);
838
839 if (bytes_written < 0 && errno == EINTR)
840 goto again;
841
842#if 0
843 if (bytes_written > 0)
844 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
845#endif
846
847 return bytes_written;
848}
849
870int
872 const DBusString *buffer1,
873 int start1,
874 int len1,
875 const DBusString *buffer2,
876 int start2,
877 int len2)
878{
879 _dbus_assert (buffer1 != NULL);
880 _dbus_assert (start1 >= 0);
881 _dbus_assert (start2 >= 0);
882 _dbus_assert (len1 >= 0);
883 _dbus_assert (len2 >= 0);
884
885#ifdef HAVE_WRITEV
886 {
887 struct iovec vectors[2];
888 const char *data1;
889 const char *data2;
890 int bytes_written;
891
892 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
893
894 if (buffer2 != NULL)
895 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
896 else
897 {
898 data2 = NULL;
899 start2 = 0;
900 len2 = 0;
901 }
902
903 vectors[0].iov_base = (char*) data1;
904 vectors[0].iov_len = len1;
905 vectors[1].iov_base = (char*) data2;
906 vectors[1].iov_len = len2;
907
908 again:
909
910 bytes_written = writev (fd,
911 vectors,
912 data2 ? 2 : 1);
913
914 if (bytes_written < 0 && errno == EINTR)
915 goto again;
916
917 return bytes_written;
918 }
919#else /* HAVE_WRITEV */
920 {
921 int ret1, ret2;
922
923 ret1 = _dbus_write (fd, buffer1, start1, len1);
924 if (ret1 == len1 && buffer2 != NULL)
925 {
926 ret2 = _dbus_write (fd, buffer2, start2, len2);
927 if (ret2 < 0)
928 ret2 = 0; /* we can't report an error as the first write was OK */
929
930 return ret1 + ret2;
931 }
932 else
933 return ret1;
934 }
935#endif /* !HAVE_WRITEV */
936}
937
956 dbus_bool_t abstract,
957 DBusError *error)
958{
959 DBusSocket fd = DBUS_SOCKET_INIT;
960 size_t path_len;
961 struct sockaddr_un addr;
962 _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
963
964 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
965
966 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
967 path, abstract);
968
969
970 if (!_dbus_open_unix_socket (&fd.fd, error))
971 {
972 _DBUS_ASSERT_ERROR_IS_SET(error);
973 return fd;
974 }
975 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
976
977 _DBUS_ZERO (addr);
978 addr.sun_family = AF_UNIX;
979 path_len = strlen (path);
980
981 if (abstract)
982 {
983#ifdef __linux__
984 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
985 path_len++; /* Account for the extra nul byte added to the start of sun_path */
986
987 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
988 {
990 "Abstract socket name too long\n");
992 return fd;
993 }
994
995 strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
996 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
997#else /* !__linux__ */
999 "Operating system does not support abstract socket namespace\n");
1000 _dbus_close_socket (&fd, NULL);
1001 return fd;
1002#endif /* !__linux__ */
1003 }
1004 else
1005 {
1006 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1007 {
1009 "Socket name too long\n");
1010 _dbus_close_socket (&fd, NULL);
1011 return fd;
1012 }
1013
1014 strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1015 }
1016
1017 if (connect (fd.fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1018 {
1019 dbus_set_error (error,
1020 _dbus_error_from_errno (errno),
1021 "Failed to connect to socket %s: %s",
1022 path, _dbus_strerror (errno));
1023
1024 _dbus_close_socket (&fd, NULL);
1025 return fd;
1026 }
1027
1028 if (!_dbus_set_fd_nonblocking (fd.fd, error))
1029 {
1030 _DBUS_ASSERT_ERROR_IS_SET (error);
1031
1032 _dbus_close_socket (&fd, NULL);
1033 return fd;
1034 }
1035
1036 return fd;
1037}
1038
1052_dbus_connect_exec (const char *path,
1053 char *const argv[],
1054 DBusError *error)
1055{
1056 DBusSocket s = DBUS_SOCKET_INIT;
1057 int fds[2];
1058 pid_t pid;
1059 int retval;
1060 dbus_bool_t cloexec_done = 0;
1061
1062 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1063
1064 _dbus_verbose ("connecting to process %s\n", path);
1065
1066#ifdef SOCK_CLOEXEC
1067 retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1068 cloexec_done = (retval >= 0);
1069
1070 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1071#endif
1072 {
1073 retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1074 }
1075
1076 if (retval < 0)
1077 {
1078 dbus_set_error (error,
1079 _dbus_error_from_errno (errno),
1080 "Failed to create socket pair: %s",
1081 _dbus_strerror (errno));
1082 _dbus_assert (!_dbus_socket_is_valid (s));
1083 return s;
1084 }
1085
1086 if (!cloexec_done)
1087 {
1090 }
1091
1092 /* Make sure our output buffers aren't redundantly printed by both the
1093 * parent and the child */
1094 fflush (stdout);
1095 fflush (stderr);
1096
1097 pid = fork ();
1098 if (pid < 0)
1099 {
1100 dbus_set_error (error,
1101 _dbus_error_from_errno (errno),
1102 "Failed to fork() to call %s: %s",
1103 path, _dbus_strerror (errno));
1104 close (fds[0]);
1105 close (fds[1]);
1106 _dbus_assert (!_dbus_socket_is_valid (s));
1107 return s;
1108 }
1109
1110 if (pid == 0)
1111 {
1112 /* child */
1113 close (fds[0]);
1114
1115 dup2 (fds[1], STDIN_FILENO);
1116 dup2 (fds[1], STDOUT_FILENO);
1117
1118 if (fds[1] != STDIN_FILENO &&
1119 fds[1] != STDOUT_FILENO)
1120 close (fds[1]);
1121
1122 /* Inherit STDERR and the controlling terminal from the
1123 parent */
1124
1125 _dbus_close_all ();
1126
1127 execvp (path, (char * const *) argv);
1128
1129 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1130
1131 _exit(1);
1132 }
1133
1134 /* parent */
1135 close (fds[1]);
1136
1137 if (!_dbus_set_fd_nonblocking (fds[0], error))
1138 {
1139 _DBUS_ASSERT_ERROR_IS_SET (error);
1140
1141 close (fds[0]);
1142 _dbus_assert (!_dbus_socket_is_valid (s));
1143 return s;
1144 }
1145
1146 s.fd = fds[0];
1147 return s;
1148}
1149
1169 dbus_bool_t abstract,
1170 DBusError *error)
1171{
1172 DBusSocket s = DBUS_SOCKET_INIT;
1173 int listen_fd;
1174 struct sockaddr_un addr;
1175 size_t path_len;
1176 _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1177
1178 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1179
1180 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1181 path, abstract);
1182
1183 if (!_dbus_open_unix_socket (&listen_fd, error))
1184 {
1185 _DBUS_ASSERT_ERROR_IS_SET(error);
1186 return s;
1187 }
1188 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1189
1190 _DBUS_ZERO (addr);
1191 addr.sun_family = AF_UNIX;
1192 path_len = strlen (path);
1193
1194 if (abstract)
1195 {
1196#ifdef __linux__
1197 /* remember that abstract names aren't nul-terminated so we rely
1198 * on sun_path being filled in with zeroes above.
1199 */
1200 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1201 path_len++; /* Account for the extra nul byte added to the start of sun_path */
1202
1203 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1204 {
1206 "Abstract socket name too long\n");
1207 _dbus_close (listen_fd, NULL);
1208 return s;
1209 }
1210
1211 strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1212 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1213#else /* !__linux__ */
1215 "Operating system does not support abstract socket namespace\n");
1216 _dbus_close (listen_fd, NULL);
1217 return s;
1218#endif /* !__linux__ */
1219 }
1220 else
1221 {
1222 /* Discussed security implications of this with Nalin,
1223 * and we couldn't think of where it would kick our ass, but
1224 * it still seems a bit sucky. It also has non-security suckage;
1225 * really we'd prefer to exit if the socket is already in use.
1226 * But there doesn't seem to be a good way to do this.
1227 *
1228 * Just to be extra careful, I threw in the stat() - clearly
1229 * the stat() can't *fix* any security issue, but it at least
1230 * avoids inadvertent/accidental data loss.
1231 */
1232 {
1233 struct stat sb;
1234
1235 if (stat (path, &sb) == 0 &&
1236 S_ISSOCK (sb.st_mode))
1237 unlink (path);
1238 }
1239
1240 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1241 {
1243 "Socket name too long\n");
1244 _dbus_close (listen_fd, NULL);
1245 return s;
1246 }
1247
1248 strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1249 }
1250
1251 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1252 {
1253 dbus_set_error (error, _dbus_error_from_errno (errno),
1254 "Failed to bind socket \"%s\": %s",
1255 path, _dbus_strerror (errno));
1256 _dbus_close (listen_fd, NULL);
1257 return s;
1258 }
1259
1260 if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1261 {
1262 dbus_set_error (error, _dbus_error_from_errno (errno),
1263 "Failed to listen on socket \"%s\": %s",
1264 path, _dbus_strerror (errno));
1265 _dbus_close (listen_fd, NULL);
1266 return s;
1267 }
1268
1269 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1270 {
1271 _DBUS_ASSERT_ERROR_IS_SET (error);
1272 _dbus_close (listen_fd, NULL);
1273 return s;
1274 }
1275
1276 /* Try opening up the permissions, but if we can't, just go ahead
1277 * and continue, maybe it will be good enough.
1278 */
1279 if (!abstract && chmod (path, 0777) < 0)
1280 _dbus_warn ("Could not set mode 0777 on socket %s", path);
1281
1282 s.fd = listen_fd;
1283 return s;
1284}
1285
1296int
1298 DBusError *error)
1299{
1300#ifdef HAVE_SYSTEMD
1301 int r, n;
1302 int fd;
1303 DBusSocket *new_fds;
1304
1305 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1306
1307 n = sd_listen_fds (TRUE);
1308 if (n < 0)
1309 {
1311 "Failed to acquire systemd socket: %s",
1312 _dbus_strerror (-n));
1313 return -1;
1314 }
1315
1316 if (n <= 0)
1317 {
1319 "No socket received.");
1320 return -1;
1321 }
1322
1323 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1324 {
1325 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1326 if (r < 0)
1327 {
1329 "Failed to verify systemd socket type: %s",
1330 _dbus_strerror (-r));
1331 return -1;
1332 }
1333
1334 if (!r)
1335 {
1337 "Passed socket has wrong type.");
1338 return -1;
1339 }
1340 }
1341
1342 /* OK, the file descriptors are all good, so let's take posession of
1343 them then. */
1344
1345 new_fds = dbus_new (DBusSocket, n);
1346 if (!new_fds)
1347 {
1349 "Failed to allocate file handle array.");
1350 goto fail;
1351 }
1352
1353 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1354 {
1355 if (!_dbus_set_fd_nonblocking (fd, error))
1356 {
1357 _DBUS_ASSERT_ERROR_IS_SET (error);
1358 goto fail;
1359 }
1360
1361 new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1362 }
1363
1364 *fds = new_fds;
1365 return n;
1366
1367 fail:
1368
1369 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1370 {
1371 _dbus_close (fd, NULL);
1372 }
1373
1374 dbus_free (new_fds);
1375 return -1;
1376#else
1378 "dbus was compiled without systemd support");
1379 return -1;
1380#endif
1381}
1382
1383/* Convert an error code from getaddrinfo() or getnameinfo() into
1384 * a D-Bus error name. */
1385static const char *
1386_dbus_error_from_gai (int gai_res,
1387 int saved_errno)
1388{
1389 switch (gai_res)
1390 {
1391#ifdef EAI_FAMILY
1392 case EAI_FAMILY:
1393 /* ai_family not supported (at all) */
1395#endif
1396
1397#ifdef EAI_SOCKTYPE
1398 case EAI_SOCKTYPE:
1399 /* ai_socktype not supported (at all) */
1401#endif
1402
1403#ifdef EAI_MEMORY
1404 case EAI_MEMORY:
1405 /* Out of memory */
1406 return DBUS_ERROR_NO_MEMORY;
1407#endif
1408
1409#ifdef EAI_SYSTEM
1410 case EAI_SYSTEM:
1411 /* Unspecified system error, details in errno */
1412 return _dbus_error_from_errno (saved_errno);
1413#endif
1414
1415 case 0:
1416 /* It succeeded, but we didn't get any addresses? */
1417 return DBUS_ERROR_FAILED;
1418
1419 /* EAI_AGAIN: Transient failure */
1420 /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1421 /* EAI_FAIL: Non-recoverable failure */
1422 /* EAI_NODATA: host exists but has no addresses */
1423 /* EAI_NONAME: host does not exist */
1424 /* EAI_OVERFLOW: argument buffer overflow */
1425 /* EAI_SERVICE: service not available for specified socket
1426 * type (we should never see this because we use numeric
1427 * ports) */
1428 default:
1429 return DBUS_ERROR_FAILED;
1430 }
1431}
1432
1448 const char *port,
1449 const char *family,
1450 DBusError *error)
1451{
1452 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1453}
1454
1456_dbus_connect_tcp_socket_with_nonce (const char *host,
1457 const char *port,
1458 const char *family,
1459 const char *noncefile,
1460 DBusError *error)
1461{
1462 int saved_errno = 0;
1463 DBusList *connect_errors = NULL;
1464 DBusSocket fd = DBUS_SOCKET_INIT;
1465 int res;
1466 struct addrinfo hints;
1467 struct addrinfo *ai = NULL;
1468 const struct addrinfo *tmp;
1469 DBusError *connect_error;
1470
1471 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1472
1473 _DBUS_ZERO (hints);
1474
1475 if (!family)
1476 hints.ai_family = AF_UNSPEC;
1477 else if (!strcmp(family, "ipv4"))
1478 hints.ai_family = AF_INET;
1479 else if (!strcmp(family, "ipv6"))
1480 hints.ai_family = AF_INET6;
1481 else
1482 {
1483 dbus_set_error (error,
1485 "Unknown address family %s", family);
1486 return _dbus_socket_get_invalid ();
1487 }
1488 hints.ai_protocol = IPPROTO_TCP;
1489 hints.ai_socktype = SOCK_STREAM;
1490 hints.ai_flags = AI_ADDRCONFIG;
1491
1492 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1493 {
1494 dbus_set_error (error,
1495 _dbus_error_from_gai (res, errno),
1496 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1497 host, port, gai_strerror(res), res);
1498 goto out;
1499 }
1500
1501 tmp = ai;
1502 while (tmp)
1503 {
1504 if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1505 {
1506 _DBUS_ASSERT_ERROR_IS_SET(error);
1507 _dbus_socket_invalidate (&fd);
1508 goto out;
1509 }
1510 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1511
1512 if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1513 {
1514 saved_errno = errno;
1515 _dbus_close_socket (&fd, NULL);
1516
1517 connect_error = dbus_new0 (DBusError, 1);
1518
1519 if (connect_error == NULL)
1520 {
1521 _DBUS_SET_OOM (error);
1522 goto out;
1523 }
1524
1525 dbus_error_init (connect_error);
1526 _dbus_set_error_with_inet_sockaddr (connect_error,
1527 tmp->ai_addr, tmp->ai_addrlen,
1528 "Failed to connect to socket",
1529 saved_errno);
1530
1531 if (!_dbus_list_append (&connect_errors, connect_error))
1532 {
1533 dbus_error_free (connect_error);
1534 dbus_free (connect_error);
1535 _DBUS_SET_OOM (error);
1536 goto out;
1537 }
1538
1539 tmp = tmp->ai_next;
1540 continue;
1541 }
1542
1543 break;
1544 }
1545
1546 if (!_dbus_socket_is_valid (fd))
1547 {
1548 _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1549 host, port, error);
1550 goto out;
1551 }
1552
1553 if (noncefile != NULL)
1554 {
1555 DBusString noncefileStr;
1556 dbus_bool_t ret;
1557 _dbus_string_init_const (&noncefileStr, noncefile);
1558 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1559
1560 if (!ret)
1561 {
1562 _dbus_close_socket (&fd, NULL);
1563 goto out;
1564 }
1565 }
1566
1567 if (!_dbus_set_fd_nonblocking (fd.fd, error))
1568 {
1569 _dbus_close_socket (&fd, NULL);
1570 goto out;
1571 }
1572
1573out:
1574 if (ai != NULL)
1575 freeaddrinfo (ai);
1576
1577 while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1578 {
1579 dbus_error_free (connect_error);
1580 dbus_free (connect_error);
1581 }
1582
1583 return fd;
1584}
1585
1603int
1604_dbus_listen_tcp_socket (const char *host,
1605 const char *port,
1606 const char *family,
1607 DBusString *retport,
1608 const char **retfamily,
1609 DBusSocket **fds_p,
1610 DBusError *error)
1611{
1612 int saved_errno;
1613 int nlisten_fd = 0, res, i;
1614 DBusList *bind_errors = NULL;
1615 DBusError *bind_error = NULL;
1616 DBusSocket *listen_fd = NULL;
1617 struct addrinfo hints;
1618 struct addrinfo *ai, *tmp;
1619 unsigned int reuseaddr;
1620 dbus_bool_t have_ipv4 = FALSE;
1621 dbus_bool_t have_ipv6 = FALSE;
1622
1623 *fds_p = NULL;
1624 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1625
1626 _DBUS_ZERO (hints);
1627
1628 if (!family)
1629 hints.ai_family = AF_UNSPEC;
1630 else if (!strcmp(family, "ipv4"))
1631 hints.ai_family = AF_INET;
1632 else if (!strcmp(family, "ipv6"))
1633 hints.ai_family = AF_INET6;
1634 else
1635 {
1636 dbus_set_error (error,
1638 "Unknown address family %s", family);
1639 return -1;
1640 }
1641
1642 hints.ai_protocol = IPPROTO_TCP;
1643 hints.ai_socktype = SOCK_STREAM;
1644 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1645
1646 redo_lookup_with_port:
1647 ai = NULL;
1648 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1649 {
1650 dbus_set_error (error,
1651 _dbus_error_from_gai (res, errno),
1652 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1653 host ? host : "*", port, gai_strerror(res), res);
1654 goto failed;
1655 }
1656
1657 tmp = ai;
1658 while (tmp)
1659 {
1660 int fd = -1, tcp_nodelay_on;
1661 DBusSocket *newlisten_fd;
1662
1663 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1664 {
1665 _DBUS_ASSERT_ERROR_IS_SET(error);
1666 goto failed;
1667 }
1668 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1669
1670 reuseaddr = 1;
1671 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1672 {
1673 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1674 host ? host : "*", port, _dbus_strerror (errno));
1675 }
1676
1677 /* Nagle's algorithm imposes a huge delay on the initial messages
1678 going over TCP. */
1679 tcp_nodelay_on = 1;
1680 if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1681 {
1682 _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1683 host ? host : "*", port, _dbus_strerror (errno));
1684 }
1685
1686 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1687 {
1688 saved_errno = errno;
1689 _dbus_close(fd, NULL);
1690
1691 /*
1692 * We don't treat this as a fatal error, because there might be
1693 * other addresses that we can listen on. In particular:
1694 *
1695 * - If saved_errno is EADDRINUSE after we
1696 * "goto redo_lookup_with_port" after binding a port on one of the
1697 * possible addresses, we will try to bind that same port on
1698 * every address, including the same address again for a second
1699 * time, which will fail with EADDRINUSE.
1700 *
1701 * - If saved_errno is EADDRINUSE, it might be because binding to
1702 * an IPv6 address implicitly binds to a corresponding IPv4
1703 * address or vice versa (e.g. Linux with bindv6only=0).
1704 *
1705 * - If saved_errno is EADDRNOTAVAIL when we asked for family
1706 * AF_UNSPEC, it might be because IPv6 is disabled for this
1707 * particular interface (e.g. Linux with
1708 * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1709 */
1710 bind_error = dbus_new0 (DBusError, 1);
1711
1712 if (bind_error == NULL)
1713 {
1714 _DBUS_SET_OOM (error);
1715 goto failed;
1716 }
1717
1718 dbus_error_init (bind_error);
1719 _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1720 "Failed to bind socket",
1721 saved_errno);
1722
1723 if (!_dbus_list_append (&bind_errors, bind_error))
1724 {
1725 dbus_error_free (bind_error);
1726 dbus_free (bind_error);
1727 _DBUS_SET_OOM (error);
1728 goto failed;
1729 }
1730
1731 /* Try the next address, maybe it will work better */
1732 tmp = tmp->ai_next;
1733 continue;
1734 }
1735
1736 if (listen (fd, 30 /* backlog */) < 0)
1737 {
1738 saved_errno = errno;
1739 _dbus_close (fd, NULL);
1740 _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1741 "Failed to listen on socket",
1742 saved_errno);
1743 goto failed;
1744 }
1745
1746 newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1747 if (!newlisten_fd)
1748 {
1749 _dbus_close (fd, NULL);
1751 "Failed to allocate file handle array");
1752 goto failed;
1753 }
1754 listen_fd = newlisten_fd;
1755 listen_fd[nlisten_fd].fd = fd;
1756 nlisten_fd++;
1757
1758 if (tmp->ai_addr->sa_family == AF_INET)
1759 have_ipv4 = TRUE;
1760 else if (tmp->ai_addr->sa_family == AF_INET6)
1761 have_ipv6 = TRUE;
1762
1763 if (!_dbus_string_get_length(retport))
1764 {
1765 /* If the user didn't specify a port, or used 0, then
1766 the kernel chooses a port. After the first address
1767 is bound to, we need to force all remaining addresses
1768 to use the same port */
1769 if (!port || !strcmp(port, "0"))
1770 {
1771 int result;
1772 struct sockaddr_storage addr;
1773 socklen_t addrlen;
1774 char portbuf[50];
1775
1776 addrlen = sizeof(addr);
1777 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1778
1779 if (result == -1)
1780 {
1781 saved_errno = errno;
1782 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1783 "Failed to retrieve socket name for \"%s:%s\": %s",
1784 host ? host : "*", port, _dbus_strerror (saved_errno));
1785 goto failed;
1786 }
1787
1788 if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1789 portbuf, sizeof(portbuf),
1790 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1791 {
1792 saved_errno = errno;
1793 dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1794 "Failed to resolve port \"%s:%s\": %s (%d)",
1795 host ? host : "*", port, gai_strerror(res), res);
1796 goto failed;
1797 }
1798
1799 if (!_dbus_string_append(retport, portbuf))
1800 {
1802 goto failed;
1803 }
1804
1805 /* Release current address list & redo lookup */
1806 port = _dbus_string_get_const_data(retport);
1807 freeaddrinfo(ai);
1808 goto redo_lookup_with_port;
1809 }
1810 else
1811 {
1812 if (!_dbus_string_append(retport, port))
1813 {
1815 goto failed;
1816 }
1817 }
1818 }
1819
1820 tmp = tmp->ai_next;
1821 }
1822 freeaddrinfo(ai);
1823 ai = NULL;
1824
1825 if (!nlisten_fd)
1826 {
1827 _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1828 port, error);
1829 goto failed;
1830 }
1831
1832 if (have_ipv4 && !have_ipv6)
1833 *retfamily = "ipv4";
1834 else if (!have_ipv4 && have_ipv6)
1835 *retfamily = "ipv6";
1836
1837 for (i = 0 ; i < nlisten_fd ; i++)
1838 {
1839 if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1840 {
1841 goto failed;
1842 }
1843 }
1844
1845 *fds_p = listen_fd;
1846
1847 /* This list might be non-empty even on success, because we might be
1848 * ignoring EADDRINUSE or EADDRNOTAVAIL */
1849 while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1850 {
1851 dbus_error_free (bind_error);
1852 dbus_free (bind_error);
1853 }
1854
1855 return nlisten_fd;
1856
1857 failed:
1858 if (ai)
1859 freeaddrinfo(ai);
1860 for (i = 0 ; i < nlisten_fd ; i++)
1861 _dbus_close(listen_fd[i].fd, NULL);
1862
1863 while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1864 {
1865 dbus_error_free (bind_error);
1866 dbus_free (bind_error);
1867 }
1868
1869 dbus_free(listen_fd);
1870 return -1;
1871}
1872
1873static dbus_bool_t
1874write_credentials_byte (int server_fd,
1875 DBusError *error)
1876{
1877 int bytes_written;
1878 char buf[1] = { '\0' };
1879#if defined(HAVE_CMSGCRED)
1880 union {
1881 struct cmsghdr hdr;
1882 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1883 } cmsg;
1884 struct iovec iov;
1885 struct msghdr msg;
1886 iov.iov_base = buf;
1887 iov.iov_len = 1;
1888
1889 _DBUS_ZERO(msg);
1890 msg.msg_iov = &iov;
1891 msg.msg_iovlen = 1;
1892
1893 msg.msg_control = (caddr_t) &cmsg;
1894 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1895 _DBUS_ZERO(cmsg);
1896 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1897 cmsg.hdr.cmsg_level = SOL_SOCKET;
1898 cmsg.hdr.cmsg_type = SCM_CREDS;
1899#endif
1900
1901 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1902
1903 again:
1904
1905#if defined(HAVE_CMSGCRED)
1906 bytes_written = sendmsg (server_fd, &msg, 0
1907#if HAVE_DECL_MSG_NOSIGNAL
1908 |MSG_NOSIGNAL
1909#endif
1910 );
1911
1912 /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1913 * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1914 * only allows that on AF_UNIX. Try just doing a send() instead. */
1915 if (bytes_written < 0 && errno == EINVAL)
1916#endif
1917 {
1918 bytes_written = send (server_fd, buf, 1, 0
1919#if HAVE_DECL_MSG_NOSIGNAL
1920 |MSG_NOSIGNAL
1921#endif
1922 );
1923 }
1924
1925 if (bytes_written < 0 && errno == EINTR)
1926 goto again;
1927
1928 if (bytes_written < 0)
1929 {
1930 dbus_set_error (error, _dbus_error_from_errno (errno),
1931 "Failed to write credentials byte: %s",
1932 _dbus_strerror (errno));
1933 return FALSE;
1934 }
1935 else if (bytes_written == 0)
1936 {
1938 "wrote zero bytes writing credentials byte");
1939 return FALSE;
1940 }
1941 else
1942 {
1943 _dbus_assert (bytes_written == 1);
1944 _dbus_verbose ("wrote credentials byte\n");
1945 return TRUE;
1946 }
1947}
1948
1949/* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1950static dbus_bool_t
1951add_groups_to_credentials (int client_fd,
1952 DBusCredentials *credentials,
1953 dbus_gid_t primary)
1954{
1955#if defined(__linux__) && defined(SO_PEERGROUPS)
1956 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1957 gid_t *buf = NULL;
1958 socklen_t len = 1024;
1959 dbus_bool_t oom = FALSE;
1960 /* libdbus has a different representation of group IDs just to annoy you */
1961 dbus_gid_t *converted_gids = NULL;
1962 dbus_bool_t need_primary = TRUE;
1963 size_t n_gids;
1964 size_t i;
1965
1966 n_gids = ((size_t) len) / sizeof (gid_t);
1967 buf = dbus_new (gid_t, n_gids);
1968
1969 if (buf == NULL)
1970 return FALSE;
1971
1972 while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1973 {
1974 int e = errno;
1975 gid_t *replacement;
1976
1977 _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1978 _dbus_strerror (e), (unsigned long) len);
1979
1980 if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1981 {
1982 _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1983 _dbus_strerror (e));
1984 goto out;
1985 }
1986
1987 /* If not enough space, len is updated to be enough.
1988 * Try again with a large enough buffer. */
1989 n_gids = ((size_t) len) / sizeof (gid_t);
1990 replacement = dbus_realloc (buf, len);
1991
1992 if (replacement == NULL)
1993 {
1994 oom = TRUE;
1995 goto out;
1996 }
1997
1998 buf = replacement;
1999 _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2000 }
2001
2002 if (len <= 0)
2003 {
2004 _dbus_verbose ("getsockopt(SO_PEERGROUPS) yielded <= 0 bytes: %ld\n",
2005 (long) len);
2006 goto out;
2007 }
2008
2009 if (len > n_gids * sizeof (gid_t))
2010 {
2011 _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
2012 _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
2013 }
2014
2015 if (len % sizeof (gid_t) != 0)
2016 {
2017 _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
2018 "integer multiple of sizeof(gid_t): %lu should be "
2019 "divisible by %zu",
2020 (unsigned long) len, sizeof (gid_t));
2021 goto out;
2022 }
2023
2024 /* Allocate an extra space for the primary group ID */
2025 n_gids = ((size_t) len) / sizeof (gid_t);
2026
2027 /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
2028 * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
2029 * This is using _DBUS_INT32_MAX as a conservative lower bound for
2030 * the maximum size_t. */
2031 if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
2032 {
2033 _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
2034 "of groups (%lu bytes), ignoring",
2035 (unsigned long) len);
2036 goto out;
2037 }
2038
2039 converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
2040
2041 if (converted_gids == NULL)
2042 {
2043 oom = TRUE;
2044 goto out;
2045 }
2046
2047 for (i = 0; i < n_gids; i++)
2048 {
2049 converted_gids[i] = (dbus_gid_t) buf[i];
2050
2051 if (converted_gids[i] == primary)
2052 need_primary = FALSE;
2053 }
2054
2055 if (need_primary && primary != DBUS_GID_UNSET)
2056 {
2057 converted_gids[n_gids] = primary;
2058 n_gids++;
2059 }
2060
2061 _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2062
2063out:
2064 dbus_free (buf);
2065 return !oom;
2066#else
2067 /* no error */
2068 return TRUE;
2069#endif
2070}
2071
2072/* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2073static dbus_bool_t
2074add_linux_security_label_to_credentials (int client_fd,
2075 DBusCredentials *credentials)
2076{
2077#if defined(__linux__) && defined(SO_PEERSEC)
2078 DBusString buf;
2079 socklen_t len = 1024;
2080 dbus_bool_t oom = FALSE;
2081
2082 if (!_dbus_string_init_preallocated (&buf, len) ||
2083 !_dbus_string_set_length (&buf, len))
2084 return FALSE;
2085
2086 while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2087 _dbus_string_get_data (&buf), &len) < 0)
2088 {
2089 int e = errno;
2090
2091 _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2092 _dbus_strerror (e), (unsigned long) len);
2093
2094 if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2095 {
2096 _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2097 _dbus_strerror (e));
2098 goto out;
2099 }
2100
2101 /* If not enough space, len is updated to be enough.
2102 * Try again with a large enough buffer. */
2103 if (!_dbus_string_set_length (&buf, len))
2104 {
2105 oom = TRUE;
2106 goto out;
2107 }
2108
2109 _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2110 }
2111
2112 if (len <= 0)
2113 {
2114 _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2115 (unsigned long) len);
2116 goto out;
2117 }
2118
2119 if (len > _dbus_string_get_length_uint (&buf))
2120 {
2121 _dbus_verbose ("%lu > %u", (unsigned long) len,
2122 _dbus_string_get_length_uint (&buf));
2123 _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2124 }
2125
2126 if (_dbus_string_get_byte (&buf, len - 1) == 0)
2127 {
2128 /* the kernel included the trailing \0 in its count,
2129 * but DBusString always has an extra \0 after the data anyway */
2130 _dbus_verbose ("subtracting trailing \\0\n");
2131 len--;
2132 }
2133
2134 if (!_dbus_string_set_length (&buf, len))
2135 {
2136 _dbus_assert_not_reached ("shortening string should not lead to OOM");
2137 oom = TRUE;
2138 goto out;
2139 }
2140
2141 if (strlen (_dbus_string_get_const_data (&buf)) != len)
2142 {
2143 /* LSM people on the linux-security-module@ mailing list say this
2144 * should never happen: the label should be a bytestring with
2145 * an optional trailing \0 */
2146 _dbus_verbose ("security label from kernel had an embedded \\0, "
2147 "ignoring it\n");
2148 goto out;
2149 }
2150
2151 _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2152 (unsigned long) len,
2154
2157 {
2158 oom = TRUE;
2159 goto out;
2160 }
2161
2162out:
2163 _dbus_string_free (&buf);
2164 return !oom;
2165#else
2166 /* no error */
2167 return TRUE;
2168#endif
2169}
2170
2213 DBusCredentials *credentials,
2214 DBusError *error)
2215{
2216 struct msghdr msg;
2217 struct iovec iov;
2218 char buf;
2219 dbus_uid_t uid_read;
2220 dbus_gid_t primary_gid_read;
2221 dbus_pid_t pid_read;
2222 int bytes_read;
2223
2224#ifdef HAVE_CMSGCRED
2225 union {
2226 struct cmsghdr hdr;
2227 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2228 } cmsg;
2229#endif
2230
2231 /* The POSIX spec certainly doesn't promise this, but
2232 * we need these assertions to fail as soon as we're wrong about
2233 * it so we can do the porting fixups
2234 */
2235 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2236 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2237 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2238
2239 uid_read = DBUS_UID_UNSET;
2240 primary_gid_read = DBUS_GID_UNSET;
2241 pid_read = DBUS_PID_UNSET;
2242
2243 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2244
2245 _dbus_credentials_clear (credentials);
2246
2247 iov.iov_base = &buf;
2248 iov.iov_len = 1;
2249
2250 _DBUS_ZERO(msg);
2251 msg.msg_iov = &iov;
2252 msg.msg_iovlen = 1;
2253
2254#if defined(HAVE_CMSGCRED)
2255 _DBUS_ZERO(cmsg);
2256 msg.msg_control = (caddr_t) &cmsg;
2257 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2258#endif
2259
2260 again:
2261 bytes_read = recvmsg (client_fd.fd, &msg, 0);
2262
2263 if (bytes_read < 0)
2264 {
2265 if (errno == EINTR)
2266 goto again;
2267
2268 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2269 * normally only call read_credentials if the socket was ready
2270 * for reading
2271 */
2272
2273 dbus_set_error (error, _dbus_error_from_errno (errno),
2274 "Failed to read credentials byte: %s",
2275 _dbus_strerror (errno));
2276 return FALSE;
2277 }
2278 else if (bytes_read == 0)
2279 {
2280 /* this should not happen unless we are using recvmsg wrong,
2281 * so is essentially here for paranoia
2282 */
2284 "Failed to read credentials byte (zero-length read)");
2285 return FALSE;
2286 }
2287 else if (buf != '\0')
2288 {
2290 "Credentials byte was not nul");
2291 return FALSE;
2292 }
2293
2294 _dbus_verbose ("read credentials byte\n");
2295
2296 {
2297#ifdef SO_PEERCRED
2298 /* Supported by at least Linux and OpenBSD, with minor differences.
2299 *
2300 * This mechanism passes the process ID through and does not require
2301 * the peer's cooperation, so we prefer it over all others. Notably,
2302 * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2303 * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2304 * because this is much less fragile.
2305 */
2306#ifdef __OpenBSD__
2307 struct sockpeercred cr;
2308#else
2309 struct ucred cr;
2310#endif
2311 socklen_t cr_len = sizeof (cr);
2312
2313 if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2314 {
2315 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2316 _dbus_strerror (errno));
2317 }
2318 else if (cr_len != sizeof (cr))
2319 {
2320 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2321 cr_len, (int) sizeof (cr));
2322 }
2323 else
2324 {
2325 pid_read = cr.pid;
2326 uid_read = cr.uid;
2327#ifdef __linux__
2328 /* Do other platforms have cr.gid? (Not that it really matters,
2329 * because the gid is useless to us unless we know the complete
2330 * group vector, which we only know on Linux.) */
2331 primary_gid_read = cr.gid;
2332#endif
2333 }
2334#elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2335 /* Another variant of the above - used on NetBSD
2336 */
2337 struct unpcbid cr;
2338 socklen_t cr_len = sizeof (cr);
2339
2340 if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2341 {
2342 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2343 _dbus_strerror (errno));
2344 }
2345 else if (cr_len != sizeof (cr))
2346 {
2347 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2348 cr_len, (int) sizeof (cr));
2349 }
2350 else
2351 {
2352 pid_read = cr.unp_pid;
2353 uid_read = cr.unp_euid;
2354 }
2355#elif defined(HAVE_CMSGCRED)
2356 /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2357 * presence of that struct implies SCM_CREDS. Supported by at least
2358 * FreeBSD and DragonflyBSD.
2359 *
2360 * This mechanism requires the peer to help us (it has to send us a
2361 * SCM_CREDS message) but it does pass the process ID through,
2362 * which makes it better than getpeereid().
2363 */
2364 struct cmsgcred *cred;
2365 struct cmsghdr *cmsgp;
2366
2367 for (cmsgp = CMSG_FIRSTHDR (&msg);
2368 cmsgp != NULL;
2369 cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2370 {
2371 if (cmsgp->cmsg_type == SCM_CREDS &&
2372 cmsgp->cmsg_level == SOL_SOCKET &&
2373 cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2374 {
2375 cred = (struct cmsgcred *) (void *) CMSG_DATA (cmsgp);
2376 pid_read = cred->cmcred_pid;
2377 uid_read = cred->cmcred_euid;
2378 break;
2379 }
2380 }
2381
2382#elif defined(HAVE_GETPEERUCRED)
2383 /* Supported in at least Solaris >= 10. It should probably be higher
2384 * up this list, because it carries the pid and we use this code path
2385 * for audit data. */
2386 ucred_t * ucred = NULL;
2387 if (getpeerucred (client_fd.fd, &ucred) == 0)
2388 {
2389#ifdef HAVE_ADT
2390 adt_session_data_t *adth = NULL;
2391#endif
2392 pid_read = ucred_getpid (ucred);
2393 uid_read = ucred_geteuid (ucred);
2394#ifdef HAVE_ADT
2395 /* generate audit session data based on socket ucred */
2396 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2397 {
2398 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2399 }
2400 else
2401 {
2402 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2403 {
2404 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2405 }
2406 else
2407 {
2408 adt_export_data_t *data = NULL;
2409 size_t size = adt_export_session_data (adth, &data);
2410 if (size <= 0)
2411 {
2412 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2413 }
2414 else
2415 {
2416 _dbus_credentials_add_adt_audit_data (credentials, data, size);
2417 free (data);
2418 }
2419 }
2420 (void) adt_end_session (adth);
2421 }
2422#endif /* HAVE_ADT */
2423 }
2424 else
2425 {
2426 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2427 }
2428 if (ucred != NULL)
2429 ucred_free (ucred);
2430
2431 /* ----------------------------------------------------------------
2432 * When adding new mechanisms, please add them above this point
2433 * if they support passing the process ID through, or below if not.
2434 * ---------------------------------------------------------------- */
2435
2436#elif defined(HAVE_GETPEEREID)
2437 /* getpeereid() originates from D.J. Bernstein and is fairly
2438 * widely-supported. According to a web search, it might be present in
2439 * any/all of:
2440 *
2441 * - AIX?
2442 * - Blackberry?
2443 * - Cygwin
2444 * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2445 * - Mac OS X
2446 * - Minix 3.1.8+
2447 * - MirBSD?
2448 * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2449 * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2450 * - QNX?
2451 */
2452 uid_t euid;
2453 gid_t egid;
2454 if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2455 {
2456 uid_read = euid;
2457 }
2458 else
2459 {
2460 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2461 }
2462#else /* no supported mechanism */
2463
2464#warning Socket credentials not supported on this Unix OS
2465#warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
2466
2467 /* Please add other operating systems known to support at least one of
2468 * the mechanisms above to this list, keeping alphabetical order.
2469 * Everything not in this list is best-effort.
2470 */
2471#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2472 defined(__linux__) || \
2473 defined(__OpenBSD__) || \
2474 defined(__NetBSD__)
2475# error Credentials passing not working on this OS is a regression!
2476#endif
2477
2478 _dbus_verbose ("Socket credentials not supported on this OS\n");
2479#endif
2480 }
2481
2482 _dbus_verbose ("Credentials:"
2483 " pid "DBUS_PID_FORMAT
2484 " uid "DBUS_UID_FORMAT
2485 "\n",
2486 pid_read,
2487 uid_read);
2488
2489 if (pid_read != DBUS_PID_UNSET)
2490 {
2491 if (!_dbus_credentials_add_pid (credentials, pid_read))
2492 {
2493 _DBUS_SET_OOM (error);
2494 return FALSE;
2495 }
2496 }
2497
2498 if (uid_read != DBUS_UID_UNSET)
2499 {
2500 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2501 {
2502 _DBUS_SET_OOM (error);
2503 return FALSE;
2504 }
2505 }
2506
2507 if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2508 {
2509 _DBUS_SET_OOM (error);
2510 return FALSE;
2511 }
2512
2513 /* We don't put any groups in the credentials unless we can put them
2514 * all there. */
2515 if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2516 {
2517 _DBUS_SET_OOM (error);
2518 return FALSE;
2519 }
2520
2521 return TRUE;
2522}
2523
2543 DBusError *error)
2544{
2545 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2546
2547 if (write_credentials_byte (server_fd.fd, error))
2548 return TRUE;
2549 else
2550 return FALSE;
2551}
2552
2564{
2565 DBusSocket client_fd;
2566 struct sockaddr addr;
2567 socklen_t addrlen;
2568#ifdef HAVE_ACCEPT4
2569 dbus_bool_t cloexec_done;
2570#endif
2571
2572 addrlen = sizeof (addr);
2573
2574 retry:
2575
2576#ifdef HAVE_ACCEPT4
2577 /*
2578 * At compile-time, we assume that if accept4() is available in
2579 * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2580 * not necessarily true that either is supported by the running kernel.
2581 */
2582 client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2583 cloexec_done = client_fd.fd >= 0;
2584
2585 if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2586#endif
2587 {
2588 client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2589 }
2590
2591 if (client_fd.fd < 0)
2592 {
2593 if (errno == EINTR)
2594 goto retry;
2595 }
2596
2597 _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2598
2599#ifdef HAVE_ACCEPT4
2600 if (!cloexec_done)
2601#endif
2602 {
2603 _dbus_fd_set_close_on_exec(client_fd.fd);
2604 }
2605
2606 return client_fd;
2607}
2608
2619{
2620 const char *directory;
2621 struct stat sb;
2622
2623 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2624
2625 directory = _dbus_string_get_const_data (dir);
2626
2627 if (stat (directory, &sb) < 0)
2628 {
2629 dbus_set_error (error, _dbus_error_from_errno (errno),
2630 "%s", _dbus_strerror (errno));
2631
2632 return FALSE;
2633 }
2634
2635 if (sb.st_uid != geteuid ())
2636 {
2638 "%s directory is owned by user %lu, not %lu",
2639 directory,
2640 (unsigned long) sb.st_uid,
2641 (unsigned long) geteuid ());
2642 return FALSE;
2643 }
2644
2645 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2646 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2647 {
2649 "%s directory is not private to the user", directory);
2650 return FALSE;
2651 }
2652
2653 return TRUE;
2654}
2655
2656static dbus_bool_t
2657fill_user_info_from_passwd (struct passwd *p,
2658 DBusUserInfo *info,
2659 DBusError *error)
2660{
2661 _dbus_assert (p->pw_name != NULL);
2662 _dbus_assert (p->pw_dir != NULL);
2663
2664 info->uid = p->pw_uid;
2665 info->primary_gid = p->pw_gid;
2666 info->username = _dbus_strdup (p->pw_name);
2667 info->homedir = _dbus_strdup (p->pw_dir);
2668
2669 if (info->username == NULL ||
2670 info->homedir == NULL)
2671 {
2673 return FALSE;
2674 }
2675
2676 return TRUE;
2677}
2678
2679static dbus_bool_t
2680fill_user_info (DBusUserInfo *info,
2681 dbus_uid_t uid,
2682 const DBusString *username,
2683 DBusError *error)
2684{
2685 const char *username_c;
2686
2687 /* exactly one of username/uid provided */
2688 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2689 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2690
2691 info->uid = DBUS_UID_UNSET;
2693 info->group_ids = NULL;
2694 info->n_group_ids = 0;
2695 info->username = NULL;
2696 info->homedir = NULL;
2697
2698 if (username != NULL)
2699 username_c = _dbus_string_get_const_data (username);
2700 else
2701 username_c = NULL;
2702
2703 /* For now assuming that the getpwnam() and getpwuid() flavors
2704 * are always symmetrical, if not we have to add more configure
2705 * checks
2706 */
2707
2708#ifdef HAVE_GETPWNAM_R
2709 {
2710 struct passwd *p;
2711 int result;
2712 size_t buflen;
2713 char *buf;
2714 struct passwd p_str;
2715
2716 /* retrieve maximum needed size for buf */
2717 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2718
2719 /* sysconf actually returns a long, but everything else expects size_t,
2720 * so just recast here.
2721 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2722 */
2723 if ((long) buflen <= 0)
2724 buflen = 1024;
2725
2726 result = -1;
2727 while (1)
2728 {
2729 buf = dbus_malloc (buflen);
2730 if (buf == NULL)
2731 {
2733 return FALSE;
2734 }
2735
2736 p = NULL;
2737 if (uid != DBUS_UID_UNSET)
2738 result = getpwuid_r (uid, &p_str, buf, buflen,
2739 &p);
2740 else
2741 result = getpwnam_r (username_c, &p_str, buf, buflen,
2742 &p);
2743 //Try a bigger buffer if ERANGE was returned
2744 if (result == ERANGE && buflen < 512 * 1024)
2745 {
2746 dbus_free (buf);
2747 buflen *= 2;
2748 }
2749 else
2750 {
2751 break;
2752 }
2753 }
2754 if (result == 0 && p == &p_str)
2755 {
2756 if (!fill_user_info_from_passwd (p, info, error))
2757 {
2758 dbus_free (buf);
2759 return FALSE;
2760 }
2761 dbus_free (buf);
2762 }
2763 else
2764 {
2765 dbus_set_error (error, _dbus_error_from_errno (errno),
2766 "User \"%s\" unknown or no memory to allocate password entry\n",
2767 username_c ? username_c : "???");
2768 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2769 dbus_free (buf);
2770 return FALSE;
2771 }
2772 }
2773#else /* ! HAVE_GETPWNAM_R */
2774 {
2775 /* I guess we're screwed on thread safety here */
2776 struct passwd *p;
2777
2778#warning getpwnam_r() not available, please report this to the dbus maintainers with details of your OS
2779
2780 if (uid != DBUS_UID_UNSET)
2781 p = getpwuid (uid);
2782 else
2783 p = getpwnam (username_c);
2784
2785 if (p != NULL)
2786 {
2787 if (!fill_user_info_from_passwd (p, info, error))
2788 {
2789 return FALSE;
2790 }
2791 }
2792 else
2793 {
2794 dbus_set_error (error, _dbus_error_from_errno (errno),
2795 "User \"%s\" unknown or no memory to allocate password entry\n",
2796 username_c ? username_c : "???");
2797 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2798 return FALSE;
2799 }
2800 }
2801#endif /* ! HAVE_GETPWNAM_R */
2802
2803 /* Fill this in so we can use it to get groups */
2804 username_c = info->username;
2805
2806#ifdef HAVE_GETGROUPLIST
2807 {
2808 gid_t *buf;
2809 int buf_count;
2810 int i;
2811 int initial_buf_count;
2812
2813 initial_buf_count = 17;
2814 buf_count = initial_buf_count;
2815 buf = dbus_new (gid_t, buf_count);
2816 if (buf == NULL)
2817 {
2819 goto failed;
2820 }
2821
2822 if (getgrouplist (username_c,
2823 info->primary_gid,
2824 buf, &buf_count) < 0)
2825 {
2826 gid_t *new;
2827 /* Presumed cause of negative return code: buf has insufficient
2828 entries to hold the entire group list. The Linux behavior in this
2829 case is to pass back the actual number of groups in buf_count, but
2830 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2831 So as a hack, try to help out a bit by guessing a larger
2832 number of groups, within reason.. might still fail, of course,
2833 but we can at least print a more informative message. I looked up
2834 the "right way" to do this by downloading Apple's own source code
2835 for the "id" command, and it turns out that they use an
2836 undocumented library function getgrouplist_2 (!) which is not
2837 declared in any header in /usr/include (!!). That did not seem
2838 like the way to go here.
2839 */
2840 if (buf_count == initial_buf_count)
2841 {
2842 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2843 }
2844 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2845 if (new == NULL)
2846 {
2848 dbus_free (buf);
2849 goto failed;
2850 }
2851
2852 buf = new;
2853
2854 errno = 0;
2855 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2856 {
2857 if (errno == 0)
2858 {
2859 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2860 username_c, buf_count, buf_count);
2861 }
2862 else
2863 {
2864 dbus_set_error (error,
2865 _dbus_error_from_errno (errno),
2866 "Failed to get groups for username \"%s\" primary GID "
2867 DBUS_GID_FORMAT ": %s\n",
2868 username_c, info->primary_gid,
2869 _dbus_strerror (errno));
2870 dbus_free (buf);
2871 goto failed;
2872 }
2873 }
2874 }
2875
2876 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2877 if (info->group_ids == NULL)
2878 {
2880 dbus_free (buf);
2881 goto failed;
2882 }
2883
2884 for (i = 0; i < buf_count; ++i)
2885 info->group_ids[i] = buf[i];
2886
2887 info->n_group_ids = buf_count;
2888
2889 dbus_free (buf);
2890 }
2891#else /* HAVE_GETGROUPLIST */
2892 {
2893 /* We just get the one group ID */
2894 info->group_ids = dbus_new (dbus_gid_t, 1);
2895 if (info->group_ids == NULL)
2896 {
2898 goto failed;
2899 }
2900
2901 info->n_group_ids = 1;
2902
2903 (info->group_ids)[0] = info->primary_gid;
2904 }
2905#endif /* HAVE_GETGROUPLIST */
2906
2907 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2908
2909 return TRUE;
2910
2911 failed:
2912 _DBUS_ASSERT_ERROR_IS_SET (error);
2913 return FALSE;
2914}
2915
2926 const DBusString *username,
2927 DBusError *error)
2928{
2929 return fill_user_info (info, DBUS_UID_UNSET,
2930 username, error);
2931}
2932
2943 dbus_uid_t uid,
2944 DBusError *error)
2945{
2946 return fill_user_info (info, uid,
2947 NULL, error);
2948}
2949
2965{
2966 /* The POSIX spec certainly doesn't promise this, but
2967 * we need these assertions to fail as soon as we're wrong about
2968 * it so we can do the porting fixups
2969 */
2970 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2971 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2972 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2973
2974 if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2975 return FALSE;
2976 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2977 return FALSE;
2978
2979 return TRUE;
2980}
2981
2995{
2996 return _dbus_string_append_uint (str,
2997 _dbus_geteuid ());
2998}
2999
3006{
3007 return getpid ();
3008}
3009
3015{
3016 return getuid ();
3017}
3018
3024{
3025 return geteuid ();
3026}
3027
3034unsigned long
3036{
3037 return getpid ();
3038}
3039
3040#if !DBUS_USE_SYNC
3041/* To be thread-safe by default on platforms that don't necessarily have
3042 * atomic operations (notably Debian armel, which is armv4t), we must
3043 * use a mutex that can be initialized statically, like this.
3044 * GLib >= 2.32 uses a similar system.
3045 */
3046static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3047#endif
3048
3057{
3058#if DBUS_USE_SYNC
3059 return __sync_add_and_fetch(&atomic->value, 1)-1;
3060#else
3061 dbus_int32_t res;
3062
3063 pthread_mutex_lock (&atomic_mutex);
3064 res = atomic->value;
3065 atomic->value += 1;
3066 pthread_mutex_unlock (&atomic_mutex);
3067
3068 return res;
3069#endif
3070}
3071
3080{
3081#if DBUS_USE_SYNC
3082 return __sync_sub_and_fetch(&atomic->value, 1)+1;
3083#else
3084 dbus_int32_t res;
3085
3086 pthread_mutex_lock (&atomic_mutex);
3087 res = atomic->value;
3088 atomic->value -= 1;
3089 pthread_mutex_unlock (&atomic_mutex);
3090
3091 return res;
3092#endif
3093}
3094
3104{
3105#if DBUS_USE_SYNC
3106 __sync_synchronize ();
3107 return atomic->value;
3108#else
3109 dbus_int32_t res;
3110
3111 pthread_mutex_lock (&atomic_mutex);
3112 res = atomic->value;
3113 pthread_mutex_unlock (&atomic_mutex);
3114
3115 return res;
3116#endif
3117}
3118
3124void
3126{
3127#if DBUS_USE_SYNC
3128 /* Atomic version of "*atomic &= 0; return *atomic" */
3129 __sync_and_and_fetch (&atomic->value, 0);
3130#else
3131 pthread_mutex_lock (&atomic_mutex);
3132 atomic->value = 0;
3133 pthread_mutex_unlock (&atomic_mutex);
3134#endif
3135}
3136
3142void
3144{
3145#if DBUS_USE_SYNC
3146 /* Atomic version of "*atomic |= 1; return *atomic" */
3147 __sync_or_and_fetch (&atomic->value, 1);
3148#else
3149 pthread_mutex_lock (&atomic_mutex);
3150 atomic->value = 1;
3151 pthread_mutex_unlock (&atomic_mutex);
3152#endif
3153}
3154
3163int
3165 int n_fds,
3166 int timeout_milliseconds)
3167{
3168#if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3169 /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3170 if (timeout_milliseconds < -1)
3171 {
3172 timeout_milliseconds = -1;
3173 }
3174
3175 return poll (fds,
3176 n_fds,
3177 timeout_milliseconds);
3178#else /* ! HAVE_POLL */
3179 /* Emulate poll() in terms of select() */
3180 fd_set read_set, write_set, err_set;
3181 int max_fd = 0;
3182 int i;
3183 struct timeval tv;
3184 int ready;
3185
3186 FD_ZERO (&read_set);
3187 FD_ZERO (&write_set);
3188 FD_ZERO (&err_set);
3189
3190 for (i = 0; i < n_fds; i++)
3191 {
3192 DBusPollFD *fdp = &fds[i];
3193
3194 if (fdp->events & _DBUS_POLLIN)
3195 FD_SET (fdp->fd, &read_set);
3196
3197 if (fdp->events & _DBUS_POLLOUT)
3198 FD_SET (fdp->fd, &write_set);
3199
3200 FD_SET (fdp->fd, &err_set);
3201
3202 max_fd = MAX (max_fd, fdp->fd);
3203 }
3204
3205 tv.tv_sec = timeout_milliseconds / 1000;
3206 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3207
3208 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3209 timeout_milliseconds < 0 ? NULL : &tv);
3210
3211 if (ready > 0)
3212 {
3213 for (i = 0; i < n_fds; i++)
3214 {
3215 DBusPollFD *fdp = &fds[i];
3216
3217 fdp->revents = 0;
3218
3219 if (FD_ISSET (fdp->fd, &read_set))
3220 fdp->revents |= _DBUS_POLLIN;
3221
3222 if (FD_ISSET (fdp->fd, &write_set))
3223 fdp->revents |= _DBUS_POLLOUT;
3224
3225 if (FD_ISSET (fdp->fd, &err_set))
3226 fdp->revents |= _DBUS_POLLERR;
3227 }
3228 }
3229
3230 return ready;
3231#endif
3232}
3233
3241void
3243 long *tv_usec)
3244{
3245#ifdef HAVE_MONOTONIC_CLOCK
3246 struct timespec ts;
3247 clock_gettime (CLOCK_MONOTONIC, &ts);
3248
3249 if (tv_sec)
3250 *tv_sec = ts.tv_sec;
3251 if (tv_usec)
3252 *tv_usec = ts.tv_nsec / 1000;
3253#else
3254 struct timeval t;
3255
3256 gettimeofday (&t, NULL);
3257
3258 if (tv_sec)
3259 *tv_sec = t.tv_sec;
3260 if (tv_usec)
3261 *tv_usec = t.tv_usec;
3262#endif
3263}
3264
3272void
3274 long *tv_usec)
3275{
3276 struct timeval t;
3277
3278 gettimeofday (&t, NULL);
3279
3280 if (tv_sec)
3281 *tv_sec = t.tv_sec;
3282 if (tv_usec)
3283 *tv_usec = t.tv_usec;
3284}
3285
3296 DBusError *error)
3297{
3298 const char *filename_c;
3299
3300 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3301
3302 filename_c = _dbus_string_get_const_data (filename);
3303
3304 if (mkdir (filename_c, 0700) < 0)
3305 {
3306 if (errno == EEXIST)
3307 return TRUE;
3308
3310 "Failed to create directory %s: %s\n",
3311 filename_c, _dbus_strerror (errno));
3312 return FALSE;
3313 }
3314 else
3315 return TRUE;
3316}
3317
3328 DBusError *error)
3329{
3330 const char *filename_c;
3331
3332 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3333
3334 filename_c = _dbus_string_get_const_data (filename);
3335
3336 if (mkdir (filename_c, 0700) < 0)
3337 {
3339 "Failed to create directory %s: %s\n",
3340 filename_c, _dbus_strerror (errno));
3341 return FALSE;
3342 }
3343 else
3344 return TRUE;
3345}
3346
3359 const DBusString *next_component)
3360{
3361 dbus_bool_t dir_ends_in_slash;
3362 dbus_bool_t file_starts_with_slash;
3363
3364 if (_dbus_string_get_length (dir) == 0 ||
3365 _dbus_string_get_length (next_component) == 0)
3366 return TRUE;
3367
3368 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3369 _dbus_string_get_length (dir) - 1);
3370
3371 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3372
3373 if (dir_ends_in_slash && file_starts_with_slash)
3374 {
3375 _dbus_string_shorten (dir, 1);
3376 }
3377 else if (!(dir_ends_in_slash || file_starts_with_slash))
3378 {
3379 if (!_dbus_string_append_byte (dir, '/'))
3380 return FALSE;
3381 }
3382
3383 return _dbus_string_copy (next_component, 0, dir,
3385}
3386
3388#define NANOSECONDS_PER_SECOND 1000000000
3390#define MICROSECONDS_PER_SECOND 1000000
3392#define MILLISECONDS_PER_SECOND 1000
3394#define NANOSECONDS_PER_MILLISECOND 1000000
3396#define MICROSECONDS_PER_MILLISECOND 1000
3397
3402void
3404{
3405#ifdef HAVE_NANOSLEEP
3406 struct timespec req;
3407 struct timespec rem;
3408
3409 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3410 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3411 rem.tv_sec = 0;
3412 rem.tv_nsec = 0;
3413
3414 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3415 req = rem;
3416#elif defined (HAVE_USLEEP)
3417 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3418#else /* ! HAVE_USLEEP */
3419 sleep (MAX (milliseconds / 1000, 1));
3420#endif
3421}
3422
3434 int n_bytes,
3435 DBusError *error)
3436{
3437 int old_len = _dbus_string_get_length (str);
3438 int fd;
3439 int result;
3440#ifdef HAVE_GETRANDOM
3441 char *buffer;
3442
3443 if (!_dbus_string_lengthen (str, n_bytes))
3444 {
3445 _DBUS_SET_OOM (error);
3446 return FALSE;
3447 }
3448
3449 buffer = _dbus_string_get_data_len (str, old_len, n_bytes);
3450 result = getrandom (buffer, n_bytes, GRND_NONBLOCK);
3451
3452 if (result == n_bytes)
3453 return TRUE;
3454
3455 _dbus_string_set_length (str, old_len);
3456#endif
3457
3458 /* note, urandom on linux will fall back to pseudorandom */
3459 fd = open ("/dev/urandom", O_RDONLY);
3460
3461 if (fd < 0)
3462 {
3463 dbus_set_error (error, _dbus_error_from_errno (errno),
3464 "Could not open /dev/urandom: %s",
3465 _dbus_strerror (errno));
3466 return FALSE;
3467 }
3468
3469 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3470
3471 result = _dbus_read (fd, str, n_bytes);
3472
3473 if (result != n_bytes)
3474 {
3475 if (result < 0)
3476 dbus_set_error (error, _dbus_error_from_errno (errno),
3477 "Could not read /dev/urandom: %s",
3478 _dbus_strerror (errno));
3479 else
3481 "Short read from /dev/urandom");
3482
3483 _dbus_close (fd, NULL);
3484 _dbus_string_set_length (str, old_len);
3485 return FALSE;
3486 }
3487
3488 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3489 n_bytes);
3490
3491 _dbus_close (fd, NULL);
3492
3493 return TRUE;
3494}
3495
3501void
3502_dbus_exit (int code)
3503{
3504 _exit (code);
3505}
3506
3515const char*
3516_dbus_strerror (int error_number)
3517{
3518 const char *msg;
3519
3520 msg = strerror (error_number);
3521 if (msg == NULL)
3522 msg = "unknown";
3523
3524 return msg;
3525}
3526
3530void
3532{
3533 signal (SIGPIPE, SIG_IGN);
3534}
3535
3543void
3545{
3546 int val;
3547
3548 val = fcntl (fd, F_GETFD, 0);
3549
3550 if (val < 0)
3551 return;
3552
3553 val |= FD_CLOEXEC;
3554
3555 fcntl (fd, F_SETFD, val);
3556}
3557
3565void
3567{
3568 int val;
3569
3570 val = fcntl (fd, F_GETFD, 0);
3571
3572 if (val < 0)
3573 return;
3574
3575 val &= ~FD_CLOEXEC;
3576
3577 fcntl (fd, F_SETFD, val);
3578}
3579
3589 DBusError *error)
3590{
3591 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3592
3593 again:
3594 if (close (fd) < 0)
3595 {
3596 if (errno == EINTR)
3597 goto again;
3598
3599 dbus_set_error (error, _dbus_error_from_errno (errno),
3600 "Could not close fd %d", fd);
3601 return FALSE;
3602 }
3603
3604 return TRUE;
3605}
3606
3615int
3617 DBusError *error)
3618{
3619 int new_fd;
3620
3621#ifdef F_DUPFD_CLOEXEC
3622 dbus_bool_t cloexec_done;
3623
3624 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3625 cloexec_done = new_fd >= 0;
3626
3627 if (new_fd < 0 && errno == EINVAL)
3628#endif
3629 {
3630 new_fd = fcntl(fd, F_DUPFD, 3);
3631 }
3632
3633 if (new_fd < 0) {
3634
3635 dbus_set_error (error, _dbus_error_from_errno (errno),
3636 "Could not duplicate fd %d", fd);
3637 return -1;
3638 }
3639
3640#ifdef F_DUPFD_CLOEXEC
3641 if (!cloexec_done)
3642#endif
3643 {
3645 }
3646
3647 return new_fd;
3648}
3649
3659 DBusError *error)
3660{
3661 return _dbus_set_fd_nonblocking (fd.fd, error);
3662}
3663
3664static dbus_bool_t
3665_dbus_set_fd_nonblocking (int fd,
3666 DBusError *error)
3667{
3668 int val;
3669
3670 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3671
3672 val = fcntl (fd, F_GETFL, 0);
3673 if (val < 0)
3674 {
3675 dbus_set_error (error, _dbus_error_from_errno (errno),
3676 "Failed to get flags from file descriptor %d: %s",
3677 fd, _dbus_strerror (errno));
3678 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3679 _dbus_strerror (errno));
3680 return FALSE;
3681 }
3682
3683 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3684 {
3685 dbus_set_error (error, _dbus_error_from_errno (errno),
3686 "Failed to set nonblocking flag of file descriptor %d: %s",
3687 fd, _dbus_strerror (errno));
3688 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3689 fd, _dbus_strerror (errno));
3690
3691 return FALSE;
3692 }
3693
3694 return TRUE;
3695}
3696
3702void
3704{
3705#if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3706 void *bt[500];
3707 int bt_size;
3708 int i;
3709 char **syms;
3710
3711 bt_size = backtrace (bt, 500);
3712
3713 syms = backtrace_symbols (bt, bt_size);
3714
3715 i = 0;
3716 while (i < bt_size)
3717 {
3718 /* don't use dbus_warn since it can _dbus_abort() */
3719 fprintf (stderr, " %s\n", syms[i]);
3720 ++i;
3721 }
3722 fflush (stderr);
3723
3724 free (syms);
3725#elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3726 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3727#else
3728 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3729#endif
3730}
3731
3746 DBusSocket *fd2,
3747 dbus_bool_t blocking,
3748 DBusError *error)
3749{
3750#ifdef HAVE_SOCKETPAIR
3751 int fds[2];
3752 int retval;
3753
3754#ifdef SOCK_CLOEXEC
3755 dbus_bool_t cloexec_done;
3756
3757 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3758 cloexec_done = retval >= 0;
3759
3760 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3761#endif
3762 {
3763 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3764 }
3765
3766 if (retval < 0)
3767 {
3768 dbus_set_error (error, _dbus_error_from_errno (errno),
3769 "Could not create full-duplex pipe");
3770 return FALSE;
3771 }
3772
3773 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3774
3775#ifdef SOCK_CLOEXEC
3776 if (!cloexec_done)
3777#endif
3778 {
3781 }
3782
3783 if (!blocking &&
3784 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3785 !_dbus_set_fd_nonblocking (fds[1], NULL)))
3786 {
3787 dbus_set_error (error, _dbus_error_from_errno (errno),
3788 "Could not set full-duplex pipe nonblocking");
3789
3790 _dbus_close (fds[0], NULL);
3791 _dbus_close (fds[1], NULL);
3792
3793 return FALSE;
3794 }
3795
3796 fd1->fd = fds[0];
3797 fd2->fd = fds[1];
3798
3799 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3800 fd1->fd, fd2->fd);
3801
3802 return TRUE;
3803#else
3804 _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3806 "_dbus_socketpair() not implemented on this OS");
3807 return FALSE;
3808#endif
3809}
3810
3819int
3821 va_list args)
3822{
3823 char static_buf[1024];
3824 int bufsize = sizeof (static_buf);
3825 int len;
3826 va_list args_copy;
3827
3828 va_copy (args_copy, args);
3829 len = vsnprintf (static_buf, bufsize, format, args_copy);
3830 va_end (args_copy);
3831
3832 /* If vsnprintf() returned non-negative, then either the string fits in
3833 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3834 * returns the number of characters that were needed, or this OS returns the
3835 * truncated length.
3836 *
3837 * We ignore the possibility that snprintf might just ignore the length and
3838 * overrun the buffer (64-bit Solaris 7), because that's pathological.
3839 * If your libc is really that bad, come back when you have a better one. */
3840 if (len == bufsize)
3841 {
3842 /* This could be the truncated length (Tru64 and IRIX have this bug),
3843 * or the real length could be coincidentally the same. Which is it?
3844 * If vsnprintf returns the truncated length, we'll go to the slow
3845 * path. */
3846 va_copy (args_copy, args);
3847
3848 if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3849 len = -1;
3850
3851 va_end (args_copy);
3852 }
3853
3854 /* If vsnprintf() returned negative, we have to do more work.
3855 * HP-UX returns negative. */
3856 while (len < 0)
3857 {
3858 char *buf;
3859
3860 bufsize *= 2;
3861
3862 buf = dbus_malloc (bufsize);
3863
3864 if (buf == NULL)
3865 return -1;
3866
3867 va_copy (args_copy, args);
3868 len = vsnprintf (buf, bufsize, format, args_copy);
3869 va_end (args_copy);
3870
3871 dbus_free (buf);
3872
3873 /* If the reported length is exactly the buffer size, round up to the
3874 * next size, in case vsnprintf has been returning the truncated
3875 * length */
3876 if (len == bufsize)
3877 len = -1;
3878 }
3879
3880 return len;
3881}
3882
3889const char*
3891{
3892 /* Protected by _DBUS_LOCK_sysdeps */
3893 static const char* tmpdir = NULL;
3894
3895 if (!_DBUS_LOCK (sysdeps))
3896 return NULL;
3897
3898 if (tmpdir == NULL)
3899 {
3900 /* TMPDIR is what glibc uses, then
3901 * glibc falls back to the P_tmpdir macro which
3902 * just expands to "/tmp"
3903 */
3904 if (tmpdir == NULL)
3905 tmpdir = getenv("TMPDIR");
3906
3907 /* These two env variables are probably
3908 * broken, but maybe some OS uses them?
3909 */
3910 if (tmpdir == NULL)
3911 tmpdir = getenv("TMP");
3912 if (tmpdir == NULL)
3913 tmpdir = getenv("TEMP");
3914
3915 /* And this is the sane fallback. */
3916 if (tmpdir == NULL)
3917 tmpdir = "/tmp";
3918 }
3919
3920 _DBUS_UNLOCK (sysdeps);
3921
3922 _dbus_assert(tmpdir != NULL);
3923
3924 return tmpdir;
3925}
3926
3927#if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3947static dbus_bool_t
3948_read_subprocess_line_argv (const char *progpath,
3949 dbus_bool_t path_fallback,
3950 const char * const *argv,
3951 DBusString *result,
3952 DBusError *error)
3953{
3954 int result_pipe[2] = { -1, -1 };
3955 int errors_pipe[2] = { -1, -1 };
3956 pid_t pid;
3957 int ret;
3958 int status;
3959 int orig_len;
3960
3961 dbus_bool_t retval;
3962 sigset_t new_set, old_set;
3963
3964 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3965 retval = FALSE;
3966
3967 /* We need to block any existing handlers for SIGCHLD temporarily; they
3968 * will cause waitpid() below to fail.
3969 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3970 */
3971 sigemptyset (&new_set);
3972 sigaddset (&new_set, SIGCHLD);
3973 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3974
3975 orig_len = _dbus_string_get_length (result);
3976
3977#define READ_END 0
3978#define WRITE_END 1
3979 if (pipe (result_pipe) < 0)
3980 {
3981 dbus_set_error (error, _dbus_error_from_errno (errno),
3982 "Failed to create a pipe to call %s: %s",
3983 progpath, _dbus_strerror (errno));
3984 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3985 progpath, _dbus_strerror (errno));
3986 goto out;
3987 }
3988 if (pipe (errors_pipe) < 0)
3989 {
3990 dbus_set_error (error, _dbus_error_from_errno (errno),
3991 "Failed to create a pipe to call %s: %s",
3992 progpath, _dbus_strerror (errno));
3993 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3994 progpath, _dbus_strerror (errno));
3995 goto out;
3996 }
3997
3998 /* Make sure our output buffers aren't redundantly printed by both the
3999 * parent and the child */
4000 fflush (stdout);
4001 fflush (stderr);
4002
4003 pid = fork ();
4004 if (pid < 0)
4005 {
4006 dbus_set_error (error, _dbus_error_from_errno (errno),
4007 "Failed to fork() to call %s: %s",
4008 progpath, _dbus_strerror (errno));
4009 _dbus_verbose ("Failed to fork() to call %s: %s\n",
4010 progpath, _dbus_strerror (errno));
4011 goto out;
4012 }
4013
4014 if (pid == 0)
4015 {
4016 /* child process */
4017 const char *error_str;
4018
4019 if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
4020 {
4021 int saved_errno = errno;
4022
4023 /* Try to write details into the pipe, but don't bother
4024 * trying too hard (no retry loop). */
4025
4026 if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
4027 write (errors_pipe[WRITE_END], ": ", 2) < 0)
4028 {
4029 /* ignore, not much we can do */
4030 }
4031
4032 error_str = _dbus_strerror (saved_errno);
4033
4034 if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
4035 {
4036 /* ignore, not much we can do */
4037 }
4038
4039 _exit (1);
4040 }
4041
4042 /* set-up stdXXX */
4043 close (result_pipe[READ_END]);
4044 close (errors_pipe[READ_END]);
4045
4046 if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
4047 _exit (1);
4048 if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
4049 _exit (1);
4050
4051 _dbus_close_all ();
4052
4053 sigprocmask (SIG_SETMASK, &old_set, NULL);
4054
4055 /* If it looks fully-qualified, try execv first */
4056 if (progpath[0] == '/')
4057 {
4058 execv (progpath, (char * const *) argv);
4059 /* Ok, that failed. Now if path_fallback is given, let's
4060 * try unqualified. This is mostly a hack to work
4061 * around systems which ship dbus-launch in /usr/bin
4062 * but everything else in /bin (because dbus-launch
4063 * depends on X11).
4064 */
4065 if (path_fallback)
4066 /* We must have a slash, because we checked above */
4067 execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4068 }
4069 else
4070 execvp (progpath, (char * const *) argv);
4071
4072 /* still nothing, we failed */
4073 _exit (1);
4074 }
4075
4076 /* parent process */
4077 close (result_pipe[WRITE_END]);
4078 close (errors_pipe[WRITE_END]);
4079 result_pipe[WRITE_END] = -1;
4080 errors_pipe[WRITE_END] = -1;
4081
4082 ret = 0;
4083 do
4084 {
4085 ret = _dbus_read (result_pipe[READ_END], result, 1024);
4086 }
4087 while (ret > 0);
4088
4089 /* reap the child process to avoid it lingering as zombie */
4090 do
4091 {
4092 ret = waitpid (pid, &status, 0);
4093 }
4094 while (ret == -1 && errno == EINTR);
4095
4096 /* We succeeded if the process exited with status 0 and
4097 anything was read */
4098 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4099 {
4100 /* The process ended with error */
4101 DBusString error_message;
4102 if (!_dbus_string_init (&error_message))
4103 {
4104 _DBUS_SET_OOM (error);
4105 goto out;
4106 }
4107
4108 ret = 0;
4109 do
4110 {
4111 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4112 }
4113 while (ret > 0);
4114
4115 _dbus_string_set_length (result, orig_len);
4116 if (_dbus_string_get_length (&error_message) > 0)
4118 "%s terminated abnormally with the following error: %s",
4119 progpath, _dbus_string_get_data (&error_message));
4120 else
4122 "%s terminated abnormally without any error message",
4123 progpath);
4124 goto out;
4125 }
4126
4127 retval = TRUE;
4128
4129 out:
4130 sigprocmask (SIG_SETMASK, &old_set, NULL);
4131
4132 _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4133
4134 if (result_pipe[0] != -1)
4135 close (result_pipe[0]);
4136 if (result_pipe[1] != -1)
4137 close (result_pipe[1]);
4138 if (errors_pipe[0] != -1)
4139 close (errors_pipe[0]);
4140 if (errors_pipe[1] != -1)
4141 close (errors_pipe[1]);
4142
4143 return retval;
4144}
4145#endif
4146
4161 DBusString *address,
4162 DBusError *error)
4163{
4164#ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4165 static const char arg_dbus_launch[] = "dbus-launch";
4166 static const char arg_autolaunch[] = "--autolaunch";
4167 static const char arg_binary_syntax[] = "--binary-syntax";
4168 static const char arg_close_stderr[] = "--close-stderr";
4169
4170 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4171 * but that's done elsewhere, and if it worked, this function wouldn't
4172 * be called.) */
4173 const char *display;
4174 const char *progpath;
4175 const char *argv[6];
4176 int i;
4177 DBusString uuid;
4178 dbus_bool_t retval;
4179
4180 if (_dbus_check_setuid ())
4181 {
4183 "Unable to autolaunch when setuid");
4184 return FALSE;
4185 }
4186
4187 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4188 retval = FALSE;
4189
4190 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4191 * dbus-launch-x11 is just going to fail. Rather than trying to
4192 * run it, we might as well bail out early with a nice error.
4193 *
4194 * This is not strictly true in a world where the user bus exists,
4195 * because dbus-launch --autolaunch knows how to connect to that -
4196 * but if we were going to connect to the user bus, we'd have done
4197 * so before trying autolaunch: in any case. */
4198 display = _dbus_getenv ("DISPLAY");
4199
4200 if (display == NULL || display[0] == '\0')
4201 {
4203 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4204 return FALSE;
4205 }
4206
4207 if (!_dbus_string_init (&uuid))
4208 {
4209 _DBUS_SET_OOM (error);
4210 return FALSE;
4211 }
4212
4213 if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4214 {
4215 goto out;
4216 }
4217
4218#ifdef DBUS_ENABLE_EMBEDDED_TESTS
4219 progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4220
4221 if (progpath == NULL)
4222#endif
4223 progpath = DBUS_BINDIR "/dbus-launch";
4224 /*
4225 * argv[0] is always dbus-launch, that's the name what we'll
4226 * get from /proc, or ps(1), regardless what the progpath is,
4227 * see fd.o#69716
4228 */
4229 i = 0;
4230 argv[i] = arg_dbus_launch;
4231 ++i;
4232 argv[i] = arg_autolaunch;
4233 ++i;
4234 argv[i] = _dbus_string_get_data (&uuid);
4235 ++i;
4236 argv[i] = arg_binary_syntax;
4237 ++i;
4238 argv[i] = arg_close_stderr;
4239 ++i;
4240 argv[i] = NULL;
4241 ++i;
4242
4243 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4244
4245 retval = _read_subprocess_line_argv (progpath,
4246 TRUE,
4247 argv, address, error);
4248
4249 out:
4250 _dbus_string_free (&uuid);
4251 return retval;
4252#else
4254 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4255 "set your DBUS_SESSION_BUS_ADDRESS instead");
4256 return FALSE;
4257#endif
4258}
4259
4280 dbus_bool_t create_if_not_found,
4281 DBusError *error)
4282{
4283 DBusError our_error = DBUS_ERROR_INIT;
4284 DBusError etc_error = DBUS_ERROR_INIT;
4285 DBusString filename;
4286 dbus_bool_t b;
4287
4288 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4289
4290 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4291 if (b)
4292 return TRUE;
4293
4294 /* Fallback to the system machine ID */
4295 _dbus_string_init_const (&filename, "/etc/machine-id");
4296 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4297
4298 if (b)
4299 {
4300 if (create_if_not_found)
4301 {
4302 /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4303 * complain if that isn't possible for whatever reason */
4304 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4305 _dbus_write_uuid_file (&filename, machine_id, NULL);
4306 }
4307
4308 dbus_error_free (&our_error);
4309 return TRUE;
4310 }
4311
4312 if (!create_if_not_found)
4313 {
4314 dbus_set_error (error, etc_error.name,
4315 "D-Bus library appears to be incorrectly set up: "
4316 "see the manual page for dbus-uuidgen to correct "
4317 "this issue. (%s; %s)",
4318 our_error.message, etc_error.message);
4319 dbus_error_free (&our_error);
4320 dbus_error_free (&etc_error);
4321 return FALSE;
4322 }
4323
4324 dbus_error_free (&our_error);
4325 dbus_error_free (&etc_error);
4326
4327 /* if none found, try to make a new one */
4328 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4329
4330 if (!_dbus_generate_uuid (machine_id, error))
4331 return FALSE;
4332
4333 return _dbus_write_uuid_file (&filename, machine_id, error);
4334}
4335
4345 const char *launchd_env_var,
4346 DBusError *error)
4347{
4348#ifdef DBUS_ENABLE_LAUNCHD
4349 char *argv[4];
4350 int i;
4351
4352 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4353
4354 if (_dbus_check_setuid ())
4355 {
4357 "Unable to find launchd socket when setuid");
4358 return FALSE;
4359 }
4360
4361 i = 0;
4362 argv[i] = "launchctl";
4363 ++i;
4364 argv[i] = "getenv";
4365 ++i;
4366 argv[i] = (char*)launchd_env_var;
4367 ++i;
4368 argv[i] = NULL;
4369 ++i;
4370
4371 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4372
4373 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4374 {
4375 return FALSE;
4376 }
4377
4378 /* no error, but no result either */
4379 if (_dbus_string_get_length(socket_path) == 0)
4380 {
4381 return FALSE;
4382 }
4383
4384 /* strip the carriage-return */
4385 _dbus_string_shorten(socket_path, 1);
4386 return TRUE;
4387#else /* DBUS_ENABLE_LAUNCHD */
4389 "can't lookup socket from launchd; launchd support not compiled in");
4390 return FALSE;
4391#endif
4392}
4393
4394#ifdef DBUS_ENABLE_LAUNCHD
4395static dbus_bool_t
4396_dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4397{
4398 dbus_bool_t valid_socket;
4399 DBusString socket_path;
4400
4401 if (_dbus_check_setuid ())
4402 {
4404 "Unable to find launchd socket when setuid");
4405 return FALSE;
4406 }
4407
4408 if (!_dbus_string_init (&socket_path))
4409 {
4410 _DBUS_SET_OOM (error);
4411 return FALSE;
4412 }
4413
4414 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4415
4416 if (dbus_error_is_set(error))
4417 {
4418 _dbus_string_free(&socket_path);
4419 return FALSE;
4420 }
4421
4422 if (!valid_socket)
4423 {
4424 dbus_set_error(error, "no socket path",
4425 "launchd did not provide a socket path, "
4426 "verify that org.freedesktop.dbus-session.plist is loaded!");
4427 _dbus_string_free(&socket_path);
4428 return FALSE;
4429 }
4430 if (!_dbus_string_append (address, "unix:path="))
4431 {
4432 _DBUS_SET_OOM (error);
4433 _dbus_string_free(&socket_path);
4434 return FALSE;
4435 }
4436 if (!_dbus_string_copy (&socket_path, 0, address,
4437 _dbus_string_get_length (address)))
4438 {
4439 _DBUS_SET_OOM (error);
4440 _dbus_string_free(&socket_path);
4441 return FALSE;
4442 }
4443
4444 _dbus_string_free(&socket_path);
4445 return TRUE;
4446}
4447#endif
4448
4449static dbus_bool_t
4450_dbus_lookup_user_bus (dbus_bool_t *supported,
4451 DBusString *address,
4452 DBusError *error)
4453{
4454 const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4455 dbus_bool_t ret = FALSE;
4456 struct stat stbuf;
4457 DBusString user_bus_path;
4458
4459 if (runtime_dir == NULL)
4460 {
4461 _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4462 *supported = FALSE;
4463 return TRUE; /* Cannot use it, but not an error */
4464 }
4465
4466 if (!_dbus_string_init (&user_bus_path))
4467 {
4468 _DBUS_SET_OOM (error);
4469 return FALSE;
4470 }
4471
4472 if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4473 {
4474 _DBUS_SET_OOM (error);
4475 goto out;
4476 }
4477
4478 if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4479 {
4480 _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4481 _dbus_strerror (errno));
4482 *supported = FALSE;
4483 ret = TRUE; /* Cannot use it, but not an error */
4484 goto out;
4485 }
4486
4487 if (stbuf.st_uid != getuid ())
4488 {
4489 _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4490 (long) stbuf.st_uid, (long) getuid ());
4491 *supported = FALSE;
4492 ret = TRUE; /* Cannot use it, but not an error */
4493 goto out;
4494 }
4495
4496 if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4497 {
4498 _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4499 (long) stbuf.st_mode);
4500 *supported = FALSE;
4501 ret = TRUE; /* Cannot use it, but not an error */
4502 goto out;
4503 }
4504
4505 if (!_dbus_string_append (address, "unix:path=") ||
4506 !_dbus_address_append_escaped (address, &user_bus_path))
4507 {
4508 _DBUS_SET_OOM (error);
4509 goto out;
4510 }
4511
4512 *supported = TRUE;
4513 ret = TRUE;
4514
4515out:
4516 _dbus_string_free (&user_bus_path);
4517 return ret;
4518}
4519
4541 DBusString *address,
4542 DBusError *error)
4543{
4544#ifdef DBUS_ENABLE_LAUNCHD
4545 *supported = TRUE;
4546 return _dbus_lookup_session_address_launchd (address, error);
4547#else
4548 *supported = FALSE;
4549
4550 if (!_dbus_lookup_user_bus (supported, address, error))
4551 return FALSE;
4552 else if (*supported)
4553 return TRUE;
4554
4555 /* On non-Mac Unix platforms, if the session address isn't already
4556 * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4557 * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4558 * autolaunch: global default; see init_session_address in
4559 * dbus/dbus-bus.c. */
4560 return TRUE;
4561#endif
4562}
4563
4571void
4573{
4575}
4576
4592 DBusCredentials *credentials)
4593{
4594 DBusString homedir;
4595 DBusString dotdir;
4596 dbus_uid_t uid;
4597
4598 _dbus_assert (credentials != NULL);
4600
4601 if (!_dbus_string_init (&homedir))
4602 return FALSE;
4603
4604 uid = _dbus_credentials_get_unix_uid (credentials);
4606
4607 if (!_dbus_homedir_from_uid (uid, &homedir))
4608 goto failed;
4609
4610#ifdef DBUS_ENABLE_EMBEDDED_TESTS
4611 {
4612 const char *override;
4613
4614 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4615 if (override != NULL && *override != '\0')
4616 {
4617 _dbus_string_set_length (&homedir, 0);
4618 if (!_dbus_string_append (&homedir, override))
4619 goto failed;
4620
4621 _dbus_verbose ("Using fake homedir for testing: %s\n",
4622 _dbus_string_get_const_data (&homedir));
4623 }
4624 else
4625 {
4626 /* Not strictly thread-safe, but if we fail at thread-safety here,
4627 * the worst that will happen is some extra warnings. */
4628 static dbus_bool_t already_warned = FALSE;
4629 if (!already_warned)
4630 {
4631 _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4632 _dbus_string_get_const_data (&homedir));
4633 already_warned = TRUE;
4634 }
4635 }
4636 }
4637#endif
4638
4639 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4640 if (!_dbus_concat_dir_and_file (&homedir,
4641 &dotdir))
4642 goto failed;
4643
4644 if (!_dbus_string_copy (&homedir, 0,
4645 directory, _dbus_string_get_length (directory))) {
4646 goto failed;
4647 }
4648
4649 _dbus_string_free (&homedir);
4650 return TRUE;
4651
4652 failed:
4653 _dbus_string_free (&homedir);
4654 return FALSE;
4655}
4656
4657/* Documented in dbus-sysdeps-win.c, does nothing on Unix */
4659_dbus_daemon_unpublish_session_bus_address (void)
4660{
4661 return TRUE;
4662}
4663
4672{
4673 /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4674 * EWOULDBLOCK are numerically equal, which is permitted as described by
4675 * errno(3).
4676 */
4677#if EAGAIN == EWOULDBLOCK
4678 return e == EAGAIN;
4679#else
4680 return e == EAGAIN || e == EWOULDBLOCK;
4681#endif
4682}
4683
4693 DBusError *error)
4694{
4695 const char *filename_c;
4696
4697 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4698
4699 filename_c = _dbus_string_get_const_data (filename);
4700
4701 if (rmdir (filename_c) != 0)
4702 {
4704 "Failed to remove directory %s: %s\n",
4705 filename_c, _dbus_strerror (errno));
4706 return FALSE;
4707 }
4708
4709 return TRUE;
4710}
4711
4721{
4722#ifdef SCM_RIGHTS
4723 union {
4724 struct sockaddr sa;
4725 struct sockaddr_storage storage;
4726 struct sockaddr_un un;
4727 } sa_buf;
4728
4729 socklen_t sa_len = sizeof(sa_buf);
4730
4731 _DBUS_ZERO(sa_buf);
4732
4733 if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4734 return FALSE;
4735
4736 return sa_buf.sa.sa_family == AF_UNIX;
4737
4738#else
4739 return FALSE;
4740
4741#endif
4742}
4743
4744/*
4745 * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4746 * and may call func for integers that are not actually valid fds.
4747 */
4748static void
4749act_on_fds_3_and_up (void (*func) (int fd))
4750{
4751 int maxfds, i;
4752
4753#if defined(__linux__) && defined(__GLIBC__)
4754 DIR *d;
4755
4756 /* On Linux we can optimize this a bit if /proc is available. If it
4757 isn't available, fall back to the brute force way. */
4758
4759 d = opendir ("/proc/self/fd");
4760 if (d)
4761 {
4762 for (;;)
4763 {
4764 struct dirent *de;
4765 int fd;
4766 long l;
4767 char *e = NULL;
4768
4769 de = readdir (d);
4770 if (!de)
4771 break;
4772
4773 if (de->d_name[0] == '.')
4774 continue;
4775
4776 errno = 0;
4777 l = strtol (de->d_name, &e, 10);
4778 if (errno != 0 || e == NULL || *e != '\0')
4779 continue;
4780
4781 fd = (int) l;
4782 if (fd < 3)
4783 continue;
4784
4785 if (fd == dirfd (d))
4786 continue;
4787
4788 func (fd);
4789 }
4790
4791 closedir (d);
4792 return;
4793 }
4794#endif
4795
4796 maxfds = sysconf (_SC_OPEN_MAX);
4797
4798 /* Pick something reasonable if for some reason sysconf says
4799 * unlimited.
4800 */
4801 if (maxfds < 0)
4802 maxfds = 1024;
4803
4804 /* close all inherited fds */
4805 for (i = 3; i < maxfds; i++)
4806 func (i);
4807}
4808
4809/* Some library implementations of closefrom() are not async-signal-safe,
4810 * and we call _dbus_close_all() after forking, so we only do this on
4811 * operating systems where we know that closefrom() is a system call */
4812#if defined(HAVE_CLOSEFROM) && ( \
4813 defined(__FreeBSD__) || \
4814 defined(__NetBSD__) || \
4815 defined(__OpenBSD__) || \
4816 defined(__sun__) && defined(F_CLOSEFROM) \
4817)
4818#define CLOSEFROM_SIGNAL_SAFE 1
4819#else
4820#define CLOSEFROM_SIGNAL_SAFE 0
4821static void
4822close_ignore_error (int fd)
4823{
4824 close (fd);
4825}
4826#endif
4827
4832void
4834{
4835#ifdef HAVE_CLOSE_RANGE
4836 if (close_range (3, INT_MAX, 0) == 0)
4837 return;
4838#endif
4839
4840#if CLOSEFROM_SIGNAL_SAFE
4841 closefrom (3);
4842#else
4843 act_on_fds_3_and_up (close_ignore_error);
4844#endif
4845}
4846
4851void
4853{
4854#if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC)
4855 if (close_range (3, INT_MAX, CLOSE_RANGE_CLOEXEC) == 0)
4856 return;
4857#endif
4858
4859 act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4860}
4861
4873{
4874 /* TODO: get __libc_enable_secure exported from glibc.
4875 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4876 */
4877#if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4878 {
4879 /* See glibc/include/unistd.h */
4880 extern int __libc_enable_secure;
4881 return __libc_enable_secure;
4882 }
4883#elif defined(HAVE_ISSETUGID)
4884 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4885 return issetugid ();
4886#else
4887 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4888 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4889
4890 /* We call into this function from _dbus_threads_init_platform_specific()
4891 * to make sure these are initialized before we start threading. */
4892 static dbus_bool_t check_setuid_initialised;
4893 static dbus_bool_t is_setuid;
4894
4895 if (_DBUS_UNLIKELY (!check_setuid_initialised))
4896 {
4897#ifdef HAVE_GETRESUID
4898 if (getresuid (&ruid, &euid, &suid) != 0 ||
4899 getresgid (&rgid, &egid, &sgid) != 0)
4900#endif /* HAVE_GETRESUID */
4901 {
4902 suid = ruid = getuid ();
4903 sgid = rgid = getgid ();
4904 euid = geteuid ();
4905 egid = getegid ();
4906 }
4907
4908 check_setuid_initialised = TRUE;
4909 is_setuid = (ruid != euid || ruid != suid ||
4910 rgid != egid || rgid != sgid);
4911
4912 }
4913 return is_setuid;
4914#endif
4915}
4916
4926 DBusString *address,
4927 DBusError *error)
4928{
4929 union {
4930 struct sockaddr sa;
4931 struct sockaddr_storage storage;
4932 struct sockaddr_un un;
4933 struct sockaddr_in ipv4;
4934 struct sockaddr_in6 ipv6;
4935 } socket;
4936 char hostip[INET6_ADDRSTRLEN];
4937 socklen_t size = sizeof (socket);
4938 DBusString path_str;
4939 const char *family_name = NULL;
4940 dbus_uint16_t port;
4941
4942 if (getsockname (fd.fd, &socket.sa, &size))
4943 goto err;
4944
4945 switch (socket.sa.sa_family)
4946 {
4947 case AF_UNIX:
4948 if (socket.un.sun_path[0]=='\0')
4949 {
4950 _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
4951 if (_dbus_string_append (address, "unix:abstract=") &&
4952 _dbus_address_append_escaped (address, &path_str))
4953 {
4954 return TRUE;
4955 }
4956 else
4957 {
4958 _DBUS_SET_OOM (error);
4959 return FALSE;
4960 }
4961 }
4962 else
4963 {
4964 _dbus_string_init_const (&path_str, socket.un.sun_path);
4965 if (_dbus_string_append (address, "unix:path=") &&
4966 _dbus_address_append_escaped (address, &path_str))
4967 {
4968 return TRUE;
4969 }
4970 else
4971 {
4972 _DBUS_SET_OOM (error);
4973 return FALSE;
4974 }
4975 }
4976 /* not reached */
4977 break;
4978
4979 case AF_INET:
4980#ifdef AF_INET6
4981 case AF_INET6:
4982#endif
4983 _dbus_string_init_const (&path_str, hostip);
4984
4985 if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
4986 &family_name, &port, error))
4987 {
4988 if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
4989 family_name, port) &&
4990 _dbus_address_append_escaped (address, &path_str))
4991 {
4992 return TRUE;
4993 }
4994 else
4995 {
4996 _DBUS_SET_OOM (error);
4997 return FALSE;
4998 }
4999 }
5000 else
5001 {
5002 return FALSE;
5003 }
5004 /* not reached */
5005 break;
5006
5007 default:
5008 dbus_set_error (error,
5009 _dbus_error_from_errno (EINVAL),
5010 "Failed to read address from socket: Unknown socket type.");
5011 return FALSE;
5012 }
5013 err:
5014 dbus_set_error (error,
5015 _dbus_error_from_errno (errno),
5016 "Failed to read address from socket: %s",
5017 _dbus_strerror (errno));
5018 return FALSE;
5019}
5020
5021int
5022_dbus_save_socket_errno (void)
5023{
5024 return errno;
5025}
5026
5027void
5028_dbus_restore_socket_errno (int saved_errno)
5029{
5030 errno = saved_errno;
5031}
5032
5033static const char *syslog_tag = "dbus";
5034#ifdef HAVE_SYSLOG_H
5035static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
5036#endif
5037
5052void
5053_dbus_init_system_log (const char *tag,
5054 DBusLogFlags flags)
5055{
5056 /* We never want to turn off logging completely */
5057 _dbus_assert (
5058 (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
5059
5060 syslog_tag = tag;
5061
5062#ifdef HAVE_SYSLOG_H
5063 log_flags = flags;
5064
5065 if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5066 openlog (tag, LOG_PID, LOG_DAEMON);
5067#endif
5068}
5069
5077void
5078_dbus_logv (DBusSystemLogSeverity severity,
5079 const char *msg,
5080 va_list args)
5081{
5082 va_list tmp;
5083#ifdef HAVE_SYSLOG_H
5084 if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5085 {
5086 int flags;
5087 switch (severity)
5088 {
5089 case DBUS_SYSTEM_LOG_INFO:
5090 flags = LOG_DAEMON | LOG_INFO;
5091 break;
5092 case DBUS_SYSTEM_LOG_WARNING:
5093 flags = LOG_DAEMON | LOG_WARNING;
5094 break;
5095 case DBUS_SYSTEM_LOG_SECURITY:
5096 flags = LOG_AUTH | LOG_NOTICE;
5097 break;
5098 case DBUS_SYSTEM_LOG_ERROR:
5099 flags = LOG_DAEMON|LOG_CRIT;
5100 break;
5101 default:
5102 _dbus_assert_not_reached ("invalid log severity");
5103 }
5104
5105 va_copy (tmp, args);
5106 vsyslog (flags, msg, tmp);
5107 va_end (tmp);
5108 }
5109
5110 /* If we don't have syslog.h, we always behave as though stderr was in
5111 * the flags */
5112 if (log_flags & DBUS_LOG_FLAGS_STDERR)
5113#endif
5114 {
5115 va_copy (tmp, args);
5116 fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5117 vfprintf (stderr, msg, tmp);
5118 fputc ('\n', stderr);
5119 va_end (tmp);
5120 }
5121}
5122
5123/*
5124 * Return the low-level representation of a socket error, as used by
5125 * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5126 * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5127 *
5128 * Some libdbus internal functions copy this into errno, but with
5129 * hindsight that was probably a design flaw.
5130 */
5131int
5132_dbus_get_low_level_socket_errno (void)
5133{
5134 return errno;
5135}
5136
5137/* tests in dbus-sysdeps-util.c */
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:107
void _dbus_credentials_clear(DBusCredentials *credentials)
Clear all credentials in the object.
dbus_uid_t _dbus_credentials_get_unix_uid(DBusCredentials *credentials)
Gets the UNIX user ID in the credentials, or DBUS_UID_UNSET if the credentials object doesn't contain...
dbus_bool_t _dbus_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.
void _dbus_credentials_take_unix_gids(DBusCredentials *credentials, dbus_gid_t *gids, size_t n_gids)
Add UNIX group IDs to the credentials, replacing any group IDs that might already have been present.
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_credentials_add_pid(DBusCredentials *credentials, dbus_pid_t pid)
Add a UNIX process ID to the credentials.
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_bool_t _dbus_credentials_are_anonymous(DBusCredentials *credentials)
Checks whether a credentials object contains a user identity.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
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
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:188
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
void dbus_error_free(DBusError *error)
Frees an error that's been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
#define READ_END
Helps remember which end of the pipe is which.
#define WRITE_END
Helps remember which end of the pipe is which.
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
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:599
dbus_bool_t _dbus_generate_uuid(DBusGUID *uuid, DBusError *error)
Generates a new UUID.
char * _dbus_strdup(const char *str)
Duplicates a string.
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.
void _dbus_user_database_flush_system(void)
Flushes the system global user database;.
Definition: dbus-userdb.c:394
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.
dbus_bool_t _dbus_write_uuid_file(const DBusString *filename, const DBusGUID *uuid, DBusError *error)
Write the give UUID to a file.
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:464
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define _DBUS_ZERO(object)
Sets all bits in an object to zero.
#define _DBUS_INT32_MAX
Maximum value of type "int32".
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
#define NULL
A null pointer, defined appropriately for C or C++.
#define TRUE
Expands to "1".
#define FALSE
Expands to "0".
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.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:692
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:592
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:452
#define DBUS_MAXIMUM_MESSAGE_UNIX_FDS
The maximum total number of unix fds in a message.
#define DBUS_ERROR_NOT_SUPPORTED
Requested operation isn't supported (like ENOSYS on UNIX).
#define DBUS_ERROR_BAD_ADDRESS
A D-Bus bus address was malformed.
#define DBUS_ERROR_IO_ERROR
Something went wrong reading or writing to a socket, for example.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
#define DBUS_ERROR_SPAWN_EXEC_FAILED
While starting a new process, the exec() call failed.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:845
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:978
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:180
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:195
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that's copied to the d...
Definition: dbus-string.c:1343
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:137
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:533
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:494
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:276
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:823
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:803
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:782
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:401
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:1188
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:1145
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:557
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:511
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:605
void _dbus_fd_clear_close_on_exec(int fd)
Sets the file descriptor to not be close-on-exec.
void _dbus_fd_set_all_close_on_exec(void)
Sets all file descriptors except the first three (i.e.
dbus_bool_t _dbus_close(int fd, DBusError *error)
Closes a file descriptor.
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 ...
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.
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.
int _dbus_listen_systemd_sockets(DBusSocket **fds, DBusError *error)
Acquires one or more sockets passed in from systemd.
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_user_info_fill(DBusUserInfo *info, const DBusString *username, DBusError *error)
Gets user info for the given username.
void _dbus_close_all(void)
Closes all file descriptors except the first three (i.e.
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
void _dbus_fd_set_close_on_exec(int fd)
Sets the file descriptor to be close on exec.
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_ensure_standard_fds(DBusEnsureStandardFdsFlags flags, const char **error_str_p)
Ensure that the standard file descriptors stdin, stdout and stderr are open, by opening /dev/null if ...
dbus_uid_t _dbus_geteuid(void)
Gets our effective UID.
dbus_bool_t _dbus_user_info_fill_uid(DBusUserInfo *info, dbus_uid_t uid, DBusError *error)
Gets user info for the given user ID.
void _dbus_logv(DBusSystemLogSeverity severity, const char *msg, va_list args)
Log a message to the system log file (e.g.
dbus_bool_t _dbus_read_local_machine_uuid(DBusGUID *machine_id, dbus_bool_t create_if_not_found, DBusError *error)
Reads the uuid of the machine we're running on from the dbus configuration.
#define _DBUS_POLLOUT
Writing now will not block.
Definition: dbus-sysdeps.h:427
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:135
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)
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...
unsigned long dbus_pid_t
A process ID.
Definition: dbus-sysdeps.h:133
int _dbus_read_socket(DBusSocket fd, DBusString *buffer, int count)
Like _dbus_read(), but only works on sockets so is available on Windows.
void _dbus_exit(int code)
Exit the process, returning the given value.
#define _DBUS_POLLERR
Error condition.
Definition: dbus-sysdeps.h:429
dbus_bool_t _dbus_socket_can_pass_unix_fd(DBusSocket fd)
Checks whether file descriptors may be passed via the socket.
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.
void _dbus_atomic_set_nonzero(DBusAtomic *atomic)
Atomically set the value of an integer to something nonzero.
dbus_bool_t _dbus_socketpair(DBusSocket *fd1, DBusSocket *fd2, dbus_bool_t blocking, DBusError *error)
Creates pair of connect sockets (as in socketpair()).
unsigned long dbus_gid_t
A group ID.
Definition: dbus-sysdeps.h:137
int _dbus_read_socket_with_unix_fds(DBusSocket fd, DBusString *buffer, int count, int *fds, unsigned int *n_fds)
Like _dbus_read_socket() but also tries to read unix fds from the socket.
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.
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition: dbus-sysdeps.h:142
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
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...
#define DBUS_PID_UNSET
an invalid PID used to represent an uninitialized dbus_pid_t field
Definition: dbus-sysdeps.h:140
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:195
DBusSocket _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.
dbus_pid_t _dbus_getpid(void)
Gets our process ID.
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
dbus_bool_t _dbus_set_socket_nonblocking(DBusSocket fd, DBusError *error)
Sets a file descriptor to be nonblocking.
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.
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.
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_check_setuid(void)
NOTE: If you modify this function, please also consider making the corresponding change in GLib.
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
#define DBUS_GID_UNSET
an invalid GID used to represent an uninitialized dbus_gid_t field
Definition: dbus-sysdeps.h:144
dbus_bool_t _dbus_check_dir_is_private_to_user(DBusString *dir, DBusError *error)
Checks to make sure the given directory is private to the user.
#define _DBUS_POLLIN
There is data to read.
Definition: dbus-sysdeps.h:423
int _dbus_listen_tcp_socket(const char *host, const char *port, const char *family, DBusString *retport, const char **retfamily, DBusSocket **fds_p, DBusError *error)
Creates a socket and binds it to the given path, then listens on the socket.
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_uid_t _dbus_getuid(void)
Gets our UID.
dbus_bool_t _dbus_credentials_add_from_current_process(DBusCredentials *credentials)
Adds the most important credentials of the current process (the uid and pid) to the passed-in credent...
dbus_bool_t _dbus_close_socket(DBusSocket *fd, DBusError *error)
Closes a socket and invalidates it.
DBusSocket _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.
void _dbus_atomic_set_zero(DBusAtomic *atomic)
Atomically set the value of an integer to 0.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
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.
#define DBUS_GID_FORMAT
an appropriate printf format for dbus_gid_t
Definition: dbus-sysdeps.h:151
int _dbus_printf_string_upper_bound(const char *format, va_list args)
Measure the length of the given format string and arguments, not including the terminating nul.
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
dbus_bool_t _dbus_delete_directory(const DBusString *filename, DBusError *error)
Removes a directory; Directory must be empty.
#define DBUS_UID_FORMAT
an appropriate printf format for dbus_uid_t
Definition: dbus-sysdeps.h:149
void _dbus_get_real_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
int _dbus_poll(DBusPollFD *fds, int n_fds, int timeout_milliseconds)
Wrapper for poll().
dbus_bool_t _dbus_get_autolaunch_address(const char *scope, DBusString *address, DBusError *error)
Returns the address of a new session bus.
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.
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
DBusSocket _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.
void _dbus_print_backtrace(void)
On GNU libc systems, print a crude backtrace to stderr.
void _dbus_init_system_log(const char *tag, DBusLogFlags flags)
Initialize the system log.
DBusSocket _dbus_accept(DBusSocket listen_fd)
Accepts a connection on a listening socket.
#define _DBUS_MAX_SUN_PATH_LENGTH
Maximum length of the path to a UNIX domain socket, sockaddr_un::sun_path member.
Definition: dbus-sysdeps.h:743
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...
void _dbus_flush_caches(void)
Called when the bus daemon is signaled to reload its configuration; any caches should be nuked.
const char * _dbus_get_tmpdir(void)
Gets the temporary files directory by inspecting the environment variables TMPDIR,...
#define DBUS_PID_FORMAT
an appropriate printf format for dbus_pid_t
Definition: dbus-sysdeps.h:147
dbus_bool_t _dbus_ensure_directory(const DBusString *filename, DBusError *error)
Creates a directory; succeeds if the directory is created or already existed.
dbus_bool_t _dbus_create_directory(const DBusString *filename, DBusError *error)
Creates a directory.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
unsigned short dbus_uint16_t
A 16-bit unsigned integer on all platforms.
int dbus_int32_t
A 32-bit signed integer on all platforms.
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:321
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:325
Object representing an exception.
Definition: dbus-errors.h:49
const char * name
public error name field
Definition: dbus-errors.h:50
const char * message
public error message field
Definition: dbus-errors.h:51
A node in a linked list.
Definition: dbus-list.h:35
short events
Events to poll for.
Definition: dbus-sysdeps.h:418
short revents
Events that occurred.
Definition: dbus-sysdeps.h:419
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:417
Socket interface.
Definition: dbus-sysdeps.h:179
Information about a UNIX user.
int n_group_ids
Size of group IDs array.
dbus_uid_t uid
UID.
char * homedir
Home directory.
dbus_gid_t * group_ids
Groups IDs, including above primary group.
char * username
Username.
dbus_gid_t primary_gid
GID.
A globally unique ID ; we have one for each DBusServer, and also one for each machine with libdbus in...