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>
58 #include <arpa/inet.h>
72 #ifdef HAVE_GETPEERUCRED
83 #include "sd-daemon.h"
94 #define AI_ADDRCONFIG 0
97 #ifndef HAVE_SOCKLEN_T
101 #if defined (__sun) || defined (__sun__)
103 * CMS_SPACE etc. definitions for Solaris < 10, based on
104 * http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
106 * http://wiki.opencsw.org/porting-faq#toc10
108 * These are only redefined for Solaris, for now: if your OS needs these too,
109 * please file a bug. (Or preferably, improve your OS so they're not needed.)
114 # define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
116 /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
117 # define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
118 ~(sizeof (long) - 1))
123 # define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
128 # define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
134 _dbus_open_socket (int *fd_p,
141 dbus_bool_t cloexec_done;
143 *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
144 cloexec_done = *fd_p >= 0;
146 /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
147 if (*fd_p < 0 && errno == EINVAL)
150 *fd_p = socket (domain, type, protocol);
159 _dbus_fd_set_close_on_exec(*fd_p);
162 _dbus_verbose ("socket fd %d opened\n", *fd_p);
167 dbus_set_error(error,
168 _dbus_error_from_errno (errno),
169 "Failed to open socket: %s",
170 _dbus_strerror (errno));
176 * Opens a UNIX domain socket (as in the socket() call).
177 * Does not bind the socket.
179 * This will set FD_CLOEXEC for the socket returned
181 * @param fd return location for socket descriptor
182 * @param error return location for an error
183 * @returns #FALSE if error is set
186 _dbus_open_unix_socket (int *fd,
189 return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
193 * Closes a socket. Should not be used on non-socket
194 * file descriptors or handles.
196 * @param fd the socket
197 * @param error return location for an error
198 * @returns #FALSE if error is set
201 _dbus_close_socket (int fd,
204 return _dbus_close (fd, error);
208 * Like _dbus_read(), but only works on sockets so is
209 * available on Windows.
211 * @param fd the socket
212 * @param buffer string to append data to
213 * @param count max amount of data to read
214 * @returns number of bytes appended to the string
217 _dbus_read_socket (int fd,
221 return _dbus_read (fd, buffer, count);
225 * Like _dbus_write(), but only supports sockets
226 * and is thus available on Windows.
228 * @param fd the file descriptor to write
229 * @param buffer the buffer to write data from
230 * @param start the first byte in the buffer to write
231 * @param len the number of bytes to try to write
232 * @returns the number of bytes written or -1 on error
235 _dbus_write_socket (int fd,
236 const DBusString *buffer,
240 #if HAVE_DECL_MSG_NOSIGNAL
244 data = _dbus_string_get_const_data_len (buffer, start, len);
248 bytes_written = send (fd, data, len, MSG_NOSIGNAL);
250 if (bytes_written < 0 && errno == EINTR)
253 return bytes_written;
256 return _dbus_write (fd, buffer, start, len);
261 * Like _dbus_read_socket() but also tries to read unix fds from the
262 * socket. When there are more fds to read than space in the array
263 * passed this function will fail with ENOSPC.
265 * @param fd the socket
266 * @param buffer string to append data to
267 * @param count max amount of data to read
268 * @param fds array to place read file descriptors in
269 * @param n_fds on input space in fds array, on output how many fds actually got read
270 * @returns number of bytes appended to string
273 _dbus_read_socket_with_unix_fds (int fd,
278 #ifndef HAVE_UNIX_FD_PASSING
281 if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
293 _dbus_assert (count >= 0);
294 _dbus_assert (*n_fds >= 0);
296 start = _dbus_string_get_length (buffer);
298 if (!_dbus_string_lengthen (buffer, count))
305 iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
312 /* Hmm, we have no clue how long the control data will actually be
313 that is queued for us. The least we can do is assume that the
314 caller knows. Hence let's make space for the number of fds that
315 we shall read at max plus the cmsg header. */
316 m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
318 /* It's probably safe to assume that systems with SCM_RIGHTS also
320 m.msg_control = alloca(m.msg_controllen);
321 memset(m.msg_control, 0, m.msg_controllen);
325 bytes_read = recvmsg(fd, &m, 0
326 #ifdef MSG_CMSG_CLOEXEC
337 /* put length back (note that this doesn't actually realloc anything) */
338 _dbus_string_set_length (buffer, start);
345 dbus_bool_t found = FALSE;
347 if (m.msg_flags & MSG_CTRUNC)
349 /* Hmm, apparently the control data was truncated. The bad
350 thing is that we might have completely lost a couple of fds
351 without chance to recover them. Hence let's treat this as a
355 _dbus_string_set_length (buffer, start);
359 for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
360 if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
364 _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
365 *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
367 memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
370 /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
371 worked, hence we need to go through this list and set
372 CLOEXEC everywhere in any case */
373 for (i = 0; i < *n_fds; i++)
374 _dbus_fd_set_close_on_exec(fds[i]);
382 /* put length back (doesn't actually realloc) */
383 _dbus_string_set_length (buffer, start + bytes_read);
387 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
396 _dbus_write_socket_with_unix_fds(int fd,
397 const DBusString *buffer,
403 #ifndef HAVE_UNIX_FD_PASSING
410 return _dbus_write_socket(fd, buffer, start, len);
412 return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
417 _dbus_write_socket_with_unix_fds_two(int fd,
418 const DBusString *buffer1,
421 const DBusString *buffer2,
427 #ifndef HAVE_UNIX_FD_PASSING
434 return _dbus_write_socket_two(fd,
435 buffer1, start1, len1,
436 buffer2, start2, len2);
444 _dbus_assert (len1 >= 0);
445 _dbus_assert (len2 >= 0);
446 _dbus_assert (n_fds >= 0);
449 iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
450 iov[0].iov_len = len1;
454 iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
455 iov[1].iov_len = len2;
460 m.msg_iovlen = buffer2 ? 2 : 1;
464 m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
465 m.msg_control = alloca(m.msg_controllen);
466 memset(m.msg_control, 0, m.msg_controllen);
468 cm = CMSG_FIRSTHDR(&m);
469 cm->cmsg_level = SOL_SOCKET;
470 cm->cmsg_type = SCM_RIGHTS;
471 cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
472 memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
477 bytes_written = sendmsg (fd, &m, 0
478 #if HAVE_DECL_MSG_NOSIGNAL
483 if (bytes_written < 0 && errno == EINTR)
487 if (bytes_written > 0)
488 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
491 return bytes_written;
496 * Like _dbus_write_two() but only works on sockets and is thus
497 * available on Windows.
499 * @param fd the file descriptor
500 * @param buffer1 first buffer
501 * @param start1 first byte to write in first buffer
502 * @param len1 number of bytes to write from first buffer
503 * @param buffer2 second buffer, or #NULL
504 * @param start2 first byte to write in second buffer
505 * @param len2 number of bytes to write in second buffer
506 * @returns total bytes written from both buffers, or -1 on error
509 _dbus_write_socket_two (int fd,
510 const DBusString *buffer1,
513 const DBusString *buffer2,
517 #if HAVE_DECL_MSG_NOSIGNAL
518 struct iovec vectors[2];
524 _dbus_assert (buffer1 != NULL);
525 _dbus_assert (start1 >= 0);
526 _dbus_assert (start2 >= 0);
527 _dbus_assert (len1 >= 0);
528 _dbus_assert (len2 >= 0);
530 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
533 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
541 vectors[0].iov_base = (char*) data1;
542 vectors[0].iov_len = len1;
543 vectors[1].iov_base = (char*) data2;
544 vectors[1].iov_len = len2;
548 m.msg_iovlen = data2 ? 2 : 1;
552 bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
554 if (bytes_written < 0 && errno == EINTR)
557 return bytes_written;
560 return _dbus_write_two (fd, buffer1, start1, len1,
561 buffer2, start2, len2);
566 _dbus_socket_is_invalid (int fd)
568 return fd < 0 ? TRUE : FALSE;
572 * Thin wrapper around the read() system call that appends
573 * the data it reads to the DBusString buffer. It appends
574 * up to the given count, and returns the same value
575 * and same errno as read(). The only exception is that
576 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
577 * return ENOMEM, even though regular UNIX read doesn't.
579 * Unlike _dbus_read_socket(), _dbus_read() is not available
582 * @param fd the file descriptor to read from
583 * @param buffer the buffer to append data to
584 * @param count the amount of data to read
585 * @returns the number of bytes read or -1
596 _dbus_assert (count >= 0);
598 start = _dbus_string_get_length (buffer);
600 if (!_dbus_string_lengthen (buffer, count))
606 data = _dbus_string_get_data_len (buffer, start, count);
610 bytes_read = read (fd, data, count);
618 /* put length back (note that this doesn't actually realloc anything) */
619 _dbus_string_set_length (buffer, start);
625 /* put length back (doesn't actually realloc) */
626 _dbus_string_set_length (buffer, start + bytes_read);
630 _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
638 * Thin wrapper around the write() system call that writes a part of a
639 * DBusString and handles EINTR for you.
641 * @param fd the file descriptor to write
642 * @param buffer the buffer to write data from
643 * @param start the first byte in the buffer to write
644 * @param len the number of bytes to try to write
645 * @returns the number of bytes written or -1 on error
649 const DBusString *buffer,
656 data = _dbus_string_get_const_data_len (buffer, start, len);
660 bytes_written = write (fd, data, len);
662 if (bytes_written < 0 && errno == EINTR)
666 if (bytes_written > 0)
667 _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
670 return bytes_written;
674 * Like _dbus_write() but will use writev() if possible
675 * to write both buffers in sequence. The return value
676 * is the number of bytes written in the first buffer,
677 * plus the number written in the second. If the first
678 * buffer is written successfully and an error occurs
679 * writing the second, the number of bytes in the first
680 * is returned (i.e. the error is ignored), on systems that
681 * don't have writev. Handles EINTR for you.
682 * The second buffer may be #NULL.
684 * @param fd the file descriptor
685 * @param buffer1 first buffer
686 * @param start1 first byte to write in first buffer
687 * @param len1 number of bytes to write from first buffer
688 * @param buffer2 second buffer, or #NULL
689 * @param start2 first byte to write in second buffer
690 * @param len2 number of bytes to write in second buffer
691 * @returns total bytes written from both buffers, or -1 on error
694 _dbus_write_two (int fd,
695 const DBusString *buffer1,
698 const DBusString *buffer2,
702 _dbus_assert (buffer1 != NULL);
703 _dbus_assert (start1 >= 0);
704 _dbus_assert (start2 >= 0);
705 _dbus_assert (len1 >= 0);
706 _dbus_assert (len2 >= 0);
710 struct iovec vectors[2];
715 data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
718 data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
726 vectors[0].iov_base = (char*) data1;
727 vectors[0].iov_len = len1;
728 vectors[1].iov_base = (char*) data2;
729 vectors[1].iov_len = len2;
733 bytes_written = writev (fd,
737 if (bytes_written < 0 && errno == EINTR)
740 return bytes_written;
742 #else /* HAVE_WRITEV */
746 ret1 = _dbus_write (fd, buffer1, start1, len1);
747 if (ret1 == len1 && buffer2 != NULL)
749 ret2 = _dbus_write (fd, buffer2, start2, len2);
751 ret2 = 0; /* we can't report an error as the first write was OK */
758 #endif /* !HAVE_WRITEV */
761 #define _DBUS_MAX_SUN_PATH_LENGTH 99
764 * @def _DBUS_MAX_SUN_PATH_LENGTH
766 * Maximum length of the path to a UNIX domain socket,
767 * sockaddr_un::sun_path member. POSIX requires that all systems
768 * support at least 100 bytes here, including the nul termination.
769 * We use 99 for the max value to allow for the nul.
771 * We could probably also do sizeof (addr.sun_path)
772 * but this way we are the same on all platforms
773 * which is probably a good idea.
777 * Creates a socket and connects it to the UNIX domain socket at the
778 * given path. The connection fd is returned, and is set up as
781 * Uses abstract sockets instead of filesystem-linked sockets if
782 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
783 * On non-Linux abstract socket usage always fails.
785 * This will set FD_CLOEXEC for the socket returned.
787 * @param path the path to UNIX domain socket
788 * @param abstract #TRUE to use abstract namespace
789 * @param error return location for error code
790 * @returns connection file descriptor or -1 on error
793 _dbus_connect_unix_socket (const char *path,
794 dbus_bool_t abstract,
799 struct sockaddr_un addr;
801 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
803 _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
807 if (!_dbus_open_unix_socket (&fd, error))
809 _DBUS_ASSERT_ERROR_IS_SET(error);
812 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
815 addr.sun_family = AF_UNIX;
816 path_len = strlen (path);
820 #ifdef HAVE_ABSTRACT_SOCKETS
821 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
822 path_len++; /* Account for the extra nul byte added to the start of sun_path */
824 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
826 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
827 "Abstract socket name too long\n");
828 _dbus_close (fd, NULL);
832 strncpy (&addr.sun_path[1], path, path_len);
833 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
834 #else /* HAVE_ABSTRACT_SOCKETS */
835 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
836 "Operating system does not support abstract socket namespace\n");
837 _dbus_close (fd, NULL);
839 #endif /* ! HAVE_ABSTRACT_SOCKETS */
843 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
845 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
846 "Socket name too long\n");
847 _dbus_close (fd, NULL);
851 strncpy (addr.sun_path, path, path_len);
854 if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
856 dbus_set_error (error,
857 _dbus_error_from_errno (errno),
858 "Failed to connect to socket %s: %s",
859 path, _dbus_strerror (errno));
861 _dbus_close (fd, NULL);
865 if (!_dbus_set_fd_nonblocking (fd, error))
867 _DBUS_ASSERT_ERROR_IS_SET (error);
869 _dbus_close (fd, NULL);
877 * Creates a UNIX domain socket and connects it to the specified
878 * process to execute.
880 * This will set FD_CLOEXEC for the socket returned.
882 * @param path the path to the executable
883 * @param argv the argument list for the process to execute.
884 * argv[0] typically is identical to the path of the executable
885 * @param error return location for error code
886 * @returns connection file descriptor or -1 on error
889 _dbus_connect_exec (const char *path,
896 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
898 _dbus_verbose ("connecting to process %s\n", path);
900 if (socketpair (AF_UNIX, SOCK_STREAM
906 dbus_set_error (error,
907 _dbus_error_from_errno (errno),
908 "Failed to create socket pair: %s",
909 _dbus_strerror (errno));
913 _dbus_fd_set_close_on_exec (fds[0]);
914 _dbus_fd_set_close_on_exec (fds[1]);
919 dbus_set_error (error,
920 _dbus_error_from_errno (errno),
921 "Failed to fork() to call %s: %s",
922 path, _dbus_strerror (errno));
933 dup2 (fds[1], STDIN_FILENO);
934 dup2 (fds[1], STDOUT_FILENO);
936 if (fds[1] != STDIN_FILENO &&
937 fds[1] != STDOUT_FILENO)
940 /* Inherit STDERR and the controlling terminal from the
947 fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
955 if (!_dbus_set_fd_nonblocking (fds[0], error))
957 _DBUS_ASSERT_ERROR_IS_SET (error);
967 * Enables or disables the reception of credentials on the given socket during
968 * the next message transmission. This is only effective if the #LOCAL_CREDS
969 * system feature exists, in which case the other side of the connection does
970 * not have to do anything special to send the credentials.
972 * @param fd socket on which to change the #LOCAL_CREDS flag.
973 * @param on whether to enable or disable the #LOCAL_CREDS flag.
976 _dbus_set_local_creds (int fd, dbus_bool_t on)
978 dbus_bool_t retval = TRUE;
980 #if defined(HAVE_CMSGCRED)
981 /* NOOP just to make sure only one codepath is used
982 * and to prefer CMSGCRED
984 #elif defined(LOCAL_CREDS)
985 int val = on ? 1 : 0;
986 if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
988 _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
992 _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
993 on ? "enabled" : "disabled", fd);
1000 * Creates a socket and binds it to the given path,
1001 * then listens on the socket. The socket is
1002 * set to be nonblocking.
1004 * Uses abstract sockets instead of filesystem-linked
1005 * sockets if requested (it's possible only on Linux;
1006 * see "man 7 unix" on Linux).
1007 * On non-Linux abstract socket usage always fails.
1009 * This will set FD_CLOEXEC for the socket returned
1011 * @param path the socket name
1012 * @param abstract #TRUE to use abstract namespace
1013 * @param error return location for errors
1014 * @returns the listening file descriptor or -1 on error
1017 _dbus_listen_unix_socket (const char *path,
1018 dbus_bool_t abstract,
1022 struct sockaddr_un addr;
1024 unsigned int reuseaddr;
1026 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1028 _dbus_verbose ("listening on unix socket %s abstract=%d\n",
1031 if (!_dbus_open_unix_socket (&listen_fd, error))
1033 _DBUS_ASSERT_ERROR_IS_SET(error);
1036 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1039 addr.sun_family = AF_UNIX;
1040 path_len = strlen (path);
1044 #ifdef HAVE_ABSTRACT_SOCKETS
1045 /* remember that abstract names aren't nul-terminated so we rely
1046 * on sun_path being filled in with zeroes above.
1048 addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
1049 path_len++; /* Account for the extra nul byte added to the start of sun_path */
1051 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1053 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1054 "Abstract socket name too long\n");
1055 _dbus_close (listen_fd, NULL);
1059 strncpy (&addr.sun_path[1], path, path_len);
1060 /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
1061 #else /* HAVE_ABSTRACT_SOCKETS */
1062 dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
1063 "Operating system does not support abstract socket namespace\n");
1064 _dbus_close (listen_fd, NULL);
1066 #endif /* ! HAVE_ABSTRACT_SOCKETS */
1070 /* Discussed security implications of this with Nalin,
1071 * and we couldn't think of where it would kick our ass, but
1072 * it still seems a bit sucky. It also has non-security suckage;
1073 * really we'd prefer to exit if the socket is already in use.
1074 * But there doesn't seem to be a good way to do this.
1076 * Just to be extra careful, I threw in the stat() - clearly
1077 * the stat() can't *fix* any security issue, but it at least
1078 * avoids inadvertent/accidental data loss.
1083 if (stat (path, &sb) == 0 &&
1084 S_ISSOCK (sb.st_mode))
1088 if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
1090 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1091 "Abstract socket name too long\n");
1092 _dbus_close (listen_fd, NULL);
1096 strncpy (addr.sun_path, path, path_len);
1100 if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1102 _dbus_warn ("Failed to set socket option\"%s\": %s",
1103 path, _dbus_strerror (errno));
1106 if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1108 dbus_set_error (error, _dbus_error_from_errno (errno),
1109 "Failed to bind socket \"%s\": %s",
1110 path, _dbus_strerror (errno));
1111 _dbus_close (listen_fd, NULL);
1115 if (listen (listen_fd, 30 /* backlog */) < 0)
1117 dbus_set_error (error, _dbus_error_from_errno (errno),
1118 "Failed to listen on socket \"%s\": %s",
1119 path, _dbus_strerror (errno));
1120 _dbus_close (listen_fd, NULL);
1124 if (!_dbus_set_local_creds (listen_fd, TRUE))
1126 dbus_set_error (error, _dbus_error_from_errno (errno),
1127 "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1128 path, _dbus_strerror (errno));
1133 if (!_dbus_set_fd_nonblocking (listen_fd, error))
1135 _DBUS_ASSERT_ERROR_IS_SET (error);
1136 _dbus_close (listen_fd, NULL);
1140 /* Try opening up the permissions, but if we can't, just go ahead
1141 * and continue, maybe it will be good enough.
1143 if (!abstract && chmod (path, 0777) < 0)
1144 _dbus_warn ("Could not set mode 0777 on socket %s\n",
1151 * Acquires one or more sockets passed in from systemd. The sockets
1152 * are set to be nonblocking.
1154 * This will set FD_CLOEXEC for the sockets returned.
1156 * @param fds the file descriptors
1157 * @param error return location for errors
1158 * @returns the number of file descriptors
1161 _dbus_listen_systemd_sockets (int **fds,
1168 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1170 n = sd_listen_fds (TRUE);
1173 dbus_set_error (error, _dbus_error_from_errno (-n),
1174 "Failed to acquire systemd socket: %s",
1175 _dbus_strerror (-n));
1181 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1182 "No socket received.");
1186 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1188 r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1191 dbus_set_error (error, _dbus_error_from_errno (-r),
1192 "Failed to verify systemd socket type: %s",
1193 _dbus_strerror (-r));
1199 dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1200 "Passed socket has wrong type.");
1205 /* OK, the file descriptors are all good, so let's take posession of
1208 new_fds = dbus_new (int, n);
1211 dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1212 "Failed to allocate file handle array.");
1216 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1218 if (!_dbus_set_local_creds (fd, TRUE))
1220 dbus_set_error (error, _dbus_error_from_errno (errno),
1221 "Failed to enable LOCAL_CREDS on systemd socket: %s",
1222 _dbus_strerror (errno));
1226 if (!_dbus_set_fd_nonblocking (fd, error))
1228 _DBUS_ASSERT_ERROR_IS_SET (error);
1232 new_fds[fd - SD_LISTEN_FDS_START] = fd;
1240 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1242 _dbus_close (fd, NULL);
1245 dbus_free (new_fds);
1250 * Creates a socket and connects to a socket at the given host
1251 * and port. The connection fd is returned, and is set up as
1254 * This will set FD_CLOEXEC for the socket returned
1256 * @param host the host name to connect to
1257 * @param port the port to connect to
1258 * @param family the address family to listen on, NULL for all
1259 * @param error return location for error code
1260 * @returns connection file descriptor or -1 on error
1263 _dbus_connect_tcp_socket (const char *host,
1268 return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1272 _dbus_connect_tcp_socket_with_nonce (const char *host,
1275 const char *noncefile,
1278 int saved_errno = 0;
1280 struct addrinfo hints;
1281 struct addrinfo *ai, *tmp;
1283 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1288 hints.ai_family = AF_UNSPEC;
1289 else if (!strcmp(family, "ipv4"))
1290 hints.ai_family = AF_INET;
1291 else if (!strcmp(family, "ipv6"))
1292 hints.ai_family = AF_INET6;
1295 dbus_set_error (error,
1296 DBUS_ERROR_BAD_ADDRESS,
1297 "Unknown address family %s", family);
1300 hints.ai_protocol = IPPROTO_TCP;
1301 hints.ai_socktype = SOCK_STREAM;
1302 hints.ai_flags = AI_ADDRCONFIG;
1304 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1306 dbus_set_error (error,
1307 _dbus_error_from_errno (errno),
1308 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1309 host, port, gai_strerror(res), res);
1316 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1319 _DBUS_ASSERT_ERROR_IS_SET(error);
1322 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1324 if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1326 saved_errno = errno;
1327 _dbus_close(fd, NULL);
1339 dbus_set_error (error,
1340 _dbus_error_from_errno (saved_errno),
1341 "Failed to connect to socket \"%s:%s\" %s",
1342 host, port, _dbus_strerror(saved_errno));
1346 if (noncefile != NULL)
1348 DBusString noncefileStr;
1350 _dbus_string_init_const (&noncefileStr, noncefile);
1351 ret = _dbus_send_nonce (fd, &noncefileStr, error);
1352 _dbus_string_free (&noncefileStr);
1356 _dbus_close (fd, NULL);
1361 if (!_dbus_set_fd_nonblocking (fd, error))
1363 _dbus_close (fd, NULL);
1371 * Creates a socket and binds it to the given path, then listens on
1372 * the socket. The socket is set to be nonblocking. In case of port=0
1373 * a random free port is used and returned in the port parameter.
1374 * If inaddr_any is specified, the hostname is ignored.
1376 * This will set FD_CLOEXEC for the socket returned
1378 * @param host the host name to listen on
1379 * @param port the port to listen on, if zero a free port will be used
1380 * @param family the address family to listen on, NULL for all
1381 * @param retport string to return the actual port listened on
1382 * @param fds_p location to store returned file descriptors
1383 * @param error return location for errors
1384 * @returns the number of listening file descriptors or -1 on error
1387 _dbus_listen_tcp_socket (const char *host,
1390 DBusString *retport,
1395 int nlisten_fd = 0, *listen_fd = NULL, res, i;
1396 struct addrinfo hints;
1397 struct addrinfo *ai, *tmp;
1398 unsigned int reuseaddr;
1401 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1406 hints.ai_family = AF_UNSPEC;
1407 else if (!strcmp(family, "ipv4"))
1408 hints.ai_family = AF_INET;
1409 else if (!strcmp(family, "ipv6"))
1410 hints.ai_family = AF_INET6;
1413 dbus_set_error (error,
1414 DBUS_ERROR_BAD_ADDRESS,
1415 "Unknown address family %s", family);
1419 hints.ai_protocol = IPPROTO_TCP;
1420 hints.ai_socktype = SOCK_STREAM;
1421 hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1423 redo_lookup_with_port:
1425 if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1427 dbus_set_error (error,
1428 _dbus_error_from_errno (errno),
1429 "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1430 host ? host : "*", port, gai_strerror(res), res);
1437 int fd = -1, *newlisten_fd;
1438 if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1440 _DBUS_ASSERT_ERROR_IS_SET(error);
1443 _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1446 if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1448 _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1449 host ? host : "*", port, _dbus_strerror (errno));
1452 if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1454 saved_errno = errno;
1455 _dbus_close(fd, NULL);
1456 if (saved_errno == EADDRINUSE)
1458 /* Depending on kernel policy, it may or may not
1459 be neccessary to bind to both IPv4 & 6 addresses
1460 so ignore EADDRINUSE here */
1464 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1465 "Failed to bind socket \"%s:%s\": %s",
1466 host ? host : "*", port, _dbus_strerror (saved_errno));
1470 if (listen (fd, 30 /* backlog */) < 0)
1472 saved_errno = errno;
1473 _dbus_close (fd, NULL);
1474 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1475 "Failed to listen on socket \"%s:%s\": %s",
1476 host ? host : "*", port, _dbus_strerror (saved_errno));
1480 newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1483 saved_errno = errno;
1484 _dbus_close (fd, NULL);
1485 dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1486 "Failed to allocate file handle array: %s",
1487 _dbus_strerror (saved_errno));
1490 listen_fd = newlisten_fd;
1491 listen_fd[nlisten_fd] = fd;
1494 if (!_dbus_string_get_length(retport))
1496 /* If the user didn't specify a port, or used 0, then
1497 the kernel chooses a port. After the first address
1498 is bound to, we need to force all remaining addresses
1499 to use the same port */
1500 if (!port || !strcmp(port, "0"))
1503 struct sockaddr_storage addr;
1507 addrlen = sizeof(addr);
1508 result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1511 (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
1512 portbuf, sizeof(portbuf),
1513 NI_NUMERICHOST)) != 0)
1515 dbus_set_error (error, _dbus_error_from_errno (errno),
1516 "Failed to resolve port \"%s:%s\": %s (%s)",
1517 host ? host : "*", port, gai_strerror(res), res);
1520 if (!_dbus_string_append(retport, portbuf))
1522 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1526 /* Release current address list & redo lookup */
1527 port = _dbus_string_get_const_data(retport);
1529 goto redo_lookup_with_port;
1533 if (!_dbus_string_append(retport, port))
1535 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1549 dbus_set_error (error, _dbus_error_from_errno (errno),
1550 "Failed to bind socket \"%s:%s\": %s",
1551 host ? host : "*", port, _dbus_strerror (errno));
1555 for (i = 0 ; i < nlisten_fd ; i++)
1557 if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1570 for (i = 0 ; i < nlisten_fd ; i++)
1571 _dbus_close(listen_fd[i], NULL);
1572 dbus_free(listen_fd);
1577 write_credentials_byte (int server_fd,
1581 char buf[1] = { '\0' };
1582 #if defined(HAVE_CMSGCRED)
1585 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1596 msg.msg_control = (caddr_t) &cmsg;
1597 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1599 cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1600 cmsg.hdr.cmsg_level = SOL_SOCKET;
1601 cmsg.hdr.cmsg_type = SCM_CREDS;
1604 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1608 #if defined(HAVE_CMSGCRED)
1609 bytes_written = sendmsg (server_fd, &msg, 0
1610 #if HAVE_DECL_MSG_NOSIGNAL
1615 bytes_written = send (server_fd, buf, 1, 0
1616 #if HAVE_DECL_MSG_NOSIGNAL
1622 if (bytes_written < 0 && errno == EINTR)
1625 if (bytes_written < 0)
1627 dbus_set_error (error, _dbus_error_from_errno (errno),
1628 "Failed to write credentials byte: %s",
1629 _dbus_strerror (errno));
1632 else if (bytes_written == 0)
1634 dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1635 "wrote zero bytes writing credentials byte");
1640 _dbus_assert (bytes_written == 1);
1641 _dbus_verbose ("wrote credentials byte\n");
1647 * Reads a single byte which must be nul (an error occurs otherwise),
1648 * and reads unix credentials if available. Clears the credentials
1649 * object, then adds pid/uid if available, so any previous credentials
1650 * stored in the object are lost.
1652 * Return value indicates whether a byte was read, not whether
1653 * we got valid credentials. On some systems, such as Linux,
1654 * reading/writing the byte isn't actually required, but we do it
1655 * anyway just to avoid multiple codepaths.
1657 * Fails if no byte is available, so you must select() first.
1659 * The point of the byte is that on some systems we have to
1660 * use sendmsg()/recvmsg() to transmit credentials.
1662 * @param client_fd the client file descriptor
1663 * @param credentials object to add client credentials to
1664 * @param error location to store error code
1665 * @returns #TRUE on success
1668 _dbus_read_credentials_socket (int client_fd,
1669 DBusCredentials *credentials,
1675 dbus_uid_t uid_read;
1676 dbus_pid_t pid_read;
1679 #ifdef HAVE_CMSGCRED
1682 char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1685 #elif defined(LOCAL_CREDS)
1688 struct sockcred cred;
1692 uid_read = DBUS_UID_UNSET;
1693 pid_read = DBUS_PID_UNSET;
1695 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1697 /* The POSIX spec certainly doesn't promise this, but
1698 * we need these assertions to fail as soon as we're wrong about
1699 * it so we can do the porting fixups
1701 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1702 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1703 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1705 _dbus_credentials_clear (credentials);
1707 /* Systems supporting LOCAL_CREDS are configured to have this feature
1708 * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1709 * the connection. Therefore, the received message must carry the
1710 * credentials information without doing anything special.
1713 iov.iov_base = &buf;
1720 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1722 msg.msg_control = (caddr_t) &cmsg;
1723 msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1727 bytes_read = recvmsg (client_fd, &msg, 0);
1734 /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1735 * normally only call read_credentials if the socket was ready
1739 dbus_set_error (error, _dbus_error_from_errno (errno),
1740 "Failed to read credentials byte: %s",
1741 _dbus_strerror (errno));
1744 else if (bytes_read == 0)
1746 /* this should not happen unless we are using recvmsg wrong,
1747 * so is essentially here for paranoia
1749 dbus_set_error (error, DBUS_ERROR_FAILED,
1750 "Failed to read credentials byte (zero-length read)");
1753 else if (buf != '\0')
1755 dbus_set_error (error, DBUS_ERROR_FAILED,
1756 "Credentials byte was not nul");
1760 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1761 if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1762 || cmsg.hdr.cmsg_type != SCM_CREDS)
1764 dbus_set_error (error, DBUS_ERROR_FAILED,
1765 "Message from recvmsg() was not SCM_CREDS");
1770 _dbus_verbose ("read credentials byte\n");
1775 struct sockpeercred cr;
1779 int cr_len = sizeof (cr);
1781 if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1782 cr_len == sizeof (cr))
1789 _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1790 cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1792 #elif defined(HAVE_CMSGCRED)
1793 struct cmsgcred *cred;
1795 cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1796 pid_read = cred->cmcred_pid;
1797 uid_read = cred->cmcred_euid;
1798 #elif defined(LOCAL_CREDS)
1799 pid_read = DBUS_PID_UNSET;
1800 uid_read = cmsg.cred.sc_uid;
1801 /* Since we have already got the credentials from this socket, we can
1802 * disable its LOCAL_CREDS flag if it was ever set. */
1803 _dbus_set_local_creds (client_fd, FALSE);
1804 #elif defined(HAVE_GETPEEREID)
1807 if (getpeereid (client_fd, &euid, &egid) == 0)
1813 _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1815 #elif defined(HAVE_GETPEERUCRED)
1816 ucred_t * ucred = NULL;
1817 if (getpeerucred (client_fd, &ucred) == 0)
1819 pid_read = ucred_getpid (ucred);
1820 uid_read = ucred_geteuid (ucred);
1822 /* generate audit session data based on socket ucred */
1823 adt_session_data_t *adth = NULL;
1824 adt_export_data_t *data = NULL;
1826 if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1828 _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1832 if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1834 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1838 size = adt_export_session_data (adth, &data);
1841 _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1845 _dbus_credentials_add_adt_audit_data (credentials, data, size);
1849 (void) adt_end_session (adth);
1851 #endif /* HAVE_ADT */
1855 _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1859 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1860 _dbus_verbose ("Socket credentials not supported on this OS\n");
1864 _dbus_verbose ("Credentials:"
1865 " pid "DBUS_PID_FORMAT
1866 " uid "DBUS_UID_FORMAT
1871 if (pid_read != DBUS_PID_UNSET)
1873 if (!_dbus_credentials_add_pid (credentials, pid_read))
1875 _DBUS_SET_OOM (error);
1880 if (uid_read != DBUS_UID_UNSET)
1882 if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1884 _DBUS_SET_OOM (error);
1893 * Sends a single nul byte with our UNIX credentials as ancillary
1894 * data. Returns #TRUE if the data was successfully written. On
1895 * systems that don't support sending credentials, just writes a byte,
1896 * doesn't send any credentials. On some systems, such as Linux,
1897 * reading/writing the byte isn't actually required, but we do it
1898 * anyway just to avoid multiple codepaths.
1900 * Fails if no byte can be written, so you must select() first.
1902 * The point of the byte is that on some systems we have to
1903 * use sendmsg()/recvmsg() to transmit credentials.
1905 * @param server_fd file descriptor for connection to server
1906 * @param error return location for error code
1907 * @returns #TRUE if the byte was sent
1910 _dbus_send_credentials_socket (int server_fd,
1913 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1915 if (write_credentials_byte (server_fd, error))
1922 * Accepts a connection on a listening socket.
1923 * Handles EINTR for you.
1925 * This will enable FD_CLOEXEC for the returned socket.
1927 * @param listen_fd the listen file descriptor
1928 * @returns the connection fd of the client, or -1 on error
1931 _dbus_accept (int listen_fd)
1934 struct sockaddr addr;
1937 dbus_bool_t cloexec_done;
1940 addrlen = sizeof (addr);
1945 /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1946 client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1947 cloexec_done = client_fd >= 0;
1949 if (client_fd < 0 && errno == ENOSYS)
1952 client_fd = accept (listen_fd, &addr, &addrlen);
1961 _dbus_verbose ("client fd %d accepted\n", client_fd);
1967 _dbus_fd_set_close_on_exec(client_fd);
1974 * Checks to make sure the given directory is
1975 * private to the user
1977 * @param dir the name of the directory
1978 * @param error error return
1979 * @returns #FALSE on failure
1982 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1984 const char *directory;
1987 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1989 directory = _dbus_string_get_const_data (dir);
1991 if (stat (directory, &sb) < 0)
1993 dbus_set_error (error, _dbus_error_from_errno (errno),
1994 "%s", _dbus_strerror (errno));
1999 if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
2000 (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
2002 dbus_set_error (error, DBUS_ERROR_FAILED,
2003 "%s directory is not private to the user", directory);
2011 fill_user_info_from_passwd (struct passwd *p,
2015 _dbus_assert (p->pw_name != NULL);
2016 _dbus_assert (p->pw_dir != NULL);
2018 info->uid = p->pw_uid;
2019 info->primary_gid = p->pw_gid;
2020 info->username = _dbus_strdup (p->pw_name);
2021 info->homedir = _dbus_strdup (p->pw_dir);
2023 if (info->username == NULL ||
2024 info->homedir == NULL)
2026 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2034 fill_user_info (DBusUserInfo *info,
2036 const DBusString *username,
2039 const char *username_c;
2041 /* exactly one of username/uid provided */
2042 _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
2043 _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
2045 info->uid = DBUS_UID_UNSET;
2046 info->primary_gid = DBUS_GID_UNSET;
2047 info->group_ids = NULL;
2048 info->n_group_ids = 0;
2049 info->username = NULL;
2050 info->homedir = NULL;
2052 if (username != NULL)
2053 username_c = _dbus_string_get_const_data (username);
2057 /* For now assuming that the getpwnam() and getpwuid() flavors
2058 * are always symmetrical, if not we have to add more configure
2062 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
2068 struct passwd p_str;
2070 /* retrieve maximum needed size for buf */
2071 buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
2073 /* sysconf actually returns a long, but everything else expects size_t,
2074 * so just recast here.
2075 * https://bugs.freedesktop.org/show_bug.cgi?id=17061
2077 if ((long) buflen <= 0)
2083 buf = dbus_malloc (buflen);
2086 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2091 #ifdef HAVE_POSIX_GETPWNAM_R
2092 if (uid != DBUS_UID_UNSET)
2093 result = getpwuid_r (uid, &p_str, buf, buflen,
2096 result = getpwnam_r (username_c, &p_str, buf, buflen,
2099 if (uid != DBUS_UID_UNSET)
2100 p = getpwuid_r (uid, &p_str, buf, buflen);
2102 p = getpwnam_r (username_c, &p_str, buf, buflen);
2104 #endif /* !HAVE_POSIX_GETPWNAM_R */
2105 //Try a bigger buffer if ERANGE was returned
2106 if (result == ERANGE && buflen < 512 * 1024)
2116 if (result == 0 && p == &p_str)
2118 if (!fill_user_info_from_passwd (p, info, error))
2127 dbus_set_error (error, _dbus_error_from_errno (errno),
2128 "User \"%s\" unknown or no memory to allocate password entry\n",
2129 username_c ? username_c : "???");
2130 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2135 #else /* ! HAVE_GETPWNAM_R */
2137 /* I guess we're screwed on thread safety here */
2140 if (uid != DBUS_UID_UNSET)
2143 p = getpwnam (username_c);
2147 if (!fill_user_info_from_passwd (p, info, error))
2154 dbus_set_error (error, _dbus_error_from_errno (errno),
2155 "User \"%s\" unknown or no memory to allocate password entry\n",
2156 username_c ? username_c : "???");
2157 _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2161 #endif /* ! HAVE_GETPWNAM_R */
2163 /* Fill this in so we can use it to get groups */
2164 username_c = info->username;
2166 #ifdef HAVE_GETGROUPLIST
2171 int initial_buf_count;
2173 initial_buf_count = 17;
2174 buf_count = initial_buf_count;
2175 buf = dbus_new (gid_t, buf_count);
2178 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2182 if (getgrouplist (username_c,
2184 buf, &buf_count) < 0)
2187 /* Presumed cause of negative return code: buf has insufficient
2188 entries to hold the entire group list. The Linux behavior in this
2189 case is to pass back the actual number of groups in buf_count, but
2190 on Mac OS X 10.5, buf_count is unhelpfully left alone.
2191 So as a hack, try to help out a bit by guessing a larger
2192 number of groups, within reason.. might still fail, of course,
2193 but we can at least print a more informative message. I looked up
2194 the "right way" to do this by downloading Apple's own source code
2195 for the "id" command, and it turns out that they use an
2196 undocumented library function getgrouplist_2 (!) which is not
2197 declared in any header in /usr/include (!!). That did not seem
2198 like the way to go here.
2200 if (buf_count == initial_buf_count)
2202 buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2204 new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2207 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2215 if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2219 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2220 username_c, buf_count, buf_count);
2224 dbus_set_error (error,
2225 _dbus_error_from_errno (errno),
2226 "Failed to get groups for username \"%s\" primary GID "
2227 DBUS_GID_FORMAT ": %s\n",
2228 username_c, info->primary_gid,
2229 _dbus_strerror (errno));
2236 info->group_ids = dbus_new (dbus_gid_t, buf_count);
2237 if (info->group_ids == NULL)
2239 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2244 for (i = 0; i < buf_count; ++i)
2245 info->group_ids[i] = buf[i];
2247 info->n_group_ids = buf_count;
2251 #else /* HAVE_GETGROUPLIST */
2253 /* We just get the one group ID */
2254 info->group_ids = dbus_new (dbus_gid_t, 1);
2255 if (info->group_ids == NULL)
2257 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2261 info->n_group_ids = 1;
2263 (info->group_ids)[0] = info->primary_gid;
2265 #endif /* HAVE_GETGROUPLIST */
2267 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2272 _DBUS_ASSERT_ERROR_IS_SET (error);
2277 * Gets user info for the given username.
2279 * @param info user info object to initialize
2280 * @param username the username
2281 * @param error error return
2282 * @returns #TRUE on success
2285 _dbus_user_info_fill (DBusUserInfo *info,
2286 const DBusString *username,
2289 return fill_user_info (info, DBUS_UID_UNSET,
2294 * Gets user info for the given user ID.
2296 * @param info user info object to initialize
2297 * @param uid the user ID
2298 * @param error error return
2299 * @returns #TRUE on success
2302 _dbus_user_info_fill_uid (DBusUserInfo *info,
2306 return fill_user_info (info, uid,
2311 * Adds the credentials of the current process to the
2312 * passed-in credentials object.
2314 * @param credentials credentials to add to
2315 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2318 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2320 /* The POSIX spec certainly doesn't promise this, but
2321 * we need these assertions to fail as soon as we're wrong about
2322 * it so we can do the porting fixups
2324 _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2325 _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2326 _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2328 if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
2330 if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2337 * Append to the string the identity we would like to have when we
2338 * authenticate, on UNIX this is the current process UID and on
2339 * Windows something else, probably a Windows SID string. No escaping
2340 * is required, that is done in dbus-auth.c. The username here
2341 * need not be anything human-readable, it can be the machine-readable
2342 * form i.e. a user id.
2344 * @param str the string to append to
2345 * @returns #FALSE on no memory
2348 _dbus_append_user_from_current_process (DBusString *str)
2350 return _dbus_string_append_uint (str,
2355 * Gets our process ID
2356 * @returns process ID
2365 * @returns process UID
2373 /** Gets our effective UID
2374 * @returns process effective UID
2377 _dbus_geteuid (void)
2383 * The only reason this is separate from _dbus_getpid() is to allow it
2384 * on Windows for logging but not for other purposes.
2386 * @returns process ID to put in log messages
2389 _dbus_pid_for_log (void)
2395 * Gets a UID from a UID string.
2397 * @param uid_str the UID in string form
2398 * @param uid UID to fill in
2399 * @returns #TRUE if successfully filled in UID
2402 _dbus_parse_uid (const DBusString *uid_str,
2408 if (_dbus_string_get_length (uid_str) == 0)
2410 _dbus_verbose ("UID string was zero length\n");
2416 if (!_dbus_string_parse_int (uid_str, 0, &val,
2419 _dbus_verbose ("could not parse string as a UID\n");
2423 if (end != _dbus_string_get_length (uid_str))
2425 _dbus_verbose ("string contained trailing stuff after UID\n");
2435 /* To be thread-safe by default on platforms that don't necessarily have
2436 * atomic operations (notably Debian armel, which is armv4t), we must
2437 * use a mutex that can be initialized statically, like this.
2438 * GLib >= 2.32 uses a similar system.
2440 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
2444 * Atomically increments an integer
2446 * @param atomic pointer to the integer to increment
2447 * @returns the value before incrementing
2450 _dbus_atomic_inc (DBusAtomic *atomic)
2453 return __sync_add_and_fetch(&atomic->value, 1)-1;
2457 pthread_mutex_lock (&atomic_mutex);
2458 res = atomic->value;
2460 pthread_mutex_unlock (&atomic_mutex);
2467 * Atomically decrement an integer
2469 * @param atomic pointer to the integer to decrement
2470 * @returns the value before decrementing
2473 _dbus_atomic_dec (DBusAtomic *atomic)
2476 return __sync_sub_and_fetch(&atomic->value, 1)+1;
2480 pthread_mutex_lock (&atomic_mutex);
2481 res = atomic->value;
2483 pthread_mutex_unlock (&atomic_mutex);
2490 * Atomically get the value of an integer. It may change at any time
2491 * thereafter, so this is mostly only useful for assertions.
2493 * @param atomic pointer to the integer to get
2494 * @returns the value at this moment
2497 _dbus_atomic_get (DBusAtomic *atomic)
2500 __sync_synchronize ();
2501 return atomic->value;
2505 pthread_mutex_lock (&atomic_mutex);
2506 res = atomic->value;
2507 pthread_mutex_unlock (&atomic_mutex);
2514 * Wrapper for poll().
2516 * @param fds the file descriptors to poll
2517 * @param n_fds number of descriptors in the array
2518 * @param timeout_milliseconds timeout or -1 for infinite
2519 * @returns numbers of fds with revents, or <0 on error
2522 _dbus_poll (DBusPollFD *fds,
2524 int timeout_milliseconds)
2526 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2527 /* This big thing is a constant expression and should get optimized
2528 * out of existence. So it's more robust than a configure check at
2531 if (_DBUS_POLLIN == POLLIN &&
2532 _DBUS_POLLPRI == POLLPRI &&
2533 _DBUS_POLLOUT == POLLOUT &&
2534 _DBUS_POLLERR == POLLERR &&
2535 _DBUS_POLLHUP == POLLHUP &&
2536 _DBUS_POLLNVAL == POLLNVAL &&
2537 sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2538 _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2539 _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2540 _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2541 _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2542 _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2543 _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2545 return poll ((struct pollfd*) fds,
2547 timeout_milliseconds);
2551 /* We have to convert the DBusPollFD to an array of
2552 * struct pollfd, poll, and convert back.
2554 _dbus_warn ("didn't implement poll() properly for this system yet\n");
2557 #else /* ! HAVE_POLL */
2559 fd_set read_set, write_set, err_set;
2565 FD_ZERO (&read_set);
2566 FD_ZERO (&write_set);
2569 for (i = 0; i < n_fds; i++)
2571 DBusPollFD *fdp = &fds[i];
2573 if (fdp->events & _DBUS_POLLIN)
2574 FD_SET (fdp->fd, &read_set);
2576 if (fdp->events & _DBUS_POLLOUT)
2577 FD_SET (fdp->fd, &write_set);
2579 FD_SET (fdp->fd, &err_set);
2581 max_fd = MAX (max_fd, fdp->fd);
2584 tv.tv_sec = timeout_milliseconds / 1000;
2585 tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2587 ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2588 timeout_milliseconds < 0 ? NULL : &tv);
2592 for (i = 0; i < n_fds; i++)
2594 DBusPollFD *fdp = &fds[i];
2598 if (FD_ISSET (fdp->fd, &read_set))
2599 fdp->revents |= _DBUS_POLLIN;
2601 if (FD_ISSET (fdp->fd, &write_set))
2602 fdp->revents |= _DBUS_POLLOUT;
2604 if (FD_ISSET (fdp->fd, &err_set))
2605 fdp->revents |= _DBUS_POLLERR;
2614 * Get current time, as in gettimeofday(). Use the monotonic clock if
2615 * available, to avoid problems when the system time changes.
2617 * @param tv_sec return location for number of seconds
2618 * @param tv_usec return location for number of microseconds
2621 _dbus_get_monotonic_time (long *tv_sec,
2624 #ifdef HAVE_MONOTONIC_CLOCK
2626 clock_gettime (CLOCK_MONOTONIC, &ts);
2629 *tv_sec = ts.tv_sec;
2631 *tv_usec = ts.tv_nsec / 1000;
2635 gettimeofday (&t, NULL);
2640 *tv_usec = t.tv_usec;
2645 * Get current time, as in gettimeofday(). Never uses the monotonic
2648 * @param tv_sec return location for number of seconds
2649 * @param tv_usec return location for number of microseconds
2652 _dbus_get_real_time (long *tv_sec,
2657 gettimeofday (&t, NULL);
2662 *tv_usec = t.tv_usec;
2666 * Creates a directory; succeeds if the directory
2667 * is created or already existed.
2669 * @param filename directory filename
2670 * @param error initialized error object
2671 * @returns #TRUE on success
2674 _dbus_create_directory (const DBusString *filename,
2677 const char *filename_c;
2679 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2681 filename_c = _dbus_string_get_const_data (filename);
2683 if (mkdir (filename_c, 0700) < 0)
2685 if (errno == EEXIST)
2688 dbus_set_error (error, DBUS_ERROR_FAILED,
2689 "Failed to create directory %s: %s\n",
2690 filename_c, _dbus_strerror (errno));
2698 * Appends the given filename to the given directory.
2700 * @todo it might be cute to collapse multiple '/' such as "foo//"
2703 * @param dir the directory name
2704 * @param next_component the filename
2705 * @returns #TRUE on success
2708 _dbus_concat_dir_and_file (DBusString *dir,
2709 const DBusString *next_component)
2711 dbus_bool_t dir_ends_in_slash;
2712 dbus_bool_t file_starts_with_slash;
2714 if (_dbus_string_get_length (dir) == 0 ||
2715 _dbus_string_get_length (next_component) == 0)
2718 dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2719 _dbus_string_get_length (dir) - 1);
2721 file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2723 if (dir_ends_in_slash && file_starts_with_slash)
2725 _dbus_string_shorten (dir, 1);
2727 else if (!(dir_ends_in_slash || file_starts_with_slash))
2729 if (!_dbus_string_append_byte (dir, '/'))
2733 return _dbus_string_copy (next_component, 0, dir,
2734 _dbus_string_get_length (dir));
2737 /** nanoseconds in a second */
2738 #define NANOSECONDS_PER_SECOND 1000000000
2739 /** microseconds in a second */
2740 #define MICROSECONDS_PER_SECOND 1000000
2741 /** milliseconds in a second */
2742 #define MILLISECONDS_PER_SECOND 1000
2743 /** nanoseconds in a millisecond */
2744 #define NANOSECONDS_PER_MILLISECOND 1000000
2745 /** microseconds in a millisecond */
2746 #define MICROSECONDS_PER_MILLISECOND 1000
2749 * Sleeps the given number of milliseconds.
2750 * @param milliseconds number of milliseconds
2753 _dbus_sleep_milliseconds (int milliseconds)
2755 #ifdef HAVE_NANOSLEEP
2756 struct timespec req;
2757 struct timespec rem;
2759 req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2760 req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2764 while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2766 #elif defined (HAVE_USLEEP)
2767 usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2768 #else /* ! HAVE_USLEEP */
2769 sleep (MAX (milliseconds / 1000, 1));
2774 _dbus_generate_pseudorandom_bytes (DBusString *str,
2780 old_len = _dbus_string_get_length (str);
2782 if (!_dbus_string_lengthen (str, n_bytes))
2785 p = _dbus_string_get_data_len (str, old_len, n_bytes);
2787 _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2793 * Generates the given number of random bytes,
2794 * using the best mechanism we can come up with.
2796 * @param str the string
2797 * @param n_bytes the number of random bytes to append to string
2798 * @returns #TRUE on success, #FALSE if no memory
2801 _dbus_generate_random_bytes (DBusString *str,
2807 /* FALSE return means "no memory", if it could
2808 * mean something else then we'd need to return
2809 * a DBusError. So we always fall back to pseudorandom
2813 old_len = _dbus_string_get_length (str);
2816 /* note, urandom on linux will fall back to pseudorandom */
2817 fd = open ("/dev/urandom", O_RDONLY);
2819 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2821 _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2823 if (_dbus_read (fd, str, n_bytes) != n_bytes)
2825 _dbus_close (fd, NULL);
2826 _dbus_string_set_length (str, old_len);
2827 return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2830 _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2833 _dbus_close (fd, NULL);
2839 * Exit the process, returning the given value.
2841 * @param code the exit code
2844 _dbus_exit (int code)
2850 * A wrapper around strerror() because some platforms
2851 * may be lame and not have strerror(). Also, never
2854 * @param error_number errno.
2855 * @returns error description.
2858 _dbus_strerror (int error_number)
2862 msg = strerror (error_number);
2870 * signal (SIGPIPE, SIG_IGN);
2873 _dbus_disable_sigpipe (void)
2875 signal (SIGPIPE, SIG_IGN);
2879 * Sets the file descriptor to be close
2880 * on exec. Should be called for all file
2881 * descriptors in D-Bus code.
2883 * @param fd the file descriptor
2886 _dbus_fd_set_close_on_exec (intptr_t fd)
2890 val = fcntl (fd, F_GETFD, 0);
2897 fcntl (fd, F_SETFD, val);
2901 * Closes a file descriptor.
2903 * @param fd the file descriptor
2904 * @param error error object
2905 * @returns #FALSE if error set
2908 _dbus_close (int fd,
2911 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2919 dbus_set_error (error, _dbus_error_from_errno (errno),
2920 "Could not close fd %d", fd);
2928 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2929 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2931 * @param fd the file descriptor to duplicate
2932 * @param error address of error location.
2933 * @returns duplicated file descriptor
2941 #ifdef F_DUPFD_CLOEXEC
2942 dbus_bool_t cloexec_done;
2944 new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2945 cloexec_done = new_fd >= 0;
2947 if (new_fd < 0 && errno == EINVAL)
2950 new_fd = fcntl(fd, F_DUPFD, 3);
2955 dbus_set_error (error, _dbus_error_from_errno (errno),
2956 "Could not duplicate fd %d", fd);
2960 #ifdef F_DUPFD_CLOEXEC
2964 _dbus_fd_set_close_on_exec(new_fd);
2971 * Sets a file descriptor to be nonblocking.
2973 * @param fd the file descriptor.
2974 * @param error address of error location.
2975 * @returns #TRUE on success.
2978 _dbus_set_fd_nonblocking (int fd,
2983 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2985 val = fcntl (fd, F_GETFL, 0);
2988 dbus_set_error (error, _dbus_error_from_errno (errno),
2989 "Failed to get flags from file descriptor %d: %s",
2990 fd, _dbus_strerror (errno));
2991 _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2992 _dbus_strerror (errno));
2996 if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2998 dbus_set_error (error, _dbus_error_from_errno (errno),
2999 "Failed to set nonblocking flag of file descriptor %d: %s",
3000 fd, _dbus_strerror (errno));
3001 _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
3002 fd, _dbus_strerror (errno));
3011 * On GNU libc systems, print a crude backtrace to stderr. On other
3012 * systems, print "no backtrace support" and block for possible gdb
3013 * attachment if an appropriate environment variable is set.
3016 _dbus_print_backtrace (void)
3018 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
3024 bt_size = backtrace (bt, 500);
3026 syms = backtrace_symbols (bt, bt_size);
3031 /* don't use dbus_warn since it can _dbus_abort() */
3032 fprintf (stderr, " %s\n", syms[i]);
3038 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
3039 fprintf (stderr, " D-Bus not built with -rdynamic so unable to print a backtrace\n");
3041 fprintf (stderr, " D-Bus not compiled with backtrace support so unable to print a backtrace\n");
3046 * Creates a full-duplex pipe (as in socketpair()).
3047 * Sets both ends of the pipe nonblocking.
3049 * Marks both file descriptors as close-on-exec
3051 * @param fd1 return location for one end
3052 * @param fd2 return location for the other end
3053 * @param blocking #TRUE if pipe should be blocking
3054 * @param error error return
3055 * @returns #FALSE on failure (if error is set)
3058 _dbus_full_duplex_pipe (int *fd1,
3060 dbus_bool_t blocking,
3063 #ifdef HAVE_SOCKETPAIR
3068 dbus_bool_t cloexec_done;
3070 retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
3071 cloexec_done = retval >= 0;
3073 if (retval < 0 && errno == EINVAL)
3076 retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
3081 dbus_set_error (error, _dbus_error_from_errno (errno),
3082 "Could not create full-duplex pipe");
3086 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3092 _dbus_fd_set_close_on_exec (fds[0]);
3093 _dbus_fd_set_close_on_exec (fds[1]);
3097 (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
3098 !_dbus_set_fd_nonblocking (fds[1], NULL)))
3100 dbus_set_error (error, _dbus_error_from_errno (errno),
3101 "Could not set full-duplex pipe nonblocking");
3103 _dbus_close (fds[0], NULL);
3104 _dbus_close (fds[1], NULL);
3112 _dbus_verbose ("full-duplex pipe %d <-> %d\n",
3117 _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
3118 dbus_set_error (error, DBUS_ERROR_FAILED,
3119 "_dbus_full_duplex_pipe() not implemented on this OS");
3125 * Measure the length of the given format string and arguments,
3126 * not including the terminating nul.
3128 * @param format a printf-style format string
3129 * @param args arguments for the format string
3130 * @returns length of the given format string and args, or -1 if no memory
3133 _dbus_printf_string_upper_bound (const char *format,
3136 char static_buf[1024];
3137 int bufsize = sizeof (static_buf);
3141 DBUS_VA_COPY (args_copy, args);
3142 len = vsnprintf (static_buf, bufsize, format, args_copy);
3145 /* If vsnprintf() returned non-negative, then either the string fits in
3146 * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
3147 * returns the number of characters that were needed, or this OS returns the
3150 * We ignore the possibility that snprintf might just ignore the length and
3151 * overrun the buffer (64-bit Solaris 7), because that's pathological.
3152 * If your libc is really that bad, come back when you have a better one. */
3155 /* This could be the truncated length (Tru64 and IRIX have this bug),
3156 * or the real length could be coincidentally the same. Which is it?
3157 * If vsnprintf returns the truncated length, we'll go to the slow
3159 DBUS_VA_COPY (args_copy, args);
3161 if (vsnprintf (static_buf, 1, format, args_copy) == 1)
3167 /* If vsnprintf() returned negative, we have to do more work.
3168 * HP-UX returns negative. */
3175 buf = dbus_malloc (bufsize);
3180 DBUS_VA_COPY (args_copy, args);
3181 len = vsnprintf (buf, bufsize, format, args_copy);
3186 /* If the reported length is exactly the buffer size, round up to the
3187 * next size, in case vsnprintf has been returning the truncated
3197 * Gets the temporary files directory by inspecting the environment variables
3198 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3200 * @returns location of temp directory
3203 _dbus_get_tmpdir(void)
3205 static const char* tmpdir = NULL;
3209 /* TMPDIR is what glibc uses, then
3210 * glibc falls back to the P_tmpdir macro which
3211 * just expands to "/tmp"
3214 tmpdir = getenv("TMPDIR");
3216 /* These two env variables are probably
3217 * broken, but maybe some OS uses them?
3220 tmpdir = getenv("TMP");
3222 tmpdir = getenv("TEMP");
3224 /* And this is the sane fallback. */
3229 _dbus_assert(tmpdir != NULL);
3234 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
3236 * Execute a subprocess, returning up to 1024 bytes of output
3239 * If successful, returns #TRUE and appends the output to @p
3240 * result. If a failure happens, returns #FALSE and
3241 * sets an error in @p error.
3243 * @note It's not an error if the subprocess terminates normally
3244 * without writing any data to stdout. Verify the @p result length
3245 * before and after this function call to cover this case.
3247 * @param progname initial path to exec (may or may not be absolute)
3248 * @param path_fallback if %TRUE, search PATH for executable
3249 * @param argv NULL-terminated list of arguments
3250 * @param result a DBusString where the output can be append
3251 * @param error a DBusError to store the error in case of failure
3252 * @returns #TRUE on success, #FALSE if an error happened
3255 _read_subprocess_line_argv (const char *progpath,
3256 dbus_bool_t path_fallback,
3261 int result_pipe[2] = { -1, -1 };
3262 int errors_pipe[2] = { -1, -1 };
3269 sigset_t new_set, old_set;
3271 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3274 /* We need to block any existing handlers for SIGCHLD temporarily; they
3275 * will cause waitpid() below to fail.
3276 * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3278 sigemptyset (&new_set);
3279 sigaddset (&new_set, SIGCHLD);
3280 sigprocmask (SIG_BLOCK, &new_set, &old_set);
3282 orig_len = _dbus_string_get_length (result);
3286 if (pipe (result_pipe) < 0)
3288 dbus_set_error (error, _dbus_error_from_errno (errno),
3289 "Failed to create a pipe to call %s: %s",
3290 progpath, _dbus_strerror (errno));
3291 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3292 progpath, _dbus_strerror (errno));
3295 if (pipe (errors_pipe) < 0)
3297 dbus_set_error (error, _dbus_error_from_errno (errno),
3298 "Failed to create a pipe to call %s: %s",
3299 progpath, _dbus_strerror (errno));
3300 _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3301 progpath, _dbus_strerror (errno));
3308 dbus_set_error (error, _dbus_error_from_errno (errno),
3309 "Failed to fork() to call %s: %s",
3310 progpath, _dbus_strerror (errno));
3311 _dbus_verbose ("Failed to fork() to call %s: %s\n",
3312 progpath, _dbus_strerror (errno));
3321 fd = open ("/dev/null", O_RDWR);
3323 /* huh?! can't open /dev/null? */
3326 _dbus_verbose ("/dev/null fd %d opened\n", fd);
3329 close (result_pipe[READ_END]);
3330 close (errors_pipe[READ_END]);
3332 if (dup2 (fd, 0) == -1) /* setup stdin */
3334 if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
3336 if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
3341 sigprocmask (SIG_SETMASK, &old_set, NULL);
3343 /* If it looks fully-qualified, try execv first */
3344 if (progpath[0] == '/')
3346 execv (progpath, argv);
3347 /* Ok, that failed. Now if path_fallback is given, let's
3348 * try unqualified. This is mostly a hack to work
3349 * around systems which ship dbus-launch in /usr/bin
3350 * but everything else in /bin (because dbus-launch
3354 /* We must have a slash, because we checked above */
3355 execvp (strrchr (progpath, '/')+1, argv);
3358 execvp (progpath, argv);
3360 /* still nothing, we failed */
3364 /* parent process */
3365 close (result_pipe[WRITE_END]);
3366 close (errors_pipe[WRITE_END]);
3367 result_pipe[WRITE_END] = -1;
3368 errors_pipe[WRITE_END] = -1;
3373 ret = _dbus_read (result_pipe[READ_END], result, 1024);
3377 /* reap the child process to avoid it lingering as zombie */
3380 ret = waitpid (pid, &status, 0);
3382 while (ret == -1 && errno == EINTR);
3384 /* We succeeded if the process exited with status 0 and
3385 anything was read */
3386 if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3388 /* The process ended with error */
3389 DBusString error_message;
3390 if (!_dbus_string_init (&error_message))
3392 _DBUS_SET_OOM (error);
3399 ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3403 _dbus_string_set_length (result, orig_len);
3404 if (_dbus_string_get_length (&error_message) > 0)
3405 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3406 "%s terminated abnormally with the following error: %s",
3407 progpath, _dbus_string_get_data (&error_message));
3409 dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3410 "%s terminated abnormally without any error message",
3418 sigprocmask (SIG_SETMASK, &old_set, NULL);
3421 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3423 _DBUS_ASSERT_ERROR_IS_SET (error);
3425 if (result_pipe[0] != -1)
3426 close (result_pipe[0]);
3427 if (result_pipe[1] != -1)
3428 close (result_pipe[1]);
3429 if (errors_pipe[0] != -1)
3430 close (errors_pipe[0]);
3431 if (errors_pipe[1] != -1)
3432 close (errors_pipe[1]);
3439 * Returns the address of a new session bus.
3441 * If successful, returns #TRUE and appends the address to @p
3442 * address. If a failure happens, returns #FALSE and
3443 * sets an error in @p error.
3445 * @param scope scope of autolaunch (Windows only)
3446 * @param address a DBusString where the address can be stored
3447 * @param error a DBusError to store the error in case of failure
3448 * @returns #TRUE on success, #FALSE if an error happened
3451 _dbus_get_autolaunch_address (const char *scope,
3452 DBusString *address,
3455 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
3456 /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
3457 * but that's done elsewhere, and if it worked, this function wouldn't
3459 const char *display;
3460 static char *argv[6];
3465 if (_dbus_check_setuid ())
3467 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3468 "Unable to autolaunch when setuid");
3472 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3475 /* fd.o #19997: if $DISPLAY isn't set to something useful, then
3476 * dbus-launch-x11 is just going to fail. Rather than trying to
3477 * run it, we might as well bail out early with a nice error. */
3478 display = _dbus_getenv ("DISPLAY");
3480 if (display == NULL || display[0] == '\0')
3482 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3483 "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
3487 if (!_dbus_string_init (&uuid))
3489 _DBUS_SET_OOM (error);
3493 if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3495 _DBUS_SET_OOM (error);
3500 argv[i] = "dbus-launch";
3502 argv[i] = "--autolaunch";
3504 argv[i] = _dbus_string_get_data (&uuid);
3506 argv[i] = "--binary-syntax";
3508 argv[i] = "--close-stderr";
3513 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3515 retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3517 argv, address, error);
3520 _dbus_string_free (&uuid);
3523 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3524 "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
3525 "set your DBUS_SESSION_BUS_ADDRESS instead");
3531 * Reads the uuid of the machine we're running on from
3532 * the dbus configuration. Optionally try to create it
3533 * (only root can do this usually).
3535 * On UNIX, reads a file that gets created by dbus-uuidgen
3536 * in a post-install script. On Windows, if there's a standard
3537 * machine uuid we could just use that, but I can't find one
3538 * with the right properties (the hardware profile guid can change
3539 * without rebooting I believe). If there's no standard one
3540 * we might want to use the registry instead of a file for
3541 * this, and I'm not sure how we'd ensure the uuid gets created.
3543 * @param machine_id guid to init with the machine's uuid
3544 * @param create_if_not_found try to create the uuid if it doesn't exist
3545 * @param error the error return
3546 * @returns #FALSE if the error is set
3549 _dbus_read_local_machine_uuid (DBusGUID *machine_id,
3550 dbus_bool_t create_if_not_found,
3553 DBusString filename;
3556 _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3558 b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3562 dbus_error_free (error);
3564 /* Fallback to the system machine ID */
3565 _dbus_string_init_const (&filename, "/etc/machine-id");
3566 return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
3569 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3570 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3573 * quries launchd for a specific env var which holds the socket path.
3574 * @param socket_path append the socket path to this DBusString
3575 * @param launchd_env_var the env var to look up
3576 * @param error a DBusError to store the error in case of failure
3577 * @return the value of the env var
3580 _dbus_lookup_launchd_socket (DBusString *socket_path,
3581 const char *launchd_env_var,
3584 #ifdef DBUS_ENABLE_LAUNCHD
3588 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3590 if (_dbus_check_setuid ())
3592 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3593 "Unable to find launchd socket when setuid");
3598 argv[i] = "launchctl";
3602 argv[i] = (char*)launchd_env_var;
3607 _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3609 if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
3614 /* no error, but no result either */
3615 if (_dbus_string_get_length(socket_path) == 0)
3620 /* strip the carriage-return */
3621 _dbus_string_shorten(socket_path, 1);
3623 #else /* DBUS_ENABLE_LAUNCHD */
3624 dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
3625 "can't lookup socket from launchd; launchd support not compiled in");
3630 #ifdef DBUS_ENABLE_LAUNCHD
3632 _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
3634 dbus_bool_t valid_socket;
3635 DBusString socket_path;
3637 if (_dbus_check_setuid ())
3639 dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
3640 "Unable to find launchd socket when setuid");
3644 if (!_dbus_string_init (&socket_path))
3646 _DBUS_SET_OOM (error);
3650 valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
3652 if (dbus_error_is_set(error))
3654 _dbus_string_free(&socket_path);
3660 dbus_set_error(error, "no socket path",
3661 "launchd did not provide a socket path, "
3662 "verify that org.freedesktop.dbus-session.plist is loaded!");
3663 _dbus_string_free(&socket_path);
3666 if (!_dbus_string_append (address, "unix:path="))
3668 _DBUS_SET_OOM (error);
3669 _dbus_string_free(&socket_path);
3672 if (!_dbus_string_copy (&socket_path, 0, address,
3673 _dbus_string_get_length (address)))
3675 _DBUS_SET_OOM (error);
3676 _dbus_string_free(&socket_path);
3680 _dbus_string_free(&socket_path);
3686 * Determines the address of the session bus by querying a
3687 * platform-specific method.
3689 * The first parameter will be a boolean specifying whether
3690 * or not a dynamic session lookup is supported on this platform.
3692 * If supported is TRUE and the return value is #TRUE, the
3693 * address will be appended to @p address.
3694 * If a failure happens, returns #FALSE and sets an error in
3697 * If supported is FALSE, ignore the return value.
3699 * @param supported returns whether this method is supported
3700 * @param address a DBusString where the address can be stored
3701 * @param error a DBusError to store the error in case of failure
3702 * @returns #TRUE on success, #FALSE if an error happened
3705 _dbus_lookup_session_address (dbus_bool_t *supported,
3706 DBusString *address,
3709 #ifdef DBUS_ENABLE_LAUNCHD
3711 return _dbus_lookup_session_address_launchd (address, error);
3713 /* On non-Mac Unix platforms, if the session address isn't already
3714 * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3715 * fall back to the autolaunch: global default; see
3716 * init_session_address in dbus/dbus-bus.c. */
3723 * Returns the standard directories for a session bus to look for service
3726 * On UNIX this should be the standard xdg freedesktop.org data directories:
3728 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3729 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3735 * @param dirs the directory list we are returning
3736 * @returns #FALSE on OOM
3740 _dbus_get_standard_session_servicedirs (DBusList **dirs)
3742 const char *xdg_data_home;
3743 const char *xdg_data_dirs;
3744 DBusString servicedir_path;
3746 if (!_dbus_string_init (&servicedir_path))
3749 xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3750 xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3752 if (xdg_data_home != NULL)
3754 if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3759 const DBusString *homedir;
3760 DBusString local_share;
3762 if (!_dbus_homedir_from_current_process (&homedir))
3765 if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3768 _dbus_string_init_const (&local_share, "/.local/share");
3769 if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3773 if (!_dbus_string_append (&servicedir_path, ":"))
3776 if (xdg_data_dirs != NULL)
3778 if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3781 if (!_dbus_string_append (&servicedir_path, ":"))
3786 if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3791 * add configured datadir to defaults
3792 * this may be the same as an xdg dir
3793 * however the config parser should take
3794 * care of duplicates
3796 if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
3799 if (!_dbus_split_paths_and_append (&servicedir_path,
3800 DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3804 _dbus_string_free (&servicedir_path);
3808 _dbus_string_free (&servicedir_path);
3814 * Returns the standard directories for a system bus to look for service
3817 * On UNIX this should be the standard xdg freedesktop.org data directories:
3819 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3825 * On Windows there is no system bus and this function can return nothing.
3827 * @param dirs the directory list we are returning
3828 * @returns #FALSE on OOM
3832 _dbus_get_standard_system_servicedirs (DBusList **dirs)
3835 * DBUS_DATADIR may be the same as one of the standard directories. However,
3836 * the config parser should take care of the duplicates.
3838 * Also, append /lib as counterpart of /usr/share on the root
3839 * directory (the root directory does not know /share), in order to
3840 * facilitate early boot system bus activation where /usr might not
3843 static const char standard_search_path[] =
3848 DBusString servicedir_path;
3850 _dbus_string_init_const (&servicedir_path, standard_search_path);
3852 return _dbus_split_paths_and_append (&servicedir_path,
3853 DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3858 * Append the absolute path of the system.conf file
3859 * (there is no system bus on Windows so this can just
3860 * return FALSE and print a warning or something)
3862 * @param str the string to append to
3863 * @returns #FALSE if no memory
3866 _dbus_append_system_config_file (DBusString *str)
3868 return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3872 * Append the absolute path of the session.conf file.
3874 * @param str the string to append to
3875 * @returns #FALSE if no memory
3878 _dbus_append_session_config_file (DBusString *str)
3880 return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3884 * Called when the bus daemon is signaled to reload its configuration; any
3885 * caches should be nuked. Of course any caches that need explicit reload
3886 * are probably broken, but c'est la vie.
3891 _dbus_flush_caches (void)
3893 _dbus_user_database_flush_system ();
3897 * Appends the directory in which a keyring for the given credentials
3898 * should be stored. The credentials should have either a Windows or
3899 * UNIX user in them. The directory should be an absolute path.
3901 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3902 * be something else, since the dotfile convention is not normal on Windows.
3904 * @param directory string to append directory to
3905 * @param credentials credentials the directory should be for
3907 * @returns #FALSE on no memory
3910 _dbus_append_keyring_directory_for_credentials (DBusString *directory,
3911 DBusCredentials *credentials)
3917 _dbus_assert (credentials != NULL);
3918 _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3920 if (!_dbus_string_init (&homedir))
3923 uid = _dbus_credentials_get_unix_uid (credentials);
3924 _dbus_assert (uid != DBUS_UID_UNSET);
3926 if (!_dbus_homedir_from_uid (uid, &homedir))
3929 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
3931 const char *override;
3933 override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3934 if (override != NULL && *override != '\0')
3936 _dbus_string_set_length (&homedir, 0);
3937 if (!_dbus_string_append (&homedir, override))
3940 _dbus_verbose ("Using fake homedir for testing: %s\n",
3941 _dbus_string_get_const_data (&homedir));
3945 static dbus_bool_t already_warned = FALSE;
3946 if (!already_warned)
3948 _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3949 already_warned = TRUE;
3955 _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3956 if (!_dbus_concat_dir_and_file (&homedir,
3960 if (!_dbus_string_copy (&homedir, 0,
3961 directory, _dbus_string_get_length (directory))) {
3965 _dbus_string_free (&homedir);
3969 _dbus_string_free (&homedir);
3973 //PENDING(kdab) docs
3975 _dbus_daemon_publish_session_bus_address (const char* addr,
3981 //PENDING(kdab) docs
3983 _dbus_daemon_unpublish_session_bus_address (void)
3989 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3990 * for Winsock so is abstracted)
3992 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3995 _dbus_get_is_errno_eagain_or_ewouldblock (void)
3997 return errno == EAGAIN || errno == EWOULDBLOCK;
4001 * Removes a directory; Directory must be empty
4003 * @param filename directory filename
4004 * @param error initialized error object
4005 * @returns #TRUE on success
4008 _dbus_delete_directory (const DBusString *filename,
4011 const char *filename_c;
4013 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
4015 filename_c = _dbus_string_get_const_data (filename);
4017 if (rmdir (filename_c) != 0)
4019 dbus_set_error (error, DBUS_ERROR_FAILED,
4020 "Failed to remove directory %s: %s\n",
4021 filename_c, _dbus_strerror (errno));
4029 * Checks whether file descriptors may be passed via the socket
4031 * @param fd the socket
4032 * @return TRUE when fd passing over this socket is supported
4036 _dbus_socket_can_pass_unix_fd(int fd) {
4041 struct sockaddr_storage storage;
4042 struct sockaddr_un un;
4045 socklen_t sa_len = sizeof(sa_buf);
4049 if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
4052 return sa_buf.sa.sa_family == AF_UNIX;
4062 * replaces the term DBUS_PREFIX in configure_time_path by the
4063 * current dbus installation directory. On unix this function is a noop
4065 * @param configure_time_path
4069 _dbus_replace_install_prefix (const char *configure_time_path)
4071 return configure_time_path;
4075 * Closes all file descriptors except the first three (i.e. stdin,
4079 _dbus_close_all (void)
4086 /* On Linux we can optimize this a bit if /proc is available. If it
4087 isn't available, fall back to the brute force way. */
4089 d = opendir ("/proc/self/fd");
4094 struct dirent buf, *de;
4099 k = readdir_r (d, &buf, &de);
4103 if (de->d_name[0] == '.')
4107 l = strtol (de->d_name, &e, 10);
4108 if (errno != 0 || e == NULL || *e != '\0')
4115 if (fd == dirfd (d))
4126 maxfds = sysconf (_SC_OPEN_MAX);
4128 /* Pick something reasonable if for some reason sysconf says
4134 /* close all inherited fds */
4135 for (i = 3; i < maxfds; i++)
4140 * **NOTE**: If you modify this function, please also consider making
4141 * the corresponding change in GLib. See
4142 * glib/gutils.c:g_check_setuid().
4144 * Returns TRUE if the current process was executed as setuid (or an
4145 * equivalent __libc_enable_secure is available). See:
4146 * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
4149 _dbus_check_setuid (void)
4151 /* TODO: get __libc_enable_secure exported from glibc.
4152 * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
4154 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
4156 /* See glibc/include/unistd.h */
4157 extern int __libc_enable_secure;
4158 return __libc_enable_secure;
4160 #elif defined(HAVE_ISSETUGID)
4161 /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
4162 return issetugid ();
4164 uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
4165 gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
4167 static dbus_bool_t check_setuid_initialised;
4168 static dbus_bool_t is_setuid;
4170 if (_DBUS_UNLIKELY (!check_setuid_initialised))
4172 #ifdef HAVE_GETRESUID
4173 if (getresuid (&ruid, &euid, &suid) != 0 ||
4174 getresgid (&rgid, &egid, &sgid) != 0)
4175 #endif /* HAVE_GETRESUID */
4177 suid = ruid = getuid ();
4178 sgid = rgid = getgid ();
4183 check_setuid_initialised = TRUE;
4184 is_setuid = (ruid != euid || ruid != suid ||
4185 rgid != egid || rgid != sgid);
4193 * Read the address from the socket and append it to the string
4195 * @param fd the socket
4197 * @param error return location for error code
4200 _dbus_append_address_from_socket (int fd,
4201 DBusString *address,
4206 struct sockaddr_storage storage;
4207 struct sockaddr_un un;
4208 struct sockaddr_in ipv4;
4209 struct sockaddr_in6 ipv6;
4211 char hostip[INET6_ADDRSTRLEN];
4212 int size = sizeof (socket);
4214 if (getsockname (fd, &socket.sa, &size))
4217 switch (socket.sa.sa_family)
4220 if (socket.un.sun_path[0]=='\0')
4222 if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1])))
4227 if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path))
4232 if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
4233 if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
4234 hostip, ntohs (socket.ipv4.sin_port)))
4239 if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
4240 if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u",
4241 hostip, ntohs (socket.ipv6.sin6_port)))
4246 dbus_set_error (error,
4247 _dbus_error_from_errno (EINVAL),
4248 "Failed to read address from socket: Unknown socket type.");
4252 dbus_set_error (error,
4253 _dbus_error_from_errno (errno),
4254 "Failed to open socket: %s",
4255 _dbus_strerror (errno));
4259 /* tests in dbus-sysdeps-util.c */