D-Bus  1.8.20
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 #include <arpa/inet.h>
00059 #include <alloca.h>
00060 
00061 #ifdef HAVE_ERRNO_H
00062 #include <errno.h>
00063 #endif
00064 #ifdef HAVE_WRITEV
00065 #include <sys/uio.h>
00066 #endif
00067 #ifdef HAVE_POLL
00068 #include <sys/poll.h>
00069 #endif
00070 #ifdef HAVE_BACKTRACE
00071 #include <execinfo.h>
00072 #endif
00073 #ifdef HAVE_GETPEERUCRED
00074 #include <ucred.h>
00075 #endif
00076 #ifdef HAVE_ALLOCA_H
00077 #include <alloca.h>
00078 #endif
00079 
00080 #ifdef HAVE_ADT
00081 #include <bsm/adt.h>
00082 #endif
00083 
00084 #include "sd-daemon.h"
00085 
00086 #if !DBUS_USE_SYNC
00087 #include <pthread.h>
00088 #endif
00089 
00090 #ifndef O_BINARY
00091 #define O_BINARY 0
00092 #endif
00093 
00094 #ifndef AI_ADDRCONFIG
00095 #define AI_ADDRCONFIG 0
00096 #endif
00097 
00098 #ifndef HAVE_SOCKLEN_T
00099 #define socklen_t int
00100 #endif
00101 
00102 #if defined (__sun) || defined (__sun__)
00103 /*
00104  * CMS_SPACE etc. definitions for Solaris < 10, based on
00105  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
00106  * via
00107  *   http://wiki.opencsw.org/porting-faq#toc10
00108  *
00109  * These are only redefined for Solaris, for now: if your OS needs these too,
00110  * please file a bug. (Or preferably, improve your OS so they're not needed.)
00111  */
00112 
00113 # ifndef CMSG_ALIGN
00114 #   ifdef __sun__
00115 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00116 #   else
00117       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
00118 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00119                               ~(sizeof (long) - 1))
00120 #   endif
00121 # endif
00122 
00123 # ifndef CMSG_SPACE
00124 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00125                             CMSG_ALIGN (len))
00126 # endif
00127 
00128 # ifndef CMSG_LEN
00129 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00130 # endif
00131 
00132 #endif /* Solaris */
00133 
00134 static dbus_bool_t
00135 _dbus_open_socket (int              *fd_p,
00136                    int               domain,
00137                    int               type,
00138                    int               protocol,
00139                    DBusError        *error)
00140 {
00141 #ifdef SOCK_CLOEXEC
00142   dbus_bool_t cloexec_done;
00143 
00144   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00145   cloexec_done = *fd_p >= 0;
00146 
00147   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00148   if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
00149 #endif
00150     {
00151       *fd_p = socket (domain, type, protocol);
00152     }
00153 
00154   if (*fd_p >= 0)
00155     {
00156 #ifdef SOCK_CLOEXEC
00157       if (!cloexec_done)
00158 #endif
00159         {
00160           _dbus_fd_set_close_on_exec(*fd_p);
00161         }
00162 
00163       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00164       return TRUE;
00165     }
00166   else
00167     {
00168       dbus_set_error(error,
00169                      _dbus_error_from_errno (errno),
00170                      "Failed to open socket: %s",
00171                      _dbus_strerror (errno));
00172       return FALSE;
00173     }
00174 }
00175 
00186 static dbus_bool_t
00187 _dbus_open_unix_socket (int              *fd,
00188                         DBusError        *error)
00189 {
00190   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00191 }
00192 
00201 dbus_bool_t
00202 _dbus_close_socket (int               fd,
00203                     DBusError        *error)
00204 {
00205   return _dbus_close (fd, error);
00206 }
00207 
00217 int
00218 _dbus_read_socket (int               fd,
00219                    DBusString       *buffer,
00220                    int               count)
00221 {
00222   return _dbus_read (fd, buffer, count);
00223 }
00224 
00235 int
00236 _dbus_write_socket (int               fd,
00237                     const DBusString *buffer,
00238                     int               start,
00239                     int               len)
00240 {
00241 #if HAVE_DECL_MSG_NOSIGNAL
00242   const char *data;
00243   int bytes_written;
00244 
00245   data = _dbus_string_get_const_data_len (buffer, start, len);
00246 
00247  again:
00248 
00249   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00250 
00251   if (bytes_written < 0 && errno == EINTR)
00252     goto again;
00253 
00254   return bytes_written;
00255 
00256 #else
00257   return _dbus_write (fd, buffer, start, len);
00258 #endif
00259 }
00260 
00273 int
00274 _dbus_read_socket_with_unix_fds (int               fd,
00275                                  DBusString       *buffer,
00276                                  int               count,
00277                                  int              *fds,
00278                                  int              *n_fds) {
00279 #ifndef HAVE_UNIX_FD_PASSING
00280   int r;
00281 
00282   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00283     return r;
00284 
00285   *n_fds = 0;
00286   return r;
00287 
00288 #else
00289   int bytes_read;
00290   int start;
00291   struct msghdr m;
00292   struct iovec iov;
00293 
00294   _dbus_assert (count >= 0);
00295   _dbus_assert (*n_fds >= 0);
00296 
00297   start = _dbus_string_get_length (buffer);
00298 
00299   if (!_dbus_string_lengthen (buffer, count))
00300     {
00301       errno = ENOMEM;
00302       return -1;
00303     }
00304 
00305   _DBUS_ZERO(iov);
00306   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00307   iov.iov_len = count;
00308 
00309   _DBUS_ZERO(m);
00310   m.msg_iov = &iov;
00311   m.msg_iovlen = 1;
00312 
00313   /* Hmm, we have no clue how long the control data will actually be
00314      that is queued for us. The least we can do is assume that the
00315      caller knows. Hence let's make space for the number of fds that
00316      we shall read at max plus the cmsg header. */
00317   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00318 
00319   /* It's probably safe to assume that systems with SCM_RIGHTS also
00320      know alloca() */
00321   m.msg_control = alloca(m.msg_controllen);
00322   memset(m.msg_control, 0, m.msg_controllen);
00323 
00324   /* Do not include the padding at the end when we tell the kernel
00325    * how much we're willing to receive. This avoids getting
00326    * the padding filled with additional fds that we weren't expecting,
00327    * if a (potentially malicious) sender included them. (fd.o #83622) */
00328   m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
00329 
00330  again:
00331 
00332   bytes_read = recvmsg(fd, &m, 0
00333 #ifdef MSG_CMSG_CLOEXEC
00334                        |MSG_CMSG_CLOEXEC
00335 #endif
00336                        );
00337 
00338   if (bytes_read < 0)
00339     {
00340       if (errno == EINTR)
00341         goto again;
00342       else
00343         {
00344           /* put length back (note that this doesn't actually realloc anything) */
00345           _dbus_string_set_length (buffer, start);
00346           return -1;
00347         }
00348     }
00349   else
00350     {
00351       struct cmsghdr *cm;
00352       dbus_bool_t found = FALSE;
00353 
00354       if (m.msg_flags & MSG_CTRUNC)
00355         {
00356           /* Hmm, apparently the control data was truncated. The bad
00357              thing is that we might have completely lost a couple of fds
00358              without chance to recover them. Hence let's treat this as a
00359              serious error. */
00360 
00361           errno = ENOSPC;
00362           _dbus_string_set_length (buffer, start);
00363           return -1;
00364         }
00365 
00366       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00367         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00368           {
00369             size_t i;
00370             int *payload = (int *) CMSG_DATA (cm);
00371             size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
00372             size_t payload_len_fds = payload_len_bytes / sizeof (int);
00373             size_t fds_to_use;
00374 
00375             /* Every non-negative int fits in a size_t without truncation,
00376              * and we already know that *n_fds is non-negative, so
00377              * casting (size_t) *n_fds is OK */
00378             _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
00379 
00380             if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
00381               {
00382                 /* The fds in the payload will fit in our buffer */
00383                 fds_to_use = payload_len_fds;
00384               }
00385             else
00386               {
00387                 /* Too many fds in the payload. This shouldn't happen
00388                  * any more because we're setting m.msg_controllen to
00389                  * the exact number we can accept, but be safe and
00390                  * truncate. */
00391                 fds_to_use = (size_t) *n_fds;
00392 
00393                 /* Close the excess fds to avoid DoS: if they stayed open,
00394                  * someone could send us an extra fd per message
00395                  * and we'd eventually run out. */
00396                 for (i = fds_to_use; i < payload_len_fds; i++)
00397                   {
00398                     close (payload[i]);
00399                   }
00400               }
00401 
00402             memcpy (fds, payload, fds_to_use * sizeof (int));
00403             found = TRUE;
00404             /* This cannot overflow because we have chosen fds_to_use
00405              * to be <= *n_fds */
00406             *n_fds = (int) fds_to_use;
00407 
00408             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00409                worked, hence we need to go through this list and set
00410                CLOEXEC everywhere in any case */
00411             for (i = 0; i < fds_to_use; i++)
00412               _dbus_fd_set_close_on_exec(fds[i]);
00413 
00414             break;
00415           }
00416 
00417       if (!found)
00418         *n_fds = 0;
00419 
00420       /* put length back (doesn't actually realloc) */
00421       _dbus_string_set_length (buffer, start + bytes_read);
00422 
00423 #if 0
00424       if (bytes_read > 0)
00425         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00426 #endif
00427 
00428       return bytes_read;
00429     }
00430 #endif
00431 }
00432 
00433 int
00434 _dbus_write_socket_with_unix_fds(int               fd,
00435                                  const DBusString *buffer,
00436                                  int               start,
00437                                  int               len,
00438                                  const int        *fds,
00439                                  int               n_fds) {
00440 
00441 #ifndef HAVE_UNIX_FD_PASSING
00442 
00443   if (n_fds > 0) {
00444     errno = ENOTSUP;
00445     return -1;
00446   }
00447 
00448   return _dbus_write_socket(fd, buffer, start, len);
00449 #else
00450   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00451 #endif
00452 }
00453 
00454 int
00455 _dbus_write_socket_with_unix_fds_two(int               fd,
00456                                      const DBusString *buffer1,
00457                                      int               start1,
00458                                      int               len1,
00459                                      const DBusString *buffer2,
00460                                      int               start2,
00461                                      int               len2,
00462                                      const int        *fds,
00463                                      int               n_fds) {
00464 
00465 #ifndef HAVE_UNIX_FD_PASSING
00466 
00467   if (n_fds > 0) {
00468     errno = ENOTSUP;
00469     return -1;
00470   }
00471 
00472   return _dbus_write_socket_two(fd,
00473                                 buffer1, start1, len1,
00474                                 buffer2, start2, len2);
00475 #else
00476 
00477   struct msghdr m;
00478   struct cmsghdr *cm;
00479   struct iovec iov[2];
00480   int bytes_written;
00481 
00482   _dbus_assert (len1 >= 0);
00483   _dbus_assert (len2 >= 0);
00484   _dbus_assert (n_fds >= 0);
00485 
00486   _DBUS_ZERO(iov);
00487   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00488   iov[0].iov_len = len1;
00489 
00490   if (buffer2)
00491     {
00492       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00493       iov[1].iov_len = len2;
00494     }
00495 
00496   _DBUS_ZERO(m);
00497   m.msg_iov = iov;
00498   m.msg_iovlen = buffer2 ? 2 : 1;
00499 
00500   if (n_fds > 0)
00501     {
00502       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00503       m.msg_control = alloca(m.msg_controllen);
00504       memset(m.msg_control, 0, m.msg_controllen);
00505 
00506       cm = CMSG_FIRSTHDR(&m);
00507       cm->cmsg_level = SOL_SOCKET;
00508       cm->cmsg_type = SCM_RIGHTS;
00509       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00510       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00511     }
00512 
00513  again:
00514 
00515   bytes_written = sendmsg (fd, &m, 0
00516 #if HAVE_DECL_MSG_NOSIGNAL
00517                            |MSG_NOSIGNAL
00518 #endif
00519                            );
00520 
00521   if (bytes_written < 0 && errno == EINTR)
00522     goto again;
00523 
00524 #if 0
00525   if (bytes_written > 0)
00526     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00527 #endif
00528 
00529   return bytes_written;
00530 #endif
00531 }
00532 
00546 int
00547 _dbus_write_socket_two (int               fd,
00548                         const DBusString *buffer1,
00549                         int               start1,
00550                         int               len1,
00551                         const DBusString *buffer2,
00552                         int               start2,
00553                         int               len2)
00554 {
00555 #if HAVE_DECL_MSG_NOSIGNAL
00556   struct iovec vectors[2];
00557   const char *data1;
00558   const char *data2;
00559   int bytes_written;
00560   struct msghdr m;
00561 
00562   _dbus_assert (buffer1 != NULL);
00563   _dbus_assert (start1 >= 0);
00564   _dbus_assert (start2 >= 0);
00565   _dbus_assert (len1 >= 0);
00566   _dbus_assert (len2 >= 0);
00567 
00568   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00569 
00570   if (buffer2 != NULL)
00571     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00572   else
00573     {
00574       data2 = NULL;
00575       start2 = 0;
00576       len2 = 0;
00577     }
00578 
00579   vectors[0].iov_base = (char*) data1;
00580   vectors[0].iov_len = len1;
00581   vectors[1].iov_base = (char*) data2;
00582   vectors[1].iov_len = len2;
00583 
00584   _DBUS_ZERO(m);
00585   m.msg_iov = vectors;
00586   m.msg_iovlen = data2 ? 2 : 1;
00587 
00588  again:
00589 
00590   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00591 
00592   if (bytes_written < 0 && errno == EINTR)
00593     goto again;
00594 
00595   return bytes_written;
00596 
00597 #else
00598   return _dbus_write_two (fd, buffer1, start1, len1,
00599                           buffer2, start2, len2);
00600 #endif
00601 }
00602 
00603 dbus_bool_t
00604 _dbus_socket_is_invalid (int fd)
00605 {
00606     return fd < 0 ? TRUE : FALSE;
00607 }
00608 
00625 int
00626 _dbus_read (int               fd,
00627             DBusString       *buffer,
00628             int               count)
00629 {
00630   int bytes_read;
00631   int start;
00632   char *data;
00633 
00634   _dbus_assert (count >= 0);
00635 
00636   start = _dbus_string_get_length (buffer);
00637 
00638   if (!_dbus_string_lengthen (buffer, count))
00639     {
00640       errno = ENOMEM;
00641       return -1;
00642     }
00643 
00644   data = _dbus_string_get_data_len (buffer, start, count);
00645 
00646  again:
00647 
00648   bytes_read = read (fd, data, count);
00649 
00650   if (bytes_read < 0)
00651     {
00652       if (errno == EINTR)
00653         goto again;
00654       else
00655         {
00656           /* put length back (note that this doesn't actually realloc anything) */
00657           _dbus_string_set_length (buffer, start);
00658           return -1;
00659         }
00660     }
00661   else
00662     {
00663       /* put length back (doesn't actually realloc) */
00664       _dbus_string_set_length (buffer, start + bytes_read);
00665 
00666 #if 0
00667       if (bytes_read > 0)
00668         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00669 #endif
00670 
00671       return bytes_read;
00672     }
00673 }
00674 
00685 int
00686 _dbus_write (int               fd,
00687              const DBusString *buffer,
00688              int               start,
00689              int               len)
00690 {
00691   const char *data;
00692   int bytes_written;
00693 
00694   data = _dbus_string_get_const_data_len (buffer, start, len);
00695 
00696  again:
00697 
00698   bytes_written = write (fd, data, len);
00699 
00700   if (bytes_written < 0 && errno == EINTR)
00701     goto again;
00702 
00703 #if 0
00704   if (bytes_written > 0)
00705     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00706 #endif
00707 
00708   return bytes_written;
00709 }
00710 
00731 int
00732 _dbus_write_two (int               fd,
00733                  const DBusString *buffer1,
00734                  int               start1,
00735                  int               len1,
00736                  const DBusString *buffer2,
00737                  int               start2,
00738                  int               len2)
00739 {
00740   _dbus_assert (buffer1 != NULL);
00741   _dbus_assert (start1 >= 0);
00742   _dbus_assert (start2 >= 0);
00743   _dbus_assert (len1 >= 0);
00744   _dbus_assert (len2 >= 0);
00745 
00746 #ifdef HAVE_WRITEV
00747   {
00748     struct iovec vectors[2];
00749     const char *data1;
00750     const char *data2;
00751     int bytes_written;
00752 
00753     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00754 
00755     if (buffer2 != NULL)
00756       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00757     else
00758       {
00759         data2 = NULL;
00760         start2 = 0;
00761         len2 = 0;
00762       }
00763 
00764     vectors[0].iov_base = (char*) data1;
00765     vectors[0].iov_len = len1;
00766     vectors[1].iov_base = (char*) data2;
00767     vectors[1].iov_len = len2;
00768 
00769   again:
00770 
00771     bytes_written = writev (fd,
00772                             vectors,
00773                             data2 ? 2 : 1);
00774 
00775     if (bytes_written < 0 && errno == EINTR)
00776       goto again;
00777 
00778     return bytes_written;
00779   }
00780 #else /* HAVE_WRITEV */
00781   {
00782     int ret1, ret2;
00783 
00784     ret1 = _dbus_write (fd, buffer1, start1, len1);
00785     if (ret1 == len1 && buffer2 != NULL)
00786       {
00787         ret2 = _dbus_write (fd, buffer2, start2, len2);
00788         if (ret2 < 0)
00789           ret2 = 0; /* we can't report an error as the first write was OK */
00790 
00791         return ret1 + ret2;
00792       }
00793     else
00794       return ret1;
00795   }
00796 #endif /* !HAVE_WRITEV */
00797 }
00798 
00799 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00800 
00830 int
00831 _dbus_connect_unix_socket (const char     *path,
00832                            dbus_bool_t     abstract,
00833                            DBusError      *error)
00834 {
00835   int fd;
00836   size_t path_len;
00837   struct sockaddr_un addr;
00838 
00839   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00840 
00841   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00842                  path, abstract);
00843 
00844 
00845   if (!_dbus_open_unix_socket (&fd, error))
00846     {
00847       _DBUS_ASSERT_ERROR_IS_SET(error);
00848       return -1;
00849     }
00850   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00851 
00852   _DBUS_ZERO (addr);
00853   addr.sun_family = AF_UNIX;
00854   path_len = strlen (path);
00855 
00856   if (abstract)
00857     {
00858 #ifdef HAVE_ABSTRACT_SOCKETS
00859       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00860       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00861 
00862       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00863         {
00864           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00865                       "Abstract socket name too long\n");
00866           _dbus_close (fd, NULL);
00867           return -1;
00868         }
00869 
00870       strncpy (&addr.sun_path[1], path, path_len);
00871       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00872 #else /* HAVE_ABSTRACT_SOCKETS */
00873       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00874                       "Operating system does not support abstract socket namespace\n");
00875       _dbus_close (fd, NULL);
00876       return -1;
00877 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00878     }
00879   else
00880     {
00881       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00882         {
00883           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00884                       "Socket name too long\n");
00885           _dbus_close (fd, NULL);
00886           return -1;
00887         }
00888 
00889       strncpy (addr.sun_path, path, path_len);
00890     }
00891 
00892   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00893     {
00894       dbus_set_error (error,
00895                       _dbus_error_from_errno (errno),
00896                       "Failed to connect to socket %s: %s",
00897                       path, _dbus_strerror (errno));
00898 
00899       _dbus_close (fd, NULL);
00900       return -1;
00901     }
00902 
00903   if (!_dbus_set_fd_nonblocking (fd, error))
00904     {
00905       _DBUS_ASSERT_ERROR_IS_SET (error);
00906 
00907       _dbus_close (fd, NULL);
00908       return -1;
00909     }
00910 
00911   return fd;
00912 }
00913 
00926 int
00927 _dbus_connect_exec (const char     *path,
00928                     char *const    argv[],
00929                     DBusError      *error)
00930 {
00931   int fds[2];
00932   pid_t pid;
00933   int retval;
00934   dbus_bool_t cloexec_done = 0;
00935 
00936   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00937 
00938   _dbus_verbose ("connecting to process %s\n", path);
00939 
00940 #ifdef SOCK_CLOEXEC
00941   retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
00942   cloexec_done = (retval >= 0);
00943 
00944   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
00945 #endif
00946     {
00947       retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
00948     }
00949 
00950   if (retval < 0)
00951     {
00952       dbus_set_error (error,
00953                       _dbus_error_from_errno (errno),
00954                       "Failed to create socket pair: %s",
00955                       _dbus_strerror (errno));
00956       return -1;
00957     }
00958 
00959   if (!cloexec_done)
00960     {
00961       _dbus_fd_set_close_on_exec (fds[0]);
00962       _dbus_fd_set_close_on_exec (fds[1]);
00963     }
00964 
00965   pid = fork ();
00966   if (pid < 0)
00967     {
00968       dbus_set_error (error,
00969                       _dbus_error_from_errno (errno),
00970                       "Failed to fork() to call %s: %s",
00971                       path, _dbus_strerror (errno));
00972       close (fds[0]);
00973       close (fds[1]);
00974       return -1;
00975     }
00976 
00977   if (pid == 0)
00978     {
00979       /* child */
00980       close (fds[0]);
00981 
00982       dup2 (fds[1], STDIN_FILENO);
00983       dup2 (fds[1], STDOUT_FILENO);
00984 
00985       if (fds[1] != STDIN_FILENO &&
00986           fds[1] != STDOUT_FILENO)
00987         close (fds[1]);
00988 
00989       /* Inherit STDERR and the controlling terminal from the
00990          parent */
00991 
00992       _dbus_close_all ();
00993 
00994       execvp (path, argv);
00995 
00996       fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
00997 
00998       _exit(1);
00999     }
01000 
01001   /* parent */
01002   close (fds[1]);
01003 
01004   if (!_dbus_set_fd_nonblocking (fds[0], error))
01005     {
01006       _DBUS_ASSERT_ERROR_IS_SET (error);
01007 
01008       close (fds[0]);
01009       return -1;
01010     }
01011 
01012   return fds[0];
01013 }
01014 
01032 int
01033 _dbus_listen_unix_socket (const char     *path,
01034                           dbus_bool_t     abstract,
01035                           DBusError      *error)
01036 {
01037   int listen_fd;
01038   struct sockaddr_un addr;
01039   size_t path_len;
01040 
01041   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01042 
01043   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
01044                  path, abstract);
01045 
01046   if (!_dbus_open_unix_socket (&listen_fd, error))
01047     {
01048       _DBUS_ASSERT_ERROR_IS_SET(error);
01049       return -1;
01050     }
01051   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01052 
01053   _DBUS_ZERO (addr);
01054   addr.sun_family = AF_UNIX;
01055   path_len = strlen (path);
01056 
01057   if (abstract)
01058     {
01059 #ifdef HAVE_ABSTRACT_SOCKETS
01060       /* remember that abstract names aren't nul-terminated so we rely
01061        * on sun_path being filled in with zeroes above.
01062        */
01063       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
01064       path_len++; /* Account for the extra nul byte added to the start of sun_path */
01065 
01066       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01067         {
01068           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01069                       "Abstract socket name too long\n");
01070           _dbus_close (listen_fd, NULL);
01071           return -1;
01072         }
01073 
01074       strncpy (&addr.sun_path[1], path, path_len);
01075       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
01076 #else /* HAVE_ABSTRACT_SOCKETS */
01077       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01078                       "Operating system does not support abstract socket namespace\n");
01079       _dbus_close (listen_fd, NULL);
01080       return -1;
01081 #endif /* ! HAVE_ABSTRACT_SOCKETS */
01082     }
01083   else
01084     {
01085       /* Discussed security implications of this with Nalin,
01086        * and we couldn't think of where it would kick our ass, but
01087        * it still seems a bit sucky. It also has non-security suckage;
01088        * really we'd prefer to exit if the socket is already in use.
01089        * But there doesn't seem to be a good way to do this.
01090        *
01091        * Just to be extra careful, I threw in the stat() - clearly
01092        * the stat() can't *fix* any security issue, but it at least
01093        * avoids inadvertent/accidental data loss.
01094        */
01095       {
01096         struct stat sb;
01097 
01098         if (stat (path, &sb) == 0 &&
01099             S_ISSOCK (sb.st_mode))
01100           unlink (path);
01101       }
01102 
01103       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01104         {
01105           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01106                       "Abstract socket name too long\n");
01107           _dbus_close (listen_fd, NULL);
01108           return -1;
01109         }
01110 
01111       strncpy (addr.sun_path, path, path_len);
01112     }
01113 
01114   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01115     {
01116       dbus_set_error (error, _dbus_error_from_errno (errno),
01117                       "Failed to bind socket \"%s\": %s",
01118                       path, _dbus_strerror (errno));
01119       _dbus_close (listen_fd, NULL);
01120       return -1;
01121     }
01122 
01123   if (listen (listen_fd, 30 /* backlog */) < 0)
01124     {
01125       dbus_set_error (error, _dbus_error_from_errno (errno),
01126                       "Failed to listen on socket \"%s\": %s",
01127                       path, _dbus_strerror (errno));
01128       _dbus_close (listen_fd, NULL);
01129       return -1;
01130     }
01131 
01132   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01133     {
01134       _DBUS_ASSERT_ERROR_IS_SET (error);
01135       _dbus_close (listen_fd, NULL);
01136       return -1;
01137     }
01138 
01139   /* Try opening up the permissions, but if we can't, just go ahead
01140    * and continue, maybe it will be good enough.
01141    */
01142   if (!abstract && chmod (path, 0777) < 0)
01143     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01144                 path);
01145 
01146   return listen_fd;
01147 }
01148 
01159 int
01160 _dbus_listen_systemd_sockets (int       **fds,
01161                               DBusError *error)
01162 {
01163   int r, n;
01164   unsigned fd;
01165   int *new_fds;
01166 
01167   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01168 
01169   n = sd_listen_fds (TRUE);
01170   if (n < 0)
01171     {
01172       dbus_set_error (error, _dbus_error_from_errno (-n),
01173                       "Failed to acquire systemd socket: %s",
01174                       _dbus_strerror (-n));
01175       return -1;
01176     }
01177 
01178   if (n <= 0)
01179     {
01180       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01181                       "No socket received.");
01182       return -1;
01183     }
01184 
01185   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01186     {
01187       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01188       if (r < 0)
01189         {
01190           dbus_set_error (error, _dbus_error_from_errno (-r),
01191                           "Failed to verify systemd socket type: %s",
01192                           _dbus_strerror (-r));
01193           return -1;
01194         }
01195 
01196       if (!r)
01197         {
01198           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01199                           "Passed socket has wrong type.");
01200           return -1;
01201         }
01202     }
01203 
01204   /* OK, the file descriptors are all good, so let's take posession of
01205      them then. */
01206 
01207   new_fds = dbus_new (int, n);
01208   if (!new_fds)
01209     {
01210       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01211                       "Failed to allocate file handle array.");
01212       goto fail;
01213     }
01214 
01215   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01216     {
01217       if (!_dbus_set_fd_nonblocking (fd, error))
01218         {
01219           _DBUS_ASSERT_ERROR_IS_SET (error);
01220           goto fail;
01221         }
01222 
01223       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01224     }
01225 
01226   *fds = new_fds;
01227   return n;
01228 
01229  fail:
01230 
01231   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01232     {
01233       _dbus_close (fd, NULL);
01234     }
01235 
01236   dbus_free (new_fds);
01237   return -1;
01238 }
01239 
01253 int
01254 _dbus_connect_tcp_socket (const char     *host,
01255                           const char     *port,
01256                           const char     *family,
01257                           DBusError      *error)
01258 {
01259     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01260 }
01261 
01262 int
01263 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01264                                      const char     *port,
01265                                      const char     *family,
01266                                      const char     *noncefile,
01267                                      DBusError      *error)
01268 {
01269   int saved_errno = 0;
01270   int fd = -1, res;
01271   struct addrinfo hints;
01272   struct addrinfo *ai, *tmp;
01273 
01274   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01275 
01276   _DBUS_ZERO (hints);
01277 
01278   if (!family)
01279     hints.ai_family = AF_UNSPEC;
01280   else if (!strcmp(family, "ipv4"))
01281     hints.ai_family = AF_INET;
01282   else if (!strcmp(family, "ipv6"))
01283     hints.ai_family = AF_INET6;
01284   else
01285     {
01286       dbus_set_error (error,
01287                       DBUS_ERROR_BAD_ADDRESS,
01288                       "Unknown address family %s", family);
01289       return -1;
01290     }
01291   hints.ai_protocol = IPPROTO_TCP;
01292   hints.ai_socktype = SOCK_STREAM;
01293   hints.ai_flags = AI_ADDRCONFIG;
01294 
01295   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01296     {
01297       dbus_set_error (error,
01298                       _dbus_error_from_errno (errno),
01299                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01300                       host, port, gai_strerror(res), res);
01301       return -1;
01302     }
01303 
01304   tmp = ai;
01305   while (tmp)
01306     {
01307       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01308         {
01309           freeaddrinfo(ai);
01310           _DBUS_ASSERT_ERROR_IS_SET(error);
01311           return -1;
01312         }
01313       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01314 
01315       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01316         {
01317           saved_errno = errno;
01318           _dbus_close(fd, NULL);
01319           fd = -1;
01320           tmp = tmp->ai_next;
01321           continue;
01322         }
01323 
01324       break;
01325     }
01326   freeaddrinfo(ai);
01327 
01328   if (fd == -1)
01329     {
01330       dbus_set_error (error,
01331                       _dbus_error_from_errno (saved_errno),
01332                       "Failed to connect to socket \"%s:%s\" %s",
01333                       host, port, _dbus_strerror(saved_errno));
01334       return -1;
01335     }
01336 
01337   if (noncefile != NULL)
01338     {
01339       DBusString noncefileStr;
01340       dbus_bool_t ret;
01341       _dbus_string_init_const (&noncefileStr, noncefile);
01342       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01343       _dbus_string_free (&noncefileStr);
01344 
01345       if (!ret)
01346     {
01347       _dbus_close (fd, NULL);
01348           return -1;
01349         }
01350     }
01351 
01352   if (!_dbus_set_fd_nonblocking (fd, error))
01353     {
01354       _dbus_close (fd, NULL);
01355       return -1;
01356     }
01357 
01358   return fd;
01359 }
01360 
01377 int
01378 _dbus_listen_tcp_socket (const char     *host,
01379                          const char     *port,
01380                          const char     *family,
01381                          DBusString     *retport,
01382                          int           **fds_p,
01383                          DBusError      *error)
01384 {
01385   int saved_errno;
01386   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01387   struct addrinfo hints;
01388   struct addrinfo *ai, *tmp;
01389   unsigned int reuseaddr;
01390 
01391   *fds_p = NULL;
01392   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01393 
01394   _DBUS_ZERO (hints);
01395 
01396   if (!family)
01397     hints.ai_family = AF_UNSPEC;
01398   else if (!strcmp(family, "ipv4"))
01399     hints.ai_family = AF_INET;
01400   else if (!strcmp(family, "ipv6"))
01401     hints.ai_family = AF_INET6;
01402   else
01403     {
01404       dbus_set_error (error,
01405                       DBUS_ERROR_BAD_ADDRESS,
01406                       "Unknown address family %s", family);
01407       return -1;
01408     }
01409 
01410   hints.ai_protocol = IPPROTO_TCP;
01411   hints.ai_socktype = SOCK_STREAM;
01412   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01413 
01414  redo_lookup_with_port:
01415   ai = NULL;
01416   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01417     {
01418       dbus_set_error (error,
01419                       _dbus_error_from_errno (errno),
01420                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01421                       host ? host : "*", port, gai_strerror(res), res);
01422       goto failed;
01423     }
01424 
01425   tmp = ai;
01426   while (tmp)
01427     {
01428       int fd = -1, *newlisten_fd;
01429       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01430         {
01431           _DBUS_ASSERT_ERROR_IS_SET(error);
01432           goto failed;
01433         }
01434       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01435 
01436       reuseaddr = 1;
01437       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01438         {
01439           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01440                       host ? host : "*", port, _dbus_strerror (errno));
01441         }
01442 
01443       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01444         {
01445           saved_errno = errno;
01446           _dbus_close(fd, NULL);
01447           if (saved_errno == EADDRINUSE)
01448             {
01449               /* Depending on kernel policy, it may or may not
01450                  be neccessary to bind to both IPv4 & 6 addresses
01451                  so ignore EADDRINUSE here */
01452               tmp = tmp->ai_next;
01453               continue;
01454             }
01455           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01456                           "Failed to bind socket \"%s:%s\": %s",
01457                           host ? host : "*", port, _dbus_strerror (saved_errno));
01458           goto failed;
01459         }
01460 
01461       if (listen (fd, 30 /* backlog */) < 0)
01462         {
01463           saved_errno = errno;
01464           _dbus_close (fd, NULL);
01465           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01466                           "Failed to listen on socket \"%s:%s\": %s",
01467                           host ? host : "*", port, _dbus_strerror (saved_errno));
01468           goto failed;
01469         }
01470 
01471       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01472       if (!newlisten_fd)
01473         {
01474           saved_errno = errno;
01475           _dbus_close (fd, NULL);
01476           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01477                           "Failed to allocate file handle array: %s",
01478                           _dbus_strerror (saved_errno));
01479           goto failed;
01480         }
01481       listen_fd = newlisten_fd;
01482       listen_fd[nlisten_fd] = fd;
01483       nlisten_fd++;
01484 
01485       if (!_dbus_string_get_length(retport))
01486         {
01487           /* If the user didn't specify a port, or used 0, then
01488              the kernel chooses a port. After the first address
01489              is bound to, we need to force all remaining addresses
01490              to use the same port */
01491           if (!port || !strcmp(port, "0"))
01492             {
01493               int result;
01494               struct sockaddr_storage addr;
01495               socklen_t addrlen;
01496               char portbuf[50];
01497 
01498               addrlen = sizeof(addr);
01499               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01500 
01501               if (result == -1 ||
01502                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01503                                       portbuf, sizeof(portbuf),
01504                                       NI_NUMERICHOST)) != 0)
01505                 {
01506                   dbus_set_error (error, _dbus_error_from_errno (errno),
01507                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01508                                   host ? host : "*", port, gai_strerror(res), res);
01509                   goto failed;
01510                 }
01511               if (!_dbus_string_append(retport, portbuf))
01512                 {
01513                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01514                   goto failed;
01515                 }
01516 
01517               /* Release current address list & redo lookup */
01518               port = _dbus_string_get_const_data(retport);
01519               freeaddrinfo(ai);
01520               goto redo_lookup_with_port;
01521             }
01522           else
01523             {
01524               if (!_dbus_string_append(retport, port))
01525                 {
01526                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01527                     goto failed;
01528                 }
01529             }
01530         }
01531 
01532       tmp = tmp->ai_next;
01533     }
01534   freeaddrinfo(ai);
01535   ai = NULL;
01536 
01537   if (!nlisten_fd)
01538     {
01539       errno = EADDRINUSE;
01540       dbus_set_error (error, _dbus_error_from_errno (errno),
01541                       "Failed to bind socket \"%s:%s\": %s",
01542                       host ? host : "*", port, _dbus_strerror (errno));
01543       goto failed;
01544     }
01545 
01546   for (i = 0 ; i < nlisten_fd ; i++)
01547     {
01548       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01549         {
01550           goto failed;
01551         }
01552     }
01553 
01554   *fds_p = listen_fd;
01555 
01556   return nlisten_fd;
01557 
01558  failed:
01559   if (ai)
01560     freeaddrinfo(ai);
01561   for (i = 0 ; i < nlisten_fd ; i++)
01562     _dbus_close(listen_fd[i], NULL);
01563   dbus_free(listen_fd);
01564   return -1;
01565 }
01566 
01567 static dbus_bool_t
01568 write_credentials_byte (int             server_fd,
01569                         DBusError      *error)
01570 {
01571   int bytes_written;
01572   char buf[1] = { '\0' };
01573 #if defined(HAVE_CMSGCRED)
01574   union {
01575           struct cmsghdr hdr;
01576           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01577   } cmsg;
01578   struct iovec iov;
01579   struct msghdr msg;
01580   iov.iov_base = buf;
01581   iov.iov_len = 1;
01582 
01583   _DBUS_ZERO(msg);
01584   msg.msg_iov = &iov;
01585   msg.msg_iovlen = 1;
01586 
01587   msg.msg_control = (caddr_t) &cmsg;
01588   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01589   _DBUS_ZERO(cmsg);
01590   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01591   cmsg.hdr.cmsg_level = SOL_SOCKET;
01592   cmsg.hdr.cmsg_type = SCM_CREDS;
01593 #endif
01594 
01595   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01596 
01597  again:
01598 
01599 #if defined(HAVE_CMSGCRED)
01600   bytes_written = sendmsg (server_fd, &msg, 0
01601 #if HAVE_DECL_MSG_NOSIGNAL
01602                            |MSG_NOSIGNAL
01603 #endif
01604                            );
01605 
01606   /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
01607    * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
01608    * only allows that on AF_UNIX. Try just doing a send() instead. */
01609   if (bytes_written < 0 && errno == EINVAL)
01610 #endif
01611     {
01612       bytes_written = send (server_fd, buf, 1, 0
01613 #if HAVE_DECL_MSG_NOSIGNAL
01614                             |MSG_NOSIGNAL
01615 #endif
01616                             );
01617     }
01618 
01619   if (bytes_written < 0 && errno == EINTR)
01620     goto again;
01621 
01622   if (bytes_written < 0)
01623     {
01624       dbus_set_error (error, _dbus_error_from_errno (errno),
01625                       "Failed to write credentials byte: %s",
01626                      _dbus_strerror (errno));
01627       return FALSE;
01628     }
01629   else if (bytes_written == 0)
01630     {
01631       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01632                       "wrote zero bytes writing credentials byte");
01633       return FALSE;
01634     }
01635   else
01636     {
01637       _dbus_assert (bytes_written == 1);
01638       _dbus_verbose ("wrote credentials byte\n");
01639       return TRUE;
01640     }
01641 }
01642 
01664 dbus_bool_t
01665 _dbus_read_credentials_socket  (int              client_fd,
01666                                 DBusCredentials *credentials,
01667                                 DBusError       *error)
01668 {
01669   struct msghdr msg;
01670   struct iovec iov;
01671   char buf;
01672   dbus_uid_t uid_read;
01673   dbus_pid_t pid_read;
01674   int bytes_read;
01675 
01676 #ifdef HAVE_CMSGCRED
01677   union {
01678     struct cmsghdr hdr;
01679     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01680   } cmsg;
01681 #endif
01682 
01683   uid_read = DBUS_UID_UNSET;
01684   pid_read = DBUS_PID_UNSET;
01685 
01686   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01687 
01688   /* The POSIX spec certainly doesn't promise this, but
01689    * we need these assertions to fail as soon as we're wrong about
01690    * it so we can do the porting fixups
01691    */
01692   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01693   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01694   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01695 
01696   _dbus_credentials_clear (credentials);
01697 
01698   iov.iov_base = &buf;
01699   iov.iov_len = 1;
01700 
01701   _DBUS_ZERO(msg);
01702   msg.msg_iov = &iov;
01703   msg.msg_iovlen = 1;
01704 
01705 #if defined(HAVE_CMSGCRED)
01706   _DBUS_ZERO(cmsg);
01707   msg.msg_control = (caddr_t) &cmsg;
01708   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01709 #endif
01710 
01711  again:
01712   bytes_read = recvmsg (client_fd, &msg, 0);
01713 
01714   if (bytes_read < 0)
01715     {
01716       if (errno == EINTR)
01717         goto again;
01718 
01719       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01720        * normally only call read_credentials if the socket was ready
01721        * for reading
01722        */
01723 
01724       dbus_set_error (error, _dbus_error_from_errno (errno),
01725                       "Failed to read credentials byte: %s",
01726                       _dbus_strerror (errno));
01727       return FALSE;
01728     }
01729   else if (bytes_read == 0)
01730     {
01731       /* this should not happen unless we are using recvmsg wrong,
01732        * so is essentially here for paranoia
01733        */
01734       dbus_set_error (error, DBUS_ERROR_FAILED,
01735                       "Failed to read credentials byte (zero-length read)");
01736       return FALSE;
01737     }
01738   else if (buf != '\0')
01739     {
01740       dbus_set_error (error, DBUS_ERROR_FAILED,
01741                       "Credentials byte was not nul");
01742       return FALSE;
01743     }
01744 
01745   _dbus_verbose ("read credentials byte\n");
01746 
01747   {
01748 #ifdef SO_PEERCRED
01749     /* Supported by at least Linux and OpenBSD, with minor differences.
01750      *
01751      * This mechanism passes the process ID through and does not require
01752      * the peer's cooperation, so we prefer it over all others. Notably,
01753      * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
01754      * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
01755      * because this is much less fragile.
01756      */
01757 #ifdef __OpenBSD__
01758     struct sockpeercred cr;
01759 #else
01760     struct ucred cr;
01761 #endif
01762     int cr_len = sizeof (cr);
01763 
01764     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01765         cr_len == sizeof (cr))
01766       {
01767         pid_read = cr.pid;
01768         uid_read = cr.uid;
01769       }
01770     else
01771       {
01772         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01773                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01774       }
01775 #elif defined(HAVE_CMSGCRED)
01776     /* We only check for HAVE_CMSGCRED, but we're really assuming that the
01777      * presence of that struct implies SCM_CREDS. Supported by at least
01778      * FreeBSD and DragonflyBSD.
01779      *
01780      * This mechanism requires the peer to help us (it has to send us a
01781      * SCM_CREDS message) but it does pass the process ID through,
01782      * which makes it better than getpeereid().
01783      */
01784     struct cmsgcred *cred;
01785     struct cmsghdr *cmsgp;
01786 
01787     for (cmsgp = CMSG_FIRSTHDR (&msg);
01788          cmsgp != NULL;
01789          cmsgp = CMSG_NXTHDR (&msg, cmsgp))
01790       {
01791         if (cmsgp->cmsg_type == SCM_CREDS &&
01792             cmsgp->cmsg_level == SOL_SOCKET &&
01793             cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
01794           {
01795             cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
01796             pid_read = cred->cmcred_pid;
01797             uid_read = cred->cmcred_euid;
01798             break;
01799           }
01800       }
01801 
01802 #elif defined(HAVE_GETPEERUCRED)
01803     /* Supported in at least Solaris >= 10. It should probably be higher
01804      * up this list, because it carries the pid and we use this code path
01805      * for audit data. */
01806     ucred_t * ucred = NULL;
01807     if (getpeerucred (client_fd, &ucred) == 0)
01808       {
01809         pid_read = ucred_getpid (ucred);
01810         uid_read = ucred_geteuid (ucred);
01811 #ifdef HAVE_ADT
01812         /* generate audit session data based on socket ucred */
01813         adt_session_data_t *adth = NULL;
01814         adt_export_data_t *data = NULL;
01815         size_t size = 0;
01816         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01817           {
01818             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01819           }
01820         else
01821           {
01822             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01823               {
01824                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01825               }
01826             else
01827               {
01828                 size = adt_export_session_data (adth, &data);
01829                 if (size <= 0)
01830                   {
01831                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01832                   }
01833                 else
01834                   {
01835                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01836                     free (data);
01837                   }
01838               }
01839             (void) adt_end_session (adth);
01840           }
01841 #endif /* HAVE_ADT */
01842       }
01843     else
01844       {
01845         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01846       }
01847     if (ucred != NULL)
01848       ucred_free (ucred);
01849 
01850     /* ----------------------------------------------------------------
01851      * When adding new mechanisms, please add them above this point
01852      * if they support passing the process ID through, or below if not.
01853      * ---------------------------------------------------------------- */
01854 
01855 #elif defined(HAVE_GETPEEREID)
01856     /* getpeereid() originates from D.J. Bernstein and is fairly
01857      * widely-supported. According to a web search, it might be present in
01858      * any/all of:
01859      *
01860      * - AIX?
01861      * - Blackberry?
01862      * - Cygwin
01863      * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
01864      * - Mac OS X
01865      * - Minix 3.1.8+
01866      * - MirBSD?
01867      * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
01868      * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
01869      * - QNX?
01870      */
01871     uid_t euid;
01872     gid_t egid;
01873     if (getpeereid (client_fd, &euid, &egid) == 0)
01874       {
01875         uid_read = euid;
01876       }
01877     else
01878       {
01879         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01880       }
01881 #else /* no supported mechanism */
01882 
01883 #warning Socket credentials not supported on this Unix OS
01884 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
01885 
01886     /* Please add other operating systems known to support at least one of
01887      * the mechanisms above to this list, keeping alphabetical order.
01888      * Everything not in this list  is best-effort.
01889      */
01890 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
01891     defined(__linux__) || \
01892     defined(__OpenBSD__) || \
01893     defined(__NetBSD__)
01894 # error Credentials passing not working on this OS is a regression!
01895 #endif
01896 
01897     _dbus_verbose ("Socket credentials not supported on this OS\n");
01898 #endif
01899   }
01900 
01901   _dbus_verbose ("Credentials:"
01902                  "  pid "DBUS_PID_FORMAT
01903                  "  uid "DBUS_UID_FORMAT
01904                  "\n",
01905                  pid_read,
01906                  uid_read);
01907 
01908   if (pid_read != DBUS_PID_UNSET)
01909     {
01910       if (!_dbus_credentials_add_pid (credentials, pid_read))
01911         {
01912           _DBUS_SET_OOM (error);
01913           return FALSE;
01914         }
01915     }
01916 
01917   if (uid_read != DBUS_UID_UNSET)
01918     {
01919       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01920         {
01921           _DBUS_SET_OOM (error);
01922           return FALSE;
01923         }
01924     }
01925 
01926   return TRUE;
01927 }
01928 
01946 dbus_bool_t
01947 _dbus_send_credentials_socket  (int              server_fd,
01948                                 DBusError       *error)
01949 {
01950   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01951 
01952   if (write_credentials_byte (server_fd, error))
01953     return TRUE;
01954   else
01955     return FALSE;
01956 }
01957 
01967 int
01968 _dbus_accept  (int listen_fd)
01969 {
01970   int client_fd;
01971   struct sockaddr addr;
01972   socklen_t addrlen;
01973 #ifdef HAVE_ACCEPT4
01974   dbus_bool_t cloexec_done;
01975 #endif
01976 
01977   addrlen = sizeof (addr);
01978 
01979  retry:
01980 
01981 #ifdef HAVE_ACCEPT4
01982   /*
01983    * At compile-time, we assume that if accept4() is available in
01984    * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
01985    * not necessarily true that either is supported by the running kernel.
01986    */
01987   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01988   cloexec_done = client_fd >= 0;
01989 
01990   if (client_fd < 0 && (errno == ENOSYS || errno == EINVAL))
01991 #endif
01992     {
01993       client_fd = accept (listen_fd, &addr, &addrlen);
01994     }
01995 
01996   if (client_fd < 0)
01997     {
01998       if (errno == EINTR)
01999         goto retry;
02000     }
02001 
02002   _dbus_verbose ("client fd %d accepted\n", client_fd);
02003 
02004 #ifdef HAVE_ACCEPT4
02005   if (!cloexec_done)
02006 #endif
02007     {
02008       _dbus_fd_set_close_on_exec(client_fd);
02009     }
02010 
02011   return client_fd;
02012 }
02013 
02022 dbus_bool_t
02023 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
02024 {
02025   const char *directory;
02026   struct stat sb;
02027 
02028   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02029 
02030   directory = _dbus_string_get_const_data (dir);
02031 
02032   if (stat (directory, &sb) < 0)
02033     {
02034       dbus_set_error (error, _dbus_error_from_errno (errno),
02035                       "%s", _dbus_strerror (errno));
02036 
02037       return FALSE;
02038     }
02039 
02040   if (sb.st_uid != geteuid ())
02041     {
02042       dbus_set_error (error, DBUS_ERROR_FAILED,
02043                      "%s directory is owned by user %lu, not %lu",
02044                      directory,
02045                      (unsigned long) sb.st_uid,
02046                      (unsigned long) geteuid ());
02047       return FALSE;
02048     }
02049 
02050   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
02051       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
02052     {
02053       dbus_set_error (error, DBUS_ERROR_FAILED,
02054                      "%s directory is not private to the user", directory);
02055       return FALSE;
02056     }
02057 
02058   return TRUE;
02059 }
02060 
02061 static dbus_bool_t
02062 fill_user_info_from_passwd (struct passwd *p,
02063                             DBusUserInfo  *info,
02064                             DBusError     *error)
02065 {
02066   _dbus_assert (p->pw_name != NULL);
02067   _dbus_assert (p->pw_dir != NULL);
02068 
02069   info->uid = p->pw_uid;
02070   info->primary_gid = p->pw_gid;
02071   info->username = _dbus_strdup (p->pw_name);
02072   info->homedir = _dbus_strdup (p->pw_dir);
02073 
02074   if (info->username == NULL ||
02075       info->homedir == NULL)
02076     {
02077       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02078       return FALSE;
02079     }
02080 
02081   return TRUE;
02082 }
02083 
02084 static dbus_bool_t
02085 fill_user_info (DBusUserInfo       *info,
02086                 dbus_uid_t          uid,
02087                 const DBusString   *username,
02088                 DBusError          *error)
02089 {
02090   const char *username_c;
02091 
02092   /* exactly one of username/uid provided */
02093   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
02094   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
02095 
02096   info->uid = DBUS_UID_UNSET;
02097   info->primary_gid = DBUS_GID_UNSET;
02098   info->group_ids = NULL;
02099   info->n_group_ids = 0;
02100   info->username = NULL;
02101   info->homedir = NULL;
02102 
02103   if (username != NULL)
02104     username_c = _dbus_string_get_const_data (username);
02105   else
02106     username_c = NULL;
02107 
02108   /* For now assuming that the getpwnam() and getpwuid() flavors
02109    * are always symmetrical, if not we have to add more configure
02110    * checks
02111    */
02112 
02113 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02114   {
02115     struct passwd *p;
02116     int result;
02117     size_t buflen;
02118     char *buf;
02119     struct passwd p_str;
02120 
02121     /* retrieve maximum needed size for buf */
02122     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02123 
02124     /* sysconf actually returns a long, but everything else expects size_t,
02125      * so just recast here.
02126      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
02127      */
02128     if ((long) buflen <= 0)
02129       buflen = 1024;
02130 
02131     result = -1;
02132     while (1)
02133       {
02134         buf = dbus_malloc (buflen);
02135         if (buf == NULL)
02136           {
02137             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02138             return FALSE;
02139           }
02140 
02141         p = NULL;
02142 #ifdef HAVE_POSIX_GETPWNAM_R
02143         if (uid != DBUS_UID_UNSET)
02144           result = getpwuid_r (uid, &p_str, buf, buflen,
02145                                &p);
02146         else
02147           result = getpwnam_r (username_c, &p_str, buf, buflen,
02148                                &p);
02149 #else
02150         if (uid != DBUS_UID_UNSET)
02151           p = getpwuid_r (uid, &p_str, buf, buflen);
02152         else
02153           p = getpwnam_r (username_c, &p_str, buf, buflen);
02154         result = 0;
02155 #endif /* !HAVE_POSIX_GETPWNAM_R */
02156         //Try a bigger buffer if ERANGE was returned
02157         if (result == ERANGE && buflen < 512 * 1024)
02158           {
02159             dbus_free (buf);
02160             buflen *= 2;
02161           }
02162         else
02163           {
02164             break;
02165           }
02166       }
02167     if (result == 0 && p == &p_str)
02168       {
02169         if (!fill_user_info_from_passwd (p, info, error))
02170           {
02171             dbus_free (buf);
02172             return FALSE;
02173           }
02174         dbus_free (buf);
02175       }
02176     else
02177       {
02178         dbus_set_error (error, _dbus_error_from_errno (errno),
02179                         "User \"%s\" unknown or no memory to allocate password entry\n",
02180                         username_c ? username_c : "???");
02181         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02182         dbus_free (buf);
02183         return FALSE;
02184       }
02185   }
02186 #else /* ! HAVE_GETPWNAM_R */
02187   {
02188     /* I guess we're screwed on thread safety here */
02189     struct passwd *p;
02190 
02191     if (uid != DBUS_UID_UNSET)
02192       p = getpwuid (uid);
02193     else
02194       p = getpwnam (username_c);
02195 
02196     if (p != NULL)
02197       {
02198         if (!fill_user_info_from_passwd (p, info, error))
02199           {
02200             return FALSE;
02201           }
02202       }
02203     else
02204       {
02205         dbus_set_error (error, _dbus_error_from_errno (errno),
02206                         "User \"%s\" unknown or no memory to allocate password entry\n",
02207                         username_c ? username_c : "???");
02208         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02209         return FALSE;
02210       }
02211   }
02212 #endif  /* ! HAVE_GETPWNAM_R */
02213 
02214   /* Fill this in so we can use it to get groups */
02215   username_c = info->username;
02216 
02217 #ifdef HAVE_GETGROUPLIST
02218   {
02219     gid_t *buf;
02220     int buf_count;
02221     int i;
02222     int initial_buf_count;
02223 
02224     initial_buf_count = 17;
02225     buf_count = initial_buf_count;
02226     buf = dbus_new (gid_t, buf_count);
02227     if (buf == NULL)
02228       {
02229         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02230         goto failed;
02231       }
02232 
02233     if (getgrouplist (username_c,
02234                       info->primary_gid,
02235                       buf, &buf_count) < 0)
02236       {
02237         gid_t *new;
02238         /* Presumed cause of negative return code: buf has insufficient
02239            entries to hold the entire group list. The Linux behavior in this
02240            case is to pass back the actual number of groups in buf_count, but
02241            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02242            So as a hack, try to help out a bit by guessing a larger
02243            number of groups, within reason.. might still fail, of course,
02244            but we can at least print a more informative message.  I looked up
02245            the "right way" to do this by downloading Apple's own source code
02246            for the "id" command, and it turns out that they use an
02247            undocumented library function getgrouplist_2 (!) which is not
02248            declared in any header in /usr/include (!!). That did not seem
02249            like the way to go here.
02250         */
02251         if (buf_count == initial_buf_count)
02252           {
02253             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02254           }
02255         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02256         if (new == NULL)
02257           {
02258             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02259             dbus_free (buf);
02260             goto failed;
02261           }
02262 
02263         buf = new;
02264 
02265         errno = 0;
02266         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02267           {
02268             if (errno == 0)
02269               {
02270                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02271                             username_c, buf_count, buf_count);
02272               }
02273             else
02274               {
02275                 dbus_set_error (error,
02276                                 _dbus_error_from_errno (errno),
02277                                 "Failed to get groups for username \"%s\" primary GID "
02278                                 DBUS_GID_FORMAT ": %s\n",
02279                                 username_c, info->primary_gid,
02280                                 _dbus_strerror (errno));
02281                 dbus_free (buf);
02282                 goto failed;
02283               }
02284           }
02285       }
02286 
02287     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02288     if (info->group_ids == NULL)
02289       {
02290         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02291         dbus_free (buf);
02292         goto failed;
02293       }
02294 
02295     for (i = 0; i < buf_count; ++i)
02296       info->group_ids[i] = buf[i];
02297 
02298     info->n_group_ids = buf_count;
02299 
02300     dbus_free (buf);
02301   }
02302 #else  /* HAVE_GETGROUPLIST */
02303   {
02304     /* We just get the one group ID */
02305     info->group_ids = dbus_new (dbus_gid_t, 1);
02306     if (info->group_ids == NULL)
02307       {
02308         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02309         goto failed;
02310       }
02311 
02312     info->n_group_ids = 1;
02313 
02314     (info->group_ids)[0] = info->primary_gid;
02315   }
02316 #endif /* HAVE_GETGROUPLIST */
02317 
02318   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02319 
02320   return TRUE;
02321 
02322  failed:
02323   _DBUS_ASSERT_ERROR_IS_SET (error);
02324   return FALSE;
02325 }
02326 
02335 dbus_bool_t
02336 _dbus_user_info_fill (DBusUserInfo     *info,
02337                       const DBusString *username,
02338                       DBusError        *error)
02339 {
02340   return fill_user_info (info, DBUS_UID_UNSET,
02341                          username, error);
02342 }
02343 
02352 dbus_bool_t
02353 _dbus_user_info_fill_uid (DBusUserInfo *info,
02354                           dbus_uid_t    uid,
02355                           DBusError    *error)
02356 {
02357   return fill_user_info (info, uid,
02358                          NULL, error);
02359 }
02360 
02368 dbus_bool_t
02369 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02370 {
02371   /* The POSIX spec certainly doesn't promise this, but
02372    * we need these assertions to fail as soon as we're wrong about
02373    * it so we can do the porting fixups
02374    */
02375   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02376   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02377   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02378 
02379   if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
02380     return FALSE;
02381   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02382     return FALSE;
02383 
02384   return TRUE;
02385 }
02386 
02398 dbus_bool_t
02399 _dbus_append_user_from_current_process (DBusString *str)
02400 {
02401   return _dbus_string_append_uint (str,
02402                                    _dbus_geteuid ());
02403 }
02404 
02409 dbus_pid_t
02410 _dbus_getpid (void)
02411 {
02412   return getpid ();
02413 }
02414 
02418 dbus_uid_t
02419 _dbus_getuid (void)
02420 {
02421   return getuid ();
02422 }
02423 
02427 dbus_uid_t
02428 _dbus_geteuid (void)
02429 {
02430   return geteuid ();
02431 }
02432 
02439 unsigned long
02440 _dbus_pid_for_log (void)
02441 {
02442   return getpid ();
02443 }
02444 
02452 dbus_bool_t
02453 _dbus_parse_uid (const DBusString      *uid_str,
02454                  dbus_uid_t            *uid)
02455 {
02456   int end;
02457   long val;
02458 
02459   if (_dbus_string_get_length (uid_str) == 0)
02460     {
02461       _dbus_verbose ("UID string was zero length\n");
02462       return FALSE;
02463     }
02464 
02465   val = -1;
02466   end = 0;
02467   if (!_dbus_string_parse_int (uid_str, 0, &val,
02468                                &end))
02469     {
02470       _dbus_verbose ("could not parse string as a UID\n");
02471       return FALSE;
02472     }
02473 
02474   if (end != _dbus_string_get_length (uid_str))
02475     {
02476       _dbus_verbose ("string contained trailing stuff after UID\n");
02477       return FALSE;
02478     }
02479 
02480   *uid = val;
02481 
02482   return TRUE;
02483 }
02484 
02485 #if !DBUS_USE_SYNC
02486 /* To be thread-safe by default on platforms that don't necessarily have
02487  * atomic operations (notably Debian armel, which is armv4t), we must
02488  * use a mutex that can be initialized statically, like this.
02489  * GLib >= 2.32 uses a similar system.
02490  */
02491 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
02492 #endif
02493 
02500 dbus_int32_t
02501 _dbus_atomic_inc (DBusAtomic *atomic)
02502 {
02503 #if DBUS_USE_SYNC
02504   return __sync_add_and_fetch(&atomic->value, 1)-1;
02505 #else
02506   dbus_int32_t res;
02507 
02508   pthread_mutex_lock (&atomic_mutex);
02509   res = atomic->value;
02510   atomic->value += 1;
02511   pthread_mutex_unlock (&atomic_mutex);
02512 
02513   return res;
02514 #endif
02515 }
02516 
02523 dbus_int32_t
02524 _dbus_atomic_dec (DBusAtomic *atomic)
02525 {
02526 #if DBUS_USE_SYNC
02527   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02528 #else
02529   dbus_int32_t res;
02530 
02531   pthread_mutex_lock (&atomic_mutex);
02532   res = atomic->value;
02533   atomic->value -= 1;
02534   pthread_mutex_unlock (&atomic_mutex);
02535 
02536   return res;
02537 #endif
02538 }
02539 
02547 dbus_int32_t
02548 _dbus_atomic_get (DBusAtomic *atomic)
02549 {
02550 #if DBUS_USE_SYNC
02551   __sync_synchronize ();
02552   return atomic->value;
02553 #else
02554   dbus_int32_t res;
02555 
02556   pthread_mutex_lock (&atomic_mutex);
02557   res = atomic->value;
02558   pthread_mutex_unlock (&atomic_mutex);
02559 
02560   return res;
02561 #endif
02562 }
02563 
02572 int
02573 _dbus_poll (DBusPollFD *fds,
02574             int         n_fds,
02575             int         timeout_milliseconds)
02576 {
02577 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02578   /* This big thing is a constant expression and should get optimized
02579    * out of existence. So it's more robust than a configure check at
02580    * no cost.
02581    */
02582   if (_DBUS_POLLIN == POLLIN &&
02583       _DBUS_POLLPRI == POLLPRI &&
02584       _DBUS_POLLOUT == POLLOUT &&
02585       _DBUS_POLLERR == POLLERR &&
02586       _DBUS_POLLHUP == POLLHUP &&
02587       _DBUS_POLLNVAL == POLLNVAL &&
02588       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02589       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02590       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02591       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02592       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02593       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02594       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02595     {
02596       return poll ((struct pollfd*) fds,
02597                    n_fds,
02598                    timeout_milliseconds);
02599     }
02600   else
02601     {
02602       /* We have to convert the DBusPollFD to an array of
02603        * struct pollfd, poll, and convert back.
02604        */
02605       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02606       return -1;
02607     }
02608 #else /* ! HAVE_POLL */
02609 
02610   fd_set read_set, write_set, err_set;
02611   int max_fd = 0;
02612   int i;
02613   struct timeval tv;
02614   int ready;
02615 
02616   FD_ZERO (&read_set);
02617   FD_ZERO (&write_set);
02618   FD_ZERO (&err_set);
02619 
02620   for (i = 0; i < n_fds; i++)
02621     {
02622       DBusPollFD *fdp = &fds[i];
02623 
02624       if (fdp->events & _DBUS_POLLIN)
02625         FD_SET (fdp->fd, &read_set);
02626 
02627       if (fdp->events & _DBUS_POLLOUT)
02628         FD_SET (fdp->fd, &write_set);
02629 
02630       FD_SET (fdp->fd, &err_set);
02631 
02632       max_fd = MAX (max_fd, fdp->fd);
02633     }
02634 
02635   tv.tv_sec = timeout_milliseconds / 1000;
02636   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02637 
02638   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02639                   timeout_milliseconds < 0 ? NULL : &tv);
02640 
02641   if (ready > 0)
02642     {
02643       for (i = 0; i < n_fds; i++)
02644         {
02645           DBusPollFD *fdp = &fds[i];
02646 
02647           fdp->revents = 0;
02648 
02649           if (FD_ISSET (fdp->fd, &read_set))
02650             fdp->revents |= _DBUS_POLLIN;
02651 
02652           if (FD_ISSET (fdp->fd, &write_set))
02653             fdp->revents |= _DBUS_POLLOUT;
02654 
02655           if (FD_ISSET (fdp->fd, &err_set))
02656             fdp->revents |= _DBUS_POLLERR;
02657         }
02658     }
02659 
02660   return ready;
02661 #endif
02662 }
02663 
02671 void
02672 _dbus_get_monotonic_time (long *tv_sec,
02673                           long *tv_usec)
02674 {
02675 #ifdef HAVE_MONOTONIC_CLOCK
02676   struct timespec ts;
02677   clock_gettime (CLOCK_MONOTONIC, &ts);
02678 
02679   if (tv_sec)
02680     *tv_sec = ts.tv_sec;
02681   if (tv_usec)
02682     *tv_usec = ts.tv_nsec / 1000;
02683 #else
02684   struct timeval t;
02685 
02686   gettimeofday (&t, NULL);
02687 
02688   if (tv_sec)
02689     *tv_sec = t.tv_sec;
02690   if (tv_usec)
02691     *tv_usec = t.tv_usec;
02692 #endif
02693 }
02694 
02702 void
02703 _dbus_get_real_time (long *tv_sec,
02704                      long *tv_usec)
02705 {
02706   struct timeval t;
02707 
02708   gettimeofday (&t, NULL);
02709 
02710   if (tv_sec)
02711     *tv_sec = t.tv_sec;
02712   if (tv_usec)
02713     *tv_usec = t.tv_usec;
02714 }
02715 
02724 dbus_bool_t
02725 _dbus_create_directory (const DBusString *filename,
02726                         DBusError        *error)
02727 {
02728   const char *filename_c;
02729 
02730   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02731 
02732   filename_c = _dbus_string_get_const_data (filename);
02733 
02734   if (mkdir (filename_c, 0700) < 0)
02735     {
02736       if (errno == EEXIST)
02737         return TRUE;
02738 
02739       dbus_set_error (error, DBUS_ERROR_FAILED,
02740                       "Failed to create directory %s: %s\n",
02741                       filename_c, _dbus_strerror (errno));
02742       return FALSE;
02743     }
02744   else
02745     return TRUE;
02746 }
02747 
02758 dbus_bool_t
02759 _dbus_concat_dir_and_file (DBusString       *dir,
02760                            const DBusString *next_component)
02761 {
02762   dbus_bool_t dir_ends_in_slash;
02763   dbus_bool_t file_starts_with_slash;
02764 
02765   if (_dbus_string_get_length (dir) == 0 ||
02766       _dbus_string_get_length (next_component) == 0)
02767     return TRUE;
02768 
02769   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02770                                                     _dbus_string_get_length (dir) - 1);
02771 
02772   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02773 
02774   if (dir_ends_in_slash && file_starts_with_slash)
02775     {
02776       _dbus_string_shorten (dir, 1);
02777     }
02778   else if (!(dir_ends_in_slash || file_starts_with_slash))
02779     {
02780       if (!_dbus_string_append_byte (dir, '/'))
02781         return FALSE;
02782     }
02783 
02784   return _dbus_string_copy (next_component, 0, dir,
02785                             _dbus_string_get_length (dir));
02786 }
02787 
02789 #define NANOSECONDS_PER_SECOND       1000000000
02790 
02791 #define MICROSECONDS_PER_SECOND      1000000
02792 
02793 #define MILLISECONDS_PER_SECOND      1000
02794 
02795 #define NANOSECONDS_PER_MILLISECOND  1000000
02796 
02797 #define MICROSECONDS_PER_MILLISECOND 1000
02798 
02803 void
02804 _dbus_sleep_milliseconds (int milliseconds)
02805 {
02806 #ifdef HAVE_NANOSLEEP
02807   struct timespec req;
02808   struct timespec rem;
02809 
02810   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02811   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02812   rem.tv_sec = 0;
02813   rem.tv_nsec = 0;
02814 
02815   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02816     req = rem;
02817 #elif defined (HAVE_USLEEP)
02818   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02819 #else /* ! HAVE_USLEEP */
02820   sleep (MAX (milliseconds / 1000, 1));
02821 #endif
02822 }
02823 
02824 static dbus_bool_t
02825 _dbus_generate_pseudorandom_bytes (DBusString *str,
02826                                    int         n_bytes)
02827 {
02828   int old_len;
02829   char *p;
02830 
02831   old_len = _dbus_string_get_length (str);
02832 
02833   if (!_dbus_string_lengthen (str, n_bytes))
02834     return FALSE;
02835 
02836   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02837 
02838   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02839 
02840   return TRUE;
02841 }
02842 
02851 dbus_bool_t
02852 _dbus_generate_random_bytes (DBusString *str,
02853                              int         n_bytes)
02854 {
02855   int old_len;
02856   int fd;
02857 
02858   /* FALSE return means "no memory", if it could
02859    * mean something else then we'd need to return
02860    * a DBusError. So we always fall back to pseudorandom
02861    * if the I/O fails.
02862    */
02863 
02864   old_len = _dbus_string_get_length (str);
02865   fd = -1;
02866 
02867   /* note, urandom on linux will fall back to pseudorandom */
02868   fd = open ("/dev/urandom", O_RDONLY);
02869   if (fd < 0)
02870     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02871 
02872   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02873 
02874   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02875     {
02876       _dbus_close (fd, NULL);
02877       _dbus_string_set_length (str, old_len);
02878       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02879     }
02880 
02881   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02882                  n_bytes);
02883 
02884   _dbus_close (fd, NULL);
02885 
02886   return TRUE;
02887 }
02888 
02894 void
02895 _dbus_exit (int code)
02896 {
02897   _exit (code);
02898 }
02899 
02908 const char*
02909 _dbus_strerror (int error_number)
02910 {
02911   const char *msg;
02912 
02913   msg = strerror (error_number);
02914   if (msg == NULL)
02915     msg = "unknown";
02916 
02917   return msg;
02918 }
02919 
02923 void
02924 _dbus_disable_sigpipe (void)
02925 {
02926   signal (SIGPIPE, SIG_IGN);
02927 }
02928 
02936 void
02937 _dbus_fd_set_close_on_exec (intptr_t fd)
02938 {
02939   int val;
02940 
02941   val = fcntl (fd, F_GETFD, 0);
02942 
02943   if (val < 0)
02944     return;
02945 
02946   val |= FD_CLOEXEC;
02947 
02948   fcntl (fd, F_SETFD, val);
02949 }
02950 
02958 dbus_bool_t
02959 _dbus_close (int        fd,
02960              DBusError *error)
02961 {
02962   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02963 
02964  again:
02965   if (close (fd) < 0)
02966     {
02967       if (errno == EINTR)
02968         goto again;
02969 
02970       dbus_set_error (error, _dbus_error_from_errno (errno),
02971                       "Could not close fd %d", fd);
02972       return FALSE;
02973     }
02974 
02975   return TRUE;
02976 }
02977 
02986 int
02987 _dbus_dup(int        fd,
02988           DBusError *error)
02989 {
02990   int new_fd;
02991 
02992 #ifdef F_DUPFD_CLOEXEC
02993   dbus_bool_t cloexec_done;
02994 
02995   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02996   cloexec_done = new_fd >= 0;
02997 
02998   if (new_fd < 0 && errno == EINVAL)
02999 #endif
03000     {
03001       new_fd = fcntl(fd, F_DUPFD, 3);
03002     }
03003 
03004   if (new_fd < 0) {
03005 
03006     dbus_set_error (error, _dbus_error_from_errno (errno),
03007                     "Could not duplicate fd %d", fd);
03008     return -1;
03009   }
03010 
03011 #ifdef F_DUPFD_CLOEXEC
03012   if (!cloexec_done)
03013 #endif
03014     {
03015       _dbus_fd_set_close_on_exec(new_fd);
03016     }
03017 
03018   return new_fd;
03019 }
03020 
03028 dbus_bool_t
03029 _dbus_set_fd_nonblocking (int             fd,
03030                           DBusError      *error)
03031 {
03032   int val;
03033 
03034   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03035 
03036   val = fcntl (fd, F_GETFL, 0);
03037   if (val < 0)
03038     {
03039       dbus_set_error (error, _dbus_error_from_errno (errno),
03040                       "Failed to get flags from file descriptor %d: %s",
03041                       fd, _dbus_strerror (errno));
03042       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
03043                      _dbus_strerror (errno));
03044       return FALSE;
03045     }
03046 
03047   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
03048     {
03049       dbus_set_error (error, _dbus_error_from_errno (errno),
03050                       "Failed to set nonblocking flag of file descriptor %d: %s",
03051                       fd, _dbus_strerror (errno));
03052       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
03053                      fd, _dbus_strerror (errno));
03054 
03055       return FALSE;
03056     }
03057 
03058   return TRUE;
03059 }
03060 
03066 void
03067 _dbus_print_backtrace (void)
03068 {
03069 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
03070   void *bt[500];
03071   int bt_size;
03072   int i;
03073   char **syms;
03074 
03075   bt_size = backtrace (bt, 500);
03076 
03077   syms = backtrace_symbols (bt, bt_size);
03078 
03079   i = 0;
03080   while (i < bt_size)
03081     {
03082       /* don't use dbus_warn since it can _dbus_abort() */
03083       fprintf (stderr, "  %s\n", syms[i]);
03084       ++i;
03085     }
03086   fflush (stderr);
03087 
03088   free (syms);
03089 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
03090   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
03091 #else
03092   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
03093 #endif
03094 }
03095 
03108 dbus_bool_t
03109 _dbus_full_duplex_pipe (int        *fd1,
03110                         int        *fd2,
03111                         dbus_bool_t blocking,
03112                         DBusError  *error)
03113 {
03114 #ifdef HAVE_SOCKETPAIR
03115   int fds[2];
03116   int retval;
03117 
03118 #ifdef SOCK_CLOEXEC
03119   dbus_bool_t cloexec_done;
03120 
03121   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03122   cloexec_done = retval >= 0;
03123 
03124   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
03125 #endif
03126     {
03127       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03128     }
03129 
03130   if (retval < 0)
03131     {
03132       dbus_set_error (error, _dbus_error_from_errno (errno),
03133                       "Could not create full-duplex pipe");
03134       return FALSE;
03135     }
03136 
03137   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03138 
03139 #ifdef SOCK_CLOEXEC
03140   if (!cloexec_done)
03141 #endif
03142     {
03143       _dbus_fd_set_close_on_exec (fds[0]);
03144       _dbus_fd_set_close_on_exec (fds[1]);
03145     }
03146 
03147   if (!blocking &&
03148       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03149        !_dbus_set_fd_nonblocking (fds[1], NULL)))
03150     {
03151       dbus_set_error (error, _dbus_error_from_errno (errno),
03152                       "Could not set full-duplex pipe nonblocking");
03153 
03154       _dbus_close (fds[0], NULL);
03155       _dbus_close (fds[1], NULL);
03156 
03157       return FALSE;
03158     }
03159 
03160   *fd1 = fds[0];
03161   *fd2 = fds[1];
03162 
03163   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03164                  *fd1, *fd2);
03165 
03166   return TRUE;
03167 #else
03168   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03169   dbus_set_error (error, DBUS_ERROR_FAILED,
03170                   "_dbus_full_duplex_pipe() not implemented on this OS");
03171   return FALSE;
03172 #endif
03173 }
03174 
03183 int
03184 _dbus_printf_string_upper_bound (const char *format,
03185                                  va_list     args)
03186 {
03187   char static_buf[1024];
03188   int bufsize = sizeof (static_buf);
03189   int len;
03190   va_list args_copy;
03191 
03192   DBUS_VA_COPY (args_copy, args);
03193   len = vsnprintf (static_buf, bufsize, format, args_copy);
03194   va_end (args_copy);
03195 
03196   /* If vsnprintf() returned non-negative, then either the string fits in
03197    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03198    * returns the number of characters that were needed, or this OS returns the
03199    * truncated length.
03200    *
03201    * We ignore the possibility that snprintf might just ignore the length and
03202    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03203    * If your libc is really that bad, come back when you have a better one. */
03204   if (len == bufsize)
03205     {
03206       /* This could be the truncated length (Tru64 and IRIX have this bug),
03207        * or the real length could be coincidentally the same. Which is it?
03208        * If vsnprintf returns the truncated length, we'll go to the slow
03209        * path. */
03210       DBUS_VA_COPY (args_copy, args);
03211 
03212       if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03213         len = -1;
03214 
03215       va_end (args_copy);
03216     }
03217 
03218   /* If vsnprintf() returned negative, we have to do more work.
03219    * HP-UX returns negative. */
03220   while (len < 0)
03221     {
03222       char *buf;
03223 
03224       bufsize *= 2;
03225 
03226       buf = dbus_malloc (bufsize);
03227 
03228       if (buf == NULL)
03229         return -1;
03230 
03231       DBUS_VA_COPY (args_copy, args);
03232       len = vsnprintf (buf, bufsize, format, args_copy);
03233       va_end (args_copy);
03234 
03235       dbus_free (buf);
03236 
03237       /* If the reported length is exactly the buffer size, round up to the
03238        * next size, in case vsnprintf has been returning the truncated
03239        * length */
03240       if (len == bufsize)
03241         len = -1;
03242     }
03243 
03244   return len;
03245 }
03246 
03253 const char*
03254 _dbus_get_tmpdir(void)
03255 {
03256   /* Protected by _DBUS_LOCK_sysdeps */
03257   static const char* tmpdir = NULL;
03258 
03259   if (!_DBUS_LOCK (sysdeps))
03260     return NULL;
03261 
03262   if (tmpdir == NULL)
03263     {
03264       /* TMPDIR is what glibc uses, then
03265        * glibc falls back to the P_tmpdir macro which
03266        * just expands to "/tmp"
03267        */
03268       if (tmpdir == NULL)
03269         tmpdir = getenv("TMPDIR");
03270 
03271       /* These two env variables are probably
03272        * broken, but maybe some OS uses them?
03273        */
03274       if (tmpdir == NULL)
03275         tmpdir = getenv("TMP");
03276       if (tmpdir == NULL)
03277         tmpdir = getenv("TEMP");
03278 
03279       /* And this is the sane fallback. */
03280       if (tmpdir == NULL)
03281         tmpdir = "/tmp";
03282     }
03283 
03284   _DBUS_UNLOCK (sysdeps);
03285 
03286   _dbus_assert(tmpdir != NULL);
03287 
03288   return tmpdir;
03289 }
03290 
03291 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
03292 
03311 static dbus_bool_t
03312 _read_subprocess_line_argv (const char *progpath,
03313                             dbus_bool_t path_fallback,
03314                             char       * const *argv,
03315                             DBusString *result,
03316                             DBusError  *error)
03317 {
03318   int result_pipe[2] = { -1, -1 };
03319   int errors_pipe[2] = { -1, -1 };
03320   pid_t pid;
03321   int ret;
03322   int status;
03323   int orig_len;
03324 
03325   dbus_bool_t retval;
03326   sigset_t new_set, old_set;
03327 
03328   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03329   retval = FALSE;
03330 
03331   /* We need to block any existing handlers for SIGCHLD temporarily; they
03332    * will cause waitpid() below to fail.
03333    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03334    */
03335   sigemptyset (&new_set);
03336   sigaddset (&new_set, SIGCHLD);
03337   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03338 
03339   orig_len = _dbus_string_get_length (result);
03340 
03341 #define READ_END        0
03342 #define WRITE_END       1
03343   if (pipe (result_pipe) < 0)
03344     {
03345       dbus_set_error (error, _dbus_error_from_errno (errno),
03346                       "Failed to create a pipe to call %s: %s",
03347                       progpath, _dbus_strerror (errno));
03348       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03349                      progpath, _dbus_strerror (errno));
03350       goto out;
03351     }
03352   if (pipe (errors_pipe) < 0)
03353     {
03354       dbus_set_error (error, _dbus_error_from_errno (errno),
03355                       "Failed to create a pipe to call %s: %s",
03356                       progpath, _dbus_strerror (errno));
03357       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03358                      progpath, _dbus_strerror (errno));
03359       goto out;
03360     }
03361 
03362   pid = fork ();
03363   if (pid < 0)
03364     {
03365       dbus_set_error (error, _dbus_error_from_errno (errno),
03366                       "Failed to fork() to call %s: %s",
03367                       progpath, _dbus_strerror (errno));
03368       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03369                      progpath, _dbus_strerror (errno));
03370       goto out;
03371     }
03372 
03373   if (pid == 0)
03374     {
03375       /* child process */
03376       int fd;
03377 
03378       fd = open ("/dev/null", O_RDWR);
03379       if (fd == -1)
03380         /* huh?! can't open /dev/null? */
03381         _exit (1);
03382 
03383       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03384 
03385       /* set-up stdXXX */
03386       close (result_pipe[READ_END]);
03387       close (errors_pipe[READ_END]);
03388 
03389       if (dup2 (fd, 0) == -1) /* setup stdin */
03390         _exit (1);
03391       if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
03392         _exit (1);
03393       if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
03394         _exit (1);
03395 
03396       _dbus_close_all ();
03397 
03398       sigprocmask (SIG_SETMASK, &old_set, NULL);
03399 
03400       /* If it looks fully-qualified, try execv first */
03401       if (progpath[0] == '/')
03402         {
03403           execv (progpath, argv);
03404           /* Ok, that failed.  Now if path_fallback is given, let's
03405            * try unqualified.  This is mostly a hack to work
03406            * around systems which ship dbus-launch in /usr/bin
03407            * but everything else in /bin (because dbus-launch
03408            * depends on X11).
03409            */
03410           if (path_fallback)
03411             /* We must have a slash, because we checked above */
03412             execvp (strrchr (progpath, '/')+1, argv);
03413         }
03414       else
03415         execvp (progpath, argv);
03416 
03417       /* still nothing, we failed */
03418       _exit (1);
03419     }
03420 
03421   /* parent process */
03422   close (result_pipe[WRITE_END]);
03423   close (errors_pipe[WRITE_END]);
03424   result_pipe[WRITE_END] = -1;
03425   errors_pipe[WRITE_END] = -1;
03426 
03427   ret = 0;
03428   do
03429     {
03430       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03431     }
03432   while (ret > 0);
03433 
03434   /* reap the child process to avoid it lingering as zombie */
03435   do
03436     {
03437       ret = waitpid (pid, &status, 0);
03438     }
03439   while (ret == -1 && errno == EINTR);
03440 
03441   /* We succeeded if the process exited with status 0 and
03442      anything was read */
03443   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03444     {
03445       /* The process ended with error */
03446       DBusString error_message;
03447       if (!_dbus_string_init (&error_message))
03448         {
03449           _DBUS_SET_OOM (error);
03450           goto out;
03451         }
03452 
03453       ret = 0;
03454       do
03455         {
03456           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03457         }
03458       while (ret > 0);
03459 
03460       _dbus_string_set_length (result, orig_len);
03461       if (_dbus_string_get_length (&error_message) > 0)
03462         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03463                         "%s terminated abnormally with the following error: %s",
03464                         progpath, _dbus_string_get_data (&error_message));
03465       else
03466         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03467                         "%s terminated abnormally without any error message",
03468                         progpath);
03469       goto out;
03470     }
03471 
03472   retval = TRUE;
03473 
03474  out:
03475   sigprocmask (SIG_SETMASK, &old_set, NULL);
03476 
03477   if (retval)
03478     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03479   else
03480     _DBUS_ASSERT_ERROR_IS_SET (error);
03481 
03482   if (result_pipe[0] != -1)
03483     close (result_pipe[0]);
03484   if (result_pipe[1] != -1)
03485     close (result_pipe[1]);
03486   if (errors_pipe[0] != -1)
03487     close (errors_pipe[0]);
03488   if (errors_pipe[1] != -1)
03489     close (errors_pipe[1]);
03490 
03491   return retval;
03492 }
03493 #endif
03494 
03507 dbus_bool_t
03508 _dbus_get_autolaunch_address (const char *scope,
03509                               DBusString *address,
03510                               DBusError  *error)
03511 {
03512 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03513   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03514    * but that's done elsewhere, and if it worked, this function wouldn't
03515    * be called.) */
03516   const char *display;
03517   char *argv[6];
03518   int i;
03519   DBusString uuid;
03520   dbus_bool_t retval;
03521 
03522   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03523   retval = FALSE;
03524 
03525   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03526    * dbus-launch-x11 is just going to fail. Rather than trying to
03527    * run it, we might as well bail out early with a nice error. */
03528   display = _dbus_getenv ("DISPLAY");
03529 
03530   if (display == NULL || display[0] == '\0')
03531     {
03532       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03533           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03534       return FALSE;
03535     }
03536 
03537   if (!_dbus_string_init (&uuid))
03538     {
03539       _DBUS_SET_OOM (error);
03540       return FALSE;
03541     }
03542 
03543   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03544     {
03545       _DBUS_SET_OOM (error);
03546       goto out;
03547     }
03548 
03549   i = 0;
03550 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03551   if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
03552     argv[i] = TEST_BUS_LAUNCH_BINARY;
03553   else
03554 #endif
03555     argv[i] = DBUS_BINDIR "/dbus-launch";
03556   ++i;
03557   argv[i] = "--autolaunch";
03558   ++i;
03559   argv[i] = _dbus_string_get_data (&uuid);
03560   ++i;
03561   argv[i] = "--binary-syntax";
03562   ++i;
03563   argv[i] = "--close-stderr";
03564   ++i;
03565   argv[i] = NULL;
03566   ++i;
03567 
03568   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03569 
03570   retval = _read_subprocess_line_argv (argv[0],
03571                                        TRUE,
03572                                        argv, address, error);
03573 
03574  out:
03575   _dbus_string_free (&uuid);
03576   return retval;
03577 #else
03578   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03579       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03580       "set your DBUS_SESSION_BUS_ADDRESS instead");
03581   return FALSE;
03582 #endif
03583 }
03584 
03603 dbus_bool_t
03604 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03605                                dbus_bool_t create_if_not_found,
03606                                DBusError  *error)
03607 {
03608   DBusString filename;
03609   dbus_bool_t b;
03610 
03611   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03612 
03613   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03614   if (b)
03615     return TRUE;
03616 
03617   dbus_error_free (error);
03618 
03619   /* Fallback to the system machine ID */
03620   _dbus_string_init_const (&filename, "/etc/machine-id");
03621   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03622 
03623   if (b)
03624     {
03625       /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
03626        * complain if that isn't possible for whatever reason */
03627       _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03628       _dbus_write_uuid_file (&filename, machine_id, NULL);
03629 
03630       return TRUE;
03631     }
03632 
03633   if (!create_if_not_found)
03634     return FALSE;
03635 
03636   /* if none found, try to make a new one */
03637   dbus_error_free (error);
03638   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03639   _dbus_generate_uuid (machine_id);
03640   return _dbus_write_uuid_file (&filename, machine_id, error);
03641 }
03642 
03650 dbus_bool_t
03651 _dbus_lookup_launchd_socket (DBusString *socket_path,
03652                              const char *launchd_env_var,
03653                              DBusError  *error)
03654 {
03655 #ifdef DBUS_ENABLE_LAUNCHD
03656   char *argv[4];
03657   int i;
03658 
03659   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03660 
03661   i = 0;
03662   argv[i] = "launchctl";
03663   ++i;
03664   argv[i] = "getenv";
03665   ++i;
03666   argv[i] = (char*)launchd_env_var;
03667   ++i;
03668   argv[i] = NULL;
03669   ++i;
03670 
03671   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03672 
03673   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03674     {
03675       return FALSE;
03676     }
03677 
03678   /* no error, but no result either */
03679   if (_dbus_string_get_length(socket_path) == 0)
03680     {
03681       return FALSE;
03682     }
03683 
03684   /* strip the carriage-return */
03685   _dbus_string_shorten(socket_path, 1);
03686   return TRUE;
03687 #else /* DBUS_ENABLE_LAUNCHD */
03688   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03689                 "can't lookup socket from launchd; launchd support not compiled in");
03690   return FALSE;
03691 #endif
03692 }
03693 
03694 #ifdef DBUS_ENABLE_LAUNCHD
03695 static dbus_bool_t
03696 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03697 {
03698   dbus_bool_t valid_socket;
03699   DBusString socket_path;
03700 
03701   if (!_dbus_string_init (&socket_path))
03702     {
03703       _DBUS_SET_OOM (error);
03704       return FALSE;
03705     }
03706 
03707   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03708 
03709   if (dbus_error_is_set(error))
03710     {
03711       _dbus_string_free(&socket_path);
03712       return FALSE;
03713     }
03714 
03715   if (!valid_socket)
03716     {
03717       dbus_set_error(error, "no socket path",
03718                 "launchd did not provide a socket path, "
03719                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03720       _dbus_string_free(&socket_path);
03721       return FALSE;
03722     }
03723   if (!_dbus_string_append (address, "unix:path="))
03724     {
03725       _DBUS_SET_OOM (error);
03726       _dbus_string_free(&socket_path);
03727       return FALSE;
03728     }
03729   if (!_dbus_string_copy (&socket_path, 0, address,
03730                           _dbus_string_get_length (address)))
03731     {
03732       _DBUS_SET_OOM (error);
03733       _dbus_string_free(&socket_path);
03734       return FALSE;
03735     }
03736 
03737   _dbus_string_free(&socket_path);
03738   return TRUE;
03739 }
03740 #endif
03741 
03761 dbus_bool_t
03762 _dbus_lookup_session_address (dbus_bool_t *supported,
03763                               DBusString  *address,
03764                               DBusError   *error)
03765 {
03766 #ifdef DBUS_ENABLE_LAUNCHD
03767   *supported = TRUE;
03768   return _dbus_lookup_session_address_launchd (address, error);
03769 #else
03770   /* On non-Mac Unix platforms, if the session address isn't already
03771    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03772    * fall back to the autolaunch: global default; see
03773    * init_session_address in dbus/dbus-bus.c. */
03774   *supported = FALSE;
03775   return TRUE;
03776 #endif
03777 }
03778 
03786 void
03787 _dbus_flush_caches (void)
03788 {
03789   _dbus_user_database_flush_system ();
03790 }
03791 
03805 dbus_bool_t
03806 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03807                                                 DBusCredentials *credentials)
03808 {
03809   DBusString homedir;
03810   DBusString dotdir;
03811   dbus_uid_t uid;
03812 
03813   _dbus_assert (credentials != NULL);
03814   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03815 
03816   if (!_dbus_string_init (&homedir))
03817     return FALSE;
03818 
03819   uid = _dbus_credentials_get_unix_uid (credentials);
03820   _dbus_assert (uid != DBUS_UID_UNSET);
03821 
03822   if (!_dbus_homedir_from_uid (uid, &homedir))
03823     goto failed;
03824 
03825 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03826   {
03827     const char *override;
03828 
03829     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03830     if (override != NULL && *override != '\0')
03831       {
03832         _dbus_string_set_length (&homedir, 0);
03833         if (!_dbus_string_append (&homedir, override))
03834           goto failed;
03835 
03836         _dbus_verbose ("Using fake homedir for testing: %s\n",
03837                        _dbus_string_get_const_data (&homedir));
03838       }
03839     else
03840       {
03841         /* Not strictly thread-safe, but if we fail at thread-safety here,
03842          * the worst that will happen is some extra warnings. */
03843         static dbus_bool_t already_warned = FALSE;
03844         if (!already_warned)
03845           {
03846             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03847             already_warned = TRUE;
03848           }
03849       }
03850   }
03851 #endif
03852 
03853   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03854   if (!_dbus_concat_dir_and_file (&homedir,
03855                                   &dotdir))
03856     goto failed;
03857 
03858   if (!_dbus_string_copy (&homedir, 0,
03859                           directory, _dbus_string_get_length (directory))) {
03860     goto failed;
03861   }
03862 
03863   _dbus_string_free (&homedir);
03864   return TRUE;
03865 
03866  failed:
03867   _dbus_string_free (&homedir);
03868   return FALSE;
03869 }
03870 
03871 //PENDING(kdab) docs
03872 dbus_bool_t
03873 _dbus_daemon_publish_session_bus_address (const char* addr,
03874                                           const char *scope)
03875 {
03876   return TRUE;
03877 }
03878 
03879 //PENDING(kdab) docs
03880 void
03881 _dbus_daemon_unpublish_session_bus_address (void)
03882 {
03883 
03884 }
03885 
03892 dbus_bool_t
03893 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03894 {
03895   return errno == EAGAIN || errno == EWOULDBLOCK;
03896 }
03897 
03905 dbus_bool_t
03906 _dbus_delete_directory (const DBusString *filename,
03907                         DBusError        *error)
03908 {
03909   const char *filename_c;
03910 
03911   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03912 
03913   filename_c = _dbus_string_get_const_data (filename);
03914 
03915   if (rmdir (filename_c) != 0)
03916     {
03917       dbus_set_error (error, DBUS_ERROR_FAILED,
03918                       "Failed to remove directory %s: %s\n",
03919                       filename_c, _dbus_strerror (errno));
03920       return FALSE;
03921     }
03922 
03923   return TRUE;
03924 }
03925 
03933 dbus_bool_t
03934 _dbus_socket_can_pass_unix_fd(int fd) {
03935 
03936 #ifdef SCM_RIGHTS
03937   union {
03938     struct sockaddr sa;
03939     struct sockaddr_storage storage;
03940     struct sockaddr_un un;
03941   } sa_buf;
03942 
03943   socklen_t sa_len = sizeof(sa_buf);
03944 
03945   _DBUS_ZERO(sa_buf);
03946 
03947   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03948     return FALSE;
03949 
03950   return sa_buf.sa.sa_family == AF_UNIX;
03951 
03952 #else
03953   return FALSE;
03954 
03955 #endif
03956 }
03957 
03962 void
03963 _dbus_close_all (void)
03964 {
03965   int maxfds, i;
03966 
03967 #if HAVE_CLOSEFROM
03968       closefrom(3);
03969 #endif
03970 
03971 #ifdef __linux__
03972   DIR *d;
03973 
03974   /* On Linux we can optimize this a bit if /proc is available. If it
03975      isn't available, fall back to the brute force way. */
03976 
03977   d = opendir ("/proc/self/fd");
03978   if (d)
03979     {
03980       for (;;)
03981         {
03982           struct dirent buf, *de;
03983           int k, fd;
03984           long l;
03985           char *e = NULL;
03986 
03987           k = readdir_r (d, &buf, &de);
03988           if (k != 0 || !de)
03989             break;
03990 
03991           if (de->d_name[0] == '.')
03992             continue;
03993 
03994           errno = 0;
03995           l = strtol (de->d_name, &e, 10);
03996           if (errno != 0 || e == NULL || *e != '\0')
03997             continue;
03998 
03999           fd = (int) l;
04000           if (fd < 3)
04001             continue;
04002 
04003           if (fd == dirfd (d))
04004             continue;
04005 
04006           close (fd);
04007         }
04008 
04009       closedir (d);
04010       return;
04011     }
04012 #endif
04013 
04014   maxfds = sysconf (_SC_OPEN_MAX);
04015 
04016   /* Pick something reasonable if for some reason sysconf says
04017    * unlimited.
04018    */
04019   if (maxfds < 0)
04020     maxfds = 1024;
04021 
04022   /* close all inherited fds */
04023   for (i = 3; i < maxfds; i++)
04024     close (i);
04025 }
04026 
04034 dbus_bool_t
04035 _dbus_append_address_from_socket (int         fd,
04036                                   DBusString *address,
04037                                   DBusError  *error)
04038 {
04039   union {
04040       struct sockaddr sa;
04041       struct sockaddr_storage storage;
04042       struct sockaddr_un un;
04043       struct sockaddr_in ipv4;
04044       struct sockaddr_in6 ipv6;
04045   } socket;
04046   char hostip[INET6_ADDRSTRLEN];
04047   int size = sizeof (socket);
04048   DBusString path_str;
04049 
04050   if (getsockname (fd, &socket.sa, &size))
04051     goto err;
04052 
04053   switch (socket.sa.sa_family)
04054     {
04055     case AF_UNIX:
04056       if (socket.un.sun_path[0]=='\0')
04057         {
04058           _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
04059           if (_dbus_string_append (address, "unix:abstract=") &&
04060               _dbus_address_append_escaped (address, &path_str))
04061             return TRUE;
04062         }
04063       else
04064         {
04065           _dbus_string_init_const (&path_str, socket.un.sun_path);
04066           if (_dbus_string_append (address, "unix:path=") &&
04067               _dbus_address_append_escaped (address, &path_str))
04068             return TRUE;
04069         }
04070       break;
04071     case AF_INET:
04072       if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
04073         if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
04074                                         hostip, ntohs (socket.ipv4.sin_port)))
04075           return TRUE;
04076       break;
04077 #ifdef AF_INET6
04078     case AF_INET6:
04079       _dbus_string_init_const (&path_str, hostip);
04080       if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
04081         if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
04082                                         ntohs (socket.ipv6.sin6_port)) &&
04083             _dbus_address_append_escaped (address, &path_str))
04084           return TRUE;
04085       break;
04086 #endif
04087     default:
04088       dbus_set_error (error,
04089                       _dbus_error_from_errno (EINVAL),
04090                       "Failed to read address from socket: Unknown socket type.");
04091       return FALSE;
04092     }
04093  err:
04094   dbus_set_error (error,
04095                   _dbus_error_from_errno (errno),
04096                   "Failed to open socket: %s",
04097                   _dbus_strerror (errno));
04098   return FALSE;
04099 }
04100 
04101 /* tests in dbus-sysdeps-util.c */