D-Bus  1.5.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 
00877 static dbus_bool_t
00878 _dbus_set_local_creds (int fd, dbus_bool_t on)
00879 {
00880   dbus_bool_t retval = TRUE;
00881 
00882 #if defined(HAVE_CMSGCRED)
00883   /* NOOP just to make sure only one codepath is used
00884    *      and to prefer CMSGCRED
00885    */
00886 #elif defined(LOCAL_CREDS)
00887   int val = on ? 1 : 0;
00888   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00889     {
00890       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00891       retval = FALSE;
00892     }
00893   else
00894     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00895                    on ? "enabled" : "disabled", fd);
00896 #endif
00897 
00898   return retval;
00899 }
00900 
00918 int
00919 _dbus_listen_unix_socket (const char     *path,
00920                           dbus_bool_t     abstract,
00921                           DBusError      *error)
00922 {
00923   int listen_fd;
00924   struct sockaddr_un addr;
00925   size_t path_len;
00926   unsigned int reuseaddr;
00927 
00928   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00929 
00930   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00931                  path, abstract);
00932 
00933   if (!_dbus_open_unix_socket (&listen_fd, error))
00934     {
00935       _DBUS_ASSERT_ERROR_IS_SET(error);
00936       return -1;
00937     }
00938   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00939 
00940   _DBUS_ZERO (addr);
00941   addr.sun_family = AF_UNIX;
00942   path_len = strlen (path);
00943 
00944   if (abstract)
00945     {
00946 #ifdef HAVE_ABSTRACT_SOCKETS
00947       /* remember that abstract names aren't nul-terminated so we rely
00948        * on sun_path being filled in with zeroes above.
00949        */
00950       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00951       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00952 
00953       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00954         {
00955           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00956                       "Abstract socket name too long\n");
00957           _dbus_close (listen_fd, NULL);
00958           return -1;
00959         }
00960 
00961       strncpy (&addr.sun_path[1], path, path_len);
00962       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00963 #else /* HAVE_ABSTRACT_SOCKETS */
00964       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00965                       "Operating system does not support abstract socket namespace\n");
00966       _dbus_close (listen_fd, NULL);
00967       return -1;
00968 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00969     }
00970   else
00971     {
00972       /* Discussed security implications of this with Nalin,
00973        * and we couldn't think of where it would kick our ass, but
00974        * it still seems a bit sucky. It also has non-security suckage;
00975        * really we'd prefer to exit if the socket is already in use.
00976        * But there doesn't seem to be a good way to do this.
00977        *
00978        * Just to be extra careful, I threw in the stat() - clearly
00979        * the stat() can't *fix* any security issue, but it at least
00980        * avoids inadvertent/accidental data loss.
00981        */
00982       {
00983         struct stat sb;
00984 
00985         if (stat (path, &sb) == 0 &&
00986             S_ISSOCK (sb.st_mode))
00987           unlink (path);
00988       }
00989 
00990       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00991         {
00992           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00993                       "Abstract socket name too long\n");
00994           _dbus_close (listen_fd, NULL);
00995           return -1;
00996         }
00997 
00998       strncpy (addr.sun_path, path, path_len);
00999     }
01000 
01001   reuseaddr = 1;
01002   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01003     {
01004       _dbus_warn ("Failed to set socket option\"%s\": %s",
01005                   path, _dbus_strerror (errno));
01006     }
01007 
01008   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01009     {
01010       dbus_set_error (error, _dbus_error_from_errno (errno),
01011                       "Failed to bind socket \"%s\": %s",
01012                       path, _dbus_strerror (errno));
01013       _dbus_close (listen_fd, NULL);
01014       return -1;
01015     }
01016 
01017   if (listen (listen_fd, 30 /* backlog */) < 0)
01018     {
01019       dbus_set_error (error, _dbus_error_from_errno (errno),
01020                       "Failed to listen on socket \"%s\": %s",
01021                       path, _dbus_strerror (errno));
01022       _dbus_close (listen_fd, NULL);
01023       return -1;
01024     }
01025 
01026   if (!_dbus_set_local_creds (listen_fd, TRUE))
01027     {
01028       dbus_set_error (error, _dbus_error_from_errno (errno),
01029                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01030                       path, _dbus_strerror (errno));
01031       close (listen_fd);
01032       return -1;
01033     }
01034 
01035   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01036     {
01037       _DBUS_ASSERT_ERROR_IS_SET (error);
01038       _dbus_close (listen_fd, NULL);
01039       return -1;
01040     }
01041 
01042   /* Try opening up the permissions, but if we can't, just go ahead
01043    * and continue, maybe it will be good enough.
01044    */
01045   if (!abstract && chmod (path, 0777) < 0)
01046     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01047                 path);
01048 
01049   return listen_fd;
01050 }
01051 
01062 int
01063 _dbus_listen_systemd_sockets (int       **fds,
01064                               DBusError *error)
01065 {
01066   int r, n;
01067   unsigned fd;
01068   int *new_fds;
01069 
01070   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01071 
01072   n = sd_listen_fds (TRUE);
01073   if (n < 0)
01074     {
01075       dbus_set_error (error, _dbus_error_from_errno (-n),
01076                       "Failed to acquire systemd socket: %s",
01077                       _dbus_strerror (-n));
01078       return -1;
01079     }
01080 
01081   if (n <= 0)
01082     {
01083       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01084                       "No socket received.");
01085       return -1;
01086     }
01087 
01088   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01089     {
01090       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01091       if (r < 0)
01092         {
01093           dbus_set_error (error, _dbus_error_from_errno (-r),
01094                           "Failed to verify systemd socket type: %s",
01095                           _dbus_strerror (-r));
01096           return -1;
01097         }
01098 
01099       if (!r)
01100         {
01101           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01102                           "Passed socket has wrong type.");
01103           return -1;
01104         }
01105     }
01106 
01107   /* OK, the file descriptors are all good, so let's take posession of
01108      them then. */
01109 
01110   new_fds = dbus_new (int, n);
01111   if (!new_fds)
01112     {
01113       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01114                       "Failed to allocate file handle array.");
01115       goto fail;
01116     }
01117 
01118   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01119     {
01120       if (!_dbus_set_local_creds (fd, TRUE))
01121         {
01122           dbus_set_error (error, _dbus_error_from_errno (errno),
01123                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01124                           _dbus_strerror (errno));
01125           goto fail;
01126         }
01127 
01128       if (!_dbus_set_fd_nonblocking (fd, error))
01129         {
01130           _DBUS_ASSERT_ERROR_IS_SET (error);
01131           goto fail;
01132         }
01133 
01134       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01135     }
01136 
01137   *fds = new_fds;
01138   return n;
01139 
01140  fail:
01141 
01142   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01143     {
01144       _dbus_close (fd, NULL);
01145     }
01146 
01147   dbus_free (new_fds);
01148   return -1;
01149 }
01150 
01164 int
01165 _dbus_connect_tcp_socket (const char     *host,
01166                           const char     *port,
01167                           const char     *family,
01168                           DBusError      *error)
01169 {
01170     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01171 }
01172 
01173 int
01174 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01175                                      const char     *port,
01176                                      const char     *family,
01177                                      const char     *noncefile,
01178                                      DBusError      *error)
01179 {
01180   int saved_errno = 0;
01181   int fd = -1, res;
01182   struct addrinfo hints;
01183   struct addrinfo *ai, *tmp;
01184 
01185   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01186 
01187   _DBUS_ZERO (hints);
01188 
01189   if (!family)
01190     hints.ai_family = AF_UNSPEC;
01191   else if (!strcmp(family, "ipv4"))
01192     hints.ai_family = AF_INET;
01193   else if (!strcmp(family, "ipv6"))
01194     hints.ai_family = AF_INET6;
01195   else
01196     {
01197       dbus_set_error (error,
01198                       DBUS_ERROR_BAD_ADDRESS,
01199                       "Unknown address family %s", family);
01200       return -1;
01201     }
01202   hints.ai_protocol = IPPROTO_TCP;
01203   hints.ai_socktype = SOCK_STREAM;
01204   hints.ai_flags = AI_ADDRCONFIG;
01205 
01206   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01207     {
01208       dbus_set_error (error,
01209                       _dbus_error_from_errno (errno),
01210                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01211                       host, port, gai_strerror(res), res);
01212       _dbus_close (fd, NULL);
01213       return -1;
01214     }
01215 
01216   tmp = ai;
01217   while (tmp)
01218     {
01219       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01220         {
01221           freeaddrinfo(ai);
01222           _DBUS_ASSERT_ERROR_IS_SET(error);
01223           return -1;
01224         }
01225       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01226 
01227       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01228         {
01229           saved_errno = errno;
01230           _dbus_close(fd, NULL);
01231           fd = -1;
01232           tmp = tmp->ai_next;
01233           continue;
01234         }
01235 
01236       break;
01237     }
01238   freeaddrinfo(ai);
01239 
01240   if (fd == -1)
01241     {
01242       dbus_set_error (error,
01243                       _dbus_error_from_errno (saved_errno),
01244                       "Failed to connect to socket \"%s:%s\" %s",
01245                       host, port, _dbus_strerror(saved_errno));
01246       return -1;
01247     }
01248 
01249   if (noncefile != NULL)
01250     {
01251       DBusString noncefileStr;
01252       dbus_bool_t ret;
01253       _dbus_string_init_const (&noncefileStr, noncefile);
01254       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01255       _dbus_string_free (&noncefileStr);
01256 
01257       if (!ret)
01258     {
01259       _dbus_close (fd, NULL);
01260           return -1;
01261         }
01262     }
01263 
01264   if (!_dbus_set_fd_nonblocking (fd, error))
01265     {
01266       _dbus_close (fd, NULL);
01267       return -1;
01268     }
01269 
01270   return fd;
01271 }
01272 
01289 int
01290 _dbus_listen_tcp_socket (const char     *host,
01291                          const char     *port,
01292                          const char     *family,
01293                          DBusString     *retport,
01294                          int           **fds_p,
01295                          DBusError      *error)
01296 {
01297   int saved_errno;
01298   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01299   struct addrinfo hints;
01300   struct addrinfo *ai, *tmp;
01301   unsigned int reuseaddr;
01302 
01303   *fds_p = NULL;
01304   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01305 
01306   _DBUS_ZERO (hints);
01307 
01308   if (!family)
01309     hints.ai_family = AF_UNSPEC;
01310   else if (!strcmp(family, "ipv4"))
01311     hints.ai_family = AF_INET;
01312   else if (!strcmp(family, "ipv6"))
01313     hints.ai_family = AF_INET6;
01314   else
01315     {
01316       dbus_set_error (error,
01317                       DBUS_ERROR_BAD_ADDRESS,
01318                       "Unknown address family %s", family);
01319       return -1;
01320     }
01321 
01322   hints.ai_protocol = IPPROTO_TCP;
01323   hints.ai_socktype = SOCK_STREAM;
01324   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01325 
01326  redo_lookup_with_port:
01327   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01328     {
01329       dbus_set_error (error,
01330                       _dbus_error_from_errno (errno),
01331                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01332                       host ? host : "*", port, gai_strerror(res), res);
01333       return -1;
01334     }
01335 
01336   tmp = ai;
01337   while (tmp)
01338     {
01339       int fd = -1, *newlisten_fd;
01340       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01341         {
01342           _DBUS_ASSERT_ERROR_IS_SET(error);
01343           goto failed;
01344         }
01345       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01346 
01347       reuseaddr = 1;
01348       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01349         {
01350           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01351                       host ? host : "*", port, _dbus_strerror (errno));
01352         }
01353 
01354       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01355         {
01356           saved_errno = errno;
01357           _dbus_close(fd, NULL);
01358           if (saved_errno == EADDRINUSE)
01359             {
01360               /* Depending on kernel policy, it may or may not
01361                  be neccessary to bind to both IPv4 & 6 addresses
01362                  so ignore EADDRINUSE here */
01363               tmp = tmp->ai_next;
01364               continue;
01365             }
01366           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01367                           "Failed to bind socket \"%s:%s\": %s",
01368                           host ? host : "*", port, _dbus_strerror (saved_errno));
01369           goto failed;
01370         }
01371 
01372       if (listen (fd, 30 /* backlog */) < 0)
01373         {
01374           saved_errno = errno;
01375           _dbus_close (fd, NULL);
01376           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01377                           "Failed to listen on socket \"%s:%s\": %s",
01378                           host ? host : "*", port, _dbus_strerror (saved_errno));
01379           goto failed;
01380         }
01381 
01382       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01383       if (!newlisten_fd)
01384         {
01385           saved_errno = errno;
01386           _dbus_close (fd, NULL);
01387           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01388                           "Failed to allocate file handle array: %s",
01389                           _dbus_strerror (saved_errno));
01390           goto failed;
01391         }
01392       listen_fd = newlisten_fd;
01393       listen_fd[nlisten_fd] = fd;
01394       nlisten_fd++;
01395 
01396       if (!_dbus_string_get_length(retport))
01397         {
01398           /* If the user didn't specify a port, or used 0, then
01399              the kernel chooses a port. After the first address
01400              is bound to, we need to force all remaining addresses
01401              to use the same port */
01402           if (!port || !strcmp(port, "0"))
01403             {
01404               int result;
01405               struct sockaddr_storage addr;
01406               socklen_t addrlen;
01407               char portbuf[50];
01408 
01409               addrlen = sizeof(addr);
01410               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01411 
01412               if (result == -1 ||
01413                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01414                                       portbuf, sizeof(portbuf),
01415                                       NI_NUMERICHOST)) != 0)
01416                 {
01417                   dbus_set_error (error, _dbus_error_from_errno (errno),
01418                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01419                                   host ? host : "*", port, gai_strerror(res), res);
01420                   goto failed;
01421                 }
01422               if (!_dbus_string_append(retport, portbuf))
01423                 {
01424                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01425                   goto failed;
01426                 }
01427 
01428               /* Release current address list & redo lookup */
01429               port = _dbus_string_get_const_data(retport);
01430               freeaddrinfo(ai);
01431               goto redo_lookup_with_port;
01432             }
01433           else
01434             {
01435               if (!_dbus_string_append(retport, port))
01436                 {
01437                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01438                     goto failed;
01439                 }
01440             }
01441         }
01442 
01443       tmp = tmp->ai_next;
01444     }
01445   freeaddrinfo(ai);
01446   ai = NULL;
01447 
01448   if (!nlisten_fd)
01449     {
01450       errno = EADDRINUSE;
01451       dbus_set_error (error, _dbus_error_from_errno (errno),
01452                       "Failed to bind socket \"%s:%s\": %s",
01453                       host ? host : "*", port, _dbus_strerror (errno));
01454       goto failed;
01455     }
01456 
01457   for (i = 0 ; i < nlisten_fd ; i++)
01458     {
01459       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01460         {
01461           goto failed;
01462         }
01463     }
01464 
01465   *fds_p = listen_fd;
01466 
01467   return nlisten_fd;
01468 
01469  failed:
01470   if (ai)
01471     freeaddrinfo(ai);
01472   for (i = 0 ; i < nlisten_fd ; i++)
01473     _dbus_close(listen_fd[i], NULL);
01474   dbus_free(listen_fd);
01475   return -1;
01476 }
01477 
01478 static dbus_bool_t
01479 write_credentials_byte (int             server_fd,
01480                         DBusError      *error)
01481 {
01482   int bytes_written;
01483   char buf[1] = { '\0' };
01484 #if defined(HAVE_CMSGCRED)
01485   union {
01486           struct cmsghdr hdr;
01487           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01488   } cmsg;
01489   struct iovec iov;
01490   struct msghdr msg;
01491   iov.iov_base = buf;
01492   iov.iov_len = 1;
01493 
01494   _DBUS_ZERO(msg);
01495   msg.msg_iov = &iov;
01496   msg.msg_iovlen = 1;
01497 
01498   msg.msg_control = (caddr_t) &cmsg;
01499   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01500   _DBUS_ZERO(cmsg);
01501   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01502   cmsg.hdr.cmsg_level = SOL_SOCKET;
01503   cmsg.hdr.cmsg_type = SCM_CREDS;
01504 #endif
01505 
01506   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01507 
01508  again:
01509 
01510 #if defined(HAVE_CMSGCRED)
01511   bytes_written = sendmsg (server_fd, &msg, 0
01512 #if HAVE_DECL_MSG_NOSIGNAL
01513                            |MSG_NOSIGNAL
01514 #endif
01515                            );
01516 #else
01517   bytes_written = send (server_fd, buf, 1, 0
01518 #if HAVE_DECL_MSG_NOSIGNAL
01519                         |MSG_NOSIGNAL
01520 #endif
01521                         );
01522 #endif
01523 
01524   if (bytes_written < 0 && errno == EINTR)
01525     goto again;
01526 
01527   if (bytes_written < 0)
01528     {
01529       dbus_set_error (error, _dbus_error_from_errno (errno),
01530                       "Failed to write credentials byte: %s",
01531                      _dbus_strerror (errno));
01532       return FALSE;
01533     }
01534   else if (bytes_written == 0)
01535     {
01536       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01537                       "wrote zero bytes writing credentials byte");
01538       return FALSE;
01539     }
01540   else
01541     {
01542       _dbus_assert (bytes_written == 1);
01543       _dbus_verbose ("wrote credentials byte\n");
01544       return TRUE;
01545     }
01546 }
01547 
01569 dbus_bool_t
01570 _dbus_read_credentials_socket  (int              client_fd,
01571                                 DBusCredentials *credentials,
01572                                 DBusError       *error)
01573 {
01574   struct msghdr msg;
01575   struct iovec iov;
01576   char buf;
01577   dbus_uid_t uid_read;
01578   dbus_pid_t pid_read;
01579   int bytes_read;
01580 
01581 #ifdef HAVE_CMSGCRED
01582   union {
01583     struct cmsghdr hdr;
01584     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01585   } cmsg;
01586 
01587 #elif defined(LOCAL_CREDS)
01588   struct {
01589     struct cmsghdr hdr;
01590     struct sockcred cred;
01591   } cmsg;
01592 #endif
01593 
01594   uid_read = DBUS_UID_UNSET;
01595   pid_read = DBUS_PID_UNSET;
01596 
01597   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01598 
01599   /* The POSIX spec certainly doesn't promise this, but
01600    * we need these assertions to fail as soon as we're wrong about
01601    * it so we can do the porting fixups
01602    */
01603   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01604   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01605   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01606 
01607   _dbus_credentials_clear (credentials);
01608 
01609   /* Systems supporting LOCAL_CREDS are configured to have this feature
01610    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01611    * the connection.  Therefore, the received message must carry the
01612    * credentials information without doing anything special.
01613    */
01614 
01615   iov.iov_base = &buf;
01616   iov.iov_len = 1;
01617 
01618   _DBUS_ZERO(msg);
01619   msg.msg_iov = &iov;
01620   msg.msg_iovlen = 1;
01621 
01622 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01623   _DBUS_ZERO(cmsg);
01624   msg.msg_control = (caddr_t) &cmsg;
01625   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01626 #endif
01627 
01628  again:
01629   bytes_read = recvmsg (client_fd, &msg, 0);
01630 
01631   if (bytes_read < 0)
01632     {
01633       if (errno == EINTR)
01634         goto again;
01635 
01636       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01637        * normally only call read_credentials if the socket was ready
01638        * for reading
01639        */
01640 
01641       dbus_set_error (error, _dbus_error_from_errno (errno),
01642                       "Failed to read credentials byte: %s",
01643                       _dbus_strerror (errno));
01644       return FALSE;
01645     }
01646   else if (bytes_read == 0)
01647     {
01648       /* this should not happen unless we are using recvmsg wrong,
01649        * so is essentially here for paranoia
01650        */
01651       dbus_set_error (error, DBUS_ERROR_FAILED,
01652                       "Failed to read credentials byte (zero-length read)");
01653       return FALSE;
01654     }
01655   else if (buf != '\0')
01656     {
01657       dbus_set_error (error, DBUS_ERROR_FAILED,
01658                       "Credentials byte was not nul");
01659       return FALSE;
01660     }
01661 
01662 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01663   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01664                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01665     {
01666       dbus_set_error (error, DBUS_ERROR_FAILED,
01667                       "Message from recvmsg() was not SCM_CREDS");
01668       return FALSE;
01669     }
01670 #endif
01671 
01672   _dbus_verbose ("read credentials byte\n");
01673 
01674   {
01675 #ifdef SO_PEERCRED
01676 #ifdef __OpenBSD__
01677     struct sockpeercred cr;
01678 #else
01679     struct ucred cr;
01680 #endif
01681     int cr_len = sizeof (cr);
01682 
01683     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01684         cr_len == sizeof (cr))
01685       {
01686         pid_read = cr.pid;
01687         uid_read = cr.uid;
01688       }
01689     else
01690       {
01691         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01692                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01693       }
01694 #elif defined(HAVE_CMSGCRED)
01695     struct cmsgcred *cred;
01696 
01697     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01698     pid_read = cred->cmcred_pid;
01699     uid_read = cred->cmcred_euid;
01700 #elif defined(LOCAL_CREDS)
01701     pid_read = DBUS_PID_UNSET;
01702     uid_read = cmsg.cred.sc_uid;
01703     /* Since we have already got the credentials from this socket, we can
01704      * disable its LOCAL_CREDS flag if it was ever set. */
01705     _dbus_set_local_creds (client_fd, FALSE);
01706 #elif defined(HAVE_GETPEEREID)
01707     uid_t euid;
01708     gid_t egid;
01709     if (getpeereid (client_fd, &euid, &egid) == 0)
01710       {
01711         uid_read = euid;
01712       }
01713     else
01714       {
01715         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01716       }
01717 #elif defined(HAVE_GETPEERUCRED)
01718     ucred_t * ucred = NULL;
01719     if (getpeerucred (client_fd, &ucred) == 0)
01720       {
01721         pid_read = ucred_getpid (ucred);
01722         uid_read = ucred_geteuid (ucred);
01723 #ifdef HAVE_ADT
01724         /* generate audit session data based on socket ucred */
01725         adt_session_data_t *adth = NULL;
01726         adt_export_data_t *data = NULL;
01727         size_t size = 0;
01728         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01729           {
01730             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01731           }
01732         else
01733           {
01734             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01735               {
01736                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01737               }
01738             else
01739               {
01740                 size = adt_export_session_data (adth, &data);
01741                 if (size <= 0)
01742                   {
01743                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01744                   }
01745                 else
01746                   {
01747                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01748                     free (data);
01749                   }
01750               }
01751             (void) adt_end_session (adth);
01752           }
01753 #endif /* HAVE_ADT */
01754       }
01755     else
01756       {
01757         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01758       }
01759     if (ucred != NULL)
01760       ucred_free (ucred);
01761 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01762     _dbus_verbose ("Socket credentials not supported on this OS\n");
01763 #endif
01764   }
01765 
01766   _dbus_verbose ("Credentials:"
01767                  "  pid "DBUS_PID_FORMAT
01768                  "  uid "DBUS_UID_FORMAT
01769                  "\n",
01770                  pid_read,
01771                  uid_read);
01772 
01773   if (pid_read != DBUS_PID_UNSET)
01774     {
01775       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01776         {
01777           _DBUS_SET_OOM (error);
01778           return FALSE;
01779         }
01780     }
01781 
01782   if (uid_read != DBUS_UID_UNSET)
01783     {
01784       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01785         {
01786           _DBUS_SET_OOM (error);
01787           return FALSE;
01788         }
01789     }
01790 
01791   return TRUE;
01792 }
01793 
01811 dbus_bool_t
01812 _dbus_send_credentials_socket  (int              server_fd,
01813                                 DBusError       *error)
01814 {
01815   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01816 
01817   if (write_credentials_byte (server_fd, error))
01818     return TRUE;
01819   else
01820     return FALSE;
01821 }
01822 
01832 int
01833 _dbus_accept  (int listen_fd)
01834 {
01835   int client_fd;
01836   struct sockaddr addr;
01837   socklen_t addrlen;
01838 #ifdef HAVE_ACCEPT4
01839   dbus_bool_t cloexec_done;
01840 #endif
01841 
01842   addrlen = sizeof (addr);
01843 
01844  retry:
01845 
01846 #ifdef HAVE_ACCEPT4
01847   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01848   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01849   cloexec_done = client_fd >= 0;
01850 
01851   if (client_fd < 0 && errno == ENOSYS)
01852 #endif
01853     {
01854       client_fd = accept (listen_fd, &addr, &addrlen);
01855     }
01856 
01857   if (client_fd < 0)
01858     {
01859       if (errno == EINTR)
01860         goto retry;
01861     }
01862 
01863   _dbus_verbose ("client fd %d accepted\n", client_fd);
01864 
01865 #ifdef HAVE_ACCEPT4
01866   if (!cloexec_done)
01867 #endif
01868     {
01869       _dbus_fd_set_close_on_exec(client_fd);
01870     }
01871 
01872   return client_fd;
01873 }
01874 
01883 dbus_bool_t
01884 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01885 {
01886   const char *directory;
01887   struct stat sb;
01888 
01889   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01890 
01891   directory = _dbus_string_get_const_data (dir);
01892 
01893   if (stat (directory, &sb) < 0)
01894     {
01895       dbus_set_error (error, _dbus_error_from_errno (errno),
01896                       "%s", _dbus_strerror (errno));
01897 
01898       return FALSE;
01899     }
01900 
01901   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01902       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01903     {
01904       dbus_set_error (error, DBUS_ERROR_FAILED,
01905                      "%s directory is not private to the user", directory);
01906       return FALSE;
01907     }
01908 
01909   return TRUE;
01910 }
01911 
01912 static dbus_bool_t
01913 fill_user_info_from_passwd (struct passwd *p,
01914                             DBusUserInfo  *info,
01915                             DBusError     *error)
01916 {
01917   _dbus_assert (p->pw_name != NULL);
01918   _dbus_assert (p->pw_dir != NULL);
01919 
01920   info->uid = p->pw_uid;
01921   info->primary_gid = p->pw_gid;
01922   info->username = _dbus_strdup (p->pw_name);
01923   info->homedir = _dbus_strdup (p->pw_dir);
01924 
01925   if (info->username == NULL ||
01926       info->homedir == NULL)
01927     {
01928       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01929       return FALSE;
01930     }
01931 
01932   return TRUE;
01933 }
01934 
01935 static dbus_bool_t
01936 fill_user_info (DBusUserInfo       *info,
01937                 dbus_uid_t          uid,
01938                 const DBusString   *username,
01939                 DBusError          *error)
01940 {
01941   const char *username_c;
01942 
01943   /* exactly one of username/uid provided */
01944   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01945   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01946 
01947   info->uid = DBUS_UID_UNSET;
01948   info->primary_gid = DBUS_GID_UNSET;
01949   info->group_ids = NULL;
01950   info->n_group_ids = 0;
01951   info->username = NULL;
01952   info->homedir = NULL;
01953 
01954   if (username != NULL)
01955     username_c = _dbus_string_get_const_data (username);
01956   else
01957     username_c = NULL;
01958 
01959   /* For now assuming that the getpwnam() and getpwuid() flavors
01960    * are always symmetrical, if not we have to add more configure
01961    * checks
01962    */
01963 
01964 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01965   {
01966     struct passwd *p;
01967     int result;
01968     size_t buflen;
01969     char *buf;
01970     struct passwd p_str;
01971 
01972     /* retrieve maximum needed size for buf */
01973     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01974 
01975     /* sysconf actually returns a long, but everything else expects size_t,
01976      * so just recast here.
01977      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
01978      */
01979     if ((long) buflen <= 0)
01980       buflen = 1024;
01981 
01982     result = -1;
01983     while (1)
01984       {
01985         buf = dbus_malloc (buflen);
01986         if (buf == NULL)
01987           {
01988             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01989             return FALSE;
01990           }
01991 
01992         p = NULL;
01993 #ifdef HAVE_POSIX_GETPWNAM_R
01994         if (uid != DBUS_UID_UNSET)
01995           result = getpwuid_r (uid, &p_str, buf, buflen,
01996                                &p);
01997         else
01998           result = getpwnam_r (username_c, &p_str, buf, buflen,
01999                                &p);
02000 #else
02001         if (uid != DBUS_UID_UNSET)
02002           p = getpwuid_r (uid, &p_str, buf, buflen);
02003         else
02004           p = getpwnam_r (username_c, &p_str, buf, buflen);
02005         result = 0;
02006 #endif /* !HAVE_POSIX_GETPWNAM_R */
02007         //Try a bigger buffer if ERANGE was returned
02008         if (result == ERANGE && buflen < 512 * 1024)
02009           {
02010             dbus_free (buf);
02011             buflen *= 2;
02012           }
02013         else
02014           {
02015             break;
02016           }
02017       }
02018     if (result == 0 && p == &p_str)
02019       {
02020         if (!fill_user_info_from_passwd (p, info, error))
02021           {
02022             dbus_free (buf);
02023             return FALSE;
02024           }
02025         dbus_free (buf);
02026       }
02027     else
02028       {
02029         dbus_set_error (error, _dbus_error_from_errno (errno),
02030                         "User \"%s\" unknown or no memory to allocate password entry\n",
02031                         username_c ? username_c : "???");
02032         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02033         dbus_free (buf);
02034         return FALSE;
02035       }
02036   }
02037 #else /* ! HAVE_GETPWNAM_R */
02038   {
02039     /* I guess we're screwed on thread safety here */
02040     struct passwd *p;
02041 
02042     if (uid != DBUS_UID_UNSET)
02043       p = getpwuid (uid);
02044     else
02045       p = getpwnam (username_c);
02046 
02047     if (p != NULL)
02048       {
02049         if (!fill_user_info_from_passwd (p, info, error))
02050           {
02051             return FALSE;
02052           }
02053       }
02054     else
02055       {
02056         dbus_set_error (error, _dbus_error_from_errno (errno),
02057                         "User \"%s\" unknown or no memory to allocate password entry\n",
02058                         username_c ? username_c : "???");
02059         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02060         return FALSE;
02061       }
02062   }
02063 #endif  /* ! HAVE_GETPWNAM_R */
02064 
02065   /* Fill this in so we can use it to get groups */
02066   username_c = info->username;
02067 
02068 #ifdef HAVE_GETGROUPLIST
02069   {
02070     gid_t *buf;
02071     int buf_count;
02072     int i;
02073     int initial_buf_count;
02074 
02075     initial_buf_count = 17;
02076     buf_count = initial_buf_count;
02077     buf = dbus_new (gid_t, buf_count);
02078     if (buf == NULL)
02079       {
02080         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02081         goto failed;
02082       }
02083 
02084     if (getgrouplist (username_c,
02085                       info->primary_gid,
02086                       buf, &buf_count) < 0)
02087       {
02088         gid_t *new;
02089         /* Presumed cause of negative return code: buf has insufficient
02090            entries to hold the entire group list. The Linux behavior in this
02091            case is to pass back the actual number of groups in buf_count, but
02092            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02093            So as a hack, try to help out a bit by guessing a larger
02094            number of groups, within reason.. might still fail, of course,
02095            but we can at least print a more informative message.  I looked up
02096            the "right way" to do this by downloading Apple's own source code
02097            for the "id" command, and it turns out that they use an
02098            undocumented library function getgrouplist_2 (!) which is not
02099            declared in any header in /usr/include (!!). That did not seem
02100            like the way to go here.
02101         */
02102         if (buf_count == initial_buf_count)
02103           {
02104             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02105           }
02106         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02107         if (new == NULL)
02108           {
02109             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02110             dbus_free (buf);
02111             goto failed;
02112           }
02113 
02114         buf = new;
02115 
02116         errno = 0;
02117         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02118           {
02119             if (errno == 0)
02120               {
02121                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02122                             username_c, buf_count, buf_count);
02123               }
02124             else
02125               {
02126                 dbus_set_error (error,
02127                                 _dbus_error_from_errno (errno),
02128                                 "Failed to get groups for username \"%s\" primary GID "
02129                                 DBUS_GID_FORMAT ": %s\n",
02130                                 username_c, info->primary_gid,
02131                                 _dbus_strerror (errno));
02132                 dbus_free (buf);
02133                 goto failed;
02134               }
02135           }
02136       }
02137 
02138     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02139     if (info->group_ids == NULL)
02140       {
02141         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02142         dbus_free (buf);
02143         goto failed;
02144       }
02145 
02146     for (i = 0; i < buf_count; ++i)
02147       info->group_ids[i] = buf[i];
02148 
02149     info->n_group_ids = buf_count;
02150 
02151     dbus_free (buf);
02152   }
02153 #else  /* HAVE_GETGROUPLIST */
02154   {
02155     /* We just get the one group ID */
02156     info->group_ids = dbus_new (dbus_gid_t, 1);
02157     if (info->group_ids == NULL)
02158       {
02159         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02160         goto failed;
02161       }
02162 
02163     info->n_group_ids = 1;
02164 
02165     (info->group_ids)[0] = info->primary_gid;
02166   }
02167 #endif /* HAVE_GETGROUPLIST */
02168 
02169   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02170 
02171   return TRUE;
02172 
02173  failed:
02174   _DBUS_ASSERT_ERROR_IS_SET (error);
02175   return FALSE;
02176 }
02177 
02186 dbus_bool_t
02187 _dbus_user_info_fill (DBusUserInfo     *info,
02188                       const DBusString *username,
02189                       DBusError        *error)
02190 {
02191   return fill_user_info (info, DBUS_UID_UNSET,
02192                          username, error);
02193 }
02194 
02203 dbus_bool_t
02204 _dbus_user_info_fill_uid (DBusUserInfo *info,
02205                           dbus_uid_t    uid,
02206                           DBusError    *error)
02207 {
02208   return fill_user_info (info, uid,
02209                          NULL, error);
02210 }
02211 
02219 dbus_bool_t
02220 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02221 {
02222   /* The POSIX spec certainly doesn't promise this, but
02223    * we need these assertions to fail as soon as we're wrong about
02224    * it so we can do the porting fixups
02225    */
02226   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02227   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02228   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02229 
02230   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02231     return FALSE;
02232   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02233     return FALSE;
02234 
02235   return TRUE;
02236 }
02237 
02249 dbus_bool_t
02250 _dbus_append_user_from_current_process (DBusString *str)
02251 {
02252   return _dbus_string_append_uint (str,
02253                                    _dbus_geteuid ());
02254 }
02255 
02260 dbus_pid_t
02261 _dbus_getpid (void)
02262 {
02263   return getpid ();
02264 }
02265 
02269 dbus_uid_t
02270 _dbus_getuid (void)
02271 {
02272   return getuid ();
02273 }
02274 
02278 dbus_uid_t
02279 _dbus_geteuid (void)
02280 {
02281   return geteuid ();
02282 }
02283 
02290 unsigned long
02291 _dbus_pid_for_log (void)
02292 {
02293   return getpid ();
02294 }
02295 
02303 dbus_bool_t
02304 _dbus_parse_uid (const DBusString      *uid_str,
02305                  dbus_uid_t            *uid)
02306 {
02307   int end;
02308   long val;
02309 
02310   if (_dbus_string_get_length (uid_str) == 0)
02311     {
02312       _dbus_verbose ("UID string was zero length\n");
02313       return FALSE;
02314     }
02315 
02316   val = -1;
02317   end = 0;
02318   if (!_dbus_string_parse_int (uid_str, 0, &val,
02319                                &end))
02320     {
02321       _dbus_verbose ("could not parse string as a UID\n");
02322       return FALSE;
02323     }
02324 
02325   if (end != _dbus_string_get_length (uid_str))
02326     {
02327       _dbus_verbose ("string contained trailing stuff after UID\n");
02328       return FALSE;
02329     }
02330 
02331   *uid = val;
02332 
02333   return TRUE;
02334 }
02335 
02336 #if !DBUS_USE_SYNC
02337 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02338 #endif
02339 
02346 dbus_int32_t
02347 _dbus_atomic_inc (DBusAtomic *atomic)
02348 {
02349 #if DBUS_USE_SYNC
02350   return __sync_add_and_fetch(&atomic->value, 1)-1;
02351 #else
02352   dbus_int32_t res;
02353   _DBUS_LOCK (atomic);
02354   res = atomic->value;
02355   atomic->value += 1;
02356   _DBUS_UNLOCK (atomic);
02357   return res;
02358 #endif
02359 }
02360 
02367 dbus_int32_t
02368 _dbus_atomic_dec (DBusAtomic *atomic)
02369 {
02370 #if DBUS_USE_SYNC
02371   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02372 #else
02373   dbus_int32_t res;
02374 
02375   _DBUS_LOCK (atomic);
02376   res = atomic->value;
02377   atomic->value -= 1;
02378   _DBUS_UNLOCK (atomic);
02379   return res;
02380 #endif
02381 }
02382 
02390 dbus_int32_t
02391 _dbus_atomic_get (DBusAtomic *atomic)
02392 {
02393 #if DBUS_USE_SYNC
02394   __sync_synchronize ();
02395   return atomic->value;
02396 #else
02397   dbus_int32_t res;
02398 
02399   _DBUS_LOCK (atomic);
02400   res = atomic->value;
02401   _DBUS_UNLOCK (atomic);
02402   return res;
02403 #endif
02404 }
02405 
02406 #ifdef DBUS_BUILD_TESTS
02407 
02410 dbus_gid_t
02411 _dbus_getgid (void)
02412 {
02413   return getgid ();
02414 }
02415 #endif
02416 
02425 int
02426 _dbus_poll (DBusPollFD *fds,
02427             int         n_fds,
02428             int         timeout_milliseconds)
02429 {
02430 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02431   /* This big thing is a constant expression and should get optimized
02432    * out of existence. So it's more robust than a configure check at
02433    * no cost.
02434    */
02435   if (_DBUS_POLLIN == POLLIN &&
02436       _DBUS_POLLPRI == POLLPRI &&
02437       _DBUS_POLLOUT == POLLOUT &&
02438       _DBUS_POLLERR == POLLERR &&
02439       _DBUS_POLLHUP == POLLHUP &&
02440       _DBUS_POLLNVAL == POLLNVAL &&
02441       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02442       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02443       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02444       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02445       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02446       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02447       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02448     {
02449       return poll ((struct pollfd*) fds,
02450                    n_fds,
02451                    timeout_milliseconds);
02452     }
02453   else
02454     {
02455       /* We have to convert the DBusPollFD to an array of
02456        * struct pollfd, poll, and convert back.
02457        */
02458       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02459       return -1;
02460     }
02461 #else /* ! HAVE_POLL */
02462 
02463   fd_set read_set, write_set, err_set;
02464   int max_fd = 0;
02465   int i;
02466   struct timeval tv;
02467   int ready;
02468 
02469   FD_ZERO (&read_set);
02470   FD_ZERO (&write_set);
02471   FD_ZERO (&err_set);
02472 
02473   for (i = 0; i < n_fds; i++)
02474     {
02475       DBusPollFD *fdp = &fds[i];
02476 
02477       if (fdp->events & _DBUS_POLLIN)
02478         FD_SET (fdp->fd, &read_set);
02479 
02480       if (fdp->events & _DBUS_POLLOUT)
02481         FD_SET (fdp->fd, &write_set);
02482 
02483       FD_SET (fdp->fd, &err_set);
02484 
02485       max_fd = MAX (max_fd, fdp->fd);
02486     }
02487 
02488   tv.tv_sec = timeout_milliseconds / 1000;
02489   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02490 
02491   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02492                   timeout_milliseconds < 0 ? NULL : &tv);
02493 
02494   if (ready > 0)
02495     {
02496       for (i = 0; i < n_fds; i++)
02497         {
02498           DBusPollFD *fdp = &fds[i];
02499 
02500           fdp->revents = 0;
02501 
02502           if (FD_ISSET (fdp->fd, &read_set))
02503             fdp->revents |= _DBUS_POLLIN;
02504 
02505           if (FD_ISSET (fdp->fd, &write_set))
02506             fdp->revents |= _DBUS_POLLOUT;
02507 
02508           if (FD_ISSET (fdp->fd, &err_set))
02509             fdp->revents |= _DBUS_POLLERR;
02510         }
02511     }
02512 
02513   return ready;
02514 #endif
02515 }
02516 
02524 void
02525 _dbus_get_current_time (long *tv_sec,
02526                         long *tv_usec)
02527 {
02528 #ifdef HAVE_MONOTONIC_CLOCK
02529   struct timespec ts;
02530   clock_gettime (CLOCK_MONOTONIC, &ts);
02531 
02532   if (tv_sec)
02533     *tv_sec = ts.tv_sec;
02534   if (tv_usec)
02535     *tv_usec = ts.tv_nsec / 1000;
02536 #else
02537   struct timeval t;
02538 
02539   gettimeofday (&t, NULL);
02540 
02541   if (tv_sec)
02542     *tv_sec = t.tv_sec;
02543   if (tv_usec)
02544     *tv_usec = t.tv_usec;
02545 #endif
02546 }
02547 
02556 dbus_bool_t
02557 _dbus_create_directory (const DBusString *filename,
02558                         DBusError        *error)
02559 {
02560   const char *filename_c;
02561 
02562   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02563 
02564   filename_c = _dbus_string_get_const_data (filename);
02565 
02566   if (mkdir (filename_c, 0700) < 0)
02567     {
02568       if (errno == EEXIST)
02569         return TRUE;
02570 
02571       dbus_set_error (error, DBUS_ERROR_FAILED,
02572                       "Failed to create directory %s: %s\n",
02573                       filename_c, _dbus_strerror (errno));
02574       return FALSE;
02575     }
02576   else
02577     return TRUE;
02578 }
02579 
02590 dbus_bool_t
02591 _dbus_concat_dir_and_file (DBusString       *dir,
02592                            const DBusString *next_component)
02593 {
02594   dbus_bool_t dir_ends_in_slash;
02595   dbus_bool_t file_starts_with_slash;
02596 
02597   if (_dbus_string_get_length (dir) == 0 ||
02598       _dbus_string_get_length (next_component) == 0)
02599     return TRUE;
02600 
02601   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02602                                                     _dbus_string_get_length (dir) - 1);
02603 
02604   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02605 
02606   if (dir_ends_in_slash && file_starts_with_slash)
02607     {
02608       _dbus_string_shorten (dir, 1);
02609     }
02610   else if (!(dir_ends_in_slash || file_starts_with_slash))
02611     {
02612       if (!_dbus_string_append_byte (dir, '/'))
02613         return FALSE;
02614     }
02615 
02616   return _dbus_string_copy (next_component, 0, dir,
02617                             _dbus_string_get_length (dir));
02618 }
02619 
02621 #define NANOSECONDS_PER_SECOND       1000000000
02622 
02623 #define MICROSECONDS_PER_SECOND      1000000
02624 
02625 #define MILLISECONDS_PER_SECOND      1000
02626 
02627 #define NANOSECONDS_PER_MILLISECOND  1000000
02628 
02629 #define MICROSECONDS_PER_MILLISECOND 1000
02630 
02635 void
02636 _dbus_sleep_milliseconds (int milliseconds)
02637 {
02638 #ifdef HAVE_NANOSLEEP
02639   struct timespec req;
02640   struct timespec rem;
02641 
02642   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02643   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02644   rem.tv_sec = 0;
02645   rem.tv_nsec = 0;
02646 
02647   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02648     req = rem;
02649 #elif defined (HAVE_USLEEP)
02650   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02651 #else /* ! HAVE_USLEEP */
02652   sleep (MAX (milliseconds / 1000, 1));
02653 #endif
02654 }
02655 
02656 static dbus_bool_t
02657 _dbus_generate_pseudorandom_bytes (DBusString *str,
02658                                    int         n_bytes)
02659 {
02660   int old_len;
02661   char *p;
02662 
02663   old_len = _dbus_string_get_length (str);
02664 
02665   if (!_dbus_string_lengthen (str, n_bytes))
02666     return FALSE;
02667 
02668   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02669 
02670   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02671 
02672   return TRUE;
02673 }
02674 
02683 dbus_bool_t
02684 _dbus_generate_random_bytes (DBusString *str,
02685                              int         n_bytes)
02686 {
02687   int old_len;
02688   int fd;
02689 
02690   /* FALSE return means "no memory", if it could
02691    * mean something else then we'd need to return
02692    * a DBusError. So we always fall back to pseudorandom
02693    * if the I/O fails.
02694    */
02695 
02696   old_len = _dbus_string_get_length (str);
02697   fd = -1;
02698 
02699   /* note, urandom on linux will fall back to pseudorandom */
02700   fd = open ("/dev/urandom", O_RDONLY);
02701   if (fd < 0)
02702     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02703 
02704   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02705 
02706   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02707     {
02708       _dbus_close (fd, NULL);
02709       _dbus_string_set_length (str, old_len);
02710       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02711     }
02712 
02713   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02714                  n_bytes);
02715 
02716   _dbus_close (fd, NULL);
02717 
02718   return TRUE;
02719 }
02720 
02726 void
02727 _dbus_exit (int code)
02728 {
02729   _exit (code);
02730 }
02731 
02740 const char*
02741 _dbus_strerror (int error_number)
02742 {
02743   const char *msg;
02744 
02745   msg = strerror (error_number);
02746   if (msg == NULL)
02747     msg = "unknown";
02748 
02749   return msg;
02750 }
02751 
02755 void
02756 _dbus_disable_sigpipe (void)
02757 {
02758   signal (SIGPIPE, SIG_IGN);
02759 }
02760 
02768 void
02769 _dbus_fd_set_close_on_exec (intptr_t fd)
02770 {
02771   int val;
02772 
02773   val = fcntl (fd, F_GETFD, 0);
02774 
02775   if (val < 0)
02776     return;
02777 
02778   val |= FD_CLOEXEC;
02779 
02780   fcntl (fd, F_SETFD, val);
02781 }
02782 
02790 dbus_bool_t
02791 _dbus_close (int        fd,
02792              DBusError *error)
02793 {
02794   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02795 
02796  again:
02797   if (close (fd) < 0)
02798     {
02799       if (errno == EINTR)
02800         goto again;
02801 
02802       dbus_set_error (error, _dbus_error_from_errno (errno),
02803                       "Could not close fd %d", fd);
02804       return FALSE;
02805     }
02806 
02807   return TRUE;
02808 }
02809 
02817 int
02818 _dbus_dup(int        fd,
02819           DBusError *error)
02820 {
02821   int new_fd;
02822 
02823 #ifdef F_DUPFD_CLOEXEC
02824   dbus_bool_t cloexec_done;
02825 
02826   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02827   cloexec_done = new_fd >= 0;
02828 
02829   if (new_fd < 0 && errno == EINVAL)
02830 #endif
02831     {
02832       new_fd = fcntl(fd, F_DUPFD, 3);
02833     }
02834 
02835   if (new_fd < 0) {
02836 
02837     dbus_set_error (error, _dbus_error_from_errno (errno),
02838                     "Could not duplicate fd %d", fd);
02839     return -1;
02840   }
02841 
02842 #ifdef F_DUPFD_CLOEXEC
02843   if (!cloexec_done)
02844 #endif
02845     {
02846       _dbus_fd_set_close_on_exec(new_fd);
02847     }
02848 
02849   return new_fd;
02850 }
02851 
02859 dbus_bool_t
02860 _dbus_set_fd_nonblocking (int             fd,
02861                           DBusError      *error)
02862 {
02863   int val;
02864 
02865   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02866 
02867   val = fcntl (fd, F_GETFL, 0);
02868   if (val < 0)
02869     {
02870       dbus_set_error (error, _dbus_error_from_errno (errno),
02871                       "Failed to get flags from file descriptor %d: %s",
02872                       fd, _dbus_strerror (errno));
02873       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02874                      _dbus_strerror (errno));
02875       return FALSE;
02876     }
02877 
02878   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02879     {
02880       dbus_set_error (error, _dbus_error_from_errno (errno),
02881                       "Failed to set nonblocking flag of file descriptor %d: %s",
02882                       fd, _dbus_strerror (errno));
02883       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02884                      fd, _dbus_strerror (errno));
02885 
02886       return FALSE;
02887     }
02888 
02889   return TRUE;
02890 }
02891 
02897 void
02898 _dbus_print_backtrace (void)
02899 {
02900 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02901   void *bt[500];
02902   int bt_size;
02903   int i;
02904   char **syms;
02905 
02906   bt_size = backtrace (bt, 500);
02907 
02908   syms = backtrace_symbols (bt, bt_size);
02909 
02910   i = 0;
02911   while (i < bt_size)
02912     {
02913       /* don't use dbus_warn since it can _dbus_abort() */
02914       fprintf (stderr, "  %s\n", syms[i]);
02915       ++i;
02916     }
02917   fflush (stderr);
02918 
02919   free (syms);
02920 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02921   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02922 #else
02923   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02924 #endif
02925 }
02926 
02944 dbus_bool_t
02945 _dbus_full_duplex_pipe (int        *fd1,
02946                         int        *fd2,
02947                         dbus_bool_t blocking,
02948                         DBusError  *error)
02949 {
02950 #ifdef HAVE_SOCKETPAIR
02951   int fds[2];
02952   int retval;
02953 
02954 #ifdef SOCK_CLOEXEC
02955   dbus_bool_t cloexec_done;
02956 
02957   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02958   cloexec_done = retval >= 0;
02959 
02960   if (retval < 0 && errno == EINVAL)
02961 #endif
02962     {
02963       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02964     }
02965 
02966   if (retval < 0)
02967     {
02968       dbus_set_error (error, _dbus_error_from_errno (errno),
02969                       "Could not create full-duplex pipe");
02970       return FALSE;
02971     }
02972 
02973   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02974 
02975 #ifdef SOCK_CLOEXEC
02976   if (!cloexec_done)
02977 #endif
02978     {
02979       _dbus_fd_set_close_on_exec (fds[0]);
02980       _dbus_fd_set_close_on_exec (fds[1]);
02981     }
02982 
02983   if (!blocking &&
02984       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02985        !_dbus_set_fd_nonblocking (fds[1], NULL)))
02986     {
02987       dbus_set_error (error, _dbus_error_from_errno (errno),
02988                       "Could not set full-duplex pipe nonblocking");
02989 
02990       _dbus_close (fds[0], NULL);
02991       _dbus_close (fds[1], NULL);
02992 
02993       return FALSE;
02994     }
02995 
02996   *fd1 = fds[0];
02997   *fd2 = fds[1];
02998 
02999   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03000                  *fd1, *fd2);
03001 
03002   return TRUE;
03003 #else
03004   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
03005   dbus_set_error (error, DBUS_ERROR_FAILED,
03006                   "_dbus_full_duplex_pipe() not implemented on this OS");
03007   return FALSE;
03008 #endif
03009 }
03010 
03019 int
03020 _dbus_printf_string_upper_bound (const char *format,
03021                                  va_list     args)
03022 {
03023   char static_buf[1024];
03024   int bufsize = sizeof (static_buf);
03025   int len;
03026 
03027   len = vsnprintf (static_buf, bufsize, format, args);
03028 
03029   /* If vsnprintf() returned non-negative, then either the string fits in
03030    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03031    * returns the number of characters that were needed, or this OS returns the
03032    * truncated length.
03033    *
03034    * We ignore the possibility that snprintf might just ignore the length and
03035    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03036    * If your libc is really that bad, come back when you have a better one. */
03037   if (len == bufsize)
03038     {
03039       /* This could be the truncated length (Tru64 and IRIX have this bug),
03040        * or the real length could be coincidentally the same. Which is it?
03041        * If vsnprintf returns the truncated length, we'll go to the slow
03042        * path. */
03043       if (vsnprintf (static_buf, 1, format, args) == 1)
03044         len = -1;
03045     }
03046 
03047   /* If vsnprintf() returned negative, we have to do more work.
03048    * HP-UX returns negative. */
03049   while (len < 0)
03050     {
03051       char *buf;
03052 
03053       bufsize *= 2;
03054 
03055       buf = dbus_malloc (bufsize);
03056 
03057       if (buf == NULL)
03058         return -1;
03059 
03060       len = vsnprintf (buf, bufsize, format, args);
03061       dbus_free (buf);
03062 
03063       /* If the reported length is exactly the buffer size, round up to the
03064        * next size, in case vsnprintf has been returning the truncated
03065        * length */
03066       if (len == bufsize)
03067         len = -1;
03068     }
03069 
03070   return len;
03071 }
03072 
03079 const char*
03080 _dbus_get_tmpdir(void)
03081 {
03082   static const char* tmpdir = NULL;
03083 
03084   if (tmpdir == NULL)
03085     {
03086       /* TMPDIR is what glibc uses, then
03087        * glibc falls back to the P_tmpdir macro which
03088        * just expands to "/tmp"
03089        */
03090       if (tmpdir == NULL)
03091         tmpdir = getenv("TMPDIR");
03092 
03093       /* These two env variables are probably
03094        * broken, but maybe some OS uses them?
03095        */
03096       if (tmpdir == NULL)
03097         tmpdir = getenv("TMP");
03098       if (tmpdir == NULL)
03099         tmpdir = getenv("TEMP");
03100 
03101       /* And this is the sane fallback. */
03102       if (tmpdir == NULL)
03103         tmpdir = "/tmp";
03104     }
03105 
03106   _dbus_assert(tmpdir != NULL);
03107 
03108   return tmpdir;
03109 }
03110 
03130 static dbus_bool_t
03131 _read_subprocess_line_argv (const char *progpath,
03132                             dbus_bool_t path_fallback,
03133                             char       * const *argv,
03134                             DBusString *result,
03135                             DBusError  *error)
03136 {
03137   int result_pipe[2] = { -1, -1 };
03138   int errors_pipe[2] = { -1, -1 };
03139   pid_t pid;
03140   int ret;
03141   int status;
03142   int orig_len;
03143   int i;
03144 
03145   dbus_bool_t retval;
03146   sigset_t new_set, old_set;
03147 
03148   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03149   retval = FALSE;
03150 
03151   /* We need to block any existing handlers for SIGCHLD temporarily; they
03152    * will cause waitpid() below to fail.
03153    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03154    */
03155   sigemptyset (&new_set);
03156   sigaddset (&new_set, SIGCHLD);
03157   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03158 
03159   orig_len = _dbus_string_get_length (result);
03160 
03161 #define READ_END        0
03162 #define WRITE_END       1
03163   if (pipe (result_pipe) < 0)
03164     {
03165       dbus_set_error (error, _dbus_error_from_errno (errno),
03166                       "Failed to create a pipe to call %s: %s",
03167                       progpath, _dbus_strerror (errno));
03168       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03169                      progpath, _dbus_strerror (errno));
03170       goto out;
03171     }
03172   if (pipe (errors_pipe) < 0)
03173     {
03174       dbus_set_error (error, _dbus_error_from_errno (errno),
03175                       "Failed to create a pipe to call %s: %s",
03176                       progpath, _dbus_strerror (errno));
03177       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03178                      progpath, _dbus_strerror (errno));
03179       goto out;
03180     }
03181 
03182   pid = fork ();
03183   if (pid < 0)
03184     {
03185       dbus_set_error (error, _dbus_error_from_errno (errno),
03186                       "Failed to fork() to call %s: %s",
03187                       progpath, _dbus_strerror (errno));
03188       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03189                      progpath, _dbus_strerror (errno));
03190       goto out;
03191     }
03192 
03193   if (pid == 0)
03194     {
03195       /* child process */
03196       int maxfds;
03197       int fd;
03198 
03199       fd = open ("/dev/null", O_RDWR);
03200       if (fd == -1)
03201         /* huh?! can't open /dev/null? */
03202         _exit (1);
03203 
03204       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03205 
03206       /* set-up stdXXX */
03207       close (result_pipe[READ_END]);
03208       close (errors_pipe[READ_END]);
03209       close (0);                /* close stdin */
03210       close (1);                /* close stdout */
03211       close (2);                /* close stderr */
03212 
03213       if (dup2 (fd, 0) == -1)
03214         _exit (1);
03215       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03216         _exit (1);
03217       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03218         _exit (1);
03219 
03220       maxfds = sysconf (_SC_OPEN_MAX);
03221       /* Pick something reasonable if for some reason sysconf
03222        * says unlimited.
03223        */
03224       if (maxfds < 0)
03225         maxfds = 1024;
03226       /* close all inherited fds */
03227       for (i = 3; i < maxfds; i++)
03228         close (i);
03229 
03230       sigprocmask (SIG_SETMASK, &old_set, NULL);
03231 
03232       /* If it looks fully-qualified, try execv first */
03233       if (progpath[0] == '/')
03234         {
03235           execv (progpath, argv);
03236           /* Ok, that failed.  Now if path_fallback is given, let's
03237            * try unqualified.  This is mostly a hack to work
03238            * around systems which ship dbus-launch in /usr/bin
03239            * but everything else in /bin (because dbus-launch
03240            * depends on X11).
03241            */
03242           if (path_fallback)
03243             /* We must have a slash, because we checked above */
03244             execvp (strrchr (progpath, '/')+1, argv);
03245         }
03246       else
03247         execvp (progpath, argv);
03248 
03249       /* still nothing, we failed */
03250       _exit (1);
03251     }
03252 
03253   /* parent process */
03254   close (result_pipe[WRITE_END]);
03255   close (errors_pipe[WRITE_END]);
03256   result_pipe[WRITE_END] = -1;
03257   errors_pipe[WRITE_END] = -1;
03258 
03259   ret = 0;
03260   do
03261     {
03262       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03263     }
03264   while (ret > 0);
03265 
03266   /* reap the child process to avoid it lingering as zombie */
03267   do
03268     {
03269       ret = waitpid (pid, &status, 0);
03270     }
03271   while (ret == -1 && errno == EINTR);
03272 
03273   /* We succeeded if the process exited with status 0 and
03274      anything was read */
03275   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03276     {
03277       /* The process ended with error */
03278       DBusString error_message;
03279       if (!_dbus_string_init (&error_message))
03280         {
03281           _DBUS_SET_OOM (error);
03282           goto out;
03283         }
03284 
03285       ret = 0;
03286       do
03287         {
03288           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03289         }
03290       while (ret > 0);
03291 
03292       _dbus_string_set_length (result, orig_len);
03293       if (_dbus_string_get_length (&error_message) > 0)
03294         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03295                         "%s terminated abnormally with the following error: %s",
03296                         progpath, _dbus_string_get_data (&error_message));
03297       else
03298         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03299                         "%s terminated abnormally without any error message",
03300                         progpath);
03301       goto out;
03302     }
03303 
03304   retval = TRUE;
03305 
03306  out:
03307   sigprocmask (SIG_SETMASK, &old_set, NULL);
03308 
03309   if (retval)
03310     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03311   else
03312     _DBUS_ASSERT_ERROR_IS_SET (error);
03313 
03314   if (result_pipe[0] != -1)
03315     close (result_pipe[0]);
03316   if (result_pipe[1] != -1)
03317     close (result_pipe[1]);
03318   if (errors_pipe[0] != -1)
03319     close (errors_pipe[0]);
03320   if (errors_pipe[1] != -1)
03321     close (errors_pipe[1]);
03322 
03323   return retval;
03324 }
03325 
03337 dbus_bool_t
03338 _dbus_get_autolaunch_address (const char *scope,
03339                               DBusString *address,
03340                               DBusError  *error)
03341 {
03342 #if 1
03343   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03344    * but that's done elsewhere, and if it worked, this function wouldn't
03345    * be called.) */
03346   const char *display;
03347   static char *argv[6];
03348   int i;
03349   DBusString uuid;
03350   dbus_bool_t retval;
03351 
03352   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03353   retval = FALSE;
03354 
03355   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03356    * dbus-launch-x11 is just going to fail. Rather than trying to
03357    * run it, we might as well bail out early with a nice error. */
03358   display = _dbus_getenv ("DISPLAY");
03359 
03360   if (display == NULL || display[0] == '\0')
03361     {
03362       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03363           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03364       return FALSE;
03365     }
03366 
03367   if (!_dbus_string_init (&uuid))
03368     {
03369       _DBUS_SET_OOM (error);
03370       return FALSE;
03371     }
03372 
03373   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03374     {
03375       _DBUS_SET_OOM (error);
03376       goto out;
03377     }
03378 
03379   i = 0;
03380   argv[i] = "dbus-launch";
03381   ++i;
03382   argv[i] = "--autolaunch";
03383   ++i;
03384   argv[i] = _dbus_string_get_data (&uuid);
03385   ++i;
03386   argv[i] = "--binary-syntax";
03387   ++i;
03388   argv[i] = "--close-stderr";
03389   ++i;
03390   argv[i] = NULL;
03391   ++i;
03392 
03393   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03394 
03395   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03396                                        TRUE,
03397                                        argv, address, error);
03398 
03399  out:
03400   _dbus_string_free (&uuid);
03401   return retval;
03402 #else
03403   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03404       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03405       "set your DBUS_SESSION_BUS_ADDRESS instead");
03406   return FALSE;
03407 #endif
03408 }
03409 
03428 dbus_bool_t
03429 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03430                                dbus_bool_t create_if_not_found,
03431                                DBusError  *error)
03432 {
03433   DBusString filename;
03434   dbus_bool_t b;
03435 
03436   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03437 
03438   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03439   if (b)
03440     return TRUE;
03441 
03442   dbus_error_free (error);
03443 
03444   /* Fallback to the system machine ID */
03445   _dbus_string_init_const (&filename, "/etc/machine-id");
03446   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03447 }
03448 
03449 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03450 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03451 
03458 dbus_bool_t
03459 _dbus_lookup_launchd_socket (DBusString *socket_path,
03460                              const char *launchd_env_var,
03461                              DBusError  *error)
03462 {
03463 #ifdef DBUS_ENABLE_LAUNCHD
03464   char *argv[4];
03465   int i;
03466 
03467   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03468 
03469   i = 0;
03470   argv[i] = "launchctl";
03471   ++i;
03472   argv[i] = "getenv";
03473   ++i;
03474   argv[i] = (char*)launchd_env_var;
03475   ++i;
03476   argv[i] = NULL;
03477   ++i;
03478 
03479   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03480 
03481   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03482     {
03483       return FALSE;
03484     }
03485 
03486   /* no error, but no result either */
03487   if (_dbus_string_get_length(socket_path) == 0)
03488     {
03489       return FALSE;
03490     }
03491 
03492   /* strip the carriage-return */
03493   _dbus_string_shorten(socket_path, 1);
03494   return TRUE;
03495 #else /* DBUS_ENABLE_LAUNCHD */
03496   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03497                 "can't lookup socket from launchd; launchd support not compiled in");
03498   return FALSE;
03499 #endif
03500 }
03501 
03502 #ifdef DBUS_ENABLE_LAUNCHD
03503 static dbus_bool_t
03504 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03505 {
03506   dbus_bool_t valid_socket;
03507   DBusString socket_path;
03508 
03509   if (!_dbus_string_init (&socket_path))
03510     {
03511       _DBUS_SET_OOM (error);
03512       return FALSE;
03513     }
03514 
03515   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03516 
03517   if (dbus_error_is_set(error))
03518     {
03519       _dbus_string_free(&socket_path);
03520       return FALSE;
03521     }
03522 
03523   if (!valid_socket)
03524     {
03525       dbus_set_error(error, "no socket path",
03526                 "launchd did not provide a socket path, "
03527                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03528       _dbus_string_free(&socket_path);
03529       return FALSE;
03530     }
03531   if (!_dbus_string_append (address, "unix:path="))
03532     {
03533       _DBUS_SET_OOM (error);
03534       _dbus_string_free(&socket_path);
03535       return FALSE;
03536     }
03537   if (!_dbus_string_copy (&socket_path, 0, address,
03538                           _dbus_string_get_length (address)))
03539     {
03540       _DBUS_SET_OOM (error);
03541       _dbus_string_free(&socket_path);
03542       return FALSE;
03543     }
03544 
03545   _dbus_string_free(&socket_path);
03546   return TRUE;
03547 }
03548 #endif
03549 
03569 dbus_bool_t
03570 _dbus_lookup_session_address (dbus_bool_t *supported,
03571                               DBusString  *address,
03572                               DBusError   *error)
03573 {
03574 #ifdef DBUS_ENABLE_LAUNCHD
03575   *supported = TRUE;
03576   return _dbus_lookup_session_address_launchd (address, error);
03577 #else
03578   /* On non-Mac Unix platforms, if the session address isn't already
03579    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03580    * fall back to the autolaunch: global default; see
03581    * init_session_address in dbus/dbus-bus.c. */
03582   *supported = FALSE;
03583   return TRUE;
03584 #endif
03585 }
03586 
03604 dbus_bool_t
03605 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03606 {
03607   const char *xdg_data_home;
03608   const char *xdg_data_dirs;
03609   DBusString servicedir_path;
03610 
03611   if (!_dbus_string_init (&servicedir_path))
03612     return FALSE;
03613 
03614   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03615   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03616 
03617   if (xdg_data_home != NULL)
03618     {
03619       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03620         goto oom;
03621     }
03622   else
03623     {
03624       const DBusString *homedir;
03625       DBusString local_share;
03626 
03627       if (!_dbus_homedir_from_current_process (&homedir))
03628         goto oom;
03629 
03630       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03631         goto oom;
03632 
03633       _dbus_string_init_const (&local_share, "/.local/share");
03634       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03635         goto oom;
03636     }
03637 
03638   if (!_dbus_string_append (&servicedir_path, ":"))
03639     goto oom;
03640 
03641   if (xdg_data_dirs != NULL)
03642     {
03643       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03644         goto oom;
03645 
03646       if (!_dbus_string_append (&servicedir_path, ":"))
03647         goto oom;
03648     }
03649   else
03650     {
03651       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03652         goto oom;
03653     }
03654 
03655   /*
03656    * add configured datadir to defaults
03657    * this may be the same as an xdg dir
03658    * however the config parser should take
03659    * care of duplicates
03660    */
03661   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03662     goto oom;
03663 
03664   if (!_dbus_split_paths_and_append (&servicedir_path,
03665                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03666                                      dirs))
03667     goto oom;
03668 
03669   _dbus_string_free (&servicedir_path);
03670   return TRUE;
03671 
03672  oom:
03673   _dbus_string_free (&servicedir_path);
03674   return FALSE;
03675 }
03676 
03677 
03696 dbus_bool_t
03697 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03698 {
03699   const char *xdg_data_dirs;
03700   DBusString servicedir_path;
03701 
03702   if (!_dbus_string_init (&servicedir_path))
03703     return FALSE;
03704 
03705   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03706 
03707   if (xdg_data_dirs != NULL)
03708     {
03709       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03710         goto oom;
03711 
03712       if (!_dbus_string_append (&servicedir_path, ":"))
03713         goto oom;
03714     }
03715   else
03716     {
03717       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03718         goto oom;
03719     }
03720 
03721   /*
03722    * Add configured datadir to defaults. This may be the same as one
03723    * of the XDG directories. However, the config parser should take
03724    * care of the duplicates.
03725    *
03726    * Also, append /lib as counterpart of /usr/share on the root
03727    * directory (the root directory does not know /share), in order to
03728    * facilitate early boot system bus activation where /usr might not
03729    * be available.
03730    */
03731   if (!_dbus_string_append (&servicedir_path,
03732                             DBUS_DATADIR":"
03733                             "/lib:"))
03734         goto oom;
03735 
03736   if (!_dbus_split_paths_and_append (&servicedir_path,
03737                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03738                                      dirs))
03739     goto oom;
03740 
03741   _dbus_string_free (&servicedir_path);
03742   return TRUE;
03743 
03744  oom:
03745   _dbus_string_free (&servicedir_path);
03746   return FALSE;
03747 }
03748 
03757 dbus_bool_t
03758 _dbus_append_system_config_file (DBusString *str)
03759 {
03760   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03761 }
03762 
03769 dbus_bool_t
03770 _dbus_append_session_config_file (DBusString *str)
03771 {
03772   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03773 }
03774 
03782 void
03783 _dbus_flush_caches (void)
03784 {
03785   _dbus_user_database_flush_system ();
03786 }
03787 
03801 dbus_bool_t
03802 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03803                                                 DBusCredentials *credentials)
03804 {
03805   DBusString homedir;
03806   DBusString dotdir;
03807   dbus_uid_t uid;
03808 
03809   _dbus_assert (credentials != NULL);
03810   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03811 
03812   if (!_dbus_string_init (&homedir))
03813     return FALSE;
03814 
03815   uid = _dbus_credentials_get_unix_uid (credentials);
03816   _dbus_assert (uid != DBUS_UID_UNSET);
03817 
03818   if (!_dbus_homedir_from_uid (uid, &homedir))
03819     goto failed;
03820 
03821 #ifdef DBUS_BUILD_TESTS
03822   {
03823     const char *override;
03824 
03825     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03826     if (override != NULL && *override != '\0')
03827       {
03828         _dbus_string_set_length (&homedir, 0);
03829         if (!_dbus_string_append (&homedir, override))
03830           goto failed;
03831 
03832         _dbus_verbose ("Using fake homedir for testing: %s\n",
03833                        _dbus_string_get_const_data (&homedir));
03834       }
03835     else
03836       {
03837         static dbus_bool_t already_warned = FALSE;
03838         if (!already_warned)
03839           {
03840             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03841             already_warned = TRUE;
03842           }
03843       }
03844   }
03845 #endif
03846 
03847   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03848   if (!_dbus_concat_dir_and_file (&homedir,
03849                                   &dotdir))
03850     goto failed;
03851 
03852   if (!_dbus_string_copy (&homedir, 0,
03853                           directory, _dbus_string_get_length (directory))) {
03854     goto failed;
03855   }
03856 
03857   _dbus_string_free (&homedir);
03858   return TRUE;
03859 
03860  failed:
03861   _dbus_string_free (&homedir);
03862   return FALSE;
03863 }
03864 
03865 //PENDING(kdab) docs
03866 dbus_bool_t
03867 _dbus_daemon_publish_session_bus_address (const char* addr,
03868                                           const char *scope)
03869 {
03870   return TRUE;
03871 }
03872 
03873 //PENDING(kdab) docs
03874 void
03875 _dbus_daemon_unpublish_session_bus_address (void)
03876 {
03877 
03878 }
03879 
03886 dbus_bool_t
03887 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03888 {
03889   return errno == EAGAIN || errno == EWOULDBLOCK;
03890 }
03891 
03899 dbus_bool_t
03900 _dbus_delete_directory (const DBusString *filename,
03901                         DBusError        *error)
03902 {
03903   const char *filename_c;
03904 
03905   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03906 
03907   filename_c = _dbus_string_get_const_data (filename);
03908 
03909   if (rmdir (filename_c) != 0)
03910     {
03911       dbus_set_error (error, DBUS_ERROR_FAILED,
03912                       "Failed to remove directory %s: %s\n",
03913                       filename_c, _dbus_strerror (errno));
03914       return FALSE;
03915     }
03916 
03917   return TRUE;
03918 }
03919 
03927 dbus_bool_t
03928 _dbus_socket_can_pass_unix_fd(int fd) {
03929 
03930 #ifdef SCM_RIGHTS
03931   union {
03932     struct sockaddr sa;
03933     struct sockaddr_storage storage;
03934     struct sockaddr_un un;
03935   } sa_buf;
03936 
03937   socklen_t sa_len = sizeof(sa_buf);
03938 
03939   _DBUS_ZERO(sa_buf);
03940 
03941   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03942     return FALSE;
03943 
03944   return sa_buf.sa.sa_family == AF_UNIX;
03945 
03946 #else
03947   return FALSE;
03948 
03949 #endif
03950 }
03951 
03952 
03953 /*
03954  * replaces the term DBUS_PREFIX in configure_time_path by the
03955  * current dbus installation directory. On unix this function is a noop
03956  *
03957  * @param configure_time_path
03958  * @return real path
03959  */
03960 const char *
03961 _dbus_replace_install_prefix (const char *configure_time_path)
03962 {
03963   return configure_time_path;
03964 }
03965 
03966 /* tests in dbus-sysdeps-util.c */