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