D-Bus 1.15.8
dbus-sysdeps-unix.c
1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2/* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3 *
4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
6 *
7 * SPDX-License-Identifier: AFL-2.1 OR GPL-2.0-or-later
8 *
9 * Licensed under the Academic Free License version 2.1
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 */
26
27#include <config.h>
28
29#include "dbus-internals.h"
30#include "dbus-sysdeps.h"
31#include "dbus-sysdeps-unix.h"
32#include "dbus-threads.h"
33#include "dbus-protocol.h"
34#include "dbus-file.h"
35#include "dbus-transport.h"
36#include "dbus-string.h"
37#include "dbus-userdb.h"
38#include "dbus-list.h"
39#include "dbus-credentials.h"
40#include "dbus-nonce.h"
41
42#include <limits.h>
43#include <sys/types.h>
44#include <stdlib.h>
45#include <string.h>
46#include <signal.h>
47#include <unistd.h>
48#include <stdio.h>
49#include <fcntl.h>
50#include <sys/socket.h>
51#include <dirent.h>
52#include <sys/un.h>
53#include <pwd.h>
54#include <time.h>
55#include <locale.h>
56#include <sys/time.h>
57#include <sys/stat.h>
58#include <sys/wait.h>
59#include <netinet/in.h>
60#include <netinet/tcp.h>
61#include <netdb.h>
62#include <grp.h>
63#include <arpa/inet.h>
64
65#ifdef HAVE_ERRNO_H
66#include <errno.h>
67#endif
68#ifdef HAVE_LINUX_CLOSE_RANGE_H
69#include <linux/close_range.h>
70#endif
71#ifdef HAVE_SYSLOG_H
72#include <syslog.h>
73#endif
74#ifdef HAVE_WRITEV
75#include <sys/uio.h>
76#endif
77#ifdef HAVE_BACKTRACE
78#include <execinfo.h>
79#endif
80#ifdef HAVE_GETPEERUCRED
81#include <ucred.h>
82#endif
83#ifdef HAVE_ALLOCA_H
84#include <alloca.h>
85#endif
86#ifdef HAVE_SYS_RANDOM_H
87#include <sys/random.h>
88#endif
89#ifdef HAVE_SYS_SYSCALL_H
90#include <sys/syscall.h>
91#endif
92
93#ifdef HAVE_ADT
94#include <bsm/adt.h>
95#endif
96
97#ifdef HAVE_SYSTEMD
98#include <systemd/sd-daemon.h>
99#endif
100
101#if !defined(HAVE_STDATOMIC_H) && !DBUS_USE_SYNC
102#include <pthread.h>
103#endif
104
105#ifndef O_BINARY
106#define O_BINARY 0
107#endif
108
109#ifndef AI_ADDRCONFIG
110#define AI_ADDRCONFIG 0
111#endif
112
113#ifndef HAVE_SOCKLEN_T
114#define socklen_t int
115#endif
116
117#if defined (__sun) || defined (__sun__)
118/*
119 * CMS_SPACE etc. definitions for Solaris < 10, based on
120 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
121 * via
122 * http://wiki.opencsw.org/porting-faq#toc10
123 *
124 * These are only redefined for Solaris, for now: if your OS needs these too,
125 * please file a bug. (Or preferably, improve your OS so they're not needed.)
126 */
127
128# ifndef CMSG_ALIGN
129# ifdef __sun__
130# define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
131# else
132 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
133# define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
134 ~(sizeof (long) - 1))
135# endif
136# endif
137
138# ifndef CMSG_SPACE
139# define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
140 CMSG_ALIGN (len))
141# endif
142
143# ifndef CMSG_LEN
144# define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
145# endif
146
147#endif /* Solaris */
148
149#if defined(__linux__) && defined(__NR_close_range) && !defined(HAVE_CLOSE_RANGE)
150/* The kernel headers are new enough to have the close_range syscall,
151 * but glibc isn't new enough to have the syscall wrapper, so call the
152 * syscall directly. */
153static inline int
154close_range (unsigned int first,
155 unsigned int last,
156 int flags)
157{
158 return syscall (__NR_close_range, first, last, flags);
159}
160/* Now we can call that inline wrapper as though it was provided by glibc. */
161#define HAVE_CLOSE_RANGE
162#endif
163
179_dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags flags,
180 const char **error_str_p)
181{
182 static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
183 DBUS_FORCE_STDOUT_NULL,
184 DBUS_FORCE_STDERR_NULL };
185 /* Should always get replaced with the real error before use */
186 const char *error_str = "Failed mysteriously";
187 int devnull = -1;
188 int saved_errno;
189 /* This function relies on the standard fds having their POSIX values. */
190 _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
191 _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
192 _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
193 int i;
194
195 for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
196 {
197 /* Because we rely on being single-threaded, and we want the
198 * standard fds to not be close-on-exec, we don't set it
199 * close-on-exec. */
200 if (devnull < i)
201 devnull = open ("/dev/null", O_RDWR);
202
203 if (devnull < 0)
204 {
205 error_str = "Failed to open /dev/null";
206 goto out;
207 }
208
209 /* We already opened all fds < i, so the only way this assertion
210 * could fail is if another thread closed one, and we document
211 * this function as not safe for multi-threading. */
212 _dbus_assert (devnull >= i);
213
214 if (devnull != i && (flags & relevant_flag[i]) != 0)
215 {
216 if (dup2 (devnull, i) < 0)
217 {
218 error_str = "Failed to dup2 /dev/null onto a standard fd";
219 goto out;
220 }
221 }
222 }
223
224 error_str = NULL;
225
226out:
227 saved_errno = errno;
228
229 if (devnull > STDERR_FILENO)
230 close (devnull);
231
232 if (error_str_p != NULL)
233 *error_str_p = error_str;
234
235 errno = saved_errno;
236 return (error_str == NULL);
237}
238
239static dbus_bool_t _dbus_set_fd_nonblocking (int fd,
240 DBusError *error);
241
242static dbus_bool_t
243_dbus_open_socket (int *fd_p,
244 int domain,
245 int type,
246 int protocol,
247 DBusError *error)
248{
249#ifdef SOCK_CLOEXEC
250 dbus_bool_t cloexec_done;
251
252 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
253 cloexec_done = *fd_p >= 0;
254
255 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
256 if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
257#endif
258 {
259 *fd_p = socket (domain, type, protocol);
260 }
261
262 if (*fd_p >= 0)
263 {
264#ifdef SOCK_CLOEXEC
265 if (!cloexec_done)
266#endif
267 {
269 }
270
271 _dbus_verbose ("socket fd %d opened\n", *fd_p);
272 return TRUE;
273 }
274 else
275 {
276 dbus_set_error(error,
278 "Failed to open socket: %s",
279 _dbus_strerror (errno));
280 return FALSE;
281 }
282}
283
294static dbus_bool_t
295_dbus_open_unix_socket (int *fd,
296 DBusError *error)
297{
298 return _dbus_open_socket(fd, AF_UNIX, SOCK_STREAM, 0, error);
299}
300
315 DBusError *error)
316{
317 dbus_bool_t rv;
318
319 _dbus_assert (fd != NULL);
320 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
321
322 rv = _dbus_close (fd->fd, error);
323 _dbus_socket_invalidate (fd);
324
325 return rv;
326}
327
337int
339 DBusString *buffer,
340 int count)
341{
342 return _dbus_read (fd.fd, buffer, count);
343}
344
355int
357 const DBusString *buffer,
358 int start,
359 int len)
360{
361#if HAVE_DECL_MSG_NOSIGNAL
362 const char *data;
363 int bytes_written;
364
365 data = _dbus_string_get_const_data_len (buffer, start, len);
366
367 again:
368
369 bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
370
371 if (bytes_written < 0 && errno == EINTR)
372 goto again;
373
374 return bytes_written;
375
376#else
377 return _dbus_write (fd.fd, buffer, start, len);
378#endif
379}
380
393int
395 DBusString *buffer,
396 int count,
397 int *fds,
398 unsigned int *n_fds) {
399#ifndef HAVE_UNIX_FD_PASSING
400 int r;
401
402 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
403 return r;
404
405 *n_fds = 0;
406 return r;
407
408#else
409 int bytes_read;
410 int start;
411 struct msghdr m;
412 struct iovec iov;
413
414 _dbus_assert (count >= 0);
416
417 start = _dbus_string_get_length (buffer);
418
419 if (!_dbus_string_lengthen (buffer, count))
420 {
421 errno = ENOMEM;
422 return -1;
423 }
424
425 _DBUS_ZERO(iov);
426 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
427 iov.iov_len = count;
428
429 _DBUS_ZERO(m);
430 m.msg_iov = &iov;
431 m.msg_iovlen = 1;
432
433 /* Hmm, we have no clue how long the control data will actually be
434 that is queued for us. The least we can do is assume that the
435 caller knows. Hence let's make space for the number of fds that
436 we shall read at max plus the cmsg header. */
437 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
438
439 /* It's probably safe to assume that systems with SCM_RIGHTS also
440 know alloca() */
441 m.msg_control = alloca(m.msg_controllen);
442 memset(m.msg_control, 0, m.msg_controllen);
443
444 /* Do not include the padding at the end when we tell the kernel
445 * how much we're willing to receive. This avoids getting
446 * the padding filled with additional fds that we weren't expecting,
447 * if a (potentially malicious) sender included them. (fd.o #83622) */
448 m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
449
450 again:
451
452 bytes_read = recvmsg (fd.fd, &m, 0
453#ifdef MSG_CMSG_CLOEXEC
454 |MSG_CMSG_CLOEXEC
455#endif
456 );
457
458 if (bytes_read < 0)
459 {
460 if (errno == EINTR)
461 goto again;
462 else
463 {
464 /* put length back (note that this doesn't actually realloc anything) */
465 _dbus_string_set_length (buffer, start);
466 return -1;
467 }
468 }
469 else
470 {
471 struct cmsghdr *cm;
472 dbus_bool_t found = FALSE;
473
474 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
475 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
476 {
477 size_t i;
478 int *payload = (int *) (void *) CMSG_DATA (cm);
479 size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
480 size_t payload_len_fds;
481 size_t fds_to_use;
482
483 /* Every unsigned int fits in a size_t without truncation, so
484 * casting (size_t) *n_fds is OK */
485 _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int));
486
487 if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL &&
488 (char *) payload + payload_len_bytes >
489 (char *) m.msg_control + m.msg_controllen)
490 {
491 /* This is the last cmsg in a truncated message and using
492 * cmsg_len would apparently overrun the allocated buffer.
493 * Some operating systems (illumos and Solaris are known) do
494 * not adjust cmsg_len in the last cmsg when truncation occurs.
495 * Adjust the payload length here. The calculation for
496 * payload_len_fds below will discard any trailing bytes that
497 * belong to an incomplete file descriptor - the kernel will
498 * have already closed that (at least for illumos and Solaris)
499 */
500 payload_len_bytes = m.msg_controllen -
501 ((char *) payload - (char *) m.msg_control);
502 }
503
504 payload_len_fds = payload_len_bytes / sizeof (int);
505
506 if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
507 {
508 /* The fds in the payload will fit in our buffer */
509 fds_to_use = payload_len_fds;
510 }
511 else
512 {
513 /* Too many fds in the payload. This shouldn't happen
514 * any more because we're setting m.msg_controllen to
515 * the exact number we can accept, but be safe and
516 * truncate. */
517 fds_to_use = (size_t) *n_fds;
518
519 /* Close the excess fds to avoid DoS: if they stayed open,
520 * someone could send us an extra fd per message
521 * and we'd eventually run out. */
522 for (i = fds_to_use; i < payload_len_fds; i++)
523 {
524 close (payload[i]);
525 }
526 }
527
528 memcpy (fds, payload, fds_to_use * sizeof (int));
529 found = TRUE;
530 /* This narrowing cast from size_t to unsigned int cannot
531 * overflow because we have chosen fds_to_use
532 * to be <= *n_fds */
533 *n_fds = (unsigned int) fds_to_use;
534
535 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
536 worked, hence we need to go through this list and set
537 CLOEXEC everywhere in any case */
538 for (i = 0; i < fds_to_use; i++)
540
541 break;
542 }
543
544 if (!found)
545 *n_fds = 0;
546
547 if (m.msg_flags & MSG_CTRUNC)
548 {
549 unsigned int i;
550
551 /* Hmm, apparently the control data was truncated. The bad
552 thing is that we might have completely lost a couple of fds
553 without chance to recover them. Hence let's treat this as a
554 serious error. */
555
556 /* We still need to close whatever fds we *did* receive,
557 * otherwise they'll never get closed. (CVE-2020-12049) */
558 for (i = 0; i < *n_fds; i++)
559 close (fds[i]);
560
561 *n_fds = 0;
562 errno = ENOSPC;
563 _dbus_string_set_length (buffer, start);
564 return -1;
565 }
566
567 /* put length back (doesn't actually realloc) */
568 _dbus_string_set_length (buffer, start + bytes_read);
569
570#if 0
571 if (bytes_read > 0)
572 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
573#endif
574
575 return bytes_read;
576 }
577#endif
578}
579
580int
581_dbus_write_socket_with_unix_fds(DBusSocket fd,
582 const DBusString *buffer,
583 int start,
584 int len,
585 const int *fds,
586 int n_fds) {
587
588#ifndef HAVE_UNIX_FD_PASSING
589
590 if (n_fds > 0) {
591 errno = ENOTSUP;
592 return -1;
593 }
594
595 return _dbus_write_socket(fd, buffer, start, len);
596#else
597 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
598#endif
599}
600
601int
602_dbus_write_socket_with_unix_fds_two(DBusSocket fd,
603 const DBusString *buffer1,
604 int start1,
605 int len1,
606 const DBusString *buffer2,
607 int start2,
608 int len2,
609 const int *fds,
610 int n_fds) {
611
612#ifndef HAVE_UNIX_FD_PASSING
613
614 if (n_fds > 0) {
615 errno = ENOTSUP;
616 return -1;
617 }
618
619 return _dbus_write_socket_two(fd,
620 buffer1, start1, len1,
621 buffer2, start2, len2);
622#else
623
624 struct msghdr m;
625 struct cmsghdr *cm;
626 struct iovec iov[2];
627 int bytes_written;
628
629 _dbus_assert (len1 >= 0);
630 _dbus_assert (len2 >= 0);
631 _dbus_assert (n_fds >= 0);
632
633 _DBUS_ZERO(iov);
634 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
635 iov[0].iov_len = len1;
636
637 if (buffer2)
638 {
639 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
640 iov[1].iov_len = len2;
641 }
642
643 _DBUS_ZERO(m);
644 m.msg_iov = iov;
645 m.msg_iovlen = buffer2 ? 2 : 1;
646
647 if (n_fds > 0)
648 {
649 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
650 m.msg_control = alloca(m.msg_controllen);
651 memset(m.msg_control, 0, m.msg_controllen);
652
653 cm = CMSG_FIRSTHDR(&m);
654 cm->cmsg_level = SOL_SOCKET;
655 cm->cmsg_type = SCM_RIGHTS;
656 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
657 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
658 }
659
660 again:
661
662 bytes_written = sendmsg (fd.fd, &m, 0
663#if HAVE_DECL_MSG_NOSIGNAL
664 |MSG_NOSIGNAL
665#endif
666 );
667
668 if (bytes_written < 0 && errno == EINTR)
669 goto again;
670
671#if 0
672 if (bytes_written > 0)
673 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
674#endif
675
676 return bytes_written;
677#endif
678}
679
693int
695 const DBusString *buffer1,
696 int start1,
697 int len1,
698 const DBusString *buffer2,
699 int start2,
700 int len2)
701{
702#if HAVE_DECL_MSG_NOSIGNAL
703 struct iovec vectors[2];
704 const char *data1;
705 const char *data2;
706 int bytes_written;
707 struct msghdr m;
708
709 _dbus_assert (buffer1 != NULL);
710 _dbus_assert (start1 >= 0);
711 _dbus_assert (start2 >= 0);
712 _dbus_assert (len1 >= 0);
713 _dbus_assert (len2 >= 0);
714
715 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
716
717 if (buffer2 != NULL)
718 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
719 else
720 {
721 data2 = NULL;
722 start2 = 0;
723 len2 = 0;
724 }
725
726 vectors[0].iov_base = (char*) data1;
727 vectors[0].iov_len = len1;
728 vectors[1].iov_base = (char*) data2;
729 vectors[1].iov_len = len2;
730
731 _DBUS_ZERO(m);
732 m.msg_iov = vectors;
733 m.msg_iovlen = data2 ? 2 : 1;
734
735 again:
736
737 bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
738
739 if (bytes_written < 0 && errno == EINTR)
740 goto again;
741
742 return bytes_written;
743
744#else
745 return _dbus_write_two (fd.fd, buffer1, start1, len1,
746 buffer2, start2, len2);
747#endif
748}
749
766int
768 DBusString *buffer,
769 int count)
770{
771 int bytes_read;
772 int start;
773 char *data;
774
775 _dbus_assert (count >= 0);
776
777 start = _dbus_string_get_length (buffer);
778
779 if (!_dbus_string_lengthen (buffer, count))
780 {
781 errno = ENOMEM;
782 return -1;
783 }
784
785 data = _dbus_string_get_data_len (buffer, start, count);
786
787 again:
788
789 bytes_read = read (fd, data, count);
790
791 if (bytes_read < 0)
792 {
793 if (errno == EINTR)
794 goto again;
795 else
796 {
797 /* put length back (note that this doesn't actually realloc anything) */
798 _dbus_string_set_length (buffer, start);
799 return -1;
800 }
801 }
802 else
803 {
804 /* put length back (doesn't actually realloc) */
805 _dbus_string_set_length (buffer, start + bytes_read);
806
807#if 0
808 if (bytes_read > 0)
809 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
810#endif
811
812 return bytes_read;
813 }
814}
815
826int
828 const DBusString *buffer,
829 int start,
830 int len)
831{
832 const char *data;
833 int bytes_written;
834
835 data = _dbus_string_get_const_data_len (buffer, start, len);
836
837 again:
838
839 bytes_written = write (fd, data, len);
840
841 if (bytes_written < 0 && errno == EINTR)
842 goto again;
843
844#if 0
845 if (bytes_written > 0)
846 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
847#endif
848
849 return bytes_written;
850}
851
872int
874 const DBusString *buffer1,
875 int start1,
876 int len1,
877 const DBusString *buffer2,
878 int start2,
879 int len2)
880{
881 _dbus_assert (buffer1 != NULL);
882 _dbus_assert (start1 >= 0);
883 _dbus_assert (start2 >= 0);
884 _dbus_assert (len1 >= 0);
885 _dbus_assert (len2 >= 0);
886
887#ifdef HAVE_WRITEV
888 {
889 struct iovec vectors[2];
890 const char *data1;
891 const char *data2;
892 int bytes_written;
893
894 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
895
896 if (buffer2 != NULL)
897 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
898 else
899 {
900 data2 = NULL;
901 start2 = 0;
902 len2 = 0;
903 }
904
905 vectors[0].iov_base = (char*) data1;
906 vectors[0].iov_len = len1;
907 vectors[1].iov_base = (char*) data2;
908 vectors[1].iov_len = len2;
909
910 again:
911
912 bytes_written = writev (fd,
913 vectors,
914 data2 ? 2 : 1);
915
916 if (bytes_written < 0 && errno == EINTR)
917 goto again;
918
919 return bytes_written;
920 }
921#else /* HAVE_WRITEV */
922 {
923 int ret1, ret2;
924
925 ret1 = _dbus_write (fd, buffer1, start1, len1);
926 if (ret1 == len1 && buffer2 != NULL)
927 {
928 ret2 = _dbus_write (fd, buffer2, start2, len2);
929 if (ret2 < 0)
930 ret2 = 0; /* we can't report an error as the first write was OK */
931
932 return ret1 + ret2;
933 }
934 else
935 return ret1;
936 }
937#endif /* !HAVE_WRITEV */
938}
939
958 dbus_bool_t abstract,
959 DBusError *error)
960{
961 DBusSocket fd = DBUS_SOCKET_INIT;
962 size_t path_len;
963 struct sockaddr_un addr;
964 _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
965
966 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
967
968 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
969 path, abstract);
970
971
972 if (!_dbus_open_unix_socket (&fd.fd, error))
973 {
974 _DBUS_ASSERT_ERROR_IS_SET(error);
975 return fd;
976 }
977 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
978
979 _DBUS_ZERO (addr);
980 addr.sun_family = AF_UNIX;
981 path_len = strlen (path);
982
983 if (abstract)
984 {
985#ifdef __linux__
986 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
987 path_len++; /* Account for the extra nul byte added to the start of sun_path */
988
989 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
990 {
992 "Abstract socket name too long\n");
994 return fd;
995 }
996
997 strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
998 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
999#else /* !__linux__ */
1001 "Operating system does not support abstract socket namespace\n");
1002 _dbus_close_socket (&fd, NULL);
1003 return fd;
1004#endif /* !__linux__ */
1005 }
1006 else
1007 {
1008 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1009 {
1011 "Socket name too long\n");
1012 _dbus_close_socket (&fd, NULL);
1013 return fd;
1014 }
1015
1016 strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1017 }
1018
1019 if (connect (fd.fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1020 {
1021 dbus_set_error (error,
1022 _dbus_error_from_errno (errno),
1023 "Failed to connect to socket %s: %s",
1024 path, _dbus_strerror (errno));
1025
1026 _dbus_close_socket (&fd, NULL);
1027 return fd;
1028 }
1029
1030 if (!_dbus_set_fd_nonblocking (fd.fd, error))
1031 {
1032 _DBUS_ASSERT_ERROR_IS_SET (error);
1033
1034 _dbus_close_socket (&fd, NULL);
1035 return fd;
1036 }
1037
1038 return fd;
1039}
1040
1054_dbus_connect_exec (const char *path,
1055 char *const argv[],
1056 DBusError *error)
1057{
1058 DBusSocket s = DBUS_SOCKET_INIT;
1059 int fds[2];
1060 pid_t pid;
1061 int retval;
1062 dbus_bool_t cloexec_done = 0;
1063
1064 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1065
1066 _dbus_verbose ("connecting to process %s\n", path);
1067
1068#ifdef SOCK_CLOEXEC
1069 retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
1070 cloexec_done = (retval >= 0);
1071
1072 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
1073#endif
1074 {
1075 retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
1076 }
1077
1078 if (retval < 0)
1079 {
1080 dbus_set_error (error,
1081 _dbus_error_from_errno (errno),
1082 "Failed to create socket pair: %s",
1083 _dbus_strerror (errno));
1084 _dbus_assert (!_dbus_socket_is_valid (s));
1085 return s;
1086 }
1087
1088 if (!cloexec_done)
1089 {
1092 }
1093
1094 /* Make sure our output buffers aren't redundantly printed by both the
1095 * parent and the child */
1096 fflush (stdout);
1097 fflush (stderr);
1098
1099 pid = fork ();
1100 if (pid < 0)
1101 {
1102 dbus_set_error (error,
1103 _dbus_error_from_errno (errno),
1104 "Failed to fork() to call %s: %s",
1105 path, _dbus_strerror (errno));
1106 close (fds[0]);
1107 close (fds[1]);
1108 _dbus_assert (!_dbus_socket_is_valid (s));
1109 return s;
1110 }
1111
1112 if (pid == 0)
1113 {
1114 /* child */
1115 close (fds[0]);
1116
1117 dup2 (fds[1], STDIN_FILENO);
1118 dup2 (fds[1], STDOUT_FILENO);
1119
1120 if (fds[1] != STDIN_FILENO &&
1121 fds[1] != STDOUT_FILENO)
1122 close (fds[1]);
1123
1124 /* Inherit STDERR and the controlling terminal from the
1125 parent */
1126
1127 _dbus_close_all ();
1128
1129 execvp (path, (char * const *) argv);
1130
1131 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
1132
1133 _exit(1);
1134 }
1135
1136 /* parent */
1137 close (fds[1]);
1138
1139 if (!_dbus_set_fd_nonblocking (fds[0], error))
1140 {
1141 _DBUS_ASSERT_ERROR_IS_SET (error);
1142
1143 close (fds[0]);
1144 _dbus_assert (!_dbus_socket_is_valid (s));
1145 return s;
1146 }
1147
1148 s.fd = fds[0];
1149 return s;
1150}
1151
1171 dbus_bool_t abstract,
1172 DBusError *error)
1173{
1174 DBusSocket s = DBUS_SOCKET_INIT;
1175 int listen_fd;
1176 struct sockaddr_un addr;
1177 size_t path_len;
1178 _DBUS_STATIC_ASSERT (sizeof (addr.sun_path) > _DBUS_MAX_SUN_PATH_LENGTH);
1179
1180 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1181
1182 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1183 path, abstract);
1184
1185 if (!_dbus_open_unix_socket (&listen_fd, error))
1186 {
1187 _DBUS_ASSERT_ERROR_IS_SET(error);
1188 return s;
1189 }
1190 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1191
1192 _DBUS_ZERO (addr);
1193 addr.sun_family = AF_UNIX;
1194 path_len = strlen (path);
1195
1196 if (abstract)
1197 {
1198#ifdef __linux__
1199 /* remember that abstract names aren't nul-terminated so we rely
1200 * on sun_path being filled in with zeroes above.
1201 */
1202 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1203 path_len++; /* Account for the extra nul byte added to the start of sun_path */
1204
1205 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1206 {
1208 "Abstract socket name too long\n");
1209 _dbus_close (listen_fd, NULL);
1210 return s;
1211 }
1212
1213 strncpy (&addr.sun_path[1], path, sizeof (addr.sun_path) - 2);
1214 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1215#else /* !__linux__ */
1217 "Operating system does not support abstract socket namespace\n");
1218 _dbus_close (listen_fd, NULL);
1219 return s;
1220#endif /* !__linux__ */
1221 }
1222 else
1223 {
1224 /* Discussed security implications of this with Nalin,
1225 * and we couldn't think of where it would kick our ass, but
1226 * it still seems a bit sucky. It also has non-security suckage;
1227 * really we'd prefer to exit if the socket is already in use.
1228 * But there doesn't seem to be a good way to do this.
1229 *
1230 * Just to be extra careful, I threw in the stat() - clearly
1231 * the stat() can't *fix* any security issue, but it at least
1232 * avoids inadvertent/accidental data loss.
1233 */
1234 {
1235 struct stat sb;
1236
1237 if (stat (path, &sb) == 0 &&
1238 S_ISSOCK (sb.st_mode))
1239 unlink (path);
1240 }
1241
1242 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1243 {
1245 "Socket name too long\n");
1246 _dbus_close (listen_fd, NULL);
1247 return s;
1248 }
1249
1250 strncpy (addr.sun_path, path, sizeof (addr.sun_path) - 1);
1251 }
1252
1253 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1254 {
1255 dbus_set_error (error, _dbus_error_from_errno (errno),
1256 "Failed to bind socket \"%s\": %s",
1257 path, _dbus_strerror (errno));
1258 _dbus_close (listen_fd, NULL);
1259 return s;
1260 }
1261
1262 if (listen (listen_fd, SOMAXCONN /* backlog */) < 0)
1263 {
1264 dbus_set_error (error, _dbus_error_from_errno (errno),
1265 "Failed to listen on socket \"%s\": %s",
1266 path, _dbus_strerror (errno));
1267 _dbus_close (listen_fd, NULL);
1268 return s;
1269 }
1270
1271 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1272 {
1273 _DBUS_ASSERT_ERROR_IS_SET (error);
1274 _dbus_close (listen_fd, NULL);
1275 return s;
1276 }
1277
1278 /* Try opening up the permissions, but if we can't, just go ahead
1279 * and continue, maybe it will be good enough.
1280 */
1281 if (!abstract && chmod (path, 0777) < 0)
1282 _dbus_warn ("Could not set mode 0777 on socket %s", path);
1283
1284 s.fd = listen_fd;
1285 return s;
1286}
1287
1298int
1300 DBusError *error)
1301{
1302#ifdef HAVE_SYSTEMD
1303 int r, n;
1304 int fd;
1305 DBusSocket *new_fds;
1306
1307 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1308
1309 n = sd_listen_fds (TRUE);
1310 if (n < 0)
1311 {
1313 "Failed to acquire systemd socket: %s",
1314 _dbus_strerror (-n));
1315 return -1;
1316 }
1317
1318 if (n <= 0)
1319 {
1321 "No socket received.");
1322 return -1;
1323 }
1324
1325 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1326 {
1327 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1328 if (r < 0)
1329 {
1331 "Failed to verify systemd socket type: %s",
1332 _dbus_strerror (-r));
1333 return -1;
1334 }
1335
1336 if (!r)
1337 {
1339 "Passed socket has wrong type.");
1340 return -1;
1341 }
1342 }
1343
1344 /* OK, the file descriptors are all good, so let's take posession of
1345 them then. */
1346
1347 new_fds = dbus_new (DBusSocket, n);
1348 if (!new_fds)
1349 {
1351 "Failed to allocate file handle array.");
1352 goto fail;
1353 }
1354
1355 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1356 {
1357 if (!_dbus_set_fd_nonblocking (fd, error))
1358 {
1359 _DBUS_ASSERT_ERROR_IS_SET (error);
1360 goto fail;
1361 }
1362
1363 new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
1364 }
1365
1366 *fds = new_fds;
1367 return n;
1368
1369 fail:
1370
1371 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1372 {
1373 _dbus_close (fd, NULL);
1374 }
1375
1376 dbus_free (new_fds);
1377 return -1;
1378#else
1380 "dbus was compiled without systemd support");
1381 return -1;
1382#endif
1383}
1384
1385/* Convert an error code from getaddrinfo() or getnameinfo() into
1386 * a D-Bus error name. */
1387static const char *
1388_dbus_error_from_gai (int gai_res,
1389 int saved_errno)
1390{
1391 switch (gai_res)
1392 {
1393#ifdef EAI_FAMILY
1394 case EAI_FAMILY:
1395 /* ai_family not supported (at all) */
1397#endif
1398
1399#ifdef EAI_SOCKTYPE
1400 case EAI_SOCKTYPE:
1401 /* ai_socktype not supported (at all) */
1403#endif
1404
1405#ifdef EAI_MEMORY
1406 case EAI_MEMORY:
1407 /* Out of memory */
1408 return DBUS_ERROR_NO_MEMORY;
1409#endif
1410
1411#ifdef EAI_SYSTEM
1412 case EAI_SYSTEM:
1413 /* Unspecified system error, details in errno */
1414 return _dbus_error_from_errno (saved_errno);
1415#endif
1416
1417 case 0:
1418 /* It succeeded, but we didn't get any addresses? */
1419 return DBUS_ERROR_FAILED;
1420
1421 /* EAI_AGAIN: Transient failure */
1422 /* EAI_BADFLAGS: invalid ai_flags (programming error) */
1423 /* EAI_FAIL: Non-recoverable failure */
1424 /* EAI_NODATA: host exists but has no addresses */
1425 /* EAI_NONAME: host does not exist */
1426 /* EAI_OVERFLOW: argument buffer overflow */
1427 /* EAI_SERVICE: service not available for specified socket
1428 * type (we should never see this because we use numeric
1429 * ports) */
1430 default:
1431 return DBUS_ERROR_FAILED;
1432 }
1433}
1434
1450 const char *port,
1451 const char *family,
1452 DBusError *error)
1453{
1454 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1455}
1456
1458_dbus_connect_tcp_socket_with_nonce (const char *host,
1459 const char *port,
1460 const char *family,
1461 const char *noncefile,
1462 DBusError *error)
1463{
1464 int saved_errno = 0;
1465 DBusList *connect_errors = NULL;
1466 DBusSocket fd = DBUS_SOCKET_INIT;
1467 int res;
1468 struct addrinfo hints;
1469 struct addrinfo *ai = NULL;
1470 const struct addrinfo *tmp;
1471 DBusError *connect_error;
1472
1473 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1474
1475 _DBUS_ZERO (hints);
1476
1477 if (!family)
1478 hints.ai_family = AF_UNSPEC;
1479 else if (!strcmp(family, "ipv4"))
1480 hints.ai_family = AF_INET;
1481 else if (!strcmp(family, "ipv6"))
1482 hints.ai_family = AF_INET6;
1483 else
1484 {
1485 dbus_set_error (error,
1487 "Unknown address family %s", family);
1488 return _dbus_socket_get_invalid ();
1489 }
1490 hints.ai_protocol = IPPROTO_TCP;
1491 hints.ai_socktype = SOCK_STREAM;
1492 hints.ai_flags = AI_ADDRCONFIG;
1493
1494 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1495 {
1496 dbus_set_error (error,
1497 _dbus_error_from_gai (res, errno),
1498 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1499 host, port, gai_strerror(res), res);
1500 goto out;
1501 }
1502
1503 tmp = ai;
1504 while (tmp)
1505 {
1506 if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
1507 {
1508 _DBUS_ASSERT_ERROR_IS_SET(error);
1509 _dbus_socket_invalidate (&fd);
1510 goto out;
1511 }
1512 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1513
1514 if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1515 {
1516 saved_errno = errno;
1517 _dbus_close_socket (&fd, NULL);
1518
1519 connect_error = dbus_new0 (DBusError, 1);
1520
1521 if (connect_error == NULL)
1522 {
1523 _DBUS_SET_OOM (error);
1524 goto out;
1525 }
1526
1527 dbus_error_init (connect_error);
1528 _dbus_set_error_with_inet_sockaddr (connect_error,
1529 tmp->ai_addr, tmp->ai_addrlen,
1530 "Failed to connect to socket",
1531 saved_errno);
1532
1533 if (!_dbus_list_append (&connect_errors, connect_error))
1534 {
1535 dbus_error_free (connect_error);
1536 dbus_free (connect_error);
1537 _DBUS_SET_OOM (error);
1538 goto out;
1539 }
1540
1541 tmp = tmp->ai_next;
1542 continue;
1543 }
1544
1545 break;
1546 }
1547
1548 if (!_dbus_socket_is_valid (fd))
1549 {
1550 _dbus_combine_tcp_errors (&connect_errors, "Failed to connect",
1551 host, port, error);
1552 goto out;
1553 }
1554
1555 if (noncefile != NULL)
1556 {
1557 DBusString noncefileStr;
1558 dbus_bool_t ret;
1559 _dbus_string_init_const (&noncefileStr, noncefile);
1560 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1561
1562 if (!ret)
1563 {
1564 _dbus_close_socket (&fd, NULL);
1565 goto out;
1566 }
1567 }
1568
1569 if (!_dbus_set_fd_nonblocking (fd.fd, error))
1570 {
1571 _dbus_close_socket (&fd, NULL);
1572 goto out;
1573 }
1574
1575out:
1576 if (ai != NULL)
1577 freeaddrinfo (ai);
1578
1579 while ((connect_error = _dbus_list_pop_first (&connect_errors)))
1580 {
1581 dbus_error_free (connect_error);
1582 dbus_free (connect_error);
1583 }
1584
1585 return fd;
1586}
1587
1605int
1606_dbus_listen_tcp_socket (const char *host,
1607 const char *port,
1608 const char *family,
1609 DBusString *retport,
1610 const char **retfamily,
1611 DBusSocket **fds_p,
1612 DBusError *error)
1613{
1614 int saved_errno;
1615 int nlisten_fd = 0, res, i;
1616 DBusList *bind_errors = NULL;
1617 DBusError *bind_error = NULL;
1618 DBusSocket *listen_fd = NULL;
1619 struct addrinfo hints;
1620 struct addrinfo *ai, *tmp;
1621 unsigned int reuseaddr;
1622 dbus_bool_t have_ipv4 = FALSE;
1623 dbus_bool_t have_ipv6 = FALSE;
1624
1625 *fds_p = NULL;
1626 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1627
1628 _DBUS_ZERO (hints);
1629
1630 if (!family)
1631 hints.ai_family = AF_UNSPEC;
1632 else if (!strcmp(family, "ipv4"))
1633 hints.ai_family = AF_INET;
1634 else if (!strcmp(family, "ipv6"))
1635 hints.ai_family = AF_INET6;
1636 else
1637 {
1638 dbus_set_error (error,
1640 "Unknown address family %s", family);
1641 return -1;
1642 }
1643
1644 hints.ai_protocol = IPPROTO_TCP;
1645 hints.ai_socktype = SOCK_STREAM;
1646 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1647
1648 redo_lookup_with_port:
1649 ai = NULL;
1650 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1651 {
1652 dbus_set_error (error,
1653 _dbus_error_from_gai (res, errno),
1654 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1655 host ? host : "*", port, gai_strerror(res), res);
1656 goto failed;
1657 }
1658
1659 tmp = ai;
1660 while (tmp)
1661 {
1662 int fd = -1, tcp_nodelay_on;
1663 DBusSocket *newlisten_fd;
1664
1665 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1666 {
1667 _DBUS_ASSERT_ERROR_IS_SET(error);
1668 goto failed;
1669 }
1670 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1671
1672 reuseaddr = 1;
1673 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1674 {
1675 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1676 host ? host : "*", port, _dbus_strerror (errno));
1677 }
1678
1679 /* Nagle's algorithm imposes a huge delay on the initial messages
1680 going over TCP. */
1681 tcp_nodelay_on = 1;
1682 if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
1683 {
1684 _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
1685 host ? host : "*", port, _dbus_strerror (errno));
1686 }
1687
1688 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1689 {
1690 saved_errno = errno;
1691 _dbus_close(fd, NULL);
1692
1693 /*
1694 * We don't treat this as a fatal error, because there might be
1695 * other addresses that we can listen on. In particular:
1696 *
1697 * - If saved_errno is EADDRINUSE after we
1698 * "goto redo_lookup_with_port" after binding a port on one of the
1699 * possible addresses, we will try to bind that same port on
1700 * every address, including the same address again for a second
1701 * time, which will fail with EADDRINUSE.
1702 *
1703 * - If saved_errno is EADDRINUSE, it might be because binding to
1704 * an IPv6 address implicitly binds to a corresponding IPv4
1705 * address or vice versa (e.g. Linux with bindv6only=0).
1706 *
1707 * - If saved_errno is EADDRNOTAVAIL when we asked for family
1708 * AF_UNSPEC, it might be because IPv6 is disabled for this
1709 * particular interface (e.g. Linux with
1710 * /proc/sys/net/ipv6/conf/lo/disable_ipv6).
1711 */
1712 bind_error = dbus_new0 (DBusError, 1);
1713
1714 if (bind_error == NULL)
1715 {
1716 _DBUS_SET_OOM (error);
1717 goto failed;
1718 }
1719
1720 dbus_error_init (bind_error);
1721 _dbus_set_error_with_inet_sockaddr (bind_error, tmp->ai_addr, tmp->ai_addrlen,
1722 "Failed to bind socket",
1723 saved_errno);
1724
1725 if (!_dbus_list_append (&bind_errors, bind_error))
1726 {
1727 dbus_error_free (bind_error);
1728 dbus_free (bind_error);
1729 _DBUS_SET_OOM (error);
1730 goto failed;
1731 }
1732
1733 /* Try the next address, maybe it will work better */
1734 tmp = tmp->ai_next;
1735 continue;
1736 }
1737
1738 if (listen (fd, 30 /* backlog */) < 0)
1739 {
1740 saved_errno = errno;
1741 _dbus_close (fd, NULL);
1742 _dbus_set_error_with_inet_sockaddr (error, tmp->ai_addr, tmp->ai_addrlen,
1743 "Failed to listen on socket",
1744 saved_errno);
1745 goto failed;
1746 }
1747
1748 newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
1749 if (!newlisten_fd)
1750 {
1751 _dbus_close (fd, NULL);
1753 "Failed to allocate file handle array");
1754 goto failed;
1755 }
1756 listen_fd = newlisten_fd;
1757 listen_fd[nlisten_fd].fd = fd;
1758 nlisten_fd++;
1759
1760 if (tmp->ai_addr->sa_family == AF_INET)
1761 have_ipv4 = TRUE;
1762 else if (tmp->ai_addr->sa_family == AF_INET6)
1763 have_ipv6 = TRUE;
1764
1765 if (!_dbus_string_get_length(retport))
1766 {
1767 /* If the user didn't specify a port, or used 0, then
1768 the kernel chooses a port. After the first address
1769 is bound to, we need to force all remaining addresses
1770 to use the same port */
1771 if (!port || !strcmp(port, "0"))
1772 {
1773 int result;
1774 struct sockaddr_storage addr;
1775 socklen_t addrlen;
1776 char portbuf[50];
1777
1778 addrlen = sizeof(addr);
1779 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1780
1781 if (result == -1)
1782 {
1783 saved_errno = errno;
1784 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1785 "Failed to retrieve socket name for \"%s:%s\": %s",
1786 host ? host : "*", port, _dbus_strerror (saved_errno));
1787 goto failed;
1788 }
1789
1790 if ((res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1791 portbuf, sizeof(portbuf),
1792 NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
1793 {
1794 saved_errno = errno;
1795 dbus_set_error (error, _dbus_error_from_gai (res, saved_errno),
1796 "Failed to resolve port \"%s:%s\": %s (%d)",
1797 host ? host : "*", port, gai_strerror(res), res);
1798 goto failed;
1799 }
1800
1801 if (!_dbus_string_append(retport, portbuf))
1802 {
1804 goto failed;
1805 }
1806
1807 /* Release current address list & redo lookup */
1808 port = _dbus_string_get_const_data(retport);
1809 freeaddrinfo(ai);
1810 goto redo_lookup_with_port;
1811 }
1812 else
1813 {
1814 if (!_dbus_string_append(retport, port))
1815 {
1817 goto failed;
1818 }
1819 }
1820 }
1821
1822 tmp = tmp->ai_next;
1823 }
1824 freeaddrinfo(ai);
1825 ai = NULL;
1826
1827 if (!nlisten_fd)
1828 {
1829 _dbus_combine_tcp_errors (&bind_errors, "Failed to bind", host,
1830 port, error);
1831 goto failed;
1832 }
1833
1834 if (have_ipv4 && !have_ipv6)
1835 *retfamily = "ipv4";
1836 else if (!have_ipv4 && have_ipv6)
1837 *retfamily = "ipv6";
1838
1839 for (i = 0 ; i < nlisten_fd ; i++)
1840 {
1841 if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
1842 {
1843 goto failed;
1844 }
1845 }
1846
1847 *fds_p = listen_fd;
1848
1849 /* This list might be non-empty even on success, because we might be
1850 * ignoring EADDRINUSE or EADDRNOTAVAIL */
1851 while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1852 {
1853 dbus_error_free (bind_error);
1854 dbus_free (bind_error);
1855 }
1856
1857 return nlisten_fd;
1858
1859 failed:
1860 if (ai)
1861 freeaddrinfo(ai);
1862 for (i = 0 ; i < nlisten_fd ; i++)
1863 _dbus_close(listen_fd[i].fd, NULL);
1864
1865 while ((bind_error = _dbus_list_pop_first (&bind_errors)))
1866 {
1867 dbus_error_free (bind_error);
1868 dbus_free (bind_error);
1869 }
1870
1871 dbus_free(listen_fd);
1872 return -1;
1873}
1874
1875static dbus_bool_t
1876write_credentials_byte (int server_fd,
1877 DBusError *error)
1878{
1879 int bytes_written;
1880 char buf[1] = { '\0' };
1881#if defined(HAVE_CMSGCRED)
1882 union {
1883 struct cmsghdr hdr;
1884 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1885 } cmsg;
1886 struct iovec iov;
1887 struct msghdr msg;
1888 iov.iov_base = buf;
1889 iov.iov_len = 1;
1890
1891 _DBUS_ZERO(msg);
1892 msg.msg_iov = &iov;
1893 msg.msg_iovlen = 1;
1894
1895 msg.msg_control = (caddr_t) &cmsg;
1896 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1897 _DBUS_ZERO(cmsg);
1898 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1899 cmsg.hdr.cmsg_level = SOL_SOCKET;
1900 cmsg.hdr.cmsg_type = SCM_CREDS;
1901#endif
1902
1903 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1904
1905 again:
1906
1907#if defined(HAVE_CMSGCRED)
1908 bytes_written = sendmsg (server_fd, &msg, 0
1909#if HAVE_DECL_MSG_NOSIGNAL
1910 |MSG_NOSIGNAL
1911#endif
1912 );
1913
1914 /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
1915 * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
1916 * only allows that on AF_UNIX. Try just doing a send() instead. */
1917 if (bytes_written < 0 && errno == EINVAL)
1918#endif
1919 {
1920 bytes_written = send (server_fd, buf, 1, 0
1921#if HAVE_DECL_MSG_NOSIGNAL
1922 |MSG_NOSIGNAL
1923#endif
1924 );
1925 }
1926
1927 if (bytes_written < 0 && errno == EINTR)
1928 goto again;
1929
1930 if (bytes_written < 0)
1931 {
1932 dbus_set_error (error, _dbus_error_from_errno (errno),
1933 "Failed to write credentials byte: %s",
1934 _dbus_strerror (errno));
1935 return FALSE;
1936 }
1937 else if (bytes_written == 0)
1938 {
1940 "wrote zero bytes writing credentials byte");
1941 return FALSE;
1942 }
1943 else
1944 {
1945 _dbus_assert (bytes_written == 1);
1946 _dbus_verbose ("wrote credentials byte\n");
1947 return TRUE;
1948 }
1949}
1950
1951/* return FALSE on OOM, TRUE otherwise, even if no groups were found */
1952static dbus_bool_t
1953add_groups_to_credentials (int client_fd,
1954 DBusCredentials *credentials,
1955 dbus_gid_t primary)
1956{
1957#if defined(__linux__) && defined(SO_PEERGROUPS)
1958 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
1959 /* This function assumes socklen_t is unsigned, which is true on Linux */
1960 _DBUS_STATIC_ASSERT (((socklen_t) -1) > 0);
1961 gid_t *buf = NULL;
1962 socklen_t len = 1024;
1963 dbus_bool_t oom = FALSE;
1964 /* libdbus has a different representation of group IDs just to annoy you */
1965 dbus_gid_t *converted_gids = NULL;
1966 dbus_bool_t need_primary = TRUE;
1967 size_t n_gids;
1968 size_t i;
1969
1970 n_gids = ((size_t) len) / sizeof (gid_t);
1971 buf = dbus_new (gid_t, n_gids);
1972
1973 if (buf == NULL)
1974 return FALSE;
1975
1976 while (getsockopt (client_fd, SOL_SOCKET, SO_PEERGROUPS, buf, &len) < 0)
1977 {
1978 int e = errno;
1979 gid_t *replacement;
1980
1981 _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
1982 _dbus_strerror (e), (unsigned long) len);
1983
1984 if (e != ERANGE || (size_t) len <= n_gids * sizeof (gid_t))
1985 {
1986 _dbus_verbose ("Failed to getsockopt(SO_PEERGROUPS): %s\n",
1987 _dbus_strerror (e));
1988 goto out;
1989 }
1990
1991 /* If not enough space, len is updated to be enough.
1992 * Try again with a large enough buffer. */
1993 n_gids = ((size_t) len) / sizeof (gid_t);
1994 replacement = dbus_realloc (buf, len);
1995
1996 if (replacement == NULL)
1997 {
1998 oom = TRUE;
1999 goto out;
2000 }
2001
2002 buf = replacement;
2003 _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2004 }
2005
2006 if (len > n_gids * sizeof (gid_t))
2007 {
2008 _dbus_verbose ("%lu > %zu", (unsigned long) len, n_gids * sizeof (gid_t));
2009 _dbus_assert_not_reached ("getsockopt(SO_PEERGROUPS) overflowed");
2010 }
2011
2012 if (len % sizeof (gid_t) != 0)
2013 {
2014 _dbus_verbose ("getsockopt(SO_PEERGROUPS) did not return an "
2015 "integer multiple of sizeof(gid_t): %lu should be "
2016 "divisible by %zu",
2017 (unsigned long) len, sizeof (gid_t));
2018 goto out;
2019 }
2020
2021 /* Allocate an extra space for the primary group ID */
2022 n_gids = ((size_t) len) / sizeof (gid_t);
2023
2024 /* If n_gids is less than this, then (n_gids + 1) certainly doesn't
2025 * overflow, and neither does multiplying that by sizeof(dbus_gid_t).
2026 * This is using _DBUS_INT32_MAX as a conservative lower bound for
2027 * the maximum size_t. */
2028 if (n_gids >= (_DBUS_INT32_MAX / sizeof (dbus_gid_t)) - 1)
2029 {
2030 _dbus_verbose ("getsockopt(SO_PEERGROUPS) returned a huge number "
2031 "of groups (%lu bytes), ignoring",
2032 (unsigned long) len);
2033 goto out;
2034 }
2035
2036 converted_gids = dbus_new (dbus_gid_t, n_gids + 1);
2037
2038 if (converted_gids == NULL)
2039 {
2040 oom = TRUE;
2041 goto out;
2042 }
2043
2044 for (i = 0; i < n_gids; i++)
2045 {
2046 converted_gids[i] = (dbus_gid_t) buf[i];
2047
2048 if (converted_gids[i] == primary)
2049 need_primary = FALSE;
2050 }
2051
2052 if (need_primary && primary != DBUS_GID_UNSET)
2053 {
2054 converted_gids[n_gids] = primary;
2055 n_gids++;
2056 }
2057
2058 _dbus_credentials_take_unix_gids (credentials, converted_gids, n_gids);
2059
2060out:
2061 dbus_free (buf);
2062 return !oom;
2063#else
2064 /* no error */
2065 return TRUE;
2066#endif
2067}
2068
2069/* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
2070static dbus_bool_t
2071add_linux_security_label_to_credentials (int client_fd,
2072 DBusCredentials *credentials)
2073{
2074#if defined(__linux__) && defined(SO_PEERSEC)
2075 DBusString buf;
2076 socklen_t len = 1024;
2077 dbus_bool_t oom = FALSE;
2078
2079 if (!_dbus_string_init_preallocated (&buf, len) ||
2080 !_dbus_string_set_length (&buf, len))
2081 return FALSE;
2082
2083 while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
2084 _dbus_string_get_data (&buf), &len) < 0)
2085 {
2086 int e = errno;
2087
2088 _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
2089 _dbus_strerror (e), (unsigned long) len);
2090
2091 if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
2092 {
2093 _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
2094 _dbus_strerror (e));
2095 goto out;
2096 }
2097
2098 /* If not enough space, len is updated to be enough.
2099 * Try again with a large enough buffer. */
2100 if (!_dbus_string_set_length (&buf, len))
2101 {
2102 oom = TRUE;
2103 goto out;
2104 }
2105
2106 _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
2107 }
2108
2109 if (len <= 0)
2110 {
2111 _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
2112 (unsigned long) len);
2113 goto out;
2114 }
2115
2116 if (len > _dbus_string_get_length_uint (&buf))
2117 {
2118 _dbus_verbose ("%lu > %u", (unsigned long) len,
2119 _dbus_string_get_length_uint (&buf));
2120 _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
2121 }
2122
2123 if (_dbus_string_get_byte (&buf, len - 1) == 0)
2124 {
2125 /* the kernel included the trailing \0 in its count,
2126 * but DBusString always has an extra \0 after the data anyway */
2127 _dbus_verbose ("subtracting trailing \\0\n");
2128 len--;
2129 }
2130
2131 if (!_dbus_string_set_length (&buf, len))
2132 {
2133 _dbus_assert_not_reached ("shortening string should not lead to OOM");
2134 oom = TRUE;
2135 goto out;
2136 }
2137
2138 if (strlen (_dbus_string_get_const_data (&buf)) != len)
2139 {
2140 /* LSM people on the linux-security-module@ mailing list say this
2141 * should never happen: the label should be a bytestring with
2142 * an optional trailing \0 */
2143 _dbus_verbose ("security label from kernel had an embedded \\0, "
2144 "ignoring it\n");
2145 goto out;
2146 }
2147
2148 _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
2149 (unsigned long) len,
2151
2154 {
2155 oom = TRUE;
2156 goto out;
2157 }
2158
2159out:
2160 _dbus_string_free (&buf);
2161 return !oom;
2162#else
2163 /* no error */
2164 return TRUE;
2165#endif
2166}
2167
2210 DBusCredentials *credentials,
2211 DBusError *error)
2212{
2213 struct msghdr msg;
2214 struct iovec iov;
2215 char buf;
2216 dbus_uid_t uid_read;
2217 dbus_gid_t primary_gid_read;
2218 dbus_pid_t pid_read;
2219 int bytes_read;
2220 int pid_fd_read;
2221
2222#ifdef HAVE_CMSGCRED
2223 union {
2224 struct cmsghdr hdr;
2225 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
2226 } cmsg;
2227#endif
2228
2229 /* The POSIX spec certainly doesn't promise this, but
2230 * we need these assertions to fail as soon as we're wrong about
2231 * it so we can do the porting fixups
2232 */
2233 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
2234 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
2235 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
2236
2237 uid_read = DBUS_UID_UNSET;
2238 primary_gid_read = DBUS_GID_UNSET;
2239 pid_read = DBUS_PID_UNSET;
2240 pid_fd_read = -1;
2241
2242 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2243
2244 _dbus_credentials_clear (credentials);
2245
2246 iov.iov_base = &buf;
2247 iov.iov_len = 1;
2248
2249 _DBUS_ZERO(msg);
2250 msg.msg_iov = &iov;
2251 msg.msg_iovlen = 1;
2252
2253#if defined(HAVE_CMSGCRED)
2254 _DBUS_ZERO(cmsg);
2255 msg.msg_control = (caddr_t) &cmsg;
2256 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
2257#endif
2258
2259 again:
2260 bytes_read = recvmsg (client_fd.fd, &msg, 0);
2261
2262 if (bytes_read < 0)
2263 {
2264 if (errno == EINTR)
2265 goto again;
2266
2267 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
2268 * normally only call read_credentials if the socket was ready
2269 * for reading
2270 */
2271
2272 dbus_set_error (error, _dbus_error_from_errno (errno),
2273 "Failed to read credentials byte: %s",
2274 _dbus_strerror (errno));
2275 return FALSE;
2276 }
2277 else if (bytes_read == 0)
2278 {
2279 /* this should not happen unless we are using recvmsg wrong,
2280 * so is essentially here for paranoia
2281 */
2283 "Failed to read credentials byte (zero-length read)");
2284 return FALSE;
2285 }
2286 else if (buf != '\0')
2287 {
2289 "Credentials byte was not nul");
2290 return FALSE;
2291 }
2292
2293 _dbus_verbose ("read credentials byte\n");
2294
2295 {
2296#ifdef SO_PEERCRED
2297 /* Supported by at least Linux and OpenBSD, with minor differences.
2298 *
2299 * This mechanism passes the process ID through and does not require
2300 * the peer's cooperation, so we prefer it over all others. Notably,
2301 * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
2302 * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
2303 * because this is much less fragile.
2304 */
2305#ifdef __OpenBSD__
2306 struct sockpeercred cr;
2307#else
2308 struct ucred cr;
2309#endif
2310 socklen_t cr_len = sizeof (cr);
2311
2312 if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
2313 {
2314 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
2315 _dbus_strerror (errno));
2316 }
2317 else if (cr_len != sizeof (cr))
2318 {
2319 _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
2320 cr_len, (int) sizeof (cr));
2321 }
2322 else
2323 {
2324 pid_read = cr.pid;
2325 uid_read = cr.uid;
2326#ifdef __linux__
2327 /* Do other platforms have cr.gid? (Not that it really matters,
2328 * because the gid is useless to us unless we know the complete
2329 * group vector, which we only know on Linux.) */
2330 primary_gid_read = cr.gid;
2331#endif
2332 }
2333
2334#ifdef SO_PEERPIDFD
2335 /* If we have SO_PEERCRED we might also have SO_PEERPIDFD, which
2336 * allows to pin the process ID, and is available on Linux since v6.5. */
2337 cr_len = sizeof (int);
2338
2339 if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERPIDFD, &pid_fd_read, &cr_len) != 0)
2340 {
2341 _dbus_verbose ("Failed to getsockopt(SO_PEERPIDFD): %s\n",
2342 _dbus_strerror (errno));
2343 }
2344 else if (cr_len != sizeof (int))
2345 {
2346 _dbus_verbose ("Failed to getsockopt(SO_PEERPIDFD), returned %d bytes, expected %d\n",
2347 cr_len, (int) sizeof (int));
2348 }
2349#endif
2350
2351#elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
2352 /* Another variant of the above - used on NetBSD
2353 */
2354 struct unpcbid cr;
2355 socklen_t cr_len = sizeof (cr);
2356
2357 if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
2358 {
2359 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
2360 _dbus_strerror (errno));
2361 }
2362 else if (cr_len != sizeof (cr))
2363 {
2364 _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
2365 cr_len, (int) sizeof (cr));
2366 }
2367 else
2368 {
2369 pid_read = cr.unp_pid;
2370 uid_read = cr.unp_euid;
2371 }
2372#elif defined(HAVE_CMSGCRED)
2373 /* We only check for HAVE_CMSGCRED, but we're really assuming that the
2374 * presence of that struct implies SCM_CREDS. Supported by at least
2375 * FreeBSD and DragonflyBSD.
2376 *
2377 * This mechanism requires the peer to help us (it has to send us a
2378 * SCM_CREDS message) but it does pass the process ID through,
2379 * which makes it better than getpeereid().
2380 */
2381 struct cmsgcred *cred;
2382 struct cmsghdr *cmsgp;
2383
2384 for (cmsgp = CMSG_FIRSTHDR (&msg);
2385 cmsgp != NULL;
2386 cmsgp = CMSG_NXTHDR (&msg, cmsgp))
2387 {
2388 if (cmsgp->cmsg_type == SCM_CREDS &&
2389 cmsgp->cmsg_level == SOL_SOCKET &&
2390 cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
2391 {
2392 cred = (struct cmsgcred *) (void *) CMSG_DATA (cmsgp);
2393 pid_read = cred->cmcred_pid;
2394 uid_read = cred->cmcred_euid;
2395 break;
2396 }
2397 }
2398
2399#elif defined(HAVE_GETPEERUCRED)
2400 /* Supported in at least Solaris >= 10. It should probably be higher
2401 * up this list, because it carries the pid and we use this code path
2402 * for audit data. */
2403 ucred_t * ucred = NULL;
2404 if (getpeerucred (client_fd.fd, &ucred) == 0)
2405 {
2406#ifdef HAVE_ADT
2407 adt_session_data_t *adth = NULL;
2408#endif
2409 pid_read = ucred_getpid (ucred);
2410 uid_read = ucred_geteuid (ucred);
2411#ifdef HAVE_ADT
2412 /* generate audit session data based on socket ucred */
2413 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
2414 {
2415 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
2416 }
2417 else
2418 {
2419 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
2420 {
2421 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
2422 }
2423 else
2424 {
2425 adt_export_data_t *data = NULL;
2426 size_t size = adt_export_session_data (adth, &data);
2427 if (size <= 0)
2428 {
2429 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
2430 }
2431 else
2432 {
2433 _dbus_credentials_add_adt_audit_data (credentials, data, size);
2434 free (data);
2435 }
2436 }
2437 (void) adt_end_session (adth);
2438 }
2439#endif /* HAVE_ADT */
2440 }
2441 else
2442 {
2443 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
2444 }
2445 if (ucred != NULL)
2446 ucred_free (ucred);
2447
2448 /* ----------------------------------------------------------------
2449 * When adding new mechanisms, please add them above this point
2450 * if they support passing the process ID through, or below if not.
2451 * ---------------------------------------------------------------- */
2452
2453#elif defined(HAVE_GETPEEREID)
2454 /* getpeereid() originates from D.J. Bernstein and is fairly
2455 * widely-supported. According to a web search, it might be present in
2456 * any/all of:
2457 *
2458 * - AIX?
2459 * - Blackberry?
2460 * - Cygwin
2461 * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
2462 * - Mac OS X
2463 * - Minix 3.1.8+
2464 * - MirBSD?
2465 * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
2466 * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
2467 * - QNX?
2468 */
2469 uid_t euid;
2470 gid_t egid;
2471 if (getpeereid (client_fd.fd, &euid, &egid) == 0)
2472 {
2473 uid_read = euid;
2474 }
2475 else
2476 {
2477 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
2478 }
2479#else /* no supported mechanism */
2480
2481#warning Socket credentials not supported on this Unix OS
2482#warning Please tell https://gitlab.freedesktop.org/dbus/dbus/-/issues/new
2483
2484 /* Please add other operating systems known to support at least one of
2485 * the mechanisms above to this list, keeping alphabetical order.
2486 * Everything not in this list is best-effort.
2487 */
2488#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
2489 defined(__linux__) || \
2490 defined(__OpenBSD__) || \
2491 defined(__NetBSD__)
2492# error Credentials passing not working on this OS is a regression!
2493#endif
2494
2495 _dbus_verbose ("Socket credentials not supported on this OS\n");
2496#endif
2497 }
2498
2499 _dbus_verbose ("Credentials:"
2500 " pid "DBUS_PID_FORMAT
2501 " uid "DBUS_UID_FORMAT
2502 "\n",
2503 pid_read,
2504 uid_read);
2505
2506 /* Assign this first, so we don't have to close it manually in case one of
2507 * the next steps fails. */
2508 if (pid_fd_read >= 0)
2509 _dbus_credentials_take_pid_fd (credentials, pid_fd_read);
2510
2511 if (pid_read != DBUS_PID_UNSET)
2512 {
2513 if (!_dbus_credentials_add_pid (credentials, pid_read))
2514 {
2515 _DBUS_SET_OOM (error);
2516 return FALSE;
2517 }
2518 }
2519
2520 if (uid_read != DBUS_UID_UNSET)
2521 {
2522 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
2523 {
2524 _DBUS_SET_OOM (error);
2525 return FALSE;
2526 }
2527 }
2528
2529 if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
2530 {
2531 _DBUS_SET_OOM (error);
2532 return FALSE;
2533 }
2534
2535 /* We don't put any groups in the credentials unless we can put them
2536 * all there. */
2537 if (!add_groups_to_credentials (client_fd.fd, credentials, primary_gid_read))
2538 {
2539 _DBUS_SET_OOM (error);
2540 return FALSE;
2541 }
2542
2543 return TRUE;
2544}
2545
2565 DBusError *error)
2566{
2567 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2568
2569 if (write_credentials_byte (server_fd.fd, error))
2570 return TRUE;
2571 else
2572 return FALSE;
2573}
2574
2586{
2587 DBusSocket client_fd;
2588 struct sockaddr addr;
2589 socklen_t addrlen;
2590#ifdef HAVE_ACCEPT4
2591 dbus_bool_t cloexec_done;
2592#endif
2593
2594 addrlen = sizeof (addr);
2595
2596 retry:
2597
2598#ifdef HAVE_ACCEPT4
2599 /*
2600 * At compile-time, we assume that if accept4() is available in
2601 * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
2602 * not necessarily true that either is supported by the running kernel.
2603 */
2604 client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
2605 cloexec_done = client_fd.fd >= 0;
2606
2607 if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
2608#endif
2609 {
2610 client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
2611 }
2612
2613 if (client_fd.fd < 0)
2614 {
2615 if (errno == EINTR)
2616 goto retry;
2617 }
2618
2619 _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
2620
2621#ifdef HAVE_ACCEPT4
2622 if (!cloexec_done)
2623#endif
2624 {
2625 _dbus_fd_set_close_on_exec(client_fd.fd);
2626 }
2627
2628 return client_fd;
2629}
2630
2641{
2642 const char *directory;
2643 struct stat sb;
2644
2645 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2646
2647 directory = _dbus_string_get_const_data (dir);
2648
2649 if (stat (directory, &sb) < 0)
2650 {
2651 dbus_set_error (error, _dbus_error_from_errno (errno),
2652 "%s", _dbus_strerror (errno));
2653
2654 return FALSE;
2655 }
2656
2657 if (sb.st_uid != geteuid ())
2658 {
2660 "%s directory is owned by user %lu, not %lu",
2661 directory,
2662 (unsigned long) sb.st_uid,
2663 (unsigned long) geteuid ());
2664 return FALSE;
2665 }
2666
2667 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2668 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2669 {
2671 "%s directory is not private to the user", directory);
2672 return FALSE;
2673 }
2674
2675 return TRUE;
2676}
2677
2678static dbus_bool_t
2679fill_user_info_from_passwd (struct passwd *p,
2680 DBusUserInfo *info,
2681 DBusError *error)
2682{
2683 _dbus_assert (p->pw_name != NULL);
2684 _dbus_assert (p->pw_dir != NULL);
2685
2686 info->uid = p->pw_uid;
2687 info->primary_gid = p->pw_gid;
2688 info->username = _dbus_strdup (p->pw_name);
2689 info->homedir = _dbus_strdup (p->pw_dir);
2690
2691 if (info->username == NULL ||
2692 info->homedir == NULL)
2693 {
2695 return FALSE;
2696 }
2697
2698 return TRUE;
2699}
2700
2701static dbus_bool_t
2702fill_user_info (DBusUserInfo *info,
2703 dbus_uid_t uid,
2704 const DBusString *username,
2705 DBusError *error)
2706{
2707 const char *username_c;
2708
2709 /* exactly one of username/uid provided */
2710 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2711 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2712
2713 info->uid = DBUS_UID_UNSET;
2715 info->group_ids = NULL;
2716 info->n_group_ids = 0;
2717 info->username = NULL;
2718 info->homedir = NULL;
2719
2720 if (username != NULL)
2721 username_c = _dbus_string_get_const_data (username);
2722 else
2723 username_c = NULL;
2724
2725 /* For now assuming that the getpwnam() and getpwuid() flavors
2726 * are always symmetrical, if not we have to add more configure
2727 * checks
2728 */
2729
2730 {
2731 struct passwd *p;
2732 char *buf = NULL;
2733 int result;
2734#ifdef HAVE_GETPWNAM_R
2735 size_t buflen;
2736 struct passwd p_str;
2737
2738 /* retrieve maximum needed size for buf */
2739 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2740
2741 /* sysconf actually returns a long, but everything else expects size_t,
2742 * so just recast here.
2743 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2744 */
2745 if ((long) buflen <= 0)
2746 buflen = 1024;
2747
2748 result = -1;
2749 while (1)
2750 {
2751 buf = dbus_malloc (buflen);
2752 if (buf == NULL)
2753 {
2755 return FALSE;
2756 }
2757
2758 p = NULL;
2759 if (uid != DBUS_UID_UNSET)
2760 result = getpwuid_r (uid, &p_str, buf, buflen,
2761 &p);
2762 else
2763 result = getpwnam_r (username_c, &p_str, buf, buflen,
2764 &p);
2765 //Try a bigger buffer if ERANGE was returned
2766 if (result == ERANGE && buflen < 512 * 1024)
2767 {
2768 dbus_free (buf);
2769 buflen *= 2;
2770 }
2771 else
2772 {
2773 break;
2774 }
2775 }
2776
2777 /* There are three possibilities:
2778 * - an error: result is a nonzero error code, p should be NULL
2779 * - name or uid not found: result is 0, p is NULL
2780 * - success: result is 0, p should be &p_str
2781 *
2782 * Ensure that in all failure cases, p is set to NULL, matching the
2783 * getpwuid/getpwnam interface. */
2784 if (result != 0 || p != &p_str)
2785 p = NULL;
2786
2787#else /* ! HAVE_GETPWNAM_R */
2788 /* I guess we're screwed on thread safety here */
2789#warning getpwnam_r() not available, please report this to the dbus maintainers with details of your OS
2790
2791 /* It is unspecified whether "failed to find" counts as an error,
2792 * or whether it's reported as p == NULL without touching errno.
2793 * Reset errno so we can distinguish. */
2794 errno = 0;
2795
2796 if (uid != DBUS_UID_UNSET)
2797 p = getpwuid (uid);
2798 else
2799 p = getpwnam (username_c);
2800
2801 /* Always initialized, but only meaningful if p is NULL */
2802 result = errno;
2803#endif /* ! HAVE_GETPWNAM_R */
2804
2805 if (p != NULL)
2806 {
2807 if (!fill_user_info_from_passwd (p, info, error))
2808 {
2809 dbus_free (buf);
2810 return FALSE;
2811 }
2812 dbus_free (buf);
2813 }
2814 else
2815 {
2816 DBusError local_error = DBUS_ERROR_INIT;
2817 const char *error_str;
2818
2819 if (result == 0)
2820 error_str = "not found";
2821 else
2822 error_str = _dbus_strerror (result);
2823
2824 if (uid != DBUS_UID_UNSET)
2825 dbus_set_error (&local_error, _dbus_error_from_errno (result),
2826 "Looking up user ID " DBUS_UID_FORMAT ": %s",
2827 uid, error_str);
2828 else
2829 dbus_set_error (&local_error, _dbus_error_from_errno (result),
2830 "Looking up user \"%s\": %s",
2831 username_c ? username_c : "???", error_str);
2832
2833 _dbus_verbose ("%s", local_error.message);
2834 dbus_move_error (&local_error, error);
2835 dbus_free (buf);
2836 return FALSE;
2837 }
2838 }
2839
2840 /* Fill this in so we can use it to get groups */
2841 username_c = info->username;
2842
2843#ifdef HAVE_GETGROUPLIST
2844 {
2845 gid_t *buf;
2846 int buf_count;
2847 int i;
2848 int initial_buf_count;
2849
2850 initial_buf_count = 17;
2851 buf_count = initial_buf_count;
2852 buf = dbus_new (gid_t, buf_count);
2853 if (buf == NULL)
2854 {
2856 goto failed;
2857 }
2858
2859 if (getgrouplist (username_c,
2860 info->primary_gid,
2861 buf, &buf_count) < 0)
2862 {
2863 gid_t *new;
2864 /* Presumed cause of negative return code: buf has insufficient
2865 entries to hold the entire group list. The Linux behavior in this
2866 case is to pass back the actual number of groups in buf_count, but
2867 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2868 So as a hack, try to help out a bit by guessing a larger
2869 number of groups, within reason.. might still fail, of course,
2870 but we can at least print a more informative message. I looked up
2871 the "right way" to do this by downloading Apple's own source code
2872 for the "id" command, and it turns out that they use an
2873 undocumented library function getgrouplist_2 (!) which is not
2874 declared in any header in /usr/include (!!). That did not seem
2875 like the way to go here.
2876 */
2877 if (buf_count == initial_buf_count)
2878 {
2879 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2880 }
2881 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2882 if (new == NULL)
2883 {
2885 dbus_free (buf);
2886 goto failed;
2887 }
2888
2889 buf = new;
2890
2891 errno = 0;
2892 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2893 {
2894 if (errno == 0)
2895 {
2896 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2897 username_c, buf_count, buf_count);
2898 }
2899 else
2900 {
2901 dbus_set_error (error,
2902 _dbus_error_from_errno (errno),
2903 "Failed to get groups for username \"%s\" primary GID "
2904 DBUS_GID_FORMAT ": %s\n",
2905 username_c, info->primary_gid,
2906 _dbus_strerror (errno));
2907 dbus_free (buf);
2908 goto failed;
2909 }
2910 }
2911 }
2912
2913 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2914 if (info->group_ids == NULL)
2915 {
2917 dbus_free (buf);
2918 goto failed;
2919 }
2920
2921 for (i = 0; i < buf_count; ++i)
2922 info->group_ids[i] = buf[i];
2923
2924 info->n_group_ids = buf_count;
2925
2926 dbus_free (buf);
2927 }
2928#else /* HAVE_GETGROUPLIST */
2929 {
2930 /* We just get the one group ID */
2931 info->group_ids = dbus_new (dbus_gid_t, 1);
2932 if (info->group_ids == NULL)
2933 {
2935 goto failed;
2936 }
2937
2938 info->n_group_ids = 1;
2939
2940 (info->group_ids)[0] = info->primary_gid;
2941 }
2942#endif /* HAVE_GETGROUPLIST */
2943
2944 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2945
2946 return TRUE;
2947
2948 failed:
2949 _DBUS_ASSERT_ERROR_IS_SET (error);
2950 return FALSE;
2951}
2952
2963 const DBusString *username,
2964 DBusError *error)
2965{
2966 return fill_user_info (info, DBUS_UID_UNSET,
2967 username, error);
2968}
2969
2980 dbus_uid_t uid,
2981 DBusError *error)
2982{
2983 return fill_user_info (info, uid,
2984 NULL, error);
2985}
2986
3002{
3003 dbus_pid_t pid = _dbus_getpid ();
3004
3005 /* The POSIX spec certainly doesn't promise this, but
3006 * we need these assertions to fail as soon as we're wrong about
3007 * it so we can do the porting fixups
3008 */
3009 _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
3010 _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
3011 _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
3012
3013#if HAVE_DECL_SYS_PIDFD_OPEN
3014 /* Normally this syscall would have a race condition, but we can trust
3015 * that our own process isn't going to exit, so the pid won't get reused. */
3016 int pid_fd = (int) syscall (SYS_pidfd_open, pid, 0);
3017 if (pid_fd >= 0)
3018 _dbus_credentials_take_pid_fd (credentials, pid_fd);
3019#endif
3020 if (!_dbus_credentials_add_pid (credentials, pid))
3021 return FALSE;
3022 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
3023 return FALSE;
3024
3025 return TRUE;
3026}
3027
3042{
3043#ifdef __linux__
3044 DBusError error = DBUS_ERROR_INIT;
3045 DBusString content = _DBUS_STRING_INIT_INVALID;
3046 DBusString filename = _DBUS_STRING_INIT_INVALID;
3047 dbus_pid_t result = DBUS_PID_UNSET;
3048 int pid_index;
3049
3050 if (pid_fd < 0)
3051 goto out;
3052
3053 if (!_dbus_string_init (&content))
3054 goto out;
3055
3056 if (!_dbus_string_init (&filename))
3057 goto out;
3058
3059 if (!_dbus_string_append_printf (&filename, "/proc/self/fdinfo/%d", pid_fd))
3060 goto out;
3061
3062 if (!_dbus_file_get_contents (&content, &filename, &error))
3063 {
3064 _dbus_verbose ("Cannot read '/proc/self/fdinfo/%d', unable to resolve PID, %s: %s\n",
3065 pid_fd, error.name, error.message);
3066 goto out;
3067 }
3068
3069 /* Ensure we are not reading PPid, either it's the first line of the file or
3070 * there's a newline before it. */
3071 if (!_dbus_string_find (&content, 0, "Pid:", &pid_index) ||
3072 (pid_index > 0 && _dbus_string_get_byte (&content, pid_index - 1) != '\n'))
3073 {
3074 _dbus_verbose ("Cannot find 'Pid:' in '/proc/self/fdinfo/%d', unable to resolve PID\n",
3075 pid_fd);
3076 goto out;
3077 }
3078
3079 if (!_dbus_string_parse_uint (&content, pid_index + strlen ("Pid:"), &result, NULL))
3080 {
3081 _dbus_verbose ("Cannot parse 'Pid:' from '/proc/self/fdinfo/%d', unable to resolve PID\n",
3082 pid_fd);
3083 goto out;
3084 }
3085
3086out:
3087 _dbus_string_free (&content);
3088 _dbus_string_free (&filename);
3089 dbus_error_free (&error);
3090
3091 if (result <= 0)
3092 return DBUS_PID_UNSET;
3093
3094 return result;
3095#else
3096 return DBUS_PID_UNSET;
3097#endif
3098
3099}
3100
3114{
3115 return _dbus_string_append_uint (str,
3116 _dbus_geteuid ());
3117}
3118
3125{
3126 return getpid ();
3127}
3128
3134{
3135 return getuid ();
3136}
3137
3143{
3144 return geteuid ();
3145}
3146
3153unsigned long
3155{
3156 return getpid ();
3157}
3158
3159#if !defined(HAVE_STDATOMIC_H) && !DBUS_USE_SYNC
3160/* To be thread-safe by default on platforms that don't necessarily have
3161 * atomic operations (notably Debian armel, which is armv4t), we must
3162 * use a mutex that can be initialized statically, like this.
3163 * GLib >= 2.32 uses a similar system.
3164 */
3165static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
3166#endif
3167
3176{
3177#ifdef HAVE_STDATOMIC_H
3178 /* Atomic version of "old = *atomic; *atomic += 1; return old" */
3179 return atomic_fetch_add (&atomic->value, 1);
3180#elif DBUS_USE_SYNC
3181 /* Atomic version of "*atomic += 1; return *atomic - 1" */
3182 return __sync_add_and_fetch(&atomic->value, 1)-1;
3183#else
3184 dbus_int32_t res;
3185
3186 pthread_mutex_lock (&atomic_mutex);
3187 res = atomic->value;
3188 atomic->value += 1;
3189 pthread_mutex_unlock (&atomic_mutex);
3190
3191 return res;
3192#endif
3193}
3194
3203{
3204#ifdef HAVE_STDATOMIC_H
3205 /* Atomic version of "old = *atomic; *atomic -= 1; return old" */
3206 return atomic_fetch_sub (&atomic->value, 1);
3207#elif DBUS_USE_SYNC
3208 /* Atomic version of "*atomic -= 1; return *atomic + 1" */
3209 return __sync_sub_and_fetch(&atomic->value, 1)+1;
3210#else
3211 dbus_int32_t res;
3212
3213 pthread_mutex_lock (&atomic_mutex);
3214 res = atomic->value;
3215 atomic->value -= 1;
3216 pthread_mutex_unlock (&atomic_mutex);
3217
3218 return res;
3219#endif
3220}
3221
3231{
3232#ifdef HAVE_STDATOMIC_H
3233 /* Atomic version of "return *atomic" */
3234 return atomic_load (&atomic->value);
3235#elif DBUS_USE_SYNC
3236 __sync_synchronize ();
3237 return atomic->value;
3238#else
3239 dbus_int32_t res;
3240
3241 pthread_mutex_lock (&atomic_mutex);
3242 res = atomic->value;
3243 pthread_mutex_unlock (&atomic_mutex);
3244
3245 return res;
3246#endif
3247}
3248
3254void
3256{
3257#ifdef HAVE_STDATOMIC_H
3258 /* Atomic version of "*atomic = 0" */
3259 atomic_store (&atomic->value, 0);
3260#elif DBUS_USE_SYNC
3261 /* Atomic version of "*atomic &= 0; return *atomic" */
3262 __sync_and_and_fetch (&atomic->value, 0);
3263#else
3264 pthread_mutex_lock (&atomic_mutex);
3265 atomic->value = 0;
3266 pthread_mutex_unlock (&atomic_mutex);
3267#endif
3268}
3269
3275void
3277{
3278#ifdef HAVE_STDATOMIC_H
3279 /* Atomic version of "*atomic = 1" */
3280 atomic_store (&atomic->value, 1);
3281#elif DBUS_USE_SYNC
3282 /* Atomic version of "*atomic |= 1; return *atomic" */
3283 __sync_or_and_fetch (&atomic->value, 1);
3284#else
3285 pthread_mutex_lock (&atomic_mutex);
3286 atomic->value = 1;
3287 pthread_mutex_unlock (&atomic_mutex);
3288#endif
3289}
3290
3299int
3301 int n_fds,
3302 int timeout_milliseconds)
3303{
3304#if defined(HAVE_POLL) && !defined(BROKEN_POLL)
3305 /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
3306 if (timeout_milliseconds < -1)
3307 {
3308 timeout_milliseconds = -1;
3309 }
3310
3311 return poll (fds,
3312 n_fds,
3313 timeout_milliseconds);
3314#else /* ! HAVE_POLL */
3315 /* Emulate poll() in terms of select() */
3316 fd_set read_set, write_set, err_set;
3317 int max_fd = 0;
3318 int i;
3319 struct timeval tv;
3320 int ready;
3321
3322 FD_ZERO (&read_set);
3323 FD_ZERO (&write_set);
3324 FD_ZERO (&err_set);
3325
3326 for (i = 0; i < n_fds; i++)
3327 {
3328 DBusPollFD *fdp = &fds[i];
3329
3330 if (fdp->events & _DBUS_POLLIN)
3331 FD_SET (fdp->fd, &read_set);
3332
3333 if (fdp->events & _DBUS_POLLOUT)
3334 FD_SET (fdp->fd, &write_set);
3335
3336 FD_SET (fdp->fd, &err_set);
3337
3338 max_fd = MAX (max_fd, fdp->fd);
3339 }
3340
3341 tv.tv_sec = timeout_milliseconds / 1000;
3342 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
3343
3344 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
3345 timeout_milliseconds < 0 ? NULL : &tv);
3346
3347 if (ready > 0)
3348 {
3349 for (i = 0; i < n_fds; i++)
3350 {
3351 DBusPollFD *fdp = &fds[i];
3352
3353 fdp->revents = 0;
3354
3355 if (FD_ISSET (fdp->fd, &read_set))
3356 fdp->revents |= _DBUS_POLLIN;
3357
3358 if (FD_ISSET (fdp->fd, &write_set))
3359 fdp->revents |= _DBUS_POLLOUT;
3360
3361 if (FD_ISSET (fdp->fd, &err_set))
3362 fdp->revents |= _DBUS_POLLERR;
3363 }
3364 }
3365
3366 return ready;
3367#endif
3368}
3369
3377void
3379 long *tv_usec)
3380{
3381#ifdef HAVE_MONOTONIC_CLOCK
3382 struct timespec ts;
3383 clock_gettime (CLOCK_MONOTONIC, &ts);
3384
3385 if (tv_sec)
3386 *tv_sec = ts.tv_sec;
3387 if (tv_usec)
3388 *tv_usec = ts.tv_nsec / 1000;
3389#else
3390 struct timeval t;
3391
3392 gettimeofday (&t, NULL);
3393
3394 if (tv_sec)
3395 *tv_sec = t.tv_sec;
3396 if (tv_usec)
3397 *tv_usec = t.tv_usec;
3398#endif
3399}
3400
3408void
3410 long *tv_usec)
3411{
3412 struct timeval t;
3413
3414 gettimeofday (&t, NULL);
3415
3416 if (tv_sec)
3417 *tv_sec = t.tv_sec;
3418 if (tv_usec)
3419 *tv_usec = t.tv_usec;
3420}
3421
3432 DBusError *error)
3433{
3434 const char *filename_c;
3435
3436 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3437
3438 filename_c = _dbus_string_get_const_data (filename);
3439
3440 if (mkdir (filename_c, 0700) < 0)
3441 {
3442 if (errno == EEXIST)
3443 return TRUE;
3444
3446 "Failed to create directory %s: %s\n",
3447 filename_c, _dbus_strerror (errno));
3448 return FALSE;
3449 }
3450 else
3451 return TRUE;
3452}
3453
3464 DBusError *error)
3465{
3466 const char *filename_c;
3467
3468 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3469
3470 filename_c = _dbus_string_get_const_data (filename);
3471
3472 if (mkdir (filename_c, 0700) < 0)
3473 {
3475 "Failed to create directory %s: %s\n",
3476 filename_c, _dbus_strerror (errno));
3477 return FALSE;
3478 }
3479 else
3480 return TRUE;
3481}
3482
3495 const DBusString *next_component)
3496{
3497 dbus_bool_t dir_ends_in_slash;
3498 dbus_bool_t file_starts_with_slash;
3499
3500 if (_dbus_string_get_length (dir) == 0 ||
3501 _dbus_string_get_length (next_component) == 0)
3502 return TRUE;
3503
3504 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
3505 _dbus_string_get_length (dir) - 1);
3506
3507 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
3508
3509 if (dir_ends_in_slash && file_starts_with_slash)
3510 {
3511 _dbus_string_shorten (dir, 1);
3512 }
3513 else if (!(dir_ends_in_slash || file_starts_with_slash))
3514 {
3515 if (!_dbus_string_append_byte (dir, '/'))
3516 return FALSE;
3517 }
3518
3519 return _dbus_string_copy (next_component, 0, dir,
3521}
3522
3524#define NANOSECONDS_PER_SECOND 1000000000
3526#define MICROSECONDS_PER_SECOND 1000000
3528#define MILLISECONDS_PER_SECOND 1000
3530#define NANOSECONDS_PER_MILLISECOND 1000000
3532#define MICROSECONDS_PER_MILLISECOND 1000
3533
3538void
3540{
3541#ifdef HAVE_NANOSLEEP
3542 struct timespec req;
3543 struct timespec rem;
3544
3545 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
3546 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
3547 rem.tv_sec = 0;
3548 rem.tv_nsec = 0;
3549
3550 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
3551 req = rem;
3552#elif defined (HAVE_USLEEP)
3553 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
3554#else /* ! HAVE_USLEEP */
3555 sleep (MAX (milliseconds / 1000, 1));
3556#endif
3557}
3558
3570 int n_bytes,
3571 DBusError *error)
3572{
3573 int old_len = _dbus_string_get_length (str);
3574 int fd;
3575 int result;
3576#ifdef HAVE_GETRANDOM
3577 char *buffer;
3578
3579 if (!_dbus_string_lengthen (str, n_bytes))
3580 {
3581 _DBUS_SET_OOM (error);
3582 return FALSE;
3583 }
3584
3585 buffer = _dbus_string_get_data_len (str, old_len, n_bytes);
3586 result = getrandom (buffer, n_bytes, GRND_NONBLOCK);
3587
3588 if (result == n_bytes)
3589 return TRUE;
3590
3591 _dbus_string_set_length (str, old_len);
3592#endif
3593
3594 /* note, urandom on linux will fall back to pseudorandom */
3595 fd = open ("/dev/urandom", O_RDONLY);
3596
3597 if (fd < 0)
3598 {
3599 dbus_set_error (error, _dbus_error_from_errno (errno),
3600 "Could not open /dev/urandom: %s",
3601 _dbus_strerror (errno));
3602 return FALSE;
3603 }
3604
3605 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
3606
3607 result = _dbus_read (fd, str, n_bytes);
3608
3609 if (result != n_bytes)
3610 {
3611 if (result < 0)
3612 dbus_set_error (error, _dbus_error_from_errno (errno),
3613 "Could not read /dev/urandom: %s",
3614 _dbus_strerror (errno));
3615 else
3617 "Short read from /dev/urandom");
3618
3619 _dbus_close (fd, NULL);
3620 _dbus_string_set_length (str, old_len);
3621 return FALSE;
3622 }
3623
3624 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
3625 n_bytes);
3626
3627 _dbus_close (fd, NULL);
3628
3629 return TRUE;
3630}
3631
3637void
3638_dbus_exit (int code)
3639{
3640 _exit (code);
3641}
3642
3651const char*
3652_dbus_strerror (int error_number)
3653{
3654 const char *msg;
3655
3656 msg = strerror (error_number);
3657 if (msg == NULL)
3658 msg = "unknown";
3659
3660 return msg;
3661}
3662
3666void
3668{
3669 signal (SIGPIPE, SIG_IGN);
3670}
3671
3679void
3681{
3682 int val;
3683
3684 val = fcntl (fd, F_GETFD, 0);
3685
3686 if (val < 0)
3687 return;
3688
3689 val |= FD_CLOEXEC;
3690
3691 fcntl (fd, F_SETFD, val);
3692}
3693
3701void
3703{
3704 int val;
3705
3706 val = fcntl (fd, F_GETFD, 0);
3707
3708 if (val < 0)
3709 return;
3710
3711 val &= ~FD_CLOEXEC;
3712
3713 fcntl (fd, F_SETFD, val);
3714}
3715
3725 DBusError *error)
3726{
3727 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3728
3729 again:
3730 if (close (fd) < 0)
3731 {
3732 if (errno == EINTR)
3733 goto again;
3734
3735 dbus_set_error (error, _dbus_error_from_errno (errno),
3736 "Could not close fd %d", fd);
3737 return FALSE;
3738 }
3739
3740 return TRUE;
3741}
3742
3751int
3753 DBusError *error)
3754{
3755 int new_fd;
3756
3757#ifdef F_DUPFD_CLOEXEC
3758 dbus_bool_t cloexec_done;
3759
3760 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
3761 cloexec_done = new_fd >= 0;
3762
3763 if (new_fd < 0 && errno == EINVAL)
3764#endif
3765 {
3766 new_fd = fcntl(fd, F_DUPFD, 3);
3767 }
3768
3769 if (new_fd < 0) {
3770
3771 dbus_set_error (error, _dbus_error_from_errno (errno),
3772 "Could not duplicate fd %d", fd);
3773 return -1;
3774 }
3775
3776#ifdef F_DUPFD_CLOEXEC
3777 if (!cloexec_done)
3778#endif
3779 {
3781 }
3782
3783 return new_fd;
3784}
3785
3795 DBusError *error)
3796{
3797 return _dbus_set_fd_nonblocking (fd.fd, error);
3798}
3799
3800static dbus_bool_t
3801_dbus_set_fd_nonblocking (int fd,
3802 DBusError *error)
3803{
3804 int val;
3805
3806 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3807
3808 val = fcntl (fd, F_GETFL, 0);
3809 if (val < 0)
3810 {
3811 dbus_set_error (error, _dbus_error_from_errno (errno),
3812 "Failed to get flags from file descriptor %d: %s",
3813 fd, _dbus_strerror (errno));
3814 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
3815 _dbus_strerror (errno));
3816 return FALSE;
3817 }
3818
3819 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
3820 {
3821 dbus_set_error (error, _dbus_error_from_errno (errno),
3822 "Failed to set nonblocking flag of file descriptor %d: %s",
3823 fd, _dbus_strerror (errno));
3824 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3825 fd, _dbus_strerror (errno));
3826
3827 return FALSE;
3828 }
3829
3830 return TRUE;
3831}
3832
3838void
3840{
3841#if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3842 void *bt[500];
3843 int bt_size;
3844 int i;
3845 char **syms;
3846
3847 bt_size = backtrace (bt, 500);
3848
3849 syms = backtrace_symbols (bt, bt_size);
3850
3851 i = 0;
3852 while (i < bt_size)
3853 {
3854 /* don't use dbus_warn since it can _dbus_abort() */
3855 fprintf (stderr, " %s\n", syms[i]);
3856 ++i;
3857 }
3858 fflush (stderr);
3859
3860 free (syms);
3861#elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3862 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3863#else
3864 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3865#endif
3866}
3867
3882 DBusSocket *fd2,
3883 dbus_bool_t blocking,
3884 DBusError *error)
3885{
3886#ifdef HAVE_SOCKETPAIR
3887 int fds[2];
3888 int retval;
3889
3890#ifdef SOCK_CLOEXEC
3891 dbus_bool_t cloexec_done;
3892
3893 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3894 cloexec_done = retval >= 0;
3895
3896 if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
3897#endif
3898 {
3899 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3900 }
3901
3902 if (retval < 0)
3903 {
3904 dbus_set_error (error, _dbus_error_from_errno (errno),
3905 "Could not create full-duplex pipe");
3906 return FALSE;
3907 }
3908
3909 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3910
3911#ifdef SOCK_CLOEXEC
3912 if (!cloexec_done)
3913#endif
3914 {
3917 }
3918
3919 if (!blocking &&
3920 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3921 !_dbus_set_fd_nonblocking (fds[1], NULL)))
3922 {
3923 dbus_set_error (error, _dbus_error_from_errno (errno),
3924 "Could not set full-duplex pipe nonblocking");
3925
3926 _dbus_close (fds[0], NULL);
3927 _dbus_close (fds[1], NULL);
3928
3929 return FALSE;
3930 }
3931
3932 fd1->fd = fds[0];
3933 fd2->fd = fds[1];
3934
3935 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3936 fd1->fd, fd2->fd);
3937
3938 return TRUE;
3939#else
3940 _dbus_warn ("_dbus_socketpair() not implemented on this OS");
3942 "_dbus_socketpair() not implemented on this OS");
3943 return FALSE;
3944#endif
3945}
3946
3955int
3957 va_list args)
3958{
3959 char static_buf[1024];
3960 int bufsize = sizeof (static_buf);
3961 int len;
3962 va_list args_copy;
3963
3964 va_copy (args_copy, args);
3965 len = vsnprintf (static_buf, bufsize, format, args_copy);
3966 va_end (args_copy);
3967
3968 /* If vsnprintf() returned non-negative, then either the string fits in
3969 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3970 * returns the number of characters that were needed, or this OS returns the
3971 * truncated length.
3972 *
3973 * We ignore the possibility that snprintf might just ignore the length and
3974 * overrun the buffer (64-bit Solaris 7), because that's pathological.
3975 * If your libc is really that bad, come back when you have a better one. */
3976 if (len == bufsize)
3977 {
3978 /* This could be the truncated length (Tru64 and IRIX have this bug),
3979 * or the real length could be coincidentally the same. Which is it?
3980 * If vsnprintf returns the truncated length, we'll go to the slow
3981 * path. */
3982 va_copy (args_copy, args);
3983
3984 if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3985 len = -1;
3986
3987 va_end (args_copy);
3988 }
3989
3990 /* If vsnprintf() returned negative, we have to do more work.
3991 * HP-UX returns negative. */
3992 while (len < 0)
3993 {
3994 char *buf;
3995
3996 bufsize *= 2;
3997
3998 buf = dbus_malloc (bufsize);
3999
4000 if (buf == NULL)
4001 return -1;
4002
4003 va_copy (args_copy, args);
4004 len = vsnprintf (buf, bufsize, format, args_copy);
4005 va_end (args_copy);
4006
4007 dbus_free (buf);
4008
4009 /* If the reported length is exactly the buffer size, round up to the
4010 * next size, in case vsnprintf has been returning the truncated
4011 * length */
4012 if (len == bufsize)
4013 len = -1;
4014 }
4015
4016 return len;
4017}
4018
4025const char*
4027{
4028 /* Protected by _DBUS_LOCK_sysdeps */
4029 static const char* tmpdir = NULL;
4030
4031 if (!_DBUS_LOCK (sysdeps))
4032 return NULL;
4033
4034 if (tmpdir == NULL)
4035 {
4036 /* TMPDIR is what glibc uses, then
4037 * glibc falls back to the P_tmpdir macro which
4038 * just expands to "/tmp"
4039 */
4040 if (tmpdir == NULL)
4041 tmpdir = getenv("TMPDIR");
4042
4043 /* These two env variables are probably
4044 * broken, but maybe some OS uses them?
4045 */
4046 if (tmpdir == NULL)
4047 tmpdir = getenv("TMP");
4048 if (tmpdir == NULL)
4049 tmpdir = getenv("TEMP");
4050
4051 /* And this is the sane fallback. */
4052 if (tmpdir == NULL)
4053 tmpdir = "/tmp";
4054 }
4055
4056 _DBUS_UNLOCK (sysdeps);
4057
4058 _dbus_assert(tmpdir != NULL);
4059
4060 return tmpdir;
4061}
4062
4063#if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
4083static dbus_bool_t
4084_read_subprocess_line_argv (const char *progpath,
4085 dbus_bool_t path_fallback,
4086 const char * const *argv,
4087 DBusString *result,
4088 DBusError *error)
4089{
4090 int result_pipe[2] = { -1, -1 };
4091 int errors_pipe[2] = { -1, -1 };
4092 pid_t pid;
4093 int ret;
4094 int status;
4095 int orig_len;
4096
4097 dbus_bool_t retval;
4098 sigset_t new_set, old_set;
4099
4100 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4101 retval = FALSE;
4102
4103 /* We need to block any existing handlers for SIGCHLD temporarily; they
4104 * will cause waitpid() below to fail.
4105 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
4106 */
4107 sigemptyset (&new_set);
4108 sigaddset (&new_set, SIGCHLD);
4109 sigprocmask (SIG_BLOCK, &new_set, &old_set);
4110
4111 orig_len = _dbus_string_get_length (result);
4112
4113#define READ_END 0
4114#define WRITE_END 1
4115 if (pipe (result_pipe) < 0)
4116 {
4117 dbus_set_error (error, _dbus_error_from_errno (errno),
4118 "Failed to create a pipe to call %s: %s",
4119 progpath, _dbus_strerror (errno));
4120 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
4121 progpath, _dbus_strerror (errno));
4122 goto out;
4123 }
4124 if (pipe (errors_pipe) < 0)
4125 {
4126 dbus_set_error (error, _dbus_error_from_errno (errno),
4127 "Failed to create a pipe to call %s: %s",
4128 progpath, _dbus_strerror (errno));
4129 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
4130 progpath, _dbus_strerror (errno));
4131 goto out;
4132 }
4133
4134 /* Make sure our output buffers aren't redundantly printed by both the
4135 * parent and the child */
4136 fflush (stdout);
4137 fflush (stderr);
4138
4139 pid = fork ();
4140 if (pid < 0)
4141 {
4142 dbus_set_error (error, _dbus_error_from_errno (errno),
4143 "Failed to fork() to call %s: %s",
4144 progpath, _dbus_strerror (errno));
4145 _dbus_verbose ("Failed to fork() to call %s: %s\n",
4146 progpath, _dbus_strerror (errno));
4147 goto out;
4148 }
4149
4150 if (pid == 0)
4151 {
4152 /* child process */
4153 const char *error_str;
4154
4155 if (!_dbus_ensure_standard_fds (DBUS_FORCE_STDIN_NULL, &error_str))
4156 {
4157 int saved_errno = errno;
4158
4159 /* Try to write details into the pipe, but don't bother
4160 * trying too hard (no retry loop). */
4161
4162 if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0 ||
4163 write (errors_pipe[WRITE_END], ": ", 2) < 0)
4164 {
4165 /* ignore, not much we can do */
4166 }
4167
4168 error_str = _dbus_strerror (saved_errno);
4169
4170 if (write (errors_pipe[WRITE_END], error_str, strlen (error_str)) < 0)
4171 {
4172 /* ignore, not much we can do */
4173 }
4174
4175 _exit (1);
4176 }
4177
4178 /* set-up stdXXX */
4179 close (result_pipe[READ_END]);
4180 close (errors_pipe[READ_END]);
4181
4182 if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
4183 _exit (1);
4184 if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
4185 _exit (1);
4186
4187 _dbus_close_all ();
4188
4189 sigprocmask (SIG_SETMASK, &old_set, NULL);
4190
4191 /* If it looks fully-qualified, try execv first */
4192 if (progpath[0] == '/')
4193 {
4194 execv (progpath, (char * const *) argv);
4195 /* Ok, that failed. Now if path_fallback is given, let's
4196 * try unqualified. This is mostly a hack to work
4197 * around systems which ship dbus-launch in /usr/bin
4198 * but everything else in /bin (because dbus-launch
4199 * depends on X11).
4200 */
4201 if (path_fallback)
4202 /* We must have a slash, because we checked above */
4203 execvp (strrchr (progpath, '/')+1, (char * const *) argv);
4204 }
4205 else
4206 execvp (progpath, (char * const *) argv);
4207
4208 /* still nothing, we failed */
4209 _exit (1);
4210 }
4211
4212 /* parent process */
4213 close (result_pipe[WRITE_END]);
4214 close (errors_pipe[WRITE_END]);
4215 result_pipe[WRITE_END] = -1;
4216 errors_pipe[WRITE_END] = -1;
4217
4218 ret = 0;
4219 do
4220 {
4221 ret = _dbus_read (result_pipe[READ_END], result, 1024);
4222 }
4223 while (ret > 0);
4224
4225 /* reap the child process to avoid it lingering as zombie */
4226 do
4227 {
4228 ret = waitpid (pid, &status, 0);
4229 }
4230 while (ret == -1 && errno == EINTR);
4231
4232 /* We succeeded if the process exited with status 0 and
4233 anything was read */
4234 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
4235 {
4236 /* The process ended with error */
4237 DBusString error_message;
4238 if (!_dbus_string_init (&error_message))
4239 {
4240 _DBUS_SET_OOM (error);
4241 goto out;
4242 }
4243
4244 ret = 0;
4245 do
4246 {
4247 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
4248 }
4249 while (ret > 0);
4250
4251 _dbus_string_set_length (result, orig_len);
4252 if (_dbus_string_get_length (&error_message) > 0)
4254 "%s terminated abnormally with the following error: %s",
4255 progpath, _dbus_string_get_data (&error_message));
4256 else
4258 "%s terminated abnormally without any error message",
4259 progpath);
4260 goto out;
4261 }
4262
4263 retval = TRUE;
4264
4265 out:
4266 sigprocmask (SIG_SETMASK, &old_set, NULL);
4267
4268 _DBUS_ASSERT_ERROR_XOR_BOOL (error, retval);
4269
4270 if (result_pipe[0] != -1)
4271 close (result_pipe[0]);
4272 if (result_pipe[1] != -1)
4273 close (result_pipe[1]);
4274 if (errors_pipe[0] != -1)
4275 close (errors_pipe[0]);
4276 if (errors_pipe[1] != -1)
4277 close (errors_pipe[1]);
4278
4279 return retval;
4280}
4281#endif
4282
4297 DBusString *address,
4298 DBusError *error)
4299{
4300#ifdef DBUS_ENABLE_X11_AUTOLAUNCH
4301 static const char arg_dbus_launch[] = "dbus-launch";
4302 static const char arg_autolaunch[] = "--autolaunch";
4303 static const char arg_binary_syntax[] = "--binary-syntax";
4304 static const char arg_close_stderr[] = "--close-stderr";
4305
4306 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
4307 * but that's done elsewhere, and if it worked, this function wouldn't
4308 * be called.) */
4309 const char *display;
4310 const char *progpath;
4311 const char *argv[6];
4312 int i;
4313 DBusString uuid;
4314 dbus_bool_t retval;
4315
4316 if (_dbus_check_setuid ())
4317 {
4319 "Unable to autolaunch when setuid");
4320 return FALSE;
4321 }
4322
4323 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4324 retval = FALSE;
4325
4326 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
4327 * dbus-launch-x11 is just going to fail. Rather than trying to
4328 * run it, we might as well bail out early with a nice error.
4329 *
4330 * This is not strictly true in a world where the user bus exists,
4331 * because dbus-launch --autolaunch knows how to connect to that -
4332 * but if we were going to connect to the user bus, we'd have done
4333 * so before trying autolaunch: in any case. */
4334 display = _dbus_getenv ("DISPLAY");
4335
4336 if (display == NULL || display[0] == '\0')
4337 {
4339 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
4340 return FALSE;
4341 }
4342
4343 if (!_dbus_string_init (&uuid))
4344 {
4345 _DBUS_SET_OOM (error);
4346 return FALSE;
4347 }
4348
4349 if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
4350 {
4351 goto out;
4352 }
4353
4354#ifdef DBUS_ENABLE_EMBEDDED_TESTS
4355 progpath = _dbus_getenv ("DBUS_TEST_DBUS_LAUNCH");
4356
4357 if (progpath == NULL)
4358#endif
4359 progpath = DBUS_BINDIR "/dbus-launch";
4360 /*
4361 * argv[0] is always dbus-launch, that's the name what we'll
4362 * get from /proc, or ps(1), regardless what the progpath is,
4363 * see fd.o#69716
4364 */
4365 i = 0;
4366 argv[i] = arg_dbus_launch;
4367 ++i;
4368 argv[i] = arg_autolaunch;
4369 ++i;
4370 argv[i] = _dbus_string_get_data (&uuid);
4371 ++i;
4372 argv[i] = arg_binary_syntax;
4373 ++i;
4374 argv[i] = arg_close_stderr;
4375 ++i;
4376 argv[i] = NULL;
4377 ++i;
4378
4379 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4380
4381 retval = _read_subprocess_line_argv (progpath,
4382 TRUE,
4383 argv, address, error);
4384
4385 out:
4386 _dbus_string_free (&uuid);
4387 return retval;
4388#else
4390 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
4391 "set your DBUS_SESSION_BUS_ADDRESS instead");
4392 return FALSE;
4393#endif
4394}
4395
4416 dbus_bool_t create_if_not_found,
4417 DBusError *error)
4418{
4419 DBusError our_error = DBUS_ERROR_INIT;
4420 DBusError etc_error = DBUS_ERROR_INIT;
4421 DBusString filename;
4422 dbus_bool_t b;
4423
4424 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4425
4426 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &our_error);
4427 if (b)
4428 return TRUE;
4429
4430 /* Fallback to the system machine ID */
4431 _dbus_string_init_const (&filename, "/etc/machine-id");
4432 b = _dbus_read_uuid_file (&filename, machine_id, FALSE, &etc_error);
4433
4434 if (b)
4435 {
4436 if (create_if_not_found)
4437 {
4438 /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
4439 * complain if that isn't possible for whatever reason */
4440 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4441 _dbus_write_uuid_file (&filename, machine_id, NULL);
4442 }
4443
4444 dbus_error_free (&our_error);
4445 return TRUE;
4446 }
4447
4448 if (!create_if_not_found)
4449 {
4450 dbus_set_error (error, etc_error.name,
4451 "D-Bus library appears to be incorrectly set up: "
4452 "see the manual page for dbus-uuidgen to correct "
4453 "this issue. (%s; %s)",
4454 our_error.message, etc_error.message);
4455 dbus_error_free (&our_error);
4456 dbus_error_free (&etc_error);
4457 return FALSE;
4458 }
4459
4460 dbus_error_free (&our_error);
4461 dbus_error_free (&etc_error);
4462
4463 /* if none found, try to make a new one */
4464 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
4465
4466 if (!_dbus_generate_uuid (machine_id, error))
4467 return FALSE;
4468
4469 return _dbus_write_uuid_file (&filename, machine_id, error);
4470}
4471
4481 const char *launchd_env_var,
4482 DBusError *error)
4483{
4484#ifdef DBUS_ENABLE_LAUNCHD
4485 char *argv[4];
4486 int i;
4487
4488 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4489
4490 if (_dbus_check_setuid ())
4491 {
4493 "Unable to find launchd socket when setuid");
4494 return FALSE;
4495 }
4496
4497 i = 0;
4498 argv[i] = "launchctl";
4499 ++i;
4500 argv[i] = "getenv";
4501 ++i;
4502 argv[i] = (char*)launchd_env_var;
4503 ++i;
4504 argv[i] = NULL;
4505 ++i;
4506
4507 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
4508
4509 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
4510 {
4511 return FALSE;
4512 }
4513
4514 /* no error, but no result either */
4515 if (_dbus_string_get_length(socket_path) == 0)
4516 {
4517 return FALSE;
4518 }
4519
4520 /* strip the carriage-return */
4521 _dbus_string_shorten(socket_path, 1);
4522 return TRUE;
4523#else /* DBUS_ENABLE_LAUNCHD */
4525 "can't lookup socket from launchd; launchd support not compiled in");
4526 return FALSE;
4527#endif
4528}
4529
4530#ifdef DBUS_ENABLE_LAUNCHD
4531static dbus_bool_t
4532_dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
4533{
4534 dbus_bool_t valid_socket;
4535 DBusString socket_path;
4536
4537 if (_dbus_check_setuid ())
4538 {
4540 "Unable to find launchd socket when setuid");
4541 return FALSE;
4542 }
4543
4544 if (!_dbus_string_init (&socket_path))
4545 {
4546 _DBUS_SET_OOM (error);
4547 return FALSE;
4548 }
4549
4550 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
4551
4552 if (dbus_error_is_set(error))
4553 {
4554 _dbus_string_free(&socket_path);
4555 return FALSE;
4556 }
4557
4558 if (!valid_socket)
4559 {
4560 dbus_set_error(error, "no socket path",
4561 "launchd did not provide a socket path, "
4562 "verify that org.freedesktop.dbus-session.plist is loaded!");
4563 _dbus_string_free(&socket_path);
4564 return FALSE;
4565 }
4566 if (!_dbus_string_append (address, "unix:path="))
4567 {
4568 _DBUS_SET_OOM (error);
4569 _dbus_string_free(&socket_path);
4570 return FALSE;
4571 }
4572 if (!_dbus_string_copy (&socket_path, 0, address,
4573 _dbus_string_get_length (address)))
4574 {
4575 _DBUS_SET_OOM (error);
4576 _dbus_string_free(&socket_path);
4577 return FALSE;
4578 }
4579
4580 _dbus_string_free(&socket_path);
4581 return TRUE;
4582}
4583#endif
4584
4585static dbus_bool_t
4586_dbus_lookup_user_bus (dbus_bool_t *supported,
4587 DBusString *address,
4588 DBusError *error)
4589{
4590 const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
4591 dbus_bool_t ret = FALSE;
4592 struct stat stbuf;
4593 DBusString user_bus_path;
4594
4595 if (runtime_dir == NULL)
4596 {
4597 _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
4598 *supported = FALSE;
4599 return TRUE; /* Cannot use it, but not an error */
4600 }
4601
4602 if (!_dbus_string_init (&user_bus_path))
4603 {
4604 _DBUS_SET_OOM (error);
4605 return FALSE;
4606 }
4607
4608 if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
4609 {
4610 _DBUS_SET_OOM (error);
4611 goto out;
4612 }
4613
4614 if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
4615 {
4616 _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
4617 _dbus_strerror (errno));
4618 *supported = FALSE;
4619 ret = TRUE; /* Cannot use it, but not an error */
4620 goto out;
4621 }
4622
4623 if (stbuf.st_uid != getuid ())
4624 {
4625 _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
4626 (long) stbuf.st_uid, (long) getuid ());
4627 *supported = FALSE;
4628 ret = TRUE; /* Cannot use it, but not an error */
4629 goto out;
4630 }
4631
4632 if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
4633 {
4634 _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
4635 (long) stbuf.st_mode);
4636 *supported = FALSE;
4637 ret = TRUE; /* Cannot use it, but not an error */
4638 goto out;
4639 }
4640
4641 if (!_dbus_string_append (address, "unix:path=") ||
4642 !_dbus_address_append_escaped (address, &user_bus_path))
4643 {
4644 _DBUS_SET_OOM (error);
4645 goto out;
4646 }
4647
4648 *supported = TRUE;
4649 ret = TRUE;
4650
4651out:
4652 _dbus_string_free (&user_bus_path);
4653 return ret;
4654}
4655
4677 DBusString *address,
4678 DBusError *error)
4679{
4680#ifdef DBUS_ENABLE_LAUNCHD
4681 *supported = TRUE;
4682 return _dbus_lookup_session_address_launchd (address, error);
4683#else
4684 *supported = FALSE;
4685
4686 if (!_dbus_lookup_user_bus (supported, address, error))
4687 return FALSE;
4688 else if (*supported)
4689 return TRUE;
4690
4691 /* On non-Mac Unix platforms, if the session address isn't already
4692 * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
4693 * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
4694 * autolaunch: global default; see init_session_address in
4695 * dbus/dbus-bus.c. */
4696 return TRUE;
4697#endif
4698}
4699
4707void
4709{
4711}
4712
4728 DBusCredentials *credentials)
4729{
4730 DBusString homedir;
4731 DBusString dotdir;
4732 dbus_uid_t uid;
4733
4734 _dbus_assert (credentials != NULL);
4736
4737 if (!_dbus_string_init (&homedir))
4738 return FALSE;
4739
4740 uid = _dbus_credentials_get_unix_uid (credentials);
4742
4743 if (!_dbus_homedir_from_uid (uid, &homedir))
4744 goto failed;
4745
4746#ifdef DBUS_ENABLE_EMBEDDED_TESTS
4747 {
4748 const char *override;
4749
4750 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
4751 if (override != NULL && *override != '\0')
4752 {
4753 _dbus_string_set_length (&homedir, 0);
4754 if (!_dbus_string_append (&homedir, override))
4755 goto failed;
4756
4757 _dbus_verbose ("Using fake homedir for testing: %s\n",
4758 _dbus_string_get_const_data (&homedir));
4759 }
4760 else
4761 {
4762 /* Not strictly thread-safe, but if we fail at thread-safety here,
4763 * the worst that will happen is some extra warnings. */
4764 static dbus_bool_t already_warned = FALSE;
4765 if (!already_warned)
4766 {
4767 _dbus_warn ("Using %s for testing, set DBUS_TEST_HOMEDIR to avoid",
4768 _dbus_string_get_const_data (&homedir));
4769 already_warned = TRUE;
4770 }
4771 }
4772 }
4773#endif
4774
4775 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
4776 if (!_dbus_concat_dir_and_file (&homedir,
4777 &dotdir))
4778 goto failed;
4779
4780 if (!_dbus_string_copy (&homedir, 0,
4781 directory, _dbus_string_get_length (directory))) {
4782 goto failed;
4783 }
4784
4785 _dbus_string_free (&homedir);
4786 return TRUE;
4787
4788 failed:
4789 _dbus_string_free (&homedir);
4790 return FALSE;
4791}
4792
4793/* Documented in dbus-sysdeps-win.c, does nothing on Unix */
4795_dbus_daemon_unpublish_session_bus_address (void)
4796{
4797 return TRUE;
4798}
4799
4808{
4809 /* Avoid the -Wlogical-op GCC warning, which can be triggered when EAGAIN and
4810 * EWOULDBLOCK are numerically equal, which is permitted as described by
4811 * errno(3).
4812 */
4813#if EAGAIN == EWOULDBLOCK
4814 return e == EAGAIN;
4815#else
4816 return e == EAGAIN || e == EWOULDBLOCK;
4817#endif
4818}
4819
4829 DBusError *error)
4830{
4831 const char *filename_c;
4832
4833 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4834
4835 filename_c = _dbus_string_get_const_data (filename);
4836
4837 if (rmdir (filename_c) != 0)
4838 {
4840 "Failed to remove directory %s: %s\n",
4841 filename_c, _dbus_strerror (errno));
4842 return FALSE;
4843 }
4844
4845 return TRUE;
4846}
4847
4857{
4858#ifdef SCM_RIGHTS
4859 union {
4860 struct sockaddr sa;
4861 struct sockaddr_storage storage;
4862 struct sockaddr_un un;
4863 } sa_buf;
4864
4865 socklen_t sa_len = sizeof(sa_buf);
4866
4867 _DBUS_ZERO(sa_buf);
4868
4869 if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
4870 return FALSE;
4871
4872 return sa_buf.sa.sa_family == AF_UNIX;
4873
4874#else
4875 return FALSE;
4876
4877#endif
4878}
4879
4880/*
4881 * Similar to Solaris fdwalk(3), but without the ability to stop iteration,
4882 * and may call func for integers that are not actually valid fds.
4883 */
4884static void
4885act_on_fds_3_and_up (void (*func) (int fd))
4886{
4887 int maxfds, i;
4888
4889#if defined(__linux__) && defined(__GLIBC__)
4890 DIR *d;
4891
4892 /* On Linux we can optimize this a bit if /proc is available. If it
4893 isn't available, fall back to the brute force way. */
4894
4895 d = opendir ("/proc/self/fd");
4896 if (d)
4897 {
4898 for (;;)
4899 {
4900 struct dirent *de;
4901 int fd;
4902 long l;
4903 char *e = NULL;
4904
4905 de = readdir (d);
4906 if (!de)
4907 break;
4908
4909 if (de->d_name[0] == '.')
4910 continue;
4911
4912 errno = 0;
4913 l = strtol (de->d_name, &e, 10);
4914 if (errno != 0 || e == NULL || *e != '\0')
4915 continue;
4916
4917 fd = (int) l;
4918 if (fd < 3)
4919 continue;
4920
4921 if (fd == dirfd (d))
4922 continue;
4923
4924 func (fd);
4925 }
4926
4927 closedir (d);
4928 return;
4929 }
4930#endif
4931
4932 maxfds = sysconf (_SC_OPEN_MAX);
4933
4934 /* Pick something reasonable if for some reason sysconf says
4935 * unlimited.
4936 */
4937 if (maxfds < 0)
4938 maxfds = 1024;
4939
4940 /* close all inherited fds */
4941 for (i = 3; i < maxfds; i++)
4942 func (i);
4943}
4944
4945/* Some library implementations of closefrom() are not async-signal-safe,
4946 * and we call _dbus_close_all() after forking, so we only do this on
4947 * operating systems where we know that closefrom() is a system call */
4948#if defined(HAVE_CLOSEFROM) && ( \
4949 defined(__FreeBSD__) || \
4950 defined(__NetBSD__) || \
4951 defined(__OpenBSD__) || \
4952 defined(__sun__) && defined(F_CLOSEFROM) \
4953)
4954#define CLOSEFROM_SIGNAL_SAFE 1
4955#else
4956#define CLOSEFROM_SIGNAL_SAFE 0
4957static void
4958close_ignore_error (int fd)
4959{
4960 close (fd);
4961}
4962#endif
4963
4968void
4970{
4971#ifdef HAVE_CLOSE_RANGE
4972 if (close_range (3, INT_MAX, 0) == 0)
4973 return;
4974#endif
4975
4976#if CLOSEFROM_SIGNAL_SAFE
4977 closefrom (3);
4978#else
4979 act_on_fds_3_and_up (close_ignore_error);
4980#endif
4981}
4982
4987void
4989{
4990#if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC)
4991 if (close_range (3, INT_MAX, CLOSE_RANGE_CLOEXEC) == 0)
4992 return;
4993#endif
4994
4995 act_on_fds_3_and_up (_dbus_fd_set_close_on_exec);
4996}
4997
5009{
5010 /* TODO: get __libc_enable_secure exported from glibc.
5011 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
5012 */
5013#if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
5014 {
5015 /* See glibc/include/unistd.h */
5016 extern int __libc_enable_secure;
5017 return __libc_enable_secure;
5018 }
5019#elif defined(HAVE_ISSETUGID)
5020 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
5021 return issetugid ();
5022#else
5023 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
5024 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
5025
5026 /* We call into this function from _dbus_threads_init_platform_specific()
5027 * to make sure these are initialized before we start threading. */
5028 static dbus_bool_t check_setuid_initialised;
5029 static dbus_bool_t is_setuid;
5030
5031 if (_DBUS_UNLIKELY (!check_setuid_initialised))
5032 {
5033#ifdef HAVE_GETRESUID
5034 if (getresuid (&ruid, &euid, &suid) != 0 ||
5035 getresgid (&rgid, &egid, &sgid) != 0)
5036#endif /* HAVE_GETRESUID */
5037 {
5038 suid = ruid = getuid ();
5039 sgid = rgid = getgid ();
5040 euid = geteuid ();
5041 egid = getegid ();
5042 }
5043
5044 check_setuid_initialised = TRUE;
5045 is_setuid = (ruid != euid || ruid != suid ||
5046 rgid != egid || rgid != sgid);
5047
5048 }
5049 return is_setuid;
5050#endif
5051}
5052
5062 DBusString *address,
5063 DBusError *error)
5064{
5065 union {
5066 struct sockaddr sa;
5067 struct sockaddr_storage storage;
5068 struct sockaddr_un un;
5069 struct sockaddr_in ipv4;
5070 struct sockaddr_in6 ipv6;
5071 } socket;
5072 char hostip[INET6_ADDRSTRLEN];
5073 socklen_t size = sizeof (socket);
5074 DBusString path_str;
5075 const char *family_name = NULL;
5076 dbus_uint16_t port;
5077
5078 if (getsockname (fd.fd, &socket.sa, &size))
5079 goto err;
5080
5081 switch (socket.sa.sa_family)
5082 {
5083 case AF_UNIX:
5084 if (socket.un.sun_path[0]=='\0')
5085 {
5086 _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
5087 if (_dbus_string_append (address, "unix:abstract=") &&
5088 _dbus_address_append_escaped (address, &path_str))
5089 {
5090 return TRUE;
5091 }
5092 else
5093 {
5094 _DBUS_SET_OOM (error);
5095 return FALSE;
5096 }
5097 }
5098 else
5099 {
5100 _dbus_string_init_const (&path_str, socket.un.sun_path);
5101 if (_dbus_string_append (address, "unix:path=") &&
5102 _dbus_address_append_escaped (address, &path_str))
5103 {
5104 return TRUE;
5105 }
5106 else
5107 {
5108 _DBUS_SET_OOM (error);
5109 return FALSE;
5110 }
5111 }
5112 /* not reached */
5113 break;
5114
5115 case AF_INET:
5116#ifdef AF_INET6
5117 case AF_INET6:
5118#endif
5119 _dbus_string_init_const (&path_str, hostip);
5120
5121 if (_dbus_inet_sockaddr_to_string (&socket, size, hostip, sizeof (hostip),
5122 &family_name, &port, error))
5123 {
5124 if (_dbus_string_append_printf (address, "tcp:family=%s,port=%u,host=",
5125 family_name, port) &&
5126 _dbus_address_append_escaped (address, &path_str))
5127 {
5128 return TRUE;
5129 }
5130 else
5131 {
5132 _DBUS_SET_OOM (error);
5133 return FALSE;
5134 }
5135 }
5136 else
5137 {
5138 return FALSE;
5139 }
5140 /* not reached */
5141 break;
5142
5143 default:
5144 dbus_set_error (error,
5145 _dbus_error_from_errno (EINVAL),
5146 "Failed to read address from socket: Unknown socket type.");
5147 return FALSE;
5148 }
5149 err:
5150 dbus_set_error (error,
5151 _dbus_error_from_errno (errno),
5152 "Failed to read address from socket: %s",
5153 _dbus_strerror (errno));
5154 return FALSE;
5155}
5156
5157int
5158_dbus_save_socket_errno (void)
5159{
5160 return errno;
5161}
5162
5163void
5164_dbus_restore_socket_errno (int saved_errno)
5165{
5166 errno = saved_errno;
5167}
5168
5169static const char *syslog_tag = "dbus";
5170#ifdef HAVE_SYSLOG_H
5171static DBusLogFlags log_flags = DBUS_LOG_FLAGS_STDERR;
5172#endif
5173
5188void
5189_dbus_init_system_log (const char *tag,
5190 DBusLogFlags flags)
5191{
5192 /* We never want to turn off logging completely */
5193 _dbus_assert (
5194 (flags & (DBUS_LOG_FLAGS_STDERR | DBUS_LOG_FLAGS_SYSTEM_LOG)) != 0);
5195
5196 syslog_tag = tag;
5197
5198#ifdef HAVE_SYSLOG_H
5199 log_flags = flags;
5200
5201 if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5202 openlog (tag, LOG_PID, LOG_DAEMON);
5203#endif
5204}
5205
5213void
5214_dbus_logv (DBusSystemLogSeverity severity,
5215 const char *msg,
5216 va_list args)
5217{
5218 va_list tmp;
5219#ifdef HAVE_SYSLOG_H
5220 if (log_flags & DBUS_LOG_FLAGS_SYSTEM_LOG)
5221 {
5222 int flags;
5223 switch (severity)
5224 {
5225 case DBUS_SYSTEM_LOG_INFO:
5226 flags = LOG_DAEMON | LOG_INFO;
5227 break;
5228 case DBUS_SYSTEM_LOG_WARNING:
5229 flags = LOG_DAEMON | LOG_WARNING;
5230 break;
5231 case DBUS_SYSTEM_LOG_SECURITY:
5232 flags = LOG_AUTH | LOG_NOTICE;
5233 break;
5234 case DBUS_SYSTEM_LOG_ERROR:
5235 flags = LOG_DAEMON|LOG_CRIT;
5236 break;
5237 default:
5238 _dbus_assert_not_reached ("invalid log severity");
5239 }
5240
5241 va_copy (tmp, args);
5242 vsyslog (flags, msg, tmp);
5243 va_end (tmp);
5244 }
5245
5246 /* If we don't have syslog.h, we always behave as though stderr was in
5247 * the flags */
5248 if (log_flags & DBUS_LOG_FLAGS_STDERR)
5249#endif
5250 {
5251 va_copy (tmp, args);
5252 fprintf (stderr, "%s[" DBUS_PID_FORMAT "]: ", syslog_tag, _dbus_getpid ());
5253 vfprintf (stderr, msg, tmp);
5254 fputc ('\n', stderr);
5255 va_end (tmp);
5256 }
5257}
5258
5259/*
5260 * Return the low-level representation of a socket error, as used by
5261 * cross-platform socket APIs like inet_ntop(), send() and recv(). This
5262 * is the standard errno on Unix, but is WSAGetLastError() on Windows.
5263 *
5264 * Some libdbus internal functions copy this into errno, but with
5265 * hindsight that was probably a design flaw.
5266 */
5267int
5268_dbus_get_low_level_socket_errno (void)
5269{
5270 return errno;
5271}
5272
5273/* 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:109
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_GNUC_NORETURN void _dbus_credentials_take_pid_fd(DBusCredentials *credentials, int pid_fd)
Add a UNIX process ID FD to the credentials.
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:64
void dbus_move_error(DBusError *src, DBusError *dest)
Moves an error src into dest, freeing src and overwriting dest.
Definition: dbus-errors.c:281
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:245
void dbus_error_init(DBusError *error)
Initializes a DBusError structure.
Definition: dbus-errors.c:190
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:356
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:213
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:331
dbus_bool_t _dbus_file_get_contents(DBusString *str, const DBusString *filename, DBusError *error)
Appends the contents of the given file to the string, returning error code.
#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:601
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:396
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:466
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:679
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:273
#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:694
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:594
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:59
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:60
void * dbus_malloc(size_t bytes)
Allocates the given number of bytes, as with standard malloc().
Definition: dbus-memory.c:454
#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:847
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:980
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:182
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:197
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:1345
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:139
dbus_bool_t _dbus_string_find(const DBusString *str, int start, const char *substr, int *found)
Finds the given substring in the string, returning TRUE and filling in the byte index where the subst...
Definition: dbus-string.c:1666
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:535
char * _dbus_string_get_data(DBusString *str)
Gets the raw character buffer from the string.
Definition: dbus-string.c:496
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:278
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:825
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_string_parse_uint(const DBusString *str, int start, unsigned long *value_return, int *end_return)
Parses an unsigned integer contained in a DBusString.
Definition: dbus-sysdeps.c:485
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:805
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:784
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:403
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:1190
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:1147
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:559
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:513
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:607
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:448
unsigned long dbus_uid_t
A user ID.
Definition: dbus-sysdeps.h:141
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:139
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:450
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:143
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:148
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:146
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition: dbus-sysdeps.c:197
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:150
dbus_pid_t _dbus_resolve_pid_fd(int pid_fd)
Resolve the PID from the PID FD, if any.
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:444
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:157
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:155
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:764
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:153
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:37
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:340
volatile dbus_int32_t value
Value of the atomic integer.
Definition: dbus-sysdeps.h:346
Object representing an exception.
Definition: dbus-errors.h:51
const char * name
public error name field
Definition: dbus-errors.h:52
const char * message
public error message field
Definition: dbus-errors.h:53
A node in a linked list.
Definition: dbus-list.h:37
short events
Events to poll for.
Definition: dbus-sysdeps.h:439
short revents
Events that occurred.
Definition: dbus-sysdeps.h:440
DBusPollable fd
File descriptor.
Definition: dbus-sysdeps.h:438
Socket interface.
Definition: dbus-sysdeps.h:185
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...