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
93 #if defined (__sun) || defined (__sun__)
95 * CMS_SPACE etc. definitions for Solaris < 10, based on
96 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
98 * http://wiki.opencsw.org/porting-faq#toc10
100 * These are only redefined for Solaris, for now: if your OS needs these too,
101 * please file a bug. (Or preferably, improve your OS so they're not needed.)
106 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
108 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
109 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
110 ~(sizeof (long) - 1))
115 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
120 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
126 _dbus_open_socket (int *fd_p,
133 dbus_bool_t cloexec_done;
135 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
136 cloexec_done = *fd_p >= 0;
138 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
139 if (*fd_p < 0 && errno == EINVAL)
142 *fd_p = socket (domain, type, protocol);
151 _dbus_fd_set_close_on_exec(*fd_p);
154 _dbus_verbose ("socket fd %d opened\n", *fd_p);
159 dbus_set_error(error,
160 _dbus_error_from_errno (errno),
161 "Failed to open socket: %s",
162 _dbus_strerror (errno));
168 _dbus_open_tcp_socket (int *fd,
171 return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
175 * Opens a UNIX domain socket (as in the socket() call).
176 * Does not bind the socket.
178 * This will set FD_CLOEXEC for the socket returned
180 * @param fd return location for socket descriptor
181 * @param error return location for an error
182 * @returns #FALSE if error is set
185 _dbus_open_unix_socket (int *fd,
188 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
192 * Closes a socket. Should not be used on non-socket
193 * file descriptors or handles.
195 * @param fd the socket
196 * @param error return location for an error
197 * @returns #FALSE if error is set
200 _dbus_close_socket (int fd,
203 return _dbus_close (fd, error);
207 * Like _dbus_read(), but only works on sockets so is
208 * available on Windows.
210 * @param fd the socket
211 * @param buffer string to append data to
212 * @param count max amount of data to read
213 * @returns number of bytes appended to the string
216 _dbus_read_socket (int fd,
220 return _dbus_read (fd, buffer, count);
224 * Like _dbus_write(), but only supports sockets
225 * and is thus available on Windows.
227 * @param fd the file descriptor to write
228 * @param buffer the buffer to write data from
229 * @param start the first byte in the buffer to write
230 * @param len the number of bytes to try to write
231 * @returns the number of bytes written or -1 on error
234 _dbus_write_socket (int fd,
235 const DBusString *buffer,
239 #if HAVE_DECL_MSG_NOSIGNAL
243 data = _dbus_string_get_const_data_len (buffer, start, len);
247 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
249 if (bytes_written < 0 && errno == EINTR)
252 return bytes_written;
255 return _dbus_write (fd, buffer, start, len);
260 * Like _dbus_read_socket() but also tries to read unix fds from the
261 * socket. When there are more fds to read than space in the array
262 * passed this function will fail with ENOSPC.
264 * @param fd the socket
265 * @param buffer string to append data to
266 * @param count max amount of data to read
267 * @param fds array to place read file descriptors in
268 * @param n_fds on input space in fds array, on output how many fds actually got read
269 * @returns number of bytes appended to string
272 _dbus_read_socket_with_unix_fds (int fd,
277 #ifndef HAVE_UNIX_FD_PASSING
280 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
292 _dbus_assert (count >= 0);
293 _dbus_assert (*n_fds >= 0);
295 start = _dbus_string_get_length (buffer);
297 if (!_dbus_string_lengthen (buffer, count))
304 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
311 /* Hmm, we have no clue how long the control data will actually be
312 that is queued for us. The least we can do is assume that the
313 caller knows. Hence let's make space for the number of fds that
314 we shall read at max plus the cmsg header. */
315 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
317 /* It's probably safe to assume that systems with SCM_RIGHTS also
319 m.msg_control = alloca(m.msg_controllen);
320 memset(m.msg_control, 0, m.msg_controllen);
324 bytes_read = recvmsg(fd, &m, 0
325 #ifdef MSG_CMSG_CLOEXEC
336 /* put length back (note that this doesn't actually realloc anything) */
337 _dbus_string_set_length (buffer, start);
344 dbus_bool_t found = FALSE;
346 if (m.msg_flags & MSG_CTRUNC)
348 /* Hmm, apparently the control data was truncated. The bad
349 thing is that we might have completely lost a couple of fds
350 without chance to recover them. Hence let's treat this as a
354 _dbus_string_set_length (buffer, start);
358 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
359 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
363 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
364 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
366 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
369 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
370 worked, hence we need to go through this list and set
371 CLOEXEC everywhere in any case */
372 for (i = 0; i < *n_fds; i++)
373 _dbus_fd_set_close_on_exec(fds[i]);
381 /* put length back (doesn't actually realloc) */
382 _dbus_string_set_length (buffer, start + bytes_read);
386 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
395 _dbus_write_socket_with_unix_fds(int fd,
396 const DBusString *buffer,
402 #ifndef HAVE_UNIX_FD_PASSING
409 return _dbus_write_socket(fd, buffer, start, len);
411 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
416 _dbus_write_socket_with_unix_fds_two(int fd,
417 const DBusString *buffer1,
420 const DBusString *buffer2,
426 #ifndef HAVE_UNIX_FD_PASSING
433 return _dbus_write_socket_two(fd,
434 buffer1, start1, len1,
435 buffer2, start2, len2);
443 _dbus_assert (len1 >= 0);
444 _dbus_assert (len2 >= 0);
445 _dbus_assert (n_fds >= 0);
448 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
449 iov[0].iov_len = len1;
453 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
454 iov[1].iov_len = len2;
459 m.msg_iovlen = buffer2 ? 2 : 1;
463 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
464 m.msg_control = alloca(m.msg_controllen);
465 memset(m.msg_control, 0, m.msg_controllen);
467 cm = CMSG_FIRSTHDR(&m);
468 cm->cmsg_level = SOL_SOCKET;
469 cm->cmsg_type = SCM_RIGHTS;
470 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
471 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
476 bytes_written = sendmsg (fd, &m, 0
477 #if HAVE_DECL_MSG_NOSIGNAL
482 if (bytes_written < 0 && errno == EINTR)
486 if (bytes_written > 0)
487 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
490 return bytes_written;
495 * Like _dbus_write_two() but only works on sockets and is thus
496 * available on Windows.
498 * @param fd the file descriptor
499 * @param buffer1 first buffer
500 * @param start1 first byte to write in first buffer
501 * @param len1 number of bytes to write from first buffer
502 * @param buffer2 second buffer, or #NULL
503 * @param start2 first byte to write in second buffer
504 * @param len2 number of bytes to write in second buffer
505 * @returns total bytes written from both buffers, or -1 on error
508 _dbus_write_socket_two (int fd,
509 const DBusString *buffer1,
512 const DBusString *buffer2,
516 #if HAVE_DECL_MSG_NOSIGNAL
517 struct iovec vectors[2];
523 _dbus_assert (buffer1 != NULL);
524 _dbus_assert (start1 >= 0);
525 _dbus_assert (start2 >= 0);
526 _dbus_assert (len1 >= 0);
527 _dbus_assert (len2 >= 0);
529 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
532 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
540 vectors[0].iov_base = (char*) data1;
541 vectors[0].iov_len = len1;
542 vectors[1].iov_base = (char*) data2;
543 vectors[1].iov_len = len2;
547 m.msg_iovlen = data2 ? 2 : 1;
551 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
553 if (bytes_written < 0 && errno == EINTR)
556 return bytes_written;
559 return _dbus_write_two (fd, buffer1, start1, len1,
560 buffer2, start2, len2);
565 _dbus_socket_is_invalid (int fd)
567 return fd < 0 ? TRUE : FALSE;
571 * Thin wrapper around the read() system call that appends
572 * the data it reads to the DBusString buffer. It appends
573 * up to the given count, and returns the same value
574 * and same errno as read(). The only exception is that
575 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
576 * return ENOMEM, even though regular UNIX read doesn't.
578 * Unlike _dbus_read_socket(), _dbus_read() is not available
581 * @param fd the file descriptor to read from
582 * @param buffer the buffer to append data to
583 * @param count the amount of data to read
584 * @returns the number of bytes read or -1
595 _dbus_assert (count >= 0);
597 start = _dbus_string_get_length (buffer);
599 if (!_dbus_string_lengthen (buffer, count))
605 data = _dbus_string_get_data_len (buffer, start, count);
609 bytes_read = read (fd, data, count);
617 /* put length back (note that this doesn't actually realloc anything) */
618 _dbus_string_set_length (buffer, start);
624 /* put length back (doesn't actually realloc) */
625 _dbus_string_set_length (buffer, start + bytes_read);
629 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
637 * Thin wrapper around the write() system call that writes a part of a
638 * DBusString and handles EINTR for you.
640 * @param fd the file descriptor to write
641 * @param buffer the buffer to write data from
642 * @param start the first byte in the buffer to write
643 * @param len the number of bytes to try to write
644 * @returns the number of bytes written or -1 on error
648 const DBusString *buffer,
655 data = _dbus_string_get_const_data_len (buffer, start, len);
659 bytes_written = write (fd, data, len);
661 if (bytes_written < 0 && errno == EINTR)
665 if (bytes_written > 0)
666 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
669 return bytes_written;
673 * Like _dbus_write() but will use writev() if possible
674 * to write both buffers in sequence. The return value
675 * is the number of bytes written in the first buffer,
676 * plus the number written in the second. If the first
677 * buffer is written successfully and an error occurs
678 * writing the second, the number of bytes in the first
679 * is returned (i.e. the error is ignored), on systems that
680 * don't have writev. Handles EINTR for you.
681 * The second buffer may be #NULL.
683 * @param fd the file descriptor
684 * @param buffer1 first buffer
685 * @param start1 first byte to write in first buffer
686 * @param len1 number of bytes to write from first buffer
687 * @param buffer2 second buffer, or #NULL
688 * @param start2 first byte to write in second buffer
689 * @param len2 number of bytes to write in second buffer
690 * @returns total bytes written from both buffers, or -1 on error
693 _dbus_write_two (int fd,
694 const DBusString *buffer1,
697 const DBusString *buffer2,
701 _dbus_assert (buffer1 != NULL);
702 _dbus_assert (start1 >= 0);
703 _dbus_assert (start2 >= 0);
704 _dbus_assert (len1 >= 0);
705 _dbus_assert (len2 >= 0);
709 struct iovec vectors[2];
714 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
717 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
725 vectors[0].iov_base = (char*) data1;
726 vectors[0].iov_len = len1;
727 vectors[1].iov_base = (char*) data2;
728 vectors[1].iov_len = len2;
732 bytes_written = writev (fd,
736 if (bytes_written < 0 && errno == EINTR)
739 return bytes_written;
741 #else /* HAVE_WRITEV */
745 ret1 = _dbus_write (fd, buffer1, start1, len1);
746 if (ret1 == len1 && buffer2 != NULL)
748 ret2 = _dbus_write (fd, buffer2, start2, len2);
750 ret2 = 0; /* we can't report an error as the first write was OK */
757 #endif /* !HAVE_WRITEV */
760 #define _DBUS_MAX_SUN_PATH_LENGTH 99
763 * @def _DBUS_MAX_SUN_PATH_LENGTH
765 * Maximum length of the path to a UNIX domain socket,
766 * sockaddr_un::sun_path member. POSIX requires that all systems
767 * support at least 100 bytes here, including the nul termination.
768 * We use 99 for the max value to allow for the nul.
770 * We could probably also do sizeof (addr.sun_path)
771 * but this way we are the same on all platforms
772 * which is probably a good idea.
776 * Creates a socket and connects it to the UNIX domain socket at the
777 * given path. The connection fd is returned, and is set up as
780 * Uses abstract sockets instead of filesystem-linked sockets if
781 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
782 * On non-Linux abstract socket usage always fails.
784 * This will set FD_CLOEXEC for the socket returned.
786 * @param path the path to UNIX domain socket
787 * @param abstract #TRUE to use abstract namespace
788 * @param error return location for error code
789 * @returns connection file descriptor or -1 on error
792 _dbus_connect_unix_socket (const char *path,
793 dbus_bool_t abstract,
798 struct sockaddr_un addr;
800 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
802 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
806 if (!_dbus_open_unix_socket (&fd, error))
808 _DBUS_ASSERT_ERROR_IS_SET(error);
811 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
814 addr.sun_family = AF_UNIX;
815 path_len = strlen (path);
819 #ifdef HAVE_ABSTRACT_SOCKETS
820 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
821 path_len++; /* Account for the extra nul byte added to the start of sun_path */
823 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
825 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
826 "Abstract socket name too long\n");
827 _dbus_close (fd, NULL);
831 strncpy (&addr.sun_path[1], path, path_len);
832 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
833 #else /* HAVE_ABSTRACT_SOCKETS */
834 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
835 "Operating system does not support abstract socket namespace\n");
836 _dbus_close (fd, NULL);
838 #endif /* ! HAVE_ABSTRACT_SOCKETS */
842 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
844 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
845 "Socket name too long\n");
846 _dbus_close (fd, NULL);
850 strncpy (addr.sun_path, path, path_len);
853 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
855 dbus_set_error (error,
856 _dbus_error_from_errno (errno),
857 "Failed to connect to socket %s: %s",
858 path, _dbus_strerror (errno));
860 _dbus_close (fd, NULL);
864 if (!_dbus_set_fd_nonblocking (fd, error))
866 _DBUS_ASSERT_ERROR_IS_SET (error);
868 _dbus_close (fd, NULL);
876 * Enables or disables the reception of credentials on the given socket during
877 * the next message transmission. This is only effective if the #LOCAL_CREDS
878 * system feature exists, in which case the other side of the connection does
879 * not have to do anything special to send the credentials.
881 * @param fd socket on which to change the #LOCAL_CREDS flag.
882 * @param on whether to enable or disable the #LOCAL_CREDS flag.
885 _dbus_set_local_creds (int fd, dbus_bool_t on)
887 dbus_bool_t retval = TRUE;
889 #if defined(HAVE_CMSGCRED)
890 /* NOOP just to make sure only one codepath is used
891 * and to prefer CMSGCRED
893 #elif defined(LOCAL_CREDS)
894 int val = on ? 1 : 0;
895 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
897 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
901 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
902 on ? "enabled" : "disabled", fd);
909 * Creates a socket and binds it to the given path,
910 * then listens on the socket. The socket is
911 * set to be nonblocking.
913 * Uses abstract sockets instead of filesystem-linked
914 * sockets if requested (it's possible only on Linux;
915 * see "man 7 unix" on Linux).
916 * On non-Linux abstract socket usage always fails.
918 * This will set FD_CLOEXEC for the socket returned
920 * @param path the socket name
921 * @param abstract #TRUE to use abstract namespace
922 * @param error return location for errors
923 * @returns the listening file descriptor or -1 on error
926 _dbus_listen_unix_socket (const char *path,
927 dbus_bool_t abstract,
931 struct sockaddr_un addr;
933 unsigned int reuseaddr;
935 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
937 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
940 if (!_dbus_open_unix_socket (&listen_fd, error))
942 _DBUS_ASSERT_ERROR_IS_SET(error);
945 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
948 addr.sun_family = AF_UNIX;
949 path_len = strlen (path);
953 #ifdef HAVE_ABSTRACT_SOCKETS
954 /* remember that abstract names aren't nul-terminated so we rely
955 * on sun_path being filled in with zeroes above.
957 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
958 path_len++; /* Account for the extra nul byte added to the start of sun_path */
960 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
962 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
963 "Abstract socket name too long\n");
964 _dbus_close (listen_fd, NULL);
968 strncpy (&addr.sun_path[1], path, path_len);
969 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
970 #else /* HAVE_ABSTRACT_SOCKETS */
971 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
972 "Operating system does not support abstract socket namespace\n");
973 _dbus_close (listen_fd, NULL);
975 #endif /* ! HAVE_ABSTRACT_SOCKETS */
979 /* Discussed security implications of this with Nalin,
980 * and we couldn't think of where it would kick our ass, but
981 * it still seems a bit sucky. It also has non-security suckage;
982 * really we'd prefer to exit if the socket is already in use.
983 * But there doesn't seem to be a good way to do this.
985 * Just to be extra careful, I threw in the stat() - clearly
986 * the stat() can't *fix* any security issue, but it at least
987 * avoids inadvertent/accidental data loss.
992 if (stat (path, &sb) == 0 &&
993 S_ISSOCK (sb.st_mode))
997 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
999 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1000 "Abstract socket name too long\n");
1001 _dbus_close (listen_fd, NULL);
1005 strncpy (addr.sun_path, path, path_len);
1009 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1011 _dbus_warn ("Failed to set socket option\"%s\": %s",
1012 path, _dbus_strerror (errno));
1015 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1017 dbus_set_error (error, _dbus_error_from_errno (errno),
1018 "Failed to bind socket \"%s\": %s",
1019 path, _dbus_strerror (errno));
1020 _dbus_close (listen_fd, NULL);
1024 if (listen (listen_fd, 30 /* backlog */) < 0)
1026 dbus_set_error (error, _dbus_error_from_errno (errno),
1027 "Failed to listen on socket \"%s\": %s",
1028 path, _dbus_strerror (errno));
1029 _dbus_close (listen_fd, NULL);
1033 if (!_dbus_set_local_creds (listen_fd, TRUE))
1035 dbus_set_error (error, _dbus_error_from_errno (errno),
1036 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1037 path, _dbus_strerror (errno));
1042 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1044 _DBUS_ASSERT_ERROR_IS_SET (error);
1045 _dbus_close (listen_fd, NULL);
1049 /* Try opening up the permissions, but if we can't, just go ahead
1050 * and continue, maybe it will be good enough.
1052 if (!abstract && chmod (path, 0777) < 0)
1053 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1060 * Acquires one or more sockets passed in from systemd. The sockets
1061 * are set to be nonblocking.
1063 * This will set FD_CLOEXEC for the sockets returned.
1065 * @oaram fds the file descriptors
1066 * @param error return location for errors
1067 * @returns the number of file descriptors
1070 _dbus_listen_systemd_sockets (int **fds,
1077 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1079 n = sd_listen_fds (TRUE);
1082 dbus_set_error (error, _dbus_error_from_errno (-n),
1083 "Failed to acquire systemd socket: %s",
1084 _dbus_strerror (-n));
1090 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1091 "No socket received.");
1095 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1097 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1100 dbus_set_error (error, _dbus_error_from_errno (-r),
1101 "Failed to verify systemd socket type: %s",
1102 _dbus_strerror (-r));
1108 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1109 "Passed socket has wrong type.");
1114 /* OK, the file descriptors are all good, so let's take posession of
1117 new_fds = dbus_new (int, n);
1120 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1121 "Failed to allocate file handle array.");
1125 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1127 if (!_dbus_set_local_creds (fd, TRUE))
1129 dbus_set_error (error, _dbus_error_from_errno (errno),
1130 "Failed to enable LOCAL_CREDS on systemd socket: %s",
1131 _dbus_strerror (errno));
1135 if (!_dbus_set_fd_nonblocking (fd, error))
1137 _DBUS_ASSERT_ERROR_IS_SET (error);
1141 new_fds[fd - SD_LISTEN_FDS_START] = fd;
1149 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1151 _dbus_close (fd, NULL);
1154 dbus_free (new_fds);
1159 * Creates a socket and connects to a socket at the given host
1160 * and port. The connection fd is returned, and is set up as
1163 * This will set FD_CLOEXEC for the socket returned
1165 * @param host the host name to connect to
1166 * @param port the port to connect to
1167 * @param family the address family to listen on, NULL for all
1168 * @param error return location for error code
1169 * @returns connection file descriptor or -1 on error
1172 _dbus_connect_tcp_socket (const char *host,
1177 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1181 _dbus_connect_tcp_socket_with_nonce (const char *host,
1184 const char *noncefile,
1187 int saved_errno = 0;
1189 struct addrinfo hints;
1190 struct addrinfo *ai, *tmp;
1192 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1197 hints.ai_family = AF_UNSPEC;
1198 else if (!strcmp(family, "ipv4"))
1199 hints.ai_family = AF_INET;
1200 else if (!strcmp(family, "ipv6"))
1201 hints.ai_family = AF_INET6;
1204 dbus_set_error (error,
1205 DBUS_ERROR_BAD_ADDRESS,
1206 "Unknown address family %s", family);
1209 hints.ai_protocol = IPPROTO_TCP;
1210 hints.ai_socktype = SOCK_STREAM;
1211 hints.ai_flags = AI_ADDRCONFIG;
1213 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1215 dbus_set_error (error,
1216 _dbus_error_from_errno (errno),
1217 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1218 host, port, gai_strerror(res), res);
1219 _dbus_close (fd, NULL);
1226 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1229 _DBUS_ASSERT_ERROR_IS_SET(error);
1232 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1234 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1236 saved_errno = errno;
1237 _dbus_close(fd, NULL);
1249 dbus_set_error (error,
1250 _dbus_error_from_errno (saved_errno),
1251 "Failed to connect to socket \"%s:%s\" %s",
1252 host, port, _dbus_strerror(saved_errno));
1256 if (noncefile != NULL)
1258 DBusString noncefileStr;
1260 _dbus_string_init_const (&noncefileStr, noncefile);
1261 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1262 _dbus_string_free (&noncefileStr);
1266 _dbus_close (fd, NULL);
1271 if (!_dbus_set_fd_nonblocking (fd, error))
1273 _dbus_close (fd, NULL);
1281 * Creates a socket and binds it to the given path, then listens on
1282 * the socket. The socket is set to be nonblocking. In case of port=0
1283 * a random free port is used and returned in the port parameter.
1284 * If inaddr_any is specified, the hostname is ignored.
1286 * This will set FD_CLOEXEC for the socket returned
1288 * @param host the host name to listen on
1289 * @param port the port to listen on, if zero a free port will be used
1290 * @param family the address family to listen on, NULL for all
1291 * @param retport string to return the actual port listened on
1292 * @param fds_p location to store returned file descriptors
1293 * @param error return location for errors
1294 * @returns the number of listening file descriptors or -1 on error
1297 _dbus_listen_tcp_socket (const char *host,
1300 DBusString *retport,
1305 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1306 struct addrinfo hints;
1307 struct addrinfo *ai, *tmp;
1308 unsigned int reuseaddr;
1311 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1316 hints.ai_family = AF_UNSPEC;
1317 else if (!strcmp(family, "ipv4"))
1318 hints.ai_family = AF_INET;
1319 else if (!strcmp(family, "ipv6"))
1320 hints.ai_family = AF_INET6;
1323 dbus_set_error (error,
1324 DBUS_ERROR_BAD_ADDRESS,
1325 "Unknown address family %s", family);
1329 hints.ai_protocol = IPPROTO_TCP;
1330 hints.ai_socktype = SOCK_STREAM;
1331 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1333 redo_lookup_with_port:
1335 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1337 dbus_set_error (error,
1338 _dbus_error_from_errno (errno),
1339 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1340 host ? host : "*", port, gai_strerror(res), res);
1347 int fd = -1, *newlisten_fd;
1348 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1350 _DBUS_ASSERT_ERROR_IS_SET(error);
1353 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1356 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1358 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1359 host ? host : "*", port, _dbus_strerror (errno));
1362 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1364 saved_errno = errno;
1365 _dbus_close(fd, NULL);
1366 if (saved_errno == EADDRINUSE)
1368 /* Depending on kernel policy, it may or may not
1369 be neccessary to bind to both IPv4 & 6 addresses
1370 so ignore EADDRINUSE here */
1374 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1375 "Failed to bind socket \"%s:%s\": %s",
1376 host ? host : "*", port, _dbus_strerror (saved_errno));
1380 if (listen (fd, 30 /* backlog */) < 0)
1382 saved_errno = errno;
1383 _dbus_close (fd, NULL);
1384 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1385 "Failed to listen on socket \"%s:%s\": %s",
1386 host ? host : "*", port, _dbus_strerror (saved_errno));
1390 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1393 saved_errno = errno;
1394 _dbus_close (fd, NULL);
1395 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1396 "Failed to allocate file handle array: %s",
1397 _dbus_strerror (saved_errno));
1400 listen_fd = newlisten_fd;
1401 listen_fd[nlisten_fd] = fd;
1404 if (!_dbus_string_get_length(retport))
1406 /* If the user didn't specify a port, or used 0, then
1407 the kernel chooses a port. After the first address
1408 is bound to, we need to force all remaining addresses
1409 to use the same port */
1410 if (!port || !strcmp(port, "0"))
1413 struct sockaddr_storage addr;
1417 addrlen = sizeof(addr);
1418 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1421 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1422 portbuf, sizeof(portbuf),
1423 NI_NUMERICHOST)) != 0)
1425 dbus_set_error (error, _dbus_error_from_errno (errno),
1426 "Failed to resolve port \"%s:%s\": %s (%s)",
1427 host ? host : "*", port, gai_strerror(res), res);
1430 if (!_dbus_string_append(retport, portbuf))
1432 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1436 /* Release current address list & redo lookup */
1437 port = _dbus_string_get_const_data(retport);
1439 goto redo_lookup_with_port;
1443 if (!_dbus_string_append(retport, port))
1445 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1459 dbus_set_error (error, _dbus_error_from_errno (errno),
1460 "Failed to bind socket \"%s:%s\": %s",
1461 host ? host : "*", port, _dbus_strerror (errno));
1465 for (i = 0 ; i < nlisten_fd ; i++)
1467 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1480 for (i = 0 ; i < nlisten_fd ; i++)
1481 _dbus_close(listen_fd[i], NULL);
1482 dbus_free(listen_fd);
1487 write_credentials_byte (int server_fd,
1491 char buf[1] = { '\0' };
1492 #if defined(HAVE_CMSGCRED)
1495 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1506 msg.msg_control = (caddr_t) &cmsg;
1507 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1509 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1510 cmsg.hdr.cmsg_level = SOL_SOCKET;
1511 cmsg.hdr.cmsg_type = SCM_CREDS;
1514 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1518 #if defined(HAVE_CMSGCRED)
1519 bytes_written = sendmsg (server_fd, &msg, 0
1520 #if HAVE_DECL_MSG_NOSIGNAL
1525 bytes_written = send (server_fd, buf, 1, 0
1526 #if HAVE_DECL_MSG_NOSIGNAL
1532 if (bytes_written < 0 && errno == EINTR)
1535 if (bytes_written < 0)
1537 dbus_set_error (error, _dbus_error_from_errno (errno),
1538 "Failed to write credentials byte: %s",
1539 _dbus_strerror (errno));
1542 else if (bytes_written == 0)
1544 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1545 "wrote zero bytes writing credentials byte");
1550 _dbus_assert (bytes_written == 1);
1551 _dbus_verbose ("wrote credentials byte\n");
1557 * Reads a single byte which must be nul (an error occurs otherwise),
1558 * and reads unix credentials if available. Clears the credentials
1559 * object, then adds pid/uid if available, so any previous credentials
1560 * stored in the object are lost.
1562 * Return value indicates whether a byte was read, not whether
1563 * we got valid credentials. On some systems, such as Linux,
1564 * reading/writing the byte isn't actually required, but we do it
1565 * anyway just to avoid multiple codepaths.
1567 * Fails if no byte is available, so you must select() first.
1569 * The point of the byte is that on some systems we have to
1570 * use sendmsg()/recvmsg() to transmit credentials.
1572 * @param client_fd the client file descriptor
1573 * @param credentials object to add client credentials to
1574 * @param error location to store error code
1575 * @returns #TRUE on success
1578 _dbus_read_credentials_socket (int client_fd,
1579 DBusCredentials *credentials,
1585 dbus_uid_t uid_read;
1586 dbus_pid_t pid_read;
1589 #ifdef HAVE_CMSGCRED
1592 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1595 #elif defined(LOCAL_CREDS)
1598 struct sockcred cred;
1602 uid_read = DBUS_UID_UNSET;
1603 pid_read = DBUS_PID_UNSET;
1605 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1607 /* The POSIX spec certainly doesn't promise this, but
1608 * we need these assertions to fail as soon as we're wrong about
1609 * it so we can do the porting fixups
1611 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1612 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1613 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1615 _dbus_credentials_clear (credentials);
1617 /* Systems supporting LOCAL_CREDS are configured to have this feature
1618 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1619 * the connection. Therefore, the received message must carry the
1620 * credentials information without doing anything special.
1623 iov.iov_base = &buf;
1630 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1632 msg.msg_control = (caddr_t) &cmsg;
1633 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1637 bytes_read = recvmsg (client_fd, &msg, 0);
1644 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1645 * normally only call read_credentials if the socket was ready
1649 dbus_set_error (error, _dbus_error_from_errno (errno),
1650 "Failed to read credentials byte: %s",
1651 _dbus_strerror (errno));
1654 else if (bytes_read == 0)
1656 /* this should not happen unless we are using recvmsg wrong,
1657 * so is essentially here for paranoia
1659 dbus_set_error (error, DBUS_ERROR_FAILED,
1660 "Failed to read credentials byte (zero-length read)");
1663 else if (buf != '\0')
1665 dbus_set_error (error, DBUS_ERROR_FAILED,
1666 "Credentials byte was not nul");
1670 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1671 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1672 || cmsg.hdr.cmsg_type != SCM_CREDS)
1674 dbus_set_error (error, DBUS_ERROR_FAILED,
1675 "Message from recvmsg() was not SCM_CREDS");
1680 _dbus_verbose ("read credentials byte\n");
1685 struct sockpeercred cr;
1689 int cr_len = sizeof (cr);
1691 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1692 cr_len == sizeof (cr))
1699 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1700 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1702 #elif defined(HAVE_CMSGCRED)
1703 struct cmsgcred *cred;
1705 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1706 pid_read = cred->cmcred_pid;
1707 uid_read = cred->cmcred_euid;
1708 #elif defined(LOCAL_CREDS)
1709 pid_read = DBUS_PID_UNSET;
1710 uid_read = cmsg.cred.sc_uid;
1711 /* Since we have already got the credentials from this socket, we can
1712 * disable its LOCAL_CREDS flag if it was ever set. */
1713 _dbus_set_local_creds (client_fd, FALSE);
1714 #elif defined(HAVE_GETPEEREID)
1717 if (getpeereid (client_fd, &euid, &egid) == 0)
1723 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1725 #elif defined(HAVE_GETPEERUCRED)
1726 ucred_t * ucred = NULL;
1727 if (getpeerucred (client_fd, &ucred) == 0)
1729 pid_read = ucred_getpid (ucred);
1730 uid_read = ucred_geteuid (ucred);
1732 /* generate audit session data based on socket ucred */
1733 adt_session_data_t *adth = NULL;
1734 adt_export_data_t *data = NULL;
1736 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1738 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1742 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1744 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1748 size = adt_export_session_data (adth, &data);
1751 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1755 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1759 (void) adt_end_session (adth);
1761 #endif /* HAVE_ADT */
1765 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1769 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1770 _dbus_verbose ("Socket credentials not supported on this OS\n");
1774 _dbus_verbose ("Credentials:"
1775 " pid "DBUS_PID_FORMAT
1776 " uid "DBUS_UID_FORMAT
1781 if (pid_read != DBUS_PID_UNSET)
1783 if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1785 _DBUS_SET_OOM (error);
1790 if (uid_read != DBUS_UID_UNSET)
1792 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1794 _DBUS_SET_OOM (error);
1803 * Sends a single nul byte with our UNIX credentials as ancillary
1804 * data. Returns #TRUE if the data was successfully written. On
1805 * systems that don't support sending credentials, just writes a byte,
1806 * doesn't send any credentials. On some systems, such as Linux,
1807 * reading/writing the byte isn't actually required, but we do it
1808 * anyway just to avoid multiple codepaths.
1810 * Fails if no byte can be written, so you must select() first.
1812 * The point of the byte is that on some systems we have to
1813 * use sendmsg()/recvmsg() to transmit credentials.
1815 * @param server_fd file descriptor for connection to server
1816 * @param error return location for error code
1817 * @returns #TRUE if the byte was sent
1820 _dbus_send_credentials_socket (int server_fd,
1823 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1825 if (write_credentials_byte (server_fd, error))
1832 * Accepts a connection on a listening socket.
1833 * Handles EINTR for you.
1835 * This will enable FD_CLOEXEC for the returned socket.
1837 * @param listen_fd the listen file descriptor
1838 * @returns the connection fd of the client, or -1 on error
1841 _dbus_accept (int listen_fd)
1844 struct sockaddr addr;
1847 dbus_bool_t cloexec_done;
1850 addrlen = sizeof (addr);
1855 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1856 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1857 cloexec_done = client_fd >= 0;
1859 if (client_fd < 0 && errno == ENOSYS)
1862 client_fd = accept (listen_fd, &addr, &addrlen);
1871 _dbus_verbose ("client fd %d accepted\n", client_fd);
1877 _dbus_fd_set_close_on_exec(client_fd);
1884 * Checks to make sure the given directory is
1885 * private to the user
1887 * @param dir the name of the directory
1888 * @param error error return
1889 * @returns #FALSE on failure
1892 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1894 const char *directory;
1897 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1899 directory = _dbus_string_get_const_data (dir);
1901 if (stat (directory, &sb) < 0)
1903 dbus_set_error (error, _dbus_error_from_errno (errno),
1904 "%s", _dbus_strerror (errno));
1909 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1910 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1912 dbus_set_error (error, DBUS_ERROR_FAILED,
1913 "%s directory is not private to the user", directory);
1921 fill_user_info_from_passwd (struct passwd *p,
1925 _dbus_assert (p->pw_name != NULL);
1926 _dbus_assert (p->pw_dir != NULL);
1928 info->uid = p->pw_uid;
1929 info->primary_gid = p->pw_gid;
1930 info->username = _dbus_strdup (p->pw_name);
1931 info->homedir = _dbus_strdup (p->pw_dir);
1933 if (info->username == NULL ||
1934 info->homedir == NULL)
1936 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1944 fill_user_info (DBusUserInfo *info,
1946 const DBusString *username,
1949 const char *username_c;
1951 /* exactly one of username/uid provided */
1952 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1953 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1955 info->uid = DBUS_UID_UNSET;
1956 info->primary_gid = DBUS_GID_UNSET;
1957 info->group_ids = NULL;
1958 info->n_group_ids = 0;
1959 info->username = NULL;
1960 info->homedir = NULL;
1962 if (username != NULL)
1963 username_c = _dbus_string_get_const_data (username);
1967 /* For now assuming that the getpwnam() and getpwuid() flavors
1968 * are always symmetrical, if not we have to add more configure
1972 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1978 struct passwd p_str;
1980 /* retrieve maximum needed size for buf */
1981 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1983 /* sysconf actually returns a long, but everything else expects size_t,
1984 * so just recast here.
1985 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1987 if ((long) buflen <= 0)
1993 buf = dbus_malloc (buflen);
1996 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2001 #ifdef HAVE_POSIX_GETPWNAM_R
2002 if (uid != DBUS_UID_UNSET)
2003 result = getpwuid_r (uid, &p_str, buf, buflen,
2006 result = getpwnam_r (username_c, &p_str, buf, buflen,
2009 if (uid != DBUS_UID_UNSET)
2010 p = getpwuid_r (uid, &p_str, buf, buflen);
2012 p = getpwnam_r (username_c, &p_str, buf, buflen);
2014 #endif /* !HAVE_POSIX_GETPWNAM_R */
2015 //Try a bigger buffer if ERANGE was returned
2016 if (result == ERANGE && buflen < 512 * 1024)
2026 if (result == 0 && p == &p_str)
2028 if (!fill_user_info_from_passwd (p, info, error))
2037 dbus_set_error (error, _dbus_error_from_errno (errno),
2038 "User \"%s\" unknown or no memory to allocate password entry\n",
2039 username_c ? username_c : "???");
2040 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2045 #else /* ! HAVE_GETPWNAM_R */
2047 /* I guess we're screwed on thread safety here */
2050 if (uid != DBUS_UID_UNSET)
2053 p = getpwnam (username_c);
2057 if (!fill_user_info_from_passwd (p, info, error))
2064 dbus_set_error (error, _dbus_error_from_errno (errno),
2065 "User \"%s\" unknown or no memory to allocate password entry\n",
2066 username_c ? username_c : "???");
2067 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2071 #endif /* ! HAVE_GETPWNAM_R */
2073 /* Fill this in so we can use it to get groups */
2074 username_c = info->username;
2076 #ifdef HAVE_GETGROUPLIST
2081 int initial_buf_count;
2083 initial_buf_count = 17;
2084 buf_count = initial_buf_count;
2085 buf = dbus_new (gid_t, buf_count);
2088 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2092 if (getgrouplist (username_c,
2094 buf, &buf_count) < 0)
2097 /* Presumed cause of negative return code: buf has insufficient
2098 entries to hold the entire group list. The Linux behavior in this
2099 case is to pass back the actual number of groups in buf_count, but
2100 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2101 So as a hack, try to help out a bit by guessing a larger
2102 number of groups, within reason.. might still fail, of course,
2103 but we can at least print a more informative message. I looked up
2104 the "right way" to do this by downloading Apple's own source code
2105 for the "id" command, and it turns out that they use an
2106 undocumented library function getgrouplist_2 (!) which is not
2107 declared in any header in /usr/include (!!). That did not seem
2108 like the way to go here.
2110 if (buf_count == initial_buf_count)
2112 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2114 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2117 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2125 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2129 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2130 username_c, buf_count, buf_count);
2134 dbus_set_error (error,
2135 _dbus_error_from_errno (errno),
2136 "Failed to get groups for username \"%s\" primary GID "
2137 DBUS_GID_FORMAT ": %s\n",
2138 username_c, info->primary_gid,
2139 _dbus_strerror (errno));
2146 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2147 if (info->group_ids == NULL)
2149 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2154 for (i = 0; i < buf_count; ++i)
2155 info->group_ids[i] = buf[i];
2157 info->n_group_ids = buf_count;
2161 #else /* HAVE_GETGROUPLIST */
2163 /* We just get the one group ID */
2164 info->group_ids = dbus_new (dbus_gid_t, 1);
2165 if (info->group_ids == NULL)
2167 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2171 info->n_group_ids = 1;
2173 (info->group_ids)[0] = info->primary_gid;
2175 #endif /* HAVE_GETGROUPLIST */
2177 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2182 _DBUS_ASSERT_ERROR_IS_SET (error);
2187 * Gets user info for the given username.
2189 * @param info user info object to initialize
2190 * @param username the username
2191 * @param error error return
2192 * @returns #TRUE on success
2195 _dbus_user_info_fill (DBusUserInfo *info,
2196 const DBusString *username,
2199 return fill_user_info (info, DBUS_UID_UNSET,
2204 * Gets user info for the given user ID.
2206 * @param info user info object to initialize
2207 * @param uid the user ID
2208 * @param error error return
2209 * @returns #TRUE on success
2212 _dbus_user_info_fill_uid (DBusUserInfo *info,
2216 return fill_user_info (info, uid,
2221 * Adds the credentials of the current process to the
2222 * passed-in credentials object.
2224 * @param credentials credentials to add to
2225 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2228 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2230 /* The POSIX spec certainly doesn't promise this, but
2231 * we need these assertions to fail as soon as we're wrong about
2232 * it so we can do the porting fixups
2234 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2235 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2236 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2238 if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2240 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2247 * Append to the string the identity we would like to have when we
2248 * authenticate, on UNIX this is the current process UID and on
2249 * Windows something else, probably a Windows SID string. No escaping
2250 * is required, that is done in dbus-auth.c. The username here
2251 * need not be anything human-readable, it can be the machine-readable
2252 * form i.e. a user id.
2254 * @param str the string to append to
2255 * @returns #FALSE on no memory
2258 _dbus_append_user_from_current_process (DBusString *str)
2260 return _dbus_string_append_uint (str,
2265 * Gets our process ID
2266 * @returns process ID
2275 * @returns process UID
2283 /** Gets our effective UID
2284 * @returns process effective UID
2287 _dbus_geteuid (void)
2293 * The only reason this is separate from _dbus_getpid() is to allow it
2294 * on Windows for logging but not for other purposes.
2296 * @returns process ID to put in log messages
2299 _dbus_pid_for_log (void)
2305 * Gets a UID from a UID string.
2307 * @param uid_str the UID in string form
2308 * @param uid UID to fill in
2309 * @returns #TRUE if successfully filled in UID
2312 _dbus_parse_uid (const DBusString *uid_str,
2318 if (_dbus_string_get_length (uid_str) == 0)
2320 _dbus_verbose ("UID string was zero length\n");
2326 if (!_dbus_string_parse_int (uid_str, 0, &val,
2329 _dbus_verbose ("could not parse string as a UID\n");
2333 if (end != _dbus_string_get_length (uid_str))
2335 _dbus_verbose ("string contained trailing stuff after UID\n");
2345 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
2349 * Atomically increments an integer
2351 * @param atomic pointer to the integer to increment
2352 * @returns the value before incrementing
2355 _dbus_atomic_inc (DBusAtomic *atomic)
2358 return __sync_add_and_fetch(&atomic->value, 1)-1;
2361 _DBUS_LOCK (atomic);
2362 res = atomic->value;
2364 _DBUS_UNLOCK (atomic);
2370 * Atomically decrement an integer
2372 * @param atomic pointer to the integer to decrement
2373 * @returns the value before decrementing
2376 _dbus_atomic_dec (DBusAtomic *atomic)
2379 return __sync_sub_and_fetch(&atomic->value, 1)+1;
2383 _DBUS_LOCK (atomic);
2384 res = atomic->value;
2386 _DBUS_UNLOCK (atomic);
2392 * Atomically get the value of an integer. It may change at any time
2393 * thereafter, so this is mostly only useful for assertions.
2395 * @param atomic pointer to the integer to get
2396 * @returns the value at this moment
2399 _dbus_atomic_get (DBusAtomic *atomic)
2402 __sync_synchronize ();
2403 return atomic->value;
2407 _DBUS_LOCK (atomic);
2408 res = atomic->value;
2409 _DBUS_UNLOCK (atomic);
2414 #ifdef DBUS_BUILD_TESTS
2416 * @returns process GID
2426 * Wrapper for poll().
2428 * @param fds the file descriptors to poll
2429 * @param n_fds number of descriptors in the array
2430 * @param timeout_milliseconds timeout or -1 for infinite
2431 * @returns numbers of fds with revents, or <0 on error
2434 _dbus_poll (DBusPollFD *fds,
2436 int timeout_milliseconds)
2438 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2439 /* This big thing is a constant expression and should get optimized
2440 * out of existence. So it's more robust than a configure check at
2443 if (_DBUS_POLLIN == POLLIN &&
2444 _DBUS_POLLPRI == POLLPRI &&
2445 _DBUS_POLLOUT == POLLOUT &&
2446 _DBUS_POLLERR == POLLERR &&
2447 _DBUS_POLLHUP == POLLHUP &&
2448 _DBUS_POLLNVAL == POLLNVAL &&
2449 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2450 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2451 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2452 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2453 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2454 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2455 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2457 return poll ((struct pollfd*) fds,
2459 timeout_milliseconds);
2463 /* We have to convert the DBusPollFD to an array of
2464 * struct pollfd, poll, and convert back.
2466 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2469 #else /* ! HAVE_POLL */
2471 fd_set read_set, write_set, err_set;
2477 FD_ZERO (&read_set);
2478 FD_ZERO (&write_set);
2481 for (i = 0; i < n_fds; i++)
2483 DBusPollFD *fdp = &fds[i];
2485 if (fdp->events & _DBUS_POLLIN)
2486 FD_SET (fdp->fd, &read_set);
2488 if (fdp->events & _DBUS_POLLOUT)
2489 FD_SET (fdp->fd, &write_set);
2491 FD_SET (fdp->fd, &err_set);
2493 max_fd = MAX (max_fd, fdp->fd);
2496 tv.tv_sec = timeout_milliseconds / 1000;
2497 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2499 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2500 timeout_milliseconds < 0 ? NULL : &tv);
2504 for (i = 0; i < n_fds; i++)
2506 DBusPollFD *fdp = &fds[i];
2510 if (FD_ISSET (fdp->fd, &read_set))
2511 fdp->revents |= _DBUS_POLLIN;
2513 if (FD_ISSET (fdp->fd, &write_set))
2514 fdp->revents |= _DBUS_POLLOUT;
2516 if (FD_ISSET (fdp->fd, &err_set))
2517 fdp->revents |= _DBUS_POLLERR;
2526 * Get current time, as in gettimeofday(). Use the monotonic clock if
2527 * available, to avoid problems when the system time changes.
2529 * @param tv_sec return location for number of seconds
2530 * @param tv_usec return location for number of microseconds (thousandths)
2533 _dbus_get_current_time (long *tv_sec,
2538 #ifdef HAVE_MONOTONIC_CLOCK
2540 clock_gettime (CLOCK_MONOTONIC, &ts);
2543 *tv_sec = ts.tv_sec;
2545 *tv_usec = ts.tv_nsec / 1000;
2547 gettimeofday (&t, NULL);
2552 *tv_usec = t.tv_usec;
2557 * Creates a directory; succeeds if the directory
2558 * is created or already existed.
2560 * @param filename directory filename
2561 * @param error initialized error object
2562 * @returns #TRUE on success
2565 _dbus_create_directory (const DBusString *filename,
2568 const char *filename_c;
2570 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2572 filename_c = _dbus_string_get_const_data (filename);
2574 if (mkdir (filename_c, 0700) < 0)
2576 if (errno == EEXIST)
2579 dbus_set_error (error, DBUS_ERROR_FAILED,
2580 "Failed to create directory %s: %s\n",
2581 filename_c, _dbus_strerror (errno));
2589 * Appends the given filename to the given directory.
2591 * @todo it might be cute to collapse multiple '/' such as "foo//"
2594 * @param dir the directory name
2595 * @param next_component the filename
2596 * @returns #TRUE on success
2599 _dbus_concat_dir_and_file (DBusString *dir,
2600 const DBusString *next_component)
2602 dbus_bool_t dir_ends_in_slash;
2603 dbus_bool_t file_starts_with_slash;
2605 if (_dbus_string_get_length (dir) == 0 ||
2606 _dbus_string_get_length (next_component) == 0)
2609 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2610 _dbus_string_get_length (dir) - 1);
2612 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2614 if (dir_ends_in_slash && file_starts_with_slash)
2616 _dbus_string_shorten (dir, 1);
2618 else if (!(dir_ends_in_slash || file_starts_with_slash))
2620 if (!_dbus_string_append_byte (dir, '/'))
2624 return _dbus_string_copy (next_component, 0, dir,
2625 _dbus_string_get_length (dir));
2628 /** nanoseconds in a second */
2629 #define NANOSECONDS_PER_SECOND 1000000000
2630 /** microseconds in a second */
2631 #define MICROSECONDS_PER_SECOND 1000000
2632 /** milliseconds in a second */
2633 #define MILLISECONDS_PER_SECOND 1000
2634 /** nanoseconds in a millisecond */
2635 #define NANOSECONDS_PER_MILLISECOND 1000000
2636 /** microseconds in a millisecond */
2637 #define MICROSECONDS_PER_MILLISECOND 1000
2640 * Sleeps the given number of milliseconds.
2641 * @param milliseconds number of milliseconds
2644 _dbus_sleep_milliseconds (int milliseconds)
2646 #ifdef HAVE_NANOSLEEP
2647 struct timespec req;
2648 struct timespec rem;
2650 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2651 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2655 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2657 #elif defined (HAVE_USLEEP)
2658 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2659 #else /* ! HAVE_USLEEP */
2660 sleep (MAX (milliseconds / 1000, 1));
2665 _dbus_generate_pseudorandom_bytes (DBusString *str,
2671 old_len = _dbus_string_get_length (str);
2673 if (!_dbus_string_lengthen (str, n_bytes))
2676 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2678 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2684 * Generates the given number of random bytes,
2685 * using the best mechanism we can come up with.
2687 * @param str the string
2688 * @param n_bytes the number of random bytes to append to string
2689 * @returns #TRUE on success, #FALSE if no memory
2692 _dbus_generate_random_bytes (DBusString *str,
2698 /* FALSE return means "no memory", if it could
2699 * mean something else then we'd need to return
2700 * a DBusError. So we always fall back to pseudorandom
2704 old_len = _dbus_string_get_length (str);
2707 /* note, urandom on linux will fall back to pseudorandom */
2708 fd = open ("/dev/urandom", O_RDONLY);
2710 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2712 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2714 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2716 _dbus_close (fd, NULL);
2717 _dbus_string_set_length (str, old_len);
2718 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2721 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2724 _dbus_close (fd, NULL);
2730 * Exit the process, returning the given value.
2732 * @param code the exit code
2735 _dbus_exit (int code)
2741 * A wrapper around strerror() because some platforms
2742 * may be lame and not have strerror(). Also, never
2745 * @param error_number errno.
2746 * @returns error description.
2749 _dbus_strerror (int error_number)
2753 msg = strerror (error_number);
2761 * signal (SIGPIPE, SIG_IGN);
2764 _dbus_disable_sigpipe (void)
2766 signal (SIGPIPE, SIG_IGN);
2770 * Sets the file descriptor to be close
2771 * on exec. Should be called for all file
2772 * descriptors in D-Bus code.
2774 * @param fd the file descriptor
2777 _dbus_fd_set_close_on_exec (intptr_t fd)
2781 val = fcntl (fd, F_GETFD, 0);
2788 fcntl (fd, F_SETFD, val);
2792 * Closes a file descriptor.
2794 * @param fd the file descriptor
2795 * @param error error object
2796 * @returns #FALSE if error set
2799 _dbus_close (int fd,
2802 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2810 dbus_set_error (error, _dbus_error_from_errno (errno),
2811 "Could not close fd %d", fd);
2819 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2820 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2822 * @param fd the file descriptor to duplicate
2823 * @returns duplicated file descriptor
2831 #ifdef F_DUPFD_CLOEXEC
2832 dbus_bool_t cloexec_done;
2834 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2835 cloexec_done = new_fd >= 0;
2837 if (new_fd < 0 && errno == EINVAL)
2840 new_fd = fcntl(fd, F_DUPFD, 3);
2845 dbus_set_error (error, _dbus_error_from_errno (errno),
2846 "Could not duplicate fd %d", fd);
2850 #ifdef F_DUPFD_CLOEXEC
2854 _dbus_fd_set_close_on_exec(new_fd);
2861 * Sets a file descriptor to be nonblocking.
2863 * @param fd the file descriptor.
2864 * @param error address of error location.
2865 * @returns #TRUE on success.
2868 _dbus_set_fd_nonblocking (int fd,
2873 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2875 val = fcntl (fd, F_GETFL, 0);
2878 dbus_set_error (error, _dbus_error_from_errno (errno),
2879 "Failed to get flags from file descriptor %d: %s",
2880 fd, _dbus_strerror (errno));
2881 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2882 _dbus_strerror (errno));
2886 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2888 dbus_set_error (error, _dbus_error_from_errno (errno),
2889 "Failed to set nonblocking flag of file descriptor %d: %s",
2890 fd, _dbus_strerror (errno));
2891 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2892 fd, _dbus_strerror (errno));
2901 * On GNU libc systems, print a crude backtrace to stderr. On other
2902 * systems, print "no backtrace support" and block for possible gdb
2903 * attachment if an appropriate environment variable is set.
2906 _dbus_print_backtrace (void)
2908 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2914 bt_size = backtrace (bt, 500);
2916 syms = backtrace_symbols (bt, bt_size);
2921 /* don't use dbus_warn since it can _dbus_abort() */
2922 fprintf (stderr, " %s\n", syms[i]);
2928 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2929 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
2931 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2936 * Creates a full-duplex pipe (as in socketpair()).
2937 * Sets both ends of the pipe nonblocking.
2939 * Marks both file descriptors as close-on-exec
2941 * @todo libdbus only uses this for the debug-pipe server, so in
2942 * principle it could be in dbus-sysdeps-util.c, except that
2943 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2944 * debug-pipe server is used.
2946 * @param fd1 return location for one end
2947 * @param fd2 return location for the other end
2948 * @param blocking #TRUE if pipe should be blocking
2949 * @param error error return
2950 * @returns #FALSE on failure (if error is set)
2953 _dbus_full_duplex_pipe (int *fd1,
2955 dbus_bool_t blocking,
2958 #ifdef HAVE_SOCKETPAIR
2963 dbus_bool_t cloexec_done;
2965 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2966 cloexec_done = retval >= 0;
2968 if (retval < 0 && errno == EINVAL)
2971 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2976 dbus_set_error (error, _dbus_error_from_errno (errno),
2977 "Could not create full-duplex pipe");
2981 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2987 _dbus_fd_set_close_on_exec (fds[0]);
2988 _dbus_fd_set_close_on_exec (fds[1]);
2992 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2993 !_dbus_set_fd_nonblocking (fds[1], NULL)))
2995 dbus_set_error (error, _dbus_error_from_errno (errno),
2996 "Could not set full-duplex pipe nonblocking");
2998 _dbus_close (fds[0], NULL);
2999 _dbus_close (fds[1], NULL);
3007 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3012 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3013 dbus_set_error (error, DBUS_ERROR_FAILED,
3014 "_dbus_full_duplex_pipe() not implemented on this OS");
3020 * Measure the length of the given format string and arguments,
3021 * not including the terminating nul.
3023 * @param format a printf-style format string
3024 * @param args arguments for the format string
3025 * @returns length of the given format string and args, or -1 if no memory
3028 _dbus_printf_string_upper_bound (const char *format,
3031 char static_buf[1024];
3032 int bufsize = sizeof (static_buf);
3035 len = vsnprintf (static_buf, bufsize, format, args);
3037 /* If vsnprintf() returned non-negative, then either the string fits in
3038 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3039 * returns the number of characters that were needed, or this OS returns the
3042 * We ignore the possibility that snprintf might just ignore the length and
3043 * overrun the buffer (64-bit Solaris 7), because that's pathological.
3044 * If your libc is really that bad, come back when you have a better one. */
3047 /* This could be the truncated length (Tru64 and IRIX have this bug),
3048 * or the real length could be coincidentally the same. Which is it?
3049 * If vsnprintf returns the truncated length, we'll go to the slow
3051 if (vsnprintf (static_buf, 1, format, args) == 1)
3055 /* If vsnprintf() returned negative, we have to do more work.
3056 * HP-UX returns negative. */
3063 buf = dbus_malloc (bufsize);
3068 len = vsnprintf (buf, bufsize, format, args);
3071 /* If the reported length is exactly the buffer size, round up to the
3072 * next size, in case vsnprintf has been returning the truncated
3082 * Gets the temporary files directory by inspecting the environment variables
3083 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3085 * @returns location of temp directory
3088 _dbus_get_tmpdir(void)
3090 static const char* tmpdir = NULL;
3094 /* TMPDIR is what glibc uses, then
3095 * glibc falls back to the P_tmpdir macro which
3096 * just expands to "/tmp"
3099 tmpdir = getenv("TMPDIR");
3101 /* These two env variables are probably
3102 * broken, but maybe some OS uses them?
3105 tmpdir = getenv("TMP");
3107 tmpdir = getenv("TEMP");
3109 /* And this is the sane fallback. */
3114 _dbus_assert(tmpdir != NULL);
3120 * Execute a subprocess, returning up to 1024 bytes of output
3123 * If successful, returns #TRUE and appends the output to @p
3124 * result. If a failure happens, returns #FALSE and
3125 * sets an error in @p error.
3127 * @note It's not an error if the subprocess terminates normally
3128 * without writing any data to stdout. Verify the @p result length
3129 * before and after this function call to cover this case.
3131 * @param progname initial path to exec (may or may not be absolute)
3132 * @param path_fallback if %TRUE, search PATH for executable
3133 * @param argv NULL-terminated list of arguments
3134 * @param result a DBusString where the output can be append
3135 * @param error a DBusError to store the error in case of failure
3136 * @returns #TRUE on success, #FALSE if an error happened
3139 _read_subprocess_line_argv (const char *progpath,
3140 dbus_bool_t path_fallback,
3145 int result_pipe[2] = { -1, -1 };
3146 int errors_pipe[2] = { -1, -1 };
3154 sigset_t new_set, old_set;
3156 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3159 /* We need to block any existing handlers for SIGCHLD temporarily; they
3160 * will cause waitpid() below to fail.
3161 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3163 sigemptyset (&new_set);
3164 sigaddset (&new_set, SIGCHLD);
3165 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3167 orig_len = _dbus_string_get_length (result);
3171 if (pipe (result_pipe) < 0)
3173 dbus_set_error (error, _dbus_error_from_errno (errno),
3174 "Failed to create a pipe to call %s: %s",
3175 progpath, _dbus_strerror (errno));
3176 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3177 progpath, _dbus_strerror (errno));
3180 if (pipe (errors_pipe) < 0)
3182 dbus_set_error (error, _dbus_error_from_errno (errno),
3183 "Failed to create a pipe to call %s: %s",
3184 progpath, _dbus_strerror (errno));
3185 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3186 progpath, _dbus_strerror (errno));
3193 dbus_set_error (error, _dbus_error_from_errno (errno),
3194 "Failed to fork() to call %s: %s",
3195 progpath, _dbus_strerror (errno));
3196 _dbus_verbose ("Failed to fork() to call %s: %s\n",
3197 progpath, _dbus_strerror (errno));
3207 fd = open ("/dev/null", O_RDWR);
3209 /* huh?! can't open /dev/null? */
3212 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3215 close (result_pipe[READ_END]);
3216 close (errors_pipe[READ_END]);
3217 close (0); /* close stdin */
3218 close (1); /* close stdout */
3219 close (2); /* close stderr */
3221 if (dup2 (fd, 0) == -1)
3223 if (dup2 (result_pipe[WRITE_END], 1) == -1)
3225 if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3228 maxfds = sysconf (_SC_OPEN_MAX);
3229 /* Pick something reasonable if for some reason sysconf
3234 /* close all inherited fds */
3235 for (i = 3; i < maxfds; i++)
3238 sigprocmask (SIG_SETMASK, &old_set, NULL);
3240 /* If it looks fully-qualified, try execv first */
3241 if (progpath[0] == '/')
3243 execv (progpath, argv);
3244 /* Ok, that failed. Now if path_fallback is given, let's
3245 * try unqualified. This is mostly a hack to work
3246 * around systems which ship dbus-launch in /usr/bin
3247 * but everything else in /bin (because dbus-launch
3251 /* We must have a slash, because we checked above */
3252 execvp (strrchr (progpath, '/')+1, argv);
3255 execvp (progpath, argv);
3257 /* still nothing, we failed */
3261 /* parent process */
3262 close (result_pipe[WRITE_END]);
3263 close (errors_pipe[WRITE_END]);
3264 result_pipe[WRITE_END] = -1;
3265 errors_pipe[WRITE_END] = -1;
3270 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3274 /* reap the child process to avoid it lingering as zombie */
3277 ret = waitpid (pid, &status, 0);
3279 while (ret == -1 && errno == EINTR);
3281 /* We succeeded if the process exited with status 0 and
3282 anything was read */
3283 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3285 /* The process ended with error */
3286 DBusString error_message;
3287 if (!_dbus_string_init (&error_message))
3289 _DBUS_SET_OOM (error);
3296 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3300 _dbus_string_set_length (result, orig_len);
3301 if (_dbus_string_get_length (&error_message) > 0)
3302 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3303 "%s terminated abnormally with the following error: %s",
3304 progpath, _dbus_string_get_data (&error_message));
3306 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3307 "%s terminated abnormally without any error message",
3315 sigprocmask (SIG_SETMASK, &old_set, NULL);
3318 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3320 _DBUS_ASSERT_ERROR_IS_SET (error);
3322 if (result_pipe[0] != -1)
3323 close (result_pipe[0]);
3324 if (result_pipe[1] != -1)
3325 close (result_pipe[1]);
3326 if (errors_pipe[0] != -1)
3327 close (errors_pipe[0]);
3328 if (errors_pipe[1] != -1)
3329 close (errors_pipe[1]);
3335 * Returns the address of a new session bus.
3337 * If successful, returns #TRUE and appends the address to @p
3338 * address. If a failure happens, returns #FALSE and
3339 * sets an error in @p error.
3341 * @param address a DBusString where the address can be stored
3342 * @param error a DBusError to store the error in case of failure
3343 * @returns #TRUE on success, #FALSE if an error happened
3346 _dbus_get_autolaunch_address (const char *scope,
3347 DBusString *address,
3350 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3351 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3352 * but that's done elsewhere, and if it worked, this function wouldn't
3354 const char *display;
3355 static char *argv[6];
3360 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3363 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3364 * dbus-launch-x11 is just going to fail. Rather than trying to
3365 * run it, we might as well bail out early with a nice error. */
3366 display = _dbus_getenv ("DISPLAY");
3368 if (display == NULL || display[0] == '\0')
3370 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3371 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3375 if (!_dbus_string_init (&uuid))
3377 _DBUS_SET_OOM (error);
3381 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3383 _DBUS_SET_OOM (error);
3388 argv[i] = "dbus-launch";
3390 argv[i] = "--autolaunch";
3392 argv[i] = _dbus_string_get_data (&uuid);
3394 argv[i] = "--binary-syntax";
3396 argv[i] = "--close-stderr";
3401 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3403 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3405 argv, address, error);
3408 _dbus_string_free (&uuid);
3411 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3412 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3413 "set your DBUS_SESSION_BUS_ADDRESS instead");
3419 * Reads the uuid of the machine we're running on from
3420 * the dbus configuration. Optionally try to create it
3421 * (only root can do this usually).
3423 * On UNIX, reads a file that gets created by dbus-uuidgen
3424 * in a post-install script. On Windows, if there's a standard
3425 * machine uuid we could just use that, but I can't find one
3426 * with the right properties (the hardware profile guid can change
3427 * without rebooting I believe). If there's no standard one
3428 * we might want to use the registry instead of a file for
3429 * this, and I'm not sure how we'd ensure the uuid gets created.
3431 * @param machine_id guid to init with the machine's uuid
3432 * @param create_if_not_found try to create the uuid if it doesn't exist
3433 * @param error the error return
3434 * @returns #FALSE if the error is set
3437 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3438 dbus_bool_t create_if_not_found,
3441 DBusString filename;
3444 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3446 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3450 dbus_error_free (error);
3452 /* Fallback to the system machine ID */
3453 _dbus_string_init_const (&filename, "/etc/machine-id");
3454 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3457 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3458 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3461 * quries launchd for a specific env var which holds the socket path.
3462 * @param launchd_env_var the env var to look up
3463 * @param error a DBusError to store the error in case of failure
3464 * @return the value of the env var
3467 _dbus_lookup_launchd_socket (DBusString *socket_path,
3468 const char *launchd_env_var,
3471 #ifdef DBUS_ENABLE_LAUNCHD
3475 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3478 argv[i] = "launchctl";
3482 argv[i] = (char*)launchd_env_var;
3487 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3489 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3494 /* no error, but no result either */
3495 if (_dbus_string_get_length(socket_path) == 0)
3500 /* strip the carriage-return */
3501 _dbus_string_shorten(socket_path, 1);
3503 #else /* DBUS_ENABLE_LAUNCHD */
3504 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3505 "can't lookup socket from launchd; launchd support not compiled in");
3511 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3513 #ifdef DBUS_ENABLE_LAUNCHD
3514 dbus_bool_t valid_socket;
3515 DBusString socket_path;
3517 if (!_dbus_string_init (&socket_path))
3519 _DBUS_SET_OOM (error);
3523 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3525 if (dbus_error_is_set(error))
3527 _dbus_string_free(&socket_path);
3533 dbus_set_error(error, "no socket path",
3534 "launchd did not provide a socket path, "
3535 "verify that org.freedesktop.dbus-session.plist is loaded!");
3536 _dbus_string_free(&socket_path);
3539 if (!_dbus_string_append (address, "unix:path="))
3541 _DBUS_SET_OOM (error);
3542 _dbus_string_free(&socket_path);
3545 if (!_dbus_string_copy (&socket_path, 0, address,
3546 _dbus_string_get_length (address)))
3548 _DBUS_SET_OOM (error);
3549 _dbus_string_free(&socket_path);
3553 _dbus_string_free(&socket_path);
3556 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3557 "can't lookup session address from launchd; launchd support not compiled in");
3563 * Determines the address of the session bus by querying a
3564 * platform-specific method.
3566 * The first parameter will be a boolean specifying whether
3567 * or not a dynamic session lookup is supported on this platform.
3569 * If supported is TRUE and the return value is #TRUE, the
3570 * address will be appended to @p address.
3571 * If a failure happens, returns #FALSE and sets an error in
3574 * If supported is FALSE, ignore the return value.
3576 * @param supported returns whether this method is supported
3577 * @param address a DBusString where the address can be stored
3578 * @param error a DBusError to store the error in case of failure
3579 * @returns #TRUE on success, #FALSE if an error happened
3582 _dbus_lookup_session_address (dbus_bool_t *supported,
3583 DBusString *address,
3586 #ifdef DBUS_ENABLE_LAUNCHD
3588 return _dbus_lookup_session_address_launchd (address, error);
3590 /* On non-Mac Unix platforms, if the session address isn't already
3591 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3592 * fall back to the autolaunch: global default; see
3593 * init_session_address in dbus/dbus-bus.c. */
3600 * Returns the standard directories for a session bus to look for service
3603 * On UNIX this should be the standard xdg freedesktop.org data directories:
3605 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3606 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3612 * @param dirs the directory list we are returning
3613 * @returns #FALSE on OOM
3617 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3619 const char *xdg_data_home;
3620 const char *xdg_data_dirs;
3621 DBusString servicedir_path;
3623 if (!_dbus_string_init (&servicedir_path))
3626 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3627 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3629 if (xdg_data_home != NULL)
3631 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3636 const DBusString *homedir;
3637 DBusString local_share;
3639 if (!_dbus_homedir_from_current_process (&homedir))
3642 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3645 _dbus_string_init_const (&local_share, "/.local/share");
3646 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3650 if (!_dbus_string_append (&servicedir_path, ":"))
3653 if (xdg_data_dirs != NULL)
3655 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3658 if (!_dbus_string_append (&servicedir_path, ":"))
3663 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3668 * add configured datadir to defaults
3669 * this may be the same as an xdg dir
3670 * however the config parser should take
3671 * care of duplicates
3673 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3676 if (!_dbus_split_paths_and_append (&servicedir_path,
3677 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3681 _dbus_string_free (&servicedir_path);
3685 _dbus_string_free (&servicedir_path);
3691 * Returns the standard directories for a system bus to look for service
3694 * On UNIX this should be the standard xdg freedesktop.org data directories:
3696 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3702 * On Windows there is no system bus and this function can return nothing.
3704 * @param dirs the directory list we are returning
3705 * @returns #FALSE on OOM
3709 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3711 const char *xdg_data_dirs;
3712 DBusString servicedir_path;
3714 if (!_dbus_string_init (&servicedir_path))
3717 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3719 if (xdg_data_dirs != NULL)
3721 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3724 if (!_dbus_string_append (&servicedir_path, ":"))
3729 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3734 * Add configured datadir to defaults. This may be the same as one
3735 * of the XDG directories. However, the config parser should take
3736 * care of the duplicates.
3738 * Also, append /lib as counterpart of /usr/share on the root
3739 * directory (the root directory does not know /share), in order to
3740 * facilitate early boot system bus activation where /usr might not
3743 if (!_dbus_string_append (&servicedir_path,
3748 if (!_dbus_split_paths_and_append (&servicedir_path,
3749 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3753 _dbus_string_free (&servicedir_path);
3757 _dbus_string_free (&servicedir_path);
3762 * Append the absolute path of the system.conf file
3763 * (there is no system bus on Windows so this can just
3764 * return FALSE and print a warning or something)
3766 * @param str the string to append to
3767 * @returns #FALSE if no memory
3770 _dbus_append_system_config_file (DBusString *str)
3772 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3776 * Append the absolute path of the session.conf file.
3778 * @param str the string to append to
3779 * @returns #FALSE if no memory
3782 _dbus_append_session_config_file (DBusString *str)
3784 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3788 * Called when the bus daemon is signaled to reload its configuration; any
3789 * caches should be nuked. Of course any caches that need explicit reload
3790 * are probably broken, but c'est la vie.
3795 _dbus_flush_caches (void)
3797 _dbus_user_database_flush_system ();
3801 * Appends the directory in which a keyring for the given credentials
3802 * should be stored. The credentials should have either a Windows or
3803 * UNIX user in them. The directory should be an absolute path.
3805 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3806 * be something else, since the dotfile convention is not normal on Windows.
3808 * @param directory string to append directory to
3809 * @param credentials credentials the directory should be for
3811 * @returns #FALSE on no memory
3814 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3815 DBusCredentials *credentials)
3821 _dbus_assert (credentials != NULL);
3822 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3824 if (!_dbus_string_init (&homedir))
3827 uid = _dbus_credentials_get_unix_uid (credentials);
3828 _dbus_assert (uid != DBUS_UID_UNSET);
3830 if (!_dbus_homedir_from_uid (uid, &homedir))
3833 #ifdef DBUS_BUILD_TESTS
3835 const char *override;
3837 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3838 if (override != NULL && *override != '\0')
3840 _dbus_string_set_length (&homedir, 0);
3841 if (!_dbus_string_append (&homedir, override))
3844 _dbus_verbose ("Using fake homedir for testing: %s\n",
3845 _dbus_string_get_const_data (&homedir));
3849 static dbus_bool_t already_warned = FALSE;
3850 if (!already_warned)
3852 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3853 already_warned = TRUE;
3859 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3860 if (!_dbus_concat_dir_and_file (&homedir,
3864 if (!_dbus_string_copy (&homedir, 0,
3865 directory, _dbus_string_get_length (directory))) {
3869 _dbus_string_free (&homedir);
3873 _dbus_string_free (&homedir);
3877 //PENDING(kdab) docs
3879 _dbus_daemon_publish_session_bus_address (const char* addr,
3885 //PENDING(kdab) docs
3887 _dbus_daemon_unpublish_session_bus_address (void)
3893 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3894 * for Winsock so is abstracted)
3896 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3899 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3901 return errno == EAGAIN || errno == EWOULDBLOCK;
3905 * Removes a directory; Directory must be empty
3907 * @param filename directory filename
3908 * @param error initialized error object
3909 * @returns #TRUE on success
3912 _dbus_delete_directory (const DBusString *filename,
3915 const char *filename_c;
3917 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3919 filename_c = _dbus_string_get_const_data (filename);
3921 if (rmdir (filename_c) != 0)
3923 dbus_set_error (error, DBUS_ERROR_FAILED,
3924 "Failed to remove directory %s: %s\n",
3925 filename_c, _dbus_strerror (errno));
3933 * Checks whether file descriptors may be passed via the socket
3935 * @param fd the socket
3936 * @return TRUE when fd passing over this socket is supported
3940 _dbus_socket_can_pass_unix_fd(int fd) {
3945 struct sockaddr_storage storage;
3946 struct sockaddr_un un;
3949 socklen_t sa_len = sizeof(sa_buf);
3953 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3956 return sa_buf.sa.sa_family == AF_UNIX;
3966 * replaces the term DBUS_PREFIX in configure_time_path by the
3967 * current dbus installation directory. On unix this function is a noop
3969 * @param configure_time_path
3973 _dbus_replace_install_prefix (const char *configure_time_path)
3975 return configure_time_path;
3978 /* tests in dbus-sysdeps-util.c */