D-Bus  1.4.18
dbus-sysdeps-unix.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038 
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058 
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074 
00075 #ifdef HAVE_ADT
00076 #include <bsm/adt.h>
00077 #endif
00078 
00079 #include "sd-daemon.h"
00080 
00081 #ifndef O_BINARY
00082 #define O_BINARY 0
00083 #endif
00084 
00085 #ifndef AI_ADDRCONFIG
00086 #define AI_ADDRCONFIG 0
00087 #endif
00088 
00089 #ifndef HAVE_SOCKLEN_T
00090 #define socklen_t int
00091 #endif
00092 
00093 #if defined (__sun) || defined (__sun__)
00094 /*
00095  * CMS_SPACE etc. definitions for Solaris < 10, based on
00096  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
00097  * via
00098  *   http://wiki.opencsw.org/porting-faq#toc10
00099  *
00100  * These are only redefined for Solaris, for now: if your OS needs these too,
00101  * please file a bug. (Or preferably, improve your OS so they're not needed.)
00102  */
00103 
00104 # ifndef CMSG_ALIGN
00105 #   ifdef __sun__
00106 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00107 #   else
00108       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
00109 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00110                               ~(sizeof (long) - 1))
00111 #   endif
00112 # endif
00113 
00114 # ifndef CMSG_SPACE
00115 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00116                             CMSG_ALIGN (len))
00117 # endif
00118 
00119 # ifndef CMSG_LEN
00120 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00121 # endif
00122 
00123 #endif /* Solaris */
00124 
00125 static dbus_bool_t
00126 _dbus_open_socket (int              *fd_p,
00127                    int               domain,
00128                    int               type,
00129                    int               protocol,
00130                    DBusError        *error)
00131 {
00132 #ifdef SOCK_CLOEXEC
00133   dbus_bool_t cloexec_done;
00134 
00135   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00136   cloexec_done = *fd_p >= 0;
00137 
00138   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00139   if (*fd_p < 0 && errno == EINVAL)
00140 #endif
00141     {
00142       *fd_p = socket (domain, type, protocol);
00143     }
00144 
00145   if (*fd_p >= 0)
00146     {
00147 #ifdef SOCK_CLOEXEC
00148       if (!cloexec_done)
00149 #endif
00150         {
00151           _dbus_fd_set_close_on_exec(*fd_p);
00152         }
00153 
00154       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00155       return TRUE;
00156     }
00157   else
00158     {
00159       dbus_set_error(error,
00160                      _dbus_error_from_errno (errno),
00161                      "Failed to open socket: %s",
00162                      _dbus_strerror (errno));
00163       return FALSE;
00164     }
00165 }
00166 
00167 dbus_bool_t
00168 _dbus_open_tcp_socket (int              *fd,
00169                        DBusError        *error)
00170 {
00171   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00172 }
00173 
00184 dbus_bool_t
00185 _dbus_open_unix_socket (int              *fd,
00186                         DBusError        *error)
00187 {
00188   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00189 }
00190 
00199 dbus_bool_t
00200 _dbus_close_socket (int               fd,
00201                     DBusError        *error)
00202 {
00203   return _dbus_close (fd, error);
00204 }
00205 
00215 int
00216 _dbus_read_socket (int               fd,
00217                    DBusString       *buffer,
00218                    int               count)
00219 {
00220   return _dbus_read (fd, buffer, count);
00221 }
00222 
00233 int
00234 _dbus_write_socket (int               fd,
00235                     const DBusString *buffer,
00236                     int               start,
00237                     int               len)
00238 {
00239 #if HAVE_DECL_MSG_NOSIGNAL
00240   const char *data;
00241   int bytes_written;
00242 
00243   data = _dbus_string_get_const_data_len (buffer, start, len);
00244 
00245  again:
00246 
00247   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00248 
00249   if (bytes_written < 0 && errno == EINTR)
00250     goto again;
00251 
00252   return bytes_written;
00253 
00254 #else
00255   return _dbus_write (fd, buffer, start, len);
00256 #endif
00257 }
00258 
00271 int
00272 _dbus_read_socket_with_unix_fds (int               fd,
00273                                  DBusString       *buffer,
00274                                  int               count,
00275                                  int              *fds,
00276                                  int              *n_fds) {
00277 #ifndef HAVE_UNIX_FD_PASSING
00278   int r;
00279 
00280   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00281     return r;
00282 
00283   *n_fds = 0;
00284   return r;
00285 
00286 #else
00287   int bytes_read;
00288   int start;
00289   struct msghdr m;
00290   struct iovec iov;
00291 
00292   _dbus_assert (count >= 0);
00293   _dbus_assert (*n_fds >= 0);
00294 
00295   start = _dbus_string_get_length (buffer);
00296 
00297   if (!_dbus_string_lengthen (buffer, count))
00298     {
00299       errno = ENOMEM;
00300       return -1;
00301     }
00302 
00303   _DBUS_ZERO(iov);
00304   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00305   iov.iov_len = count;
00306 
00307   _DBUS_ZERO(m);
00308   m.msg_iov = &iov;
00309   m.msg_iovlen = 1;
00310 
00311   /* Hmm, we have no clue how long the control data will actually be
00312      that is queued for us. The least we can do is assume that the
00313      caller knows. Hence let's make space for the number of fds that
00314      we shall read at max plus the cmsg header. */
00315   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00316 
00317   /* It's probably safe to assume that systems with SCM_RIGHTS also
00318      know alloca() */
00319   m.msg_control = alloca(m.msg_controllen);
00320   memset(m.msg_control, 0, m.msg_controllen);
00321 
00322   /* Do not include the padding at the end when we tell the kernel
00323    * how much we're willing to receive. This avoids getting
00324    * the padding filled with additional fds that we weren't expecting,
00325    * if a (potentially malicious) sender included them. (fd.o #83622) */
00326   m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
00327 
00328  again:
00329 
00330   bytes_read = recvmsg(fd, &m, 0
00331 #ifdef MSG_CMSG_CLOEXEC
00332                        |MSG_CMSG_CLOEXEC
00333 #endif
00334                        );
00335 
00336   if (bytes_read < 0)
00337     {
00338       if (errno == EINTR)
00339         goto again;
00340       else
00341         {
00342           /* put length back (note that this doesn't actually realloc anything) */
00343           _dbus_string_set_length (buffer, start);
00344           return -1;
00345         }
00346     }
00347   else
00348     {
00349       struct cmsghdr *cm;
00350       dbus_bool_t found = FALSE;
00351 
00352       if (m.msg_flags & MSG_CTRUNC)
00353         {
00354           /* Hmm, apparently the control data was truncated. The bad
00355              thing is that we might have completely lost a couple of fds
00356              without chance to recover them. Hence let's treat this as a
00357              serious error. */
00358 
00359           errno = ENOSPC;
00360           _dbus_string_set_length (buffer, start);
00361           return -1;
00362         }
00363 
00364       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00365         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00366           {
00367             size_t i;
00368             int *payload = (int *) CMSG_DATA (cm);
00369             size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
00370             size_t payload_len_fds = payload_len_bytes / sizeof (int);
00371             size_t fds_to_use;
00372 
00373             /* Every non-negative int fits in a size_t without truncation,
00374              * and we already know that *n_fds is non-negative, so
00375              * casting (size_t) *n_fds is OK */
00376             _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
00377 
00378             if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
00379               {
00380                 /* The fds in the payload will fit in our buffer */
00381                 fds_to_use = payload_len_fds;
00382               }
00383             else
00384               {
00385                 /* Too many fds in the payload. This shouldn't happen
00386                  * any more because we're setting m.msg_controllen to
00387                  * the exact number we can accept, but be safe and
00388                  * truncate. */
00389                 fds_to_use = (size_t) *n_fds;
00390 
00391                 /* Close the excess fds to avoid DoS: if they stayed open,
00392                  * someone could send us an extra fd per message
00393                  * and we'd eventually run out. */
00394                 for (i = fds_to_use; i < payload_len_fds; i++)
00395                   {
00396                     close (payload[i]);
00397                   }
00398               }
00399 
00400             memcpy (fds, payload, fds_to_use * sizeof (int));
00401             found = TRUE;
00402             /* This cannot overflow because we have chosen fds_to_use
00403              * to be <= *n_fds */
00404             *n_fds = (int) fds_to_use;
00405 
00406             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00407                worked, hence we need to go through this list and set
00408                CLOEXEC everywhere in any case */
00409             for (i = 0; i < fds_to_use; i++)
00410               _dbus_fd_set_close_on_exec(fds[i]);
00411 
00412             break;
00413           }
00414 
00415       if (!found)
00416         *n_fds = 0;
00417 
00418       /* put length back (doesn't actually realloc) */
00419       _dbus_string_set_length (buffer, start + bytes_read);
00420 
00421 #if 0
00422       if (bytes_read > 0)
00423         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00424 #endif
00425 
00426       return bytes_read;
00427     }
00428 #endif
00429 }
00430 
00431 int
00432 _dbus_write_socket_with_unix_fds(int               fd,
00433                                  const DBusString *buffer,
00434                                  int               start,
00435                                  int               len,
00436                                  const int        *fds,
00437                                  int               n_fds) {
00438 
00439 #ifndef HAVE_UNIX_FD_PASSING
00440 
00441   if (n_fds > 0) {
00442     errno = ENOTSUP;
00443     return -1;
00444   }
00445 
00446   return _dbus_write_socket(fd, buffer, start, len);
00447 #else
00448   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00449 #endif
00450 }
00451 
00452 int
00453 _dbus_write_socket_with_unix_fds_two(int               fd,
00454                                      const DBusString *buffer1,
00455                                      int               start1,
00456                                      int               len1,
00457                                      const DBusString *buffer2,
00458                                      int               start2,
00459                                      int               len2,
00460                                      const int        *fds,
00461                                      int               n_fds) {
00462 
00463 #ifndef HAVE_UNIX_FD_PASSING
00464 
00465   if (n_fds > 0) {
00466     errno = ENOTSUP;
00467     return -1;
00468   }
00469 
00470   return _dbus_write_socket_two(fd,
00471                                 buffer1, start1, len1,
00472                                 buffer2, start2, len2);
00473 #else
00474 
00475   struct msghdr m;
00476   struct cmsghdr *cm;
00477   struct iovec iov[2];
00478   int bytes_written;
00479 
00480   _dbus_assert (len1 >= 0);
00481   _dbus_assert (len2 >= 0);
00482   _dbus_assert (n_fds >= 0);
00483 
00484   _DBUS_ZERO(iov);
00485   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00486   iov[0].iov_len = len1;
00487 
00488   if (buffer2)
00489     {
00490       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00491       iov[1].iov_len = len2;
00492     }
00493 
00494   _DBUS_ZERO(m);
00495   m.msg_iov = iov;
00496   m.msg_iovlen = buffer2 ? 2 : 1;
00497 
00498   if (n_fds > 0)
00499     {
00500       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00501       m.msg_control = alloca(m.msg_controllen);
00502       memset(m.msg_control, 0, m.msg_controllen);
00503 
00504       cm = CMSG_FIRSTHDR(&m);
00505       cm->cmsg_level = SOL_SOCKET;
00506       cm->cmsg_type = SCM_RIGHTS;
00507       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00508       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00509     }
00510 
00511  again:
00512 
00513   bytes_written = sendmsg (fd, &m, 0
00514 #if HAVE_DECL_MSG_NOSIGNAL
00515                            |MSG_NOSIGNAL
00516 #endif
00517                            );
00518 
00519   if (bytes_written < 0 && errno == EINTR)
00520     goto again;
00521 
00522 #if 0
00523   if (bytes_written > 0)
00524     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00525 #endif
00526 
00527   return bytes_written;
00528 #endif
00529 }
00530 
00544 int
00545 _dbus_write_socket_two (int               fd,
00546                         const DBusString *buffer1,
00547                         int               start1,
00548                         int               len1,
00549                         const DBusString *buffer2,
00550                         int               start2,
00551                         int               len2)
00552 {
00553 #if HAVE_DECL_MSG_NOSIGNAL
00554   struct iovec vectors[2];
00555   const char *data1;
00556   const char *data2;
00557   int bytes_written;
00558   struct msghdr m;
00559 
00560   _dbus_assert (buffer1 != NULL);
00561   _dbus_assert (start1 >= 0);
00562   _dbus_assert (start2 >= 0);
00563   _dbus_assert (len1 >= 0);
00564   _dbus_assert (len2 >= 0);
00565 
00566   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00567 
00568   if (buffer2 != NULL)
00569     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00570   else
00571     {
00572       data2 = NULL;
00573       start2 = 0;
00574       len2 = 0;
00575     }
00576 
00577   vectors[0].iov_base = (char*) data1;
00578   vectors[0].iov_len = len1;
00579   vectors[1].iov_base = (char*) data2;
00580   vectors[1].iov_len = len2;
00581 
00582   _DBUS_ZERO(m);
00583   m.msg_iov = vectors;
00584   m.msg_iovlen = data2 ? 2 : 1;
00585 
00586  again:
00587 
00588   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00589 
00590   if (bytes_written < 0 && errno == EINTR)
00591     goto again;
00592 
00593   return bytes_written;
00594 
00595 #else
00596   return _dbus_write_two (fd, buffer1, start1, len1,
00597                           buffer2, start2, len2);
00598 #endif
00599 }
00600 
00601 dbus_bool_t
00602 _dbus_socket_is_invalid (int fd)
00603 {
00604     return fd < 0 ? TRUE : FALSE;
00605 }
00606 
00623 int
00624 _dbus_read (int               fd,
00625             DBusString       *buffer,
00626             int               count)
00627 {
00628   int bytes_read;
00629   int start;
00630   char *data;
00631 
00632   _dbus_assert (count >= 0);
00633 
00634   start = _dbus_string_get_length (buffer);
00635 
00636   if (!_dbus_string_lengthen (buffer, count))
00637     {
00638       errno = ENOMEM;
00639       return -1;
00640     }
00641 
00642   data = _dbus_string_get_data_len (buffer, start, count);
00643 
00644  again:
00645 
00646   bytes_read = read (fd, data, count);
00647 
00648   if (bytes_read < 0)
00649     {
00650       if (errno == EINTR)
00651         goto again;
00652       else
00653         {
00654           /* put length back (note that this doesn't actually realloc anything) */
00655           _dbus_string_set_length (buffer, start);
00656           return -1;
00657         }
00658     }
00659   else
00660     {
00661       /* put length back (doesn't actually realloc) */
00662       _dbus_string_set_length (buffer, start + bytes_read);
00663 
00664 #if 0
00665       if (bytes_read > 0)
00666         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00667 #endif
00668 
00669       return bytes_read;
00670     }
00671 }
00672 
00683 int
00684 _dbus_write (int               fd,
00685              const DBusString *buffer,
00686              int               start,
00687              int               len)
00688 {
00689   const char *data;
00690   int bytes_written;
00691 
00692   data = _dbus_string_get_const_data_len (buffer, start, len);
00693 
00694  again:
00695 
00696   bytes_written = write (fd, data, len);
00697 
00698   if (bytes_written < 0 && errno == EINTR)
00699     goto again;
00700 
00701 #if 0
00702   if (bytes_written > 0)
00703     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00704 #endif
00705 
00706   return bytes_written;
00707 }
00708 
00729 int
00730 _dbus_write_two (int               fd,
00731                  const DBusString *buffer1,
00732                  int               start1,
00733                  int               len1,
00734                  const DBusString *buffer2,
00735                  int               start2,
00736                  int               len2)
00737 {
00738   _dbus_assert (buffer1 != NULL);
00739   _dbus_assert (start1 >= 0);
00740   _dbus_assert (start2 >= 0);
00741   _dbus_assert (len1 >= 0);
00742   _dbus_assert (len2 >= 0);
00743 
00744 #ifdef HAVE_WRITEV
00745   {
00746     struct iovec vectors[2];
00747     const char *data1;
00748     const char *data2;
00749     int bytes_written;
00750 
00751     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00752 
00753     if (buffer2 != NULL)
00754       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00755     else
00756       {
00757         data2 = NULL;
00758         start2 = 0;
00759         len2 = 0;
00760       }
00761 
00762     vectors[0].iov_base = (char*) data1;
00763     vectors[0].iov_len = len1;
00764     vectors[1].iov_base = (char*) data2;
00765     vectors[1].iov_len = len2;
00766 
00767   again:
00768 
00769     bytes_written = writev (fd,
00770                             vectors,
00771                             data2 ? 2 : 1);
00772 
00773     if (bytes_written < 0 && errno == EINTR)
00774       goto again;
00775 
00776     return bytes_written;
00777   }
00778 #else /* HAVE_WRITEV */
00779   {
00780     int ret1;
00781 
00782     ret1 = _dbus_write (fd, buffer1, start1, len1);
00783     if (ret1 == len1 && buffer2 != NULL)
00784       {
00785         ret2 = _dbus_write (fd, buffer2, start2, len2);
00786         if (ret2 < 0)
00787           ret2 = 0; /* we can't report an error as the first write was OK */
00788 
00789         return ret1 + ret2;
00790       }
00791     else
00792       return ret1;
00793   }
00794 #endif /* !HAVE_WRITEV */
00795 }
00796 
00797 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00798 
00828 int
00829 _dbus_connect_unix_socket (const char     *path,
00830                            dbus_bool_t     abstract,
00831                            DBusError      *error)
00832 {
00833   int fd;
00834   size_t path_len;
00835   struct sockaddr_un addr;
00836 
00837   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00838 
00839   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00840                  path, abstract);
00841 
00842 
00843   if (!_dbus_open_unix_socket (&fd, error))
00844     {
00845       _DBUS_ASSERT_ERROR_IS_SET(error);
00846       return -1;
00847     }
00848   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00849 
00850   _DBUS_ZERO (addr);
00851   addr.sun_family = AF_UNIX;
00852   path_len = strlen (path);
00853 
00854   if (abstract)
00855     {
00856 #ifdef HAVE_ABSTRACT_SOCKETS
00857       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00858       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00859 
00860       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00861         {
00862           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00863                       "Abstract socket name too long\n");
00864           _dbus_close (fd, NULL);
00865           return -1;
00866         }
00867 
00868       strncpy (&addr.sun_path[1], path, path_len);
00869       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00870 #else /* HAVE_ABSTRACT_SOCKETS */
00871       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00872                       "Operating system does not support abstract socket namespace\n");
00873       _dbus_close (fd, NULL);
00874       return -1;
00875 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00876     }
00877   else
00878     {
00879       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00880         {
00881           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00882                       "Socket name too long\n");
00883           _dbus_close (fd, NULL);
00884           return -1;
00885         }
00886 
00887       strncpy (addr.sun_path, path, path_len);
00888     }
00889 
00890   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00891     {
00892       dbus_set_error (error,
00893                       _dbus_error_from_errno (errno),
00894                       "Failed to connect to socket %s: %s",
00895                       path, _dbus_strerror (errno));
00896 
00897       _dbus_close (fd, NULL);
00898       return -1;
00899     }
00900 
00901   if (!_dbus_set_fd_nonblocking (fd, error))
00902     {
00903       _DBUS_ASSERT_ERROR_IS_SET (error);
00904 
00905       _dbus_close (fd, NULL);
00906       return -1;
00907     }
00908 
00909   return fd;
00910 }
00911 
00921 static dbus_bool_t
00922 _dbus_set_local_creds (int fd, dbus_bool_t on)
00923 {
00924   dbus_bool_t retval = TRUE;
00925 
00926 #if defined(HAVE_CMSGCRED)
00927   /* NOOP just to make sure only one codepath is used
00928    *      and to prefer CMSGCRED
00929    */
00930 #elif defined(LOCAL_CREDS)
00931   int val = on ? 1 : 0;
00932   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00933     {
00934       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00935       retval = FALSE;
00936     }
00937   else
00938     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00939                    on ? "enabled" : "disabled", fd);
00940 #endif
00941 
00942   return retval;
00943 }
00944 
00962 int
00963 _dbus_listen_unix_socket (const char     *path,
00964                           dbus_bool_t     abstract,
00965                           DBusError      *error)
00966 {
00967   int listen_fd;
00968   struct sockaddr_un addr;
00969   size_t path_len;
00970   unsigned int reuseaddr;
00971 
00972   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00973 
00974   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00975                  path, abstract);
00976 
00977   if (!_dbus_open_unix_socket (&listen_fd, error))
00978     {
00979       _DBUS_ASSERT_ERROR_IS_SET(error);
00980       return -1;
00981     }
00982   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00983 
00984   _DBUS_ZERO (addr);
00985   addr.sun_family = AF_UNIX;
00986   path_len = strlen (path);
00987 
00988   if (abstract)
00989     {
00990 #ifdef HAVE_ABSTRACT_SOCKETS
00991       /* remember that abstract names aren't nul-terminated so we rely
00992        * on sun_path being filled in with zeroes above.
00993        */
00994       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00995       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00996 
00997       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00998         {
00999           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01000                       "Abstract socket name too long\n");
01001           _dbus_close (listen_fd, NULL);
01002           return -1;
01003         }
01004 
01005       strncpy (&addr.sun_path[1], path, path_len);
01006       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
01007 #else /* HAVE_ABSTRACT_SOCKETS */
01008       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01009                       "Operating system does not support abstract socket namespace\n");
01010       _dbus_close (listen_fd, NULL);
01011       return -1;
01012 #endif /* ! HAVE_ABSTRACT_SOCKETS */
01013     }
01014   else
01015     {
01016       /* Discussed security implications of this with Nalin,
01017        * and we couldn't think of where it would kick our ass, but
01018        * it still seems a bit sucky. It also has non-security suckage;
01019        * really we'd prefer to exit if the socket is already in use.
01020        * But there doesn't seem to be a good way to do this.
01021        *
01022        * Just to be extra careful, I threw in the stat() - clearly
01023        * the stat() can't *fix* any security issue, but it at least
01024        * avoids inadvertent/accidental data loss.
01025        */
01026       {
01027         struct stat sb;
01028 
01029         if (stat (path, &sb) == 0 &&
01030             S_ISSOCK (sb.st_mode))
01031           unlink (path);
01032       }
01033 
01034       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01035         {
01036           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01037                       "Abstract socket name too long\n");
01038           _dbus_close (listen_fd, NULL);
01039           return -1;
01040         }
01041 
01042       strncpy (addr.sun_path, path, path_len);
01043     }
01044 
01045   reuseaddr = 1;
01046   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01047     {
01048       _dbus_warn ("Failed to set socket option\"%s\": %s",
01049                   path, _dbus_strerror (errno));
01050     }
01051 
01052   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01053     {
01054       dbus_set_error (error, _dbus_error_from_errno (errno),
01055                       "Failed to bind socket \"%s\": %s",
01056                       path, _dbus_strerror (errno));
01057       _dbus_close (listen_fd, NULL);
01058       return -1;
01059     }
01060 
01061   if (listen (listen_fd, 30 /* backlog */) < 0)
01062     {
01063       dbus_set_error (error, _dbus_error_from_errno (errno),
01064                       "Failed to listen on socket \"%s\": %s",
01065                       path, _dbus_strerror (errno));
01066       _dbus_close (listen_fd, NULL);
01067       return -1;
01068     }
01069 
01070   if (!_dbus_set_local_creds (listen_fd, TRUE))
01071     {
01072       dbus_set_error (error, _dbus_error_from_errno (errno),
01073                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01074                       path, _dbus_strerror (errno));
01075       close (listen_fd);
01076       return -1;
01077     }
01078 
01079   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01080     {
01081       _DBUS_ASSERT_ERROR_IS_SET (error);
01082       _dbus_close (listen_fd, NULL);
01083       return -1;
01084     }
01085 
01086   /* Try opening up the permissions, but if we can't, just go ahead
01087    * and continue, maybe it will be good enough.
01088    */
01089   if (!abstract && chmod (path, 0777) < 0)
01090     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01091                 path);
01092 
01093   return listen_fd;
01094 }
01095 
01106 int
01107 _dbus_listen_systemd_sockets (int       **fds,
01108                               DBusError *error)
01109 {
01110   int r, n;
01111   unsigned fd;
01112   int *new_fds;
01113 
01114   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01115 
01116   n = sd_listen_fds (TRUE);
01117   if (n < 0)
01118     {
01119       dbus_set_error (error, _dbus_error_from_errno (-n),
01120                       "Failed to acquire systemd socket: %s",
01121                       _dbus_strerror (-n));
01122       return -1;
01123     }
01124 
01125   if (n <= 0)
01126     {
01127       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01128                       "No socket received.");
01129       return -1;
01130     }
01131 
01132   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01133     {
01134       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01135       if (r < 0)
01136         {
01137           dbus_set_error (error, _dbus_error_from_errno (-r),
01138                           "Failed to verify systemd socket type: %s",
01139                           _dbus_strerror (-r));
01140           return -1;
01141         }
01142 
01143       if (!r)
01144         {
01145           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01146                           "Passed socket has wrong type.");
01147           return -1;
01148         }
01149     }
01150 
01151   /* OK, the file descriptors are all good, so let's take posession of
01152      them then. */
01153 
01154   new_fds = dbus_new (int, n);
01155   if (!new_fds)
01156     {
01157       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01158                       "Failed to allocate file handle array.");
01159       goto fail;
01160     }
01161 
01162   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01163     {
01164       if (!_dbus_set_local_creds (fd, TRUE))
01165         {
01166           dbus_set_error (error, _dbus_error_from_errno (errno),
01167                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01168                           _dbus_strerror (errno));
01169           goto fail;
01170         }
01171 
01172       if (!_dbus_set_fd_nonblocking (fd, error))
01173         {
01174           _DBUS_ASSERT_ERROR_IS_SET (error);
01175           goto fail;
01176         }
01177 
01178       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01179     }
01180 
01181   *fds = new_fds;
01182   return n;
01183 
01184  fail:
01185 
01186   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01187     {
01188       _dbus_close (fd, NULL);
01189     }
01190 
01191   dbus_free (new_fds);
01192   return -1;
01193 }
01194 
01208 int
01209 _dbus_connect_tcp_socket (const char     *host,
01210                           const char     *port,
01211                           const char     *family,
01212                           DBusError      *error)
01213 {
01214     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01215 }
01216 
01217 int
01218 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01219                                      const char     *port,
01220                                      const char     *family,
01221                                      const char     *noncefile,
01222                                      DBusError      *error)
01223 {
01224   int saved_errno = 0;
01225   int fd = -1, res;
01226   struct addrinfo hints;
01227   struct addrinfo *ai, *tmp;
01228 
01229   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01230 
01231   _DBUS_ZERO (hints);
01232 
01233   if (!family)
01234     hints.ai_family = AF_UNSPEC;
01235   else if (!strcmp(family, "ipv4"))
01236     hints.ai_family = AF_INET;
01237   else if (!strcmp(family, "ipv6"))
01238     hints.ai_family = AF_INET6;
01239   else
01240     {
01241       dbus_set_error (error,
01242                       DBUS_ERROR_BAD_ADDRESS,
01243                       "Unknown address family %s", family);
01244       return -1;
01245     }
01246   hints.ai_protocol = IPPROTO_TCP;
01247   hints.ai_socktype = SOCK_STREAM;
01248   hints.ai_flags = AI_ADDRCONFIG;
01249 
01250   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01251     {
01252       dbus_set_error (error,
01253                       _dbus_error_from_errno (errno),
01254                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01255                       host, port, gai_strerror(res), res);
01256       return -1;
01257     }
01258 
01259   tmp = ai;
01260   while (tmp)
01261     {
01262       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01263         {
01264           freeaddrinfo(ai);
01265           _DBUS_ASSERT_ERROR_IS_SET(error);
01266           return -1;
01267         }
01268       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01269 
01270       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01271         {
01272           saved_errno = errno;
01273           _dbus_close(fd, NULL);
01274           fd = -1;
01275           tmp = tmp->ai_next;
01276           continue;
01277         }
01278 
01279       break;
01280     }
01281   freeaddrinfo(ai);
01282 
01283   if (fd == -1)
01284     {
01285       dbus_set_error (error,
01286                       _dbus_error_from_errno (saved_errno),
01287                       "Failed to connect to socket \"%s:%s\" %s",
01288                       host, port, _dbus_strerror(saved_errno));
01289       return -1;
01290     }
01291 
01292   if (noncefile != NULL)
01293     {
01294       DBusString noncefileStr;
01295       dbus_bool_t ret;
01296       _dbus_string_init_const (&noncefileStr, noncefile);
01297       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01298       _dbus_string_free (&noncefileStr);
01299 
01300       if (!ret)
01301     {
01302       _dbus_close (fd, NULL);
01303           return -1;
01304         }
01305     }
01306 
01307   if (!_dbus_set_fd_nonblocking (fd, error))
01308     {
01309       _dbus_close (fd, NULL);
01310       return -1;
01311     }
01312 
01313   return fd;
01314 }
01315 
01332 int
01333 _dbus_listen_tcp_socket (const char     *host,
01334                          const char     *port,
01335                          const char     *family,
01336                          DBusString     *retport,
01337                          int           **fds_p,
01338                          DBusError      *error)
01339 {
01340   int saved_errno;
01341   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01342   struct addrinfo hints;
01343   struct addrinfo *ai, *tmp;
01344   unsigned int reuseaddr;
01345 
01346   *fds_p = NULL;
01347   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01348 
01349   _DBUS_ZERO (hints);
01350 
01351   if (!family)
01352     hints.ai_family = AF_UNSPEC;
01353   else if (!strcmp(family, "ipv4"))
01354     hints.ai_family = AF_INET;
01355   else if (!strcmp(family, "ipv6"))
01356     hints.ai_family = AF_INET6;
01357   else
01358     {
01359       dbus_set_error (error,
01360                       DBUS_ERROR_BAD_ADDRESS,
01361                       "Unknown address family %s", family);
01362       return -1;
01363     }
01364 
01365   hints.ai_protocol = IPPROTO_TCP;
01366   hints.ai_socktype = SOCK_STREAM;
01367   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01368 
01369  redo_lookup_with_port:
01370   ai = NULL;
01371   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01372     {
01373       dbus_set_error (error,
01374                       _dbus_error_from_errno (errno),
01375                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01376                       host ? host : "*", port, gai_strerror(res), res);
01377       goto failed;
01378     }
01379 
01380   tmp = ai;
01381   while (tmp)
01382     {
01383       int fd = -1, *newlisten_fd;
01384       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01385         {
01386           _DBUS_ASSERT_ERROR_IS_SET(error);
01387           goto failed;
01388         }
01389       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01390 
01391       reuseaddr = 1;
01392       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01393         {
01394           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01395                       host ? host : "*", port, _dbus_strerror (errno));
01396         }
01397 
01398       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01399         {
01400           saved_errno = errno;
01401           _dbus_close(fd, NULL);
01402           if (saved_errno == EADDRINUSE)
01403             {
01404               /* Depending on kernel policy, it may or may not
01405                  be neccessary to bind to both IPv4 & 6 addresses
01406                  so ignore EADDRINUSE here */
01407               tmp = tmp->ai_next;
01408               continue;
01409             }
01410           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01411                           "Failed to bind socket \"%s:%s\": %s",
01412                           host ? host : "*", port, _dbus_strerror (saved_errno));
01413           goto failed;
01414         }
01415 
01416       if (listen (fd, 30 /* backlog */) < 0)
01417         {
01418           saved_errno = errno;
01419           _dbus_close (fd, NULL);
01420           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01421                           "Failed to listen on socket \"%s:%s\": %s",
01422                           host ? host : "*", port, _dbus_strerror (saved_errno));
01423           goto failed;
01424         }
01425 
01426       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01427       if (!newlisten_fd)
01428         {
01429           saved_errno = errno;
01430           _dbus_close (fd, NULL);
01431           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01432                           "Failed to allocate file handle array: %s",
01433                           _dbus_strerror (saved_errno));
01434           goto failed;
01435         }
01436       listen_fd = newlisten_fd;
01437       listen_fd[nlisten_fd] = fd;
01438       nlisten_fd++;
01439 
01440       if (!_dbus_string_get_length(retport))
01441         {
01442           /* If the user didn't specify a port, or used 0, then
01443              the kernel chooses a port. After the first address
01444              is bound to, we need to force all remaining addresses
01445              to use the same port */
01446           if (!port || !strcmp(port, "0"))
01447             {
01448               int result;
01449               struct sockaddr_storage addr;
01450               socklen_t addrlen;
01451               char portbuf[50];
01452 
01453               addrlen = sizeof(addr);
01454               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01455 
01456               if (result == -1 ||
01457                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01458                                       portbuf, sizeof(portbuf),
01459                                       NI_NUMERICHOST)) != 0)
01460                 {
01461                   dbus_set_error (error, _dbus_error_from_errno (errno),
01462                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01463                                   host ? host : "*", port, gai_strerror(res), res);
01464                   goto failed;
01465                 }
01466               if (!_dbus_string_append(retport, portbuf))
01467                 {
01468                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01469                   goto failed;
01470                 }
01471 
01472               /* Release current address list & redo lookup */
01473               port = _dbus_string_get_const_data(retport);
01474               freeaddrinfo(ai);
01475               goto redo_lookup_with_port;
01476             }
01477           else
01478             {
01479               if (!_dbus_string_append(retport, port))
01480                 {
01481                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01482                     goto failed;
01483                 }
01484             }
01485         }
01486 
01487       tmp = tmp->ai_next;
01488     }
01489   freeaddrinfo(ai);
01490   ai = NULL;
01491 
01492   if (!nlisten_fd)
01493     {
01494       errno = EADDRINUSE;
01495       dbus_set_error (error, _dbus_error_from_errno (errno),
01496                       "Failed to bind socket \"%s:%s\": %s",
01497                       host ? host : "*", port, _dbus_strerror (errno));
01498       goto failed;
01499     }
01500 
01501   for (i = 0 ; i < nlisten_fd ; i++)
01502     {
01503       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01504         {
01505           goto failed;
01506         }
01507     }
01508 
01509   *fds_p = listen_fd;
01510 
01511   return nlisten_fd;
01512 
01513  failed:
01514   if (ai)
01515     freeaddrinfo(ai);
01516   for (i = 0 ; i < nlisten_fd ; i++)
01517     _dbus_close(listen_fd[i], NULL);
01518   dbus_free(listen_fd);
01519   return -1;
01520 }
01521 
01522 static dbus_bool_t
01523 write_credentials_byte (int             server_fd,
01524                         DBusError      *error)
01525 {
01526   int bytes_written;
01527   char buf[1] = { '\0' };
01528 #if defined(HAVE_CMSGCRED)
01529   union {
01530           struct cmsghdr hdr;
01531           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01532   } cmsg;
01533   struct iovec iov;
01534   struct msghdr msg;
01535   iov.iov_base = buf;
01536   iov.iov_len = 1;
01537 
01538   _DBUS_ZERO(msg);
01539   msg.msg_iov = &iov;
01540   msg.msg_iovlen = 1;
01541 
01542   msg.msg_control = (caddr_t) &cmsg;
01543   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01544   _DBUS_ZERO(cmsg);
01545   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01546   cmsg.hdr.cmsg_level = SOL_SOCKET;
01547   cmsg.hdr.cmsg_type = SCM_CREDS;
01548 #endif
01549 
01550   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01551 
01552  again:
01553 
01554 #if defined(HAVE_CMSGCRED)
01555   bytes_written = sendmsg (server_fd, &msg, 0
01556 #if HAVE_DECL_MSG_NOSIGNAL
01557                            |MSG_NOSIGNAL
01558 #endif
01559                            );
01560 #else
01561   bytes_written = send (server_fd, buf, 1, 0
01562 #if HAVE_DECL_MSG_NOSIGNAL
01563                         |MSG_NOSIGNAL
01564 #endif
01565                         );
01566 #endif
01567 
01568   if (bytes_written < 0 && errno == EINTR)
01569     goto again;
01570 
01571   if (bytes_written < 0)
01572     {
01573       dbus_set_error (error, _dbus_error_from_errno (errno),
01574                       "Failed to write credentials byte: %s",
01575                      _dbus_strerror (errno));
01576       return FALSE;
01577     }
01578   else if (bytes_written == 0)
01579     {
01580       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01581                       "wrote zero bytes writing credentials byte");
01582       return FALSE;
01583     }
01584   else
01585     {
01586       _dbus_assert (bytes_written == 1);
01587       _dbus_verbose ("wrote credentials byte\n");
01588       return TRUE;
01589     }
01590 }
01591 
01613 dbus_bool_t
01614 _dbus_read_credentials_socket  (int              client_fd,
01615                                 DBusCredentials *credentials,
01616                                 DBusError       *error)
01617 {
01618   struct msghdr msg;
01619   struct iovec iov;
01620   char buf;
01621   dbus_uid_t uid_read;
01622   dbus_pid_t pid_read;
01623   int bytes_read;
01624 
01625 #ifdef HAVE_CMSGCRED
01626   union {
01627     struct cmsghdr hdr;
01628     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01629   } cmsg;
01630 
01631 #elif defined(LOCAL_CREDS)
01632   struct {
01633     struct cmsghdr hdr;
01634     struct sockcred cred;
01635   } cmsg;
01636 #endif
01637 
01638   uid_read = DBUS_UID_UNSET;
01639   pid_read = DBUS_PID_UNSET;
01640 
01641   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01642 
01643   /* The POSIX spec certainly doesn't promise this, but
01644    * we need these assertions to fail as soon as we're wrong about
01645    * it so we can do the porting fixups
01646    */
01647   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01648   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01649   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01650 
01651   _dbus_credentials_clear (credentials);
01652 
01653   /* Systems supporting LOCAL_CREDS are configured to have this feature
01654    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01655    * the connection.  Therefore, the received message must carry the
01656    * credentials information without doing anything special.
01657    */
01658 
01659   iov.iov_base = &buf;
01660   iov.iov_len = 1;
01661 
01662   _DBUS_ZERO(msg);
01663   msg.msg_iov = &iov;
01664   msg.msg_iovlen = 1;
01665 
01666 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01667   _DBUS_ZERO(cmsg);
01668   msg.msg_control = (caddr_t) &cmsg;
01669   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01670 #endif
01671 
01672  again:
01673   bytes_read = recvmsg (client_fd, &msg, 0);
01674 
01675   if (bytes_read < 0)
01676     {
01677       if (errno == EINTR)
01678         goto again;
01679 
01680       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01681        * normally only call read_credentials if the socket was ready
01682        * for reading
01683        */
01684 
01685       dbus_set_error (error, _dbus_error_from_errno (errno),
01686                       "Failed to read credentials byte: %s",
01687                       _dbus_strerror (errno));
01688       return FALSE;
01689     }
01690   else if (bytes_read == 0)
01691     {
01692       /* this should not happen unless we are using recvmsg wrong,
01693        * so is essentially here for paranoia
01694        */
01695       dbus_set_error (error, DBUS_ERROR_FAILED,
01696                       "Failed to read credentials byte (zero-length read)");
01697       return FALSE;
01698     }
01699   else if (buf != '\0')
01700     {
01701       dbus_set_error (error, DBUS_ERROR_FAILED,
01702                       "Credentials byte was not nul");
01703       return FALSE;
01704     }
01705 
01706 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01707   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01708                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01709     {
01710       dbus_set_error (error, DBUS_ERROR_FAILED,
01711                       "Message from recvmsg() was not SCM_CREDS");
01712       return FALSE;
01713     }
01714 #endif
01715 
01716   _dbus_verbose ("read credentials byte\n");
01717 
01718   {
01719 #ifdef SO_PEERCRED
01720 #ifdef __OpenBSD__
01721     struct sockpeercred cr;
01722 #else
01723     struct ucred cr;
01724 #endif
01725     int cr_len = sizeof (cr);
01726 
01727     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01728         cr_len == sizeof (cr))
01729       {
01730         pid_read = cr.pid;
01731         uid_read = cr.uid;
01732       }
01733     else
01734       {
01735         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01736                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01737       }
01738 #elif defined(HAVE_CMSGCRED)
01739     struct cmsgcred *cred;
01740 
01741     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01742     pid_read = cred->cmcred_pid;
01743     uid_read = cred->cmcred_euid;
01744 #elif defined(LOCAL_CREDS)
01745     pid_read = DBUS_PID_UNSET;
01746     uid_read = cmsg.cred.sc_uid;
01747     /* Since we have already got the credentials from this socket, we can
01748      * disable its LOCAL_CREDS flag if it was ever set. */
01749     _dbus_set_local_creds (client_fd, FALSE);
01750 #elif defined(HAVE_GETPEEREID)
01751     uid_t euid;
01752     gid_t egid;
01753     if (getpeereid (client_fd, &euid, &egid) == 0)
01754       {
01755         uid_read = euid;
01756       }
01757     else
01758       {
01759         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01760       }
01761 #elif defined(HAVE_GETPEERUCRED)
01762     ucred_t * ucred = NULL;
01763     if (getpeerucred (client_fd, &ucred) == 0)
01764       {
01765         pid_read = ucred_getpid (ucred);
01766         uid_read = ucred_geteuid (ucred);
01767 #ifdef HAVE_ADT
01768         /* generate audit session data based on socket ucred */
01769         adt_session_data_t *adth = NULL;
01770         adt_export_data_t *data = NULL;
01771         size_t size = 0;
01772         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01773           {
01774             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01775           }
01776         else
01777           {
01778             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01779               {
01780                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01781               }
01782             else
01783               {
01784                 size = adt_export_session_data (adth, &data);
01785                 if (size <= 0)
01786                   {
01787                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01788                   }
01789                 else
01790                   {
01791                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01792                     free (data);
01793                   }
01794               }
01795             (void) adt_end_session (adth);
01796           }
01797 #endif /* HAVE_ADT */
01798       }
01799     else
01800       {
01801         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01802       }
01803     if (ucred != NULL)
01804       ucred_free (ucred);
01805 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01806     _dbus_verbose ("Socket credentials not supported on this OS\n");
01807 #endif
01808   }
01809 
01810   _dbus_verbose ("Credentials:"
01811                  "  pid "DBUS_PID_FORMAT
01812                  "  uid "DBUS_UID_FORMAT
01813                  "\n",
01814                  pid_read,
01815                  uid_read);
01816 
01817   if (pid_read != DBUS_PID_UNSET)
01818     {
01819       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01820         {
01821           _DBUS_SET_OOM (error);
01822           return FALSE;
01823         }
01824     }
01825 
01826   if (uid_read != DBUS_UID_UNSET)
01827     {
01828       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01829         {
01830           _DBUS_SET_OOM (error);
01831           return FALSE;
01832         }
01833     }
01834 
01835   return TRUE;
01836 }
01837 
01855 dbus_bool_t
01856 _dbus_send_credentials_socket  (int              server_fd,
01857                                 DBusError       *error)
01858 {
01859   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01860 
01861   if (write_credentials_byte (server_fd, error))
01862     return TRUE;
01863   else
01864     return FALSE;
01865 }
01866 
01876 int
01877 _dbus_accept  (int listen_fd)
01878 {
01879   int client_fd;
01880   struct sockaddr addr;
01881   socklen_t addrlen;
01882 #ifdef HAVE_ACCEPT4
01883   dbus_bool_t cloexec_done;
01884 #endif
01885 
01886   addrlen = sizeof (addr);
01887 
01888  retry:
01889 
01890 #ifdef HAVE_ACCEPT4
01891   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01892   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01893   cloexec_done = client_fd >= 0;
01894 
01895   if (client_fd < 0 && errno == ENOSYS)
01896 #endif
01897     {
01898       client_fd = accept (listen_fd, &addr, &addrlen);
01899     }
01900 
01901   if (client_fd < 0)
01902     {
01903       if (errno == EINTR)
01904         goto retry;
01905     }
01906 
01907   _dbus_verbose ("client fd %d accepted\n", client_fd);
01908 
01909 #ifdef HAVE_ACCEPT4
01910   if (!cloexec_done)
01911 #endif
01912     {
01913       _dbus_fd_set_close_on_exec(client_fd);
01914     }
01915 
01916   return client_fd;
01917 }
01918 
01927 dbus_bool_t
01928 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01929 {
01930   const char *directory;
01931   struct stat sb;
01932 
01933   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01934 
01935   directory = _dbus_string_get_const_data (dir);
01936 
01937   if (stat (directory, &sb) < 0)
01938     {
01939       dbus_set_error (error, _dbus_error_from_errno (errno),
01940                       "%s", _dbus_strerror (errno));
01941 
01942       return FALSE;
01943     }
01944 
01945   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01946       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01947     {
01948       dbus_set_error (error, DBUS_ERROR_FAILED,
01949                      "%s directory is not private to the user", directory);
01950       return FALSE;
01951     }
01952 
01953   return TRUE;
01954 }
01955 
01956 static dbus_bool_t
01957 fill_user_info_from_passwd (struct passwd *p,
01958                             DBusUserInfo  *info,
01959                             DBusError     *error)
01960 {
01961   _dbus_assert (p->pw_name != NULL);
01962   _dbus_assert (p->pw_dir != NULL);
01963 
01964   info->uid = p->pw_uid;
01965   info->primary_gid = p->pw_gid;
01966   info->username = _dbus_strdup (p->pw_name);
01967   info->homedir = _dbus_strdup (p->pw_dir);
01968 
01969   if (info->username == NULL ||
01970       info->homedir == NULL)
01971     {
01972       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01973       return FALSE;
01974     }
01975 
01976   return TRUE;
01977 }
01978 
01979 static dbus_bool_t
01980 fill_user_info (DBusUserInfo       *info,
01981                 dbus_uid_t          uid,
01982                 const DBusString   *username,
01983                 DBusError          *error)
01984 {
01985   const char *username_c;
01986 
01987   /* exactly one of username/uid provided */
01988   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01989   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01990 
01991   info->uid = DBUS_UID_UNSET;
01992   info->primary_gid = DBUS_GID_UNSET;
01993   info->group_ids = NULL;
01994   info->n_group_ids = 0;
01995   info->username = NULL;
01996   info->homedir = NULL;
01997 
01998   if (username != NULL)
01999     username_c = _dbus_string_get_const_data (username);
02000   else
02001     username_c = NULL;
02002 
02003   /* For now assuming that the getpwnam() and getpwuid() flavors
02004    * are always symmetrical, if not we have to add more configure
02005    * checks
02006    */
02007 
02008 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02009   {
02010     struct passwd *p;
02011     int result;
02012     size_t buflen;
02013     char *buf;
02014     struct passwd p_str;
02015 
02016     /* retrieve maximum needed size for buf */
02017     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02018 
02019     /* sysconf actually returns a long, but everything else expects size_t,
02020      * so just recast here.
02021      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
02022      */
02023     if ((long) buflen <= 0)
02024       buflen = 1024;
02025 
02026     result = -1;
02027     while (1)
02028       {
02029         buf = dbus_malloc (buflen);
02030         if (buf == NULL)
02031           {
02032             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02033             return FALSE;
02034           }
02035 
02036         p = NULL;
02037 #ifdef HAVE_POSIX_GETPWNAM_R
02038         if (uid != DBUS_UID_UNSET)
02039           result = getpwuid_r (uid, &p_str, buf, buflen,
02040                                &p);
02041         else
02042           result = getpwnam_r (username_c, &p_str, buf, buflen,
02043                                &p);
02044 #else
02045         if (uid != DBUS_UID_UNSET)
02046           p = getpwuid_r (uid, &p_str, buf, buflen);
02047         else
02048           p = getpwnam_r (username_c, &p_str, buf, buflen);
02049         result = 0;
02050 #endif /* !HAVE_POSIX_GETPWNAM_R */
02051         //Try a bigger buffer if ERANGE was returned
02052         if (result == ERANGE && buflen < 512 * 1024)
02053           {
02054             dbus_free (buf);
02055             buflen *= 2;
02056           }
02057         else
02058           {
02059             break;
02060           }
02061       }
02062     if (result == 0 && p == &p_str)
02063       {
02064         if (!fill_user_info_from_passwd (p, info, error))
02065           {
02066             dbus_free (buf);
02067             return FALSE;
02068           }
02069         dbus_free (buf);
02070       }
02071     else
02072       {
02073         dbus_set_error (error, _dbus_error_from_errno (errno),
02074                         "User \"%s\" unknown or no memory to allocate password entry\n",
02075                         username_c ? username_c : "???");
02076         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02077         dbus_free (buf);
02078         return FALSE;
02079       }
02080   }
02081 #else /* ! HAVE_GETPWNAM_R */
02082   {
02083     /* I guess we're screwed on thread safety here */
02084     struct passwd *p;
02085 
02086     if (uid != DBUS_UID_UNSET)
02087       p = getpwuid (uid);
02088     else
02089       p = getpwnam (username_c);
02090 
02091     if (p != NULL)
02092       {
02093         if (!fill_user_info_from_passwd (p, info, error))
02094           {
02095             return FALSE;
02096           }
02097       }
02098     else
02099       {
02100         dbus_set_error (error, _dbus_error_from_errno (errno),
02101                         "User \"%s\" unknown or no memory to allocate password entry\n",
02102                         username_c ? username_c : "???");
02103         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02104         return FALSE;
02105       }
02106   }
02107 #endif  /* ! HAVE_GETPWNAM_R */
02108 
02109   /* Fill this in so we can use it to get groups */
02110   username_c = info->username;
02111 
02112 #ifdef HAVE_GETGROUPLIST
02113   {
02114     gid_t *buf;
02115     int buf_count;
02116     int i;
02117     int initial_buf_count;
02118 
02119     initial_buf_count = 17;
02120     buf_count = initial_buf_count;
02121     buf = dbus_new (gid_t, buf_count);
02122     if (buf == NULL)
02123       {
02124         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02125         goto failed;
02126       }
02127 
02128     if (getgrouplist (username_c,
02129                       info->primary_gid,
02130                       buf, &buf_count) < 0)
02131       {
02132         gid_t *new;
02133         /* Presumed cause of negative return code: buf has insufficient
02134            entries to hold the entire group list. The Linux behavior in this
02135            case is to pass back the actual number of groups in buf_count, but
02136            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02137            So as a hack, try to help out a bit by guessing a larger
02138            number of groups, within reason.. might still fail, of course,
02139            but we can at least print a more informative message.  I looked up
02140            the "right way" to do this by downloading Apple's own source code
02141            for the "id" command, and it turns out that they use an
02142            undocumented library function getgrouplist_2 (!) which is not
02143            declared in any header in /usr/include (!!). That did not seem
02144            like the way to go here.
02145         */
02146         if (buf_count == initial_buf_count)
02147           {
02148             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02149           }
02150         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02151         if (new == NULL)
02152           {
02153             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02154             dbus_free (buf);
02155             goto failed;
02156           }
02157 
02158         buf = new;
02159 
02160         errno = 0;
02161         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02162           {
02163             if (errno == 0)
02164               {
02165                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02166                             username_c, buf_count, buf_count);
02167               }
02168             else
02169               {
02170                 dbus_set_error (error,
02171                                 _dbus_error_from_errno (errno),
02172                                 "Failed to get groups for username \"%s\" primary GID "
02173                                 DBUS_GID_FORMAT ": %s\n",
02174                                 username_c, info->primary_gid,
02175                                 _dbus_strerror (errno));
02176                 dbus_free (buf);
02177                 goto failed;
02178               }
02179           }
02180       }
02181 
02182     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02183     if (info->group_ids == NULL)
02184       {
02185         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02186         dbus_free (buf);
02187         goto failed;
02188       }
02189 
02190     for (i = 0; i < buf_count; ++i)
02191       info->group_ids[i] = buf[i];
02192 
02193     info->n_group_ids = buf_count;
02194 
02195     dbus_free (buf);
02196   }
02197 #else  /* HAVE_GETGROUPLIST */
02198   {
02199     /* We just get the one group ID */
02200     info->group_ids = dbus_new (dbus_gid_t, 1);
02201     if (info->group_ids == NULL)
02202       {
02203         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02204         goto failed;
02205       }
02206 
02207     info->n_group_ids = 1;
02208 
02209     (info->group_ids)[0] = info->primary_gid;
02210   }
02211 #endif /* HAVE_GETGROUPLIST */
02212 
02213   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02214 
02215   return TRUE;
02216 
02217  failed:
02218   _DBUS_ASSERT_ERROR_IS_SET (error);
02219   return FALSE;
02220 }
02221 
02230 dbus_bool_t
02231 _dbus_user_info_fill (DBusUserInfo     *info,
02232                       const DBusString *username,
02233                       DBusError        *error)
02234 {
02235   return fill_user_info (info, DBUS_UID_UNSET,
02236                          username, error);
02237 }
02238 
02247 dbus_bool_t
02248 _dbus_user_info_fill_uid (DBusUserInfo *info,
02249                           dbus_uid_t    uid,
02250                           DBusError    *error)
02251 {
02252   return fill_user_info (info, uid,
02253                          NULL, error);
02254 }
02255 
02263 dbus_bool_t
02264 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02265 {
02266   /* The POSIX spec certainly doesn't promise this, but
02267    * we need these assertions to fail as soon as we're wrong about
02268    * it so we can do the porting fixups
02269    */
02270   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02271   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02272   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02273 
02274   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02275     return FALSE;
02276   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02277     return FALSE;
02278 
02279   return TRUE;
02280 }
02281 
02293 dbus_bool_t
02294 _dbus_append_user_from_current_process (DBusString *str)
02295 {
02296   return _dbus_string_append_uint (str,
02297                                    _dbus_geteuid ());
02298 }
02299 
02304 dbus_pid_t
02305 _dbus_getpid (void)
02306 {
02307   return getpid ();
02308 }
02309 
02313 dbus_uid_t
02314 _dbus_getuid (void)
02315 {
02316   return getuid ();
02317 }
02318 
02322 dbus_uid_t
02323 _dbus_geteuid (void)
02324 {
02325   return geteuid ();
02326 }
02327 
02334 unsigned long
02335 _dbus_pid_for_log (void)
02336 {
02337   return getpid ();
02338 }
02339 
02347 dbus_bool_t
02348 _dbus_parse_uid (const DBusString      *uid_str,
02349                  dbus_uid_t            *uid)
02350 {
02351   int end;
02352   long val;
02353 
02354   if (_dbus_string_get_length (uid_str) == 0)
02355     {
02356       _dbus_verbose ("UID string was zero length\n");
02357       return FALSE;
02358     }
02359 
02360   val = -1;
02361   end = 0;
02362   if (!_dbus_string_parse_int (uid_str, 0, &val,
02363                                &end))
02364     {
02365       _dbus_verbose ("could not parse string as a UID\n");
02366       return FALSE;
02367     }
02368 
02369   if (end != _dbus_string_get_length (uid_str))
02370     {
02371       _dbus_verbose ("string contained trailing stuff after UID\n");
02372       return FALSE;
02373     }
02374 
02375   *uid = val;
02376 
02377   return TRUE;
02378 }
02379 
02380 #if !DBUS_USE_SYNC
02381 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02382 #endif
02383 
02390 dbus_int32_t
02391 _dbus_atomic_inc (DBusAtomic *atomic)
02392 {
02393 #if DBUS_USE_SYNC
02394   return __sync_add_and_fetch(&atomic->value, 1)-1;
02395 #else
02396   dbus_int32_t res;
02397   _DBUS_LOCK (atomic);
02398   res = atomic->value;
02399   atomic->value += 1;
02400   _DBUS_UNLOCK (atomic);
02401   return res;
02402 #endif
02403 }
02404 
02411 dbus_int32_t
02412 _dbus_atomic_dec (DBusAtomic *atomic)
02413 {
02414 #if DBUS_USE_SYNC
02415   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02416 #else
02417   dbus_int32_t res;
02418 
02419   _DBUS_LOCK (atomic);
02420   res = atomic->value;
02421   atomic->value -= 1;
02422   _DBUS_UNLOCK (atomic);
02423   return res;
02424 #endif
02425 }
02426 
02434 dbus_int32_t
02435 _dbus_atomic_get (DBusAtomic *atomic)
02436 {
02437 #if DBUS_USE_SYNC
02438   __sync_synchronize ();
02439   return atomic->value;
02440 #else
02441   dbus_int32_t res;
02442 
02443   _DBUS_LOCK (atomic);
02444   res = atomic->value;
02445   _DBUS_UNLOCK (atomic);
02446   return res;
02447 #endif
02448 }
02449 
02450 #ifdef DBUS_BUILD_TESTS
02451 
02454 dbus_gid_t
02455 _dbus_getgid (void)
02456 {
02457   return getgid ();
02458 }
02459 #endif
02460 
02469 int
02470 _dbus_poll (DBusPollFD *fds,
02471             int         n_fds,
02472             int         timeout_milliseconds)
02473 {
02474 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02475   /* This big thing is a constant expression and should get optimized
02476    * out of existence. So it's more robust than a configure check at
02477    * no cost.
02478    */
02479   if (_DBUS_POLLIN == POLLIN &&
02480       _DBUS_POLLPRI == POLLPRI &&
02481       _DBUS_POLLOUT == POLLOUT &&
02482       _DBUS_POLLERR == POLLERR &&
02483       _DBUS_POLLHUP == POLLHUP &&
02484       _DBUS_POLLNVAL == POLLNVAL &&
02485       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02486       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02487       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02488       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02489       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02490       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02491       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02492     {
02493       return poll ((struct pollfd*) fds,
02494                    n_fds,
02495                    timeout_milliseconds);
02496     }
02497   else
02498     {
02499       /* We have to convert the DBusPollFD to an array of
02500        * struct pollfd, poll, and convert back.
02501        */
02502       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02503       return -1;
02504     }
02505 #else /* ! HAVE_POLL */
02506 
02507   fd_set read_set, write_set, err_set;
02508   int max_fd = 0;
02509   int i;
02510   struct timeval tv;
02511   int ready;
02512 
02513   FD_ZERO (&read_set);
02514   FD_ZERO (&write_set);
02515   FD_ZERO (&err_set);
02516 
02517   for (i = 0; i < n_fds; i++)
02518     {
02519       DBusPollFD *fdp = &fds[i];
02520 
02521       if (fdp->events & _DBUS_POLLIN)
02522         FD_SET (fdp->fd, &read_set);
02523 
02524       if (fdp->events & _DBUS_POLLOUT)
02525         FD_SET (fdp->fd, &write_set);
02526 
02527       FD_SET (fdp->fd, &err_set);
02528 
02529       max_fd = MAX (max_fd, fdp->fd);
02530     }
02531 
02532   tv.tv_sec = timeout_milliseconds / 1000;
02533   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02534 
02535   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02536                   timeout_milliseconds < 0 ? NULL : &tv);
02537 
02538   if (ready > 0)
02539     {
02540       for (i = 0; i < n_fds; i++)
02541         {
02542           DBusPollFD *fdp = &fds[i];
02543 
02544           fdp->revents = 0;
02545 
02546           if (FD_ISSET (fdp->fd, &read_set))
02547             fdp->revents |= _DBUS_POLLIN;
02548 
02549           if (FD_ISSET (fdp->fd, &write_set))
02550             fdp->revents |= _DBUS_POLLOUT;
02551 
02552           if (FD_ISSET (fdp->fd, &err_set))
02553             fdp->revents |= _DBUS_POLLERR;
02554         }
02555     }
02556 
02557   return ready;
02558 #endif
02559 }
02560 
02568 void
02569 _dbus_get_current_time (long *tv_sec,
02570                         long *tv_usec)
02571 {
02572   struct timeval t;
02573 
02574 #ifdef HAVE_MONOTONIC_CLOCK
02575   struct timespec ts;
02576   clock_gettime (CLOCK_MONOTONIC, &ts);
02577 
02578   if (tv_sec)
02579     *tv_sec = ts.tv_sec;
02580   if (tv_usec)
02581     *tv_usec = ts.tv_nsec / 1000;
02582 #else
02583   gettimeofday (&t, NULL);
02584 
02585   if (tv_sec)
02586     *tv_sec = t.tv_sec;
02587   if (tv_usec)
02588     *tv_usec = t.tv_usec;
02589 #endif
02590 }
02591 
02600 dbus_bool_t
02601 _dbus_create_directory (const DBusString *filename,
02602                         DBusError        *error)
02603 {
02604   const char *filename_c;
02605 
02606   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02607 
02608   filename_c = _dbus_string_get_const_data (filename);
02609 
02610   if (mkdir (filename_c, 0700) < 0)
02611     {
02612       if (errno == EEXIST)
02613         return TRUE;
02614 
02615       dbus_set_error (error, DBUS_ERROR_FAILED,
02616                       "Failed to create directory %s: %s\n",
02617                       filename_c, _dbus_strerror (errno));
02618       return FALSE;
02619     }
02620   else
02621     return TRUE;
02622 }
02623 
02634 dbus_bool_t
02635 _dbus_concat_dir_and_file (DBusString       *dir,
02636                            const DBusString *next_component)
02637 {
02638   dbus_bool_t dir_ends_in_slash;
02639   dbus_bool_t file_starts_with_slash;
02640 
02641   if (_dbus_string_get_length (dir) == 0 ||
02642       _dbus_string_get_length (next_component) == 0)
02643     return TRUE;
02644 
02645   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02646                                                     _dbus_string_get_length (dir) - 1);
02647 
02648   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02649 
02650   if (dir_ends_in_slash && file_starts_with_slash)
02651     {
02652       _dbus_string_shorten (dir, 1);
02653     }
02654   else if (!(dir_ends_in_slash || file_starts_with_slash))
02655     {
02656       if (!_dbus_string_append_byte (dir, '/'))
02657         return FALSE;
02658     }
02659 
02660   return _dbus_string_copy (next_component, 0, dir,
02661                             _dbus_string_get_length (dir));
02662 }
02663 
02665 #define NANOSECONDS_PER_SECOND       1000000000
02666 
02667 #define MICROSECONDS_PER_SECOND      1000000
02668 
02669 #define MILLISECONDS_PER_SECOND      1000
02670 
02671 #define NANOSECONDS_PER_MILLISECOND  1000000
02672 
02673 #define MICROSECONDS_PER_MILLISECOND 1000
02674 
02679 void
02680 _dbus_sleep_milliseconds (int milliseconds)
02681 {
02682 #ifdef HAVE_NANOSLEEP
02683   struct timespec req;
02684   struct timespec rem;
02685 
02686   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02687   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02688   rem.tv_sec = 0;
02689   rem.tv_nsec = 0;
02690 
02691   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02692     req = rem;
02693 #elif defined (HAVE_USLEEP)
02694   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02695 #else /* ! HAVE_USLEEP */
02696   sleep (MAX (milliseconds / 1000, 1));
02697 #endif
02698 }
02699 
02700 static dbus_bool_t
02701 _dbus_generate_pseudorandom_bytes (DBusString *str,
02702                                    int         n_bytes)
02703 {
02704   int old_len;
02705   char *p;
02706 
02707   old_len = _dbus_string_get_length (str);
02708 
02709   if (!_dbus_string_lengthen (str, n_bytes))
02710     return FALSE;
02711 
02712   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02713 
02714   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02715 
02716   return TRUE;
02717 }
02718 
02727 dbus_bool_t
02728 _dbus_generate_random_bytes (DBusString *str,
02729                              int         n_bytes)
02730 {
02731   int old_len;
02732   int fd;
02733 
02734   /* FALSE return means "no memory", if it could
02735    * mean something else then we'd need to return
02736    * a DBusError. So we always fall back to pseudorandom
02737    * if the I/O fails.
02738    */
02739 
02740   old_len = _dbus_string_get_length (str);
02741   fd = -1;
02742 
02743   /* note, urandom on linux will fall back to pseudorandom */
02744   fd = open ("/dev/urandom", O_RDONLY);
02745   if (fd < 0)
02746     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02747 
02748   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02749 
02750   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02751     {
02752       _dbus_close (fd, NULL);
02753       _dbus_string_set_length (str, old_len);
02754       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02755     }
02756 
02757   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02758                  n_bytes);
02759 
02760   _dbus_close (fd, NULL);
02761 
02762   return TRUE;
02763 }
02764 
02770 void
02771 _dbus_exit (int code)
02772 {
02773   _exit (code);
02774 }
02775 
02784 const char*
02785 _dbus_strerror (int error_number)
02786 {
02787   const char *msg;
02788 
02789   msg = strerror (error_number);
02790   if (msg == NULL)
02791     msg = "unknown";
02792 
02793   return msg;
02794 }
02795 
02799 void
02800 _dbus_disable_sigpipe (void)
02801 {
02802   signal (SIGPIPE, SIG_IGN);
02803 }
02804 
02812 void
02813 _dbus_fd_set_close_on_exec (intptr_t fd)
02814 {
02815   int val;
02816 
02817   val = fcntl (fd, F_GETFD, 0);
02818 
02819   if (val < 0)
02820     return;
02821 
02822   val |= FD_CLOEXEC;
02823 
02824   fcntl (fd, F_SETFD, val);
02825 }
02826 
02834 dbus_bool_t
02835 _dbus_close (int        fd,
02836              DBusError *error)
02837 {
02838   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02839 
02840  again:
02841   if (close (fd) < 0)
02842     {
02843       if (errno == EINTR)
02844         goto again;
02845 
02846       dbus_set_error (error, _dbus_error_from_errno (errno),
02847                       "Could not close fd %d", fd);
02848       return FALSE;
02849     }
02850 
02851   return TRUE;
02852 }
02853 
02861 int
02862 _dbus_dup(int        fd,
02863           DBusError *error)
02864 {
02865   int new_fd;
02866 
02867 #ifdef F_DUPFD_CLOEXEC
02868   dbus_bool_t cloexec_done;
02869 
02870   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02871   cloexec_done = new_fd >= 0;
02872 
02873   if (new_fd < 0 && errno == EINVAL)
02874 #endif
02875     {
02876       new_fd = fcntl(fd, F_DUPFD, 3);
02877     }
02878 
02879   if (new_fd < 0) {
02880 
02881     dbus_set_error (error, _dbus_error_from_errno (errno),
02882                     "Could not duplicate fd %d", fd);
02883     return -1;
02884   }
02885 
02886 #ifdef F_DUPFD_CLOEXEC
02887   if (!cloexec_done)
02888 #endif
02889     {
02890       _dbus_fd_set_close_on_exec(new_fd);
02891     }
02892 
02893   return new_fd;
02894 }
02895 
02903 dbus_bool_t
02904 _dbus_set_fd_nonblocking (int             fd,
02905                           DBusError      *error)
02906 {
02907   int val;
02908 
02909   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02910 
02911   val = fcntl (fd, F_GETFL, 0);
02912   if (val < 0)
02913     {
02914       dbus_set_error (error, _dbus_error_from_errno (errno),
02915                       "Failed to get flags from file descriptor %d: %s",
02916                       fd, _dbus_strerror (errno));
02917       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02918                      _dbus_strerror (errno));
02919       return FALSE;
02920     }
02921 
02922   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02923     {
02924       dbus_set_error (error, _dbus_error_from_errno (errno),
02925                       "Failed to set nonblocking flag of file descriptor %d: %s",
02926                       fd, _dbus_strerror (errno));
02927       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02928                      fd, _dbus_strerror (errno));
02929 
02930       return FALSE;
02931     }
02932 
02933   return TRUE;
02934 }
02935 
02941 void
02942 _dbus_print_backtrace (void)
02943 {
02944 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02945   void *bt[500];
02946   int bt_size;
02947   int i;
02948   char **syms;
02949 
02950   bt_size = backtrace (bt, 500);
02951 
02952   syms = backtrace_symbols (bt, bt_size);
02953 
02954   i = 0;
02955   while (i < bt_size)
02956     {
02957       /* don't use dbus_warn since it can _dbus_abort() */
02958       fprintf (stderr, "  %s\n", syms[i]);
02959       ++i;
02960     }
02961   fflush (stderr);
02962 
02963   free (syms);
02964 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02965   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02966 #else
02967   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02968 #endif
02969 }
02970 
02988 dbus_bool_t
02989 _dbus_full_duplex_pipe (int        *fd1,
02990                         int        *fd2,
02991                         dbus_bool_t blocking,
02992                         DBusError  *error)
02993 {
02994 #ifdef HAVE_SOCKETPAIR
02995   int fds[2];
02996   int retval;
02997 
02998 #ifdef SOCK_CLOEXEC
02999   dbus_bool_t cloexec_done;
03000 
03001   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03002   cloexec_done = retval >= 0;
03003 
03004   if (retval < 0 && errno == EINVAL)
03005 #endif
03006     {
03007       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03008     }
03009 
03010   if (retval < 0)
03011     {
03012       dbus_set_error (error, _dbus_error_from_errno (errno),
03013                       "Could not create full-duplex pipe");
03014       return FALSE;
03015     }
03016 
03017   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03018 
03019 #ifdef SOCK_CLOEXEC
03020   if (!cloexec_done)
03021 #endif
03022     {
03023       _dbus_fd_set_close_on_exec (fds[0]);
03024       _dbus_fd_set_close_on_exec (fds[1]);
03025     }
03026 
03027   if (!blocking &&
03028       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03029        !_dbus_set_fd_nonblocking (fds[1], NULL)))
03030     {
03031       dbus_set_error (error, _dbus_error_from_errno (errno),
03032                       "Could not set full-duplex pipe nonblocking");
03033 
03034       _dbus_close (fds[0], NULL);
03035       _dbus_close (fds[1], NULL);
03036 
03037       return FALSE;
03038     }
03039 
03040   *fd1 = fds[0];
03041   *fd2 = fds[1];
03042 
03043   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03044                  *fd1, *fd2);
03045 
03046   return TRUE;
03047 #else
03048   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03049   dbus_set_error (error, DBUS_ERROR_FAILED,
03050                   "_dbus_full_duplex_pipe() not implemented on this OS");
03051   return FALSE;
03052 #endif
03053 }
03054 
03063 int
03064 _dbus_printf_string_upper_bound (const char *format,
03065                                  va_list     args)
03066 {
03067   char static_buf[1024];
03068   int bufsize = sizeof (static_buf);
03069   int len;
03070   va_list args_copy;
03071 
03072   DBUS_VA_COPY (args_copy, args);
03073   len = vsnprintf (static_buf, bufsize, format, args_copy);
03074   va_end (args_copy);
03075 
03076   /* If vsnprintf() returned non-negative, then either the string fits in
03077    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03078    * returns the number of characters that were needed, or this OS returns the
03079    * truncated length.
03080    *
03081    * We ignore the possibility that snprintf might just ignore the length and
03082    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03083    * If your libc is really that bad, come back when you have a better one. */
03084   if (len == bufsize)
03085     {
03086       /* This could be the truncated length (Tru64 and IRIX have this bug),
03087        * or the real length could be coincidentally the same. Which is it?
03088        * If vsnprintf returns the truncated length, we'll go to the slow
03089        * path. */
03090       DBUS_VA_COPY (args_copy, args);
03091 
03092       if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03093         len = -1;
03094 
03095       va_end (args_copy);
03096     }
03097 
03098   /* If vsnprintf() returned negative, we have to do more work.
03099    * HP-UX returns negative. */
03100   while (len < 0)
03101     {
03102       char *buf;
03103 
03104       bufsize *= 2;
03105 
03106       buf = dbus_malloc (bufsize);
03107 
03108       if (buf == NULL)
03109         return -1;
03110 
03111       DBUS_VA_COPY (args_copy, args);
03112       len = vsnprintf (buf, bufsize, format, args_copy);
03113       va_end (args_copy);
03114 
03115       dbus_free (buf);
03116 
03117       /* If the reported length is exactly the buffer size, round up to the
03118        * next size, in case vsnprintf has been returning the truncated
03119        * length */
03120       if (len == bufsize)
03121         len = -1;
03122     }
03123 
03124   return len;
03125 }
03126 
03133 const char*
03134 _dbus_get_tmpdir(void)
03135 {
03136   static const char* tmpdir = NULL;
03137 
03138   if (tmpdir == NULL)
03139     {
03140       /* TMPDIR is what glibc uses, then
03141        * glibc falls back to the P_tmpdir macro which
03142        * just expands to "/tmp"
03143        */
03144       if (tmpdir == NULL)
03145         tmpdir = getenv("TMPDIR");
03146 
03147       /* These two env variables are probably
03148        * broken, but maybe some OS uses them?
03149        */
03150       if (tmpdir == NULL)
03151         tmpdir = getenv("TMP");
03152       if (tmpdir == NULL)
03153         tmpdir = getenv("TEMP");
03154 
03155       /* And this is the sane fallback. */
03156       if (tmpdir == NULL)
03157         tmpdir = "/tmp";
03158     }
03159 
03160   _dbus_assert(tmpdir != NULL);
03161 
03162   return tmpdir;
03163 }
03164 
03184 static dbus_bool_t
03185 _read_subprocess_line_argv (const char *progpath,
03186                             dbus_bool_t path_fallback,
03187                             char       * const *argv,
03188                             DBusString *result,
03189                             DBusError  *error)
03190 {
03191   int result_pipe[2] = { -1, -1 };
03192   int errors_pipe[2] = { -1, -1 };
03193   pid_t pid;
03194   int ret;
03195   int status;
03196   int orig_len;
03197   int i;
03198 
03199   dbus_bool_t retval;
03200   sigset_t new_set, old_set;
03201 
03202   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03203   retval = FALSE;
03204 
03205   /* We need to block any existing handlers for SIGCHLD temporarily; they
03206    * will cause waitpid() below to fail.
03207    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03208    */
03209   sigemptyset (&new_set);
03210   sigaddset (&new_set, SIGCHLD);
03211   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03212 
03213   orig_len = _dbus_string_get_length (result);
03214 
03215 #define READ_END        0
03216 #define WRITE_END       1
03217   if (pipe (result_pipe) < 0)
03218     {
03219       dbus_set_error (error, _dbus_error_from_errno (errno),
03220                       "Failed to create a pipe to call %s: %s",
03221                       progpath, _dbus_strerror (errno));
03222       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03223                      progpath, _dbus_strerror (errno));
03224       goto out;
03225     }
03226   if (pipe (errors_pipe) < 0)
03227     {
03228       dbus_set_error (error, _dbus_error_from_errno (errno),
03229                       "Failed to create a pipe to call %s: %s",
03230                       progpath, _dbus_strerror (errno));
03231       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03232                      progpath, _dbus_strerror (errno));
03233       goto out;
03234     }
03235 
03236   pid = fork ();
03237   if (pid < 0)
03238     {
03239       dbus_set_error (error, _dbus_error_from_errno (errno),
03240                       "Failed to fork() to call %s: %s",
03241                       progpath, _dbus_strerror (errno));
03242       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03243                      progpath, _dbus_strerror (errno));
03244       goto out;
03245     }
03246 
03247   if (pid == 0)
03248     {
03249       /* child process */
03250       int maxfds;
03251       int fd;
03252 
03253       fd = open ("/dev/null", O_RDWR);
03254       if (fd == -1)
03255         /* huh?! can't open /dev/null? */
03256         _exit (1);
03257 
03258       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03259 
03260       /* set-up stdXXX */
03261       close (result_pipe[READ_END]);
03262       close (errors_pipe[READ_END]);
03263       close (0);                /* close stdin */
03264       close (1);                /* close stdout */
03265       close (2);                /* close stderr */
03266 
03267       if (dup2 (fd, 0) == -1)
03268         _exit (1);
03269       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03270         _exit (1);
03271       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03272         _exit (1);
03273 
03274       maxfds = sysconf (_SC_OPEN_MAX);
03275       /* Pick something reasonable if for some reason sysconf
03276        * says unlimited.
03277        */
03278       if (maxfds < 0)
03279         maxfds = 1024;
03280       /* close all inherited fds */
03281       for (i = 3; i < maxfds; i++)
03282         close (i);
03283 
03284       sigprocmask (SIG_SETMASK, &old_set, NULL);
03285 
03286       /* If it looks fully-qualified, try execv first */
03287       if (progpath[0] == '/')
03288         {
03289           execv (progpath, argv);
03290           /* Ok, that failed.  Now if path_fallback is given, let's
03291            * try unqualified.  This is mostly a hack to work
03292            * around systems which ship dbus-launch in /usr/bin
03293            * but everything else in /bin (because dbus-launch
03294            * depends on X11).
03295            */
03296           if (path_fallback)
03297             /* We must have a slash, because we checked above */
03298             execvp (strrchr (progpath, '/')+1, argv);
03299         }
03300       else
03301         execvp (progpath, argv);
03302 
03303       /* still nothing, we failed */
03304       _exit (1);
03305     }
03306 
03307   /* parent process */
03308   close (result_pipe[WRITE_END]);
03309   close (errors_pipe[WRITE_END]);
03310   result_pipe[WRITE_END] = -1;
03311   errors_pipe[WRITE_END] = -1;
03312 
03313   ret = 0;
03314   do
03315     {
03316       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03317     }
03318   while (ret > 0);
03319 
03320   /* reap the child process to avoid it lingering as zombie */
03321   do
03322     {
03323       ret = waitpid (pid, &status, 0);
03324     }
03325   while (ret == -1 && errno == EINTR);
03326 
03327   /* We succeeded if the process exited with status 0 and
03328      anything was read */
03329   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03330     {
03331       /* The process ended with error */
03332       DBusString error_message;
03333       if (!_dbus_string_init (&error_message))
03334         {
03335           _DBUS_SET_OOM (error);
03336           goto out;
03337         }
03338 
03339       ret = 0;
03340       do
03341         {
03342           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03343         }
03344       while (ret > 0);
03345 
03346       _dbus_string_set_length (result, orig_len);
03347       if (_dbus_string_get_length (&error_message) > 0)
03348         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03349                         "%s terminated abnormally with the following error: %s",
03350                         progpath, _dbus_string_get_data (&error_message));
03351       else
03352         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03353                         "%s terminated abnormally without any error message",
03354                         progpath);
03355       goto out;
03356     }
03357 
03358   retval = TRUE;
03359 
03360  out:
03361   sigprocmask (SIG_SETMASK, &old_set, NULL);
03362 
03363   if (retval)
03364     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03365   else
03366     _DBUS_ASSERT_ERROR_IS_SET (error);
03367 
03368   if (result_pipe[0] != -1)
03369     close (result_pipe[0]);
03370   if (result_pipe[1] != -1)
03371     close (result_pipe[1]);
03372   if (errors_pipe[0] != -1)
03373     close (errors_pipe[0]);
03374   if (errors_pipe[1] != -1)
03375     close (errors_pipe[1]);
03376 
03377   return retval;
03378 }
03379 
03391 dbus_bool_t
03392 _dbus_get_autolaunch_address (const char *scope,
03393                               DBusString *address,
03394                               DBusError  *error)
03395 {
03396 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03397   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03398    * but that's done elsewhere, and if it worked, this function wouldn't
03399    * be called.) */
03400   const char *display;
03401   static char *argv[6];
03402   int i;
03403   DBusString uuid;
03404   dbus_bool_t retval;
03405 
03406   if (_dbus_check_setuid ())
03407     {
03408       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03409                             "Unable to autolaunch when setuid");
03410       return FALSE;
03411     }
03412 
03413   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03414   retval = FALSE;
03415 
03416   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03417    * dbus-launch-x11 is just going to fail. Rather than trying to
03418    * run it, we might as well bail out early with a nice error. */
03419   display = _dbus_getenv ("DISPLAY");
03420 
03421   if (display == NULL || display[0] == '\0')
03422     {
03423       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03424           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03425       return FALSE;
03426     }
03427 
03428   if (!_dbus_string_init (&uuid))
03429     {
03430       _DBUS_SET_OOM (error);
03431       return FALSE;
03432     }
03433 
03434   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03435     {
03436       _DBUS_SET_OOM (error);
03437       goto out;
03438     }
03439 
03440   i = 0;
03441   argv[i] = "dbus-launch";
03442   ++i;
03443   argv[i] = "--autolaunch";
03444   ++i;
03445   argv[i] = _dbus_string_get_data (&uuid);
03446   ++i;
03447   argv[i] = "--binary-syntax";
03448   ++i;
03449   argv[i] = "--close-stderr";
03450   ++i;
03451   argv[i] = NULL;
03452   ++i;
03453 
03454   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03455 
03456   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03457                                        TRUE,
03458                                        argv, address, error);
03459 
03460  out:
03461   _dbus_string_free (&uuid);
03462   return retval;
03463 #else
03464   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03465       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03466       "set your DBUS_SESSION_BUS_ADDRESS instead");
03467   return FALSE;
03468 #endif
03469 }
03470 
03489 dbus_bool_t
03490 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03491                                dbus_bool_t create_if_not_found,
03492                                DBusError  *error)
03493 {
03494   DBusString filename;
03495   dbus_bool_t b;
03496 
03497   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03498 
03499   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03500   if (b)
03501     return TRUE;
03502 
03503   dbus_error_free (error);
03504 
03505   /* Fallback to the system machine ID */
03506   _dbus_string_init_const (&filename, "/etc/machine-id");
03507   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03508 }
03509 
03510 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03511 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03512 
03519 dbus_bool_t
03520 _dbus_lookup_launchd_socket (DBusString *socket_path,
03521                              const char *launchd_env_var,
03522                              DBusError  *error)
03523 {
03524 #ifdef DBUS_ENABLE_LAUNCHD
03525   char *argv[4];
03526   int i;
03527 
03528   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03529 
03530   if (_dbus_check_setuid ())
03531     {
03532       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03533                             "Unable to find launchd socket when setuid");
03534       return FALSE;
03535     }
03536 
03537   i = 0;
03538   argv[i] = "launchctl";
03539   ++i;
03540   argv[i] = "getenv";
03541   ++i;
03542   argv[i] = (char*)launchd_env_var;
03543   ++i;
03544   argv[i] = NULL;
03545   ++i;
03546 
03547   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03548 
03549   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03550     {
03551       return FALSE;
03552     }
03553 
03554   /* no error, but no result either */
03555   if (_dbus_string_get_length(socket_path) == 0)
03556     {
03557       return FALSE;
03558     }
03559 
03560   /* strip the carriage-return */
03561   _dbus_string_shorten(socket_path, 1);
03562   return TRUE;
03563 #else /* DBUS_ENABLE_LAUNCHD */
03564   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03565                 "can't lookup socket from launchd; launchd support not compiled in");
03566   return FALSE;
03567 #endif
03568 }
03569 
03570 static dbus_bool_t
03571 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03572 {
03573 #ifdef DBUS_ENABLE_LAUNCHD
03574   dbus_bool_t valid_socket;
03575   DBusString socket_path;
03576 
03577   if (_dbus_check_setuid ())
03578     {
03579       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03580                             "Unable to find launchd socket when setuid");
03581       return FALSE;
03582     }
03583 
03584   if (!_dbus_string_init (&socket_path))
03585     {
03586       _DBUS_SET_OOM (error);
03587       return FALSE;
03588     }
03589 
03590   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03591 
03592   if (dbus_error_is_set(error))
03593     {
03594       _dbus_string_free(&socket_path);
03595       return FALSE;
03596     }
03597 
03598   if (!valid_socket)
03599     {
03600       dbus_set_error(error, "no socket path",
03601                 "launchd did not provide a socket path, "
03602                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03603       _dbus_string_free(&socket_path);
03604       return FALSE;
03605     }
03606   if (!_dbus_string_append (address, "unix:path="))
03607     {
03608       _DBUS_SET_OOM (error);
03609       _dbus_string_free(&socket_path);
03610       return FALSE;
03611     }
03612   if (!_dbus_string_copy (&socket_path, 0, address,
03613                           _dbus_string_get_length (address)))
03614     {
03615       _DBUS_SET_OOM (error);
03616       _dbus_string_free(&socket_path);
03617       return FALSE;
03618     }
03619 
03620   _dbus_string_free(&socket_path);
03621   return TRUE;
03622 #else
03623   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03624                 "can't lookup session address from launchd; launchd support not compiled in");
03625   return FALSE;
03626 #endif
03627 }
03628 
03648 dbus_bool_t
03649 _dbus_lookup_session_address (dbus_bool_t *supported,
03650                               DBusString  *address,
03651                               DBusError   *error)
03652 {
03653 #ifdef DBUS_ENABLE_LAUNCHD
03654   *supported = TRUE;
03655   return _dbus_lookup_session_address_launchd (address, error);
03656 #else
03657   /* On non-Mac Unix platforms, if the session address isn't already
03658    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03659    * fall back to the autolaunch: global default; see
03660    * init_session_address in dbus/dbus-bus.c. */
03661   *supported = FALSE;
03662   return TRUE;
03663 #endif
03664 }
03665 
03683 dbus_bool_t
03684 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03685 {
03686   const char *xdg_data_home;
03687   const char *xdg_data_dirs;
03688   DBusString servicedir_path;
03689 
03690   if (!_dbus_string_init (&servicedir_path))
03691     return FALSE;
03692 
03693   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03694   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03695 
03696   if (xdg_data_home != NULL)
03697     {
03698       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03699         goto oom;
03700     }
03701   else
03702     {
03703       const DBusString *homedir;
03704       DBusString local_share;
03705 
03706       if (!_dbus_homedir_from_current_process (&homedir))
03707         goto oom;
03708 
03709       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03710         goto oom;
03711 
03712       _dbus_string_init_const (&local_share, "/.local/share");
03713       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03714         goto oom;
03715     }
03716 
03717   if (!_dbus_string_append (&servicedir_path, ":"))
03718     goto oom;
03719 
03720   if (xdg_data_dirs != NULL)
03721     {
03722       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03723         goto oom;
03724 
03725       if (!_dbus_string_append (&servicedir_path, ":"))
03726         goto oom;
03727     }
03728   else
03729     {
03730       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03731         goto oom;
03732     }
03733 
03734   /*
03735    * add configured datadir to defaults
03736    * this may be the same as an xdg dir
03737    * however the config parser should take
03738    * care of duplicates
03739    */
03740   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03741     goto oom;
03742 
03743   if (!_dbus_split_paths_and_append (&servicedir_path,
03744                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03745                                      dirs))
03746     goto oom;
03747 
03748   _dbus_string_free (&servicedir_path);
03749   return TRUE;
03750 
03751  oom:
03752   _dbus_string_free (&servicedir_path);
03753   return FALSE;
03754 }
03755 
03756 
03775 dbus_bool_t
03776 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03777 {
03778   const char *xdg_data_dirs;
03779   DBusString servicedir_path;
03780 
03781   if (!_dbus_string_init (&servicedir_path))
03782     return FALSE;
03783 
03784   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03785 
03786   if (xdg_data_dirs != NULL)
03787     {
03788       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03789         goto oom;
03790 
03791       if (!_dbus_string_append (&servicedir_path, ":"))
03792         goto oom;
03793     }
03794   else
03795     {
03796       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03797         goto oom;
03798     }
03799 
03800   /*
03801    * Add configured datadir to defaults. This may be the same as one
03802    * of the XDG directories. However, the config parser should take
03803    * care of the duplicates.
03804    *
03805    * Also, append /lib as counterpart of /usr/share on the root
03806    * directory (the root directory does not know /share), in order to
03807    * facilitate early boot system bus activation where /usr might not
03808    * be available.
03809    */
03810   if (!_dbus_string_append (&servicedir_path,
03811                             DBUS_DATADIR":"
03812                             "/lib:"))
03813         goto oom;
03814 
03815   if (!_dbus_split_paths_and_append (&servicedir_path,
03816                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03817                                      dirs))
03818     goto oom;
03819 
03820   _dbus_string_free (&servicedir_path);
03821   return TRUE;
03822 
03823  oom:
03824   _dbus_string_free (&servicedir_path);
03825   return FALSE;
03826 }
03827 
03836 dbus_bool_t
03837 _dbus_append_system_config_file (DBusString *str)
03838 {
03839   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03840 }
03841 
03848 dbus_bool_t
03849 _dbus_append_session_config_file (DBusString *str)
03850 {
03851   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03852 }
03853 
03861 void
03862 _dbus_flush_caches (void)
03863 {
03864   _dbus_user_database_flush_system ();
03865 }
03866 
03880 dbus_bool_t
03881 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03882                                                 DBusCredentials *credentials)
03883 {
03884   DBusString homedir;
03885   DBusString dotdir;
03886   dbus_uid_t uid;
03887 
03888   _dbus_assert (credentials != NULL);
03889   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03890 
03891   if (!_dbus_string_init (&homedir))
03892     return FALSE;
03893 
03894   uid = _dbus_credentials_get_unix_uid (credentials);
03895   _dbus_assert (uid != DBUS_UID_UNSET);
03896 
03897   if (!_dbus_homedir_from_uid (uid, &homedir))
03898     goto failed;
03899 
03900 #ifdef DBUS_BUILD_TESTS
03901   {
03902     const char *override;
03903 
03904     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03905     if (override != NULL && *override != '\0')
03906       {
03907         _dbus_string_set_length (&homedir, 0);
03908         if (!_dbus_string_append (&homedir, override))
03909           goto failed;
03910 
03911         _dbus_verbose ("Using fake homedir for testing: %s\n",
03912                        _dbus_string_get_const_data (&homedir));
03913       }
03914     else
03915       {
03916         static dbus_bool_t already_warned = FALSE;
03917         if (!already_warned)
03918           {
03919             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03920             already_warned = TRUE;
03921           }
03922       }
03923   }
03924 #endif
03925 
03926   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03927   if (!_dbus_concat_dir_and_file (&homedir,
03928                                   &dotdir))
03929     goto failed;
03930 
03931   if (!_dbus_string_copy (&homedir, 0,
03932                           directory, _dbus_string_get_length (directory))) {
03933     goto failed;
03934   }
03935 
03936   _dbus_string_free (&homedir);
03937   return TRUE;
03938 
03939  failed:
03940   _dbus_string_free (&homedir);
03941   return FALSE;
03942 }
03943 
03944 //PENDING(kdab) docs
03945 dbus_bool_t
03946 _dbus_daemon_publish_session_bus_address (const char* addr,
03947                                           const char *scope)
03948 {
03949   return TRUE;
03950 }
03951 
03952 //PENDING(kdab) docs
03953 void
03954 _dbus_daemon_unpublish_session_bus_address (void)
03955 {
03956 
03957 }
03958 
03965 dbus_bool_t
03966 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03967 {
03968   return errno == EAGAIN || errno == EWOULDBLOCK;
03969 }
03970 
03978 dbus_bool_t
03979 _dbus_delete_directory (const DBusString *filename,
03980                         DBusError        *error)
03981 {
03982   const char *filename_c;
03983 
03984   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03985 
03986   filename_c = _dbus_string_get_const_data (filename);
03987 
03988   if (rmdir (filename_c) != 0)
03989     {
03990       dbus_set_error (error, DBUS_ERROR_FAILED,
03991                       "Failed to remove directory %s: %s\n",
03992                       filename_c, _dbus_strerror (errno));
03993       return FALSE;
03994     }
03995 
03996   return TRUE;
03997 }
03998 
04006 dbus_bool_t
04007 _dbus_socket_can_pass_unix_fd(int fd) {
04008 
04009 #ifdef SCM_RIGHTS
04010   union {
04011     struct sockaddr sa;
04012     struct sockaddr_storage storage;
04013     struct sockaddr_un un;
04014   } sa_buf;
04015 
04016   socklen_t sa_len = sizeof(sa_buf);
04017 
04018   _DBUS_ZERO(sa_buf);
04019 
04020   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
04021     return FALSE;
04022 
04023   return sa_buf.sa.sa_family == AF_UNIX;
04024 
04025 #else
04026   return FALSE;
04027 
04028 #endif
04029 }
04030 
04031 
04032 /*
04033  * replaces the term DBUS_PREFIX in configure_time_path by the
04034  * current dbus installation directory. On unix this function is a noop
04035  *
04036  * @param configure_time_path
04037  * @return real path
04038  */
04039 const char *
04040 _dbus_replace_install_prefix (const char *configure_time_path)
04041 {
04042   return configure_time_path;
04043 }
04044 
04054 dbus_bool_t
04055 _dbus_check_setuid (void)
04056 {
04057   /* TODO: get __libc_enable_secure exported from glibc.
04058    * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
04059    */
04060 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
04061   {
04062     /* See glibc/include/unistd.h */
04063     extern int __libc_enable_secure;
04064     return __libc_enable_secure;
04065   }
04066 #elif defined(HAVE_ISSETUGID)
04067   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
04068   return issetugid ();
04069 #else
04070   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
04071   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
04072 
04073   static dbus_bool_t check_setuid_initialised;
04074   static dbus_bool_t is_setuid;
04075 
04076   if (_DBUS_UNLIKELY (!check_setuid_initialised))
04077     {
04078 #ifdef HAVE_GETRESUID
04079       if (getresuid (&ruid, &euid, &suid) != 0 ||
04080           getresgid (&rgid, &egid, &sgid) != 0)
04081 #endif /* HAVE_GETRESUID */
04082         {
04083           suid = ruid = getuid ();
04084           sgid = rgid = getgid ();
04085           euid = geteuid ();
04086           egid = getegid ();
04087         }
04088 
04089       check_setuid_initialised = TRUE;
04090       is_setuid = (ruid != euid || ruid != suid ||
04091                    rgid != egid || rgid != sgid);
04092 
04093     }
04094   return is_setuid;
04095 #endif
04096 }
04097 
04098 /* tests in dbus-sysdeps-util.c */