D-Bus  1.10.12
dbus-sysdeps-unix.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-file.h"
00033 #include "dbus-transport.h"
00034 #include "dbus-string.h"
00035 #include "dbus-userdb.h"
00036 #include "dbus-list.h"
00037 #include "dbus-credentials.h"
00038 #include "dbus-nonce.h"
00039 
00040 #include <sys/types.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <signal.h>
00044 #include <unistd.h>
00045 #include <stdio.h>
00046 #include <fcntl.h>
00047 #include <sys/socket.h>
00048 #include <dirent.h>
00049 #include <sys/un.h>
00050 #include <pwd.h>
00051 #include <time.h>
00052 #include <locale.h>
00053 #include <sys/time.h>
00054 #include <sys/stat.h>
00055 #include <sys/wait.h>
00056 #include <netinet/in.h>
00057 #include <netinet/tcp.h>
00058 #include <netdb.h>
00059 #include <grp.h>
00060 #include <arpa/inet.h>
00061 
00062 #ifdef HAVE_ERRNO_H
00063 #include <errno.h>
00064 #endif
00065 #ifdef HAVE_WRITEV
00066 #include <sys/uio.h>
00067 #endif
00068 #ifdef HAVE_POLL
00069 #include <sys/poll.h>
00070 #endif
00071 #ifdef HAVE_BACKTRACE
00072 #include <execinfo.h>
00073 #endif
00074 #ifdef HAVE_GETPEERUCRED
00075 #include <ucred.h>
00076 #endif
00077 #ifdef HAVE_ALLOCA_H
00078 #include <alloca.h>
00079 #endif
00080 
00081 #ifdef HAVE_ADT
00082 #include <bsm/adt.h>
00083 #endif
00084 
00085 #ifdef HAVE_SYSTEMD
00086 #include <systemd/sd-daemon.h>
00087 #endif
00088 
00089 #if !DBUS_USE_SYNC
00090 #include <pthread.h>
00091 #endif
00092 
00093 #ifndef O_BINARY
00094 #define O_BINARY 0
00095 #endif
00096 
00097 #ifndef AI_ADDRCONFIG
00098 #define AI_ADDRCONFIG 0
00099 #endif
00100 
00101 #ifndef HAVE_SOCKLEN_T
00102 #define socklen_t int
00103 #endif
00104 
00105 #if defined (__sun) || defined (__sun__)
00106 /*
00107  * CMS_SPACE etc. definitions for Solaris < 10, based on
00108  *   http://mailman.videolan.org/pipermail/vlc-devel/2006-May/024402.html
00109  * via
00110  *   http://wiki.opencsw.org/porting-faq#toc10
00111  *
00112  * These are only redefined for Solaris, for now: if your OS needs these too,
00113  * please file a bug. (Or preferably, improve your OS so they're not needed.)
00114  */
00115 
00116 # ifndef CMSG_ALIGN
00117 #   ifdef __sun__
00118 #     define CMSG_ALIGN(len) _CMSG_DATA_ALIGN (len)
00119 #   else
00120       /* aligning to sizeof (long) is assumed to be portable (fd.o#40235) */
00121 #     define CMSG_ALIGN(len) (((len) + sizeof (long) - 1) & \
00122                               ~(sizeof (long) - 1))
00123 #   endif
00124 # endif
00125 
00126 # ifndef CMSG_SPACE
00127 #   define CMSG_SPACE(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + \
00128                             CMSG_ALIGN (len))
00129 # endif
00130 
00131 # ifndef CMSG_LEN
00132 #   define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
00133 # endif
00134 
00135 #endif /* Solaris */
00136 
00151 dbus_bool_t
00152 _dbus_ensure_standard_fds (DBusEnsureStandardFdsFlags   flags,
00153                            const char                 **error_str_p)
00154 {
00155   static int const relevant_flag[] = { DBUS_FORCE_STDIN_NULL,
00156       DBUS_FORCE_STDOUT_NULL,
00157       DBUS_FORCE_STDERR_NULL };
00158   /* Should always get replaced with the real error before use */
00159   const char *error_str = "Failed mysteriously";
00160   int devnull = -1;
00161   int saved_errno;
00162   /* This function relies on the standard fds having their POSIX values. */
00163   _DBUS_STATIC_ASSERT (STDIN_FILENO == 0);
00164   _DBUS_STATIC_ASSERT (STDOUT_FILENO == 1);
00165   _DBUS_STATIC_ASSERT (STDERR_FILENO == 2);
00166   int i;
00167 
00168   for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
00169     {
00170       /* Because we rely on being single-threaded, and we want the
00171        * standard fds to not be close-on-exec, we don't set it
00172        * close-on-exec. */
00173       if (devnull < i)
00174         devnull = open ("/dev/null", O_RDWR);
00175 
00176       if (devnull < 0)
00177         {
00178           error_str = "Failed to open /dev/null";
00179           goto out;
00180         }
00181 
00182       /* We already opened all fds < i, so the only way this assertion
00183        * could fail is if another thread closed one, and we document
00184        * this function as not safe for multi-threading. */
00185       _dbus_assert (devnull >= i);
00186 
00187       if (devnull != i && (flags & relevant_flag[i]) != 0)
00188         {
00189           if (dup2 (devnull, i) < 0)
00190             {
00191               error_str = "Failed to dup2 /dev/null onto a standard fd";
00192               goto out;
00193             }
00194         }
00195     }
00196 
00197   error_str = NULL;
00198 
00199 out:
00200   saved_errno = errno;
00201 
00202   if (devnull > STDERR_FILENO)
00203     close (devnull);
00204 
00205   if (error_str_p != NULL)
00206     *error_str_p = error_str;
00207 
00208   errno = saved_errno;
00209   return (error_str == NULL);
00210 }
00211 
00212 static dbus_bool_t _dbus_set_fd_nonblocking (int             fd,
00213                                              DBusError      *error);
00214 
00215 static dbus_bool_t
00216 _dbus_open_socket (int              *fd_p,
00217                    int               domain,
00218                    int               type,
00219                    int               protocol,
00220                    DBusError        *error)
00221 {
00222 #ifdef SOCK_CLOEXEC
00223   dbus_bool_t cloexec_done;
00224 
00225   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00226   cloexec_done = *fd_p >= 0;
00227 
00228   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00229   if (*fd_p < 0 && (errno == EINVAL || errno == EPROTOTYPE))
00230 #endif
00231     {
00232       *fd_p = socket (domain, type, protocol);
00233     }
00234 
00235   if (*fd_p >= 0)
00236     {
00237 #ifdef SOCK_CLOEXEC
00238       if (!cloexec_done)
00239 #endif
00240         {
00241           _dbus_fd_set_close_on_exec(*fd_p);
00242         }
00243 
00244       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00245       return TRUE;
00246     }
00247   else
00248     {
00249       dbus_set_error(error,
00250                      _dbus_error_from_errno (errno),
00251                      "Failed to open socket: %s",
00252                      _dbus_strerror (errno));
00253       return FALSE;
00254     }
00255 }
00256 
00267 static dbus_bool_t
00268 _dbus_open_unix_socket (int              *fd,
00269                         DBusError        *error)
00270 {
00271   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00272 }
00273 
00282 dbus_bool_t
00283 _dbus_close_socket (DBusSocket        fd,
00284                     DBusError        *error)
00285 {
00286   return _dbus_close (fd.fd, error);
00287 }
00288 
00298 int
00299 _dbus_read_socket (DBusSocket        fd,
00300                    DBusString       *buffer,
00301                    int               count)
00302 {
00303   return _dbus_read (fd.fd, buffer, count);
00304 }
00305 
00316 int
00317 _dbus_write_socket (DBusSocket        fd,
00318                     const DBusString *buffer,
00319                     int               start,
00320                     int               len)
00321 {
00322 #if HAVE_DECL_MSG_NOSIGNAL
00323   const char *data;
00324   int bytes_written;
00325 
00326   data = _dbus_string_get_const_data_len (buffer, start, len);
00327 
00328  again:
00329 
00330   bytes_written = send (fd.fd, data, len, MSG_NOSIGNAL);
00331 
00332   if (bytes_written < 0 && errno == EINTR)
00333     goto again;
00334 
00335   return bytes_written;
00336 
00337 #else
00338   return _dbus_write (fd.fd, buffer, start, len);
00339 #endif
00340 }
00341 
00354 int
00355 _dbus_read_socket_with_unix_fds (DBusSocket        fd,
00356                                  DBusString       *buffer,
00357                                  int               count,
00358                                  int              *fds,
00359                                  int              *n_fds) {
00360 #ifndef HAVE_UNIX_FD_PASSING
00361   int r;
00362 
00363   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00364     return r;
00365 
00366   *n_fds = 0;
00367   return r;
00368 
00369 #else
00370   int bytes_read;
00371   int start;
00372   struct msghdr m;
00373   struct iovec iov;
00374 
00375   _dbus_assert (count >= 0);
00376   _dbus_assert (*n_fds >= 0);
00377 
00378   start = _dbus_string_get_length (buffer);
00379 
00380   if (!_dbus_string_lengthen (buffer, count))
00381     {
00382       errno = ENOMEM;
00383       return -1;
00384     }
00385 
00386   _DBUS_ZERO(iov);
00387   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00388   iov.iov_len = count;
00389 
00390   _DBUS_ZERO(m);
00391   m.msg_iov = &iov;
00392   m.msg_iovlen = 1;
00393 
00394   /* Hmm, we have no clue how long the control data will actually be
00395      that is queued for us. The least we can do is assume that the
00396      caller knows. Hence let's make space for the number of fds that
00397      we shall read at max plus the cmsg header. */
00398   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00399 
00400   /* It's probably safe to assume that systems with SCM_RIGHTS also
00401      know alloca() */
00402   m.msg_control = alloca(m.msg_controllen);
00403   memset(m.msg_control, 0, m.msg_controllen);
00404 
00405   /* Do not include the padding at the end when we tell the kernel
00406    * how much we're willing to receive. This avoids getting
00407    * the padding filled with additional fds that we weren't expecting,
00408    * if a (potentially malicious) sender included them. (fd.o #83622) */
00409   m.msg_controllen = CMSG_LEN (*n_fds * sizeof(int));
00410 
00411  again:
00412 
00413   bytes_read = recvmsg (fd.fd, &m, 0
00414 #ifdef MSG_CMSG_CLOEXEC
00415                        |MSG_CMSG_CLOEXEC
00416 #endif
00417                        );
00418 
00419   if (bytes_read < 0)
00420     {
00421       if (errno == EINTR)
00422         goto again;
00423       else
00424         {
00425           /* put length back (note that this doesn't actually realloc anything) */
00426           _dbus_string_set_length (buffer, start);
00427           return -1;
00428         }
00429     }
00430   else
00431     {
00432       struct cmsghdr *cm;
00433       dbus_bool_t found = FALSE;
00434 
00435       if (m.msg_flags & MSG_CTRUNC)
00436         {
00437           /* Hmm, apparently the control data was truncated. The bad
00438              thing is that we might have completely lost a couple of fds
00439              without chance to recover them. Hence let's treat this as a
00440              serious error. */
00441 
00442           errno = ENOSPC;
00443           _dbus_string_set_length (buffer, start);
00444           return -1;
00445         }
00446 
00447       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00448         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00449           {
00450             size_t i;
00451             int *payload = (int *) CMSG_DATA (cm);
00452             size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0));
00453             size_t payload_len_fds = payload_len_bytes / sizeof (int);
00454             size_t fds_to_use;
00455 
00456             /* Every non-negative int fits in a size_t without truncation,
00457              * and we already know that *n_fds is non-negative, so
00458              * casting (size_t) *n_fds is OK */
00459             _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int));
00460 
00461             if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds))
00462               {
00463                 /* The fds in the payload will fit in our buffer */
00464                 fds_to_use = payload_len_fds;
00465               }
00466             else
00467               {
00468                 /* Too many fds in the payload. This shouldn't happen
00469                  * any more because we're setting m.msg_controllen to
00470                  * the exact number we can accept, but be safe and
00471                  * truncate. */
00472                 fds_to_use = (size_t) *n_fds;
00473 
00474                 /* Close the excess fds to avoid DoS: if they stayed open,
00475                  * someone could send us an extra fd per message
00476                  * and we'd eventually run out. */
00477                 for (i = fds_to_use; i < payload_len_fds; i++)
00478                   {
00479                     close (payload[i]);
00480                   }
00481               }
00482 
00483             memcpy (fds, payload, fds_to_use * sizeof (int));
00484             found = TRUE;
00485             /* This cannot overflow because we have chosen fds_to_use
00486              * to be <= *n_fds */
00487             *n_fds = (int) fds_to_use;
00488 
00489             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00490                worked, hence we need to go through this list and set
00491                CLOEXEC everywhere in any case */
00492             for (i = 0; i < fds_to_use; i++)
00493               _dbus_fd_set_close_on_exec(fds[i]);
00494 
00495             break;
00496           }
00497 
00498       if (!found)
00499         *n_fds = 0;
00500 
00501       /* put length back (doesn't actually realloc) */
00502       _dbus_string_set_length (buffer, start + bytes_read);
00503 
00504 #if 0
00505       if (bytes_read > 0)
00506         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00507 #endif
00508 
00509       return bytes_read;
00510     }
00511 #endif
00512 }
00513 
00514 int
00515 _dbus_write_socket_with_unix_fds(DBusSocket        fd,
00516                                  const DBusString *buffer,
00517                                  int               start,
00518                                  int               len,
00519                                  const int        *fds,
00520                                  int               n_fds) {
00521 
00522 #ifndef HAVE_UNIX_FD_PASSING
00523 
00524   if (n_fds > 0) {
00525     errno = ENOTSUP;
00526     return -1;
00527   }
00528 
00529   return _dbus_write_socket(fd, buffer, start, len);
00530 #else
00531   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00532 #endif
00533 }
00534 
00535 int
00536 _dbus_write_socket_with_unix_fds_two(DBusSocket        fd,
00537                                      const DBusString *buffer1,
00538                                      int               start1,
00539                                      int               len1,
00540                                      const DBusString *buffer2,
00541                                      int               start2,
00542                                      int               len2,
00543                                      const int        *fds,
00544                                      int               n_fds) {
00545 
00546 #ifndef HAVE_UNIX_FD_PASSING
00547 
00548   if (n_fds > 0) {
00549     errno = ENOTSUP;
00550     return -1;
00551   }
00552 
00553   return _dbus_write_socket_two(fd,
00554                                 buffer1, start1, len1,
00555                                 buffer2, start2, len2);
00556 #else
00557 
00558   struct msghdr m;
00559   struct cmsghdr *cm;
00560   struct iovec iov[2];
00561   int bytes_written;
00562 
00563   _dbus_assert (len1 >= 0);
00564   _dbus_assert (len2 >= 0);
00565   _dbus_assert (n_fds >= 0);
00566 
00567   _DBUS_ZERO(iov);
00568   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00569   iov[0].iov_len = len1;
00570 
00571   if (buffer2)
00572     {
00573       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00574       iov[1].iov_len = len2;
00575     }
00576 
00577   _DBUS_ZERO(m);
00578   m.msg_iov = iov;
00579   m.msg_iovlen = buffer2 ? 2 : 1;
00580 
00581   if (n_fds > 0)
00582     {
00583       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00584       m.msg_control = alloca(m.msg_controllen);
00585       memset(m.msg_control, 0, m.msg_controllen);
00586 
00587       cm = CMSG_FIRSTHDR(&m);
00588       cm->cmsg_level = SOL_SOCKET;
00589       cm->cmsg_type = SCM_RIGHTS;
00590       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00591       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00592     }
00593 
00594  again:
00595 
00596   bytes_written = sendmsg (fd.fd, &m, 0
00597 #if HAVE_DECL_MSG_NOSIGNAL
00598                            |MSG_NOSIGNAL
00599 #endif
00600                            );
00601 
00602   if (bytes_written < 0 && errno == EINTR)
00603     goto again;
00604 
00605 #if 0
00606   if (bytes_written > 0)
00607     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00608 #endif
00609 
00610   return bytes_written;
00611 #endif
00612 }
00613 
00627 int
00628 _dbus_write_socket_two (DBusSocket        fd,
00629                         const DBusString *buffer1,
00630                         int               start1,
00631                         int               len1,
00632                         const DBusString *buffer2,
00633                         int               start2,
00634                         int               len2)
00635 {
00636 #if HAVE_DECL_MSG_NOSIGNAL
00637   struct iovec vectors[2];
00638   const char *data1;
00639   const char *data2;
00640   int bytes_written;
00641   struct msghdr m;
00642 
00643   _dbus_assert (buffer1 != NULL);
00644   _dbus_assert (start1 >= 0);
00645   _dbus_assert (start2 >= 0);
00646   _dbus_assert (len1 >= 0);
00647   _dbus_assert (len2 >= 0);
00648 
00649   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00650 
00651   if (buffer2 != NULL)
00652     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00653   else
00654     {
00655       data2 = NULL;
00656       start2 = 0;
00657       len2 = 0;
00658     }
00659 
00660   vectors[0].iov_base = (char*) data1;
00661   vectors[0].iov_len = len1;
00662   vectors[1].iov_base = (char*) data2;
00663   vectors[1].iov_len = len2;
00664 
00665   _DBUS_ZERO(m);
00666   m.msg_iov = vectors;
00667   m.msg_iovlen = data2 ? 2 : 1;
00668 
00669  again:
00670 
00671   bytes_written = sendmsg (fd.fd, &m, MSG_NOSIGNAL);
00672 
00673   if (bytes_written < 0 && errno == EINTR)
00674     goto again;
00675 
00676   return bytes_written;
00677 
00678 #else
00679   return _dbus_write_two (fd.fd, buffer1, start1, len1,
00680                           buffer2, start2, len2);
00681 #endif
00682 }
00683 
00700 int
00701 _dbus_read (int               fd,
00702             DBusString       *buffer,
00703             int               count)
00704 {
00705   int bytes_read;
00706   int start;
00707   char *data;
00708 
00709   _dbus_assert (count >= 0);
00710 
00711   start = _dbus_string_get_length (buffer);
00712 
00713   if (!_dbus_string_lengthen (buffer, count))
00714     {
00715       errno = ENOMEM;
00716       return -1;
00717     }
00718 
00719   data = _dbus_string_get_data_len (buffer, start, count);
00720 
00721  again:
00722 
00723   bytes_read = read (fd, data, count);
00724 
00725   if (bytes_read < 0)
00726     {
00727       if (errno == EINTR)
00728         goto again;
00729       else
00730         {
00731           /* put length back (note that this doesn't actually realloc anything) */
00732           _dbus_string_set_length (buffer, start);
00733           return -1;
00734         }
00735     }
00736   else
00737     {
00738       /* put length back (doesn't actually realloc) */
00739       _dbus_string_set_length (buffer, start + bytes_read);
00740 
00741 #if 0
00742       if (bytes_read > 0)
00743         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00744 #endif
00745 
00746       return bytes_read;
00747     }
00748 }
00749 
00760 int
00761 _dbus_write (int               fd,
00762              const DBusString *buffer,
00763              int               start,
00764              int               len)
00765 {
00766   const char *data;
00767   int bytes_written;
00768 
00769   data = _dbus_string_get_const_data_len (buffer, start, len);
00770 
00771  again:
00772 
00773   bytes_written = write (fd, data, len);
00774 
00775   if (bytes_written < 0 && errno == EINTR)
00776     goto again;
00777 
00778 #if 0
00779   if (bytes_written > 0)
00780     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00781 #endif
00782 
00783   return bytes_written;
00784 }
00785 
00806 int
00807 _dbus_write_two (int               fd,
00808                  const DBusString *buffer1,
00809                  int               start1,
00810                  int               len1,
00811                  const DBusString *buffer2,
00812                  int               start2,
00813                  int               len2)
00814 {
00815   _dbus_assert (buffer1 != NULL);
00816   _dbus_assert (start1 >= 0);
00817   _dbus_assert (start2 >= 0);
00818   _dbus_assert (len1 >= 0);
00819   _dbus_assert (len2 >= 0);
00820 
00821 #ifdef HAVE_WRITEV
00822   {
00823     struct iovec vectors[2];
00824     const char *data1;
00825     const char *data2;
00826     int bytes_written;
00827 
00828     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00829 
00830     if (buffer2 != NULL)
00831       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00832     else
00833       {
00834         data2 = NULL;
00835         start2 = 0;
00836         len2 = 0;
00837       }
00838 
00839     vectors[0].iov_base = (char*) data1;
00840     vectors[0].iov_len = len1;
00841     vectors[1].iov_base = (char*) data2;
00842     vectors[1].iov_len = len2;
00843 
00844   again:
00845 
00846     bytes_written = writev (fd,
00847                             vectors,
00848                             data2 ? 2 : 1);
00849 
00850     if (bytes_written < 0 && errno == EINTR)
00851       goto again;
00852 
00853     return bytes_written;
00854   }
00855 #else /* HAVE_WRITEV */
00856   {
00857     int ret1, ret2;
00858 
00859     ret1 = _dbus_write (fd, buffer1, start1, len1);
00860     if (ret1 == len1 && buffer2 != NULL)
00861       {
00862         ret2 = _dbus_write (fd, buffer2, start2, len2);
00863         if (ret2 < 0)
00864           ret2 = 0; /* we can't report an error as the first write was OK */
00865 
00866         return ret1 + ret2;
00867       }
00868     else
00869       return ret1;
00870   }
00871 #endif /* !HAVE_WRITEV */
00872 }
00873 
00874 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00875 
00905 int
00906 _dbus_connect_unix_socket (const char     *path,
00907                            dbus_bool_t     abstract,
00908                            DBusError      *error)
00909 {
00910   int fd;
00911   size_t path_len;
00912   struct sockaddr_un addr;
00913 
00914   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00915 
00916   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00917                  path, abstract);
00918 
00919 
00920   if (!_dbus_open_unix_socket (&fd, error))
00921     {
00922       _DBUS_ASSERT_ERROR_IS_SET(error);
00923       return -1;
00924     }
00925   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00926 
00927   _DBUS_ZERO (addr);
00928   addr.sun_family = AF_UNIX;
00929   path_len = strlen (path);
00930 
00931   if (abstract)
00932     {
00933 #ifdef HAVE_ABSTRACT_SOCKETS
00934       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00935       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00936 
00937       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00938         {
00939           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00940                       "Abstract socket name too long\n");
00941           _dbus_close (fd, NULL);
00942           return -1;
00943         }
00944 
00945       strncpy (&addr.sun_path[1], path, path_len);
00946       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00947 #else /* HAVE_ABSTRACT_SOCKETS */
00948       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00949                       "Operating system does not support abstract socket namespace\n");
00950       _dbus_close (fd, NULL);
00951       return -1;
00952 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00953     }
00954   else
00955     {
00956       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00957         {
00958           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00959                       "Socket name too long\n");
00960           _dbus_close (fd, NULL);
00961           return -1;
00962         }
00963 
00964       strncpy (addr.sun_path, path, path_len);
00965     }
00966 
00967   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00968     {
00969       dbus_set_error (error,
00970                       _dbus_error_from_errno (errno),
00971                       "Failed to connect to socket %s: %s",
00972                       path, _dbus_strerror (errno));
00973 
00974       _dbus_close (fd, NULL);
00975       return -1;
00976     }
00977 
00978   if (!_dbus_set_fd_nonblocking (fd, error))
00979     {
00980       _DBUS_ASSERT_ERROR_IS_SET (error);
00981 
00982       _dbus_close (fd, NULL);
00983       return -1;
00984     }
00985 
00986   return fd;
00987 }
00988 
01001 int
01002 _dbus_connect_exec (const char     *path,
01003                     char *const    argv[],
01004                     DBusError      *error)
01005 {
01006   int fds[2];
01007   pid_t pid;
01008   int retval;
01009   dbus_bool_t cloexec_done = 0;
01010 
01011   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01012 
01013   _dbus_verbose ("connecting to process %s\n", path);
01014 
01015 #ifdef SOCK_CLOEXEC
01016   retval = socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
01017   cloexec_done = (retval >= 0);
01018 
01019   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
01020 #endif
01021     {
01022       retval = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
01023     }
01024 
01025   if (retval < 0)
01026     {
01027       dbus_set_error (error,
01028                       _dbus_error_from_errno (errno),
01029                       "Failed to create socket pair: %s",
01030                       _dbus_strerror (errno));
01031       return -1;
01032     }
01033 
01034   if (!cloexec_done)
01035     {
01036       _dbus_fd_set_close_on_exec (fds[0]);
01037       _dbus_fd_set_close_on_exec (fds[1]);
01038     }
01039 
01040   pid = fork ();
01041   if (pid < 0)
01042     {
01043       dbus_set_error (error,
01044                       _dbus_error_from_errno (errno),
01045                       "Failed to fork() to call %s: %s",
01046                       path, _dbus_strerror (errno));
01047       close (fds[0]);
01048       close (fds[1]);
01049       return -1;
01050     }
01051 
01052   if (pid == 0)
01053     {
01054       /* child */
01055       close (fds[0]);
01056 
01057       dup2 (fds[1], STDIN_FILENO);
01058       dup2 (fds[1], STDOUT_FILENO);
01059 
01060       if (fds[1] != STDIN_FILENO &&
01061           fds[1] != STDOUT_FILENO)
01062         close (fds[1]);
01063 
01064       /* Inherit STDERR and the controlling terminal from the
01065          parent */
01066 
01067       _dbus_close_all ();
01068 
01069       execvp (path, argv);
01070 
01071       fprintf (stderr, "Failed to execute process %s: %s\n", path, _dbus_strerror (errno));
01072 
01073       _exit(1);
01074     }
01075 
01076   /* parent */
01077   close (fds[1]);
01078 
01079   if (!_dbus_set_fd_nonblocking (fds[0], error))
01080     {
01081       _DBUS_ASSERT_ERROR_IS_SET (error);
01082 
01083       close (fds[0]);
01084       return -1;
01085     }
01086 
01087   return fds[0];
01088 }
01089 
01107 int
01108 _dbus_listen_unix_socket (const char     *path,
01109                           dbus_bool_t     abstract,
01110                           DBusError      *error)
01111 {
01112   int listen_fd;
01113   struct sockaddr_un addr;
01114   size_t path_len;
01115 
01116   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01117 
01118   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
01119                  path, abstract);
01120 
01121   if (!_dbus_open_unix_socket (&listen_fd, error))
01122     {
01123       _DBUS_ASSERT_ERROR_IS_SET(error);
01124       return -1;
01125     }
01126   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01127 
01128   _DBUS_ZERO (addr);
01129   addr.sun_family = AF_UNIX;
01130   path_len = strlen (path);
01131 
01132   if (abstract)
01133     {
01134 #ifdef HAVE_ABSTRACT_SOCKETS
01135       /* remember that abstract names aren't nul-terminated so we rely
01136        * on sun_path being filled in with zeroes above.
01137        */
01138       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
01139       path_len++; /* Account for the extra nul byte added to the start of sun_path */
01140 
01141       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01142         {
01143           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01144                       "Abstract socket name too long\n");
01145           _dbus_close (listen_fd, NULL);
01146           return -1;
01147         }
01148 
01149       strncpy (&addr.sun_path[1], path, path_len);
01150       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
01151 #else /* HAVE_ABSTRACT_SOCKETS */
01152       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
01153                       "Operating system does not support abstract socket namespace\n");
01154       _dbus_close (listen_fd, NULL);
01155       return -1;
01156 #endif /* ! HAVE_ABSTRACT_SOCKETS */
01157     }
01158   else
01159     {
01160       /* Discussed security implications of this with Nalin,
01161        * and we couldn't think of where it would kick our ass, but
01162        * it still seems a bit sucky. It also has non-security suckage;
01163        * really we'd prefer to exit if the socket is already in use.
01164        * But there doesn't seem to be a good way to do this.
01165        *
01166        * Just to be extra careful, I threw in the stat() - clearly
01167        * the stat() can't *fix* any security issue, but it at least
01168        * avoids inadvertent/accidental data loss.
01169        */
01170       {
01171         struct stat sb;
01172 
01173         if (stat (path, &sb) == 0 &&
01174             S_ISSOCK (sb.st_mode))
01175           unlink (path);
01176       }
01177 
01178       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
01179         {
01180           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01181                       "Socket name too long\n");
01182           _dbus_close (listen_fd, NULL);
01183           return -1;
01184         }
01185 
01186       strncpy (addr.sun_path, path, path_len);
01187     }
01188 
01189   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
01190     {
01191       dbus_set_error (error, _dbus_error_from_errno (errno),
01192                       "Failed to bind socket \"%s\": %s",
01193                       path, _dbus_strerror (errno));
01194       _dbus_close (listen_fd, NULL);
01195       return -1;
01196     }
01197 
01198   if (listen (listen_fd, 30 /* backlog */) < 0)
01199     {
01200       dbus_set_error (error, _dbus_error_from_errno (errno),
01201                       "Failed to listen on socket \"%s\": %s",
01202                       path, _dbus_strerror (errno));
01203       _dbus_close (listen_fd, NULL);
01204       return -1;
01205     }
01206 
01207   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01208     {
01209       _DBUS_ASSERT_ERROR_IS_SET (error);
01210       _dbus_close (listen_fd, NULL);
01211       return -1;
01212     }
01213 
01214   /* Try opening up the permissions, but if we can't, just go ahead
01215    * and continue, maybe it will be good enough.
01216    */
01217   if (!abstract && chmod (path, 0777) < 0)
01218     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01219                 path);
01220 
01221   return listen_fd;
01222 }
01223 
01234 int
01235 _dbus_listen_systemd_sockets (DBusSocket **fds,
01236                               DBusError   *error)
01237 {
01238 #ifdef HAVE_SYSTEMD
01239   int r, n;
01240   int fd;
01241   DBusSocket *new_fds;
01242 
01243   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01244 
01245   n = sd_listen_fds (TRUE);
01246   if (n < 0)
01247     {
01248       dbus_set_error (error, _dbus_error_from_errno (-n),
01249                       "Failed to acquire systemd socket: %s",
01250                       _dbus_strerror (-n));
01251       return -1;
01252     }
01253 
01254   if (n <= 0)
01255     {
01256       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01257                       "No socket received.");
01258       return -1;
01259     }
01260 
01261   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01262     {
01263       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01264       if (r < 0)
01265         {
01266           dbus_set_error (error, _dbus_error_from_errno (-r),
01267                           "Failed to verify systemd socket type: %s",
01268                           _dbus_strerror (-r));
01269           return -1;
01270         }
01271 
01272       if (!r)
01273         {
01274           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01275                           "Passed socket has wrong type.");
01276           return -1;
01277         }
01278     }
01279 
01280   /* OK, the file descriptors are all good, so let's take posession of
01281      them then. */
01282 
01283   new_fds = dbus_new (DBusSocket, n);
01284   if (!new_fds)
01285     {
01286       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01287                       "Failed to allocate file handle array.");
01288       goto fail;
01289     }
01290 
01291   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01292     {
01293       if (!_dbus_set_fd_nonblocking (fd, error))
01294         {
01295           _DBUS_ASSERT_ERROR_IS_SET (error);
01296           goto fail;
01297         }
01298 
01299       new_fds[fd - SD_LISTEN_FDS_START].fd = fd;
01300     }
01301 
01302   *fds = new_fds;
01303   return n;
01304 
01305  fail:
01306 
01307   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01308     {
01309       _dbus_close (fd, NULL);
01310     }
01311 
01312   dbus_free (new_fds);
01313   return -1;
01314 #else
01315   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
01316                         "dbus was compiled without systemd support");
01317   return -1;
01318 #endif
01319 }
01320 
01334 DBusSocket
01335 _dbus_connect_tcp_socket (const char     *host,
01336                           const char     *port,
01337                           const char     *family,
01338                           DBusError      *error)
01339 {
01340     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01341 }
01342 
01343 DBusSocket
01344 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01345                                      const char     *port,
01346                                      const char     *family,
01347                                      const char     *noncefile,
01348                                      DBusError      *error)
01349 {
01350   int saved_errno = 0;
01351   DBusSocket fd = DBUS_SOCKET_INIT;
01352   int res;
01353   struct addrinfo hints;
01354   struct addrinfo *ai, *tmp;
01355 
01356   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01357 
01358   _DBUS_ZERO (hints);
01359 
01360   if (!family)
01361     hints.ai_family = AF_UNSPEC;
01362   else if (!strcmp(family, "ipv4"))
01363     hints.ai_family = AF_INET;
01364   else if (!strcmp(family, "ipv6"))
01365     hints.ai_family = AF_INET6;
01366   else
01367     {
01368       dbus_set_error (error,
01369                       DBUS_ERROR_BAD_ADDRESS,
01370                       "Unknown address family %s", family);
01371       return _dbus_socket_get_invalid ();
01372     }
01373   hints.ai_protocol = IPPROTO_TCP;
01374   hints.ai_socktype = SOCK_STREAM;
01375   hints.ai_flags = AI_ADDRCONFIG;
01376 
01377   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01378     {
01379       dbus_set_error (error,
01380                       _dbus_error_from_errno (errno),
01381                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01382                       host, port, gai_strerror(res), res);
01383       return _dbus_socket_get_invalid ();
01384     }
01385 
01386   tmp = ai;
01387   while (tmp)
01388     {
01389       if (!_dbus_open_socket (&fd.fd, tmp->ai_family, SOCK_STREAM, 0, error))
01390         {
01391           freeaddrinfo(ai);
01392           _DBUS_ASSERT_ERROR_IS_SET(error);
01393           return _dbus_socket_get_invalid ();
01394         }
01395       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01396 
01397       if (connect (fd.fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01398         {
01399           saved_errno = errno;
01400           _dbus_close (fd.fd, NULL);
01401           fd.fd = -1;
01402           tmp = tmp->ai_next;
01403           continue;
01404         }
01405 
01406       break;
01407     }
01408   freeaddrinfo(ai);
01409 
01410   if (fd.fd == -1)
01411     {
01412       dbus_set_error (error,
01413                       _dbus_error_from_errno (saved_errno),
01414                       "Failed to connect to socket \"%s:%s\" %s",
01415                       host, port, _dbus_strerror(saved_errno));
01416       return _dbus_socket_get_invalid ();
01417     }
01418 
01419   if (noncefile != NULL)
01420     {
01421       DBusString noncefileStr;
01422       dbus_bool_t ret;
01423       _dbus_string_init_const (&noncefileStr, noncefile);
01424       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01425       _dbus_string_free (&noncefileStr);
01426 
01427       if (!ret)
01428         {
01429           _dbus_close (fd.fd, NULL);
01430           return _dbus_socket_get_invalid ();
01431         }
01432     }
01433 
01434   if (!_dbus_set_fd_nonblocking (fd.fd, error))
01435     {
01436       _dbus_close (fd.fd, NULL);
01437       return _dbus_socket_get_invalid ();
01438     }
01439 
01440   return fd;
01441 }
01442 
01459 int
01460 _dbus_listen_tcp_socket (const char     *host,
01461                          const char     *port,
01462                          const char     *family,
01463                          DBusString     *retport,
01464                          DBusSocket    **fds_p,
01465                          DBusError      *error)
01466 {
01467   int saved_errno;
01468   int nlisten_fd = 0, res, i;
01469   DBusSocket *listen_fd = NULL;
01470   struct addrinfo hints;
01471   struct addrinfo *ai, *tmp;
01472   unsigned int reuseaddr;
01473 
01474   *fds_p = NULL;
01475   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01476 
01477   _DBUS_ZERO (hints);
01478 
01479   if (!family)
01480     hints.ai_family = AF_UNSPEC;
01481   else if (!strcmp(family, "ipv4"))
01482     hints.ai_family = AF_INET;
01483   else if (!strcmp(family, "ipv6"))
01484     hints.ai_family = AF_INET6;
01485   else
01486     {
01487       dbus_set_error (error,
01488                       DBUS_ERROR_BAD_ADDRESS,
01489                       "Unknown address family %s", family);
01490       return -1;
01491     }
01492 
01493   hints.ai_protocol = IPPROTO_TCP;
01494   hints.ai_socktype = SOCK_STREAM;
01495   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01496 
01497  redo_lookup_with_port:
01498   ai = NULL;
01499   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01500     {
01501       dbus_set_error (error,
01502                       _dbus_error_from_errno (errno),
01503                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01504                       host ? host : "*", port, gai_strerror(res), res);
01505       goto failed;
01506     }
01507 
01508   tmp = ai;
01509   while (tmp)
01510     {
01511       int fd = -1, tcp_nodelay_on;
01512       DBusSocket *newlisten_fd;
01513 
01514       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01515         {
01516           _DBUS_ASSERT_ERROR_IS_SET(error);
01517           goto failed;
01518         }
01519       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01520 
01521       reuseaddr = 1;
01522       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01523         {
01524           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01525                       host ? host : "*", port, _dbus_strerror (errno));
01526         }
01527 
01528       /* Nagle's algorithm imposes a huge delay on the initial messages
01529          going over TCP. */
01530       tcp_nodelay_on = 1;
01531       if (setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay_on, sizeof (tcp_nodelay_on)) == -1)
01532         {
01533           _dbus_warn ("Failed to set TCP_NODELAY socket option \"%s:%s\": %s",
01534                       host ? host : "*", port, _dbus_strerror (errno));
01535         }
01536 
01537       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01538         {
01539           saved_errno = errno;
01540           _dbus_close(fd, NULL);
01541           if (saved_errno == EADDRINUSE)
01542             {
01543               /* Depending on kernel policy, binding to an IPv6 address
01544                  might implicitly bind to a corresponding IPv4
01545                  address or vice versa, resulting in EADDRINUSE for the
01546                  other one (e.g. bindv6only=0 on Linux).
01547 
01548                  Also, after we "goto redo_lookup_with_port" after binding
01549                  a port on one of the possible addresses, we will
01550                  try to bind that same port on every address, including the
01551                  same address again for a second time; that one will
01552                  also fail with EADDRINUSE.
01553 
01554                  For both those reasons, ignore EADDRINUSE here */
01555               tmp = tmp->ai_next;
01556               continue;
01557             }
01558           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01559                           "Failed to bind socket \"%s:%s\": %s",
01560                           host ? host : "*", port, _dbus_strerror (saved_errno));
01561           goto failed;
01562         }
01563 
01564       if (listen (fd, 30 /* backlog */) < 0)
01565         {
01566           saved_errno = errno;
01567           _dbus_close (fd, NULL);
01568           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01569                           "Failed to listen on socket \"%s:%s\": %s",
01570                           host ? host : "*", port, _dbus_strerror (saved_errno));
01571           goto failed;
01572         }
01573 
01574       newlisten_fd = dbus_realloc(listen_fd, sizeof(DBusSocket)*(nlisten_fd+1));
01575       if (!newlisten_fd)
01576         {
01577           saved_errno = errno;
01578           _dbus_close (fd, NULL);
01579           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01580                           "Failed to allocate file handle array: %s",
01581                           _dbus_strerror (saved_errno));
01582           goto failed;
01583         }
01584       listen_fd = newlisten_fd;
01585       listen_fd[nlisten_fd].fd = fd;
01586       nlisten_fd++;
01587 
01588       if (!_dbus_string_get_length(retport))
01589         {
01590           /* If the user didn't specify a port, or used 0, then
01591              the kernel chooses a port. After the first address
01592              is bound to, we need to force all remaining addresses
01593              to use the same port */
01594           if (!port || !strcmp(port, "0"))
01595             {
01596               int result;
01597               struct sockaddr_storage addr;
01598               socklen_t addrlen;
01599               char portbuf[50];
01600 
01601               addrlen = sizeof(addr);
01602               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01603 
01604               if (result == -1 ||
01605                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01606                                       portbuf, sizeof(portbuf),
01607                                       NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
01608                 {
01609                   dbus_set_error (error, _dbus_error_from_errno (errno),
01610                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01611                                   host ? host : "*", port, gai_strerror(res), res);
01612                   goto failed;
01613                 }
01614               if (!_dbus_string_append(retport, portbuf))
01615                 {
01616                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01617                   goto failed;
01618                 }
01619 
01620               /* Release current address list & redo lookup */
01621               port = _dbus_string_get_const_data(retport);
01622               freeaddrinfo(ai);
01623               goto redo_lookup_with_port;
01624             }
01625           else
01626             {
01627               if (!_dbus_string_append(retport, port))
01628                 {
01629                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01630                     goto failed;
01631                 }
01632             }
01633         }
01634 
01635       tmp = tmp->ai_next;
01636     }
01637   freeaddrinfo(ai);
01638   ai = NULL;
01639 
01640   if (!nlisten_fd)
01641     {
01642       errno = EADDRINUSE;
01643       dbus_set_error (error, _dbus_error_from_errno (errno),
01644                       "Failed to bind socket \"%s:%s\": %s",
01645                       host ? host : "*", port, _dbus_strerror (errno));
01646       goto failed;
01647     }
01648 
01649   for (i = 0 ; i < nlisten_fd ; i++)
01650     {
01651       if (!_dbus_set_fd_nonblocking (listen_fd[i].fd, error))
01652         {
01653           goto failed;
01654         }
01655     }
01656 
01657   *fds_p = listen_fd;
01658 
01659   return nlisten_fd;
01660 
01661  failed:
01662   if (ai)
01663     freeaddrinfo(ai);
01664   for (i = 0 ; i < nlisten_fd ; i++)
01665     _dbus_close(listen_fd[i].fd, NULL);
01666   dbus_free(listen_fd);
01667   return -1;
01668 }
01669 
01670 static dbus_bool_t
01671 write_credentials_byte (int             server_fd,
01672                         DBusError      *error)
01673 {
01674   int bytes_written;
01675   char buf[1] = { '\0' };
01676 #if defined(HAVE_CMSGCRED)
01677   union {
01678           struct cmsghdr hdr;
01679           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01680   } cmsg;
01681   struct iovec iov;
01682   struct msghdr msg;
01683   iov.iov_base = buf;
01684   iov.iov_len = 1;
01685 
01686   _DBUS_ZERO(msg);
01687   msg.msg_iov = &iov;
01688   msg.msg_iovlen = 1;
01689 
01690   msg.msg_control = (caddr_t) &cmsg;
01691   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01692   _DBUS_ZERO(cmsg);
01693   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01694   cmsg.hdr.cmsg_level = SOL_SOCKET;
01695   cmsg.hdr.cmsg_type = SCM_CREDS;
01696 #endif
01697 
01698   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01699 
01700  again:
01701 
01702 #if defined(HAVE_CMSGCRED)
01703   bytes_written = sendmsg (server_fd, &msg, 0
01704 #if HAVE_DECL_MSG_NOSIGNAL
01705                            |MSG_NOSIGNAL
01706 #endif
01707                            );
01708 
01709   /* If we HAVE_CMSGCRED, the OS still might not let us sendmsg()
01710    * with a SOL_SOCKET/SCM_CREDS message - for instance, FreeBSD
01711    * only allows that on AF_UNIX. Try just doing a send() instead. */
01712   if (bytes_written < 0 && errno == EINVAL)
01713 #endif
01714     {
01715       bytes_written = send (server_fd, buf, 1, 0
01716 #if HAVE_DECL_MSG_NOSIGNAL
01717                             |MSG_NOSIGNAL
01718 #endif
01719                             );
01720     }
01721 
01722   if (bytes_written < 0 && errno == EINTR)
01723     goto again;
01724 
01725   if (bytes_written < 0)
01726     {
01727       dbus_set_error (error, _dbus_error_from_errno (errno),
01728                       "Failed to write credentials byte: %s",
01729                      _dbus_strerror (errno));
01730       return FALSE;
01731     }
01732   else if (bytes_written == 0)
01733     {
01734       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01735                       "wrote zero bytes writing credentials byte");
01736       return FALSE;
01737     }
01738   else
01739     {
01740       _dbus_assert (bytes_written == 1);
01741       _dbus_verbose ("wrote credentials byte\n");
01742       return TRUE;
01743     }
01744 }
01745 
01746 /* return FALSE on OOM, TRUE otherwise, even if no credentials were found */
01747 static dbus_bool_t
01748 add_linux_security_label_to_credentials (int              client_fd,
01749                                          DBusCredentials *credentials)
01750 {
01751 #if defined(__linux__) && defined(SO_PEERSEC)
01752   DBusString buf;
01753   socklen_t len = 1024;
01754   dbus_bool_t oom = FALSE;
01755 
01756   if (!_dbus_string_init_preallocated (&buf, len) ||
01757       !_dbus_string_set_length (&buf, len))
01758     return FALSE;
01759 
01760   while (getsockopt (client_fd, SOL_SOCKET, SO_PEERSEC,
01761          _dbus_string_get_data (&buf), &len) < 0)
01762     {
01763       int e = errno;
01764 
01765       _dbus_verbose ("getsockopt failed with %s, len now %lu\n",
01766                      _dbus_strerror (e), (unsigned long) len);
01767 
01768       if (e != ERANGE || len <= _dbus_string_get_length_uint (&buf))
01769         {
01770           _dbus_verbose ("Failed to getsockopt(SO_PEERSEC): %s\n",
01771                          _dbus_strerror (e));
01772           goto out;
01773         }
01774 
01775       /* If not enough space, len is updated to be enough.
01776        * Try again with a large enough buffer. */
01777       if (!_dbus_string_set_length (&buf, len))
01778         {
01779           oom = TRUE;
01780           goto out;
01781         }
01782 
01783       _dbus_verbose ("will try again with %lu\n", (unsigned long) len);
01784     }
01785 
01786   if (len <= 0)
01787     {
01788       _dbus_verbose ("getsockopt(SO_PEERSEC) yielded <= 0 bytes: %lu\n",
01789                      (unsigned long) len);
01790       goto out;
01791     }
01792 
01793   if (len > _dbus_string_get_length_uint (&buf))
01794     {
01795       _dbus_verbose ("%lu > %u", (unsigned long) len,
01796                      _dbus_string_get_length_uint (&buf));
01797       _dbus_assert_not_reached ("getsockopt(SO_PEERSEC) overflowed");
01798     }
01799 
01800   if (_dbus_string_get_byte (&buf, len - 1) == 0)
01801     {
01802       /* the kernel included the trailing \0 in its count,
01803        * but DBusString always has an extra \0 after the data anyway */
01804       _dbus_verbose ("subtracting trailing \\0\n");
01805       len--;
01806     }
01807 
01808   if (!_dbus_string_set_length (&buf, len))
01809     {
01810       _dbus_assert_not_reached ("shortening string should not lead to OOM");
01811       oom = TRUE;
01812       goto out;
01813     }
01814 
01815   if (strlen (_dbus_string_get_const_data (&buf)) != len)
01816     {
01817       /* LSM people on the linux-security-module@ mailing list say this
01818        * should never happen: the label should be a bytestring with
01819        * an optional trailing \0 */
01820       _dbus_verbose ("security label from kernel had an embedded \\0, "
01821                      "ignoring it\n");
01822       goto out;
01823     }
01824 
01825   _dbus_verbose ("getsockopt(SO_PEERSEC): %lu bytes excluding \\0: %s\n",
01826                  (unsigned long) len,
01827                  _dbus_string_get_const_data (&buf));
01828 
01829   if (!_dbus_credentials_add_linux_security_label (credentials,
01830         _dbus_string_get_const_data (&buf)))
01831     {
01832       oom = TRUE;
01833       goto out;
01834     }
01835 
01836 out:
01837   _dbus_string_free (&buf);
01838   return !oom;
01839 #else
01840   /* no error */
01841   return TRUE;
01842 #endif
01843 }
01844 
01885 dbus_bool_t
01886 _dbus_read_credentials_socket  (DBusSocket       client_fd,
01887                                 DBusCredentials *credentials,
01888                                 DBusError       *error)
01889 {
01890   struct msghdr msg;
01891   struct iovec iov;
01892   char buf;
01893   dbus_uid_t uid_read;
01894   dbus_pid_t pid_read;
01895   int bytes_read;
01896 
01897 #ifdef HAVE_CMSGCRED
01898   union {
01899     struct cmsghdr hdr;
01900     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01901   } cmsg;
01902 #endif
01903 
01904   /* The POSIX spec certainly doesn't promise this, but
01905    * we need these assertions to fail as soon as we're wrong about
01906    * it so we can do the porting fixups
01907    */
01908   _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
01909   _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
01910   _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
01911 
01912   uid_read = DBUS_UID_UNSET;
01913   pid_read = DBUS_PID_UNSET;
01914 
01915   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01916 
01917   _dbus_credentials_clear (credentials);
01918 
01919   iov.iov_base = &buf;
01920   iov.iov_len = 1;
01921 
01922   _DBUS_ZERO(msg);
01923   msg.msg_iov = &iov;
01924   msg.msg_iovlen = 1;
01925 
01926 #if defined(HAVE_CMSGCRED)
01927   _DBUS_ZERO(cmsg);
01928   msg.msg_control = (caddr_t) &cmsg;
01929   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01930 #endif
01931 
01932  again:
01933   bytes_read = recvmsg (client_fd.fd, &msg, 0);
01934 
01935   if (bytes_read < 0)
01936     {
01937       if (errno == EINTR)
01938         goto again;
01939 
01940       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01941        * normally only call read_credentials if the socket was ready
01942        * for reading
01943        */
01944 
01945       dbus_set_error (error, _dbus_error_from_errno (errno),
01946                       "Failed to read credentials byte: %s",
01947                       _dbus_strerror (errno));
01948       return FALSE;
01949     }
01950   else if (bytes_read == 0)
01951     {
01952       /* this should not happen unless we are using recvmsg wrong,
01953        * so is essentially here for paranoia
01954        */
01955       dbus_set_error (error, DBUS_ERROR_FAILED,
01956                       "Failed to read credentials byte (zero-length read)");
01957       return FALSE;
01958     }
01959   else if (buf != '\0')
01960     {
01961       dbus_set_error (error, DBUS_ERROR_FAILED,
01962                       "Credentials byte was not nul");
01963       return FALSE;
01964     }
01965 
01966   _dbus_verbose ("read credentials byte\n");
01967 
01968   {
01969 #ifdef SO_PEERCRED
01970     /* Supported by at least Linux and OpenBSD, with minor differences.
01971      *
01972      * This mechanism passes the process ID through and does not require
01973      * the peer's cooperation, so we prefer it over all others. Notably,
01974      * Linux also supports SCM_CREDENTIALS, which is similar to FreeBSD
01975      * SCM_CREDS; it's implemented in GIO, but we don't use it in dbus at all,
01976      * because this is much less fragile.
01977      */
01978 #ifdef __OpenBSD__
01979     struct sockpeercred cr;
01980 #else
01981     struct ucred cr;
01982 #endif
01983     int cr_len = sizeof (cr);
01984 
01985     if (getsockopt (client_fd.fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) != 0)
01986       {
01987         _dbus_verbose ("Failed to getsockopt(SO_PEERCRED): %s\n",
01988                        _dbus_strerror (errno));
01989       }
01990     else if (cr_len != sizeof (cr))
01991       {
01992         _dbus_verbose ("Failed to getsockopt(SO_PEERCRED), returned %d bytes, expected %d\n",
01993                        cr_len, (int) sizeof (cr));
01994       }
01995     else
01996       {
01997         pid_read = cr.pid;
01998         uid_read = cr.uid;
01999       }
02000 #elif defined(HAVE_UNPCBID) && defined(LOCAL_PEEREID)
02001     /* Another variant of the above - used on NetBSD
02002      */
02003     struct unpcbid cr;
02004     socklen_t cr_len = sizeof (cr);
02005 
02006     if (getsockopt (client_fd.fd, 0, LOCAL_PEEREID, &cr, &cr_len) != 0)
02007       {
02008         _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID): %s\n",
02009                        _dbus_strerror (errno));
02010       }
02011     else if (cr_len != sizeof (cr))
02012       {
02013         _dbus_verbose ("Failed to getsockopt(LOCAL_PEEREID), returned %d bytes, expected %d\n",
02014                        cr_len, (int) sizeof (cr));
02015       }
02016     else
02017       {
02018         pid_read = cr.unp_pid;
02019         uid_read = cr.unp_euid;
02020       }
02021 #elif defined(HAVE_CMSGCRED)
02022     /* We only check for HAVE_CMSGCRED, but we're really assuming that the
02023      * presence of that struct implies SCM_CREDS. Supported by at least
02024      * FreeBSD and DragonflyBSD.
02025      *
02026      * This mechanism requires the peer to help us (it has to send us a
02027      * SCM_CREDS message) but it does pass the process ID through,
02028      * which makes it better than getpeereid().
02029      */
02030     struct cmsgcred *cred;
02031     struct cmsghdr *cmsgp;
02032 
02033     for (cmsgp = CMSG_FIRSTHDR (&msg);
02034          cmsgp != NULL;
02035          cmsgp = CMSG_NXTHDR (&msg, cmsgp))
02036       {
02037         if (cmsgp->cmsg_type == SCM_CREDS &&
02038             cmsgp->cmsg_level == SOL_SOCKET &&
02039             cmsgp->cmsg_len >= CMSG_LEN (sizeof (struct cmsgcred)))
02040           {
02041             cred = (struct cmsgcred *) CMSG_DATA (cmsgp);
02042             pid_read = cred->cmcred_pid;
02043             uid_read = cred->cmcred_euid;
02044             break;
02045           }
02046       }
02047 
02048 #elif defined(HAVE_GETPEERUCRED)
02049     /* Supported in at least Solaris >= 10. It should probably be higher
02050      * up this list, because it carries the pid and we use this code path
02051      * for audit data. */
02052     ucred_t * ucred = NULL;
02053     if (getpeerucred (client_fd.fd, &ucred) == 0)
02054       {
02055         pid_read = ucred_getpid (ucred);
02056         uid_read = ucred_geteuid (ucred);
02057 #ifdef HAVE_ADT
02058         /* generate audit session data based on socket ucred */
02059         adt_session_data_t *adth = NULL;
02060         adt_export_data_t *data = NULL;
02061         size_t size = 0;
02062         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
02063           {
02064             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
02065           }
02066         else
02067           {
02068             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
02069               {
02070                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
02071               }
02072             else
02073               {
02074                 size = adt_export_session_data (adth, &data);
02075                 if (size <= 0)
02076                   {
02077                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
02078                   }
02079                 else
02080                   {
02081                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
02082                     free (data);
02083                   }
02084               }
02085             (void) adt_end_session (adth);
02086           }
02087 #endif /* HAVE_ADT */
02088       }
02089     else
02090       {
02091         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
02092       }
02093     if (ucred != NULL)
02094       ucred_free (ucred);
02095 
02096     /* ----------------------------------------------------------------
02097      * When adding new mechanisms, please add them above this point
02098      * if they support passing the process ID through, or below if not.
02099      * ---------------------------------------------------------------- */
02100 
02101 #elif defined(HAVE_GETPEEREID)
02102     /* getpeereid() originates from D.J. Bernstein and is fairly
02103      * widely-supported. According to a web search, it might be present in
02104      * any/all of:
02105      *
02106      * - AIX?
02107      * - Blackberry?
02108      * - Cygwin
02109      * - FreeBSD 4.6+ (but we prefer SCM_CREDS: it carries the pid)
02110      * - Mac OS X
02111      * - Minix 3.1.8+
02112      * - MirBSD?
02113      * - NetBSD 5.0+ (but LOCAL_PEEREID would be better: it carries the pid)
02114      * - OpenBSD 3.0+ (but we prefer SO_PEERCRED: it carries the pid)
02115      * - QNX?
02116      */
02117     uid_t euid;
02118     gid_t egid;
02119     if (getpeereid (client_fd.fd, &euid, &egid) == 0)
02120       {
02121         uid_read = euid;
02122       }
02123     else
02124       {
02125         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
02126       }
02127 #else /* no supported mechanism */
02128 
02129 #warning Socket credentials not supported on this Unix OS
02130 #warning Please tell https://bugs.freedesktop.org/enter_bug.cgi?product=DBus
02131 
02132     /* Please add other operating systems known to support at least one of
02133      * the mechanisms above to this list, keeping alphabetical order.
02134      * Everything not in this list  is best-effort.
02135      */
02136 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
02137     defined(__linux__) || \
02138     defined(__OpenBSD__) || \
02139     defined(__NetBSD__)
02140 # error Credentials passing not working on this OS is a regression!
02141 #endif
02142 
02143     _dbus_verbose ("Socket credentials not supported on this OS\n");
02144 #endif
02145   }
02146 
02147   _dbus_verbose ("Credentials:"
02148                  "  pid "DBUS_PID_FORMAT
02149                  "  uid "DBUS_UID_FORMAT
02150                  "\n",
02151                  pid_read,
02152                  uid_read);
02153 
02154   if (pid_read != DBUS_PID_UNSET)
02155     {
02156       if (!_dbus_credentials_add_pid (credentials, pid_read))
02157         {
02158           _DBUS_SET_OOM (error);
02159           return FALSE;
02160         }
02161     }
02162 
02163   if (uid_read != DBUS_UID_UNSET)
02164     {
02165       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
02166         {
02167           _DBUS_SET_OOM (error);
02168           return FALSE;
02169         }
02170     }
02171 
02172   if (!add_linux_security_label_to_credentials (client_fd.fd, credentials))
02173     {
02174       _DBUS_SET_OOM (error);
02175       return FALSE;
02176     }
02177 
02178   return TRUE;
02179 }
02180 
02198 dbus_bool_t
02199 _dbus_send_credentials_socket  (DBusSocket       server_fd,
02200                                 DBusError       *error)
02201 {
02202   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02203 
02204   if (write_credentials_byte (server_fd.fd, error))
02205     return TRUE;
02206   else
02207     return FALSE;
02208 }
02209 
02219 DBusSocket
02220 _dbus_accept  (DBusSocket listen_fd)
02221 {
02222   DBusSocket client_fd;
02223   struct sockaddr addr;
02224   socklen_t addrlen;
02225 #ifdef HAVE_ACCEPT4
02226   dbus_bool_t cloexec_done;
02227 #endif
02228 
02229   addrlen = sizeof (addr);
02230 
02231  retry:
02232 
02233 #ifdef HAVE_ACCEPT4
02234   /*
02235    * At compile-time, we assume that if accept4() is available in
02236    * libc headers, SOCK_CLOEXEC is too. At runtime, it is still
02237    * not necessarily true that either is supported by the running kernel.
02238    */
02239   client_fd.fd = accept4 (listen_fd.fd, &addr, &addrlen, SOCK_CLOEXEC);
02240   cloexec_done = client_fd.fd >= 0;
02241 
02242   if (client_fd.fd < 0 && (errno == ENOSYS || errno == EINVAL))
02243 #endif
02244     {
02245       client_fd.fd = accept (listen_fd.fd, &addr, &addrlen);
02246     }
02247 
02248   if (client_fd.fd < 0)
02249     {
02250       if (errno == EINTR)
02251         goto retry;
02252     }
02253 
02254   _dbus_verbose ("client fd %d accepted\n", client_fd.fd);
02255 
02256 #ifdef HAVE_ACCEPT4
02257   if (!cloexec_done)
02258 #endif
02259     {
02260       _dbus_fd_set_close_on_exec(client_fd.fd);
02261     }
02262 
02263   return client_fd;
02264 }
02265 
02274 dbus_bool_t
02275 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
02276 {
02277   const char *directory;
02278   struct stat sb;
02279 
02280   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02281 
02282   directory = _dbus_string_get_const_data (dir);
02283 
02284   if (stat (directory, &sb) < 0)
02285     {
02286       dbus_set_error (error, _dbus_error_from_errno (errno),
02287                       "%s", _dbus_strerror (errno));
02288 
02289       return FALSE;
02290     }
02291 
02292   if (sb.st_uid != geteuid ())
02293     {
02294       dbus_set_error (error, DBUS_ERROR_FAILED,
02295                      "%s directory is owned by user %lu, not %lu",
02296                      directory,
02297                      (unsigned long) sb.st_uid,
02298                      (unsigned long) geteuid ());
02299       return FALSE;
02300     }
02301 
02302   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
02303       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
02304     {
02305       dbus_set_error (error, DBUS_ERROR_FAILED,
02306                      "%s directory is not private to the user", directory);
02307       return FALSE;
02308     }
02309 
02310   return TRUE;
02311 }
02312 
02313 static dbus_bool_t
02314 fill_user_info_from_passwd (struct passwd *p,
02315                             DBusUserInfo  *info,
02316                             DBusError     *error)
02317 {
02318   _dbus_assert (p->pw_name != NULL);
02319   _dbus_assert (p->pw_dir != NULL);
02320 
02321   info->uid = p->pw_uid;
02322   info->primary_gid = p->pw_gid;
02323   info->username = _dbus_strdup (p->pw_name);
02324   info->homedir = _dbus_strdup (p->pw_dir);
02325 
02326   if (info->username == NULL ||
02327       info->homedir == NULL)
02328     {
02329       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02330       return FALSE;
02331     }
02332 
02333   return TRUE;
02334 }
02335 
02336 static dbus_bool_t
02337 fill_user_info (DBusUserInfo       *info,
02338                 dbus_uid_t          uid,
02339                 const DBusString   *username,
02340                 DBusError          *error)
02341 {
02342   const char *username_c;
02343 
02344   /* exactly one of username/uid provided */
02345   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
02346   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
02347 
02348   info->uid = DBUS_UID_UNSET;
02349   info->primary_gid = DBUS_GID_UNSET;
02350   info->group_ids = NULL;
02351   info->n_group_ids = 0;
02352   info->username = NULL;
02353   info->homedir = NULL;
02354 
02355   if (username != NULL)
02356     username_c = _dbus_string_get_const_data (username);
02357   else
02358     username_c = NULL;
02359 
02360   /* For now assuming that the getpwnam() and getpwuid() flavors
02361    * are always symmetrical, if not we have to add more configure
02362    * checks
02363    */
02364 
02365 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
02366   {
02367     struct passwd *p;
02368     int result;
02369     size_t buflen;
02370     char *buf;
02371     struct passwd p_str;
02372 
02373     /* retrieve maximum needed size for buf */
02374     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
02375 
02376     /* sysconf actually returns a long, but everything else expects size_t,
02377      * so just recast here.
02378      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
02379      */
02380     if ((long) buflen <= 0)
02381       buflen = 1024;
02382 
02383     result = -1;
02384     while (1)
02385       {
02386         buf = dbus_malloc (buflen);
02387         if (buf == NULL)
02388           {
02389             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02390             return FALSE;
02391           }
02392 
02393         p = NULL;
02394 #ifdef HAVE_POSIX_GETPWNAM_R
02395         if (uid != DBUS_UID_UNSET)
02396           result = getpwuid_r (uid, &p_str, buf, buflen,
02397                                &p);
02398         else
02399           result = getpwnam_r (username_c, &p_str, buf, buflen,
02400                                &p);
02401 #else
02402         if (uid != DBUS_UID_UNSET)
02403           p = getpwuid_r (uid, &p_str, buf, buflen);
02404         else
02405           p = getpwnam_r (username_c, &p_str, buf, buflen);
02406         result = 0;
02407 #endif /* !HAVE_POSIX_GETPWNAM_R */
02408         //Try a bigger buffer if ERANGE was returned
02409         if (result == ERANGE && buflen < 512 * 1024)
02410           {
02411             dbus_free (buf);
02412             buflen *= 2;
02413           }
02414         else
02415           {
02416             break;
02417           }
02418       }
02419     if (result == 0 && p == &p_str)
02420       {
02421         if (!fill_user_info_from_passwd (p, info, error))
02422           {
02423             dbus_free (buf);
02424             return FALSE;
02425           }
02426         dbus_free (buf);
02427       }
02428     else
02429       {
02430         dbus_set_error (error, _dbus_error_from_errno (errno),
02431                         "User \"%s\" unknown or no memory to allocate password entry\n",
02432                         username_c ? username_c : "???");
02433         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02434         dbus_free (buf);
02435         return FALSE;
02436       }
02437   }
02438 #else /* ! HAVE_GETPWNAM_R */
02439   {
02440     /* I guess we're screwed on thread safety here */
02441     struct passwd *p;
02442 
02443     if (uid != DBUS_UID_UNSET)
02444       p = getpwuid (uid);
02445     else
02446       p = getpwnam (username_c);
02447 
02448     if (p != NULL)
02449       {
02450         if (!fill_user_info_from_passwd (p, info, error))
02451           {
02452             return FALSE;
02453           }
02454       }
02455     else
02456       {
02457         dbus_set_error (error, _dbus_error_from_errno (errno),
02458                         "User \"%s\" unknown or no memory to allocate password entry\n",
02459                         username_c ? username_c : "???");
02460         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02461         return FALSE;
02462       }
02463   }
02464 #endif  /* ! HAVE_GETPWNAM_R */
02465 
02466   /* Fill this in so we can use it to get groups */
02467   username_c = info->username;
02468 
02469 #ifdef HAVE_GETGROUPLIST
02470   {
02471     gid_t *buf;
02472     int buf_count;
02473     int i;
02474     int initial_buf_count;
02475 
02476     initial_buf_count = 17;
02477     buf_count = initial_buf_count;
02478     buf = dbus_new (gid_t, buf_count);
02479     if (buf == NULL)
02480       {
02481         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02482         goto failed;
02483       }
02484 
02485     if (getgrouplist (username_c,
02486                       info->primary_gid,
02487                       buf, &buf_count) < 0)
02488       {
02489         gid_t *new;
02490         /* Presumed cause of negative return code: buf has insufficient
02491            entries to hold the entire group list. The Linux behavior in this
02492            case is to pass back the actual number of groups in buf_count, but
02493            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02494            So as a hack, try to help out a bit by guessing a larger
02495            number of groups, within reason.. might still fail, of course,
02496            but we can at least print a more informative message.  I looked up
02497            the "right way" to do this by downloading Apple's own source code
02498            for the "id" command, and it turns out that they use an
02499            undocumented library function getgrouplist_2 (!) which is not
02500            declared in any header in /usr/include (!!). That did not seem
02501            like the way to go here.
02502         */
02503         if (buf_count == initial_buf_count)
02504           {
02505             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02506           }
02507         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02508         if (new == NULL)
02509           {
02510             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02511             dbus_free (buf);
02512             goto failed;
02513           }
02514 
02515         buf = new;
02516 
02517         errno = 0;
02518         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02519           {
02520             if (errno == 0)
02521               {
02522                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02523                             username_c, buf_count, buf_count);
02524               }
02525             else
02526               {
02527                 dbus_set_error (error,
02528                                 _dbus_error_from_errno (errno),
02529                                 "Failed to get groups for username \"%s\" primary GID "
02530                                 DBUS_GID_FORMAT ": %s\n",
02531                                 username_c, info->primary_gid,
02532                                 _dbus_strerror (errno));
02533                 dbus_free (buf);
02534                 goto failed;
02535               }
02536           }
02537       }
02538 
02539     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02540     if (info->group_ids == NULL)
02541       {
02542         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02543         dbus_free (buf);
02544         goto failed;
02545       }
02546 
02547     for (i = 0; i < buf_count; ++i)
02548       info->group_ids[i] = buf[i];
02549 
02550     info->n_group_ids = buf_count;
02551 
02552     dbus_free (buf);
02553   }
02554 #else  /* HAVE_GETGROUPLIST */
02555   {
02556     /* We just get the one group ID */
02557     info->group_ids = dbus_new (dbus_gid_t, 1);
02558     if (info->group_ids == NULL)
02559       {
02560         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02561         goto failed;
02562       }
02563 
02564     info->n_group_ids = 1;
02565 
02566     (info->group_ids)[0] = info->primary_gid;
02567   }
02568 #endif /* HAVE_GETGROUPLIST */
02569 
02570   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02571 
02572   return TRUE;
02573 
02574  failed:
02575   _DBUS_ASSERT_ERROR_IS_SET (error);
02576   return FALSE;
02577 }
02578 
02587 dbus_bool_t
02588 _dbus_user_info_fill (DBusUserInfo     *info,
02589                       const DBusString *username,
02590                       DBusError        *error)
02591 {
02592   return fill_user_info (info, DBUS_UID_UNSET,
02593                          username, error);
02594 }
02595 
02604 dbus_bool_t
02605 _dbus_user_info_fill_uid (DBusUserInfo *info,
02606                           dbus_uid_t    uid,
02607                           DBusError    *error)
02608 {
02609   return fill_user_info (info, uid,
02610                          NULL, error);
02611 }
02612 
02620 dbus_bool_t
02621 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02622 {
02623   /* The POSIX spec certainly doesn't promise this, but
02624    * we need these assertions to fail as soon as we're wrong about
02625    * it so we can do the porting fixups
02626    */
02627   _DBUS_STATIC_ASSERT (sizeof (pid_t) <= sizeof (dbus_pid_t));
02628   _DBUS_STATIC_ASSERT (sizeof (uid_t) <= sizeof (dbus_uid_t));
02629   _DBUS_STATIC_ASSERT (sizeof (gid_t) <= sizeof (dbus_gid_t));
02630 
02631   if (!_dbus_credentials_add_pid(credentials, _dbus_getpid()))
02632     return FALSE;
02633   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02634     return FALSE;
02635 
02636   return TRUE;
02637 }
02638 
02650 dbus_bool_t
02651 _dbus_append_user_from_current_process (DBusString *str)
02652 {
02653   return _dbus_string_append_uint (str,
02654                                    _dbus_geteuid ());
02655 }
02656 
02661 dbus_pid_t
02662 _dbus_getpid (void)
02663 {
02664   return getpid ();
02665 }
02666 
02670 dbus_uid_t
02671 _dbus_getuid (void)
02672 {
02673   return getuid ();
02674 }
02675 
02679 dbus_uid_t
02680 _dbus_geteuid (void)
02681 {
02682   return geteuid ();
02683 }
02684 
02691 unsigned long
02692 _dbus_pid_for_log (void)
02693 {
02694   return getpid ();
02695 }
02696 
02704 dbus_bool_t
02705 _dbus_parse_uid (const DBusString      *uid_str,
02706                  dbus_uid_t            *uid)
02707 {
02708   int end;
02709   long val;
02710 
02711   if (_dbus_string_get_length (uid_str) == 0)
02712     {
02713       _dbus_verbose ("UID string was zero length\n");
02714       return FALSE;
02715     }
02716 
02717   val = -1;
02718   end = 0;
02719   if (!_dbus_string_parse_int (uid_str, 0, &val,
02720                                &end))
02721     {
02722       _dbus_verbose ("could not parse string as a UID\n");
02723       return FALSE;
02724     }
02725 
02726   if (end != _dbus_string_get_length (uid_str))
02727     {
02728       _dbus_verbose ("string contained trailing stuff after UID\n");
02729       return FALSE;
02730     }
02731 
02732   *uid = val;
02733 
02734   return TRUE;
02735 }
02736 
02737 #if !DBUS_USE_SYNC
02738 /* To be thread-safe by default on platforms that don't necessarily have
02739  * atomic operations (notably Debian armel, which is armv4t), we must
02740  * use a mutex that can be initialized statically, like this.
02741  * GLib >= 2.32 uses a similar system.
02742  */
02743 static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER;
02744 #endif
02745 
02752 dbus_int32_t
02753 _dbus_atomic_inc (DBusAtomic *atomic)
02754 {
02755 #if DBUS_USE_SYNC
02756   return __sync_add_and_fetch(&atomic->value, 1)-1;
02757 #else
02758   dbus_int32_t res;
02759 
02760   pthread_mutex_lock (&atomic_mutex);
02761   res = atomic->value;
02762   atomic->value += 1;
02763   pthread_mutex_unlock (&atomic_mutex);
02764 
02765   return res;
02766 #endif
02767 }
02768 
02775 dbus_int32_t
02776 _dbus_atomic_dec (DBusAtomic *atomic)
02777 {
02778 #if DBUS_USE_SYNC
02779   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02780 #else
02781   dbus_int32_t res;
02782 
02783   pthread_mutex_lock (&atomic_mutex);
02784   res = atomic->value;
02785   atomic->value -= 1;
02786   pthread_mutex_unlock (&atomic_mutex);
02787 
02788   return res;
02789 #endif
02790 }
02791 
02799 dbus_int32_t
02800 _dbus_atomic_get (DBusAtomic *atomic)
02801 {
02802 #if DBUS_USE_SYNC
02803   __sync_synchronize ();
02804   return atomic->value;
02805 #else
02806   dbus_int32_t res;
02807 
02808   pthread_mutex_lock (&atomic_mutex);
02809   res = atomic->value;
02810   pthread_mutex_unlock (&atomic_mutex);
02811 
02812   return res;
02813 #endif
02814 }
02815 
02824 int
02825 _dbus_poll (DBusPollFD *fds,
02826             int         n_fds,
02827             int         timeout_milliseconds)
02828 {
02829 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02830   /* DBusPollFD is a struct pollfd in this code path, so we can just poll() */
02831   if (timeout_milliseconds < -1)
02832     {
02833       timeout_milliseconds = -1;
02834     }
02835 
02836   return poll (fds,
02837                n_fds,
02838                timeout_milliseconds);
02839 #else /* ! HAVE_POLL */
02840   /* Emulate poll() in terms of select() */
02841   fd_set read_set, write_set, err_set;
02842   int max_fd = 0;
02843   int i;
02844   struct timeval tv;
02845   int ready;
02846 
02847   FD_ZERO (&read_set);
02848   FD_ZERO (&write_set);
02849   FD_ZERO (&err_set);
02850 
02851   for (i = 0; i < n_fds; i++)
02852     {
02853       DBusPollFD *fdp = &fds[i];
02854 
02855       if (fdp->events & _DBUS_POLLIN)
02856         FD_SET (fdp->fd, &read_set);
02857 
02858       if (fdp->events & _DBUS_POLLOUT)
02859         FD_SET (fdp->fd, &write_set);
02860 
02861       FD_SET (fdp->fd, &err_set);
02862 
02863       max_fd = MAX (max_fd, fdp->fd);
02864     }
02865 
02866   tv.tv_sec = timeout_milliseconds / 1000;
02867   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02868 
02869   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02870                   timeout_milliseconds < 0 ? NULL : &tv);
02871 
02872   if (ready > 0)
02873     {
02874       for (i = 0; i < n_fds; i++)
02875         {
02876           DBusPollFD *fdp = &fds[i];
02877 
02878           fdp->revents = 0;
02879 
02880           if (FD_ISSET (fdp->fd, &read_set))
02881             fdp->revents |= _DBUS_POLLIN;
02882 
02883           if (FD_ISSET (fdp->fd, &write_set))
02884             fdp->revents |= _DBUS_POLLOUT;
02885 
02886           if (FD_ISSET (fdp->fd, &err_set))
02887             fdp->revents |= _DBUS_POLLERR;
02888         }
02889     }
02890 
02891   return ready;
02892 #endif
02893 }
02894 
02902 void
02903 _dbus_get_monotonic_time (long *tv_sec,
02904                           long *tv_usec)
02905 {
02906 #ifdef HAVE_MONOTONIC_CLOCK
02907   struct timespec ts;
02908   clock_gettime (CLOCK_MONOTONIC, &ts);
02909 
02910   if (tv_sec)
02911     *tv_sec = ts.tv_sec;
02912   if (tv_usec)
02913     *tv_usec = ts.tv_nsec / 1000;
02914 #else
02915   struct timeval t;
02916 
02917   gettimeofday (&t, NULL);
02918 
02919   if (tv_sec)
02920     *tv_sec = t.tv_sec;
02921   if (tv_usec)
02922     *tv_usec = t.tv_usec;
02923 #endif
02924 }
02925 
02933 void
02934 _dbus_get_real_time (long *tv_sec,
02935                      long *tv_usec)
02936 {
02937   struct timeval t;
02938 
02939   gettimeofday (&t, NULL);
02940 
02941   if (tv_sec)
02942     *tv_sec = t.tv_sec;
02943   if (tv_usec)
02944     *tv_usec = t.tv_usec;
02945 }
02946 
02955 dbus_bool_t
02956 _dbus_create_directory (const DBusString *filename,
02957                         DBusError        *error)
02958 {
02959   const char *filename_c;
02960 
02961   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02962 
02963   filename_c = _dbus_string_get_const_data (filename);
02964 
02965   if (mkdir (filename_c, 0700) < 0)
02966     {
02967       if (errno == EEXIST)
02968         return TRUE;
02969 
02970       dbus_set_error (error, DBUS_ERROR_FAILED,
02971                       "Failed to create directory %s: %s\n",
02972                       filename_c, _dbus_strerror (errno));
02973       return FALSE;
02974     }
02975   else
02976     return TRUE;
02977 }
02978 
02989 dbus_bool_t
02990 _dbus_concat_dir_and_file (DBusString       *dir,
02991                            const DBusString *next_component)
02992 {
02993   dbus_bool_t dir_ends_in_slash;
02994   dbus_bool_t file_starts_with_slash;
02995 
02996   if (_dbus_string_get_length (dir) == 0 ||
02997       _dbus_string_get_length (next_component) == 0)
02998     return TRUE;
02999 
03000   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
03001                                                     _dbus_string_get_length (dir) - 1);
03002 
03003   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
03004 
03005   if (dir_ends_in_slash && file_starts_with_slash)
03006     {
03007       _dbus_string_shorten (dir, 1);
03008     }
03009   else if (!(dir_ends_in_slash || file_starts_with_slash))
03010     {
03011       if (!_dbus_string_append_byte (dir, '/'))
03012         return FALSE;
03013     }
03014 
03015   return _dbus_string_copy (next_component, 0, dir,
03016                             _dbus_string_get_length (dir));
03017 }
03018 
03020 #define NANOSECONDS_PER_SECOND       1000000000
03021 
03022 #define MICROSECONDS_PER_SECOND      1000000
03023 
03024 #define MILLISECONDS_PER_SECOND      1000
03025 
03026 #define NANOSECONDS_PER_MILLISECOND  1000000
03027 
03028 #define MICROSECONDS_PER_MILLISECOND 1000
03029 
03034 void
03035 _dbus_sleep_milliseconds (int milliseconds)
03036 {
03037 #ifdef HAVE_NANOSLEEP
03038   struct timespec req;
03039   struct timespec rem;
03040 
03041   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
03042   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
03043   rem.tv_sec = 0;
03044   rem.tv_nsec = 0;
03045 
03046   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
03047     req = rem;
03048 #elif defined (HAVE_USLEEP)
03049   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
03050 #else /* ! HAVE_USLEEP */
03051   sleep (MAX (milliseconds / 1000, 1));
03052 #endif
03053 }
03054 
03064 dbus_bool_t
03065 _dbus_generate_random_bytes (DBusString *str,
03066                              int         n_bytes,
03067                              DBusError  *error)
03068 {
03069   int old_len;
03070   int fd;
03071   int result;
03072 
03073   old_len = _dbus_string_get_length (str);
03074   fd = -1;
03075 
03076   /* note, urandom on linux will fall back to pseudorandom */
03077   fd = open ("/dev/urandom", O_RDONLY);
03078 
03079   if (fd < 0)
03080     {
03081       dbus_set_error (error, _dbus_error_from_errno (errno),
03082                       "Could not open /dev/urandom: %s",
03083                       _dbus_strerror (errno));
03084       return FALSE;
03085     }
03086 
03087   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
03088 
03089   result = _dbus_read (fd, str, n_bytes);
03090 
03091   if (result != n_bytes)
03092     {
03093       if (result < 0)
03094         dbus_set_error (error, _dbus_error_from_errno (errno),
03095                         "Could not read /dev/urandom: %s",
03096                         _dbus_strerror (errno));
03097       else
03098         dbus_set_error (error, DBUS_ERROR_IO_ERROR,
03099                         "Short read from /dev/urandom");
03100 
03101       _dbus_close (fd, NULL);
03102       _dbus_string_set_length (str, old_len);
03103       return FALSE;
03104     }
03105 
03106   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
03107                  n_bytes);
03108 
03109   _dbus_close (fd, NULL);
03110 
03111   return TRUE;
03112 }
03113 
03119 void
03120 _dbus_exit (int code)
03121 {
03122   _exit (code);
03123 }
03124 
03133 const char*
03134 _dbus_strerror (int error_number)
03135 {
03136   const char *msg;
03137 
03138   msg = strerror (error_number);
03139   if (msg == NULL)
03140     msg = "unknown";
03141 
03142   return msg;
03143 }
03144 
03148 void
03149 _dbus_disable_sigpipe (void)
03150 {
03151   signal (SIGPIPE, SIG_IGN);
03152 }
03153 
03161 void
03162 _dbus_fd_set_close_on_exec (int fd)
03163 {
03164   int val;
03165 
03166   val = fcntl (fd, F_GETFD, 0);
03167 
03168   if (val < 0)
03169     return;
03170 
03171   val |= FD_CLOEXEC;
03172 
03173   fcntl (fd, F_SETFD, val);
03174 }
03175 
03183 dbus_bool_t
03184 _dbus_close (int        fd,
03185              DBusError *error)
03186 {
03187   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03188 
03189  again:
03190   if (close (fd) < 0)
03191     {
03192       if (errno == EINTR)
03193         goto again;
03194 
03195       dbus_set_error (error, _dbus_error_from_errno (errno),
03196                       "Could not close fd %d", fd);
03197       return FALSE;
03198     }
03199 
03200   return TRUE;
03201 }
03202 
03211 int
03212 _dbus_dup(int        fd,
03213           DBusError *error)
03214 {
03215   int new_fd;
03216 
03217 #ifdef F_DUPFD_CLOEXEC
03218   dbus_bool_t cloexec_done;
03219 
03220   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
03221   cloexec_done = new_fd >= 0;
03222 
03223   if (new_fd < 0 && errno == EINVAL)
03224 #endif
03225     {
03226       new_fd = fcntl(fd, F_DUPFD, 3);
03227     }
03228 
03229   if (new_fd < 0) {
03230 
03231     dbus_set_error (error, _dbus_error_from_errno (errno),
03232                     "Could not duplicate fd %d", fd);
03233     return -1;
03234   }
03235 
03236 #ifdef F_DUPFD_CLOEXEC
03237   if (!cloexec_done)
03238 #endif
03239     {
03240       _dbus_fd_set_close_on_exec(new_fd);
03241     }
03242 
03243   return new_fd;
03244 }
03245 
03253 dbus_bool_t
03254 _dbus_set_socket_nonblocking (DBusSocket      fd,
03255                               DBusError      *error)
03256 {
03257   return _dbus_set_fd_nonblocking (fd.fd, error);
03258 }
03259 
03260 static dbus_bool_t
03261 _dbus_set_fd_nonblocking (int             fd,
03262                           DBusError      *error)
03263 {
03264   int val;
03265 
03266   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03267 
03268   val = fcntl (fd, F_GETFL, 0);
03269   if (val < 0)
03270     {
03271       dbus_set_error (error, _dbus_error_from_errno (errno),
03272                       "Failed to get flags from file descriptor %d: %s",
03273                       fd, _dbus_strerror (errno));
03274       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
03275                      _dbus_strerror (errno));
03276       return FALSE;
03277     }
03278 
03279   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
03280     {
03281       dbus_set_error (error, _dbus_error_from_errno (errno),
03282                       "Failed to set nonblocking flag of file descriptor %d: %s",
03283                       fd, _dbus_strerror (errno));
03284       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
03285                      fd, _dbus_strerror (errno));
03286 
03287       return FALSE;
03288     }
03289 
03290   return TRUE;
03291 }
03292 
03298 void
03299 _dbus_print_backtrace (void)
03300 {
03301 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
03302   void *bt[500];
03303   int bt_size;
03304   int i;
03305   char **syms;
03306 
03307   bt_size = backtrace (bt, 500);
03308 
03309   syms = backtrace_symbols (bt, bt_size);
03310 
03311   i = 0;
03312   while (i < bt_size)
03313     {
03314       /* don't use dbus_warn since it can _dbus_abort() */
03315       fprintf (stderr, "  %s\n", syms[i]);
03316       ++i;
03317     }
03318   fflush (stderr);
03319 
03320   free (syms);
03321 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
03322   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
03323 #else
03324   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
03325 #endif
03326 }
03327 
03340 dbus_bool_t
03341 _dbus_socketpair (DBusSocket *fd1,
03342                   DBusSocket *fd2,
03343                   dbus_bool_t blocking,
03344                   DBusError  *error)
03345 {
03346 #ifdef HAVE_SOCKETPAIR
03347   int fds[2];
03348   int retval;
03349 
03350 #ifdef SOCK_CLOEXEC
03351   dbus_bool_t cloexec_done;
03352 
03353   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
03354   cloexec_done = retval >= 0;
03355 
03356   if (retval < 0 && (errno == EINVAL || errno == EPROTOTYPE))
03357 #endif
03358     {
03359       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
03360     }
03361 
03362   if (retval < 0)
03363     {
03364       dbus_set_error (error, _dbus_error_from_errno (errno),
03365                       "Could not create full-duplex pipe");
03366       return FALSE;
03367     }
03368 
03369   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03370 
03371 #ifdef SOCK_CLOEXEC
03372   if (!cloexec_done)
03373 #endif
03374     {
03375       _dbus_fd_set_close_on_exec (fds[0]);
03376       _dbus_fd_set_close_on_exec (fds[1]);
03377     }
03378 
03379   if (!blocking &&
03380       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
03381        !_dbus_set_fd_nonblocking (fds[1], NULL)))
03382     {
03383       dbus_set_error (error, _dbus_error_from_errno (errno),
03384                       "Could not set full-duplex pipe nonblocking");
03385 
03386       _dbus_close (fds[0], NULL);
03387       _dbus_close (fds[1], NULL);
03388 
03389       return FALSE;
03390     }
03391 
03392   fd1->fd = fds[0];
03393   fd2->fd = fds[1];
03394 
03395   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
03396                  fd1->fd, fd2->fd);
03397 
03398   return TRUE;
03399 #else
03400   _dbus_warn ("_dbus_socketpair() not implemented on this OS\n");
03401   dbus_set_error (error, DBUS_ERROR_FAILED,
03402                   "_dbus_socketpair() not implemented on this OS");
03403   return FALSE;
03404 #endif
03405 }
03406 
03415 int
03416 _dbus_printf_string_upper_bound (const char *format,
03417                                  va_list     args)
03418 {
03419   char static_buf[1024];
03420   int bufsize = sizeof (static_buf);
03421   int len;
03422   va_list args_copy;
03423 
03424   DBUS_VA_COPY (args_copy, args);
03425   len = vsnprintf (static_buf, bufsize, format, args_copy);
03426   va_end (args_copy);
03427 
03428   /* If vsnprintf() returned non-negative, then either the string fits in
03429    * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
03430    * returns the number of characters that were needed, or this OS returns the
03431    * truncated length.
03432    *
03433    * We ignore the possibility that snprintf might just ignore the length and
03434    * overrun the buffer (64-bit Solaris 7), because that's pathological.
03435    * If your libc is really that bad, come back when you have a better one. */
03436   if (len == bufsize)
03437     {
03438       /* This could be the truncated length (Tru64 and IRIX have this bug),
03439        * or the real length could be coincidentally the same. Which is it?
03440        * If vsnprintf returns the truncated length, we'll go to the slow
03441        * path. */
03442       DBUS_VA_COPY (args_copy, args);
03443 
03444       if (vsnprintf (static_buf, 1, format, args_copy) == 1)
03445         len = -1;
03446 
03447       va_end (args_copy);
03448     }
03449 
03450   /* If vsnprintf() returned negative, we have to do more work.
03451    * HP-UX returns negative. */
03452   while (len < 0)
03453     {
03454       char *buf;
03455 
03456       bufsize *= 2;
03457 
03458       buf = dbus_malloc (bufsize);
03459 
03460       if (buf == NULL)
03461         return -1;
03462 
03463       DBUS_VA_COPY (args_copy, args);
03464       len = vsnprintf (buf, bufsize, format, args_copy);
03465       va_end (args_copy);
03466 
03467       dbus_free (buf);
03468 
03469       /* If the reported length is exactly the buffer size, round up to the
03470        * next size, in case vsnprintf has been returning the truncated
03471        * length */
03472       if (len == bufsize)
03473         len = -1;
03474     }
03475 
03476   return len;
03477 }
03478 
03485 const char*
03486 _dbus_get_tmpdir(void)
03487 {
03488   /* Protected by _DBUS_LOCK_sysdeps */
03489   static const char* tmpdir = NULL;
03490 
03491   if (!_DBUS_LOCK (sysdeps))
03492     return NULL;
03493 
03494   if (tmpdir == NULL)
03495     {
03496       /* TMPDIR is what glibc uses, then
03497        * glibc falls back to the P_tmpdir macro which
03498        * just expands to "/tmp"
03499        */
03500       if (tmpdir == NULL)
03501         tmpdir = getenv("TMPDIR");
03502 
03503       /* These two env variables are probably
03504        * broken, but maybe some OS uses them?
03505        */
03506       if (tmpdir == NULL)
03507         tmpdir = getenv("TMP");
03508       if (tmpdir == NULL)
03509         tmpdir = getenv("TEMP");
03510 
03511       /* And this is the sane fallback. */
03512       if (tmpdir == NULL)
03513         tmpdir = "/tmp";
03514     }
03515 
03516   _DBUS_UNLOCK (sysdeps);
03517 
03518   _dbus_assert(tmpdir != NULL);
03519 
03520   return tmpdir;
03521 }
03522 
03523 #if defined(DBUS_ENABLE_X11_AUTOLAUNCH) || defined(DBUS_ENABLE_LAUNCHD)
03524 
03543 static dbus_bool_t
03544 _read_subprocess_line_argv (const char *progpath,
03545                             dbus_bool_t path_fallback,
03546                             char       * const *argv,
03547                             DBusString *result,
03548                             DBusError  *error)
03549 {
03550   int result_pipe[2] = { -1, -1 };
03551   int errors_pipe[2] = { -1, -1 };
03552   pid_t pid;
03553   int ret;
03554   int status;
03555   int orig_len;
03556 
03557   dbus_bool_t retval;
03558   sigset_t new_set, old_set;
03559 
03560   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03561   retval = FALSE;
03562 
03563   /* We need to block any existing handlers for SIGCHLD temporarily; they
03564    * will cause waitpid() below to fail.
03565    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03566    */
03567   sigemptyset (&new_set);
03568   sigaddset (&new_set, SIGCHLD);
03569   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03570 
03571   orig_len = _dbus_string_get_length (result);
03572 
03573 #define READ_END        0
03574 #define WRITE_END       1
03575   if (pipe (result_pipe) < 0)
03576     {
03577       dbus_set_error (error, _dbus_error_from_errno (errno),
03578                       "Failed to create a pipe to call %s: %s",
03579                       progpath, _dbus_strerror (errno));
03580       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03581                      progpath, _dbus_strerror (errno));
03582       goto out;
03583     }
03584   if (pipe (errors_pipe) < 0)
03585     {
03586       dbus_set_error (error, _dbus_error_from_errno (errno),
03587                       "Failed to create a pipe to call %s: %s",
03588                       progpath, _dbus_strerror (errno));
03589       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03590                      progpath, _dbus_strerror (errno));
03591       goto out;
03592     }
03593 
03594   pid = fork ();
03595   if (pid < 0)
03596     {
03597       dbus_set_error (error, _dbus_error_from_errno (errno),
03598                       "Failed to fork() to call %s: %s",
03599                       progpath, _dbus_strerror (errno));
03600       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03601                      progpath, _dbus_strerror (errno));
03602       goto out;
03603     }
03604 
03605   if (pid == 0)
03606     {
03607       /* child process */
03608       int fd;
03609 
03610       fd = open ("/dev/null", O_RDWR);
03611       if (fd == -1)
03612         /* huh?! can't open /dev/null? */
03613         _exit (1);
03614 
03615       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03616 
03617       /* set-up stdXXX */
03618       close (result_pipe[READ_END]);
03619       close (errors_pipe[READ_END]);
03620 
03621       if (dup2 (fd, 0) == -1) /* setup stdin */
03622         _exit (1);
03623       if (dup2 (result_pipe[WRITE_END], 1) == -1) /* setup stdout */
03624         _exit (1);
03625       if (dup2 (errors_pipe[WRITE_END], 2) == -1) /* setup stderr */
03626         _exit (1);
03627 
03628       _dbus_close_all ();
03629 
03630       sigprocmask (SIG_SETMASK, &old_set, NULL);
03631 
03632       /* If it looks fully-qualified, try execv first */
03633       if (progpath[0] == '/')
03634         {
03635           execv (progpath, argv);
03636           /* Ok, that failed.  Now if path_fallback is given, let's
03637            * try unqualified.  This is mostly a hack to work
03638            * around systems which ship dbus-launch in /usr/bin
03639            * but everything else in /bin (because dbus-launch
03640            * depends on X11).
03641            */
03642           if (path_fallback)
03643             /* We must have a slash, because we checked above */
03644             execvp (strrchr (progpath, '/')+1, argv);
03645         }
03646       else
03647         execvp (progpath, argv);
03648 
03649       /* still nothing, we failed */
03650       _exit (1);
03651     }
03652 
03653   /* parent process */
03654   close (result_pipe[WRITE_END]);
03655   close (errors_pipe[WRITE_END]);
03656   result_pipe[WRITE_END] = -1;
03657   errors_pipe[WRITE_END] = -1;
03658 
03659   ret = 0;
03660   do
03661     {
03662       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03663     }
03664   while (ret > 0);
03665 
03666   /* reap the child process to avoid it lingering as zombie */
03667   do
03668     {
03669       ret = waitpid (pid, &status, 0);
03670     }
03671   while (ret == -1 && errno == EINTR);
03672 
03673   /* We succeeded if the process exited with status 0 and
03674      anything was read */
03675   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03676     {
03677       /* The process ended with error */
03678       DBusString error_message;
03679       if (!_dbus_string_init (&error_message))
03680         {
03681           _DBUS_SET_OOM (error);
03682           goto out;
03683         }
03684 
03685       ret = 0;
03686       do
03687         {
03688           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03689         }
03690       while (ret > 0);
03691 
03692       _dbus_string_set_length (result, orig_len);
03693       if (_dbus_string_get_length (&error_message) > 0)
03694         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03695                         "%s terminated abnormally with the following error: %s",
03696                         progpath, _dbus_string_get_data (&error_message));
03697       else
03698         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03699                         "%s terminated abnormally without any error message",
03700                         progpath);
03701       goto out;
03702     }
03703 
03704   retval = TRUE;
03705 
03706  out:
03707   sigprocmask (SIG_SETMASK, &old_set, NULL);
03708 
03709   if (retval)
03710     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03711   else
03712     _DBUS_ASSERT_ERROR_IS_SET (error);
03713 
03714   if (result_pipe[0] != -1)
03715     close (result_pipe[0]);
03716   if (result_pipe[1] != -1)
03717     close (result_pipe[1]);
03718   if (errors_pipe[0] != -1)
03719     close (errors_pipe[0]);
03720   if (errors_pipe[1] != -1)
03721     close (errors_pipe[1]);
03722 
03723   return retval;
03724 }
03725 #endif
03726 
03739 dbus_bool_t
03740 _dbus_get_autolaunch_address (const char *scope,
03741                               DBusString *address,
03742                               DBusError  *error)
03743 {
03744 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03745   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03746    * but that's done elsewhere, and if it worked, this function wouldn't
03747    * be called.) */
03748   const char *display;
03749   char *progpath;
03750   char *argv[6];
03751   int i;
03752   DBusString uuid;
03753   dbus_bool_t retval;
03754 
03755   if (_dbus_check_setuid ())
03756     {
03757       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03758                             "Unable to autolaunch when setuid");
03759       return FALSE;
03760     }
03761 
03762   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03763   retval = FALSE;
03764 
03765   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03766    * dbus-launch-x11 is just going to fail. Rather than trying to
03767    * run it, we might as well bail out early with a nice error.
03768    *
03769    * This is not strictly true in a world where the user bus exists,
03770    * because dbus-launch --autolaunch knows how to connect to that -
03771    * but if we were going to connect to the user bus, we'd have done
03772    * so before trying autolaunch: in any case. */
03773   display = _dbus_getenv ("DISPLAY");
03774 
03775   if (display == NULL || display[0] == '\0')
03776     {
03777       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03778           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03779       return FALSE;
03780     }
03781 
03782   if (!_dbus_string_init (&uuid))
03783     {
03784       _DBUS_SET_OOM (error);
03785       return FALSE;
03786     }
03787 
03788   if (!_dbus_get_local_machine_uuid_encoded (&uuid, error))
03789     {
03790       goto out;
03791     }
03792 
03793 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
03794   if (_dbus_getenv ("DBUS_USE_TEST_BINARY") != NULL)
03795     progpath = TEST_BUS_LAUNCH_BINARY;
03796   else
03797 #endif
03798     progpath = DBUS_BINDIR "/dbus-launch";
03799   /*
03800    * argv[0] is always dbus-launch, that's the name what we'll
03801    * get from /proc, or ps(1), regardless what the progpath is,
03802    * see fd.o#69716
03803    */
03804   i = 0;
03805   argv[i] = "dbus-launch";
03806   ++i;
03807   argv[i] = "--autolaunch";
03808   ++i;
03809   argv[i] = _dbus_string_get_data (&uuid);
03810   ++i;
03811   argv[i] = "--binary-syntax";
03812   ++i;
03813   argv[i] = "--close-stderr";
03814   ++i;
03815   argv[i] = NULL;
03816   ++i;
03817 
03818   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03819 
03820   retval = _read_subprocess_line_argv (progpath,
03821                                        TRUE,
03822                                        argv, address, error);
03823 
03824  out:
03825   _dbus_string_free (&uuid);
03826   return retval;
03827 #else
03828   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03829       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03830       "set your DBUS_SESSION_BUS_ADDRESS instead");
03831   return FALSE;
03832 #endif
03833 }
03834 
03853 dbus_bool_t
03854 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03855                                dbus_bool_t create_if_not_found,
03856                                DBusError  *error)
03857 {
03858   DBusString filename;
03859   dbus_bool_t b;
03860 
03861   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03862 
03863   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03864   if (b)
03865     return TRUE;
03866 
03867   dbus_error_free (error);
03868 
03869   /* Fallback to the system machine ID */
03870   _dbus_string_init_const (&filename, "/etc/machine-id");
03871   b = _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03872 
03873   if (b)
03874     {
03875       /* try to copy it to the DBUS_MACHINE_UUID_FILE, but do not
03876        * complain if that isn't possible for whatever reason */
03877       _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03878       _dbus_write_uuid_file (&filename, machine_id, NULL);
03879 
03880       return TRUE;
03881     }
03882 
03883   if (!create_if_not_found)
03884     return FALSE;
03885 
03886   /* if none found, try to make a new one */
03887   dbus_error_free (error);
03888   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03889 
03890   if (!_dbus_generate_uuid (machine_id, error))
03891     return FALSE;
03892 
03893   return _dbus_write_uuid_file (&filename, machine_id, error);
03894 }
03895 
03903 dbus_bool_t
03904 _dbus_lookup_launchd_socket (DBusString *socket_path,
03905                              const char *launchd_env_var,
03906                              DBusError  *error)
03907 {
03908 #ifdef DBUS_ENABLE_LAUNCHD
03909   char *argv[4];
03910   int i;
03911 
03912   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03913 
03914   if (_dbus_check_setuid ())
03915     {
03916       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03917                             "Unable to find launchd socket when setuid");
03918       return FALSE;
03919     }
03920 
03921   i = 0;
03922   argv[i] = "launchctl";
03923   ++i;
03924   argv[i] = "getenv";
03925   ++i;
03926   argv[i] = (char*)launchd_env_var;
03927   ++i;
03928   argv[i] = NULL;
03929   ++i;
03930 
03931   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03932 
03933   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03934     {
03935       return FALSE;
03936     }
03937 
03938   /* no error, but no result either */
03939   if (_dbus_string_get_length(socket_path) == 0)
03940     {
03941       return FALSE;
03942     }
03943 
03944   /* strip the carriage-return */
03945   _dbus_string_shorten(socket_path, 1);
03946   return TRUE;
03947 #else /* DBUS_ENABLE_LAUNCHD */
03948   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03949                 "can't lookup socket from launchd; launchd support not compiled in");
03950   return FALSE;
03951 #endif
03952 }
03953 
03954 #ifdef DBUS_ENABLE_LAUNCHD
03955 static dbus_bool_t
03956 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03957 {
03958   dbus_bool_t valid_socket;
03959   DBusString socket_path;
03960 
03961   if (_dbus_check_setuid ())
03962     {
03963       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03964                             "Unable to find launchd socket when setuid");
03965       return FALSE;
03966     }
03967 
03968   if (!_dbus_string_init (&socket_path))
03969     {
03970       _DBUS_SET_OOM (error);
03971       return FALSE;
03972     }
03973 
03974   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03975 
03976   if (dbus_error_is_set(error))
03977     {
03978       _dbus_string_free(&socket_path);
03979       return FALSE;
03980     }
03981 
03982   if (!valid_socket)
03983     {
03984       dbus_set_error(error, "no socket path",
03985                 "launchd did not provide a socket path, "
03986                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03987       _dbus_string_free(&socket_path);
03988       return FALSE;
03989     }
03990   if (!_dbus_string_append (address, "unix:path="))
03991     {
03992       _DBUS_SET_OOM (error);
03993       _dbus_string_free(&socket_path);
03994       return FALSE;
03995     }
03996   if (!_dbus_string_copy (&socket_path, 0, address,
03997                           _dbus_string_get_length (address)))
03998     {
03999       _DBUS_SET_OOM (error);
04000       _dbus_string_free(&socket_path);
04001       return FALSE;
04002     }
04003 
04004   _dbus_string_free(&socket_path);
04005   return TRUE;
04006 }
04007 #endif
04008 
04009 dbus_bool_t
04010 _dbus_lookup_user_bus (dbus_bool_t *supported,
04011                        DBusString  *address,
04012                        DBusError   *error)
04013 {
04014   const char *runtime_dir = _dbus_getenv ("XDG_RUNTIME_DIR");
04015   dbus_bool_t ret = FALSE;
04016   struct stat stbuf;
04017   DBusString user_bus_path;
04018 
04019   if (runtime_dir == NULL)
04020     {
04021       _dbus_verbose ("XDG_RUNTIME_DIR not found in environment");
04022       *supported = FALSE;
04023       return TRUE;        /* Cannot use it, but not an error */
04024     }
04025 
04026   if (!_dbus_string_init (&user_bus_path))
04027     {
04028       _DBUS_SET_OOM (error);
04029       return FALSE;
04030     }
04031 
04032   if (!_dbus_string_append_printf (&user_bus_path, "%s/bus", runtime_dir))
04033     {
04034       _DBUS_SET_OOM (error);
04035       goto out;
04036     }
04037 
04038   if (lstat (_dbus_string_get_const_data (&user_bus_path), &stbuf) == -1)
04039     {
04040       _dbus_verbose ("XDG_RUNTIME_DIR/bus not available: %s",
04041                      _dbus_strerror (errno));
04042       *supported = FALSE;
04043       ret = TRUE;       /* Cannot use it, but not an error */
04044       goto out;
04045     }
04046 
04047   if (stbuf.st_uid != getuid ())
04048     {
04049       _dbus_verbose ("XDG_RUNTIME_DIR/bus owned by uid %ld, not our uid %ld",
04050                      (long) stbuf.st_uid, (long) getuid ());
04051       *supported = FALSE;
04052       ret = TRUE;       /* Cannot use it, but not an error */
04053       goto out;
04054     }
04055 
04056   if ((stbuf.st_mode & S_IFMT) != S_IFSOCK)
04057     {
04058       _dbus_verbose ("XDG_RUNTIME_DIR/bus is not a socket: st_mode = 0o%lo",
04059                      (long) stbuf.st_mode);
04060       *supported = FALSE;
04061       ret = TRUE;       /* Cannot use it, but not an error */
04062       goto out;
04063     }
04064 
04065   if (!_dbus_string_append (address, "unix:path=") ||
04066       !_dbus_address_append_escaped (address, &user_bus_path))
04067     {
04068       _DBUS_SET_OOM (error);
04069       goto out;
04070     }
04071 
04072   *supported = TRUE;
04073   ret = TRUE;
04074 
04075 out:
04076   _dbus_string_free (&user_bus_path);
04077   return ret;
04078 }
04079 
04099 dbus_bool_t
04100 _dbus_lookup_session_address (dbus_bool_t *supported,
04101                               DBusString  *address,
04102                               DBusError   *error)
04103 {
04104 #ifdef DBUS_ENABLE_LAUNCHD
04105   *supported = TRUE;
04106   return _dbus_lookup_session_address_launchd (address, error);
04107 #else
04108   *supported = FALSE;
04109 
04110   if (!_dbus_lookup_user_bus (supported, address, error))
04111     return FALSE;
04112   else if (*supported)
04113     return TRUE;
04114 
04115   /* On non-Mac Unix platforms, if the session address isn't already
04116    * set in DBUS_SESSION_BUS_ADDRESS environment variable and the
04117    * $XDG_RUNTIME_DIR/bus can't be used, we punt and fall back to the
04118    * autolaunch: global default; see init_session_address in
04119    * dbus/dbus-bus.c. */
04120   return TRUE;
04121 #endif
04122 }
04123 
04131 void
04132 _dbus_flush_caches (void)
04133 {
04134   _dbus_user_database_flush_system ();
04135 }
04136 
04150 dbus_bool_t
04151 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
04152                                                 DBusCredentials *credentials)
04153 {
04154   DBusString homedir;
04155   DBusString dotdir;
04156   dbus_uid_t uid;
04157 
04158   _dbus_assert (credentials != NULL);
04159   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
04160 
04161   if (!_dbus_string_init (&homedir))
04162     return FALSE;
04163 
04164   uid = _dbus_credentials_get_unix_uid (credentials);
04165   _dbus_assert (uid != DBUS_UID_UNSET);
04166 
04167   if (!_dbus_homedir_from_uid (uid, &homedir))
04168     goto failed;
04169 
04170 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
04171   {
04172     const char *override;
04173 
04174     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
04175     if (override != NULL && *override != '\0')
04176       {
04177         _dbus_string_set_length (&homedir, 0);
04178         if (!_dbus_string_append (&homedir, override))
04179           goto failed;
04180 
04181         _dbus_verbose ("Using fake homedir for testing: %s\n",
04182                        _dbus_string_get_const_data (&homedir));
04183       }
04184     else
04185       {
04186         /* Not strictly thread-safe, but if we fail at thread-safety here,
04187          * the worst that will happen is some extra warnings. */
04188         static dbus_bool_t already_warned = FALSE;
04189         if (!already_warned)
04190           {
04191             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
04192             already_warned = TRUE;
04193           }
04194       }
04195   }
04196 #endif
04197 
04198   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
04199   if (!_dbus_concat_dir_and_file (&homedir,
04200                                   &dotdir))
04201     goto failed;
04202 
04203   if (!_dbus_string_copy (&homedir, 0,
04204                           directory, _dbus_string_get_length (directory))) {
04205     goto failed;
04206   }
04207 
04208   _dbus_string_free (&homedir);
04209   return TRUE;
04210 
04211  failed:
04212   _dbus_string_free (&homedir);
04213   return FALSE;
04214 }
04215 
04216 //PENDING(kdab) docs
04217 dbus_bool_t
04218 _dbus_daemon_publish_session_bus_address (const char* addr,
04219                                           const char *scope)
04220 {
04221   return TRUE;
04222 }
04223 
04224 //PENDING(kdab) docs
04225 void
04226 _dbus_daemon_unpublish_session_bus_address (void)
04227 {
04228 
04229 }
04230 
04237 dbus_bool_t
04238 _dbus_get_is_errno_eagain_or_ewouldblock (int e)
04239 {
04240   return e == EAGAIN || e == EWOULDBLOCK;
04241 }
04242 
04250 dbus_bool_t
04251 _dbus_delete_directory (const DBusString *filename,
04252                         DBusError        *error)
04253 {
04254   const char *filename_c;
04255 
04256   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
04257 
04258   filename_c = _dbus_string_get_const_data (filename);
04259 
04260   if (rmdir (filename_c) != 0)
04261     {
04262       dbus_set_error (error, DBUS_ERROR_FAILED,
04263                       "Failed to remove directory %s: %s\n",
04264                       filename_c, _dbus_strerror (errno));
04265       return FALSE;
04266     }
04267 
04268   return TRUE;
04269 }
04270 
04278 dbus_bool_t
04279 _dbus_socket_can_pass_unix_fd (DBusSocket fd)
04280 {
04281 #ifdef SCM_RIGHTS
04282   union {
04283     struct sockaddr sa;
04284     struct sockaddr_storage storage;
04285     struct sockaddr_un un;
04286   } sa_buf;
04287 
04288   socklen_t sa_len = sizeof(sa_buf);
04289 
04290   _DBUS_ZERO(sa_buf);
04291 
04292   if (getsockname(fd.fd, &sa_buf.sa, &sa_len) < 0)
04293     return FALSE;
04294 
04295   return sa_buf.sa.sa_family == AF_UNIX;
04296 
04297 #else
04298   return FALSE;
04299 
04300 #endif
04301 }
04302 
04307 void
04308 _dbus_close_all (void)
04309 {
04310   int maxfds, i;
04311 
04312 #ifdef __linux__
04313   DIR *d;
04314 
04315   /* On Linux we can optimize this a bit if /proc is available. If it
04316      isn't available, fall back to the brute force way. */
04317 
04318   d = opendir ("/proc/self/fd");
04319   if (d)
04320     {
04321       for (;;)
04322         {
04323           struct dirent buf, *de;
04324           int k, fd;
04325           long l;
04326           char *e = NULL;
04327 
04328           k = readdir_r (d, &buf, &de);
04329           if (k != 0 || !de)
04330             break;
04331 
04332           if (de->d_name[0] == '.')
04333             continue;
04334 
04335           errno = 0;
04336           l = strtol (de->d_name, &e, 10);
04337           if (errno != 0 || e == NULL || *e != '\0')
04338             continue;
04339 
04340           fd = (int) l;
04341           if (fd < 3)
04342             continue;
04343 
04344           if (fd == dirfd (d))
04345             continue;
04346 
04347           close (fd);
04348         }
04349 
04350       closedir (d);
04351       return;
04352     }
04353 #endif
04354 
04355   maxfds = sysconf (_SC_OPEN_MAX);
04356 
04357   /* Pick something reasonable if for some reason sysconf says
04358    * unlimited.
04359    */
04360   if (maxfds < 0)
04361     maxfds = 1024;
04362 
04363   /* close all inherited fds */
04364   for (i = 3; i < maxfds; i++)
04365     close (i);
04366 }
04367 
04377 dbus_bool_t
04378 _dbus_check_setuid (void)
04379 {
04380   /* TODO: get __libc_enable_secure exported from glibc.
04381    * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
04382    */
04383 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
04384   {
04385     /* See glibc/include/unistd.h */
04386     extern int __libc_enable_secure;
04387     return __libc_enable_secure;
04388   }
04389 #elif defined(HAVE_ISSETUGID)
04390   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
04391   return issetugid ();
04392 #else
04393   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
04394   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
04395 
04396   /* We call into this function from _dbus_threads_init_platform_specific()
04397    * to make sure these are initialized before we start threading. */
04398   static dbus_bool_t check_setuid_initialised;
04399   static dbus_bool_t is_setuid;
04400 
04401   if (_DBUS_UNLIKELY (!check_setuid_initialised))
04402     {
04403 #ifdef HAVE_GETRESUID
04404       if (getresuid (&ruid, &euid, &suid) != 0 ||
04405           getresgid (&rgid, &egid, &sgid) != 0)
04406 #endif /* HAVE_GETRESUID */
04407         {
04408           suid = ruid = getuid ();
04409           sgid = rgid = getgid ();
04410           euid = geteuid ();
04411           egid = getegid ();
04412         }
04413 
04414       check_setuid_initialised = TRUE;
04415       is_setuid = (ruid != euid || ruid != suid ||
04416                    rgid != egid || rgid != sgid);
04417 
04418     }
04419   return is_setuid;
04420 #endif
04421 }
04422 
04430 dbus_bool_t
04431 _dbus_append_address_from_socket (DBusSocket  fd,
04432                                   DBusString *address,
04433                                   DBusError  *error)
04434 {
04435   union {
04436       struct sockaddr sa;
04437       struct sockaddr_storage storage;
04438       struct sockaddr_un un;
04439       struct sockaddr_in ipv4;
04440       struct sockaddr_in6 ipv6;
04441   } socket;
04442   char hostip[INET6_ADDRSTRLEN];
04443   int size = sizeof (socket);
04444   DBusString path_str;
04445 
04446   if (getsockname (fd.fd, &socket.sa, &size))
04447     goto err;
04448 
04449   switch (socket.sa.sa_family)
04450     {
04451     case AF_UNIX:
04452       if (socket.un.sun_path[0]=='\0')
04453         {
04454           _dbus_string_init_const (&path_str, &(socket.un.sun_path[1]));
04455           if (_dbus_string_append (address, "unix:abstract=") &&
04456               _dbus_address_append_escaped (address, &path_str))
04457             return TRUE;
04458         }
04459       else
04460         {
04461           _dbus_string_init_const (&path_str, socket.un.sun_path);
04462           if (_dbus_string_append (address, "unix:path=") &&
04463               _dbus_address_append_escaped (address, &path_str))
04464             return TRUE;
04465         }
04466       break;
04467     case AF_INET:
04468       if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip)))
04469         if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u",
04470                                         hostip, ntohs (socket.ipv4.sin_port)))
04471           return TRUE;
04472       break;
04473 #ifdef AF_INET6
04474     case AF_INET6:
04475       _dbus_string_init_const (&path_str, hostip);
04476       if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip)))
04477         if (_dbus_string_append_printf (address, "tcp:family=ipv6,port=%u,host=",
04478                                         ntohs (socket.ipv6.sin6_port)) &&
04479             _dbus_address_append_escaped (address, &path_str))
04480           return TRUE;
04481       break;
04482 #endif
04483     default:
04484       dbus_set_error (error,
04485                       _dbus_error_from_errno (EINVAL),
04486                       "Failed to read address from socket: Unknown socket type.");
04487       return FALSE;
04488     }
04489  err:
04490   dbus_set_error (error,
04491                   _dbus_error_from_errno (errno),
04492                   "Failed to open socket: %s",
04493                   _dbus_strerror (errno));
04494   return FALSE;
04495 }
04496 
04497 int
04498 _dbus_save_socket_errno (void)
04499 {
04500   return errno;
04501 }
04502 
04503 void
04504 _dbus_restore_socket_errno (int saved_errno)
04505 {
04506   errno = saved_errno;
04507 }
04508 
04509 /* tests in dbus-sysdeps-util.c */