D-Bus 1.6.12

dbus-sysdeps-unix.c

00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038 
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058 
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074 #ifdef HAVE_ALLOCA_H
00075 #include <alloca.h>
00076 #endif
00077 
00078 #ifdef HAVE_ADT
00079 #include <bsm/adt.h>
00080 #endif
00081 
00082 #include "sd-daemon.h"
00083 
00084 #ifndef O_BINARY
00085 #define O_BINARY 0
00086 #endif
00087 
00088 #ifndef AI_ADDRCONFIG
00089 #define AI_ADDRCONFIG 0
00090 #endif
00091 
00092 #ifndef HAVE_SOCKLEN_T
00093 #define socklen_t int
00094 #endif
00095 
00096 #if defined (__sun) || defined (__sun__)
00097 /*
00098  * CMS_SPACE etc. definitions for Solaris < 10, based on
00099  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
00100  * via
00101  *   http://wiki.opencsw.org/porting-faq#toc10
00102  *
00103  * These are only redefined for Solaris, for now: if your OS needs these too,
00104  * please file a bug. (Or preferably, improve your OS so they're not needed.)
00105  */
00106 
00107 # ifndef CMSG_ALIGN
00108 #   ifdef __sun__
00109 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00110 #   else
00111       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
00112 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00113                               ~(sizeof (long) - 1))
00114 #   endif
00115 # endif
00116 
00117 # ifndef CMSG_SPACE
00118 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00119                             CMSG_ALIGN (len))
00120 # endif
00121 
00122 # ifndef CMSG_LEN
00123 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00124 # endif
00125 
00126 #endif /* Solaris */
00127 
00128 static dbus_bool_t
00129 _dbus_open_socket (int              *fd_p,
00130                    int               domain,
00131                    int               type,
00132                    int               protocol,
00133                    DBusError        *error)
00134 {
00135 #ifdef SOCK_CLOEXEC
00136   dbus_bool_t cloexec_done;
00137 
00138   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00139   cloexec_done = *fd_p >= 0;
00140 
00141   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00142   if (*fd_p < 0 && errno == EINVAL)
00143 #endif
00144     {
00145       *fd_p = socket (domain, type, protocol);
00146     }
00147 
00148   if (*fd_p >= 0)
00149     {
00150 #ifdef SOCK_CLOEXEC
00151       if (!cloexec_done)
00152 #endif
00153         {
00154           _dbus_fd_set_close_on_exec(*fd_p);
00155         }
00156 
00157       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00158       return TRUE;
00159     }
00160   else
00161     {
00162       dbus_set_error(error,
00163                      _dbus_error_from_errno (errno),
00164                      "Failed to open socket: %s",
00165                      _dbus_strerror (errno));
00166       return FALSE;
00167     }
00168 }
00169 
00180 static dbus_bool_t
00181 _dbus_open_unix_socket (int              *fd,
00182                         DBusError        *error)
00183 {
00184   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00185 }
00186 
00195 dbus_bool_t
00196 _dbus_close_socket (int               fd,
00197                     DBusError        *error)
00198 {
00199   return _dbus_close (fd, error);
00200 }
00201 
00211 int
00212 _dbus_read_socket (int               fd,
00213                    DBusString       *buffer,
00214                    int               count)
00215 {
00216   return _dbus_read (fd, buffer, count);
00217 }
00218 
00229 int
00230 _dbus_write_socket (int               fd,
00231                     const DBusString *buffer,
00232                     int               start,
00233                     int               len)
00234 {
00235 #if HAVE_DECL_MSG_NOSIGNAL
00236   const char *data;
00237   int bytes_written;
00238 
00239   data = _dbus_string_get_const_data_len (buffer, start, len);
00240 
00241  again:
00242 
00243   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00244 
00245   if (bytes_written < 0 && errno == EINTR)
00246     goto again;
00247 
00248   return bytes_written;
00249 
00250 #else
00251   return _dbus_write (fd, buffer, start, len);
00252 #endif
00253 }
00254 
00267 int
00268 _dbus_read_socket_with_unix_fds (int               fd,
00269                                  DBusString       *buffer,
00270                                  int               count,
00271                                  int              *fds,
00272                                  int              *n_fds) {
00273 #ifndef HAVE_UNIX_FD_PASSING
00274   int r;
00275 
00276   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00277     return r;
00278 
00279   *n_fds = 0;
00280   return r;
00281 
00282 #else
00283   int bytes_read;
00284   int start;
00285   struct msghdr m;
00286   struct iovec iov;
00287 
00288   _dbus_assert (count >= 0);
00289   _dbus_assert (*n_fds >= 0);
00290 
00291   start = _dbus_string_get_length (buffer);
00292 
00293   if (!_dbus_string_lengthen (buffer, count))
00294     {
00295       errno = ENOMEM;
00296       return -1;
00297     }
00298 
00299   _DBUS_ZERO(iov);
00300   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00301   iov.iov_len = count;
00302 
00303   _DBUS_ZERO(m);
00304   m.msg_iov = &iov;
00305   m.msg_iovlen = 1;
00306 
00307   /* Hmm, we have no clue how long the control data will actually be
00308      that is queued for us. The least we can do is assume that the
00309      caller knows. Hence let's make space for the number of fds that
00310      we shall read at max plus the cmsg header. */
00311   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00312 
00313   /* It's probably safe to assume that systems with SCM_RIGHTS also
00314      know alloca() */
00315   m.msg_control = alloca(m.msg_controllen);
00316   memset(m.msg_control, 0, m.msg_controllen);
00317 
00318  again:
00319 
00320   bytes_read = recvmsg(fd, &m, 0
00321 #ifdef MSG_CMSG_CLOEXEC
00322                        |MSG_CMSG_CLOEXEC
00323 #endif
00324                        );
00325 
00326   if (bytes_read < 0)
00327     {
00328       if (errno == EINTR)
00329         goto again;
00330       else
00331         {
00332           /* put length back (note that this doesn't actually realloc anything) */
00333           _dbus_string_set_length (buffer, start);
00334           return -1;
00335         }
00336     }
00337   else
00338     {
00339       struct cmsghdr *cm;
00340       dbus_bool_t found = FALSE;
00341 
00342       if (m.msg_flags & MSG_CTRUNC)
00343         {
00344           /* Hmm, apparently the control data was truncated. The bad
00345              thing is that we might have completely lost a couple of fds
00346              without chance to recover them. Hence let's treat this as a
00347              serious error. */
00348 
00349           errno = ENOSPC;
00350           _dbus_string_set_length (buffer, start);
00351           return -1;
00352         }
00353 
00354       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00355         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00356           {
00357             unsigned i;
00358 
00359             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00360             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00361 
00362             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00363             found = TRUE;
00364 
00365             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00366                worked, hence we need to go through this list and set
00367                CLOEXEC everywhere in any case */
00368             for (i = 0; i < *n_fds; i++)
00369               _dbus_fd_set_close_on_exec(fds[i]);
00370 
00371             break;
00372           }
00373 
00374       if (!found)
00375         *n_fds = 0;
00376 
00377       /* put length back (doesn't actually realloc) */
00378       _dbus_string_set_length (buffer, start + bytes_read);
00379 
00380 #if 0
00381       if (bytes_read > 0)
00382         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00383 #endif
00384 
00385       return bytes_read;
00386     }
00387 #endif
00388 }
00389 
00390 int
00391 _dbus_write_socket_with_unix_fds(int               fd,
00392                                  const DBusString *buffer,
00393                                  int               start,
00394                                  int               len,
00395                                  const int        *fds,
00396                                  int               n_fds) {
00397 
00398 #ifndef HAVE_UNIX_FD_PASSING
00399 
00400   if (n_fds > 0) {
00401     errno = ENOTSUP;
00402     return -1;
00403   }
00404 
00405   return _dbus_write_socket(fd, buffer, start, len);
00406 #else
00407   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00408 #endif
00409 }
00410 
00411 int
00412 _dbus_write_socket_with_unix_fds_two(int               fd,
00413                                      const DBusString *buffer1,
00414                                      int               start1,
00415                                      int               len1,
00416                                      const DBusString *buffer2,
00417                                      int               start2,
00418                                      int               len2,
00419                                      const int        *fds,
00420                                      int               n_fds) {
00421 
00422 #ifndef HAVE_UNIX_FD_PASSING
00423 
00424   if (n_fds > 0) {
00425     errno = ENOTSUP;
00426     return -1;
00427   }
00428 
00429   return _dbus_write_socket_two(fd,
00430                                 buffer1, start1, len1,
00431                                 buffer2, start2, len2);
00432 #else
00433 
00434   struct msghdr m;
00435   struct cmsghdr *cm;
00436   struct iovec iov[2];
00437   int bytes_written;
00438 
00439   _dbus_assert (len1 >= 0);
00440   _dbus_assert (len2 >= 0);
00441   _dbus_assert (n_fds >= 0);
00442 
00443   _DBUS_ZERO(iov);
00444   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00445   iov[0].iov_len = len1;
00446 
00447   if (buffer2)
00448     {
00449       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00450       iov[1].iov_len = len2;
00451     }
00452 
00453   _DBUS_ZERO(m);
00454   m.msg_iov = iov;
00455   m.msg_iovlen = buffer2 ? 2 : 1;
00456 
00457   if (n_fds > 0)
00458     {
00459       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00460       m.msg_control = alloca(m.msg_controllen);
00461       memset(m.msg_control, 0, m.msg_controllen);
00462 
00463       cm = CMSG_FIRSTHDR(&m);
00464       cm->cmsg_level = SOL_SOCKET;
00465       cm->cmsg_type = SCM_RIGHTS;
00466       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00467       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00468     }
00469 
00470  again:
00471 
00472   bytes_written = sendmsg (fd, &m, 0
00473 #if HAVE_DECL_MSG_NOSIGNAL
00474                            |MSG_NOSIGNAL
00475 #endif
00476                            );
00477 
00478   if (bytes_written < 0 && errno == EINTR)
00479     goto again;
00480 
00481 #if 0
00482   if (bytes_written > 0)
00483     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00484 #endif
00485 
00486   return bytes_written;
00487 #endif
00488 }
00489 
00503 int
00504 _dbus_write_socket_two (int               fd,
00505                         const DBusString *buffer1,
00506                         int               start1,
00507                         int               len1,
00508                         const DBusString *buffer2,
00509                         int               start2,
00510                         int               len2)
00511 {
00512 #if HAVE_DECL_MSG_NOSIGNAL
00513   struct iovec vectors[2];
00514   const char *data1;
00515   const char *data2;
00516   int bytes_written;
00517   struct msghdr m;
00518 
00519   _dbus_assert (buffer1 != NULL);
00520   _dbus_assert (start1 >= 0);
00521   _dbus_assert (start2 >= 0);
00522   _dbus_assert (len1 >= 0);
00523   _dbus_assert (len2 >= 0);
00524 
00525   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00526 
00527   if (buffer2 != NULL)
00528     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00529   else
00530     {
00531       data2 = NULL;
00532       start2 = 0;
00533       len2 = 0;
00534     }
00535 
00536   vectors[0].iov_base = (char*) data1;
00537   vectors[0].iov_len = len1;
00538   vectors[1].iov_base = (char*) data2;
00539   vectors[1].iov_len = len2;
00540 
00541   _DBUS_ZERO(m);
00542   m.msg_iov = vectors;
00543   m.msg_iovlen = data2 ? 2 : 1;
00544 
00545  again:
00546 
00547   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00548 
00549   if (bytes_written < 0 && errno == EINTR)
00550     goto again;
00551 
00552   return bytes_written;
00553 
00554 #else
00555   return _dbus_write_two (fd, buffer1, start1, len1,
00556                           buffer2, start2, len2);
00557 #endif
00558 }
00559 
00560 dbus_bool_t
00561 _dbus_socket_is_invalid (int fd)
00562 {
00563     return fd < 0 ? TRUE : FALSE;
00564 }
00565 
00582 int
00583 _dbus_read (int               fd,
00584             DBusString       *buffer,
00585             int               count)
00586 {
00587   int bytes_read;
00588   int start;
00589   char *data;
00590 
00591   _dbus_assert (count >= 0);
00592 
00593   start = _dbus_string_get_length (buffer);
00594 
00595   if (!_dbus_string_lengthen (buffer, count))
00596     {
00597       errno = ENOMEM;
00598       return -1;
00599     }
00600 
00601   data = _dbus_string_get_data_len (buffer, start, count);
00602 
00603  again:
00604 
00605   bytes_read = read (fd, data, count);
00606 
00607   if (bytes_read < 0)
00608     {
00609       if (errno == EINTR)
00610         goto again;
00611       else
00612         {
00613           /* put length back (note that this doesn't actually realloc anything) */
00614           _dbus_string_set_length (buffer, start);
00615           return -1;
00616         }
00617     }
00618   else
00619     {
00620       /* put length back (doesn't actually realloc) */
00621       _dbus_string_set_length (buffer, start + bytes_read);
00622 
00623 #if 0
00624       if (bytes_read > 0)
00625         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00626 #endif
00627 
00628       return bytes_read;
00629     }
00630 }
00631 
00642 int
00643 _dbus_write (int               fd,
00644              const DBusString *buffer,
00645              int               start,
00646              int               len)
00647 {
00648   const char *data;
00649   int bytes_written;
00650 
00651   data = _dbus_string_get_const_data_len (buffer, start, len);
00652 
00653  again:
00654 
00655   bytes_written = write (fd, data, len);
00656 
00657   if (bytes_written < 0 && errno == EINTR)
00658     goto again;
00659 
00660 #if 0
00661   if (bytes_written > 0)
00662     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00663 #endif
00664 
00665   return bytes_written;
00666 }
00667 
00688 int
00689 _dbus_write_two (int               fd,
00690                  const DBusString *buffer1,
00691                  int               start1,
00692                  int               len1,
00693                  const DBusString *buffer2,
00694                  int               start2,
00695                  int               len2)
00696 {
00697   _dbus_assert (buffer1 != NULL);
00698   _dbus_assert (start1 >= 0);
00699   _dbus_assert (start2 >= 0);
00700   _dbus_assert (len1 >= 0);
00701   _dbus_assert (len2 >= 0);
00702 
00703 #ifdef HAVE_WRITEV
00704   {
00705     struct iovec vectors[2];
00706     const char *data1;
00707     const char *data2;
00708     int bytes_written;
00709 
00710     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00711 
00712     if (buffer2 != NULL)
00713       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00714     else
00715       {
00716         data2 = NULL;
00717         start2 = 0;
00718         len2 = 0;
00719       }
00720 
00721     vectors[0].iov_base = (char*) data1;
00722     vectors[0].iov_len = len1;
00723     vectors[1].iov_base = (char*) data2;
00724     vectors[1].iov_len = len2;
00725 
00726   again:
00727 
00728     bytes_written = writev (fd,
00729                             vectors,
00730                             data2 ? 2 : 1);
00731 
00732     if (bytes_written < 0 && errno == EINTR)
00733       goto again;
00734 
00735     return bytes_written;
00736   }
00737 #else /* HAVE_WRITEV */
00738   {
00739     int ret1;
00740 
00741     ret1 = _dbus_write (fd, buffer1, start1, len1);
00742     if (ret1 == len1 && buffer2 != NULL)
00743       {
00744         ret2 = _dbus_write (fd, buffer2, start2, len2);
00745         if (ret2 < 0)
00746           ret2 = 0; /* we can't report an error as the first write was OK */
00747 
00748         return ret1 + ret2;
00749       }
00750     else
00751       return ret1;
00752   }
00753 #endif /* !HAVE_WRITEV */
00754 }
00755 
00756 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00757 
00787 int
00788 _dbus_connect_unix_socket (const char     *path,
00789                            dbus_bool_t     abstract,
00790                            DBusError      *error)
00791 {
00792   int fd;
00793   size_t path_len;
00794   struct sockaddr_un addr;
00795 
00796   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00797 
00798   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00799                  path, abstract);
00800 
00801 
00802   if (!_dbus_open_unix_socket (&fd, error))
00803     {
00804       _DBUS_ASSERT_ERROR_IS_SET(error);
00805       return -1;
00806     }
00807   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00808 
00809   _DBUS_ZERO (addr);
00810   addr.sun_family = AF_UNIX;
00811   path_len = strlen (path);
00812 
00813   if (abstract)
00814     {
00815 #ifdef HAVE_ABSTRACT_SOCKETS
00816       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00817       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00818 
00819       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00820         {
00821           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00822                       "Abstract socket name too long\n");
00823           _dbus_close (fd, NULL);
00824           return -1;
00825         }
00826 
00827       strncpy (&addr.sun_path[1], path, path_len);
00828       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00829 #else /* HAVE_ABSTRACT_SOCKETS */
00830       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00831                       "Operating system does not support abstract socket namespace\n");
00832       _dbus_close (fd, NULL);
00833       return -1;
00834 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00835     }
00836   else
00837     {
00838       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00839         {
00840           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00841                       "Socket name too long\n");
00842           _dbus_close (fd, NULL);
00843           return -1;
00844         }
00845 
00846       strncpy (addr.sun_path, path, path_len);
00847     }
00848 
00849   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00850     {
00851       dbus_set_error (error,
00852                       _dbus_error_from_errno (errno),
00853                       "Failed to connect to socket %s: %s",
00854                       path, _dbus_strerror (errno));
00855 
00856       _dbus_close (fd, NULL);
00857       return -1;
00858     }
00859 
00860   if (!_dbus_set_fd_nonblocking (fd, error))
00861     {
00862       _DBUS_ASSERT_ERROR_IS_SET (error);
00863 
00864       _dbus_close (fd, NULL);
00865       return -1;
00866     }
00867 
00868   return fd;
00869 }
00870 
00883 int
00884 _dbus_connect_exec (const char     *path,
00885                     char *const    argv[],
00886                     DBusError      *error)
00887 {
00888   int fds[2];
00889   pid_t pid;
00890 
00891   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00892 
00893   _dbus_verbose ("connecting to process %s\n", path);
00894 
00895   if (socketpair (AF_UNIX, SOCK_STREAM
00896 #ifdef SOCK_CLOEXEC
00897                   |SOCK_CLOEXEC
00898 #endif
00899                   , 0, fds) < 0)
00900     {
00901       dbus_set_error (error,
00902                       _dbus_error_from_errno (errno),
00903                       "Failed to create socket pair: %s",
00904                       _dbus_strerror (errno));
00905       return -1;
00906     }
00907 
00908   _dbus_fd_set_close_on_exec (fds[0]);
00909   _dbus_fd_set_close_on_exec (fds[1]);
00910 
00911   pid = fork ();
00912   if (pid < 0)
00913     {
00914       dbus_set_error (error,
00915                       _dbus_error_from_errno (errno),
00916                       "Failed to fork() to call %s: %s",
00917                       path, _dbus_strerror (errno));
00918       close (fds[0]);
00919       close (fds[1]);
00920       return -1;
00921     }
00922 
00923   if (pid == 0)
00924     {
00925       /* child */
00926       close (fds[0]);
00927 
00928       dup2 (fds[1], STDIN_FILENO);
00929       dup2 (fds[1], STDOUT_FILENO);
00930 
00931       if (fds[1] != STDIN_FILENO &&
00932           fds[1] != STDOUT_FILENO)
00933         close (fds[1]);
00934 
00935       /* Inherit STDERR and the controlling terminal from the
00936          parent */
00937 
00938       _dbus_close_all ();
00939 
00940       execvp (path, argv);
00941 
00942       fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
00943 
00944       _exit(1);
00945     }
00946 
00947   /* parent */
00948   close (fds[1]);
00949 
00950   if (!_dbus_set_fd_nonblocking (fds[0], error))
00951     {
00952       _DBUS_ASSERT_ERROR_IS_SET (error);
00953 
00954       close (fds[0]);
00955       return -1;
00956     }
00957 
00958   return fds[0];
00959 }
00960 
00970 static dbus_bool_t
00971 _dbus_set_local_creds (int fd, dbus_bool_t on)
00972 {
00973   dbus_bool_t retval = TRUE;
00974 
00975 #if defined(HAVE_CMSGCRED)
00976   /* NOOP just to make sure only one codepath is used
00977    *      and to prefer CMSGCRED
00978    */
00979 #elif defined(LOCAL_CREDS)
00980   int val = on ? 1 : 0;
00981   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00982     {
00983       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00984       retval = FALSE;
00985     }
00986   else
00987     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00988                    on ? "enabled" : "disabled", fd);
00989 #endif
00990 
00991   return retval;
00992 }
00993 
01011 int
01012 _dbus_listen_unix_socket (const char     *path,
01013                           dbus_bool_t     abstract,
01014                           DBusError      *error)
01015 {
01016   int listen_fd;
01017   struct sockaddr_un addr;
01018   size_t path_len;
01019   unsigned int reuseaddr;
01020 
01021   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01022 
01023   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
01024                  path, abstract);
01025 
01026   if (!_dbus_open_unix_socket (&listen_fd, error))
01027     {
01028       _DBUS_ASSERT_ERROR_IS_SET(error);
01029       return -1;
01030     }
01031   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01032 
01033   _DBUS_ZERO (addr);
01034   addr.sun_family = AF_UNIX;
01035   path_len = strlen (path);
01036 
01037   if (abstract)
01038     {
01039 #ifdef HAVE_ABSTRACT_SOCKETS
01040       /* remember that abstract names aren't nul-terminated so we rely
01041        * on sun_path being filled in with zeroes above.
01042        */
01043       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
01044       path_len++; /* Account for the extra nul byte added to the start of sun_path */
01045 
01046       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01047         {
01048           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01049                       "Abstract socket name too long\n");
01050           _dbus_close (listen_fd, NULL);
01051           return -1;
01052         }
01053 
01054       strncpy (&addr.sun_path[1], path, path_len);
01055       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
01056 #else /* HAVE_ABSTRACT_SOCKETS */
01057       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01058                       "Operating system does not support abstract socket namespace\n");
01059       _dbus_close (listen_fd, NULL);
01060       return -1;
01061 #endif /* ! HAVE_ABSTRACT_SOCKETS */
01062     }
01063   else
01064     {
01065       /* Discussed security implications of this with Nalin,
01066        * and we couldn't think of where it would kick our ass, but
01067        * it still seems a bit sucky. It also has non-security suckage;
01068        * really we'd prefer to exit if the socket is already in use.
01069        * But there doesn't seem to be a good way to do this.
01070        *
01071        * Just to be extra careful, I threw in the stat() - clearly
01072        * the stat() can't *fix* any security issue, but it at least
01073        * avoids inadvertent/accidental data loss.
01074        */
01075       {
01076         struct stat sb;
01077 
01078         if (stat (path, &sb) == 0 &&
01079             S_ISSOCK (sb.st_mode))
01080           unlink (path);
01081       }
01082 
01083       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01084         {
01085           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01086                       "Abstract socket name too long\n");
01087           _dbus_close (listen_fd, NULL);
01088           return -1;
01089         }
01090 
01091       strncpy (addr.sun_path, path, path_len);
01092     }
01093 
01094   reuseaddr = 1;
01095   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01096     {
01097       _dbus_warn ("Failed to set socket option\"%s\": %s",
01098                   path, _dbus_strerror (errno));
01099     }
01100 
01101   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01102     {
01103       dbus_set_error (error, _dbus_error_from_errno (errno),
01104                       "Failed to bind socket \"%s\": %s",
01105                       path, _dbus_strerror (errno));
01106       _dbus_close (listen_fd, NULL);
01107       return -1;
01108     }
01109 
01110   if (listen (listen_fd, 30 /* backlog */) < 0)
01111     {
01112       dbus_set_error (error, _dbus_error_from_errno (errno),
01113                       "Failed to listen on socket \"%s\": %s",
01114                       path, _dbus_strerror (errno));
01115       _dbus_close (listen_fd, NULL);
01116       return -1;
01117     }
01118 
01119   if (!_dbus_set_local_creds (listen_fd, TRUE))
01120     {
01121       dbus_set_error (error, _dbus_error_from_errno (errno),
01122                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01123                       path, _dbus_strerror (errno));
01124       close (listen_fd);
01125       return -1;
01126     }
01127 
01128   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01129     {
01130       _DBUS_ASSERT_ERROR_IS_SET (error);
01131       _dbus_close (listen_fd, NULL);
01132       return -1;
01133     }
01134 
01135   /* Try opening up the permissions, but if we can't, just go ahead
01136    * and continue, maybe it will be good enough.
01137    */
01138   if (!abstract && chmod (path, 0777) < 0)
01139     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01140                 path);
01141 
01142   return listen_fd;
01143 }
01144 
01155 int
01156 _dbus_listen_systemd_sockets (int       **fds,
01157                               DBusError *error)
01158 {
01159   int r, n;
01160   unsigned fd;
01161   int *new_fds;
01162 
01163   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01164 
01165   n = sd_listen_fds (TRUE);
01166   if (n < 0)
01167     {
01168       dbus_set_error (error, _dbus_error_from_errno (-n),
01169                       "Failed to acquire systemd socket: %s",
01170                       _dbus_strerror (-n));
01171       return -1;
01172     }
01173 
01174   if (n <= 0)
01175     {
01176       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01177                       "No socket received.");
01178       return -1;
01179     }
01180 
01181   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01182     {
01183       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01184       if (r < 0)
01185         {
01186           dbus_set_error (error, _dbus_error_from_errno (-r),
01187                           "Failed to verify systemd socket type: %s",
01188                           _dbus_strerror (-r));
01189           return -1;
01190         }
01191 
01192       if (!r)
01193         {
01194           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01195                           "Passed socket has wrong type.");
01196           return -1;
01197         }
01198     }
01199 
01200   /* OK, the file descriptors are all good, so let's take posession of
01201      them then. */
01202 
01203   new_fds = dbus_new (int, n);
01204   if (!new_fds)
01205     {
01206       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01207                       "Failed to allocate file handle array.");
01208       goto fail;
01209     }
01210 
01211   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01212     {
01213       if (!_dbus_set_local_creds (fd, TRUE))
01214         {
01215           dbus_set_error (error, _dbus_error_from_errno (errno),
01216                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01217                           _dbus_strerror (errno));
01218           goto fail;
01219         }
01220 
01221       if (!_dbus_set_fd_nonblocking (fd, error))
01222         {
01223           _DBUS_ASSERT_ERROR_IS_SET (error);
01224           goto fail;
01225         }
01226 
01227       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01228     }
01229 
01230   *fds = new_fds;
01231   return n;
01232 
01233  fail:
01234 
01235   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01236     {
01237       _dbus_close (fd, NULL);
01238     }
01239 
01240   dbus_free (new_fds);
01241   return -1;
01242 }
01243 
01257 int
01258 _dbus_connect_tcp_socket (const char     *host,
01259                           const char     *port,
01260                           const char     *family,
01261                           DBusError      *error)
01262 {
01263     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01264 }
01265 
01266 int
01267 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01268                                      const char     *port,
01269                                      const char     *family,
01270                                      const char     *noncefile,
01271                                      DBusError      *error)
01272 {
01273   int saved_errno = 0;
01274   int fd = -1, res;
01275   struct addrinfo hints;
01276   struct addrinfo *ai, *tmp;
01277 
01278   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01279 
01280   _DBUS_ZERO (hints);
01281 
01282   if (!family)
01283     hints.ai_family = AF_UNSPEC;
01284   else if (!strcmp(family, "ipv4"))
01285     hints.ai_family = AF_INET;
01286   else if (!strcmp(family, "ipv6"))
01287     hints.ai_family = AF_INET6;
01288   else
01289     {
01290       dbus_set_error (error,
01291                       DBUS_ERROR_BAD_ADDRESS,
01292                       "Unknown address family %s", family);
01293       return -1;
01294     }
01295   hints.ai_protocol = IPPROTO_TCP;
01296   hints.ai_socktype = SOCK_STREAM;
01297   hints.ai_flags = AI_ADDRCONFIG;
01298 
01299   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01300     {
01301       dbus_set_error (error,
01302                       _dbus_error_from_errno (errno),
01303                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01304                       host, port, gai_strerror(res), res);
01305       return -1;
01306     }
01307 
01308   tmp = ai;
01309   while (tmp)
01310     {
01311       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01312         {
01313           freeaddrinfo(ai);
01314           _DBUS_ASSERT_ERROR_IS_SET(error);
01315           return -1;
01316         }
01317       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01318 
01319       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01320         {
01321           saved_errno = errno;
01322           _dbus_close(fd, NULL);
01323           fd = -1;
01324           tmp = tmp->ai_next;
01325           continue;
01326         }
01327 
01328       break;
01329     }
01330   freeaddrinfo(ai);
01331 
01332   if (fd == -1)
01333     {
01334       dbus_set_error (error,
01335                       _dbus_error_from_errno (saved_errno),
01336                       "Failed to connect to socket \"%s:%s\" %s",
01337                       host, port, _dbus_strerror(saved_errno));
01338       return -1;
01339     }
01340 
01341   if (noncefile != NULL)
01342     {
01343       DBusString noncefileStr;
01344       dbus_bool_t ret;
01345       _dbus_string_init_const (&noncefileStr, noncefile);
01346       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01347       _dbus_string_free (&noncefileStr);
01348 
01349       if (!ret)
01350     {
01351       _dbus_close (fd, NULL);
01352           return -1;
01353         }
01354     }
01355 
01356   if (!_dbus_set_fd_nonblocking (fd, error))
01357     {
01358       _dbus_close (fd, NULL);
01359       return -1;
01360     }
01361 
01362   return fd;
01363 }
01364 
01381 int
01382 _dbus_listen_tcp_socket (const char     *host,
01383                          const char     *port,
01384                          const char     *family,
01385                          DBusString     *retport,
01386                          int           **fds_p,
01387                          DBusError      *error)
01388 {
01389   int saved_errno;
01390   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01391   struct addrinfo hints;
01392   struct addrinfo *ai, *tmp;
01393   unsigned int reuseaddr;
01394 
01395   *fds_p = NULL;
01396   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01397 
01398   _DBUS_ZERO (hints);
01399 
01400   if (!family)
01401     hints.ai_family = AF_UNSPEC;
01402   else if (!strcmp(family, "ipv4"))
01403     hints.ai_family = AF_INET;
01404   else if (!strcmp(family, "ipv6"))
01405     hints.ai_family = AF_INET6;
01406   else
01407     {
01408       dbus_set_error (error,
01409                       DBUS_ERROR_BAD_ADDRESS,
01410                       "Unknown address family %s", family);
01411       return -1;
01412     }
01413 
01414   hints.ai_protocol = IPPROTO_TCP;
01415   hints.ai_socktype = SOCK_STREAM;
01416   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01417 
01418  redo_lookup_with_port:
01419   ai = NULL;
01420   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01421     {
01422       dbus_set_error (error,
01423                       _dbus_error_from_errno (errno),
01424                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01425                       host ? host : "*", port, gai_strerror(res), res);
01426       goto failed;
01427     }
01428 
01429   tmp = ai;
01430   while (tmp)
01431     {
01432       int fd = -1, *newlisten_fd;
01433       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01434         {
01435           _DBUS_ASSERT_ERROR_IS_SET(error);
01436           goto failed;
01437         }
01438       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01439 
01440       reuseaddr = 1;
01441       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01442         {
01443           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01444                       host ? host : "*", port, _dbus_strerror (errno));
01445         }
01446 
01447       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01448         {
01449           saved_errno = errno;
01450           _dbus_close(fd, NULL);
01451           if (saved_errno == EADDRINUSE)
01452             {
01453               /* Depending on kernel policy, it may or may not
01454                  be neccessary to bind to both IPv4 & 6 addresses
01455                  so ignore EADDRINUSE here */
01456               tmp = tmp->ai_next;
01457               continue;
01458             }
01459           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01460                           "Failed to bind socket \"%s:%s\": %s",
01461                           host ? host : "*", port, _dbus_strerror (saved_errno));
01462           goto failed;
01463         }
01464 
01465       if (listen (fd, 30 /* backlog */) < 0)
01466         {
01467           saved_errno = errno;
01468           _dbus_close (fd, NULL);
01469           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01470                           "Failed to listen on socket \"%s:%s\": %s",
01471                           host ? host : "*", port, _dbus_strerror (saved_errno));
01472           goto failed;
01473         }
01474 
01475       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01476       if (!newlisten_fd)
01477         {
01478           saved_errno = errno;
01479           _dbus_close (fd, NULL);
01480           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01481                           "Failed to allocate file handle array: %s",
01482                           _dbus_strerror (saved_errno));
01483           goto failed;
01484         }
01485       listen_fd = newlisten_fd;
01486       listen_fd[nlisten_fd] = fd;
01487       nlisten_fd++;
01488 
01489       if (!_dbus_string_get_length(retport))
01490         {
01491           /* If the user didn't specify a port, or used 0, then
01492              the kernel chooses a port. After the first address
01493              is bound to, we need to force all remaining addresses
01494              to use the same port */
01495           if (!port || !strcmp(port, "0"))
01496             {
01497               int result;
01498               struct sockaddr_storage addr;
01499               socklen_t addrlen;
01500               char portbuf[50];
01501 
01502               addrlen = sizeof(addr);
01503               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01504 
01505               if (result == -1 ||
01506                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01507                                       portbuf, sizeof(portbuf),
01508                                       NI_NUMERICHOST)) != 0)
01509                 {
01510                   dbus_set_error (error, _dbus_error_from_errno (errno),
01511                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01512                                   host ? host : "*", port, gai_strerror(res), res);
01513                   goto failed;
01514                 }
01515               if (!_dbus_string_append(retport, portbuf))
01516                 {
01517                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01518                   goto failed;
01519                 }
01520 
01521               /* Release current address list & redo lookup */
01522               port = _dbus_string_get_const_data(retport);
01523               freeaddrinfo(ai);
01524               goto redo_lookup_with_port;
01525             }
01526           else
01527             {
01528               if (!_dbus_string_append(retport, port))
01529                 {
01530                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01531                     goto failed;
01532                 }
01533             }
01534         }
01535 
01536       tmp = tmp->ai_next;
01537     }
01538   freeaddrinfo(ai);
01539   ai = NULL;
01540 
01541   if (!nlisten_fd)
01542     {
01543       errno = EADDRINUSE;
01544       dbus_set_error (error, _dbus_error_from_errno (errno),
01545                       "Failed to bind socket \"%s:%s\": %s",
01546                       host ? host : "*", port, _dbus_strerror (errno));
01547       goto failed;
01548     }
01549 
01550   for (i = 0 ; i < nlisten_fd ; i++)
01551     {
01552       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01553         {
01554           goto failed;
01555         }
01556     }
01557 
01558   *fds_p = listen_fd;
01559 
01560   return nlisten_fd;
01561 
01562  failed:
01563   if (ai)
01564     freeaddrinfo(ai);
01565   for (i = 0 ; i < nlisten_fd ; i++)
01566     _dbus_close(listen_fd[i], NULL);
01567   dbus_free(listen_fd);
01568   return -1;
01569 }
01570 
01571 static dbus_bool_t
01572 write_credentials_byte (int             server_fd,
01573                         DBusError      *error)
01574 {
01575   int bytes_written;
01576   char buf[1] = { '\0' };
01577 #if defined(HAVE_CMSGCRED)
01578   union {
01579           struct cmsghdr hdr;
01580           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01581   } cmsg;
01582   struct iovec iov;
01583   struct msghdr msg;
01584   iov.iov_base = buf;
01585   iov.iov_len = 1;
01586 
01587   _DBUS_ZERO(msg);
01588   msg.msg_iov = &iov;
01589   msg.msg_iovlen = 1;
01590 
01591   msg.msg_control = (caddr_t) &cmsg;
01592   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01593   _DBUS_ZERO(cmsg);
01594   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01595   cmsg.hdr.cmsg_level = SOL_SOCKET;
01596   cmsg.hdr.cmsg_type = SCM_CREDS;
01597 #endif
01598 
01599   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01600 
01601  again:
01602 
01603 #if defined(HAVE_CMSGCRED)
01604   bytes_written = sendmsg (server_fd, &msg, 0
01605 #if HAVE_DECL_MSG_NOSIGNAL
01606                            |MSG_NOSIGNAL
01607 #endif
01608                            );
01609 #else
01610   bytes_written = send (server_fd, buf, 1, 0
01611 #if HAVE_DECL_MSG_NOSIGNAL
01612                         |MSG_NOSIGNAL
01613 #endif
01614                         );
01615 #endif
01616 
01617   if (bytes_written < 0 && errno == EINTR)
01618     goto again;
01619 
01620   if (bytes_written < 0)
01621     {
01622       dbus_set_error (error, _dbus_error_from_errno (errno),
01623                       "Failed to write credentials byte: %s",
01624                      _dbus_strerror (errno));
01625       return FALSE;
01626     }
01627   else if (bytes_written == 0)
01628     {
01629       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01630                       "wrote zero bytes writing credentials byte");
01631       return FALSE;
01632     }
01633   else
01634     {
01635       _dbus_assert (bytes_written == 1);
01636       _dbus_verbose ("wrote credentials byte\n");
01637       return TRUE;
01638     }
01639 }
01640 
01662 dbus_bool_t
01663 _dbus_read_credentials_socket  (int              client_fd,
01664                                 DBusCredentials *credentials,
01665                                 DBusError       *error)
01666 {
01667   struct msghdr msg;
01668   struct iovec iov;
01669   char buf;
01670   dbus_uid_t uid_read;
01671   dbus_pid_t pid_read;
01672   int bytes_read;
01673 
01674 #ifdef HAVE_CMSGCRED
01675   union {
01676     struct cmsghdr hdr;
01677     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01678   } cmsg;
01679 
01680 #elif defined(LOCAL_CREDS)
01681   struct {
01682     struct cmsghdr hdr;
01683     struct sockcred cred;
01684   } cmsg;
01685 #endif
01686 
01687   uid_read = DBUS_UID_UNSET;
01688   pid_read = DBUS_PID_UNSET;
01689 
01690   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01691 
01692   /* The POSIX spec certainly doesn't promise this, but
01693    * we need these assertions to fail as soon as we're wrong about
01694    * it so we can do the porting fixups
01695    */
01696   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01697   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01698   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01699 
01700   _dbus_credentials_clear (credentials);
01701 
01702   /* Systems supporting LOCAL_CREDS are configured to have this feature
01703    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01704    * the connection.  Therefore, the received message must carry the
01705    * credentials information without doing anything special.
01706    */
01707 
01708   iov.iov_base = &buf;
01709   iov.iov_len = 1;
01710 
01711   _DBUS_ZERO(msg);
01712   msg.msg_iov = &iov;
01713   msg.msg_iovlen = 1;
01714 
01715 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01716   _DBUS_ZERO(cmsg);
01717   msg.msg_control = (caddr_t) &cmsg;
01718   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01719 #endif
01720 
01721  again:
01722   bytes_read = recvmsg (client_fd, &msg, 0);
01723 
01724   if (bytes_read < 0)
01725     {
01726       if (errno == EINTR)
01727         goto again;
01728 
01729       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01730        * normally only call read_credentials if the socket was ready
01731        * for reading
01732        */
01733 
01734       dbus_set_error (error, _dbus_error_from_errno (errno),
01735                       "Failed to read credentials byte: %s",
01736                       _dbus_strerror (errno));
01737       return FALSE;
01738     }
01739   else if (bytes_read == 0)
01740     {
01741       /* this should not happen unless we are using recvmsg wrong,
01742        * so is essentially here for paranoia
01743        */
01744       dbus_set_error (error, DBUS_ERROR_FAILED,
01745                       "Failed to read credentials byte (zero-length read)");
01746       return FALSE;
01747     }
01748   else if (buf != '\0')
01749     {
01750       dbus_set_error (error, DBUS_ERROR_FAILED,
01751                       "Credentials byte was not nul");
01752       return FALSE;
01753     }
01754 
01755 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01756   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01757                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01758     {
01759       dbus_set_error (error, DBUS_ERROR_FAILED,
01760                       "Message from recvmsg() was not SCM_CREDS");
01761       return FALSE;
01762     }
01763 #endif
01764 
01765   _dbus_verbose ("read credentials byte\n");
01766 
01767   {
01768 #ifdef SO_PEERCRED
01769 #ifdef __OpenBSD__
01770     struct sockpeercred cr;
01771 #else
01772     struct ucred cr;
01773 #endif
01774     int cr_len = sizeof (cr);
01775 
01776     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01777         cr_len == sizeof (cr))
01778       {
01779         pid_read = cr.pid;
01780         uid_read = cr.uid;
01781       }
01782     else
01783       {
01784         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01785                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01786       }
01787 #elif defined(HAVE_CMSGCRED)
01788     struct cmsgcred *cred;
01789 
01790     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01791     pid_read = cred->cmcred_pid;
01792     uid_read = cred->cmcred_euid;
01793 #elif defined(LOCAL_CREDS)
01794     pid_read = DBUS_PID_UNSET;
01795     uid_read = cmsg.cred.sc_uid;
01796     /* Since we have already got the credentials from this socket, we can
01797      * disable its LOCAL_CREDS flag if it was ever set. */
01798     _dbus_set_local_creds (client_fd, FALSE);
01799 #elif defined(HAVE_GETPEEREID)
01800     uid_t euid;
01801     gid_t egid;
01802     if (getpeereid (client_fd, &euid, &egid) == 0)
01803       {
01804         uid_read = euid;
01805       }
01806     else
01807       {
01808         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01809       }
01810 #elif defined(HAVE_GETPEERUCRED)
01811     ucred_t * ucred = NULL;
01812     if (getpeerucred (client_fd, &ucred) == 0)
01813       {
01814         pid_read = ucred_getpid (ucred);
01815         uid_read = ucred_geteuid (ucred);
01816 #ifdef HAVE_ADT
01817         /* generate audit session data based on socket ucred */
01818         adt_session_data_t *adth = NULL;
01819         adt_export_data_t *data = NULL;
01820         size_t size = 0;
01821         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01822           {
01823             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01824           }
01825         else
01826           {
01827             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01828               {
01829                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01830               }
01831             else
01832               {
01833                 size = adt_export_session_data (adth, &data);
01834                 if (size <= 0)
01835                   {
01836                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01837                   }
01838                 else
01839                   {
01840                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01841                     free (data);
01842                   }
01843               }
01844             (void) adt_end_session (adth);
01845           }
01846 #endif /* HAVE_ADT */
01847       }
01848     else
01849       {
01850         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01851       }
01852     if (ucred != NULL)
01853       ucred_free (ucred);
01854 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01855     _dbus_verbose ("Socket credentials not supported on this OS\n");
01856 #endif
01857   }
01858 
01859   _dbus_verbose ("Credentials:"
01860                  "  pid "DBUS_PID_FORMAT
01861                  "  uid "DBUS_UID_FORMAT
01862                  "\n",
01863                  pid_read,
01864                  uid_read);
01865 
01866   if (pid_read != DBUS_PID_UNSET)
01867     {
01868       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01869         {
01870           _DBUS_SET_OOM (error);
01871           return FALSE;
01872         }
01873     }
01874 
01875   if (uid_read != DBUS_UID_UNSET)
01876     {
01877       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01878         {
01879           _DBUS_SET_OOM (error);
01880           return FALSE;
01881         }
01882     }
01883 
01884   return TRUE;
01885 }
01886 
01904 dbus_bool_t
01905 _dbus_send_credentials_socket  (int              server_fd,
01906                                 DBusError       *error)
01907 {
01908   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01909 
01910   if (write_credentials_byte (server_fd, error))
01911     return TRUE;
01912   else
01913     return FALSE;
01914 }
01915 
01925 int
01926 _dbus_accept  (int listen_fd)
01927 {
01928   int client_fd;
01929   struct sockaddr addr;
01930   socklen_t addrlen;
01931 #ifdef HAVE_ACCEPT4
01932   dbus_bool_t cloexec_done;
01933 #endif
01934 
01935   addrlen = sizeof (addr);
01936 
01937  retry:
01938 
01939 #ifdef HAVE_ACCEPT4
01940   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01941   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01942   cloexec_done = client_fd >= 0;
01943 
01944   if (client_fd < 0 && errno == ENOSYS)
01945 #endif
01946     {
01947       client_fd = accept (listen_fd, &addr, &addrlen);
01948     }
01949 
01950   if (client_fd < 0)
01951     {
01952       if (errno == EINTR)
01953         goto retry;
01954     }
01955 
01956   _dbus_verbose ("client fd %d accepted\n", client_fd);
01957 
01958 #ifdef HAVE_ACCEPT4
01959   if (!cloexec_done)
01960 #endif
01961     {
01962       _dbus_fd_set_close_on_exec(client_fd);
01963     }
01964 
01965   return client_fd;
01966 }
01967 
01976 dbus_bool_t
01977 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01978 {
01979   const char *directory;
01980   struct stat sb;
01981 
01982   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01983 
01984   directory = _dbus_string_get_const_data (dir);
01985 
01986   if (stat (directory, &sb) < 0)
01987     {
01988       dbus_set_error (error, _dbus_error_from_errno (errno),
01989                       "%s", _dbus_strerror (errno));
01990 
01991       return FALSE;
01992     }
01993 
01994   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01995       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01996     {
01997       dbus_set_error (error, DBUS_ERROR_FAILED,
01998                      "%s directory is not private to the user", directory);
01999       return FALSE;
02000     }
02001 
02002   return TRUE;
02003 }
02004 
02005 static dbus_bool_t
02006 fill_user_info_from_passwd (struct passwd *p,
02007                             DBusUserInfo  *info,
02008                             DBusError     *error)
02009 {
02010   _dbus_assert (p->pw_name != NULL);
02011   _dbus_assert (p->pw_dir != NULL);
02012 
02013   info->uid = p->pw_uid;
02014   info->primary_gid = p->pw_gid;
02015   info->username = _dbus_strdup (p->pw_name);
02016   info->homedir = _dbus_strdup (p->pw_dir);
02017 
02018   if (info->username == NULL ||
02019       info->homedir == NULL)
02020     {
02021       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02022       return FALSE;
02023     }
02024 
02025   return TRUE;
02026 }
02027 
02028 static dbus_bool_t
02029 fill_user_info (DBusUserInfo       *info,
02030                 dbus_uid_t          uid,
02031                 const DBusString   *username,
02032                 DBusError          *error)
02033 {
02034   const char *username_c;
02035 
02036   /* exactly one of username/uid provided */
02037   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
02038   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
02039 
02040   info->uid = DBUS_UID_UNSET;
02041   info->primary_gid = DBUS_GID_UNSET;
02042   info->group_ids = NULL;
02043   info->n_group_ids = 0;
02044   info->username = NULL;
02045   info->homedir = NULL;
02046 
02047   if (username != NULL)
02048     username_c = _dbus_string_get_const_data (username);
02049   else
02050     username_c = NULL;
02051 
02052   /* For now assuming that the getpwnam() and getpwuid() flavors
02053    * are always symmetrical, if not we have to add more configure
02054    * checks
02055    */
02056 
02057 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02058   {
02059     struct passwd *p;
02060     int result;
02061     size_t buflen;
02062     char *buf;
02063     struct passwd p_str;
02064 
02065     /* retrieve maximum needed size for buf */
02066     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02067 
02068     /* sysconf actually returns a long, but everything else expects size_t,
02069      * so just recast here.
02070      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
02071      */
02072     if ((long) buflen <= 0)
02073       buflen = 1024;
02074 
02075     result = -1;
02076     while (1)
02077       {
02078         buf = dbus_malloc (buflen);
02079         if (buf == NULL)
02080           {
02081             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02082             return FALSE;
02083           }
02084 
02085         p = NULL;
02086 #ifdef HAVE_POSIX_GETPWNAM_R
02087         if (uid != DBUS_UID_UNSET)
02088           result = getpwuid_r (uid, &p_str, buf, buflen,
02089                                &p);
02090         else
02091           result = getpwnam_r (username_c, &p_str, buf, buflen,
02092                                &p);
02093 #else
02094         if (uid != DBUS_UID_UNSET)
02095           p = getpwuid_r (uid, &p_str, buf, buflen);
02096         else
02097           p = getpwnam_r (username_c, &p_str, buf, buflen);
02098         result = 0;
02099 #endif /* !HAVE_POSIX_GETPWNAM_R */
02100         //Try a bigger buffer if ERANGE was returned
02101         if (result == ERANGE && buflen < 512 * 1024)
02102           {
02103             dbus_free (buf);
02104             buflen *= 2;
02105           }
02106         else
02107           {
02108             break;
02109           }
02110       }
02111     if (result == 0 && p == &p_str)
02112       {
02113         if (!fill_user_info_from_passwd (p, info, error))
02114           {
02115             dbus_free (buf);
02116             return FALSE;
02117           }
02118         dbus_free (buf);
02119       }
02120     else
02121       {
02122         dbus_set_error (error, _dbus_error_from_errno (errno),
02123                         "User \"%s\" unknown or no memory to allocate password entry\n",
02124                         username_c ? username_c : "???");
02125         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02126         dbus_free (buf);
02127         return FALSE;
02128       }
02129   }
02130 #else /* ! HAVE_GETPWNAM_R */
02131   {
02132     /* I guess we're screwed on thread safety here */
02133     struct passwd *p;
02134 
02135     if (uid != DBUS_UID_UNSET)
02136       p = getpwuid (uid);
02137     else
02138       p = getpwnam (username_c);
02139 
02140     if (p != NULL)
02141       {
02142         if (!fill_user_info_from_passwd (p, info, error))
02143           {
02144             return FALSE;
02145           }
02146       }
02147     else
02148       {
02149         dbus_set_error (error, _dbus_error_from_errno (errno),
02150                         "User \"%s\" unknown or no memory to allocate password entry\n",
02151                         username_c ? username_c : "???");
02152         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02153         return FALSE;
02154       }
02155   }
02156 #endif  /* ! HAVE_GETPWNAM_R */
02157 
02158   /* Fill this in so we can use it to get groups */
02159   username_c = info->username;
02160 
02161 #ifdef HAVE_GETGROUPLIST
02162   {
02163     gid_t *buf;
02164     int buf_count;
02165     int i;
02166     int initial_buf_count;
02167 
02168     initial_buf_count = 17;
02169     buf_count = initial_buf_count;
02170     buf = dbus_new (gid_t, buf_count);
02171     if (buf == NULL)
02172       {
02173         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02174         goto failed;
02175       }
02176 
02177     if (getgrouplist (username_c,
02178                       info->primary_gid,
02179                       buf, &buf_count) < 0)
02180       {
02181         gid_t *new;
02182         /* Presumed cause of negative return code: buf has insufficient
02183            entries to hold the entire group list. The Linux behavior in this
02184            case is to pass back the actual number of groups in buf_count, but
02185            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02186            So as a hack, try to help out a bit by guessing a larger
02187            number of groups, within reason.. might still fail, of course,
02188            but we can at least print a more informative message.  I looked up
02189            the "right way" to do this by downloading Apple's own source code
02190            for the "id" command, and it turns out that they use an
02191            undocumented library function getgrouplist_2 (!) which is not
02192            declared in any header in /usr/include (!!). That did not seem
02193            like the way to go here.
02194         */
02195         if (buf_count == initial_buf_count)
02196           {
02197             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02198           }
02199         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02200         if (new == NULL)
02201           {
02202             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02203             dbus_free (buf);
02204             goto failed;
02205           }
02206 
02207         buf = new;
02208 
02209         errno = 0;
02210         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02211           {
02212             if (errno == 0)
02213               {
02214                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02215                             username_c, buf_count, buf_count);
02216               }
02217             else
02218               {
02219                 dbus_set_error (error,
02220                                 _dbus_error_from_errno (errno),
02221                                 "Failed to get groups for username \"%s\" primary GID "
02222                                 DBUS_GID_FORMAT ": %s\n",
02223                                 username_c, info->primary_gid,
02224                                 _dbus_strerror (errno));
02225                 dbus_free (buf);
02226                 goto failed;
02227               }
02228           }
02229       }
02230 
02231     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02232     if (info->group_ids == NULL)
02233       {
02234         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02235         dbus_free (buf);
02236         goto failed;
02237       }
02238 
02239     for (i = 0; i < buf_count; ++i)
02240       info->group_ids[i] = buf[i];
02241 
02242     info->n_group_ids = buf_count;
02243 
02244     dbus_free (buf);
02245   }
02246 #else  /* HAVE_GETGROUPLIST */
02247   {
02248     /* We just get the one group ID */
02249     info->group_ids = dbus_new (dbus_gid_t, 1);
02250     if (info->group_ids == NULL)
02251       {
02252         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02253         goto failed;
02254       }
02255 
02256     info->n_group_ids = 1;
02257 
02258     (info->group_ids)[0] = info->primary_gid;
02259   }
02260 #endif /* HAVE_GETGROUPLIST */
02261 
02262   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02263 
02264   return TRUE;
02265 
02266  failed:
02267   _DBUS_ASSERT_ERROR_IS_SET (error);
02268   return FALSE;
02269 }
02270 
02279 dbus_bool_t
02280 _dbus_user_info_fill (DBusUserInfo     *info,
02281                       const DBusString *username,
02282                       DBusError        *error)
02283 {
02284   return fill_user_info (info, DBUS_UID_UNSET,
02285                          username, error);
02286 }
02287 
02296 dbus_bool_t
02297 _dbus_user_info_fill_uid (DBusUserInfo *info,
02298                           dbus_uid_t    uid,
02299                           DBusError    *error)
02300 {
02301   return fill_user_info (info, uid,
02302                          NULL, error);
02303 }
02304 
02312 dbus_bool_t
02313 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02314 {
02315   /* The POSIX spec certainly doesn't promise this, but
02316    * we need these assertions to fail as soon as we're wrong about
02317    * it so we can do the porting fixups
02318    */
02319   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02320   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02321   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02322 
02323   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02324     return FALSE;
02325   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02326     return FALSE;
02327 
02328   return TRUE;
02329 }
02330 
02342 dbus_bool_t
02343 _dbus_append_user_from_current_process (DBusString *str)
02344 {
02345   return _dbus_string_append_uint (str,
02346                                    _dbus_geteuid ());
02347 }
02348 
02353 dbus_pid_t
02354 _dbus_getpid (void)
02355 {
02356   return getpid ();
02357 }
02358 
02362 dbus_uid_t
02363 _dbus_getuid (void)
02364 {
02365   return getuid ();
02366 }
02367 
02371 dbus_uid_t
02372 _dbus_geteuid (void)
02373 {
02374   return geteuid ();
02375 }
02376 
02383 unsigned long
02384 _dbus_pid_for_log (void)
02385 {
02386   return getpid ();
02387 }
02388 
02396 dbus_bool_t
02397 _dbus_parse_uid (const DBusString      *uid_str,
02398                  dbus_uid_t            *uid)
02399 {
02400   int end;
02401   long val;
02402 
02403   if (_dbus_string_get_length (uid_str) == 0)
02404     {
02405       _dbus_verbose ("UID string was zero length\n");
02406       return FALSE;
02407     }
02408 
02409   val = -1;
02410   end = 0;
02411   if (!_dbus_string_parse_int (uid_str, 0, &val,
02412                                &end))
02413     {
02414       _dbus_verbose ("could not parse string as a UID\n");
02415       return FALSE;
02416     }
02417 
02418   if (end != _dbus_string_get_length (uid_str))
02419     {
02420       _dbus_verbose ("string contained trailing stuff after UID\n");
02421       return FALSE;
02422     }
02423 
02424   *uid = val;
02425 
02426   return TRUE;
02427 }
02428 
02429 #if !DBUS_USE_SYNC
02430 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02431 #endif
02432 
02439 dbus_int32_t
02440 _dbus_atomic_inc (DBusAtomic *atomic)
02441 {
02442 #if DBUS_USE_SYNC
02443   return __sync_add_and_fetch(&atomic->value, 1)-1;
02444 #else
02445   dbus_int32_t res;
02446   _DBUS_LOCK (atomic);
02447   res = atomic->value;
02448   atomic->value += 1;
02449   _DBUS_UNLOCK (atomic);
02450   return res;
02451 #endif
02452 }
02453 
02460 dbus_int32_t
02461 _dbus_atomic_dec (DBusAtomic *atomic)
02462 {
02463 #if DBUS_USE_SYNC
02464   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02465 #else
02466   dbus_int32_t res;
02467 
02468   _DBUS_LOCK (atomic);
02469   res = atomic->value;
02470   atomic->value -= 1;
02471   _DBUS_UNLOCK (atomic);
02472   return res;
02473 #endif
02474 }
02475 
02483 dbus_int32_t
02484 _dbus_atomic_get (DBusAtomic *atomic)
02485 {
02486 #if DBUS_USE_SYNC
02487   __sync_synchronize ();
02488   return atomic->value;
02489 #else
02490   dbus_int32_t res;
02491 
02492   _DBUS_LOCK (atomic);
02493   res = atomic->value;
02494   _DBUS_UNLOCK (atomic);
02495   return res;
02496 #endif
02497 }
02498 
02507 int
02508 _dbus_poll (DBusPollFD *fds,
02509             int         n_fds,
02510             int         timeout_milliseconds)
02511 {
02512 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02513   /* This big thing is a constant expression and should get optimized
02514    * out of existence. So it's more robust than a configure check at
02515    * no cost.
02516    */
02517   if (_DBUS_POLLIN == POLLIN &&
02518       _DBUS_POLLPRI == POLLPRI &&
02519       _DBUS_POLLOUT == POLLOUT &&
02520       _DBUS_POLLERR == POLLERR &&
02521       _DBUS_POLLHUP == POLLHUP &&
02522       _DBUS_POLLNVAL == POLLNVAL &&
02523       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02524       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02525       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02526       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02527       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02528       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02529       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02530     {
02531       return poll ((struct pollfd*) fds,
02532                    n_fds,
02533                    timeout_milliseconds);
02534     }
02535   else
02536     {
02537       /* We have to convert the DBusPollFD to an array of
02538        * struct pollfd, poll, and convert back.
02539        */
02540       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02541       return -1;
02542     }
02543 #else /* ! HAVE_POLL */
02544 
02545   fd_set read_set, write_set, err_set;
02546   int max_fd = 0;
02547   int i;
02548   struct timeval tv;
02549   int ready;
02550 
02551   FD_ZERO (&read_set);
02552   FD_ZERO (&write_set);
02553   FD_ZERO (&err_set);
02554 
02555   for (i = 0; i < n_fds; i++)
02556     {
02557       DBusPollFD *fdp = &fds[i];
02558 
02559       if (fdp->events & _DBUS_POLLIN)
02560         FD_SET (fdp->fd, &read_set);
02561 
02562       if (fdp->events & _DBUS_POLLOUT)
02563         FD_SET (fdp->fd, &write_set);
02564 
02565       FD_SET (fdp->fd, &err_set);
02566 
02567       max_fd = MAX (max_fd, fdp->fd);
02568     }
02569 
02570   tv.tv_sec = timeout_milliseconds / 1000;
02571   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02572 
02573   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02574                   timeout_milliseconds < 0 ? NULL : &tv);
02575 
02576   if (ready > 0)
02577     {
02578       for (i = 0; i < n_fds; i++)
02579         {
02580           DBusPollFD *fdp = &fds[i];
02581 
02582           fdp->revents = 0;
02583 
02584           if (FD_ISSET (fdp->fd, &read_set))
02585             fdp->revents |= _DBUS_POLLIN;
02586 
02587           if (FD_ISSET (fdp->fd, &write_set))
02588             fdp->revents |= _DBUS_POLLOUT;
02589 
02590           if (FD_ISSET (fdp->fd, &err_set))
02591             fdp->revents |= _DBUS_POLLERR;
02592         }
02593     }
02594 
02595   return ready;
02596 #endif
02597 }
02598 
02606 void
02607 _dbus_get_monotonic_time (long *tv_sec,
02608                           long *tv_usec)
02609 {
02610 #ifdef HAVE_MONOTONIC_CLOCK
02611   struct timespec ts;
02612   clock_gettime (CLOCK_MONOTONIC, &ts);
02613 
02614   if (tv_sec)
02615     *tv_sec = ts.tv_sec;
02616   if (tv_usec)
02617     *tv_usec = ts.tv_nsec / 1000;
02618 #else
02619   struct timeval t;
02620 
02621   gettimeofday (&t, NULL);
02622 
02623   if (tv_sec)
02624     *tv_sec = t.tv_sec;
02625   if (tv_usec)
02626     *tv_usec = t.tv_usec;
02627 #endif
02628 }
02629 
02637 void
02638 _dbus_get_real_time (long *tv_sec,
02639                      long *tv_usec)
02640 {
02641   struct timeval t;
02642 
02643   gettimeofday (&t, NULL);
02644 
02645   if (tv_sec)
02646     *tv_sec = t.tv_sec;
02647   if (tv_usec)
02648     *tv_usec = t.tv_usec;
02649 }
02650 
02659 dbus_bool_t
02660 _dbus_create_directory (const DBusString *filename,
02661                         DBusError        *error)
02662 {
02663   const char *filename_c;
02664 
02665   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02666 
02667   filename_c = _dbus_string_get_const_data (filename);
02668 
02669   if (mkdir (filename_c, 0700) < 0)
02670     {
02671       if (errno == EEXIST)
02672         return TRUE;
02673 
02674       dbus_set_error (error, DBUS_ERROR_FAILED,
02675                       "Failed to create directory %s: %s\n",
02676                       filename_c, _dbus_strerror (errno));
02677       return FALSE;
02678     }
02679   else
02680     return TRUE;
02681 }
02682 
02693 dbus_bool_t
02694 _dbus_concat_dir_and_file (DBusString       *dir,
02695                            const DBusString *next_component)
02696 {
02697   dbus_bool_t dir_ends_in_slash;
02698   dbus_bool_t file_starts_with_slash;
02699 
02700   if (_dbus_string_get_length (dir) == 0 ||
02701       _dbus_string_get_length (next_component) == 0)
02702     return TRUE;
02703 
02704   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02705                                                     _dbus_string_get_length (dir) - 1);
02706 
02707   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02708 
02709   if (dir_ends_in_slash && file_starts_with_slash)
02710     {
02711       _dbus_string_shorten (dir, 1);
02712     }
02713   else if (!(dir_ends_in_slash || file_starts_with_slash))
02714     {
02715       if (!_dbus_string_append_byte (dir, '/'))
02716         return FALSE;
02717     }
02718 
02719   return _dbus_string_copy (next_component, 0, dir,
02720                             _dbus_string_get_length (dir));
02721 }
02722 
02724 #define NANOSECONDS_PER_SECOND       1000000000
02725 
02726 #define MICROSECONDS_PER_SECOND      1000000
02727 
02728 #define MILLISECONDS_PER_SECOND      1000
02729 
02730 #define NANOSECONDS_PER_MILLISECOND  1000000
02731 
02732 #define MICROSECONDS_PER_MILLISECOND 1000
02733 
02738 void
02739 _dbus_sleep_milliseconds (int milliseconds)
02740 {
02741 #ifdef HAVE_NANOSLEEP
02742   struct timespec req;
02743   struct timespec rem;
02744 
02745   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02746   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02747   rem.tv_sec = 0;
02748   rem.tv_nsec = 0;
02749 
02750   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02751     req = rem;
02752 #elif defined (HAVE_USLEEP)
02753   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02754 #else /* ! HAVE_USLEEP */
02755   sleep (MAX (milliseconds / 1000, 1));
02756 #endif
02757 }
02758 
02759 static dbus_bool_t
02760 _dbus_generate_pseudorandom_bytes (DBusString *str,
02761                                    int         n_bytes)
02762 {
02763   int old_len;
02764   char *p;
02765 
02766   old_len = _dbus_string_get_length (str);
02767 
02768   if (!_dbus_string_lengthen (str, n_bytes))
02769     return FALSE;
02770 
02771   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02772 
02773   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02774 
02775   return TRUE;
02776 }
02777 
02786 dbus_bool_t
02787 _dbus_generate_random_bytes (DBusString *str,
02788                              int         n_bytes)
02789 {
02790   int old_len;
02791   int fd;
02792 
02793   /* FALSE return means "no memory", if it could
02794    * mean something else then we'd need to return
02795    * a DBusError. So we always fall back to pseudorandom
02796    * if the I/O fails.
02797    */
02798 
02799   old_len = _dbus_string_get_length (str);
02800   fd = -1;
02801 
02802   /* note, urandom on linux will fall back to pseudorandom */
02803   fd = open ("/dev/urandom", O_RDONLY);
02804   if (fd < 0)
02805     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02806 
02807   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02808 
02809   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02810     {
02811       _dbus_close (fd, NULL);
02812       _dbus_string_set_length (str, old_len);
02813       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02814     }
02815 
02816   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02817                  n_bytes);
02818 
02819   _dbus_close (fd, NULL);
02820 
02821   return TRUE;
02822 }
02823 
02829 void
02830 _dbus_exit (int code)
02831 {
02832   _exit (code);
02833 }
02834 
02843 const char*
02844 _dbus_strerror (int error_number)
02845 {
02846   const char *msg;
02847 
02848   msg = strerror (error_number);
02849   if (msg == NULL)
02850     msg = "unknown";
02851 
02852   return msg;
02853 }
02854 
02858 void
02859 _dbus_disable_sigpipe (void)
02860 {
02861   signal (SIGPIPE, SIG_IGN);
02862 }
02863 
02871 void
02872 _dbus_fd_set_close_on_exec (intptr_t fd)
02873 {
02874   int val;
02875 
02876   val = fcntl (fd, F_GETFD, 0);
02877 
02878   if (val < 0)
02879     return;
02880 
02881   val |= FD_CLOEXEC;
02882 
02883   fcntl (fd, F_SETFD, val);
02884 }
02885 
02893 dbus_bool_t
02894 _dbus_close (int        fd,
02895              DBusError *error)
02896 {
02897   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02898 
02899  again:
02900   if (close (fd) < 0)
02901     {
02902       if (errno == EINTR)
02903         goto again;
02904 
02905       dbus_set_error (error, _dbus_error_from_errno (errno),
02906                       "Could not close fd %d", fd);
02907       return FALSE;
02908     }
02909 
02910   return TRUE;
02911 }
02912 
02920 int
02921 _dbus_dup(int        fd,
02922           DBusError *error)
02923 {
02924   int new_fd;
02925 
02926 #ifdef F_DUPFD_CLOEXEC
02927   dbus_bool_t cloexec_done;
02928 
02929   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02930   cloexec_done = new_fd >= 0;
02931 
02932   if (new_fd < 0 && errno == EINVAL)
02933 #endif
02934     {
02935       new_fd = fcntl(fd, F_DUPFD, 3);
02936     }
02937 
02938   if (new_fd < 0) {
02939 
02940     dbus_set_error (error, _dbus_error_from_errno (errno),
02941                     "Could not duplicate fd %d", fd);
02942     return -1;
02943   }
02944 
02945 #ifdef F_DUPFD_CLOEXEC
02946   if (!cloexec_done)
02947 #endif
02948     {
02949       _dbus_fd_set_close_on_exec(new_fd);
02950     }
02951 
02952   return new_fd;
02953 }
02954 
02962 dbus_bool_t
02963 _dbus_set_fd_nonblocking (int             fd,
02964                           DBusError      *error)
02965 {
02966   int val;
02967 
02968   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02969 
02970   val = fcntl (fd, F_GETFL, 0);
02971   if (val < 0)
02972     {
02973       dbus_set_error (error, _dbus_error_from_errno (errno),
02974                       "Failed to get flags from file descriptor %d: %s",
02975                       fd, _dbus_strerror (errno));
02976       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02977                      _dbus_strerror (errno));
02978       return FALSE;
02979     }
02980 
02981   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02982     {
02983       dbus_set_error (error, _dbus_error_from_errno (errno),
02984                       "Failed to set nonblocking flag of file descriptor %d: %s",
02985                       fd, _dbus_strerror (errno));
02986       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02987                      fd, _dbus_strerror (errno));
02988 
02989       return FALSE;
02990     }
02991 
02992   return TRUE;
02993 }
02994 
03000 void
03001 _dbus_print_backtrace (void)
03002 {
03003 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
03004   void *bt[500];
03005   int bt_size;
03006   int i;
03007   char **syms;
03008 
03009   bt_size = backtrace (bt, 500);
03010 
03011   syms = backtrace_symbols (bt, bt_size);
03012 
03013   i = 0;
03014   while (i < bt_size)
03015     {
03016       /* don't use dbus_warn since it can _dbus_abort() */
03017       fprintf (stderr, "  %s\n", syms[i]);
03018       ++i;
03019     }
03020   fflush (stderr);
03021 
03022   free (syms);
03023 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
03024   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
03025 #else
03026   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
03027 #endif
03028 }
03029 
03042 dbus_bool_t
03043 _dbus_full_duplex_pipe (int        *fd1,
03044                         int        *fd2,
03045                         dbus_bool_t blocking,
03046                         DBusError  *error)
03047 {
03048 #ifdef HAVE_SOCKETPAIR
03049   int fds[2];
03050   int retval;
03051 
03052 #ifdef SOCK_CLOEXEC
03053   dbus_bool_t cloexec_done;
03054 
03055   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03056   cloexec_done = retval >= 0;
03057 
03058   if (retval < 0 && errno == EINVAL)
03059 #endif
03060     {
03061       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03062     }
03063 
03064   if (retval < 0)
03065     {
03066       dbus_set_error (error, _dbus_error_from_errno (errno),
03067                       "Could not create full-duplex pipe");
03068       return FALSE;
03069     }
03070 
03071   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03072 
03073 #ifdef SOCK_CLOEXEC
03074   if (!cloexec_done)
03075 #endif
03076     {
03077       _dbus_fd_set_close_on_exec (fds[0]);
03078       _dbus_fd_set_close_on_exec (fds[1]);
03079     }
03080 
03081   if (!blocking &&
03082       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03083        !_dbus_set_fd_nonblocking (fds[1], NULL)))
03084     {
03085       dbus_set_error (error, _dbus_error_from_errno (errno),
03086                       "Could not set full-duplex pipe nonblocking");
03087 
03088       _dbus_close (fds[0], NULL);
03089       _dbus_close (fds[1], NULL);
03090 
03091       return FALSE;
03092     }
03093 
03094   *fd1 = fds[0];
03095   *fd2 = fds[1];
03096 
03097   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03098                  *fd1, *fd2);
03099 
03100   return TRUE;
03101 #else
03102   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03103   dbus_set_error (error, DBUS_ERROR_FAILED,
03104                   "_dbus_full_duplex_pipe() not implemented on this OS");
03105   return FALSE;
03106 #endif
03107 }
03108 
03117 int
03118 _dbus_printf_string_upper_bound (const char *format,
03119                                  va_list     args)
03120 {
03121   char static_buf[1024];
03122   int bufsize = sizeof (static_buf);
03123   int len;
03124   va_list args_copy;
03125 
03126   DBUS_VA_COPY (args_copy, args);
03127   len = vsnprintf (static_buf, bufsize, format, args_copy);
03128   va_end (args_copy);
03129 
03130   /* If vsnprintf() returned non-negative, then either the string fits in
03131    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03132    * returns the number of characters that were needed, or this OS returns the
03133    * truncated length.
03134    *
03135    * We ignore the possibility that snprintf might just ignore the length and
03136    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03137    * If your libc is really that bad, come back when you have a better one. */
03138   if (len == bufsize)
03139     {
03140       /* This could be the truncated length (Tru64 and IRIX have this bug),
03141        * or the real length could be coincidentally the same. Which is it?
03142        * If vsnprintf returns the truncated length, we'll go to the slow
03143        * path. */
03144       DBUS_VA_COPY (args_copy, args);
03145 
03146       if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03147         len = -1;
03148 
03149       va_end (args_copy);
03150     }
03151 
03152   /* If vsnprintf() returned negative, we have to do more work.
03153    * HP-UX returns negative. */
03154   while (len < 0)
03155     {
03156       char *buf;
03157 
03158       bufsize *= 2;
03159 
03160       buf = dbus_malloc (bufsize);
03161 
03162       if (buf == NULL)
03163         return -1;
03164 
03165       DBUS_VA_COPY (args_copy, args);
03166       len = vsnprintf (buf, bufsize, format, args_copy);
03167       va_end (args_copy);
03168 
03169       dbus_free (buf);
03170 
03171       /* If the reported length is exactly the buffer size, round up to the
03172        * next size, in case vsnprintf has been returning the truncated
03173        * length */
03174       if (len == bufsize)
03175         len = -1;
03176     }
03177 
03178   return len;
03179 }
03180 
03187 const char*
03188 _dbus_get_tmpdir(void)
03189 {
03190   static const char* tmpdir = NULL;
03191 
03192   if (tmpdir == NULL)
03193     {
03194       /* TMPDIR is what glibc uses, then
03195        * glibc falls back to the P_tmpdir macro which
03196        * just expands to "/tmp"
03197        */
03198       if (tmpdir == NULL)
03199         tmpdir = getenv("TMPDIR");
03200 
03201       /* These two env variables are probably
03202        * broken, but maybe some OS uses them?
03203        */
03204       if (tmpdir == NULL)
03205         tmpdir = getenv("TMP");
03206       if (tmpdir == NULL)
03207         tmpdir = getenv("TEMP");
03208 
03209       /* And this is the sane fallback. */
03210       if (tmpdir == NULL)
03211         tmpdir = "/tmp";
03212     }
03213 
03214   _dbus_assert(tmpdir != NULL);
03215 
03216   return tmpdir;
03217 }
03218 
03238 static dbus_bool_t
03239 _read_subprocess_line_argv (const char *progpath,
03240                             dbus_bool_t path_fallback,
03241                             char       * const *argv,
03242                             DBusString *result,
03243                             DBusError  *error)
03244 {
03245   int result_pipe[2] = { -1, -1 };
03246   int errors_pipe[2] = { -1, -1 };
03247   pid_t pid;
03248   int ret;
03249   int status;
03250   int orig_len;
03251 
03252   dbus_bool_t retval;
03253   sigset_t new_set, old_set;
03254 
03255   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03256   retval = FALSE;
03257 
03258   /* We need to block any existing handlers for SIGCHLD temporarily; they
03259    * will cause waitpid() below to fail.
03260    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03261    */
03262   sigemptyset (&new_set);
03263   sigaddset (&new_set, SIGCHLD);
03264   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03265 
03266   orig_len = _dbus_string_get_length (result);
03267 
03268 #define READ_END        0
03269 #define WRITE_END       1
03270   if (pipe (result_pipe) < 0)
03271     {
03272       dbus_set_error (error, _dbus_error_from_errno (errno),
03273                       "Failed to create a pipe to call %s: %s",
03274                       progpath, _dbus_strerror (errno));
03275       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03276                      progpath, _dbus_strerror (errno));
03277       goto out;
03278     }
03279   if (pipe (errors_pipe) < 0)
03280     {
03281       dbus_set_error (error, _dbus_error_from_errno (errno),
03282                       "Failed to create a pipe to call %s: %s",
03283                       progpath, _dbus_strerror (errno));
03284       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03285                      progpath, _dbus_strerror (errno));
03286       goto out;
03287     }
03288 
03289   pid = fork ();
03290   if (pid < 0)
03291     {
03292       dbus_set_error (error, _dbus_error_from_errno (errno),
03293                       "Failed to fork() to call %s: %s",
03294                       progpath, _dbus_strerror (errno));
03295       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03296                      progpath, _dbus_strerror (errno));
03297       goto out;
03298     }
03299 
03300   if (pid == 0)
03301     {
03302       /* child process */
03303       int fd;
03304 
03305       fd = open ("/dev/null", O_RDWR);
03306       if (fd == -1)
03307         /* huh?! can't open /dev/null? */
03308         _exit (1);
03309 
03310       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03311 
03312       /* set-up stdXXX */
03313       close (result_pipe[READ_END]);
03314       close (errors_pipe[READ_END]);
03315       close (0);                /* close stdin */
03316       close (1);                /* close stdout */
03317       close (2);                /* close stderr */
03318 
03319       if (dup2 (fd, 0) == -1)
03320         _exit (1);
03321       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03322         _exit (1);
03323       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03324         _exit (1);
03325 
03326       _dbus_close_all ();
03327 
03328       sigprocmask (SIG_SETMASK, &old_set, NULL);
03329 
03330       /* If it looks fully-qualified, try execv first */
03331       if (progpath[0] == '/')
03332         {
03333           execv (progpath, argv);
03334           /* Ok, that failed.  Now if path_fallback is given, let's
03335            * try unqualified.  This is mostly a hack to work
03336            * around systems which ship dbus-launch in /usr/bin
03337            * but everything else in /bin (because dbus-launch
03338            * depends on X11).
03339            */
03340           if (path_fallback)
03341             /* We must have a slash, because we checked above */
03342             execvp (strrchr (progpath, '/')+1, argv);
03343         }
03344       else
03345         execvp (progpath, argv);
03346 
03347       /* still nothing, we failed */
03348       _exit (1);
03349     }
03350 
03351   /* parent process */
03352   close (result_pipe[WRITE_END]);
03353   close (errors_pipe[WRITE_END]);
03354   result_pipe[WRITE_END] = -1;
03355   errors_pipe[WRITE_END] = -1;
03356 
03357   ret = 0;
03358   do
03359     {
03360       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03361     }
03362   while (ret > 0);
03363 
03364   /* reap the child process to avoid it lingering as zombie */
03365   do
03366     {
03367       ret = waitpid (pid, &status, 0);
03368     }
03369   while (ret == -1 && errno == EINTR);
03370 
03371   /* We succeeded if the process exited with status 0 and
03372      anything was read */
03373   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03374     {
03375       /* The process ended with error */
03376       DBusString error_message;
03377       if (!_dbus_string_init (&error_message))
03378         {
03379           _DBUS_SET_OOM (error);
03380           goto out;
03381         }
03382 
03383       ret = 0;
03384       do
03385         {
03386           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03387         }
03388       while (ret > 0);
03389 
03390       _dbus_string_set_length (result, orig_len);
03391       if (_dbus_string_get_length (&error_message) > 0)
03392         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03393                         "%s terminated abnormally with the following error: %s",
03394                         progpath, _dbus_string_get_data (&error_message));
03395       else
03396         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03397                         "%s terminated abnormally without any error message",
03398                         progpath);
03399       goto out;
03400     }
03401 
03402   retval = TRUE;
03403 
03404  out:
03405   sigprocmask (SIG_SETMASK, &old_set, NULL);
03406 
03407   if (retval)
03408     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03409   else
03410     _DBUS_ASSERT_ERROR_IS_SET (error);
03411 
03412   if (result_pipe[0] != -1)
03413     close (result_pipe[0]);
03414   if (result_pipe[1] != -1)
03415     close (result_pipe[1]);
03416   if (errors_pipe[0] != -1)
03417     close (errors_pipe[0]);
03418   if (errors_pipe[1] != -1)
03419     close (errors_pipe[1]);
03420 
03421   return retval;
03422 }
03423 
03435 dbus_bool_t
03436 _dbus_get_autolaunch_address (const char *scope,
03437                               DBusString *address,
03438                               DBusError  *error)
03439 {
03440 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03441   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03442    * but that's done elsewhere, and if it worked, this function wouldn't
03443    * be called.) */
03444   const char *display;
03445   static char *argv[6];
03446   int i;
03447   DBusString uuid;
03448   dbus_bool_t retval;
03449 
03450   if (_dbus_check_setuid ())
03451     {
03452       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03453                             "Unable to autolaunch when setuid");
03454       return FALSE;
03455     }
03456 
03457   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03458   retval = FALSE;
03459 
03460   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03461    * dbus-launch-x11 is just going to fail. Rather than trying to
03462    * run it, we might as well bail out early with a nice error. */
03463   display = _dbus_getenv ("DISPLAY");
03464 
03465   if (display == NULL || display[0] == '\0')
03466     {
03467       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03468           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03469       return FALSE;
03470     }
03471 
03472   if (!_dbus_string_init (&uuid))
03473     {
03474       _DBUS_SET_OOM (error);
03475       return FALSE;
03476     }
03477 
03478   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03479     {
03480       _DBUS_SET_OOM (error);
03481       goto out;
03482     }
03483 
03484   i = 0;
03485   argv[i] = "dbus-launch";
03486   ++i;
03487   argv[i] = "--autolaunch";
03488   ++i;
03489   argv[i] = _dbus_string_get_data (&uuid);
03490   ++i;
03491   argv[i] = "--binary-syntax";
03492   ++i;
03493   argv[i] = "--close-stderr";
03494   ++i;
03495   argv[i] = NULL;
03496   ++i;
03497 
03498   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03499 
03500   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03501                                        TRUE,
03502                                        argv, address, error);
03503 
03504  out:
03505   _dbus_string_free (&uuid);
03506   return retval;
03507 #else
03508   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03509       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03510       "set your DBUS_SESSION_BUS_ADDRESS instead");
03511   return FALSE;
03512 #endif
03513 }
03514 
03533 dbus_bool_t
03534 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03535                                dbus_bool_t create_if_not_found,
03536                                DBusError  *error)
03537 {
03538   DBusString filename;
03539   dbus_bool_t b;
03540 
03541   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03542 
03543   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03544   if (b)
03545     return TRUE;
03546 
03547   dbus_error_free (error);
03548 
03549   /* Fallback to the system machine ID */
03550   _dbus_string_init_const (&filename, "/etc/machine-id");
03551   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03552 }
03553 
03554 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03555 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03556 
03563 dbus_bool_t
03564 _dbus_lookup_launchd_socket (DBusString *socket_path,
03565                              const char *launchd_env_var,
03566                              DBusError  *error)
03567 {
03568 #ifdef DBUS_ENABLE_LAUNCHD
03569   char *argv[4];
03570   int i;
03571 
03572   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03573 
03574   if (_dbus_check_setuid ())
03575     {
03576       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03577                             "Unable to find launchd socket when setuid");
03578       return FALSE;
03579     }
03580 
03581   i = 0;
03582   argv[i] = "launchctl";
03583   ++i;
03584   argv[i] = "getenv";
03585   ++i;
03586   argv[i] = (char*)launchd_env_var;
03587   ++i;
03588   argv[i] = NULL;
03589   ++i;
03590 
03591   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03592 
03593   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03594     {
03595       return FALSE;
03596     }
03597 
03598   /* no error, but no result either */
03599   if (_dbus_string_get_length(socket_path) == 0)
03600     {
03601       return FALSE;
03602     }
03603 
03604   /* strip the carriage-return */
03605   _dbus_string_shorten(socket_path, 1);
03606   return TRUE;
03607 #else /* DBUS_ENABLE_LAUNCHD */
03608   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03609                 "can't lookup socket from launchd; launchd support not compiled in");
03610   return FALSE;
03611 #endif
03612 }
03613 
03614 #ifdef DBUS_ENABLE_LAUNCHD
03615 static dbus_bool_t
03616 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03617 {
03618   dbus_bool_t valid_socket;
03619   DBusString socket_path;
03620 
03621   if (_dbus_check_setuid ())
03622     {
03623       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03624                             "Unable to find launchd socket when setuid");
03625       return FALSE;
03626     }
03627 
03628   if (!_dbus_string_init (&socket_path))
03629     {
03630       _DBUS_SET_OOM (error);
03631       return FALSE;
03632     }
03633 
03634   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03635 
03636   if (dbus_error_is_set(error))
03637     {
03638       _dbus_string_free(&socket_path);
03639       return FALSE;
03640     }
03641 
03642   if (!valid_socket)
03643     {
03644       dbus_set_error(error, "no socket path",
03645                 "launchd did not provide a socket path, "
03646                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03647       _dbus_string_free(&socket_path);
03648       return FALSE;
03649     }
03650   if (!_dbus_string_append (address, "unix:path="))
03651     {
03652       _DBUS_SET_OOM (error);
03653       _dbus_string_free(&socket_path);
03654       return FALSE;
03655     }
03656   if (!_dbus_string_copy (&socket_path, 0, address,
03657                           _dbus_string_get_length (address)))
03658     {
03659       _DBUS_SET_OOM (error);
03660       _dbus_string_free(&socket_path);
03661       return FALSE;
03662     }
03663 
03664   _dbus_string_free(&socket_path);
03665   return TRUE;
03666 }
03667 #endif
03668 
03688 dbus_bool_t
03689 _dbus_lookup_session_address (dbus_bool_t *supported,
03690                               DBusString  *address,
03691                               DBusError   *error)
03692 {
03693 #ifdef DBUS_ENABLE_LAUNCHD
03694   *supported = TRUE;
03695   return _dbus_lookup_session_address_launchd (address, error);
03696 #else
03697   /* On non-Mac Unix platforms, if the session address isn't already
03698    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03699    * fall back to the autolaunch: global default; see
03700    * init_session_address in dbus/dbus-bus.c. */
03701   *supported = FALSE;
03702   return TRUE;
03703 #endif
03704 }
03705 
03723 dbus_bool_t
03724 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03725 {
03726   const char *xdg_data_home;
03727   const char *xdg_data_dirs;
03728   DBusString servicedir_path;
03729 
03730   if (!_dbus_string_init (&servicedir_path))
03731     return FALSE;
03732 
03733   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03734   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03735 
03736   if (xdg_data_home != NULL)
03737     {
03738       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03739         goto oom;
03740     }
03741   else
03742     {
03743       const DBusString *homedir;
03744       DBusString local_share;
03745 
03746       if (!_dbus_homedir_from_current_process (&homedir))
03747         goto oom;
03748 
03749       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03750         goto oom;
03751 
03752       _dbus_string_init_const (&local_share, "/.local/share");
03753       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03754         goto oom;
03755     }
03756 
03757   if (!_dbus_string_append (&servicedir_path, ":"))
03758     goto oom;
03759 
03760   if (xdg_data_dirs != NULL)
03761     {
03762       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03763         goto oom;
03764 
03765       if (!_dbus_string_append (&servicedir_path, ":"))
03766         goto oom;
03767     }
03768   else
03769     {
03770       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03771         goto oom;
03772     }
03773 
03774   /*
03775    * add configured datadir to defaults
03776    * this may be the same as an xdg dir
03777    * however the config parser should take
03778    * care of duplicates
03779    */
03780   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03781     goto oom;
03782 
03783   if (!_dbus_split_paths_and_append (&servicedir_path,
03784                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03785                                      dirs))
03786     goto oom;
03787 
03788   _dbus_string_free (&servicedir_path);
03789   return TRUE;
03790 
03791  oom:
03792   _dbus_string_free (&servicedir_path);
03793   return FALSE;
03794 }
03795 
03796 
03815 dbus_bool_t
03816 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03817 {
03818   /*
03819    * DBUS_DATADIR may be the same as one of the standard directories. However,
03820    * the config parser should take care of the duplicates.
03821    *
03822    * Also, append /lib as counterpart of /usr/share on the root
03823    * directory (the root directory does not know /share), in order to
03824    * facilitate early boot system bus activation where /usr might not
03825    * be available.
03826    */
03827   static const char standard_search_path[] =
03828     "/usr/local/share:"
03829     "/usr/share:"
03830     DBUS_DATADIR ":"
03831     "/lib";
03832   DBusString servicedir_path;
03833 
03834   _dbus_string_init_const (&servicedir_path, standard_search_path);
03835 
03836   return _dbus_split_paths_and_append (&servicedir_path,
03837                                        DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03838                                        dirs);
03839 }
03840 
03849 dbus_bool_t
03850 _dbus_append_system_config_file (DBusString *str)
03851 {
03852   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03853 }
03854 
03861 dbus_bool_t
03862 _dbus_append_session_config_file (DBusString *str)
03863 {
03864   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03865 }
03866 
03874 void
03875 _dbus_flush_caches (void)
03876 {
03877   _dbus_user_database_flush_system ();
03878 }
03879 
03893 dbus_bool_t
03894 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03895                                                 DBusCredentials *credentials)
03896 {
03897   DBusString homedir;
03898   DBusString dotdir;
03899   dbus_uid_t uid;
03900 
03901   _dbus_assert (credentials != NULL);
03902   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03903 
03904   if (!_dbus_string_init (&homedir))
03905     return FALSE;
03906 
03907   uid = _dbus_credentials_get_unix_uid (credentials);
03908   _dbus_assert (uid != DBUS_UID_UNSET);
03909 
03910   if (!_dbus_homedir_from_uid (uid, &homedir))
03911     goto failed;
03912 
03913 #ifdef DBUS_BUILD_TESTS
03914   {
03915     const char *override;
03916 
03917     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03918     if (override != NULL && *override != '\0')
03919       {
03920         _dbus_string_set_length (&homedir, 0);
03921         if (!_dbus_string_append (&homedir, override))
03922           goto failed;
03923 
03924         _dbus_verbose ("Using fake homedir for testing: %s\n",
03925                        _dbus_string_get_const_data (&homedir));
03926       }
03927     else
03928       {
03929         static dbus_bool_t already_warned = FALSE;
03930         if (!already_warned)
03931           {
03932             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03933             already_warned = TRUE;
03934           }
03935       }
03936   }
03937 #endif
03938 
03939   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03940   if (!_dbus_concat_dir_and_file (&homedir,
03941                                   &dotdir))
03942     goto failed;
03943 
03944   if (!_dbus_string_copy (&homedir, 0,
03945                           directory, _dbus_string_get_length (directory))) {
03946     goto failed;
03947   }
03948 
03949   _dbus_string_free (&homedir);
03950   return TRUE;
03951 
03952  failed:
03953   _dbus_string_free (&homedir);
03954   return FALSE;
03955 }
03956 
03957 //PENDING(kdab) docs
03958 dbus_bool_t
03959 _dbus_daemon_publish_session_bus_address (const char* addr,
03960                                           const char *scope)
03961 {
03962   return TRUE;
03963 }
03964 
03965 //PENDING(kdab) docs
03966 void
03967 _dbus_daemon_unpublish_session_bus_address (void)
03968 {
03969 
03970 }
03971 
03978 dbus_bool_t
03979 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03980 {
03981   return errno == EAGAIN || errno == EWOULDBLOCK;
03982 }
03983 
03991 dbus_bool_t
03992 _dbus_delete_directory (const DBusString *filename,
03993                         DBusError        *error)
03994 {
03995   const char *filename_c;
03996 
03997   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03998 
03999   filename_c = _dbus_string_get_const_data (filename);
04000 
04001   if (rmdir (filename_c) != 0)
04002     {
04003       dbus_set_error (error, DBUS_ERROR_FAILED,
04004                       "Failed to remove directory %s: %s\n",
04005                       filename_c, _dbus_strerror (errno));
04006       return FALSE;
04007     }
04008 
04009   return TRUE;
04010 }
04011 
04019 dbus_bool_t
04020 _dbus_socket_can_pass_unix_fd(int fd) {
04021 
04022 #ifdef SCM_RIGHTS
04023   union {
04024     struct sockaddr sa;
04025     struct sockaddr_storage storage;
04026     struct sockaddr_un un;
04027   } sa_buf;
04028 
04029   socklen_t sa_len = sizeof(sa_buf);
04030 
04031   _DBUS_ZERO(sa_buf);
04032 
04033   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
04034     return FALSE;
04035 
04036   return sa_buf.sa.sa_family == AF_UNIX;
04037 
04038 #else
04039   return FALSE;
04040 
04041 #endif
04042 }
04043 
04044 
04045 /*
04046  * replaces the term DBUS_PREFIX in configure_time_path by the
04047  * current dbus installation directory. On unix this function is a noop
04048  *
04049  * @param configure_time_path
04050  * @return real path
04051  */
04052 const char *
04053 _dbus_replace_install_prefix (const char *configure_time_path)
04054 {
04055   return configure_time_path;
04056 }
04057 
04062 void
04063 _dbus_close_all (void)
04064 {
04065   int maxfds, i;
04066 
04067 #ifdef __linux__
04068   DIR *d;
04069 
04070   /* On Linux we can optimize this a bit if /proc is available. If it
04071      isn't available, fall back to the brute force way. */
04072 
04073   d = opendir ("/proc/self/fd");
04074   if (d)
04075     {
04076       for (;;)
04077         {
04078           struct dirent buf, *de;
04079           int k, fd;
04080           long l;
04081           char *e = NULL;
04082 
04083           k = readdir_r (d, &buf, &de);
04084           if (k != 0 || !de)
04085             break;
04086 
04087           if (de->d_name[0] == '.')
04088             continue;
04089 
04090           errno = 0;
04091           l = strtol (de->d_name, &e, 10);
04092           if (errno != 0 || e == NULL || *e != '\0')
04093             continue;
04094 
04095           fd = (int) l;
04096           if (fd < 3)
04097             continue;
04098 
04099           if (fd == dirfd (d))
04100             continue;
04101 
04102           close (fd);
04103         }
04104 
04105       closedir (d);
04106       return;
04107     }
04108 #endif
04109 
04110   maxfds = sysconf (_SC_OPEN_MAX);
04111 
04112   /* Pick something reasonable if for some reason sysconf says
04113    * unlimited.
04114    */
04115   if (maxfds < 0)
04116     maxfds = 1024;
04117 
04118   /* close all inherited fds */
04119   for (i = 3; i < maxfds; i++)
04120     close (i);
04121 }
04122 
04132 dbus_bool_t
04133 _dbus_check_setuid (void)
04134 {
04135   /* TODO: get __libc_enable_secure exported from glibc.
04136    * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
04137    */
04138 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
04139   {
04140     /* See glibc/include/unistd.h */
04141     extern int __libc_enable_secure;
04142     return __libc_enable_secure;
04143   }
04144 #elif defined(HAVE_ISSETUGID)
04145   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
04146   return issetugid ();
04147 #else
04148   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
04149   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
04150 
04151   static dbus_bool_t check_setuid_initialised;
04152   static dbus_bool_t is_setuid;
04153 
04154   if (_DBUS_UNLIKELY (!check_setuid_initialised))
04155     {
04156 #ifdef HAVE_GETRESUID
04157       if (getresuid (&ruid, &euid, &suid) != 0 ||
04158           getresgid (&rgid, &egid, &sgid) != 0)
04159 #endif /* HAVE_GETRESUID */
04160         {
04161           suid = ruid = getuid ();
04162           sgid = rgid = getgid ();
04163           euid = geteuid ();
04164           egid = getegid ();
04165         }
04166 
04167       check_setuid_initialised = TRUE;
04168       is_setuid = (ruid != euid || ruid != suid ||
04169                    rgid != egid || rgid != sgid);
04170 
04171     }
04172   return is_setuid;
04173 #endif
04174 }
04175 
04176 /* tests in dbus-sysdeps-util.c */