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)
4 * Copyright (C) 2002, 2003, 2006 Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
7 * Licensed under the Academic Free License version 2.1
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "dbus-internals.h"
28 #include "dbus-sysdeps.h"
29 #include "dbus-sysdeps-unix.h"
30 #include "dbus-threads.h"
31 #include "dbus-protocol.h"
32 #include "dbus-transport.h"
33 #include "dbus-string.h"
34 #include "dbus-userdb.h"
35 #include "dbus-list.h"
36 #include "dbus-credentials.h"
37 #include "dbus-nonce.h"
39 #include <sys/types.h>
46 #include <sys/socket.h>
55 #include <netinet/in.h>
71 #ifdef HAVE_GETPEERUCRED
79 #include "sd-daemon.h"
86 #define AI_ADDRCONFIG 0
89 #ifndef HAVE_SOCKLEN_T
94 _dbus_open_socket (int *fd_p,
101 dbus_bool_t cloexec_done;
103 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
104 cloexec_done = *fd_p >= 0;
106 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
107 if (*fd_p < 0 && errno == EINVAL)
110 *fd_p = socket (domain, type, protocol);
119 _dbus_fd_set_close_on_exec(*fd_p);
122 _dbus_verbose ("socket fd %d opened\n", *fd_p);
127 dbus_set_error(error,
128 _dbus_error_from_errno (errno),
129 "Failed to open socket: %s",
130 _dbus_strerror (errno));
136 _dbus_open_tcp_socket (int *fd,
139 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
143 * Opens a UNIX domain socket (as in the socket() call).
144 * Does not bind the socket.
146 * This will set FD_CLOEXEC for the socket returned
148 * @param fd return location for socket descriptor
149 * @param error return location for an error
150 * @returns #FALSE if error is set
153 _dbus_open_unix_socket (int *fd,
156 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
160 * Closes a socket. Should not be used on non-socket
161 * file descriptors or handles.
163 * @param fd the socket
164 * @param error return location for an error
165 * @returns #FALSE if error is set
168 _dbus_close_socket (int fd,
171 return _dbus_close (fd, error);
175 * Like _dbus_read(), but only works on sockets so is
176 * available on Windows.
178 * @param fd the socket
179 * @param buffer string to append data to
180 * @param count max amount of data to read
181 * @returns number of bytes appended to the string
184 _dbus_read_socket (int fd,
188 return _dbus_read (fd, buffer, count);
192 * Like _dbus_write(), but only supports sockets
193 * and is thus available on Windows.
195 * @param fd the file descriptor to write
196 * @param buffer the buffer to write data from
197 * @param start the first byte in the buffer to write
198 * @param len the number of bytes to try to write
199 * @returns the number of bytes written or -1 on error
202 _dbus_write_socket (int fd,
203 const DBusString *buffer,
207 #if HAVE_DECL_MSG_NOSIGNAL
211 data = _dbus_string_get_const_data_len (buffer, start, len);
215 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
217 if (bytes_written < 0 && errno == EINTR)
220 return bytes_written;
223 return _dbus_write (fd, buffer, start, len);
228 * Like _dbus_read_socket() but also tries to read unix fds from the
229 * socket. When there are more fds to read than space in the array
230 * passed this function will fail with ENOSPC.
232 * @param fd the socket
233 * @param buffer string to append data to
234 * @param count max amount of data to read
235 * @param fds array to place read file descriptors in
236 * @param n_fds on input space in fds array, on output how many fds actually got read
237 * @returns number of bytes appended to string
240 _dbus_read_socket_with_unix_fds (int fd,
245 #ifndef HAVE_UNIX_FD_PASSING
248 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
260 _dbus_assert (count >= 0);
261 _dbus_assert (*n_fds >= 0);
263 start = _dbus_string_get_length (buffer);
265 if (!_dbus_string_lengthen (buffer, count))
272 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
279 /* Hmm, we have no clue how long the control data will actually be
280 that is queued for us. The least we can do is assume that the
281 caller knows. Hence let's make space for the number of fds that
282 we shall read at max plus the cmsg header. */
283 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
285 /* It's probably safe to assume that systems with SCM_RIGHTS also
287 m.msg_control = alloca(m.msg_controllen);
288 memset(m.msg_control, 0, m.msg_controllen);
292 bytes_read = recvmsg(fd, &m, 0
293 #ifdef MSG_CMSG_CLOEXEC
304 /* put length back (note that this doesn't actually realloc anything) */
305 _dbus_string_set_length (buffer, start);
312 dbus_bool_t found = FALSE;
314 if (m.msg_flags & MSG_CTRUNC)
316 /* Hmm, apparently the control data was truncated. The bad
317 thing is that we might have completely lost a couple of fds
318 without chance to recover them. Hence let's treat this as a
322 _dbus_string_set_length (buffer, start);
326 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
327 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
331 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
332 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
334 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
337 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
338 worked, hence we need to go through this list and set
339 CLOEXEC everywhere in any case */
340 for (i = 0; i < *n_fds; i++)
341 _dbus_fd_set_close_on_exec(fds[i]);
349 /* put length back (doesn't actually realloc) */
350 _dbus_string_set_length (buffer, start + bytes_read);
354 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
363 _dbus_write_socket_with_unix_fds(int fd,
364 const DBusString *buffer,
370 #ifndef HAVE_UNIX_FD_PASSING
377 return _dbus_write_socket(fd, buffer, start, len);
379 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
384 _dbus_write_socket_with_unix_fds_two(int fd,
385 const DBusString *buffer1,
388 const DBusString *buffer2,
394 #ifndef HAVE_UNIX_FD_PASSING
401 return _dbus_write_socket_two(fd,
402 buffer1, start1, len1,
403 buffer2, start2, len2);
411 _dbus_assert (len1 >= 0);
412 _dbus_assert (len2 >= 0);
413 _dbus_assert (n_fds >= 0);
416 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
417 iov[0].iov_len = len1;
421 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
422 iov[1].iov_len = len2;
427 m.msg_iovlen = buffer2 ? 2 : 1;
431 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
432 m.msg_control = alloca(m.msg_controllen);
433 memset(m.msg_control, 0, m.msg_controllen);
435 cm = CMSG_FIRSTHDR(&m);
436 cm->cmsg_level = SOL_SOCKET;
437 cm->cmsg_type = SCM_RIGHTS;
438 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
439 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
444 bytes_written = sendmsg (fd, &m, 0
445 #if HAVE_DECL_MSG_NOSIGNAL
450 if (bytes_written < 0 && errno == EINTR)
454 if (bytes_written > 0)
455 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
458 return bytes_written;
463 * Like _dbus_write_two() but only works on sockets and is thus
464 * available on Windows.
466 * @param fd the file descriptor
467 * @param buffer1 first buffer
468 * @param start1 first byte to write in first buffer
469 * @param len1 number of bytes to write from first buffer
470 * @param buffer2 second buffer, or #NULL
471 * @param start2 first byte to write in second buffer
472 * @param len2 number of bytes to write in second buffer
473 * @returns total bytes written from both buffers, or -1 on error
476 _dbus_write_socket_two (int fd,
477 const DBusString *buffer1,
480 const DBusString *buffer2,
484 #if HAVE_DECL_MSG_NOSIGNAL
485 struct iovec vectors[2];
491 _dbus_assert (buffer1 != NULL);
492 _dbus_assert (start1 >= 0);
493 _dbus_assert (start2 >= 0);
494 _dbus_assert (len1 >= 0);
495 _dbus_assert (len2 >= 0);
497 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
500 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
508 vectors[0].iov_base = (char*) data1;
509 vectors[0].iov_len = len1;
510 vectors[1].iov_base = (char*) data2;
511 vectors[1].iov_len = len2;
515 m.msg_iovlen = data2 ? 2 : 1;
519 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
521 if (bytes_written < 0 && errno == EINTR)
524 return bytes_written;
527 return _dbus_write_two (fd, buffer1, start1, len1,
528 buffer2, start2, len2);
533 _dbus_socket_is_invalid (int fd)
535 return fd < 0 ? TRUE : FALSE;
539 * Thin wrapper around the read() system call that appends
540 * the data it reads to the DBusString buffer. It appends
541 * up to the given count, and returns the same value
542 * and same errno as read(). The only exception is that
543 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
544 * return ENOMEM, even though regular UNIX read doesn't.
546 * Unlike _dbus_read_socket(), _dbus_read() is not available
549 * @param fd the file descriptor to read from
550 * @param buffer the buffer to append data to
551 * @param count the amount of data to read
552 * @returns the number of bytes read or -1
563 _dbus_assert (count >= 0);
565 start = _dbus_string_get_length (buffer);
567 if (!_dbus_string_lengthen (buffer, count))
573 data = _dbus_string_get_data_len (buffer, start, count);
577 bytes_read = read (fd, data, count);
585 /* put length back (note that this doesn't actually realloc anything) */
586 _dbus_string_set_length (buffer, start);
592 /* put length back (doesn't actually realloc) */
593 _dbus_string_set_length (buffer, start + bytes_read);
597 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
605 * Thin wrapper around the write() system call that writes a part of a
606 * DBusString and handles EINTR for you.
608 * @param fd the file descriptor to write
609 * @param buffer the buffer to write data from
610 * @param start the first byte in the buffer to write
611 * @param len the number of bytes to try to write
612 * @returns the number of bytes written or -1 on error
616 const DBusString *buffer,
623 data = _dbus_string_get_const_data_len (buffer, start, len);
627 bytes_written = write (fd, data, len);
629 if (bytes_written < 0 && errno == EINTR)
633 if (bytes_written > 0)
634 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
637 return bytes_written;
641 * Like _dbus_write() but will use writev() if possible
642 * to write both buffers in sequence. The return value
643 * is the number of bytes written in the first buffer,
644 * plus the number written in the second. If the first
645 * buffer is written successfully and an error occurs
646 * writing the second, the number of bytes in the first
647 * is returned (i.e. the error is ignored), on systems that
648 * don't have writev. Handles EINTR for you.
649 * The second buffer may be #NULL.
651 * @param fd the file descriptor
652 * @param buffer1 first buffer
653 * @param start1 first byte to write in first buffer
654 * @param len1 number of bytes to write from first buffer
655 * @param buffer2 second buffer, or #NULL
656 * @param start2 first byte to write in second buffer
657 * @param len2 number of bytes to write in second buffer
658 * @returns total bytes written from both buffers, or -1 on error
661 _dbus_write_two (int fd,
662 const DBusString *buffer1,
665 const DBusString *buffer2,
669 _dbus_assert (buffer1 != NULL);
670 _dbus_assert (start1 >= 0);
671 _dbus_assert (start2 >= 0);
672 _dbus_assert (len1 >= 0);
673 _dbus_assert (len2 >= 0);
677 struct iovec vectors[2];
682 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
685 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
693 vectors[0].iov_base = (char*) data1;
694 vectors[0].iov_len = len1;
695 vectors[1].iov_base = (char*) data2;
696 vectors[1].iov_len = len2;
700 bytes_written = writev (fd,
704 if (bytes_written < 0 && errno == EINTR)
707 return bytes_written;
709 #else /* HAVE_WRITEV */
713 ret1 = _dbus_write (fd, buffer1, start1, len1);
714 if (ret1 == len1 && buffer2 != NULL)
716 ret2 = _dbus_write (fd, buffer2, start2, len2);
718 ret2 = 0; /* we can't report an error as the first write was OK */
725 #endif /* !HAVE_WRITEV */
728 #define _DBUS_MAX_SUN_PATH_LENGTH 99
731 * @def _DBUS_MAX_SUN_PATH_LENGTH
733 * Maximum length of the path to a UNIX domain socket,
734 * sockaddr_un::sun_path member. POSIX requires that all systems
735 * support at least 100 bytes here, including the nul termination.
736 * We use 99 for the max value to allow for the nul.
738 * We could probably also do sizeof (addr.sun_path)
739 * but this way we are the same on all platforms
740 * which is probably a good idea.
744 * Creates a socket and connects it to the UNIX domain socket at the
745 * given path. The connection fd is returned, and is set up as
748 * Uses abstract sockets instead of filesystem-linked sockets if
749 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
750 * On non-Linux abstract socket usage always fails.
752 * This will set FD_CLOEXEC for the socket returned.
754 * @param path the path to UNIX domain socket
755 * @param abstract #TRUE to use abstract namespace
756 * @param error return location for error code
757 * @returns connection file descriptor or -1 on error
760 _dbus_connect_unix_socket (const char *path,
761 dbus_bool_t abstract,
766 struct sockaddr_un addr;
768 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
770 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
774 if (!_dbus_open_unix_socket (&fd, error))
776 _DBUS_ASSERT_ERROR_IS_SET(error);
779 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
782 addr.sun_family = AF_UNIX;
783 path_len = strlen (path);
787 #ifdef HAVE_ABSTRACT_SOCKETS
788 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
789 path_len++; /* Account for the extra nul byte added to the start of sun_path */
791 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
793 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
794 "Abstract socket name too long\n");
795 _dbus_close (fd, NULL);
799 strncpy (&addr.sun_path[1], path, path_len);
800 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
801 #else /* HAVE_ABSTRACT_SOCKETS */
802 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
803 "Operating system does not support abstract socket namespace\n");
804 _dbus_close (fd, NULL);
806 #endif /* ! HAVE_ABSTRACT_SOCKETS */
810 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
812 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
813 "Socket name too long\n");
814 _dbus_close (fd, NULL);
818 strncpy (addr.sun_path, path, path_len);
821 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
823 dbus_set_error (error,
824 _dbus_error_from_errno (errno),
825 "Failed to connect to socket %s: %s",
826 path, _dbus_strerror (errno));
828 _dbus_close (fd, NULL);
832 if (!_dbus_set_fd_nonblocking (fd, error))
834 _DBUS_ASSERT_ERROR_IS_SET (error);
836 _dbus_close (fd, NULL);
844 * Enables or disables the reception of credentials on the given socket during
845 * the next message transmission. This is only effective if the #LOCAL_CREDS
846 * system feature exists, in which case the other side of the connection does
847 * not have to do anything special to send the credentials.
849 * @param fd socket on which to change the #LOCAL_CREDS flag.
850 * @param on whether to enable or disable the #LOCAL_CREDS flag.
853 _dbus_set_local_creds (int fd, dbus_bool_t on)
855 dbus_bool_t retval = TRUE;
857 #if defined(HAVE_CMSGCRED)
858 /* NOOP just to make sure only one codepath is used
859 * and to prefer CMSGCRED
861 #elif defined(LOCAL_CREDS)
862 int val = on ? 1 : 0;
863 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
865 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
869 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
870 on ? "enabled" : "disabled", fd);
877 * Creates a socket and binds it to the given path,
878 * then listens on the socket. The socket is
879 * set to be nonblocking.
881 * Uses abstract sockets instead of filesystem-linked
882 * sockets if requested (it's possible only on Linux;
883 * see "man 7 unix" on Linux).
884 * On non-Linux abstract socket usage always fails.
886 * This will set FD_CLOEXEC for the socket returned
888 * @param path the socket name
889 * @param abstract #TRUE to use abstract namespace
890 * @param error return location for errors
891 * @returns the listening file descriptor or -1 on error
894 _dbus_listen_unix_socket (const char *path,
895 dbus_bool_t abstract,
899 struct sockaddr_un addr;
901 unsigned int reuseaddr;
903 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
905 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
908 if (!_dbus_open_unix_socket (&listen_fd, error))
910 _DBUS_ASSERT_ERROR_IS_SET(error);
913 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
916 addr.sun_family = AF_UNIX;
917 path_len = strlen (path);
921 #ifdef HAVE_ABSTRACT_SOCKETS
922 /* remember that abstract names aren't nul-terminated so we rely
923 * on sun_path being filled in with zeroes above.
925 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
926 path_len++; /* Account for the extra nul byte added to the start of sun_path */
928 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
930 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
931 "Abstract socket name too long\n");
932 _dbus_close (listen_fd, NULL);
936 strncpy (&addr.sun_path[1], path, path_len);
937 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
938 #else /* HAVE_ABSTRACT_SOCKETS */
939 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
940 "Operating system does not support abstract socket namespace\n");
941 _dbus_close (listen_fd, NULL);
943 #endif /* ! HAVE_ABSTRACT_SOCKETS */
947 /* Discussed security implications of this with Nalin,
948 * and we couldn't think of where it would kick our ass, but
949 * it still seems a bit sucky. It also has non-security suckage;
950 * really we'd prefer to exit if the socket is already in use.
951 * But there doesn't seem to be a good way to do this.
953 * Just to be extra careful, I threw in the stat() - clearly
954 * the stat() can't *fix* any security issue, but it at least
955 * avoids inadvertent/accidental data loss.
960 if (stat (path, &sb) == 0 &&
961 S_ISSOCK (sb.st_mode))
965 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
967 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
968 "Abstract socket name too long\n");
969 _dbus_close (listen_fd, NULL);
973 strncpy (addr.sun_path, path, path_len);
977 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
979 _dbus_warn ("Failed to set socket option\"%s\": %s",
980 path, _dbus_strerror (errno));
983 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
985 dbus_set_error (error, _dbus_error_from_errno (errno),
986 "Failed to bind socket \"%s\": %s",
987 path, _dbus_strerror (errno));
988 _dbus_close (listen_fd, NULL);
992 if (listen (listen_fd, 30 /* backlog */) < 0)
994 dbus_set_error (error, _dbus_error_from_errno (errno),
995 "Failed to listen on socket \"%s\": %s",
996 path, _dbus_strerror (errno));
997 _dbus_close (listen_fd, NULL);
1001 if (!_dbus_set_local_creds (listen_fd, TRUE))
1003 dbus_set_error (error, _dbus_error_from_errno (errno),
1004 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1005 path, _dbus_strerror (errno));
1010 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1012 _DBUS_ASSERT_ERROR_IS_SET (error);
1013 _dbus_close (listen_fd, NULL);
1017 /* Try opening up the permissions, but if we can't, just go ahead
1018 * and continue, maybe it will be good enough.
1020 if (!abstract && chmod (path, 0777) < 0)
1021 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1028 * Acquires one or more sockets passed in from systemd. The sockets
1029 * are set to be nonblocking.
1031 * This will set FD_CLOEXEC for the sockets returned.
1033 * @oaram fds the file descriptors
1034 * @param error return location for errors
1035 * @returns the number of file descriptors
1038 _dbus_listen_systemd_sockets (int **fds,
1045 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1047 n = sd_listen_fds (TRUE);
1050 dbus_set_error (error, _dbus_error_from_errno (-n),
1051 "Failed to acquire systemd socket: %s",
1052 _dbus_strerror (-n));
1058 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1059 "No socket received.");
1063 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1065 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1068 dbus_set_error (error, _dbus_error_from_errno (-r),
1069 "Failed to verify systemd socket type: %s",
1070 _dbus_strerror (-r));
1076 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1077 "Passed socket has wrong type.");
1082 /* OK, the file descriptors are all good, so let's take posession of
1085 new_fds = dbus_new (int, n);
1088 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1089 "Failed to allocate file handle array.");
1093 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1095 if (!_dbus_set_local_creds (fd, TRUE))
1097 dbus_set_error (error, _dbus_error_from_errno (errno),
1098 "Failed to enable LOCAL_CREDS on systemd socket: %s",
1099 _dbus_strerror (errno));
1103 if (!_dbus_set_fd_nonblocking (fd, error))
1105 _DBUS_ASSERT_ERROR_IS_SET (error);
1109 new_fds[fd - SD_LISTEN_FDS_START] = fd;
1117 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1119 _dbus_close (fd, NULL);
1122 dbus_free (new_fds);
1127 * Creates a socket and connects to a socket at the given host
1128 * and port. The connection fd is returned, and is set up as
1131 * This will set FD_CLOEXEC for the socket returned
1133 * @param host the host name to connect to
1134 * @param port the port to connect to
1135 * @param family the address family to listen on, NULL for all
1136 * @param error return location for error code
1137 * @returns connection file descriptor or -1 on error
1140 _dbus_connect_tcp_socket (const char *host,
1145 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1149 _dbus_connect_tcp_socket_with_nonce (const char *host,
1152 const char *noncefile,
1155 int saved_errno = 0;
1157 struct addrinfo hints;
1158 struct addrinfo *ai, *tmp;
1160 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1165 hints.ai_family = AF_UNSPEC;
1166 else if (!strcmp(family, "ipv4"))
1167 hints.ai_family = AF_INET;
1168 else if (!strcmp(family, "ipv6"))
1169 hints.ai_family = AF_INET6;
1172 dbus_set_error (error,
1173 DBUS_ERROR_BAD_ADDRESS,
1174 "Unknown address family %s", family);
1177 hints.ai_protocol = IPPROTO_TCP;
1178 hints.ai_socktype = SOCK_STREAM;
1179 hints.ai_flags = AI_ADDRCONFIG;
1181 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1183 dbus_set_error (error,
1184 _dbus_error_from_errno (errno),
1185 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1186 host, port, gai_strerror(res), res);
1187 _dbus_close (fd, NULL);
1194 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1197 _DBUS_ASSERT_ERROR_IS_SET(error);
1200 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1202 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1204 saved_errno = errno;
1205 _dbus_close(fd, NULL);
1217 dbus_set_error (error,
1218 _dbus_error_from_errno (saved_errno),
1219 "Failed to connect to socket \"%s:%s\" %s",
1220 host, port, _dbus_strerror(saved_errno));
1224 if (noncefile != NULL)
1226 DBusString noncefileStr;
1228 _dbus_string_init_const (&noncefileStr, noncefile);
1229 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1230 _dbus_string_free (&noncefileStr);
1234 _dbus_close (fd, NULL);
1239 if (!_dbus_set_fd_nonblocking (fd, error))
1241 _dbus_close (fd, NULL);
1249 * Creates a socket and binds it to the given path, then listens on
1250 * the socket. The socket is set to be nonblocking. In case of port=0
1251 * a random free port is used and returned in the port parameter.
1252 * If inaddr_any is specified, the hostname is ignored.
1254 * This will set FD_CLOEXEC for the socket returned
1256 * @param host the host name to listen on
1257 * @param port the port to listen on, if zero a free port will be used
1258 * @param family the address family to listen on, NULL for all
1259 * @param retport string to return the actual port listened on
1260 * @param fds_p location to store returned file descriptors
1261 * @param error return location for errors
1262 * @returns the number of listening file descriptors or -1 on error
1265 _dbus_listen_tcp_socket (const char *host,
1268 DBusString *retport,
1273 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1274 struct addrinfo hints;
1275 struct addrinfo *ai, *tmp;
1276 unsigned int reuseaddr;
1279 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1284 hints.ai_family = AF_UNSPEC;
1285 else if (!strcmp(family, "ipv4"))
1286 hints.ai_family = AF_INET;
1287 else if (!strcmp(family, "ipv6"))
1288 hints.ai_family = AF_INET6;
1291 dbus_set_error (error,
1292 DBUS_ERROR_BAD_ADDRESS,
1293 "Unknown address family %s", family);
1297 hints.ai_protocol = IPPROTO_TCP;
1298 hints.ai_socktype = SOCK_STREAM;
1299 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1301 redo_lookup_with_port:
1302 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1304 dbus_set_error (error,
1305 _dbus_error_from_errno (errno),
1306 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1307 host ? host : "*", port, gai_strerror(res), res);
1314 int fd = -1, *newlisten_fd;
1315 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1317 _DBUS_ASSERT_ERROR_IS_SET(error);
1320 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1323 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1325 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1326 host ? host : "*", port, _dbus_strerror (errno));
1329 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1331 saved_errno = errno;
1332 _dbus_close(fd, NULL);
1333 if (saved_errno == EADDRINUSE)
1335 /* Depending on kernel policy, it may or may not
1336 be neccessary to bind to both IPv4 & 6 addresses
1337 so ignore EADDRINUSE here */
1341 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1342 "Failed to bind socket \"%s:%s\": %s",
1343 host ? host : "*", port, _dbus_strerror (saved_errno));
1347 if (listen (fd, 30 /* backlog */) < 0)
1349 saved_errno = errno;
1350 _dbus_close (fd, NULL);
1351 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1352 "Failed to listen on socket \"%s:%s\": %s",
1353 host ? host : "*", port, _dbus_strerror (saved_errno));
1357 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1360 saved_errno = errno;
1361 _dbus_close (fd, NULL);
1362 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1363 "Failed to allocate file handle array: %s",
1364 _dbus_strerror (saved_errno));
1367 listen_fd = newlisten_fd;
1368 listen_fd[nlisten_fd] = fd;
1371 if (!_dbus_string_get_length(retport))
1373 /* If the user didn't specify a port, or used 0, then
1374 the kernel chooses a port. After the first address
1375 is bound to, we need to force all remaining addresses
1376 to use the same port */
1377 if (!port || !strcmp(port, "0"))
1380 struct sockaddr_storage addr;
1384 addrlen = sizeof(addr);
1385 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1388 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1389 portbuf, sizeof(portbuf),
1390 NI_NUMERICHOST)) != 0)
1392 dbus_set_error (error, _dbus_error_from_errno (errno),
1393 "Failed to resolve port \"%s:%s\": %s (%s)",
1394 host ? host : "*", port, gai_strerror(res), res);
1397 if (!_dbus_string_append(retport, portbuf))
1399 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1403 /* Release current address list & redo lookup */
1404 port = _dbus_string_get_const_data(retport);
1406 goto redo_lookup_with_port;
1410 if (!_dbus_string_append(retport, port))
1412 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1426 dbus_set_error (error, _dbus_error_from_errno (errno),
1427 "Failed to bind socket \"%s:%s\": %s",
1428 host ? host : "*", port, _dbus_strerror (errno));
1432 for (i = 0 ; i < nlisten_fd ; i++)
1434 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1447 for (i = 0 ; i < nlisten_fd ; i++)
1448 _dbus_close(listen_fd[i], NULL);
1449 dbus_free(listen_fd);
1454 write_credentials_byte (int server_fd,
1458 char buf[1] = { '\0' };
1459 #if defined(HAVE_CMSGCRED)
1462 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1473 msg.msg_control = (caddr_t) &cmsg;
1474 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1476 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1477 cmsg.hdr.cmsg_level = SOL_SOCKET;
1478 cmsg.hdr.cmsg_type = SCM_CREDS;
1481 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1485 #if defined(HAVE_CMSGCRED)
1486 bytes_written = sendmsg (server_fd, &msg, 0
1487 #if HAVE_DECL_MSG_NOSIGNAL
1492 bytes_written = send (server_fd, buf, 1, 0
1493 #if HAVE_DECL_MSG_NOSIGNAL
1499 if (bytes_written < 0 && errno == EINTR)
1502 if (bytes_written < 0)
1504 dbus_set_error (error, _dbus_error_from_errno (errno),
1505 "Failed to write credentials byte: %s",
1506 _dbus_strerror (errno));
1509 else if (bytes_written == 0)
1511 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1512 "wrote zero bytes writing credentials byte");
1517 _dbus_assert (bytes_written == 1);
1518 _dbus_verbose ("wrote credentials byte\n");
1524 * Reads a single byte which must be nul (an error occurs otherwise),
1525 * and reads unix credentials if available. Clears the credentials
1526 * object, then adds pid/uid if available, so any previous credentials
1527 * stored in the object are lost.
1529 * Return value indicates whether a byte was read, not whether
1530 * we got valid credentials. On some systems, such as Linux,
1531 * reading/writing the byte isn't actually required, but we do it
1532 * anyway just to avoid multiple codepaths.
1534 * Fails if no byte is available, so you must select() first.
1536 * The point of the byte is that on some systems we have to
1537 * use sendmsg()/recvmsg() to transmit credentials.
1539 * @param client_fd the client file descriptor
1540 * @param credentials object to add client credentials to
1541 * @param error location to store error code
1542 * @returns #TRUE on success
1545 _dbus_read_credentials_socket (int client_fd,
1546 DBusCredentials *credentials,
1552 dbus_uid_t uid_read;
1553 dbus_pid_t pid_read;
1556 #ifdef HAVE_CMSGCRED
1559 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1562 #elif defined(LOCAL_CREDS)
1565 struct sockcred cred;
1569 uid_read = DBUS_UID_UNSET;
1570 pid_read = DBUS_PID_UNSET;
1572 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1574 /* The POSIX spec certainly doesn't promise this, but
1575 * we need these assertions to fail as soon as we're wrong about
1576 * it so we can do the porting fixups
1578 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1579 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1580 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1582 _dbus_credentials_clear (credentials);
1584 /* Systems supporting LOCAL_CREDS are configured to have this feature
1585 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1586 * the connection. Therefore, the received message must carry the
1587 * credentials information without doing anything special.
1590 iov.iov_base = &buf;
1597 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1599 msg.msg_control = (caddr_t) &cmsg;
1600 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1604 bytes_read = recvmsg (client_fd, &msg, 0);
1611 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1612 * normally only call read_credentials if the socket was ready
1616 dbus_set_error (error, _dbus_error_from_errno (errno),
1617 "Failed to read credentials byte: %s",
1618 _dbus_strerror (errno));
1621 else if (bytes_read == 0)
1623 /* this should not happen unless we are using recvmsg wrong,
1624 * so is essentially here for paranoia
1626 dbus_set_error (error, DBUS_ERROR_FAILED,
1627 "Failed to read credentials byte (zero-length read)");
1630 else if (buf != '\0')
1632 dbus_set_error (error, DBUS_ERROR_FAILED,
1633 "Credentials byte was not nul");
1637 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1638 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1639 || cmsg.hdr.cmsg_type != SCM_CREDS)
1641 dbus_set_error (error, DBUS_ERROR_FAILED,
1642 "Message from recvmsg() was not SCM_CREDS");
1647 _dbus_verbose ("read credentials byte\n");
1652 struct sockpeercred cr;
1656 int cr_len = sizeof (cr);
1658 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1659 cr_len == sizeof (cr))
1666 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1667 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1669 #elif defined(HAVE_CMSGCRED)
1670 struct cmsgcred *cred;
1672 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1673 pid_read = cred->cmcred_pid;
1674 uid_read = cred->cmcred_euid;
1675 #elif defined(LOCAL_CREDS)
1676 pid_read = DBUS_PID_UNSET;
1677 uid_read = cmsg.cred.sc_uid;
1678 /* Since we have already got the credentials from this socket, we can
1679 * disable its LOCAL_CREDS flag if it was ever set. */
1680 _dbus_set_local_creds (client_fd, FALSE);
1681 #elif defined(HAVE_GETPEEREID)
1684 if (getpeereid (client_fd, &euid, &egid) == 0)
1690 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1692 #elif defined(HAVE_GETPEERUCRED)
1693 ucred_t * ucred = NULL;
1694 if (getpeerucred (client_fd, &ucred) == 0)
1696 pid_read = ucred_getpid (ucred);
1697 uid_read = ucred_geteuid (ucred);
1699 /* generate audit session data based on socket ucred */
1700 adt_session_data_t *adth = NULL;
1701 adt_export_data_t *data = NULL;
1703 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1705 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1709 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1711 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1715 size = adt_export_session_data (adth, &data);
1718 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1722 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1726 (void) adt_end_session (adth);
1728 #endif /* HAVE_ADT */
1732 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1736 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1737 _dbus_verbose ("Socket credentials not supported on this OS\n");
1741 _dbus_verbose ("Credentials:"
1742 " pid "DBUS_PID_FORMAT
1743 " uid "DBUS_UID_FORMAT
1748 if (pid_read != DBUS_PID_UNSET)
1750 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1752 _DBUS_SET_OOM (error);
1757 if (uid_read != DBUS_UID_UNSET)
1759 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1761 _DBUS_SET_OOM (error);
1770 * Sends a single nul byte with our UNIX credentials as ancillary
1771 * data. Returns #TRUE if the data was successfully written. On
1772 * systems that don't support sending credentials, just writes a byte,
1773 * doesn't send any credentials. On some systems, such as Linux,
1774 * reading/writing the byte isn't actually required, but we do it
1775 * anyway just to avoid multiple codepaths.
1777 * Fails if no byte can be written, so you must select() first.
1779 * The point of the byte is that on some systems we have to
1780 * use sendmsg()/recvmsg() to transmit credentials.
1782 * @param server_fd file descriptor for connection to server
1783 * @param error return location for error code
1784 * @returns #TRUE if the byte was sent
1787 _dbus_send_credentials_socket (int server_fd,
1790 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1792 if (write_credentials_byte (server_fd, error))
1799 * Accepts a connection on a listening socket.
1800 * Handles EINTR for you.
1802 * This will enable FD_CLOEXEC for the returned socket.
1804 * @param listen_fd the listen file descriptor
1805 * @returns the connection fd of the client, or -1 on error
1808 _dbus_accept (int listen_fd)
1811 struct sockaddr addr;
1814 dbus_bool_t cloexec_done;
1817 addrlen = sizeof (addr);
1822 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1823 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1824 cloexec_done = client_fd >= 0;
1826 if (client_fd < 0 && errno == ENOSYS)
1829 client_fd = accept (listen_fd, &addr, &addrlen);
1838 _dbus_verbose ("client fd %d accepted\n", client_fd);
1844 _dbus_fd_set_close_on_exec(client_fd);
1851 * Checks to make sure the given directory is
1852 * private to the user
1854 * @param dir the name of the directory
1855 * @param error error return
1856 * @returns #FALSE on failure
1859 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1861 const char *directory;
1864 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1866 directory = _dbus_string_get_const_data (dir);
1868 if (stat (directory, &sb) < 0)
1870 dbus_set_error (error, _dbus_error_from_errno (errno),
1871 "%s", _dbus_strerror (errno));
1876 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1877 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1879 dbus_set_error (error, DBUS_ERROR_FAILED,
1880 "%s directory is not private to the user", directory);
1888 fill_user_info_from_passwd (struct passwd *p,
1892 _dbus_assert (p->pw_name != NULL);
1893 _dbus_assert (p->pw_dir != NULL);
1895 info->uid = p->pw_uid;
1896 info->primary_gid = p->pw_gid;
1897 info->username = _dbus_strdup (p->pw_name);
1898 info->homedir = _dbus_strdup (p->pw_dir);
1900 if (info->username == NULL ||
1901 info->homedir == NULL)
1903 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1911 fill_user_info (DBusUserInfo *info,
1913 const DBusString *username,
1916 const char *username_c;
1918 /* exactly one of username/uid provided */
1919 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1920 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1922 info->uid = DBUS_UID_UNSET;
1923 info->primary_gid = DBUS_GID_UNSET;
1924 info->group_ids = NULL;
1925 info->n_group_ids = 0;
1926 info->username = NULL;
1927 info->homedir = NULL;
1929 if (username != NULL)
1930 username_c = _dbus_string_get_const_data (username);
1934 /* For now assuming that the getpwnam() and getpwuid() flavors
1935 * are always symmetrical, if not we have to add more configure
1939 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1945 struct passwd p_str;
1947 /* retrieve maximum needed size for buf */
1948 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1950 /* sysconf actually returns a long, but everything else expects size_t,
1951 * so just recast here.
1952 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1954 if ((long) buflen <= 0)
1960 buf = dbus_malloc (buflen);
1963 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1968 #ifdef HAVE_POSIX_GETPWNAM_R
1969 if (uid != DBUS_UID_UNSET)
1970 result = getpwuid_r (uid, &p_str, buf, buflen,
1973 result = getpwnam_r (username_c, &p_str, buf, buflen,
1976 if (uid != DBUS_UID_UNSET)
1977 p = getpwuid_r (uid, &p_str, buf, buflen);
1979 p = getpwnam_r (username_c, &p_str, buf, buflen);
1981 #endif /* !HAVE_POSIX_GETPWNAM_R */
1982 //Try a bigger buffer if ERANGE was returned
1983 if (result == ERANGE && buflen < 512 * 1024)
1993 if (result == 0 && p == &p_str)
1995 if (!fill_user_info_from_passwd (p, info, error))
2004 dbus_set_error (error, _dbus_error_from_errno (errno),
2005 "User \"%s\" unknown or no memory to allocate password entry\n",
2006 username_c ? username_c : "???");
2007 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2012 #else /* ! HAVE_GETPWNAM_R */
2014 /* I guess we're screwed on thread safety here */
2017 if (uid != DBUS_UID_UNSET)
2020 p = getpwnam (username_c);
2024 if (!fill_user_info_from_passwd (p, info, error))
2031 dbus_set_error (error, _dbus_error_from_errno (errno),
2032 "User \"%s\" unknown or no memory to allocate password entry\n",
2033 username_c ? username_c : "???");
2034 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2038 #endif /* ! HAVE_GETPWNAM_R */
2040 /* Fill this in so we can use it to get groups */
2041 username_c = info->username;
2043 #ifdef HAVE_GETGROUPLIST
2048 int initial_buf_count;
2050 initial_buf_count = 17;
2051 buf_count = initial_buf_count;
2052 buf = dbus_new (gid_t, buf_count);
2055 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2059 if (getgrouplist (username_c,
2061 buf, &buf_count) < 0)
2064 /* Presumed cause of negative return code: buf has insufficient
2065 entries to hold the entire group list. The Linux behavior in this
2066 case is to pass back the actual number of groups in buf_count, but
2067 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2068 So as a hack, try to help out a bit by guessing a larger
2069 number of groups, within reason.. might still fail, of course,
2070 but we can at least print a more informative message. I looked up
2071 the "right way" to do this by downloading Apple's own source code
2072 for the "id" command, and it turns out that they use an
2073 undocumented library function getgrouplist_2 (!) which is not
2074 declared in any header in /usr/include (!!). That did not seem
2075 like the way to go here.
2077 if (buf_count == initial_buf_count)
2079 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2081 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2084 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2092 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2096 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2097 username_c, buf_count, buf_count);
2101 dbus_set_error (error,
2102 _dbus_error_from_errno (errno),
2103 "Failed to get groups for username \"%s\" primary GID "
2104 DBUS_GID_FORMAT ": %s\n",
2105 username_c, info->primary_gid,
2106 _dbus_strerror (errno));
2113 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2114 if (info->group_ids == NULL)
2116 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2121 for (i = 0; i < buf_count; ++i)
2122 info->group_ids[i] = buf[i];
2124 info->n_group_ids = buf_count;
2128 #else /* HAVE_GETGROUPLIST */
2130 /* We just get the one group ID */
2131 info->group_ids = dbus_new (dbus_gid_t, 1);
2132 if (info->group_ids == NULL)
2134 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2138 info->n_group_ids = 1;
2140 (info->group_ids)[0] = info->primary_gid;
2142 #endif /* HAVE_GETGROUPLIST */
2144 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2149 _DBUS_ASSERT_ERROR_IS_SET (error);
2154 * Gets user info for the given username.
2156 * @param info user info object to initialize
2157 * @param username the username
2158 * @param error error return
2159 * @returns #TRUE on success
2162 _dbus_user_info_fill (DBusUserInfo *info,
2163 const DBusString *username,
2166 return fill_user_info (info, DBUS_UID_UNSET,
2171 * Gets user info for the given user ID.
2173 * @param info user info object to initialize
2174 * @param uid the user ID
2175 * @param error error return
2176 * @returns #TRUE on success
2179 _dbus_user_info_fill_uid (DBusUserInfo *info,
2183 return fill_user_info (info, uid,
2188 * Adds the credentials of the current process to the
2189 * passed-in credentials object.
2191 * @param credentials credentials to add to
2192 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2195 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2197 /* The POSIX spec certainly doesn't promise this, but
2198 * we need these assertions to fail as soon as we're wrong about
2199 * it so we can do the porting fixups
2201 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2202 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2203 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2205 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2207 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2214 * Append to the string the identity we would like to have when we
2215 * authenticate, on UNIX this is the current process UID and on
2216 * Windows something else, probably a Windows SID string. No escaping
2217 * is required, that is done in dbus-auth.c. The username here
2218 * need not be anything human-readable, it can be the machine-readable
2219 * form i.e. a user id.
2221 * @param str the string to append to
2222 * @returns #FALSE on no memory
2225 _dbus_append_user_from_current_process (DBusString *str)
2227 return _dbus_string_append_uint (str,
2232 * Gets our process ID
2233 * @returns process ID
2242 * @returns process UID
2250 /** Gets our effective UID
2251 * @returns process effective UID
2254 _dbus_geteuid (void)
2260 * The only reason this is separate from _dbus_getpid() is to allow it
2261 * on Windows for logging but not for other purposes.
2263 * @returns process ID to put in log messages
2266 _dbus_pid_for_log (void)
2272 * Gets a UID from a UID string.
2274 * @param uid_str the UID in string form
2275 * @param uid UID to fill in
2276 * @returns #TRUE if successfully filled in UID
2279 _dbus_parse_uid (const DBusString *uid_str,
2285 if (_dbus_string_get_length (uid_str) == 0)
2287 _dbus_verbose ("UID string was zero length\n");
2293 if (!_dbus_string_parse_int (uid_str, 0, &val,
2296 _dbus_verbose ("could not parse string as a UID\n");
2300 if (end != _dbus_string_get_length (uid_str))
2302 _dbus_verbose ("string contained trailing stuff after UID\n");
2312 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2316 * Atomically increments an integer
2318 * @param atomic pointer to the integer to increment
2319 * @returns the value before incrementing
2322 _dbus_atomic_inc (DBusAtomic *atomic)
2325 return __sync_add_and_fetch(&atomic->value, 1)-1;
2328 _DBUS_LOCK (atomic);
2329 res = atomic->value;
2331 _DBUS_UNLOCK (atomic);
2337 * Atomically decrement an integer
2339 * @param atomic pointer to the integer to decrement
2340 * @returns the value before decrementing
2343 _dbus_atomic_dec (DBusAtomic *atomic)
2346 return __sync_sub_and_fetch(&atomic->value, 1)+1;
2350 _DBUS_LOCK (atomic);
2351 res = atomic->value;
2353 _DBUS_UNLOCK (atomic);
2359 * Atomically get the value of an integer. It may change at any time
2360 * thereafter, so this is mostly only useful for assertions.
2362 * @param atomic pointer to the integer to get
2363 * @returns the value at this moment
2366 _dbus_atomic_get (DBusAtomic *atomic)
2369 __sync_synchronize ();
2370 return atomic->value;
2374 _DBUS_LOCK (atomic);
2375 res = atomic->value;
2376 _DBUS_UNLOCK (atomic);
2381 #ifdef DBUS_BUILD_TESTS
2383 * @returns process GID
2393 * Wrapper for poll().
2395 * @param fds the file descriptors to poll
2396 * @param n_fds number of descriptors in the array
2397 * @param timeout_milliseconds timeout or -1 for infinite
2398 * @returns numbers of fds with revents, or <0 on error
2401 _dbus_poll (DBusPollFD *fds,
2403 int timeout_milliseconds)
2405 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2406 /* This big thing is a constant expression and should get optimized
2407 * out of existence. So it's more robust than a configure check at
2410 if (_DBUS_POLLIN == POLLIN &&
2411 _DBUS_POLLPRI == POLLPRI &&
2412 _DBUS_POLLOUT == POLLOUT &&
2413 _DBUS_POLLERR == POLLERR &&
2414 _DBUS_POLLHUP == POLLHUP &&
2415 _DBUS_POLLNVAL == POLLNVAL &&
2416 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2417 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2418 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2419 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2420 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2421 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2422 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2424 return poll ((struct pollfd*) fds,
2426 timeout_milliseconds);
2430 /* We have to convert the DBusPollFD to an array of
2431 * struct pollfd, poll, and convert back.
2433 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2436 #else /* ! HAVE_POLL */
2438 fd_set read_set, write_set, err_set;
2444 FD_ZERO (&read_set);
2445 FD_ZERO (&write_set);
2448 for (i = 0; i < n_fds; i++)
2450 DBusPollFD *fdp = &fds[i];
2452 if (fdp->events & _DBUS_POLLIN)
2453 FD_SET (fdp->fd, &read_set);
2455 if (fdp->events & _DBUS_POLLOUT)
2456 FD_SET (fdp->fd, &write_set);
2458 FD_SET (fdp->fd, &err_set);
2460 max_fd = MAX (max_fd, fdp->fd);
2463 tv.tv_sec = timeout_milliseconds / 1000;
2464 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2466 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2467 timeout_milliseconds < 0 ? NULL : &tv);
2471 for (i = 0; i < n_fds; i++)
2473 DBusPollFD *fdp = &fds[i];
2477 if (FD_ISSET (fdp->fd, &read_set))
2478 fdp->revents |= _DBUS_POLLIN;
2480 if (FD_ISSET (fdp->fd, &write_set))
2481 fdp->revents |= _DBUS_POLLOUT;
2483 if (FD_ISSET (fdp->fd, &err_set))
2484 fdp->revents |= _DBUS_POLLERR;
2493 * Get current time, as in gettimeofday(). Use the monotonic clock if
2494 * available, to avoid problems when the system time changes.
2496 * @param tv_sec return location for number of seconds
2497 * @param tv_usec return location for number of microseconds (thousandths)
2500 _dbus_get_current_time (long *tv_sec,
2505 #ifdef HAVE_MONOTONIC_CLOCK
2507 clock_gettime (CLOCK_MONOTONIC, &ts);
2510 *tv_sec = ts.tv_sec;
2512 *tv_usec = ts.tv_nsec / 1000;
2514 gettimeofday (&t, NULL);
2519 *tv_usec = t.tv_usec;
2524 * Creates a directory; succeeds if the directory
2525 * is created or already existed.
2527 * @param filename directory filename
2528 * @param error initialized error object
2529 * @returns #TRUE on success
2532 _dbus_create_directory (const DBusString *filename,
2535 const char *filename_c;
2537 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2539 filename_c = _dbus_string_get_const_data (filename);
2541 if (mkdir (filename_c, 0700) < 0)
2543 if (errno == EEXIST)
2546 dbus_set_error (error, DBUS_ERROR_FAILED,
2547 "Failed to create directory %s: %s\n",
2548 filename_c, _dbus_strerror (errno));
2556 * Appends the given filename to the given directory.
2558 * @todo it might be cute to collapse multiple '/' such as "foo//"
2561 * @param dir the directory name
2562 * @param next_component the filename
2563 * @returns #TRUE on success
2566 _dbus_concat_dir_and_file (DBusString *dir,
2567 const DBusString *next_component)
2569 dbus_bool_t dir_ends_in_slash;
2570 dbus_bool_t file_starts_with_slash;
2572 if (_dbus_string_get_length (dir) == 0 ||
2573 _dbus_string_get_length (next_component) == 0)
2576 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2577 _dbus_string_get_length (dir) - 1);
2579 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2581 if (dir_ends_in_slash && file_starts_with_slash)
2583 _dbus_string_shorten (dir, 1);
2585 else if (!(dir_ends_in_slash || file_starts_with_slash))
2587 if (!_dbus_string_append_byte (dir, '/'))
2591 return _dbus_string_copy (next_component, 0, dir,
2592 _dbus_string_get_length (dir));
2595 /** nanoseconds in a second */
2596 #define NANOSECONDS_PER_SECOND 1000000000
2597 /** microseconds in a second */
2598 #define MICROSECONDS_PER_SECOND 1000000
2599 /** milliseconds in a second */
2600 #define MILLISECONDS_PER_SECOND 1000
2601 /** nanoseconds in a millisecond */
2602 #define NANOSECONDS_PER_MILLISECOND 1000000
2603 /** microseconds in a millisecond */
2604 #define MICROSECONDS_PER_MILLISECOND 1000
2607 * Sleeps the given number of milliseconds.
2608 * @param milliseconds number of milliseconds
2611 _dbus_sleep_milliseconds (int milliseconds)
2613 #ifdef HAVE_NANOSLEEP
2614 struct timespec req;
2615 struct timespec rem;
2617 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2618 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2622 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2624 #elif defined (HAVE_USLEEP)
2625 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2626 #else /* ! HAVE_USLEEP */
2627 sleep (MAX (milliseconds / 1000, 1));
2632 _dbus_generate_pseudorandom_bytes (DBusString *str,
2638 old_len = _dbus_string_get_length (str);
2640 if (!_dbus_string_lengthen (str, n_bytes))
2643 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2645 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2651 * Generates the given number of random bytes,
2652 * using the best mechanism we can come up with.
2654 * @param str the string
2655 * @param n_bytes the number of random bytes to append to string
2656 * @returns #TRUE on success, #FALSE if no memory
2659 _dbus_generate_random_bytes (DBusString *str,
2665 /* FALSE return means "no memory", if it could
2666 * mean something else then we'd need to return
2667 * a DBusError. So we always fall back to pseudorandom
2671 old_len = _dbus_string_get_length (str);
2674 /* note, urandom on linux will fall back to pseudorandom */
2675 fd = open ("/dev/urandom", O_RDONLY);
2677 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2679 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2681 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2683 _dbus_close (fd, NULL);
2684 _dbus_string_set_length (str, old_len);
2685 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2688 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2691 _dbus_close (fd, NULL);
2697 * Exit the process, returning the given value.
2699 * @param code the exit code
2702 _dbus_exit (int code)
2708 * A wrapper around strerror() because some platforms
2709 * may be lame and not have strerror(). Also, never
2712 * @param error_number errno.
2713 * @returns error description.
2716 _dbus_strerror (int error_number)
2720 msg = strerror (error_number);
2728 * signal (SIGPIPE, SIG_IGN);
2731 _dbus_disable_sigpipe (void)
2733 signal (SIGPIPE, SIG_IGN);
2737 * Sets the file descriptor to be close
2738 * on exec. Should be called for all file
2739 * descriptors in D-Bus code.
2741 * @param fd the file descriptor
2744 _dbus_fd_set_close_on_exec (intptr_t fd)
2748 val = fcntl (fd, F_GETFD, 0);
2755 fcntl (fd, F_SETFD, val);
2759 * Closes a file descriptor.
2761 * @param fd the file descriptor
2762 * @param error error object
2763 * @returns #FALSE if error set
2766 _dbus_close (int fd,
2769 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2777 dbus_set_error (error, _dbus_error_from_errno (errno),
2778 "Could not close fd %d", fd);
2786 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2787 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2789 * @param fd the file descriptor to duplicate
2790 * @returns duplicated file descriptor
2798 #ifdef F_DUPFD_CLOEXEC
2799 dbus_bool_t cloexec_done;
2801 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2802 cloexec_done = new_fd >= 0;
2804 if (new_fd < 0 && errno == EINVAL)
2807 new_fd = fcntl(fd, F_DUPFD, 3);
2812 dbus_set_error (error, _dbus_error_from_errno (errno),
2813 "Could not duplicate fd %d", fd);
2817 #ifdef F_DUPFD_CLOEXEC
2821 _dbus_fd_set_close_on_exec(new_fd);
2828 * Sets a file descriptor to be nonblocking.
2830 * @param fd the file descriptor.
2831 * @param error address of error location.
2832 * @returns #TRUE on success.
2835 _dbus_set_fd_nonblocking (int fd,
2840 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2842 val = fcntl (fd, F_GETFL, 0);
2845 dbus_set_error (error, _dbus_error_from_errno (errno),
2846 "Failed to get flags from file descriptor %d: %s",
2847 fd, _dbus_strerror (errno));
2848 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2849 _dbus_strerror (errno));
2853 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2855 dbus_set_error (error, _dbus_error_from_errno (errno),
2856 "Failed to set nonblocking flag of file descriptor %d: %s",
2857 fd, _dbus_strerror (errno));
2858 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2859 fd, _dbus_strerror (errno));
2868 * On GNU libc systems, print a crude backtrace to stderr. On other
2869 * systems, print "no backtrace support" and block for possible gdb
2870 * attachment if an appropriate environment variable is set.
2873 _dbus_print_backtrace (void)
2875 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2881 bt_size = backtrace (bt, 500);
2883 syms = backtrace_symbols (bt, bt_size);
2888 /* don't use dbus_warn since it can _dbus_abort() */
2889 fprintf (stderr, " %s\n", syms[i]);
2895 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2896 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2898 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2903 * Creates a full-duplex pipe (as in socketpair()).
2904 * Sets both ends of the pipe nonblocking.
2906 * Marks both file descriptors as close-on-exec
2908 * @todo libdbus only uses this for the debug-pipe server, so in
2909 * principle it could be in dbus-sysdeps-util.c, except that
2910 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2911 * debug-pipe server is used.
2913 * @param fd1 return location for one end
2914 * @param fd2 return location for the other end
2915 * @param blocking #TRUE if pipe should be blocking
2916 * @param error error return
2917 * @returns #FALSE on failure (if error is set)
2920 _dbus_full_duplex_pipe (int *fd1,
2922 dbus_bool_t blocking,
2925 #ifdef HAVE_SOCKETPAIR
2930 dbus_bool_t cloexec_done;
2932 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2933 cloexec_done = retval >= 0;
2935 if (retval < 0 && errno == EINVAL)
2938 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2943 dbus_set_error (error, _dbus_error_from_errno (errno),
2944 "Could not create full-duplex pipe");
2948 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2954 _dbus_fd_set_close_on_exec (fds[0]);
2955 _dbus_fd_set_close_on_exec (fds[1]);
2959 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2960 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2962 dbus_set_error (error, _dbus_error_from_errno (errno),
2963 "Could not set full-duplex pipe nonblocking");
2965 _dbus_close (fds[0], NULL);
2966 _dbus_close (fds[1], NULL);
2974 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2979 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2980 dbus_set_error (error, DBUS_ERROR_FAILED,
2981 "_dbus_full_duplex_pipe() not implemented on this OS");
2987 * Measure the length of the given format string and arguments,
2988 * not including the terminating nul.
2990 * @param format a printf-style format string
2991 * @param args arguments for the format string
2992 * @returns length of the given format string and args
2995 _dbus_printf_string_upper_bound (const char *format,
2999 return vsnprintf (&c, 1, format, args);
3003 * Gets the temporary files directory by inspecting the environment variables
3004 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3006 * @returns location of temp directory
3009 _dbus_get_tmpdir(void)
3011 static const char* tmpdir = NULL;
3015 /* TMPDIR is what glibc uses, then
3016 * glibc falls back to the P_tmpdir macro which
3017 * just expands to "/tmp"
3020 tmpdir = getenv("TMPDIR");
3022 /* These two env variables are probably
3023 * broken, but maybe some OS uses them?
3026 tmpdir = getenv("TMP");
3028 tmpdir = getenv("TEMP");
3030 /* And this is the sane fallback. */
3035 _dbus_assert(tmpdir != NULL);
3041 * Execute a subprocess, returning up to 1024 bytes of output
3044 * If successful, returns #TRUE and appends the output to @p
3045 * result. If a failure happens, returns #FALSE and
3046 * sets an error in @p error.
3048 * @note It's not an error if the subprocess terminates normally
3049 * without writing any data to stdout. Verify the @p result length
3050 * before and after this function call to cover this case.
3052 * @param progname initial path to exec (may or may not be absolute)
3053 * @param path_fallback if %TRUE, search PATH for executable
3054 * @param argv NULL-terminated list of arguments
3055 * @param result a DBusString where the output can be append
3056 * @param error a DBusError to store the error in case of failure
3057 * @returns #TRUE on success, #FALSE if an error happened
3060 _read_subprocess_line_argv (const char *progpath,
3061 dbus_bool_t path_fallback,
3066 int result_pipe[2] = { -1, -1 };
3067 int errors_pipe[2] = { -1, -1 };
3075 sigset_t new_set, old_set;
3077 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3080 /* We need to block any existing handlers for SIGCHLD temporarily; they
3081 * will cause waitpid() below to fail.
3082 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3084 sigemptyset (&new_set);
3085 sigaddset (&new_set, SIGCHLD);
3086 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3088 orig_len = _dbus_string_get_length (result);
3092 if (pipe (result_pipe) < 0)
3094 dbus_set_error (error, _dbus_error_from_errno (errno),
3095 "Failed to create a pipe to call %s: %s",
3096 progpath, _dbus_strerror (errno));
3097 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3098 progpath, _dbus_strerror (errno));
3101 if (pipe (errors_pipe) < 0)
3103 dbus_set_error (error, _dbus_error_from_errno (errno),
3104 "Failed to create a pipe to call %s: %s",
3105 progpath, _dbus_strerror (errno));
3106 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3107 progpath, _dbus_strerror (errno));
3114 dbus_set_error (error, _dbus_error_from_errno (errno),
3115 "Failed to fork() to call %s: %s",
3116 progpath, _dbus_strerror (errno));
3117 _dbus_verbose ("Failed to fork() to call %s: %s\n",
3118 progpath, _dbus_strerror (errno));
3128 fd = open ("/dev/null", O_RDWR);
3130 /* huh?! can't open /dev/null? */
3133 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3136 close (result_pipe[READ_END]);
3137 close (errors_pipe[READ_END]);
3138 close (0); /* close stdin */
3139 close (1); /* close stdout */
3140 close (2); /* close stderr */
3142 if (dup2 (fd, 0) == -1)
3144 if (dup2 (result_pipe[WRITE_END], 1) == -1)
3146 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3149 maxfds = sysconf (_SC_OPEN_MAX);
3150 /* Pick something reasonable if for some reason sysconf
3155 /* close all inherited fds */
3156 for (i = 3; i < maxfds; i++)
3159 sigprocmask (SIG_SETMASK, &old_set, NULL);
3161 /* If it looks fully-qualified, try execv first */
3162 if (progpath[0] == '/')
3164 execv (progpath, argv);
3165 /* Ok, that failed. Now if path_fallback is given, let's
3166 * try unqualified. This is mostly a hack to work
3167 * around systems which ship dbus-launch in /usr/bin
3168 * but everything else in /bin (because dbus-launch
3172 /* We must have a slash, because we checked above */
3173 execvp (strrchr (progpath, '/')+1, argv);
3176 execvp (progpath, argv);
3178 /* still nothing, we failed */
3182 /* parent process */
3183 close (result_pipe[WRITE_END]);
3184 close (errors_pipe[WRITE_END]);
3185 result_pipe[WRITE_END] = -1;
3186 errors_pipe[WRITE_END] = -1;
3191 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3195 /* reap the child process to avoid it lingering as zombie */
3198 ret = waitpid (pid, &status, 0);
3200 while (ret == -1 && errno == EINTR);
3202 /* We succeeded if the process exited with status 0 and
3203 anything was read */
3204 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3206 /* The process ended with error */
3207 DBusString error_message;
3208 if (!_dbus_string_init (&error_message))
3210 _DBUS_SET_OOM (error);
3217 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3221 _dbus_string_set_length (result, orig_len);
3222 if (_dbus_string_get_length (&error_message) > 0)
3223 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3224 "%s terminated abnormally with the following error: %s",
3225 progpath, _dbus_string_get_data (&error_message));
3227 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3228 "%s terminated abnormally without any error message",
3236 sigprocmask (SIG_SETMASK, &old_set, NULL);
3239 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3241 _DBUS_ASSERT_ERROR_IS_SET (error);
3243 if (result_pipe[0] != -1)
3244 close (result_pipe[0]);
3245 if (result_pipe[1] != -1)
3246 close (result_pipe[1]);
3247 if (errors_pipe[0] != -1)
3248 close (errors_pipe[0]);
3249 if (errors_pipe[1] != -1)
3250 close (errors_pipe[1]);
3256 * Returns the address of a new session bus.
3258 * If successful, returns #TRUE and appends the address to @p
3259 * address. If a failure happens, returns #FALSE and
3260 * sets an error in @p error.
3262 * @param address a DBusString where the address can be stored
3263 * @param error a DBusError to store the error in case of failure
3264 * @returns #TRUE on success, #FALSE if an error happened
3267 _dbus_get_autolaunch_address (const char *scope,
3268 DBusString *address,
3271 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3272 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3273 * but that's done elsewhere, and if it worked, this function wouldn't
3275 const char *display;
3276 static char *argv[6];
3281 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3284 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3285 * dbus-launch-x11 is just going to fail. Rather than trying to
3286 * run it, we might as well bail out early with a nice error. */
3287 display = _dbus_getenv ("DISPLAY");
3289 if (display == NULL || display[0] == '\0')
3291 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3292 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3296 if (!_dbus_string_init (&uuid))
3298 _DBUS_SET_OOM (error);
3302 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3304 _DBUS_SET_OOM (error);
3309 argv[i] = "dbus-launch";
3311 argv[i] = "--autolaunch";
3313 argv[i] = _dbus_string_get_data (&uuid);
3315 argv[i] = "--binary-syntax";
3317 argv[i] = "--close-stderr";
3322 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3324 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3326 argv, address, error);
3329 _dbus_string_free (&uuid);
3332 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3333 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3334 "set your DBUS_SESSION_BUS_ADDRESS instead");
3340 * Reads the uuid of the machine we're running on from
3341 * the dbus configuration. Optionally try to create it
3342 * (only root can do this usually).
3344 * On UNIX, reads a file that gets created by dbus-uuidgen
3345 * in a post-install script. On Windows, if there's a standard
3346 * machine uuid we could just use that, but I can't find one
3347 * with the right properties (the hardware profile guid can change
3348 * without rebooting I believe). If there's no standard one
3349 * we might want to use the registry instead of a file for
3350 * this, and I'm not sure how we'd ensure the uuid gets created.
3352 * @param machine_id guid to init with the machine's uuid
3353 * @param create_if_not_found try to create the uuid if it doesn't exist
3354 * @param error the error return
3355 * @returns #FALSE if the error is set
3358 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3359 dbus_bool_t create_if_not_found,
3362 DBusString filename;
3365 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3367 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3371 dbus_error_free (error);
3373 /* Fallback to the system machine ID */
3374 _dbus_string_init_const (&filename, "/etc/machine-id");
3375 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3378 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3379 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3382 * quries launchd for a specific env var which holds the socket path.
3383 * @param launchd_env_var the env var to look up
3384 * @param error a DBusError to store the error in case of failure
3385 * @return the value of the env var
3388 _dbus_lookup_launchd_socket (DBusString *socket_path,
3389 const char *launchd_env_var,
3392 #ifdef DBUS_ENABLE_LAUNCHD
3396 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3399 argv[i] = "launchctl";
3403 argv[i] = (char*)launchd_env_var;
3408 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3410 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3415 /* no error, but no result either */
3416 if (_dbus_string_get_length(socket_path) == 0)
3421 /* strip the carriage-return */
3422 _dbus_string_shorten(socket_path, 1);
3424 #else /* DBUS_ENABLE_LAUNCHD */
3425 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3426 "can't lookup socket from launchd; launchd support not compiled in");
3432 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3434 #ifdef DBUS_ENABLE_LAUNCHD
3435 dbus_bool_t valid_socket;
3436 DBusString socket_path;
3438 if (!_dbus_string_init (&socket_path))
3440 _DBUS_SET_OOM (error);
3444 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3446 if (dbus_error_is_set(error))
3448 _dbus_string_free(&socket_path);
3454 dbus_set_error(error, "no socket path",
3455 "launchd did not provide a socket path, "
3456 "verify that org.freedesktop.dbus-session.plist is loaded!");
3457 _dbus_string_free(&socket_path);
3460 if (!_dbus_string_append (address, "unix:path="))
3462 _DBUS_SET_OOM (error);
3463 _dbus_string_free(&socket_path);
3466 if (!_dbus_string_copy (&socket_path, 0, address,
3467 _dbus_string_get_length (address)))
3469 _DBUS_SET_OOM (error);
3470 _dbus_string_free(&socket_path);
3474 _dbus_string_free(&socket_path);
3477 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3478 "can't lookup session address from launchd; launchd support not compiled in");
3484 * Determines the address of the session bus by querying a
3485 * platform-specific method.
3487 * The first parameter will be a boolean specifying whether
3488 * or not a dynamic session lookup is supported on this platform.
3490 * If supported is TRUE and the return value is #TRUE, the
3491 * address will be appended to @p address.
3492 * If a failure happens, returns #FALSE and sets an error in
3495 * If supported is FALSE, ignore the return value.
3497 * @param supported returns whether this method is supported
3498 * @param address a DBusString where the address can be stored
3499 * @param error a DBusError to store the error in case of failure
3500 * @returns #TRUE on success, #FALSE if an error happened
3503 _dbus_lookup_session_address (dbus_bool_t *supported,
3504 DBusString *address,
3507 #ifdef DBUS_ENABLE_LAUNCHD
3509 return _dbus_lookup_session_address_launchd (address, error);
3511 /* On non-Mac Unix platforms, if the session address isn't already
3512 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3513 * fall back to the autolaunch: global default; see
3514 * init_session_address in dbus/dbus-bus.c. */
3521 * Returns the standard directories for a session bus to look for service
3524 * On UNIX this should be the standard xdg freedesktop.org data directories:
3526 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3527 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3533 * @param dirs the directory list we are returning
3534 * @returns #FALSE on OOM
3538 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3540 const char *xdg_data_home;
3541 const char *xdg_data_dirs;
3542 DBusString servicedir_path;
3544 if (!_dbus_string_init (&servicedir_path))
3547 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3548 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3550 if (xdg_data_home != NULL)
3552 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3557 const DBusString *homedir;
3558 DBusString local_share;
3560 if (!_dbus_homedir_from_current_process (&homedir))
3563 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3566 _dbus_string_init_const (&local_share, "/.local/share");
3567 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3571 if (!_dbus_string_append (&servicedir_path, ":"))
3574 if (xdg_data_dirs != NULL)
3576 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3579 if (!_dbus_string_append (&servicedir_path, ":"))
3584 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3589 * add configured datadir to defaults
3590 * this may be the same as an xdg dir
3591 * however the config parser should take
3592 * care of duplicates
3594 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3597 if (!_dbus_split_paths_and_append (&servicedir_path,
3598 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3602 _dbus_string_free (&servicedir_path);
3606 _dbus_string_free (&servicedir_path);
3612 * Returns the standard directories for a system bus to look for service
3615 * On UNIX this should be the standard xdg freedesktop.org data directories:
3617 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3623 * On Windows there is no system bus and this function can return nothing.
3625 * @param dirs the directory list we are returning
3626 * @returns #FALSE on OOM
3630 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3632 const char *xdg_data_dirs;
3633 DBusString servicedir_path;
3635 if (!_dbus_string_init (&servicedir_path))
3638 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3640 if (xdg_data_dirs != NULL)
3642 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3645 if (!_dbus_string_append (&servicedir_path, ":"))
3650 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3655 * Add configured datadir to defaults. This may be the same as one
3656 * of the XDG directories. However, the config parser should take
3657 * care of the duplicates.
3659 * Also, append /lib as counterpart of /usr/share on the root
3660 * directory (the root directory does not know /share), in order to
3661 * facilitate early boot system bus activation where /usr might not
3664 if (!_dbus_string_append (&servicedir_path,
3669 if (!_dbus_split_paths_and_append (&servicedir_path,
3670 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3674 _dbus_string_free (&servicedir_path);
3678 _dbus_string_free (&servicedir_path);
3683 * Append the absolute path of the system.conf file
3684 * (there is no system bus on Windows so this can just
3685 * return FALSE and print a warning or something)
3687 * @param str the string to append to
3688 * @returns #FALSE if no memory
3691 _dbus_append_system_config_file (DBusString *str)
3693 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3697 * Append the absolute path of the session.conf file.
3699 * @param str the string to append to
3700 * @returns #FALSE if no memory
3703 _dbus_append_session_config_file (DBusString *str)
3705 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3709 * Called when the bus daemon is signaled to reload its configuration; any
3710 * caches should be nuked. Of course any caches that need explicit reload
3711 * are probably broken, but c'est la vie.
3716 _dbus_flush_caches (void)
3718 _dbus_user_database_flush_system ();
3722 * Appends the directory in which a keyring for the given credentials
3723 * should be stored. The credentials should have either a Windows or
3724 * UNIX user in them. The directory should be an absolute path.
3726 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3727 * be something else, since the dotfile convention is not normal on Windows.
3729 * @param directory string to append directory to
3730 * @param credentials credentials the directory should be for
3732 * @returns #FALSE on no memory
3735 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3736 DBusCredentials *credentials)
3742 _dbus_assert (credentials != NULL);
3743 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3745 if (!_dbus_string_init (&homedir))
3748 uid = _dbus_credentials_get_unix_uid (credentials);
3749 _dbus_assert (uid != DBUS_UID_UNSET);
3751 if (!_dbus_homedir_from_uid (uid, &homedir))
3754 #ifdef DBUS_BUILD_TESTS
3756 const char *override;
3758 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3759 if (override != NULL && *override != '\0')
3761 _dbus_string_set_length (&homedir, 0);
3762 if (!_dbus_string_append (&homedir, override))
3765 _dbus_verbose ("Using fake homedir for testing: %s\n",
3766 _dbus_string_get_const_data (&homedir));
3770 static dbus_bool_t already_warned = FALSE;
3771 if (!already_warned)
3773 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3774 already_warned = TRUE;
3780 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3781 if (!_dbus_concat_dir_and_file (&homedir,
3785 if (!_dbus_string_copy (&homedir, 0,
3786 directory, _dbus_string_get_length (directory))) {
3790 _dbus_string_free (&homedir);
3794 _dbus_string_free (&homedir);
3798 //PENDING(kdab) docs
3800 _dbus_daemon_publish_session_bus_address (const char* addr,
3806 //PENDING(kdab) docs
3808 _dbus_daemon_unpublish_session_bus_address (void)
3814 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3815 * for Winsock so is abstracted)
3817 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3820 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3822 return errno == EAGAIN || errno == EWOULDBLOCK;
3826 * Removes a directory; Directory must be empty
3828 * @param filename directory filename
3829 * @param error initialized error object
3830 * @returns #TRUE on success
3833 _dbus_delete_directory (const DBusString *filename,
3836 const char *filename_c;
3838 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3840 filename_c = _dbus_string_get_const_data (filename);
3842 if (rmdir (filename_c) != 0)
3844 dbus_set_error (error, DBUS_ERROR_FAILED,
3845 "Failed to remove directory %s: %s\n",
3846 filename_c, _dbus_strerror (errno));
3854 * Checks whether file descriptors may be passed via the socket
3856 * @param fd the socket
3857 * @return TRUE when fd passing over this socket is supported
3861 _dbus_socket_can_pass_unix_fd(int fd) {
3866 struct sockaddr_storage storage;
3867 struct sockaddr_un un;
3870 socklen_t sa_len = sizeof(sa_buf);
3874 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3877 return sa_buf.sa.sa_family == AF_UNIX;
3887 * replaces the term DBUS_PREFIX in configure_time_path by the
3888 * current dbus installation directory. On unix this function is a noop
3890 * @param configure_time_path
3894 _dbus_replace_install_prefix (const char *configure_time_path)
3896 return configure_time_path;
3899 /* tests in dbus-sysdeps-util.c */