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);
834 if (!_dbus_set_fd_nonblocking (fd, error))
836 _DBUS_ASSERT_ERROR_IS_SET (error);
838 _dbus_close (fd, NULL);
848 * Enables or disables the reception of credentials on the given socket during
849 * the next message transmission. This is only effective if the #LOCAL_CREDS
850 * system feature exists, in which case the other side of the connection does
851 * not have to do anything special to send the credentials.
853 * @param fd socket on which to change the #LOCAL_CREDS flag.
854 * @param on whether to enable or disable the #LOCAL_CREDS flag.
857 _dbus_set_local_creds (int fd, dbus_bool_t on)
859 dbus_bool_t retval = TRUE;
861 #if defined(HAVE_CMSGCRED)
862 /* NOOP just to make sure only one codepath is used
863 * and to prefer CMSGCRED
865 #elif defined(LOCAL_CREDS)
866 int val = on ? 1 : 0;
867 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
869 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
873 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
874 on ? "enabled" : "disabled", fd);
881 * Creates a socket and binds it to the given path,
882 * then listens on the socket. The socket is
883 * set to be nonblocking.
885 * Uses abstract sockets instead of filesystem-linked
886 * sockets if requested (it's possible only on Linux;
887 * see "man 7 unix" on Linux).
888 * On non-Linux abstract socket usage always fails.
890 * This will set FD_CLOEXEC for the socket returned
892 * @param path the socket name
893 * @param abstract #TRUE to use abstract namespace
894 * @param error return location for errors
895 * @returns the listening file descriptor or -1 on error
898 _dbus_listen_unix_socket (const char *path,
899 dbus_bool_t abstract,
903 struct sockaddr_un addr;
905 unsigned int reuseaddr;
907 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
909 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
912 if (!_dbus_open_unix_socket (&listen_fd, error))
914 _DBUS_ASSERT_ERROR_IS_SET(error);
917 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
920 addr.sun_family = AF_UNIX;
921 path_len = strlen (path);
925 #ifdef HAVE_ABSTRACT_SOCKETS
926 /* remember that abstract names aren't nul-terminated so we rely
927 * on sun_path being filled in with zeroes above.
929 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
930 path_len++; /* Account for the extra nul byte added to the start of sun_path */
932 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
934 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
935 "Abstract socket name too long\n");
936 _dbus_close (listen_fd, NULL);
940 strncpy (&addr.sun_path[1], path, path_len);
941 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
942 #else /* HAVE_ABSTRACT_SOCKETS */
943 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
944 "Operating system does not support abstract socket namespace\n");
945 _dbus_close (listen_fd, NULL);
947 #endif /* ! HAVE_ABSTRACT_SOCKETS */
951 /* Discussed security implications of this with Nalin,
952 * and we couldn't think of where it would kick our ass, but
953 * it still seems a bit sucky. It also has non-security suckage;
954 * really we'd prefer to exit if the socket is already in use.
955 * But there doesn't seem to be a good way to do this.
957 * Just to be extra careful, I threw in the stat() - clearly
958 * the stat() can't *fix* any security issue, but it at least
959 * avoids inadvertent/accidental data loss.
964 if (stat (path, &sb) == 0 &&
965 S_ISSOCK (sb.st_mode))
969 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
971 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
972 "Abstract socket name too long\n");
973 _dbus_close (listen_fd, NULL);
977 strncpy (addr.sun_path, path, path_len);
981 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
983 _dbus_warn ("Failed to set socket option\"%s\": %s",
984 path, _dbus_strerror (errno));
987 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
989 dbus_set_error (error, _dbus_error_from_errno (errno),
990 "Failed to bind socket \"%s\": %s",
991 path, _dbus_strerror (errno));
992 _dbus_close (listen_fd, NULL);
996 if (listen (listen_fd, 30 /* backlog */) < 0)
998 dbus_set_error (error, _dbus_error_from_errno (errno),
999 "Failed to listen on socket \"%s\": %s",
1000 path, _dbus_strerror (errno));
1001 _dbus_close (listen_fd, NULL);
1005 if (!_dbus_set_local_creds (listen_fd, TRUE))
1007 dbus_set_error (error, _dbus_error_from_errno (errno),
1008 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1009 path, _dbus_strerror (errno));
1014 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1016 _DBUS_ASSERT_ERROR_IS_SET (error);
1017 _dbus_close (listen_fd, NULL);
1021 /* Try opening up the permissions, but if we can't, just go ahead
1022 * and continue, maybe it will be good enough.
1024 if (!abstract && chmod (path, 0777) < 0)
1025 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1032 * Acquires one or more sockets passed in from systemd. The sockets
1033 * are set to be nonblocking.
1035 * This will set FD_CLOEXEC for the sockets returned.
1037 * @oaram fds the file descriptors
1038 * @param error return location for errors
1039 * @returns the number of file descriptors
1042 _dbus_listen_systemd_sockets (int **fds,
1049 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1051 n = sd_listen_fds (TRUE);
1054 dbus_set_error (error, _dbus_error_from_errno (-n),
1055 "Failed to acquire systemd socket: %s",
1056 _dbus_strerror (-n));
1062 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1063 "No socket received.");
1067 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1069 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1072 dbus_set_error (error, _dbus_error_from_errno (-r),
1073 "Failed to verify systemd socket type: %s",
1074 _dbus_strerror (-r));
1080 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1081 "Passed socket has wrong type.");
1086 /* OK, the file descriptors are all good, so let's take posession of
1089 new_fds = dbus_new (int, n);
1092 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1093 "Failed to allocate file handle array.");
1097 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1099 if (!_dbus_set_local_creds (fd, TRUE))
1101 dbus_set_error (error, _dbus_error_from_errno (errno),
1102 "Failed to enable LOCAL_CREDS on systemd socket: %s",
1103 _dbus_strerror (errno));
1107 if (!_dbus_set_fd_nonblocking (fd, error))
1109 _DBUS_ASSERT_ERROR_IS_SET (error);
1113 new_fds[fd - SD_LISTEN_FDS_START] = fd;
1121 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1123 _dbus_close (fd, NULL);
1126 dbus_free (new_fds);
1131 * Creates a socket and connects to a socket at the given host
1132 * and port. The connection fd is returned, and is set up as
1135 * This will set FD_CLOEXEC for the socket returned
1137 * @param host the host name to connect to
1138 * @param port the port to connect to
1139 * @param family the address family to listen on, NULL for all
1140 * @param error return location for error code
1141 * @returns connection file descriptor or -1 on error
1144 _dbus_connect_tcp_socket (const char *host,
1149 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1153 _dbus_connect_tcp_socket_with_nonce (const char *host,
1156 const char *noncefile,
1159 int saved_errno = 0;
1161 struct addrinfo hints;
1162 struct addrinfo *ai, *tmp;
1164 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1166 if (!_dbus_open_tcp_socket (&fd, error))
1168 _DBUS_ASSERT_ERROR_IS_SET(error);
1172 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1177 hints.ai_family = AF_UNSPEC;
1178 else if (!strcmp(family, "ipv4"))
1179 hints.ai_family = AF_INET;
1180 else if (!strcmp(family, "ipv6"))
1181 hints.ai_family = AF_INET6;
1184 dbus_set_error (error,
1185 DBUS_ERROR_BAD_ADDRESS,
1186 "Unknown address family %s", family);
1189 hints.ai_protocol = IPPROTO_TCP;
1190 hints.ai_socktype = SOCK_STREAM;
1191 hints.ai_flags = AI_ADDRCONFIG;
1193 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1195 dbus_set_error (error,
1196 _dbus_error_from_errno (errno),
1197 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1198 host, port, gai_strerror(res), res);
1199 _dbus_close (fd, NULL);
1206 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1209 _DBUS_ASSERT_ERROR_IS_SET(error);
1212 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1214 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1216 saved_errno = errno;
1217 _dbus_close(fd, NULL);
1229 dbus_set_error (error,
1230 _dbus_error_from_errno (saved_errno),
1231 "Failed to connect to socket \"%s:%s\" %s",
1232 host, port, _dbus_strerror(saved_errno));
1236 if (noncefile != NULL)
1238 DBusString noncefileStr;
1240 _dbus_string_init_const (&noncefileStr, noncefile);
1241 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1242 _dbus_string_free (&noncefileStr);
1246 _dbus_close (fd, NULL);
1251 if (!_dbus_set_fd_nonblocking (fd, error))
1253 _dbus_close (fd, NULL);
1261 * Creates a socket and binds it to the given path, then listens on
1262 * the socket. The socket is set to be nonblocking. In case of port=0
1263 * a random free port is used and returned in the port parameter.
1264 * If inaddr_any is specified, the hostname is ignored.
1266 * This will set FD_CLOEXEC for the socket returned
1268 * @param host the host name to listen on
1269 * @param port the port to listen on, if zero a free port will be used
1270 * @param family the address family to listen on, NULL for all
1271 * @param retport string to return the actual port listened on
1272 * @param fds_p location to store returned file descriptors
1273 * @param error return location for errors
1274 * @returns the number of listening file descriptors or -1 on error
1277 _dbus_listen_tcp_socket (const char *host,
1280 DBusString *retport,
1285 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1286 struct addrinfo hints;
1287 struct addrinfo *ai, *tmp;
1288 unsigned int reuseaddr;
1291 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1296 hints.ai_family = AF_UNSPEC;
1297 else if (!strcmp(family, "ipv4"))
1298 hints.ai_family = AF_INET;
1299 else if (!strcmp(family, "ipv6"))
1300 hints.ai_family = AF_INET6;
1303 dbus_set_error (error,
1304 DBUS_ERROR_BAD_ADDRESS,
1305 "Unknown address family %s", family);
1309 hints.ai_protocol = IPPROTO_TCP;
1310 hints.ai_socktype = SOCK_STREAM;
1311 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1313 redo_lookup_with_port:
1314 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1316 dbus_set_error (error,
1317 _dbus_error_from_errno (errno),
1318 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1319 host ? host : "*", port, gai_strerror(res), res);
1326 int fd = -1, *newlisten_fd;
1327 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1329 _DBUS_ASSERT_ERROR_IS_SET(error);
1332 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1335 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1337 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1338 host ? host : "*", port, _dbus_strerror (errno));
1341 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1343 saved_errno = errno;
1344 _dbus_close(fd, NULL);
1345 if (saved_errno == EADDRINUSE)
1347 /* Depending on kernel policy, it may or may not
1348 be neccessary to bind to both IPv4 & 6 addresses
1349 so ignore EADDRINUSE here */
1353 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1354 "Failed to bind socket \"%s:%s\": %s",
1355 host ? host : "*", port, _dbus_strerror (saved_errno));
1359 if (listen (fd, 30 /* backlog */) < 0)
1361 saved_errno = errno;
1362 _dbus_close (fd, NULL);
1363 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1364 "Failed to listen on socket \"%s:%s\": %s",
1365 host ? host : "*", port, _dbus_strerror (saved_errno));
1369 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1372 saved_errno = errno;
1373 _dbus_close (fd, NULL);
1374 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1375 "Failed to allocate file handle array: %s",
1376 _dbus_strerror (saved_errno));
1379 listen_fd = newlisten_fd;
1380 listen_fd[nlisten_fd] = fd;
1383 if (!_dbus_string_get_length(retport))
1385 /* If the user didn't specify a port, or used 0, then
1386 the kernel chooses a port. After the first address
1387 is bound to, we need to force all remaining addresses
1388 to use the same port */
1389 if (!port || !strcmp(port, "0"))
1392 struct sockaddr_storage addr;
1396 addrlen = sizeof(addr);
1397 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1400 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1401 portbuf, sizeof(portbuf),
1402 NI_NUMERICHOST)) != 0)
1404 dbus_set_error (error, _dbus_error_from_errno (errno),
1405 "Failed to resolve port \"%s:%s\": %s (%s)",
1406 host ? host : "*", port, gai_strerror(res), res);
1409 if (!_dbus_string_append(retport, portbuf))
1411 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1415 /* Release current address list & redo lookup */
1416 port = _dbus_string_get_const_data(retport);
1418 goto redo_lookup_with_port;
1422 if (!_dbus_string_append(retport, port))
1424 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1438 dbus_set_error (error, _dbus_error_from_errno (errno),
1439 "Failed to bind socket \"%s:%s\": %s",
1440 host ? host : "*", port, _dbus_strerror (errno));
1444 for (i = 0 ; i < nlisten_fd ; i++)
1446 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1459 for (i = 0 ; i < nlisten_fd ; i++)
1460 _dbus_close(listen_fd[i], NULL);
1461 dbus_free(listen_fd);
1466 write_credentials_byte (int server_fd,
1470 char buf[1] = { '\0' };
1471 #if defined(HAVE_CMSGCRED)
1474 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1485 msg.msg_control = (caddr_t) &cmsg;
1486 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1488 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1489 cmsg.hdr.cmsg_level = SOL_SOCKET;
1490 cmsg.hdr.cmsg_type = SCM_CREDS;
1493 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1497 #if defined(HAVE_CMSGCRED)
1498 bytes_written = sendmsg (server_fd, &msg, 0
1499 #if HAVE_DECL_MSG_NOSIGNAL
1504 bytes_written = send (server_fd, buf, 1, 0
1505 #if HAVE_DECL_MSG_NOSIGNAL
1511 if (bytes_written < 0 && errno == EINTR)
1514 if (bytes_written < 0)
1516 dbus_set_error (error, _dbus_error_from_errno (errno),
1517 "Failed to write credentials byte: %s",
1518 _dbus_strerror (errno));
1521 else if (bytes_written == 0)
1523 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1524 "wrote zero bytes writing credentials byte");
1529 _dbus_assert (bytes_written == 1);
1530 _dbus_verbose ("wrote credentials byte\n");
1536 * Reads a single byte which must be nul (an error occurs otherwise),
1537 * and reads unix credentials if available. Clears the credentials
1538 * object, then adds pid/uid if available, so any previous credentials
1539 * stored in the object are lost.
1541 * Return value indicates whether a byte was read, not whether
1542 * we got valid credentials. On some systems, such as Linux,
1543 * reading/writing the byte isn't actually required, but we do it
1544 * anyway just to avoid multiple codepaths.
1546 * Fails if no byte is available, so you must select() first.
1548 * The point of the byte is that on some systems we have to
1549 * use sendmsg()/recvmsg() to transmit credentials.
1551 * @param client_fd the client file descriptor
1552 * @param credentials object to add client credentials to
1553 * @param error location to store error code
1554 * @returns #TRUE on success
1557 _dbus_read_credentials_socket (int client_fd,
1558 DBusCredentials *credentials,
1564 dbus_uid_t uid_read;
1565 dbus_pid_t pid_read;
1568 #ifdef HAVE_CMSGCRED
1571 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1574 #elif defined(LOCAL_CREDS)
1577 struct sockcred cred;
1581 uid_read = DBUS_UID_UNSET;
1582 pid_read = DBUS_PID_UNSET;
1584 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1586 /* The POSIX spec certainly doesn't promise this, but
1587 * we need these assertions to fail as soon as we're wrong about
1588 * it so we can do the porting fixups
1590 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1591 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1592 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1594 _dbus_credentials_clear (credentials);
1596 /* Systems supporting LOCAL_CREDS are configured to have this feature
1597 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1598 * the connection. Therefore, the received message must carry the
1599 * credentials information without doing anything special.
1602 iov.iov_base = &buf;
1609 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1611 msg.msg_control = (caddr_t) &cmsg;
1612 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1616 bytes_read = recvmsg (client_fd, &msg, 0);
1623 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1624 * normally only call read_credentials if the socket was ready
1628 dbus_set_error (error, _dbus_error_from_errno (errno),
1629 "Failed to read credentials byte: %s",
1630 _dbus_strerror (errno));
1633 else if (bytes_read == 0)
1635 /* this should not happen unless we are using recvmsg wrong,
1636 * so is essentially here for paranoia
1638 dbus_set_error (error, DBUS_ERROR_FAILED,
1639 "Failed to read credentials byte (zero-length read)");
1642 else if (buf != '\0')
1644 dbus_set_error (error, DBUS_ERROR_FAILED,
1645 "Credentials byte was not nul");
1649 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1650 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1651 || cmsg.hdr.cmsg_type != SCM_CREDS)
1653 dbus_set_error (error, DBUS_ERROR_FAILED,
1654 "Message from recvmsg() was not SCM_CREDS");
1659 _dbus_verbose ("read credentials byte\n");
1664 struct sockpeercred cr;
1668 int cr_len = sizeof (cr);
1670 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1671 cr_len == sizeof (cr))
1678 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1679 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1681 #elif defined(HAVE_CMSGCRED)
1682 struct cmsgcred *cred;
1684 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1685 pid_read = cred->cmcred_pid;
1686 uid_read = cred->cmcred_euid;
1687 #elif defined(LOCAL_CREDS)
1688 pid_read = DBUS_PID_UNSET;
1689 uid_read = cmsg.cred.sc_uid;
1690 /* Since we have already got the credentials from this socket, we can
1691 * disable its LOCAL_CREDS flag if it was ever set. */
1692 _dbus_set_local_creds (client_fd, FALSE);
1693 #elif defined(HAVE_GETPEEREID)
1696 if (getpeereid (client_fd, &euid, &egid) == 0)
1702 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1704 #elif defined(HAVE_GETPEERUCRED)
1705 ucred_t * ucred = NULL;
1706 if (getpeerucred (client_fd, &ucred) == 0)
1708 pid_read = ucred_getpid (ucred);
1709 uid_read = ucred_geteuid (ucred);
1711 /* generate audit session data based on socket ucred */
1712 adt_session_data_t *adth = NULL;
1713 adt_export_data_t *data = NULL;
1715 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1717 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1721 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1723 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1727 size = adt_export_session_data (adth, &data);
1730 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1734 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1738 (void) adt_end_session (adth);
1740 #endif /* HAVE_ADT */
1744 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1748 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1749 _dbus_verbose ("Socket credentials not supported on this OS\n");
1753 _dbus_verbose ("Credentials:"
1754 " pid "DBUS_PID_FORMAT
1755 " uid "DBUS_UID_FORMAT
1760 if (pid_read != DBUS_PID_UNSET)
1762 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1764 _DBUS_SET_OOM (error);
1769 if (uid_read != DBUS_UID_UNSET)
1771 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1773 _DBUS_SET_OOM (error);
1782 * Sends a single nul byte with our UNIX credentials as ancillary
1783 * data. Returns #TRUE if the data was successfully written. On
1784 * systems that don't support sending credentials, just writes a byte,
1785 * doesn't send any credentials. On some systems, such as Linux,
1786 * reading/writing the byte isn't actually required, but we do it
1787 * anyway just to avoid multiple codepaths.
1789 * Fails if no byte can be written, so you must select() first.
1791 * The point of the byte is that on some systems we have to
1792 * use sendmsg()/recvmsg() to transmit credentials.
1794 * @param server_fd file descriptor for connection to server
1795 * @param error return location for error code
1796 * @returns #TRUE if the byte was sent
1799 _dbus_send_credentials_socket (int server_fd,
1802 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1804 if (write_credentials_byte (server_fd, error))
1811 * Accepts a connection on a listening socket.
1812 * Handles EINTR for you.
1814 * This will enable FD_CLOEXEC for the returned socket.
1816 * @param listen_fd the listen file descriptor
1817 * @returns the connection fd of the client, or -1 on error
1820 _dbus_accept (int listen_fd)
1823 struct sockaddr addr;
1826 dbus_bool_t cloexec_done;
1829 addrlen = sizeof (addr);
1834 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1835 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1836 cloexec_done = client_fd >= 0;
1838 if (client_fd < 0 && errno == ENOSYS)
1841 client_fd = accept (listen_fd, &addr, &addrlen);
1850 _dbus_verbose ("client fd %d accepted\n", client_fd);
1856 _dbus_fd_set_close_on_exec(client_fd);
1863 * Checks to make sure the given directory is
1864 * private to the user
1866 * @param dir the name of the directory
1867 * @param error error return
1868 * @returns #FALSE on failure
1871 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1873 const char *directory;
1876 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1878 directory = _dbus_string_get_const_data (dir);
1880 if (stat (directory, &sb) < 0)
1882 dbus_set_error (error, _dbus_error_from_errno (errno),
1883 "%s", _dbus_strerror (errno));
1888 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1889 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1891 dbus_set_error (error, DBUS_ERROR_FAILED,
1892 "%s directory is not private to the user", directory);
1900 fill_user_info_from_passwd (struct passwd *p,
1904 _dbus_assert (p->pw_name != NULL);
1905 _dbus_assert (p->pw_dir != NULL);
1907 info->uid = p->pw_uid;
1908 info->primary_gid = p->pw_gid;
1909 info->username = _dbus_strdup (p->pw_name);
1910 info->homedir = _dbus_strdup (p->pw_dir);
1912 if (info->username == NULL ||
1913 info->homedir == NULL)
1915 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1923 fill_user_info (DBusUserInfo *info,
1925 const DBusString *username,
1928 const char *username_c;
1930 /* exactly one of username/uid provided */
1931 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1932 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1934 info->uid = DBUS_UID_UNSET;
1935 info->primary_gid = DBUS_GID_UNSET;
1936 info->group_ids = NULL;
1937 info->n_group_ids = 0;
1938 info->username = NULL;
1939 info->homedir = NULL;
1941 if (username != NULL)
1942 username_c = _dbus_string_get_const_data (username);
1946 /* For now assuming that the getpwnam() and getpwuid() flavors
1947 * are always symmetrical, if not we have to add more configure
1951 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1957 struct passwd p_str;
1959 /* retrieve maximum needed size for buf */
1960 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1962 /* sysconf actually returns a long, but everything else expects size_t,
1963 * so just recast here.
1964 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1966 if ((long) buflen <= 0)
1972 buf = dbus_malloc (buflen);
1975 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1980 #ifdef HAVE_POSIX_GETPWNAM_R
1981 if (uid != DBUS_UID_UNSET)
1982 result = getpwuid_r (uid, &p_str, buf, buflen,
1985 result = getpwnam_r (username_c, &p_str, buf, buflen,
1988 if (uid != DBUS_UID_UNSET)
1989 p = getpwuid_r (uid, &p_str, buf, buflen);
1991 p = getpwnam_r (username_c, &p_str, buf, buflen);
1993 #endif /* !HAVE_POSIX_GETPWNAM_R */
1994 //Try a bigger buffer if ERANGE was returned
1995 if (result == ERANGE && buflen < 512 * 1024)
2005 if (result == 0 && p == &p_str)
2007 if (!fill_user_info_from_passwd (p, info, error))
2016 dbus_set_error (error, _dbus_error_from_errno (errno),
2017 "User \"%s\" unknown or no memory to allocate password entry\n",
2018 username_c ? username_c : "???");
2019 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2024 #else /* ! HAVE_GETPWNAM_R */
2026 /* I guess we're screwed on thread safety here */
2029 if (uid != DBUS_UID_UNSET)
2032 p = getpwnam (username_c);
2036 if (!fill_user_info_from_passwd (p, info, error))
2043 dbus_set_error (error, _dbus_error_from_errno (errno),
2044 "User \"%s\" unknown or no memory to allocate password entry\n",
2045 username_c ? username_c : "???");
2046 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2050 #endif /* ! HAVE_GETPWNAM_R */
2052 /* Fill this in so we can use it to get groups */
2053 username_c = info->username;
2055 #ifdef HAVE_GETGROUPLIST
2060 int initial_buf_count;
2062 initial_buf_count = 17;
2063 buf_count = initial_buf_count;
2064 buf = dbus_new (gid_t, buf_count);
2067 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2071 if (getgrouplist (username_c,
2073 buf, &buf_count) < 0)
2076 /* Presumed cause of negative return code: buf has insufficient
2077 entries to hold the entire group list. The Linux behavior in this
2078 case is to pass back the actual number of groups in buf_count, but
2079 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2080 So as a hack, try to help out a bit by guessing a larger
2081 number of groups, within reason.. might still fail, of course,
2082 but we can at least print a more informative message. I looked up
2083 the "right way" to do this by downloading Apple's own source code
2084 for the "id" command, and it turns out that they use an
2085 undocumented library function getgrouplist_2 (!) which is not
2086 declared in any header in /usr/include (!!). That did not seem
2087 like the way to go here.
2089 if (buf_count == initial_buf_count)
2091 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2093 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2096 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2104 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2108 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2109 username_c, buf_count, buf_count);
2113 dbus_set_error (error,
2114 _dbus_error_from_errno (errno),
2115 "Failed to get groups for username \"%s\" primary GID "
2116 DBUS_GID_FORMAT ": %s\n",
2117 username_c, info->primary_gid,
2118 _dbus_strerror (errno));
2125 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2126 if (info->group_ids == NULL)
2128 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2133 for (i = 0; i < buf_count; ++i)
2134 info->group_ids[i] = buf[i];
2136 info->n_group_ids = buf_count;
2140 #else /* HAVE_GETGROUPLIST */
2142 /* We just get the one group ID */
2143 info->group_ids = dbus_new (dbus_gid_t, 1);
2144 if (info->group_ids == NULL)
2146 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2150 info->n_group_ids = 1;
2152 (info->group_ids)[0] = info->primary_gid;
2154 #endif /* HAVE_GETGROUPLIST */
2156 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2161 _DBUS_ASSERT_ERROR_IS_SET (error);
2166 * Gets user info for the given username.
2168 * @param info user info object to initialize
2169 * @param username the username
2170 * @param error error return
2171 * @returns #TRUE on success
2174 _dbus_user_info_fill (DBusUserInfo *info,
2175 const DBusString *username,
2178 return fill_user_info (info, DBUS_UID_UNSET,
2183 * Gets user info for the given user ID.
2185 * @param info user info object to initialize
2186 * @param uid the user ID
2187 * @param error error return
2188 * @returns #TRUE on success
2191 _dbus_user_info_fill_uid (DBusUserInfo *info,
2195 return fill_user_info (info, uid,
2200 * Adds the credentials of the current process to the
2201 * passed-in credentials object.
2203 * @param credentials credentials to add to
2204 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2207 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2209 /* The POSIX spec certainly doesn't promise this, but
2210 * we need these assertions to fail as soon as we're wrong about
2211 * it so we can do the porting fixups
2213 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2214 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2215 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2217 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2219 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2226 * Append to the string the identity we would like to have when we
2227 * authenticate, on UNIX this is the current process UID and on
2228 * Windows something else, probably a Windows SID string. No escaping
2229 * is required, that is done in dbus-auth.c. The username here
2230 * need not be anything human-readable, it can be the machine-readable
2231 * form i.e. a user id.
2233 * @param str the string to append to
2234 * @returns #FALSE on no memory
2237 _dbus_append_user_from_current_process (DBusString *str)
2239 return _dbus_string_append_uint (str,
2244 * Gets our process ID
2245 * @returns process ID
2254 * @returns process UID
2262 /** Gets our effective UID
2263 * @returns process effective UID
2266 _dbus_geteuid (void)
2272 * The only reason this is separate from _dbus_getpid() is to allow it
2273 * on Windows for logging but not for other purposes.
2275 * @returns process ID to put in log messages
2278 _dbus_pid_for_log (void)
2284 * Gets a UID from a UID string.
2286 * @param uid_str the UID in string form
2287 * @param uid UID to fill in
2288 * @returns #TRUE if successfully filled in UID
2291 _dbus_parse_uid (const DBusString *uid_str,
2297 if (_dbus_string_get_length (uid_str) == 0)
2299 _dbus_verbose ("UID string was zero length\n");
2305 if (!_dbus_string_parse_int (uid_str, 0, &val,
2308 _dbus_verbose ("could not parse string as a UID\n");
2312 if (end != _dbus_string_get_length (uid_str))
2314 _dbus_verbose ("string contained trailing stuff after UID\n");
2324 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2328 * Atomically increments an integer
2330 * @param atomic pointer to the integer to increment
2331 * @returns the value before incrementing
2334 _dbus_atomic_inc (DBusAtomic *atomic)
2337 return __sync_add_and_fetch(&atomic->value, 1)-1;
2340 _DBUS_LOCK (atomic);
2341 res = atomic->value;
2343 _DBUS_UNLOCK (atomic);
2349 * Atomically decrement an integer
2351 * @param atomic pointer to the integer to decrement
2352 * @returns the value before decrementing
2355 _dbus_atomic_dec (DBusAtomic *atomic)
2358 return __sync_sub_and_fetch(&atomic->value, 1)+1;
2362 _DBUS_LOCK (atomic);
2363 res = atomic->value;
2365 _DBUS_UNLOCK (atomic);
2370 #ifdef DBUS_BUILD_TESTS
2372 * @returns process GID
2382 * Wrapper for poll().
2384 * @param fds the file descriptors to poll
2385 * @param n_fds number of descriptors in the array
2386 * @param timeout_milliseconds timeout or -1 for infinite
2387 * @returns numbers of fds with revents, or <0 on error
2390 _dbus_poll (DBusPollFD *fds,
2392 int timeout_milliseconds)
2394 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2395 /* This big thing is a constant expression and should get optimized
2396 * out of existence. So it's more robust than a configure check at
2399 if (_DBUS_POLLIN == POLLIN &&
2400 _DBUS_POLLPRI == POLLPRI &&
2401 _DBUS_POLLOUT == POLLOUT &&
2402 _DBUS_POLLERR == POLLERR &&
2403 _DBUS_POLLHUP == POLLHUP &&
2404 _DBUS_POLLNVAL == POLLNVAL &&
2405 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2406 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2407 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2408 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2409 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2410 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2411 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2413 return poll ((struct pollfd*) fds,
2415 timeout_milliseconds);
2419 /* We have to convert the DBusPollFD to an array of
2420 * struct pollfd, poll, and convert back.
2422 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2425 #else /* ! HAVE_POLL */
2427 fd_set read_set, write_set, err_set;
2433 FD_ZERO (&read_set);
2434 FD_ZERO (&write_set);
2437 for (i = 0; i < n_fds; i++)
2439 DBusPollFD *fdp = &fds[i];
2441 if (fdp->events & _DBUS_POLLIN)
2442 FD_SET (fdp->fd, &read_set);
2444 if (fdp->events & _DBUS_POLLOUT)
2445 FD_SET (fdp->fd, &write_set);
2447 FD_SET (fdp->fd, &err_set);
2449 max_fd = MAX (max_fd, fdp->fd);
2452 tv.tv_sec = timeout_milliseconds / 1000;
2453 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2455 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2456 timeout_milliseconds < 0 ? NULL : &tv);
2460 for (i = 0; i < n_fds; i++)
2462 DBusPollFD *fdp = &fds[i];
2466 if (FD_ISSET (fdp->fd, &read_set))
2467 fdp->revents |= _DBUS_POLLIN;
2469 if (FD_ISSET (fdp->fd, &write_set))
2470 fdp->revents |= _DBUS_POLLOUT;
2472 if (FD_ISSET (fdp->fd, &err_set))
2473 fdp->revents |= _DBUS_POLLERR;
2482 * Get current time, as in gettimeofday(). Use the monotonic clock if
2483 * available, to avoid problems when the system time changes.
2485 * @param tv_sec return location for number of seconds
2486 * @param tv_usec return location for number of microseconds (thousandths)
2489 _dbus_get_current_time (long *tv_sec,
2494 #ifdef HAVE_MONOTONIC_CLOCK
2496 clock_gettime (CLOCK_MONOTONIC, &ts);
2499 *tv_sec = ts.tv_sec;
2501 *tv_usec = ts.tv_nsec / 1000;
2503 gettimeofday (&t, NULL);
2508 *tv_usec = t.tv_usec;
2513 * Creates a directory; succeeds if the directory
2514 * is created or already existed.
2516 * @param filename directory filename
2517 * @param error initialized error object
2518 * @returns #TRUE on success
2521 _dbus_create_directory (const DBusString *filename,
2524 const char *filename_c;
2526 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2528 filename_c = _dbus_string_get_const_data (filename);
2530 if (mkdir (filename_c, 0700) < 0)
2532 if (errno == EEXIST)
2535 dbus_set_error (error, DBUS_ERROR_FAILED,
2536 "Failed to create directory %s: %s\n",
2537 filename_c, _dbus_strerror (errno));
2545 * Appends the given filename to the given directory.
2547 * @todo it might be cute to collapse multiple '/' such as "foo//"
2550 * @param dir the directory name
2551 * @param next_component the filename
2552 * @returns #TRUE on success
2555 _dbus_concat_dir_and_file (DBusString *dir,
2556 const DBusString *next_component)
2558 dbus_bool_t dir_ends_in_slash;
2559 dbus_bool_t file_starts_with_slash;
2561 if (_dbus_string_get_length (dir) == 0 ||
2562 _dbus_string_get_length (next_component) == 0)
2565 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2566 _dbus_string_get_length (dir) - 1);
2568 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2570 if (dir_ends_in_slash && file_starts_with_slash)
2572 _dbus_string_shorten (dir, 1);
2574 else if (!(dir_ends_in_slash || file_starts_with_slash))
2576 if (!_dbus_string_append_byte (dir, '/'))
2580 return _dbus_string_copy (next_component, 0, dir,
2581 _dbus_string_get_length (dir));
2584 /** nanoseconds in a second */
2585 #define NANOSECONDS_PER_SECOND 1000000000
2586 /** microseconds in a second */
2587 #define MICROSECONDS_PER_SECOND 1000000
2588 /** milliseconds in a second */
2589 #define MILLISECONDS_PER_SECOND 1000
2590 /** nanoseconds in a millisecond */
2591 #define NANOSECONDS_PER_MILLISECOND 1000000
2592 /** microseconds in a millisecond */
2593 #define MICROSECONDS_PER_MILLISECOND 1000
2596 * Sleeps the given number of milliseconds.
2597 * @param milliseconds number of milliseconds
2600 _dbus_sleep_milliseconds (int milliseconds)
2602 #ifdef HAVE_NANOSLEEP
2603 struct timespec req;
2604 struct timespec rem;
2606 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2607 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2611 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2613 #elif defined (HAVE_USLEEP)
2614 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2615 #else /* ! HAVE_USLEEP */
2616 sleep (MAX (milliseconds / 1000, 1));
2621 _dbus_generate_pseudorandom_bytes (DBusString *str,
2627 old_len = _dbus_string_get_length (str);
2629 if (!_dbus_string_lengthen (str, n_bytes))
2632 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2634 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2640 * Generates the given number of random bytes,
2641 * using the best mechanism we can come up with.
2643 * @param str the string
2644 * @param n_bytes the number of random bytes to append to string
2645 * @returns #TRUE on success, #FALSE if no memory
2648 _dbus_generate_random_bytes (DBusString *str,
2654 /* FALSE return means "no memory", if it could
2655 * mean something else then we'd need to return
2656 * a DBusError. So we always fall back to pseudorandom
2660 old_len = _dbus_string_get_length (str);
2663 /* note, urandom on linux will fall back to pseudorandom */
2664 fd = open ("/dev/urandom", O_RDONLY);
2666 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2668 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2670 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2672 _dbus_close (fd, NULL);
2673 _dbus_string_set_length (str, old_len);
2674 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2677 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2680 _dbus_close (fd, NULL);
2686 * Exit the process, returning the given value.
2688 * @param code the exit code
2691 _dbus_exit (int code)
2697 * A wrapper around strerror() because some platforms
2698 * may be lame and not have strerror(). Also, never
2701 * @param error_number errno.
2702 * @returns error description.
2705 _dbus_strerror (int error_number)
2709 msg = strerror (error_number);
2717 * signal (SIGPIPE, SIG_IGN);
2720 _dbus_disable_sigpipe (void)
2722 signal (SIGPIPE, SIG_IGN);
2726 * Sets the file descriptor to be close
2727 * on exec. Should be called for all file
2728 * descriptors in D-Bus code.
2730 * @param fd the file descriptor
2733 _dbus_fd_set_close_on_exec (intptr_t fd)
2737 val = fcntl (fd, F_GETFD, 0);
2744 fcntl (fd, F_SETFD, val);
2748 * Closes a file descriptor.
2750 * @param fd the file descriptor
2751 * @param error error object
2752 * @returns #FALSE if error set
2755 _dbus_close (int fd,
2758 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2766 dbus_set_error (error, _dbus_error_from_errno (errno),
2767 "Could not close fd %d", fd);
2775 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2776 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2778 * @param fd the file descriptor to duplicate
2779 * @returns duplicated file descriptor
2787 #ifdef F_DUPFD_CLOEXEC
2788 dbus_bool_t cloexec_done;
2790 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2791 cloexec_done = new_fd >= 0;
2793 if (new_fd < 0 && errno == EINVAL)
2796 new_fd = fcntl(fd, F_DUPFD, 3);
2801 dbus_set_error (error, _dbus_error_from_errno (errno),
2802 "Could not duplicate fd %d", fd);
2806 #ifdef F_DUPFD_CLOEXEC
2810 _dbus_fd_set_close_on_exec(new_fd);
2817 * Sets a file descriptor to be nonblocking.
2819 * @param fd the file descriptor.
2820 * @param error address of error location.
2821 * @returns #TRUE on success.
2824 _dbus_set_fd_nonblocking (int fd,
2829 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2831 val = fcntl (fd, F_GETFL, 0);
2834 dbus_set_error (error, _dbus_error_from_errno (errno),
2835 "Failed to get flags from file descriptor %d: %s",
2836 fd, _dbus_strerror (errno));
2837 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2838 _dbus_strerror (errno));
2842 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2844 dbus_set_error (error, _dbus_error_from_errno (errno),
2845 "Failed to set nonblocking flag of file descriptor %d: %s",
2846 fd, _dbus_strerror (errno));
2847 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2848 fd, _dbus_strerror (errno));
2857 * On GNU libc systems, print a crude backtrace to stderr. On other
2858 * systems, print "no backtrace support" and block for possible gdb
2859 * attachment if an appropriate environment variable is set.
2862 _dbus_print_backtrace (void)
2864 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2870 bt_size = backtrace (bt, 500);
2872 syms = backtrace_symbols (bt, bt_size);
2877 /* don't use dbus_warn since it can _dbus_abort() */
2878 fprintf (stderr, " %s\n", syms[i]);
2884 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2885 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2887 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2892 * Creates a full-duplex pipe (as in socketpair()).
2893 * Sets both ends of the pipe nonblocking.
2895 * Marks both file descriptors as close-on-exec
2897 * @todo libdbus only uses this for the debug-pipe server, so in
2898 * principle it could be in dbus-sysdeps-util.c, except that
2899 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2900 * debug-pipe server is used.
2902 * @param fd1 return location for one end
2903 * @param fd2 return location for the other end
2904 * @param blocking #TRUE if pipe should be blocking
2905 * @param error error return
2906 * @returns #FALSE on failure (if error is set)
2909 _dbus_full_duplex_pipe (int *fd1,
2911 dbus_bool_t blocking,
2914 #ifdef HAVE_SOCKETPAIR
2919 dbus_bool_t cloexec_done;
2921 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2922 cloexec_done = retval >= 0;
2924 if (retval < 0 && errno == EINVAL)
2927 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2932 dbus_set_error (error, _dbus_error_from_errno (errno),
2933 "Could not create full-duplex pipe");
2937 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2943 _dbus_fd_set_close_on_exec (fds[0]);
2944 _dbus_fd_set_close_on_exec (fds[1]);
2948 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2949 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2951 dbus_set_error (error, _dbus_error_from_errno (errno),
2952 "Could not set full-duplex pipe nonblocking");
2954 _dbus_close (fds[0], NULL);
2955 _dbus_close (fds[1], NULL);
2963 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2968 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2969 dbus_set_error (error, DBUS_ERROR_FAILED,
2970 "_dbus_full_duplex_pipe() not implemented on this OS");
2976 * Measure the length of the given format string and arguments,
2977 * not including the terminating nul.
2979 * @param format a printf-style format string
2980 * @param args arguments for the format string
2981 * @returns length of the given format string and args
2984 _dbus_printf_string_upper_bound (const char *format,
2988 return vsnprintf (&c, 1, format, args);
2992 * Gets the temporary files directory by inspecting the environment variables
2993 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
2995 * @returns location of temp directory
2998 _dbus_get_tmpdir(void)
3000 static const char* tmpdir = NULL;
3004 /* TMPDIR is what glibc uses, then
3005 * glibc falls back to the P_tmpdir macro which
3006 * just expands to "/tmp"
3009 tmpdir = getenv("TMPDIR");
3011 /* These two env variables are probably
3012 * broken, but maybe some OS uses them?
3015 tmpdir = getenv("TMP");
3017 tmpdir = getenv("TEMP");
3019 /* And this is the sane fallback. */
3024 _dbus_assert(tmpdir != NULL);
3030 * Execute a subprocess, returning up to 1024 bytes of output
3033 * If successful, returns #TRUE and appends the output to @p
3034 * result. If a failure happens, returns #FALSE and
3035 * sets an error in @p error.
3037 * @note It's not an error if the subprocess terminates normally
3038 * without writing any data to stdout. Verify the @p result length
3039 * before and after this function call to cover this case.
3041 * @param progname initial path to exec (may or may not be absolute)
3042 * @param path_fallback if %TRUE, search PATH for executable
3043 * @param argv NULL-terminated list of arguments
3044 * @param result a DBusString where the output can be append
3045 * @param error a DBusError to store the error in case of failure
3046 * @returns #TRUE on success, #FALSE if an error happened
3049 _read_subprocess_line_argv (const char *progpath,
3050 dbus_bool_t path_fallback,
3055 int result_pipe[2] = { -1, -1 };
3056 int errors_pipe[2] = { -1, -1 };
3064 sigset_t new_set, old_set;
3066 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3069 /* We need to block any existing handlers for SIGCHLD temporarily; they
3070 * will cause waitpid() below to fail.
3071 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3073 sigemptyset (&new_set);
3074 sigaddset (&new_set, SIGCHLD);
3075 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3077 orig_len = _dbus_string_get_length (result);
3081 if (pipe (result_pipe) < 0)
3083 dbus_set_error (error, _dbus_error_from_errno (errno),
3084 "Failed to create a pipe to call %s: %s",
3085 progpath, _dbus_strerror (errno));
3086 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3087 progpath, _dbus_strerror (errno));
3090 if (pipe (errors_pipe) < 0)
3092 dbus_set_error (error, _dbus_error_from_errno (errno),
3093 "Failed to create a pipe to call %s: %s",
3094 progpath, _dbus_strerror (errno));
3095 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3096 progpath, _dbus_strerror (errno));
3103 dbus_set_error (error, _dbus_error_from_errno (errno),
3104 "Failed to fork() to call %s: %s",
3105 progpath, _dbus_strerror (errno));
3106 _dbus_verbose ("Failed to fork() to call %s: %s\n",
3107 progpath, _dbus_strerror (errno));
3117 fd = open ("/dev/null", O_RDWR);
3119 /* huh?! can't open /dev/null? */
3122 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3125 close (result_pipe[READ_END]);
3126 close (errors_pipe[READ_END]);
3127 close (0); /* close stdin */
3128 close (1); /* close stdout */
3129 close (2); /* close stderr */
3131 if (dup2 (fd, 0) == -1)
3133 if (dup2 (result_pipe[WRITE_END], 1) == -1)
3135 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3138 maxfds = sysconf (_SC_OPEN_MAX);
3139 /* Pick something reasonable if for some reason sysconf
3144 /* close all inherited fds */
3145 for (i = 3; i < maxfds; i++)
3148 sigprocmask (SIG_SETMASK, &old_set, NULL);
3150 /* If it looks fully-qualified, try execv first */
3151 if (progpath[0] == '/')
3153 execv (progpath, argv);
3154 /* Ok, that failed. Now if path_fallback is given, let's
3155 * try unqualified. This is mostly a hack to work
3156 * around systems which ship dbus-launch in /usr/bin
3157 * but everything else in /bin (because dbus-launch
3161 /* We must have a slash, because we checked above */
3162 execvp (strrchr (progpath, '/')+1, argv);
3165 execvp (progpath, argv);
3167 /* still nothing, we failed */
3171 /* parent process */
3172 close (result_pipe[WRITE_END]);
3173 close (errors_pipe[WRITE_END]);
3174 result_pipe[WRITE_END] = -1;
3175 errors_pipe[WRITE_END] = -1;
3180 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3184 /* reap the child process to avoid it lingering as zombie */
3187 ret = waitpid (pid, &status, 0);
3189 while (ret == -1 && errno == EINTR);
3191 /* We succeeded if the process exited with status 0 and
3192 anything was read */
3193 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3195 /* The process ended with error */
3196 DBusString error_message;
3197 if (!_dbus_string_init (&error_message))
3199 _DBUS_SET_OOM (error);
3206 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3210 _dbus_string_set_length (result, orig_len);
3211 if (_dbus_string_get_length (&error_message) > 0)
3212 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3213 "%s terminated abnormally with the following error: %s",
3214 progpath, _dbus_string_get_data (&error_message));
3216 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3217 "%s terminated abnormally without any error message",
3225 sigprocmask (SIG_SETMASK, &old_set, NULL);
3228 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3230 _DBUS_ASSERT_ERROR_IS_SET (error);
3232 if (result_pipe[0] != -1)
3233 close (result_pipe[0]);
3234 if (result_pipe[1] != -1)
3235 close (result_pipe[1]);
3236 if (errors_pipe[0] != -1)
3237 close (errors_pipe[0]);
3238 if (errors_pipe[1] != -1)
3239 close (errors_pipe[1]);
3245 * Returns the address of a new session bus.
3247 * If successful, returns #TRUE and appends the address to @p
3248 * address. If a failure happens, returns #FALSE and
3249 * sets an error in @p error.
3251 * @param address a DBusString where the address can be stored
3252 * @param error a DBusError to store the error in case of failure
3253 * @returns #TRUE on success, #FALSE if an error happened
3256 _dbus_get_autolaunch_address (const char *scope,
3257 DBusString *address,
3260 static char *argv[6];
3265 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3268 if (!_dbus_string_init (&uuid))
3270 _DBUS_SET_OOM (error);
3274 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3276 _DBUS_SET_OOM (error);
3281 argv[i] = "dbus-launch";
3283 argv[i] = "--autolaunch";
3285 argv[i] = _dbus_string_get_data (&uuid);
3287 argv[i] = "--binary-syntax";
3289 argv[i] = "--close-stderr";
3294 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3296 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3298 argv, address, error);
3301 _dbus_string_free (&uuid);
3306 * Reads the uuid of the machine we're running on from
3307 * the dbus configuration. Optionally try to create it
3308 * (only root can do this usually).
3310 * On UNIX, reads a file that gets created by dbus-uuidgen
3311 * in a post-install script. On Windows, if there's a standard
3312 * machine uuid we could just use that, but I can't find one
3313 * with the right properties (the hardware profile guid can change
3314 * without rebooting I believe). If there's no standard one
3315 * we might want to use the registry instead of a file for
3316 * this, and I'm not sure how we'd ensure the uuid gets created.
3318 * @param machine_id guid to init with the machine's uuid
3319 * @param create_if_not_found try to create the uuid if it doesn't exist
3320 * @param error the error return
3321 * @returns #FALSE if the error is set
3324 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3325 dbus_bool_t create_if_not_found,
3328 DBusString filename;
3329 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3330 return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3333 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3334 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3337 * quries launchd for a specific env var which holds the socket path.
3338 * @param launchd_env_var the env var to look up
3339 * @param error a DBusError to store the error in case of failure
3340 * @return the value of the env var
3343 _dbus_lookup_launchd_socket (DBusString *socket_path,
3344 const char *launchd_env_var,
3347 #ifdef DBUS_ENABLE_LAUNCHD
3351 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3354 argv[i] = "launchctl";
3358 argv[i] = (char*)launchd_env_var;
3363 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3365 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3370 /* no error, but no result either */
3371 if (_dbus_string_get_length(socket_path) == 0)
3376 /* strip the carriage-return */
3377 _dbus_string_shorten(socket_path, 1);
3379 #else /* DBUS_ENABLE_LAUNCHD */
3380 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3381 "can't lookup socket from launchd; launchd support not compiled in");
3387 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3389 #ifdef DBUS_ENABLE_LAUNCHD
3390 dbus_bool_t valid_socket;
3391 DBusString socket_path;
3393 if (!_dbus_string_init (&socket_path))
3395 _DBUS_SET_OOM (error);
3399 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3401 if (dbus_error_is_set(error))
3403 _dbus_string_free(&socket_path);
3409 dbus_set_error(error, "no socket path",
3410 "launchd did not provide a socket path, "
3411 "verify that org.freedesktop.dbus-session.plist is loaded!");
3412 _dbus_string_free(&socket_path);
3415 if (!_dbus_string_append (address, "unix:path="))
3417 _DBUS_SET_OOM (error);
3418 _dbus_string_free(&socket_path);
3421 if (!_dbus_string_copy (&socket_path, 0, address,
3422 _dbus_string_get_length (address)))
3424 _DBUS_SET_OOM (error);
3425 _dbus_string_free(&socket_path);
3429 _dbus_string_free(&socket_path);
3432 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3433 "can't lookup session address from launchd; launchd support not compiled in");
3439 * Determines the address of the session bus by querying a
3440 * platform-specific method.
3442 * The first parameter will be a boolean specifying whether
3443 * or not a dynamic session lookup is supported on this platform.
3445 * If supported is TRUE and the return value is #TRUE, the
3446 * address will be appended to @p address.
3447 * If a failure happens, returns #FALSE and sets an error in
3450 * If supported is FALSE, ignore the return value.
3452 * @param supported returns whether this method is supported
3453 * @param address a DBusString where the address can be stored
3454 * @param error a DBusError to store the error in case of failure
3455 * @returns #TRUE on success, #FALSE if an error happened
3458 _dbus_lookup_session_address (dbus_bool_t *supported,
3459 DBusString *address,
3462 #ifdef DBUS_ENABLE_LAUNCHD
3464 return _dbus_lookup_session_address_launchd (address, error);
3466 /* On non-Mac Unix platforms, if the session address isn't already
3467 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3468 * fall back to the autolaunch: global default; see
3469 * init_session_address in dbus/dbus-bus.c. */
3476 * Returns the standard directories for a session bus to look for service
3479 * On UNIX this should be the standard xdg freedesktop.org data directories:
3481 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3482 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3488 * @param dirs the directory list we are returning
3489 * @returns #FALSE on OOM
3493 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3495 const char *xdg_data_home;
3496 const char *xdg_data_dirs;
3497 DBusString servicedir_path;
3499 if (!_dbus_string_init (&servicedir_path))
3502 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3503 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3505 if (xdg_data_home != NULL)
3507 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3512 const DBusString *homedir;
3513 DBusString local_share;
3515 if (!_dbus_homedir_from_current_process (&homedir))
3518 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3521 _dbus_string_init_const (&local_share, "/.local/share");
3522 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3526 if (!_dbus_string_append (&servicedir_path, ":"))
3529 if (xdg_data_dirs != NULL)
3531 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3534 if (!_dbus_string_append (&servicedir_path, ":"))
3539 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3544 * add configured datadir to defaults
3545 * this may be the same as an xdg dir
3546 * however the config parser should take
3547 * care of duplicates
3549 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3552 if (!_dbus_split_paths_and_append (&servicedir_path,
3553 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3557 _dbus_string_free (&servicedir_path);
3561 _dbus_string_free (&servicedir_path);
3567 * Returns the standard directories for a system bus to look for service
3570 * On UNIX this should be the standard xdg freedesktop.org data directories:
3572 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3578 * On Windows there is no system bus and this function can return nothing.
3580 * @param dirs the directory list we are returning
3581 * @returns #FALSE on OOM
3585 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3587 const char *xdg_data_dirs;
3588 DBusString servicedir_path;
3590 if (!_dbus_string_init (&servicedir_path))
3593 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3595 if (xdg_data_dirs != NULL)
3597 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3600 if (!_dbus_string_append (&servicedir_path, ":"))
3605 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3610 * add configured datadir to defaults
3611 * this may be the same as an xdg dir
3612 * however the config parser should take
3613 * care of duplicates
3615 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3618 if (!_dbus_split_paths_and_append (&servicedir_path,
3619 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3623 _dbus_string_free (&servicedir_path);
3627 _dbus_string_free (&servicedir_path);
3632 * Append the absolute path of the system.conf file
3633 * (there is no system bus on Windows so this can just
3634 * return FALSE and print a warning or something)
3636 * @param str the string to append to
3637 * @returns #FALSE if no memory
3640 _dbus_append_system_config_file (DBusString *str)
3642 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3646 * Append the absolute path of the session.conf file.
3648 * @param str the string to append to
3649 * @returns #FALSE if no memory
3652 _dbus_append_session_config_file (DBusString *str)
3654 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3658 * Called when the bus daemon is signaled to reload its configuration; any
3659 * caches should be nuked. Of course any caches that need explicit reload
3660 * are probably broken, but c'est la vie.
3665 _dbus_flush_caches (void)
3667 _dbus_user_database_flush_system ();
3671 * Appends the directory in which a keyring for the given credentials
3672 * should be stored. The credentials should have either a Windows or
3673 * UNIX user in them. The directory should be an absolute path.
3675 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3676 * be something else, since the dotfile convention is not normal on Windows.
3678 * @param directory string to append directory to
3679 * @param credentials credentials the directory should be for
3681 * @returns #FALSE on no memory
3684 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3685 DBusCredentials *credentials)
3691 _dbus_assert (credentials != NULL);
3692 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3694 if (!_dbus_string_init (&homedir))
3697 uid = _dbus_credentials_get_unix_uid (credentials);
3698 _dbus_assert (uid != DBUS_UID_UNSET);
3700 if (!_dbus_homedir_from_uid (uid, &homedir))
3703 #ifdef DBUS_BUILD_TESTS
3705 const char *override;
3707 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3708 if (override != NULL && *override != '\0')
3710 _dbus_string_set_length (&homedir, 0);
3711 if (!_dbus_string_append (&homedir, override))
3714 _dbus_verbose ("Using fake homedir for testing: %s\n",
3715 _dbus_string_get_const_data (&homedir));
3719 static dbus_bool_t already_warned = FALSE;
3720 if (!already_warned)
3722 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3723 already_warned = TRUE;
3729 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3730 if (!_dbus_concat_dir_and_file (&homedir,
3734 if (!_dbus_string_copy (&homedir, 0,
3735 directory, _dbus_string_get_length (directory))) {
3739 _dbus_string_free (&homedir);
3743 _dbus_string_free (&homedir);
3747 //PENDING(kdab) docs
3749 _dbus_daemon_publish_session_bus_address (const char* addr,
3755 //PENDING(kdab) docs
3757 _dbus_daemon_unpublish_session_bus_address (void)
3763 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3764 * for Winsock so is abstracted)
3766 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3769 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3771 return errno == EAGAIN || errno == EWOULDBLOCK;
3775 * Removes a directory; Directory must be empty
3777 * @param filename directory filename
3778 * @param error initialized error object
3779 * @returns #TRUE on success
3782 _dbus_delete_directory (const DBusString *filename,
3785 const char *filename_c;
3787 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3789 filename_c = _dbus_string_get_const_data (filename);
3791 if (rmdir (filename_c) != 0)
3793 dbus_set_error (error, DBUS_ERROR_FAILED,
3794 "Failed to remove directory %s: %s\n",
3795 filename_c, _dbus_strerror (errno));
3803 * Checks whether file descriptors may be passed via the socket
3805 * @param fd the socket
3806 * @return TRUE when fd passing over this socket is supported
3810 _dbus_socket_can_pass_unix_fd(int fd) {
3815 struct sockaddr_storage storage;
3816 struct sockaddr_un un;
3819 socklen_t sa_len = sizeof(sa_buf);
3823 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3826 return sa_buf.sa.sa_family == AF_UNIX;
3836 * replaces the term DBUS_PREFIX in configure_time_path by the
3837 * current dbus installation directory. On unix this function is a noop
3839 * @param configure_time_path
3843 _dbus_replace_install_prefix (const char *configure_time_path)
3845 return configure_time_path;
3848 /* tests in dbus-sysdeps-util.c */