D-Bus 1.4.14
dbus-sysdeps-unix.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
00003  *
00004  * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
00005  * Copyright (C) 2003 CodeFactory AB
00006  *
00007  * Licensed under the Academic Free License version 2.1
00008  *
00009  * This program is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include "dbus-internals.h"
00028 #include "dbus-sysdeps.h"
00029 #include "dbus-sysdeps-unix.h"
00030 #include "dbus-threads.h"
00031 #include "dbus-protocol.h"
00032 #include "dbus-transport.h"
00033 #include "dbus-string.h"
00034 #include "dbus-userdb.h"
00035 #include "dbus-list.h"
00036 #include "dbus-credentials.h"
00037 #include "dbus-nonce.h"
00038 
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <unistd.h>
00044 #include <stdio.h>
00045 #include <fcntl.h>
00046 #include <sys/socket.h>
00047 #include <dirent.h>
00048 #include <sys/un.h>
00049 #include <pwd.h>
00050 #include <time.h>
00051 #include <locale.h>
00052 #include <sys/time.h>
00053 #include <sys/stat.h>
00054 #include <sys/wait.h>
00055 #include <netinet/in.h>
00056 #include <netdb.h>
00057 #include <grp.h>
00058 
00059 #ifdef HAVE_ERRNO_H
00060 #include <errno.h>
00061 #endif
00062 #ifdef HAVE_WRITEV
00063 #include <sys/uio.h>
00064 #endif
00065 #ifdef HAVE_POLL
00066 #include <sys/poll.h>
00067 #endif
00068 #ifdef HAVE_BACKTRACE
00069 #include <execinfo.h>
00070 #endif
00071 #ifdef HAVE_GETPEERUCRED
00072 #include <ucred.h>
00073 #endif
00074 
00075 #ifdef HAVE_ADT
00076 #include <bsm/adt.h>
00077 #endif
00078 
00079 #include "sd-daemon.h"
00080 
00081 #ifndef O_BINARY
00082 #define O_BINARY 0
00083 #endif
00084 
00085 #ifndef AI_ADDRCONFIG
00086 #define AI_ADDRCONFIG 0
00087 #endif
00088 
00089 #ifndef HAVE_SOCKLEN_T
00090 #define socklen_t int
00091 #endif
00092 
00093 static dbus_bool_t
00094 _dbus_open_socket (int              *fd_p,
00095                    int               domain,
00096                    int               type,
00097                    int               protocol,
00098                    DBusError        *error)
00099 {
00100 #ifdef SOCK_CLOEXEC
00101   dbus_bool_t cloexec_done;
00102 
00103   *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
00104   cloexec_done = *fd_p >= 0;
00105 
00106   /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
00107   if (*fd_p < 0 && errno == EINVAL)
00108 #endif
00109     {
00110       *fd_p = socket (domain, type, protocol);
00111     }
00112 
00113   if (*fd_p >= 0)
00114     {
00115 #ifdef SOCK_CLOEXEC
00116       if (!cloexec_done)
00117 #endif
00118         {
00119           _dbus_fd_set_close_on_exec(*fd_p);
00120         }
00121 
00122       _dbus_verbose ("socket fd %d opened\n", *fd_p);
00123       return TRUE;
00124     }
00125   else
00126     {
00127       dbus_set_error(error,
00128                      _dbus_error_from_errno (errno),
00129                      "Failed to open socket: %s",
00130                      _dbus_strerror (errno));
00131       return FALSE;
00132     }
00133 }
00134 
00135 dbus_bool_t
00136 _dbus_open_tcp_socket (int              *fd,
00137                        DBusError        *error)
00138 {
00139   return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
00140 }
00141 
00152 dbus_bool_t
00153 _dbus_open_unix_socket (int              *fd,
00154                         DBusError        *error)
00155 {
00156   return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
00157 }
00158 
00167 dbus_bool_t
00168 _dbus_close_socket (int               fd,
00169                     DBusError        *error)
00170 {
00171   return _dbus_close (fd, error);
00172 }
00173 
00183 int
00184 _dbus_read_socket (int               fd,
00185                    DBusString       *buffer,
00186                    int               count)
00187 {
00188   return _dbus_read (fd, buffer, count);
00189 }
00190 
00201 int
00202 _dbus_write_socket (int               fd,
00203                     const DBusString *buffer,
00204                     int               start,
00205                     int               len)
00206 {
00207 #if HAVE_DECL_MSG_NOSIGNAL
00208   const char *data;
00209   int bytes_written;
00210 
00211   data = _dbus_string_get_const_data_len (buffer, start, len);
00212 
00213  again:
00214 
00215   bytes_written = send (fd, data, len, MSG_NOSIGNAL);
00216 
00217   if (bytes_written < 0 && errno == EINTR)
00218     goto again;
00219 
00220   return bytes_written;
00221 
00222 #else
00223   return _dbus_write (fd, buffer, start, len);
00224 #endif
00225 }
00226 
00239 int
00240 _dbus_read_socket_with_unix_fds (int               fd,
00241                                  DBusString       *buffer,
00242                                  int               count,
00243                                  int              *fds,
00244                                  int              *n_fds) {
00245 #ifndef HAVE_UNIX_FD_PASSING
00246   int r;
00247 
00248   if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
00249     return r;
00250 
00251   *n_fds = 0;
00252   return r;
00253 
00254 #else
00255   int bytes_read;
00256   int start;
00257   struct msghdr m;
00258   struct iovec iov;
00259 
00260   _dbus_assert (count >= 0);
00261   _dbus_assert (*n_fds >= 0);
00262 
00263   start = _dbus_string_get_length (buffer);
00264 
00265   if (!_dbus_string_lengthen (buffer, count))
00266     {
00267       errno = ENOMEM;
00268       return -1;
00269     }
00270 
00271   _DBUS_ZERO(iov);
00272   iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
00273   iov.iov_len = count;
00274 
00275   _DBUS_ZERO(m);
00276   m.msg_iov = &iov;
00277   m.msg_iovlen = 1;
00278 
00279   /* Hmm, we have no clue how long the control data will actually be
00280      that is queued for us. The least we can do is assume that the
00281      caller knows. Hence let's make space for the number of fds that
00282      we shall read at max plus the cmsg header. */
00283   m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
00284 
00285   /* It's probably safe to assume that systems with SCM_RIGHTS also
00286      know alloca() */
00287   m.msg_control = alloca(m.msg_controllen);
00288   memset(m.msg_control, 0, m.msg_controllen);
00289 
00290  again:
00291 
00292   bytes_read = recvmsg(fd, &m, 0
00293 #ifdef MSG_CMSG_CLOEXEC
00294                        |MSG_CMSG_CLOEXEC
00295 #endif
00296                        );
00297 
00298   if (bytes_read < 0)
00299     {
00300       if (errno == EINTR)
00301         goto again;
00302       else
00303         {
00304           /* put length back (note that this doesn't actually realloc anything) */
00305           _dbus_string_set_length (buffer, start);
00306           return -1;
00307         }
00308     }
00309   else
00310     {
00311       struct cmsghdr *cm;
00312       dbus_bool_t found = FALSE;
00313 
00314       if (m.msg_flags & MSG_CTRUNC)
00315         {
00316           /* Hmm, apparently the control data was truncated. The bad
00317              thing is that we might have completely lost a couple of fds
00318              without chance to recover them. Hence let's treat this as a
00319              serious error. */
00320 
00321           errno = ENOSPC;
00322           _dbus_string_set_length (buffer, start);
00323           return -1;
00324         }
00325 
00326       for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
00327         if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
00328           {
00329             unsigned i;
00330 
00331             _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
00332             *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
00333 
00334             memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
00335             found = TRUE;
00336 
00337             /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
00338                worked, hence we need to go through this list and set
00339                CLOEXEC everywhere in any case */
00340             for (i = 0; i < *n_fds; i++)
00341               _dbus_fd_set_close_on_exec(fds[i]);
00342 
00343             break;
00344           }
00345 
00346       if (!found)
00347         *n_fds = 0;
00348 
00349       /* put length back (doesn't actually realloc) */
00350       _dbus_string_set_length (buffer, start + bytes_read);
00351 
00352 #if 0
00353       if (bytes_read > 0)
00354         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00355 #endif
00356 
00357       return bytes_read;
00358     }
00359 #endif
00360 }
00361 
00362 int
00363 _dbus_write_socket_with_unix_fds(int               fd,
00364                                  const DBusString *buffer,
00365                                  int               start,
00366                                  int               len,
00367                                  const int        *fds,
00368                                  int               n_fds) {
00369 
00370 #ifndef HAVE_UNIX_FD_PASSING
00371 
00372   if (n_fds > 0) {
00373     errno = ENOTSUP;
00374     return -1;
00375   }
00376 
00377   return _dbus_write_socket(fd, buffer, start, len);
00378 #else
00379   return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
00380 #endif
00381 }
00382 
00383 int
00384 _dbus_write_socket_with_unix_fds_two(int               fd,
00385                                      const DBusString *buffer1,
00386                                      int               start1,
00387                                      int               len1,
00388                                      const DBusString *buffer2,
00389                                      int               start2,
00390                                      int               len2,
00391                                      const int        *fds,
00392                                      int               n_fds) {
00393 
00394 #ifndef HAVE_UNIX_FD_PASSING
00395 
00396   if (n_fds > 0) {
00397     errno = ENOTSUP;
00398     return -1;
00399   }
00400 
00401   return _dbus_write_socket_two(fd,
00402                                 buffer1, start1, len1,
00403                                 buffer2, start2, len2);
00404 #else
00405 
00406   struct msghdr m;
00407   struct cmsghdr *cm;
00408   struct iovec iov[2];
00409   int bytes_written;
00410 
00411   _dbus_assert (len1 >= 0);
00412   _dbus_assert (len2 >= 0);
00413   _dbus_assert (n_fds >= 0);
00414 
00415   _DBUS_ZERO(iov);
00416   iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
00417   iov[0].iov_len = len1;
00418 
00419   if (buffer2)
00420     {
00421       iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
00422       iov[1].iov_len = len2;
00423     }
00424 
00425   _DBUS_ZERO(m);
00426   m.msg_iov = iov;
00427   m.msg_iovlen = buffer2 ? 2 : 1;
00428 
00429   if (n_fds > 0)
00430     {
00431       m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
00432       m.msg_control = alloca(m.msg_controllen);
00433       memset(m.msg_control, 0, m.msg_controllen);
00434 
00435       cm = CMSG_FIRSTHDR(&m);
00436       cm->cmsg_level = SOL_SOCKET;
00437       cm->cmsg_type = SCM_RIGHTS;
00438       cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
00439       memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
00440     }
00441 
00442  again:
00443 
00444   bytes_written = sendmsg (fd, &m, 0
00445 #if HAVE_DECL_MSG_NOSIGNAL
00446                            |MSG_NOSIGNAL
00447 #endif
00448                            );
00449 
00450   if (bytes_written < 0 && errno == EINTR)
00451     goto again;
00452 
00453 #if 0
00454   if (bytes_written > 0)
00455     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00456 #endif
00457 
00458   return bytes_written;
00459 #endif
00460 }
00461 
00475 int
00476 _dbus_write_socket_two (int               fd,
00477                         const DBusString *buffer1,
00478                         int               start1,
00479                         int               len1,
00480                         const DBusString *buffer2,
00481                         int               start2,
00482                         int               len2)
00483 {
00484 #if HAVE_DECL_MSG_NOSIGNAL
00485   struct iovec vectors[2];
00486   const char *data1;
00487   const char *data2;
00488   int bytes_written;
00489   struct msghdr m;
00490 
00491   _dbus_assert (buffer1 != NULL);
00492   _dbus_assert (start1 >= 0);
00493   _dbus_assert (start2 >= 0);
00494   _dbus_assert (len1 >= 0);
00495   _dbus_assert (len2 >= 0);
00496 
00497   data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00498 
00499   if (buffer2 != NULL)
00500     data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00501   else
00502     {
00503       data2 = NULL;
00504       start2 = 0;
00505       len2 = 0;
00506     }
00507 
00508   vectors[0].iov_base = (char*) data1;
00509   vectors[0].iov_len = len1;
00510   vectors[1].iov_base = (char*) data2;
00511   vectors[1].iov_len = len2;
00512 
00513   _DBUS_ZERO(m);
00514   m.msg_iov = vectors;
00515   m.msg_iovlen = data2 ? 2 : 1;
00516 
00517  again:
00518 
00519   bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
00520 
00521   if (bytes_written < 0 && errno == EINTR)
00522     goto again;
00523 
00524   return bytes_written;
00525 
00526 #else
00527   return _dbus_write_two (fd, buffer1, start1, len1,
00528                           buffer2, start2, len2);
00529 #endif
00530 }
00531 
00532 dbus_bool_t
00533 _dbus_socket_is_invalid (int fd)
00534 {
00535     return fd < 0 ? TRUE : FALSE;
00536 }
00537 
00554 int
00555 _dbus_read (int               fd,
00556             DBusString       *buffer,
00557             int               count)
00558 {
00559   int bytes_read;
00560   int start;
00561   char *data;
00562 
00563   _dbus_assert (count >= 0);
00564 
00565   start = _dbus_string_get_length (buffer);
00566 
00567   if (!_dbus_string_lengthen (buffer, count))
00568     {
00569       errno = ENOMEM;
00570       return -1;
00571     }
00572 
00573   data = _dbus_string_get_data_len (buffer, start, count);
00574 
00575  again:
00576 
00577   bytes_read = read (fd, data, count);
00578 
00579   if (bytes_read < 0)
00580     {
00581       if (errno == EINTR)
00582         goto again;
00583       else
00584         {
00585           /* put length back (note that this doesn't actually realloc anything) */
00586           _dbus_string_set_length (buffer, start);
00587           return -1;
00588         }
00589     }
00590   else
00591     {
00592       /* put length back (doesn't actually realloc) */
00593       _dbus_string_set_length (buffer, start + bytes_read);
00594 
00595 #if 0
00596       if (bytes_read > 0)
00597         _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
00598 #endif
00599 
00600       return bytes_read;
00601     }
00602 }
00603 
00614 int
00615 _dbus_write (int               fd,
00616              const DBusString *buffer,
00617              int               start,
00618              int               len)
00619 {
00620   const char *data;
00621   int bytes_written;
00622 
00623   data = _dbus_string_get_const_data_len (buffer, start, len);
00624 
00625  again:
00626 
00627   bytes_written = write (fd, data, len);
00628 
00629   if (bytes_written < 0 && errno == EINTR)
00630     goto again;
00631 
00632 #if 0
00633   if (bytes_written > 0)
00634     _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
00635 #endif
00636 
00637   return bytes_written;
00638 }
00639 
00660 int
00661 _dbus_write_two (int               fd,
00662                  const DBusString *buffer1,
00663                  int               start1,
00664                  int               len1,
00665                  const DBusString *buffer2,
00666                  int               start2,
00667                  int               len2)
00668 {
00669   _dbus_assert (buffer1 != NULL);
00670   _dbus_assert (start1 >= 0);
00671   _dbus_assert (start2 >= 0);
00672   _dbus_assert (len1 >= 0);
00673   _dbus_assert (len2 >= 0);
00674 
00675 #ifdef HAVE_WRITEV
00676   {
00677     struct iovec vectors[2];
00678     const char *data1;
00679     const char *data2;
00680     int bytes_written;
00681 
00682     data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
00683 
00684     if (buffer2 != NULL)
00685       data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
00686     else
00687       {
00688         data2 = NULL;
00689         start2 = 0;
00690         len2 = 0;
00691       }
00692 
00693     vectors[0].iov_base = (char*) data1;
00694     vectors[0].iov_len = len1;
00695     vectors[1].iov_base = (char*) data2;
00696     vectors[1].iov_len = len2;
00697 
00698   again:
00699 
00700     bytes_written = writev (fd,
00701                             vectors,
00702                             data2 ? 2 : 1);
00703 
00704     if (bytes_written < 0 && errno == EINTR)
00705       goto again;
00706 
00707     return bytes_written;
00708   }
00709 #else /* HAVE_WRITEV */
00710   {
00711     int ret1;
00712 
00713     ret1 = _dbus_write (fd, buffer1, start1, len1);
00714     if (ret1 == len1 && buffer2 != NULL)
00715       {
00716         ret2 = _dbus_write (fd, buffer2, start2, len2);
00717         if (ret2 < 0)
00718           ret2 = 0; /* we can't report an error as the first write was OK */
00719 
00720         return ret1 + ret2;
00721       }
00722     else
00723       return ret1;
00724   }
00725 #endif /* !HAVE_WRITEV */
00726 }
00727 
00728 #define _DBUS_MAX_SUN_PATH_LENGTH 99
00729 
00759 int
00760 _dbus_connect_unix_socket (const char     *path,
00761                            dbus_bool_t     abstract,
00762                            DBusError      *error)
00763 {
00764   int fd;
00765   size_t path_len;
00766   struct sockaddr_un addr;
00767 
00768   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00769 
00770   _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
00771                  path, abstract);
00772 
00773 
00774   if (!_dbus_open_unix_socket (&fd, error))
00775     {
00776       _DBUS_ASSERT_ERROR_IS_SET(error);
00777       return -1;
00778     }
00779   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00780 
00781   _DBUS_ZERO (addr);
00782   addr.sun_family = AF_UNIX;
00783   path_len = strlen (path);
00784 
00785   if (abstract)
00786     {
00787 #ifdef HAVE_ABSTRACT_SOCKETS
00788       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00789       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00790 
00791       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00792         {
00793           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00794                       "Abstract socket name too long\n");
00795           _dbus_close (fd, NULL);
00796           return -1;
00797         }
00798 
00799       strncpy (&addr.sun_path[1], path, path_len);
00800       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00801 #else /* HAVE_ABSTRACT_SOCKETS */
00802       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00803                       "Operating system does not support abstract socket namespace\n");
00804       _dbus_close (fd, NULL);
00805       return -1;
00806 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00807     }
00808   else
00809     {
00810       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00811         {
00812           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00813                       "Socket name too long\n");
00814           _dbus_close (fd, NULL);
00815           return -1;
00816         }
00817 
00818       strncpy (addr.sun_path, path, path_len);
00819     }
00820 
00821   if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00822     {
00823       dbus_set_error (error,
00824                       _dbus_error_from_errno (errno),
00825                       "Failed to connect to socket %s: %s",
00826                       path, _dbus_strerror (errno));
00827 
00828       _dbus_close (fd, NULL);
00829       return -1;
00830     }
00831 
00832   if (!_dbus_set_fd_nonblocking (fd, error))
00833     {
00834       _DBUS_ASSERT_ERROR_IS_SET (error);
00835 
00836       _dbus_close (fd, NULL);
00837       return -1;
00838     }
00839 
00840   return fd;
00841 }
00842 
00852 static dbus_bool_t
00853 _dbus_set_local_creds (int fd, dbus_bool_t on)
00854 {
00855   dbus_bool_t retval = TRUE;
00856 
00857 #if defined(HAVE_CMSGCRED)
00858   /* NOOP just to make sure only one codepath is used
00859    *      and to prefer CMSGCRED
00860    */
00861 #elif defined(LOCAL_CREDS)
00862   int val = on ? 1 : 0;
00863   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00864     {
00865       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00866       retval = FALSE;
00867     }
00868   else
00869     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00870                    on ? "enabled" : "disabled", fd);
00871 #endif
00872 
00873   return retval;
00874 }
00875 
00893 int
00894 _dbus_listen_unix_socket (const char     *path,
00895                           dbus_bool_t     abstract,
00896                           DBusError      *error)
00897 {
00898   int listen_fd;
00899   struct sockaddr_un addr;
00900   size_t path_len;
00901   unsigned int reuseaddr;
00902 
00903   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00904 
00905   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00906                  path, abstract);
00907 
00908   if (!_dbus_open_unix_socket (&listen_fd, error))
00909     {
00910       _DBUS_ASSERT_ERROR_IS_SET(error);
00911       return -1;
00912     }
00913   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00914 
00915   _DBUS_ZERO (addr);
00916   addr.sun_family = AF_UNIX;
00917   path_len = strlen (path);
00918 
00919   if (abstract)
00920     {
00921 #ifdef HAVE_ABSTRACT_SOCKETS
00922       /* remember that abstract names aren't nul-terminated so we rely
00923        * on sun_path being filled in with zeroes above.
00924        */
00925       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00926       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00927 
00928       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00929         {
00930           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00931                       "Abstract socket name too long\n");
00932           _dbus_close (listen_fd, NULL);
00933           return -1;
00934         }
00935 
00936       strncpy (&addr.sun_path[1], path, path_len);
00937       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00938 #else /* HAVE_ABSTRACT_SOCKETS */
00939       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00940                       "Operating system does not support abstract socket namespace\n");
00941       _dbus_close (listen_fd, NULL);
00942       return -1;
00943 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00944     }
00945   else
00946     {
00947       /* Discussed security implications of this with Nalin,
00948        * and we couldn't think of where it would kick our ass, but
00949        * it still seems a bit sucky. It also has non-security suckage;
00950        * really we'd prefer to exit if the socket is already in use.
00951        * But there doesn't seem to be a good way to do this.
00952        *
00953        * Just to be extra careful, I threw in the stat() - clearly
00954        * the stat() can't *fix* any security issue, but it at least
00955        * avoids inadvertent/accidental data loss.
00956        */
00957       {
00958         struct stat sb;
00959 
00960         if (stat (path, &sb) == 0 &&
00961             S_ISSOCK (sb.st_mode))
00962           unlink (path);
00963       }
00964 
00965       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00966         {
00967           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00968                       "Abstract socket name too long\n");
00969           _dbus_close (listen_fd, NULL);
00970           return -1;
00971         }
00972 
00973       strncpy (addr.sun_path, path, path_len);
00974     }
00975 
00976   reuseaddr = 1;
00977   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
00978     {
00979       _dbus_warn ("Failed to set socket option\"%s\": %s",
00980                   path, _dbus_strerror (errno));
00981     }
00982 
00983   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00984     {
00985       dbus_set_error (error, _dbus_error_from_errno (errno),
00986                       "Failed to bind socket \"%s\": %s",
00987                       path, _dbus_strerror (errno));
00988       _dbus_close (listen_fd, NULL);
00989       return -1;
00990     }
00991 
00992   if (listen (listen_fd, 30 /* backlog */) < 0)
00993     {
00994       dbus_set_error (error, _dbus_error_from_errno (errno),
00995                       "Failed to listen on socket \"%s\": %s",
00996                       path, _dbus_strerror (errno));
00997       _dbus_close (listen_fd, NULL);
00998       return -1;
00999     }
01000 
01001   if (!_dbus_set_local_creds (listen_fd, TRUE))
01002     {
01003       dbus_set_error (error, _dbus_error_from_errno (errno),
01004                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01005                       path, _dbus_strerror (errno));
01006       close (listen_fd);
01007       return -1;
01008     }
01009 
01010   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01011     {
01012       _DBUS_ASSERT_ERROR_IS_SET (error);
01013       _dbus_close (listen_fd, NULL);
01014       return -1;
01015     }
01016 
01017   /* Try opening up the permissions, but if we can't, just go ahead
01018    * and continue, maybe it will be good enough.
01019    */
01020   if (!abstract && chmod (path, 0777) < 0)
01021     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01022                 path);
01023 
01024   return listen_fd;
01025 }
01026 
01037 int
01038 _dbus_listen_systemd_sockets (int       **fds,
01039                               DBusError *error)
01040 {
01041   int r, n;
01042   unsigned fd;
01043   int *new_fds;
01044 
01045   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01046 
01047   n = sd_listen_fds (TRUE);
01048   if (n < 0)
01049     {
01050       dbus_set_error (error, _dbus_error_from_errno (-n),
01051                       "Failed to acquire systemd socket: %s",
01052                       _dbus_strerror (-n));
01053       return -1;
01054     }
01055 
01056   if (n <= 0)
01057     {
01058       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01059                       "No socket received.");
01060       return -1;
01061     }
01062 
01063   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01064     {
01065       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01066       if (r < 0)
01067         {
01068           dbus_set_error (error, _dbus_error_from_errno (-r),
01069                           "Failed to verify systemd socket type: %s",
01070                           _dbus_strerror (-r));
01071           return -1;
01072         }
01073 
01074       if (!r)
01075         {
01076           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01077                           "Passed socket has wrong type.");
01078           return -1;
01079         }
01080     }
01081 
01082   /* OK, the file descriptors are all good, so let's take posession of
01083      them then. */
01084 
01085   new_fds = dbus_new (int, n);
01086   if (!new_fds)
01087     {
01088       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01089                       "Failed to allocate file handle array.");
01090       goto fail;
01091     }
01092 
01093   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01094     {
01095       if (!_dbus_set_local_creds (fd, TRUE))
01096         {
01097           dbus_set_error (error, _dbus_error_from_errno (errno),
01098                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01099                           _dbus_strerror (errno));
01100           goto fail;
01101         }
01102 
01103       if (!_dbus_set_fd_nonblocking (fd, error))
01104         {
01105           _DBUS_ASSERT_ERROR_IS_SET (error);
01106           goto fail;
01107         }
01108 
01109       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01110     }
01111 
01112   *fds = new_fds;
01113   return n;
01114 
01115  fail:
01116 
01117   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01118     {
01119       _dbus_close (fd, NULL);
01120     }
01121 
01122   dbus_free (new_fds);
01123   return -1;
01124 }
01125 
01139 int
01140 _dbus_connect_tcp_socket (const char     *host,
01141                           const char     *port,
01142                           const char     *family,
01143                           DBusError      *error)
01144 {
01145     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01146 }
01147 
01148 int
01149 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01150                                      const char     *port,
01151                                      const char     *family,
01152                                      const char     *noncefile,
01153                                      DBusError      *error)
01154 {
01155   int saved_errno = 0;
01156   int fd = -1, res;
01157   struct addrinfo hints;
01158   struct addrinfo *ai, *tmp;
01159 
01160   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01161 
01162   _DBUS_ZERO (hints);
01163 
01164   if (!family)
01165     hints.ai_family = AF_UNSPEC;
01166   else if (!strcmp(family, "ipv4"))
01167     hints.ai_family = AF_INET;
01168   else if (!strcmp(family, "ipv6"))
01169     hints.ai_family = AF_INET6;
01170   else
01171     {
01172       dbus_set_error (error,
01173                       DBUS_ERROR_BAD_ADDRESS,
01174                       "Unknown address family %s", family);
01175       return -1;
01176     }
01177   hints.ai_protocol = IPPROTO_TCP;
01178   hints.ai_socktype = SOCK_STREAM;
01179   hints.ai_flags = AI_ADDRCONFIG;
01180 
01181   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01182     {
01183       dbus_set_error (error,
01184                       _dbus_error_from_errno (errno),
01185                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01186                       host, port, gai_strerror(res), res);
01187       _dbus_close (fd, NULL);
01188       return -1;
01189     }
01190 
01191   tmp = ai;
01192   while (tmp)
01193     {
01194       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01195         {
01196           freeaddrinfo(ai);
01197           _DBUS_ASSERT_ERROR_IS_SET(error);
01198           return -1;
01199         }
01200       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01201 
01202       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01203         {
01204           saved_errno = errno;
01205           _dbus_close(fd, NULL);
01206           fd = -1;
01207           tmp = tmp->ai_next;
01208           continue;
01209         }
01210 
01211       break;
01212     }
01213   freeaddrinfo(ai);
01214 
01215   if (fd == -1)
01216     {
01217       dbus_set_error (error,
01218                       _dbus_error_from_errno (saved_errno),
01219                       "Failed to connect to socket \"%s:%s\" %s",
01220                       host, port, _dbus_strerror(saved_errno));
01221       return -1;
01222     }
01223 
01224   if (noncefile != NULL)
01225     {
01226       DBusString noncefileStr;
01227       dbus_bool_t ret;
01228       _dbus_string_init_const (&noncefileStr, noncefile);
01229       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01230       _dbus_string_free (&noncefileStr);
01231 
01232       if (!ret)
01233     {
01234       _dbus_close (fd, NULL);
01235           return -1;
01236         }
01237     }
01238 
01239   if (!_dbus_set_fd_nonblocking (fd, error))
01240     {
01241       _dbus_close (fd, NULL);
01242       return -1;
01243     }
01244 
01245   return fd;
01246 }
01247 
01264 int
01265 _dbus_listen_tcp_socket (const char     *host,
01266                          const char     *port,
01267                          const char     *family,
01268                          DBusString     *retport,
01269                          int           **fds_p,
01270                          DBusError      *error)
01271 {
01272   int saved_errno;
01273   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01274   struct addrinfo hints;
01275   struct addrinfo *ai, *tmp;
01276   unsigned int reuseaddr;
01277 
01278   *fds_p = NULL;
01279   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01280 
01281   _DBUS_ZERO (hints);
01282 
01283   if (!family)
01284     hints.ai_family = AF_UNSPEC;
01285   else if (!strcmp(family, "ipv4"))
01286     hints.ai_family = AF_INET;
01287   else if (!strcmp(family, "ipv6"))
01288     hints.ai_family = AF_INET6;
01289   else
01290     {
01291       dbus_set_error (error,
01292                       DBUS_ERROR_BAD_ADDRESS,
01293                       "Unknown address family %s", family);
01294       return -1;
01295     }
01296 
01297   hints.ai_protocol = IPPROTO_TCP;
01298   hints.ai_socktype = SOCK_STREAM;
01299   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01300 
01301  redo_lookup_with_port:
01302   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01303     {
01304       dbus_set_error (error,
01305                       _dbus_error_from_errno (errno),
01306                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01307                       host ? host : "*", port, gai_strerror(res), res);
01308       return -1;
01309     }
01310 
01311   tmp = ai;
01312   while (tmp)
01313     {
01314       int fd = -1, *newlisten_fd;
01315       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01316         {
01317           _DBUS_ASSERT_ERROR_IS_SET(error);
01318           goto failed;
01319         }
01320       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01321 
01322       reuseaddr = 1;
01323       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01324         {
01325           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01326                       host ? host : "*", port, _dbus_strerror (errno));
01327         }
01328 
01329       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01330         {
01331           saved_errno = errno;
01332           _dbus_close(fd, NULL);
01333           if (saved_errno == EADDRINUSE)
01334             {
01335               /* Depending on kernel policy, it may or may not
01336                  be neccessary to bind to both IPv4 & 6 addresses
01337                  so ignore EADDRINUSE here */
01338               tmp = tmp->ai_next;
01339               continue;
01340             }
01341           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01342                           "Failed to bind socket \"%s:%s\": %s",
01343                           host ? host : "*", port, _dbus_strerror (saved_errno));
01344           goto failed;
01345         }
01346 
01347       if (listen (fd, 30 /* backlog */) < 0)
01348         {
01349           saved_errno = errno;
01350           _dbus_close (fd, NULL);
01351           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01352                           "Failed to listen on socket \"%s:%s\": %s",
01353                           host ? host : "*", port, _dbus_strerror (saved_errno));
01354           goto failed;
01355         }
01356 
01357       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01358       if (!newlisten_fd)
01359         {
01360           saved_errno = errno;
01361           _dbus_close (fd, NULL);
01362           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01363                           "Failed to allocate file handle array: %s",
01364                           _dbus_strerror (saved_errno));
01365           goto failed;
01366         }
01367       listen_fd = newlisten_fd;
01368       listen_fd[nlisten_fd] = fd;
01369       nlisten_fd++;
01370 
01371       if (!_dbus_string_get_length(retport))
01372         {
01373           /* If the user didn't specify a port, or used 0, then
01374              the kernel chooses a port. After the first address
01375              is bound to, we need to force all remaining addresses
01376              to use the same port */
01377           if (!port || !strcmp(port, "0"))
01378             {
01379               int result;
01380               struct sockaddr_storage addr;
01381               socklen_t addrlen;
01382               char portbuf[50];
01383 
01384               addrlen = sizeof(addr);
01385               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01386 
01387               if (result == -1 ||
01388                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01389                                       portbuf, sizeof(portbuf),
01390                                       NI_NUMERICHOST)) != 0)
01391                 {
01392                   dbus_set_error (error, _dbus_error_from_errno (errno),
01393                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01394                                   host ? host : "*", port, gai_strerror(res), res);
01395                   goto failed;
01396                 }
01397               if (!_dbus_string_append(retport, portbuf))
01398                 {
01399                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01400                   goto failed;
01401                 }
01402 
01403               /* Release current address list & redo lookup */
01404               port = _dbus_string_get_const_data(retport);
01405               freeaddrinfo(ai);
01406               goto redo_lookup_with_port;
01407             }
01408           else
01409             {
01410               if (!_dbus_string_append(retport, port))
01411                 {
01412                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01413                     goto failed;
01414                 }
01415             }
01416         }
01417 
01418       tmp = tmp->ai_next;
01419     }
01420   freeaddrinfo(ai);
01421   ai = NULL;
01422 
01423   if (!nlisten_fd)
01424     {
01425       errno = EADDRINUSE;
01426       dbus_set_error (error, _dbus_error_from_errno (errno),
01427                       "Failed to bind socket \"%s:%s\": %s",
01428                       host ? host : "*", port, _dbus_strerror (errno));
01429       goto failed;
01430     }
01431 
01432   for (i = 0 ; i < nlisten_fd ; i++)
01433     {
01434       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01435         {
01436           goto failed;
01437         }
01438     }
01439 
01440   *fds_p = listen_fd;
01441 
01442   return nlisten_fd;
01443 
01444  failed:
01445   if (ai)
01446     freeaddrinfo(ai);
01447   for (i = 0 ; i < nlisten_fd ; i++)
01448     _dbus_close(listen_fd[i], NULL);
01449   dbus_free(listen_fd);
01450   return -1;
01451 }
01452 
01453 static dbus_bool_t
01454 write_credentials_byte (int             server_fd,
01455                         DBusError      *error)
01456 {
01457   int bytes_written;
01458   char buf[1] = { '\0' };
01459 #if defined(HAVE_CMSGCRED)
01460   union {
01461           struct cmsghdr hdr;
01462           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01463   } cmsg;
01464   struct iovec iov;
01465   struct msghdr msg;
01466   iov.iov_base = buf;
01467   iov.iov_len = 1;
01468 
01469   _DBUS_ZERO(msg);
01470   msg.msg_iov = &iov;
01471   msg.msg_iovlen = 1;
01472 
01473   msg.msg_control = (caddr_t) &cmsg;
01474   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01475   _DBUS_ZERO(cmsg);
01476   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01477   cmsg.hdr.cmsg_level = SOL_SOCKET;
01478   cmsg.hdr.cmsg_type = SCM_CREDS;
01479 #endif
01480 
01481   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01482 
01483  again:
01484 
01485 #if defined(HAVE_CMSGCRED)
01486   bytes_written = sendmsg (server_fd, &msg, 0
01487 #if HAVE_DECL_MSG_NOSIGNAL
01488                            |MSG_NOSIGNAL
01489 #endif
01490                            );
01491 #else
01492   bytes_written = send (server_fd, buf, 1, 0
01493 #if HAVE_DECL_MSG_NOSIGNAL
01494                         |MSG_NOSIGNAL
01495 #endif
01496                         );
01497 #endif
01498 
01499   if (bytes_written < 0 && errno == EINTR)
01500     goto again;
01501 
01502   if (bytes_written < 0)
01503     {
01504       dbus_set_error (error, _dbus_error_from_errno (errno),
01505                       "Failed to write credentials byte: %s",
01506                      _dbus_strerror (errno));
01507       return FALSE;
01508     }
01509   else if (bytes_written == 0)
01510     {
01511       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01512                       "wrote zero bytes writing credentials byte");
01513       return FALSE;
01514     }
01515   else
01516     {
01517       _dbus_assert (bytes_written == 1);
01518       _dbus_verbose ("wrote credentials byte\n");
01519       return TRUE;
01520     }
01521 }
01522 
01544 dbus_bool_t
01545 _dbus_read_credentials_socket  (int              client_fd,
01546                                 DBusCredentials *credentials,
01547                                 DBusError       *error)
01548 {
01549   struct msghdr msg;
01550   struct iovec iov;
01551   char buf;
01552   dbus_uid_t uid_read;
01553   dbus_pid_t pid_read;
01554   int bytes_read;
01555 
01556 #ifdef HAVE_CMSGCRED
01557   union {
01558     struct cmsghdr hdr;
01559     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01560   } cmsg;
01561 
01562 #elif defined(LOCAL_CREDS)
01563   struct {
01564     struct cmsghdr hdr;
01565     struct sockcred cred;
01566   } cmsg;
01567 #endif
01568 
01569   uid_read = DBUS_UID_UNSET;
01570   pid_read = DBUS_PID_UNSET;
01571 
01572   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01573 
01574   /* The POSIX spec certainly doesn't promise this, but
01575    * we need these assertions to fail as soon as we're wrong about
01576    * it so we can do the porting fixups
01577    */
01578   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01579   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01580   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01581 
01582   _dbus_credentials_clear (credentials);
01583 
01584   /* Systems supporting LOCAL_CREDS are configured to have this feature
01585    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01586    * the connection.  Therefore, the received message must carry the
01587    * credentials information without doing anything special.
01588    */
01589 
01590   iov.iov_base = &buf;
01591   iov.iov_len = 1;
01592 
01593   _DBUS_ZERO(msg);
01594   msg.msg_iov = &iov;
01595   msg.msg_iovlen = 1;
01596 
01597 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01598   _DBUS_ZERO(cmsg);
01599   msg.msg_control = (caddr_t) &cmsg;
01600   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01601 #endif
01602 
01603  again:
01604   bytes_read = recvmsg (client_fd, &msg, 0);
01605 
01606   if (bytes_read < 0)
01607     {
01608       if (errno == EINTR)
01609         goto again;
01610 
01611       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01612        * normally only call read_credentials if the socket was ready
01613        * for reading
01614        */
01615 
01616       dbus_set_error (error, _dbus_error_from_errno (errno),
01617                       "Failed to read credentials byte: %s",
01618                       _dbus_strerror (errno));
01619       return FALSE;
01620     }
01621   else if (bytes_read == 0)
01622     {
01623       /* this should not happen unless we are using recvmsg wrong,
01624        * so is essentially here for paranoia
01625        */
01626       dbus_set_error (error, DBUS_ERROR_FAILED,
01627                       "Failed to read credentials byte (zero-length read)");
01628       return FALSE;
01629     }
01630   else if (buf != '\0')
01631     {
01632       dbus_set_error (error, DBUS_ERROR_FAILED,
01633                       "Credentials byte was not nul");
01634       return FALSE;
01635     }
01636 
01637 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01638   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01639                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01640     {
01641       dbus_set_error (error, DBUS_ERROR_FAILED,
01642                       "Message from recvmsg() was not SCM_CREDS");
01643       return FALSE;
01644     }
01645 #endif
01646 
01647   _dbus_verbose ("read credentials byte\n");
01648 
01649   {
01650 #ifdef SO_PEERCRED
01651 #ifdef __OpenBSD__
01652     struct sockpeercred cr;
01653 #else
01654     struct ucred cr;
01655 #endif
01656     int cr_len = sizeof (cr);
01657 
01658     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01659         cr_len == sizeof (cr))
01660       {
01661         pid_read = cr.pid;
01662         uid_read = cr.uid;
01663       }
01664     else
01665       {
01666         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01667                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01668       }
01669 #elif defined(HAVE_CMSGCRED)
01670     struct cmsgcred *cred;
01671 
01672     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01673     pid_read = cred->cmcred_pid;
01674     uid_read = cred->cmcred_euid;
01675 #elif defined(LOCAL_CREDS)
01676     pid_read = DBUS_PID_UNSET;
01677     uid_read = cmsg.cred.sc_uid;
01678     /* Since we have already got the credentials from this socket, we can
01679      * disable its LOCAL_CREDS flag if it was ever set. */
01680     _dbus_set_local_creds (client_fd, FALSE);
01681 #elif defined(HAVE_GETPEEREID)
01682     uid_t euid;
01683     gid_t egid;
01684     if (getpeereid (client_fd, &euid, &egid) == 0)
01685       {
01686         uid_read = euid;
01687       }
01688     else
01689       {
01690         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01691       }
01692 #elif defined(HAVE_GETPEERUCRED)
01693     ucred_t * ucred = NULL;
01694     if (getpeerucred (client_fd, &ucred) == 0)
01695       {
01696         pid_read = ucred_getpid (ucred);
01697         uid_read = ucred_geteuid (ucred);
01698 #ifdef HAVE_ADT
01699         /* generate audit session data based on socket ucred */
01700         adt_session_data_t *adth = NULL;
01701         adt_export_data_t *data = NULL;
01702         size_t size = 0;
01703         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01704           {
01705             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01706           }
01707         else
01708           {
01709             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01710               {
01711                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01712               }
01713             else
01714               {
01715                 size = adt_export_session_data (adth, &data);
01716                 if (size <= 0)
01717                   {
01718                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01719                   }
01720                 else
01721                   {
01722                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01723                     free (data);
01724                   }
01725               }
01726             (void) adt_end_session (adth);
01727           }
01728 #endif /* HAVE_ADT */
01729       }
01730     else
01731       {
01732         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01733       }
01734     if (ucred != NULL)
01735       ucred_free (ucred);
01736 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01737     _dbus_verbose ("Socket credentials not supported on this OS\n");
01738 #endif
01739   }
01740 
01741   _dbus_verbose ("Credentials:"
01742                  "  pid "DBUS_PID_FORMAT
01743                  "  uid "DBUS_UID_FORMAT
01744                  "\n",
01745                  pid_read,
01746                  uid_read);
01747 
01748   if (pid_read != DBUS_PID_UNSET)
01749     {
01750       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01751         {
01752           _DBUS_SET_OOM (error);
01753           return FALSE;
01754         }
01755     }
01756 
01757   if (uid_read != DBUS_UID_UNSET)
01758     {
01759       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01760         {
01761           _DBUS_SET_OOM (error);
01762           return FALSE;
01763         }
01764     }
01765 
01766   return TRUE;
01767 }
01768 
01786 dbus_bool_t
01787 _dbus_send_credentials_socket  (int              server_fd,
01788                                 DBusError       *error)
01789 {
01790   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01791 
01792   if (write_credentials_byte (server_fd, error))
01793     return TRUE;
01794   else
01795     return FALSE;
01796 }
01797 
01807 int
01808 _dbus_accept  (int listen_fd)
01809 {
01810   int client_fd;
01811   struct sockaddr addr;
01812   socklen_t addrlen;
01813 #ifdef HAVE_ACCEPT4
01814   dbus_bool_t cloexec_done;
01815 #endif
01816 
01817   addrlen = sizeof (addr);
01818 
01819  retry:
01820 
01821 #ifdef HAVE_ACCEPT4
01822   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01823   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01824   cloexec_done = client_fd >= 0;
01825 
01826   if (client_fd < 0 && errno == ENOSYS)
01827 #endif
01828     {
01829       client_fd = accept (listen_fd, &addr, &addrlen);
01830     }
01831 
01832   if (client_fd < 0)
01833     {
01834       if (errno == EINTR)
01835         goto retry;
01836     }
01837 
01838   _dbus_verbose ("client fd %d accepted\n", client_fd);
01839 
01840 #ifdef HAVE_ACCEPT4
01841   if (!cloexec_done)
01842 #endif
01843     {
01844       _dbus_fd_set_close_on_exec(client_fd);
01845     }
01846 
01847   return client_fd;
01848 }
01849 
01858 dbus_bool_t
01859 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01860 {
01861   const char *directory;
01862   struct stat sb;
01863 
01864   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01865 
01866   directory = _dbus_string_get_const_data (dir);
01867 
01868   if (stat (directory, &sb) < 0)
01869     {
01870       dbus_set_error (error, _dbus_error_from_errno (errno),
01871                       "%s", _dbus_strerror (errno));
01872 
01873       return FALSE;
01874     }
01875 
01876   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01877       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01878     {
01879       dbus_set_error (error, DBUS_ERROR_FAILED,
01880                      "%s directory is not private to the user", directory);
01881       return FALSE;
01882     }
01883 
01884   return TRUE;
01885 }
01886 
01887 static dbus_bool_t
01888 fill_user_info_from_passwd (struct passwd *p,
01889                             DBusUserInfo  *info,
01890                             DBusError     *error)
01891 {
01892   _dbus_assert (p->pw_name != NULL);
01893   _dbus_assert (p->pw_dir != NULL);
01894 
01895   info->uid = p->pw_uid;
01896   info->primary_gid = p->pw_gid;
01897   info->username = _dbus_strdup (p->pw_name);
01898   info->homedir = _dbus_strdup (p->pw_dir);
01899 
01900   if (info->username == NULL ||
01901       info->homedir == NULL)
01902     {
01903       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01904       return FALSE;
01905     }
01906 
01907   return TRUE;
01908 }
01909 
01910 static dbus_bool_t
01911 fill_user_info (DBusUserInfo       *info,
01912                 dbus_uid_t          uid,
01913                 const DBusString   *username,
01914                 DBusError          *error)
01915 {
01916   const char *username_c;
01917 
01918   /* exactly one of username/uid provided */
01919   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01920   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01921 
01922   info->uid = DBUS_UID_UNSET;
01923   info->primary_gid = DBUS_GID_UNSET;
01924   info->group_ids = NULL;
01925   info->n_group_ids = 0;
01926   info->username = NULL;
01927   info->homedir = NULL;
01928 
01929   if (username != NULL)
01930     username_c = _dbus_string_get_const_data (username);
01931   else
01932     username_c = NULL;
01933 
01934   /* For now assuming that the getpwnam() and getpwuid() flavors
01935    * are always symmetrical, if not we have to add more configure
01936    * checks
01937    */
01938 
01939 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01940   {
01941     struct passwd *p;
01942     int result;
01943     size_t buflen;
01944     char *buf;
01945     struct passwd p_str;
01946 
01947     /* retrieve maximum needed size for buf */
01948     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01949 
01950     /* sysconf actually returns a long, but everything else expects size_t,
01951      * so just recast here.
01952      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
01953      */
01954     if ((long) buflen <= 0)
01955       buflen = 1024;
01956 
01957     result = -1;
01958     while (1)
01959       {
01960         buf = dbus_malloc (buflen);
01961         if (buf == NULL)
01962           {
01963             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01964             return FALSE;
01965           }
01966 
01967         p = NULL;
01968 #ifdef HAVE_POSIX_GETPWNAM_R
01969         if (uid != DBUS_UID_UNSET)
01970           result = getpwuid_r (uid, &p_str, buf, buflen,
01971                                &p);
01972         else
01973           result = getpwnam_r (username_c, &p_str, buf, buflen,
01974                                &p);
01975 #else
01976         if (uid != DBUS_UID_UNSET)
01977           p = getpwuid_r (uid, &p_str, buf, buflen);
01978         else
01979           p = getpwnam_r (username_c, &p_str, buf, buflen);
01980         result = 0;
01981 #endif /* !HAVE_POSIX_GETPWNAM_R */
01982         //Try a bigger buffer if ERANGE was returned
01983         if (result == ERANGE && buflen < 512 * 1024)
01984           {
01985             dbus_free (buf);
01986             buflen *= 2;
01987           }
01988         else
01989           {
01990             break;
01991           }
01992       }
01993     if (result == 0 && p == &p_str)
01994       {
01995         if (!fill_user_info_from_passwd (p, info, error))
01996           {
01997             dbus_free (buf);
01998             return FALSE;
01999           }
02000         dbus_free (buf);
02001       }
02002     else
02003       {
02004         dbus_set_error (error, _dbus_error_from_errno (errno),
02005                         "User \"%s\" unknown or no memory to allocate password entry\n",
02006                         username_c ? username_c : "???");
02007         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02008         dbus_free (buf);
02009         return FALSE;
02010       }
02011   }
02012 #else /* ! HAVE_GETPWNAM_R */
02013   {
02014     /* I guess we're screwed on thread safety here */
02015     struct passwd *p;
02016 
02017     if (uid != DBUS_UID_UNSET)
02018       p = getpwuid (uid);
02019     else
02020       p = getpwnam (username_c);
02021 
02022     if (p != NULL)
02023       {
02024         if (!fill_user_info_from_passwd (p, info, error))
02025           {
02026             return FALSE;
02027           }
02028       }
02029     else
02030       {
02031         dbus_set_error (error, _dbus_error_from_errno (errno),
02032                         "User \"%s\" unknown or no memory to allocate password entry\n",
02033                         username_c ? username_c : "???");
02034         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02035         return FALSE;
02036       }
02037   }
02038 #endif  /* ! HAVE_GETPWNAM_R */
02039 
02040   /* Fill this in so we can use it to get groups */
02041   username_c = info->username;
02042 
02043 #ifdef HAVE_GETGROUPLIST
02044   {
02045     gid_t *buf;
02046     int buf_count;
02047     int i;
02048     int initial_buf_count;
02049 
02050     initial_buf_count = 17;
02051     buf_count = initial_buf_count;
02052     buf = dbus_new (gid_t, buf_count);
02053     if (buf == NULL)
02054       {
02055         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02056         goto failed;
02057       }
02058 
02059     if (getgrouplist (username_c,
02060                       info->primary_gid,
02061                       buf, &buf_count) < 0)
02062       {
02063         gid_t *new;
02064         /* Presumed cause of negative return code: buf has insufficient
02065            entries to hold the entire group list. The Linux behavior in this
02066            case is to pass back the actual number of groups in buf_count, but
02067            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02068            So as a hack, try to help out a bit by guessing a larger
02069            number of groups, within reason.. might still fail, of course,
02070            but we can at least print a more informative message.  I looked up
02071            the "right way" to do this by downloading Apple's own source code
02072            for the "id" command, and it turns out that they use an
02073            undocumented library function getgrouplist_2 (!) which is not
02074            declared in any header in /usr/include (!!). That did not seem
02075            like the way to go here.
02076         */
02077         if (buf_count == initial_buf_count)
02078           {
02079             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02080           }
02081         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02082         if (new == NULL)
02083           {
02084             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02085             dbus_free (buf);
02086             goto failed;
02087           }
02088 
02089         buf = new;
02090 
02091         errno = 0;
02092         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02093           {
02094             if (errno == 0)
02095               {
02096                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02097                             username_c, buf_count, buf_count);
02098               }
02099             else
02100               {
02101                 dbus_set_error (error,
02102                                 _dbus_error_from_errno (errno),
02103                                 "Failed to get groups for username \"%s\" primary GID "
02104                                 DBUS_GID_FORMAT ": %s\n",
02105                                 username_c, info->primary_gid,
02106                                 _dbus_strerror (errno));
02107                 dbus_free (buf);
02108                 goto failed;
02109               }
02110           }
02111       }
02112 
02113     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02114     if (info->group_ids == NULL)
02115       {
02116         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02117         dbus_free (buf);
02118         goto failed;
02119       }
02120 
02121     for (i = 0; i < buf_count; ++i)
02122       info->group_ids[i] = buf[i];
02123 
02124     info->n_group_ids = buf_count;
02125 
02126     dbus_free (buf);
02127   }
02128 #else  /* HAVE_GETGROUPLIST */
02129   {
02130     /* We just get the one group ID */
02131     info->group_ids = dbus_new (dbus_gid_t, 1);
02132     if (info->group_ids == NULL)
02133       {
02134         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02135         goto failed;
02136       }
02137 
02138     info->n_group_ids = 1;
02139 
02140     (info->group_ids)[0] = info->primary_gid;
02141   }
02142 #endif /* HAVE_GETGROUPLIST */
02143 
02144   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02145 
02146   return TRUE;
02147 
02148  failed:
02149   _DBUS_ASSERT_ERROR_IS_SET (error);
02150   return FALSE;
02151 }
02152 
02161 dbus_bool_t
02162 _dbus_user_info_fill (DBusUserInfo     *info,
02163                       const DBusString *username,
02164                       DBusError        *error)
02165 {
02166   return fill_user_info (info, DBUS_UID_UNSET,
02167                          username, error);
02168 }
02169 
02178 dbus_bool_t
02179 _dbus_user_info_fill_uid (DBusUserInfo *info,
02180                           dbus_uid_t    uid,
02181                           DBusError    *error)
02182 {
02183   return fill_user_info (info, uid,
02184                          NULL, error);
02185 }
02186 
02194 dbus_bool_t
02195 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02196 {
02197   /* The POSIX spec certainly doesn't promise this, but
02198    * we need these assertions to fail as soon as we're wrong about
02199    * it so we can do the porting fixups
02200    */
02201   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02202   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02203   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02204 
02205   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02206     return FALSE;
02207   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02208     return FALSE;
02209 
02210   return TRUE;
02211 }
02212 
02224 dbus_bool_t
02225 _dbus_append_user_from_current_process (DBusString *str)
02226 {
02227   return _dbus_string_append_uint (str,
02228                                    _dbus_geteuid ());
02229 }
02230 
02235 dbus_pid_t
02236 _dbus_getpid (void)
02237 {
02238   return getpid ();
02239 }
02240 
02244 dbus_uid_t
02245 _dbus_getuid (void)
02246 {
02247   return getuid ();
02248 }
02249 
02253 dbus_uid_t
02254 _dbus_geteuid (void)
02255 {
02256   return geteuid ();
02257 }
02258 
02265 unsigned long
02266 _dbus_pid_for_log (void)
02267 {
02268   return getpid ();
02269 }
02270 
02278 dbus_bool_t
02279 _dbus_parse_uid (const DBusString      *uid_str,
02280                  dbus_uid_t            *uid)
02281 {
02282   int end;
02283   long val;
02284 
02285   if (_dbus_string_get_length (uid_str) == 0)
02286     {
02287       _dbus_verbose ("UID string was zero length\n");
02288       return FALSE;
02289     }
02290 
02291   val = -1;
02292   end = 0;
02293   if (!_dbus_string_parse_int (uid_str, 0, &val,
02294                                &end))
02295     {
02296       _dbus_verbose ("could not parse string as a UID\n");
02297       return FALSE;
02298     }
02299 
02300   if (end != _dbus_string_get_length (uid_str))
02301     {
02302       _dbus_verbose ("string contained trailing stuff after UID\n");
02303       return FALSE;
02304     }
02305 
02306   *uid = val;
02307 
02308   return TRUE;
02309 }
02310 
02311 #if !DBUS_USE_SYNC
02312 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02313 #endif
02314 
02321 dbus_int32_t
02322 _dbus_atomic_inc (DBusAtomic *atomic)
02323 {
02324 #if DBUS_USE_SYNC
02325   return __sync_add_and_fetch(&atomic->value, 1)-1;
02326 #else
02327   dbus_int32_t res;
02328   _DBUS_LOCK (atomic);
02329   res = atomic->value;
02330   atomic->value += 1;
02331   _DBUS_UNLOCK (atomic);
02332   return res;
02333 #endif
02334 }
02335 
02342 dbus_int32_t
02343 _dbus_atomic_dec (DBusAtomic *atomic)
02344 {
02345 #if DBUS_USE_SYNC
02346   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02347 #else
02348   dbus_int32_t res;
02349 
02350   _DBUS_LOCK (atomic);
02351   res = atomic->value;
02352   atomic->value -= 1;
02353   _DBUS_UNLOCK (atomic);
02354   return res;
02355 #endif
02356 }
02357 
02365 dbus_int32_t
02366 _dbus_atomic_get (DBusAtomic *atomic)
02367 {
02368 #if DBUS_USE_SYNC
02369   __sync_synchronize ();
02370   return atomic->value;
02371 #else
02372   dbus_int32_t res;
02373 
02374   _DBUS_LOCK (atomic);
02375   res = atomic->value;
02376   _DBUS_UNLOCK (atomic);
02377   return res;
02378 #endif
02379 }
02380 
02381 #ifdef DBUS_BUILD_TESTS
02382 
02385 dbus_gid_t
02386 _dbus_getgid (void)
02387 {
02388   return getgid ();
02389 }
02390 #endif
02391 
02400 int
02401 _dbus_poll (DBusPollFD *fds,
02402             int         n_fds,
02403             int         timeout_milliseconds)
02404 {
02405 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02406   /* This big thing is a constant expression and should get optimized
02407    * out of existence. So it's more robust than a configure check at
02408    * no cost.
02409    */
02410   if (_DBUS_POLLIN == POLLIN &&
02411       _DBUS_POLLPRI == POLLPRI &&
02412       _DBUS_POLLOUT == POLLOUT &&
02413       _DBUS_POLLERR == POLLERR &&
02414       _DBUS_POLLHUP == POLLHUP &&
02415       _DBUS_POLLNVAL == POLLNVAL &&
02416       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02417       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02418       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02419       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02420       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02421       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02422       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02423     {
02424       return poll ((struct pollfd*) fds,
02425                    n_fds,
02426                    timeout_milliseconds);
02427     }
02428   else
02429     {
02430       /* We have to convert the DBusPollFD to an array of
02431        * struct pollfd, poll, and convert back.
02432        */
02433       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02434       return -1;
02435     }
02436 #else /* ! HAVE_POLL */
02437 
02438   fd_set read_set, write_set, err_set;
02439   int max_fd = 0;
02440   int i;
02441   struct timeval tv;
02442   int ready;
02443 
02444   FD_ZERO (&read_set);
02445   FD_ZERO (&write_set);
02446   FD_ZERO (&err_set);
02447 
02448   for (i = 0; i < n_fds; i++)
02449     {
02450       DBusPollFD *fdp = &fds[i];
02451 
02452       if (fdp->events & _DBUS_POLLIN)
02453         FD_SET (fdp->fd, &read_set);
02454 
02455       if (fdp->events & _DBUS_POLLOUT)
02456         FD_SET (fdp->fd, &write_set);
02457 
02458       FD_SET (fdp->fd, &err_set);
02459 
02460       max_fd = MAX (max_fd, fdp->fd);
02461     }
02462 
02463   tv.tv_sec = timeout_milliseconds / 1000;
02464   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02465 
02466   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02467                   timeout_milliseconds < 0 ? NULL : &tv);
02468 
02469   if (ready > 0)
02470     {
02471       for (i = 0; i < n_fds; i++)
02472         {
02473           DBusPollFD *fdp = &fds[i];
02474 
02475           fdp->revents = 0;
02476 
02477           if (FD_ISSET (fdp->fd, &read_set))
02478             fdp->revents |= _DBUS_POLLIN;
02479 
02480           if (FD_ISSET (fdp->fd, &write_set))
02481             fdp->revents |= _DBUS_POLLOUT;
02482 
02483           if (FD_ISSET (fdp->fd, &err_set))
02484             fdp->revents |= _DBUS_POLLERR;
02485         }
02486     }
02487 
02488   return ready;
02489 #endif
02490 }
02491 
02499 void
02500 _dbus_get_current_time (long *tv_sec,
02501                         long *tv_usec)
02502 {
02503   struct timeval t;
02504 
02505 #ifdef HAVE_MONOTONIC_CLOCK
02506   struct timespec ts;
02507   clock_gettime (CLOCK_MONOTONIC, &ts);
02508 
02509   if (tv_sec)
02510     *tv_sec = ts.tv_sec;
02511   if (tv_usec)
02512     *tv_usec = ts.tv_nsec / 1000;
02513 #else
02514   gettimeofday (&t, NULL);
02515 
02516   if (tv_sec)
02517     *tv_sec = t.tv_sec;
02518   if (tv_usec)
02519     *tv_usec = t.tv_usec;
02520 #endif
02521 }
02522 
02531 dbus_bool_t
02532 _dbus_create_directory (const DBusString *filename,
02533                         DBusError        *error)
02534 {
02535   const char *filename_c;
02536 
02537   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02538 
02539   filename_c = _dbus_string_get_const_data (filename);
02540 
02541   if (mkdir (filename_c, 0700) < 0)
02542     {
02543       if (errno == EEXIST)
02544         return TRUE;
02545 
02546       dbus_set_error (error, DBUS_ERROR_FAILED,
02547                       "Failed to create directory %s: %s\n",
02548                       filename_c, _dbus_strerror (errno));
02549       return FALSE;
02550     }
02551   else
02552     return TRUE;
02553 }
02554 
02565 dbus_bool_t
02566 _dbus_concat_dir_and_file (DBusString       *dir,
02567                            const DBusString *next_component)
02568 {
02569   dbus_bool_t dir_ends_in_slash;
02570   dbus_bool_t file_starts_with_slash;
02571 
02572   if (_dbus_string_get_length (dir) == 0 ||
02573       _dbus_string_get_length (next_component) == 0)
02574     return TRUE;
02575 
02576   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02577                                                     _dbus_string_get_length (dir) - 1);
02578 
02579   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02580 
02581   if (dir_ends_in_slash && file_starts_with_slash)
02582     {
02583       _dbus_string_shorten (dir, 1);
02584     }
02585   else if (!(dir_ends_in_slash || file_starts_with_slash))
02586     {
02587       if (!_dbus_string_append_byte (dir, '/'))
02588         return FALSE;
02589     }
02590 
02591   return _dbus_string_copy (next_component, 0, dir,
02592                             _dbus_string_get_length (dir));
02593 }
02594 
02596 #define NANOSECONDS_PER_SECOND       1000000000
02597 
02598 #define MICROSECONDS_PER_SECOND      1000000
02599 
02600 #define MILLISECONDS_PER_SECOND      1000
02601 
02602 #define NANOSECONDS_PER_MILLISECOND  1000000
02603 
02604 #define MICROSECONDS_PER_MILLISECOND 1000
02605 
02610 void
02611 _dbus_sleep_milliseconds (int milliseconds)
02612 {
02613 #ifdef HAVE_NANOSLEEP
02614   struct timespec req;
02615   struct timespec rem;
02616 
02617   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02618   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02619   rem.tv_sec = 0;
02620   rem.tv_nsec = 0;
02621 
02622   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02623     req = rem;
02624 #elif defined (HAVE_USLEEP)
02625   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02626 #else /* ! HAVE_USLEEP */
02627   sleep (MAX (milliseconds / 1000, 1));
02628 #endif
02629 }
02630 
02631 static dbus_bool_t
02632 _dbus_generate_pseudorandom_bytes (DBusString *str,
02633                                    int         n_bytes)
02634 {
02635   int old_len;
02636   char *p;
02637 
02638   old_len = _dbus_string_get_length (str);
02639 
02640   if (!_dbus_string_lengthen (str, n_bytes))
02641     return FALSE;
02642 
02643   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02644 
02645   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02646 
02647   return TRUE;
02648 }
02649 
02658 dbus_bool_t
02659 _dbus_generate_random_bytes (DBusString *str,
02660                              int         n_bytes)
02661 {
02662   int old_len;
02663   int fd;
02664 
02665   /* FALSE return means "no memory", if it could
02666    * mean something else then we'd need to return
02667    * a DBusError. So we always fall back to pseudorandom
02668    * if the I/O fails.
02669    */
02670 
02671   old_len = _dbus_string_get_length (str);
02672   fd = -1;
02673 
02674   /* note, urandom on linux will fall back to pseudorandom */
02675   fd = open ("/dev/urandom", O_RDONLY);
02676   if (fd < 0)
02677     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02678 
02679   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02680 
02681   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02682     {
02683       _dbus_close (fd, NULL);
02684       _dbus_string_set_length (str, old_len);
02685       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02686     }
02687 
02688   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02689                  n_bytes);
02690 
02691   _dbus_close (fd, NULL);
02692 
02693   return TRUE;
02694 }
02695 
02701 void
02702 _dbus_exit (int code)
02703 {
02704   _exit (code);
02705 }
02706 
02715 const char*
02716 _dbus_strerror (int error_number)
02717 {
02718   const char *msg;
02719 
02720   msg = strerror (error_number);
02721   if (msg == NULL)
02722     msg = "unknown";
02723 
02724   return msg;
02725 }
02726 
02730 void
02731 _dbus_disable_sigpipe (void)
02732 {
02733   signal (SIGPIPE, SIG_IGN);
02734 }
02735 
02743 void
02744 _dbus_fd_set_close_on_exec (intptr_t fd)
02745 {
02746   int val;
02747 
02748   val = fcntl (fd, F_GETFD, 0);
02749 
02750   if (val < 0)
02751     return;
02752 
02753   val |= FD_CLOEXEC;
02754 
02755   fcntl (fd, F_SETFD, val);
02756 }
02757 
02765 dbus_bool_t
02766 _dbus_close (int        fd,
02767              DBusError *error)
02768 {
02769   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02770 
02771  again:
02772   if (close (fd) < 0)
02773     {
02774       if (errno == EINTR)
02775         goto again;
02776 
02777       dbus_set_error (error, _dbus_error_from_errno (errno),
02778                       "Could not close fd %d", fd);
02779       return FALSE;
02780     }
02781 
02782   return TRUE;
02783 }
02784 
02792 int
02793 _dbus_dup(int        fd,
02794           DBusError *error)
02795 {
02796   int new_fd;
02797 
02798 #ifdef F_DUPFD_CLOEXEC
02799   dbus_bool_t cloexec_done;
02800 
02801   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02802   cloexec_done = new_fd >= 0;
02803 
02804   if (new_fd < 0 && errno == EINVAL)
02805 #endif
02806     {
02807       new_fd = fcntl(fd, F_DUPFD, 3);
02808     }
02809 
02810   if (new_fd < 0) {
02811 
02812     dbus_set_error (error, _dbus_error_from_errno (errno),
02813                     "Could not duplicate fd %d", fd);
02814     return -1;
02815   }
02816 
02817 #ifdef F_DUPFD_CLOEXEC
02818   if (!cloexec_done)
02819 #endif
02820     {
02821       _dbus_fd_set_close_on_exec(new_fd);
02822     }
02823 
02824   return new_fd;
02825 }
02826 
02834 dbus_bool_t
02835 _dbus_set_fd_nonblocking (int             fd,
02836                           DBusError      *error)
02837 {
02838   int val;
02839 
02840   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02841 
02842   val = fcntl (fd, F_GETFL, 0);
02843   if (val < 0)
02844     {
02845       dbus_set_error (error, _dbus_error_from_errno (errno),
02846                       "Failed to get flags from file descriptor %d: %s",
02847                       fd, _dbus_strerror (errno));
02848       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02849                      _dbus_strerror (errno));
02850       return FALSE;
02851     }
02852 
02853   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02854     {
02855       dbus_set_error (error, _dbus_error_from_errno (errno),
02856                       "Failed to set nonblocking flag of file descriptor %d: %s",
02857                       fd, _dbus_strerror (errno));
02858       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02859                      fd, _dbus_strerror (errno));
02860 
02861       return FALSE;
02862     }
02863 
02864   return TRUE;
02865 }
02866 
02872 void
02873 _dbus_print_backtrace (void)
02874 {
02875 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02876   void *bt[500];
02877   int bt_size;
02878   int i;
02879   char **syms;
02880 
02881   bt_size = backtrace (bt, 500);
02882 
02883   syms = backtrace_symbols (bt, bt_size);
02884 
02885   i = 0;
02886   while (i < bt_size)
02887     {
02888       /* don't use dbus_warn since it can _dbus_abort() */
02889       fprintf (stderr, "  %s\n", syms[i]);
02890       ++i;
02891     }
02892   fflush (stderr);
02893 
02894   free (syms);
02895 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02896   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02897 #else
02898   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02899 #endif
02900 }
02901 
02919 dbus_bool_t
02920 _dbus_full_duplex_pipe (int        *fd1,
02921                         int        *fd2,
02922                         dbus_bool_t blocking,
02923                         DBusError  *error)
02924 {
02925 #ifdef HAVE_SOCKETPAIR
02926   int fds[2];
02927   int retval;
02928 
02929 #ifdef SOCK_CLOEXEC
02930   dbus_bool_t cloexec_done;
02931 
02932   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02933   cloexec_done = retval >= 0;
02934 
02935   if (retval < 0 && errno == EINVAL)
02936 #endif
02937     {
02938       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02939     }
02940 
02941   if (retval < 0)
02942     {
02943       dbus_set_error (error, _dbus_error_from_errno (errno),
02944                       "Could not create full-duplex pipe");
02945       return FALSE;
02946     }
02947 
02948   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02949 
02950 #ifdef SOCK_CLOEXEC
02951   if (!cloexec_done)
02952 #endif
02953     {
02954       _dbus_fd_set_close_on_exec (fds[0]);
02955       _dbus_fd_set_close_on_exec (fds[1]);
02956     }
02957 
02958   if (!blocking &&
02959       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02960        !_dbus_set_fd_nonblocking (fds[1], NULL)))
02961     {
02962       dbus_set_error (error, _dbus_error_from_errno (errno),
02963                       "Could not set full-duplex pipe nonblocking");
02964 
02965       _dbus_close (fds[0], NULL);
02966       _dbus_close (fds[1], NULL);
02967 
02968       return FALSE;
02969     }
02970 
02971   *fd1 = fds[0];
02972   *fd2 = fds[1];
02973 
02974   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02975                  *fd1, *fd2);
02976 
02977   return TRUE;
02978 #else
02979   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02980   dbus_set_error (error, DBUS_ERROR_FAILED,
02981                   "_dbus_full_duplex_pipe() not implemented on this OS");
02982   return FALSE;
02983 #endif
02984 }
02985 
02994 int
02995 _dbus_printf_string_upper_bound (const char *format,
02996                                  va_list     args)
02997 {
02998   char c;
02999   return vsnprintf (&c, 1, format, args);
03000 }
03001 
03008 const char*
03009 _dbus_get_tmpdir(void)
03010 {
03011   static const char* tmpdir = NULL;
03012 
03013   if (tmpdir == NULL)
03014     {
03015       /* TMPDIR is what glibc uses, then
03016        * glibc falls back to the P_tmpdir macro which
03017        * just expands to "/tmp"
03018        */
03019       if (tmpdir == NULL)
03020         tmpdir = getenv("TMPDIR");
03021 
03022       /* These two env variables are probably
03023        * broken, but maybe some OS uses them?
03024        */
03025       if (tmpdir == NULL)
03026         tmpdir = getenv("TMP");
03027       if (tmpdir == NULL)
03028         tmpdir = getenv("TEMP");
03029 
03030       /* And this is the sane fallback. */
03031       if (tmpdir == NULL)
03032         tmpdir = "/tmp";
03033     }
03034 
03035   _dbus_assert(tmpdir != NULL);
03036 
03037   return tmpdir;
03038 }
03039 
03059 static dbus_bool_t
03060 _read_subprocess_line_argv (const char *progpath,
03061                             dbus_bool_t path_fallback,
03062                             char       * const *argv,
03063                             DBusString *result,
03064                             DBusError  *error)
03065 {
03066   int result_pipe[2] = { -1, -1 };
03067   int errors_pipe[2] = { -1, -1 };
03068   pid_t pid;
03069   int ret;
03070   int status;
03071   int orig_len;
03072   int i;
03073 
03074   dbus_bool_t retval;
03075   sigset_t new_set, old_set;
03076 
03077   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03078   retval = FALSE;
03079 
03080   /* We need to block any existing handlers for SIGCHLD temporarily; they
03081    * will cause waitpid() below to fail.
03082    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03083    */
03084   sigemptyset (&new_set);
03085   sigaddset (&new_set, SIGCHLD);
03086   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03087 
03088   orig_len = _dbus_string_get_length (result);
03089 
03090 #define READ_END        0
03091 #define WRITE_END       1
03092   if (pipe (result_pipe) < 0)
03093     {
03094       dbus_set_error (error, _dbus_error_from_errno (errno),
03095                       "Failed to create a pipe to call %s: %s",
03096                       progpath, _dbus_strerror (errno));
03097       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03098                      progpath, _dbus_strerror (errno));
03099       goto out;
03100     }
03101   if (pipe (errors_pipe) < 0)
03102     {
03103       dbus_set_error (error, _dbus_error_from_errno (errno),
03104                       "Failed to create a pipe to call %s: %s",
03105                       progpath, _dbus_strerror (errno));
03106       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03107                      progpath, _dbus_strerror (errno));
03108       goto out;
03109     }
03110 
03111   pid = fork ();
03112   if (pid < 0)
03113     {
03114       dbus_set_error (error, _dbus_error_from_errno (errno),
03115                       "Failed to fork() to call %s: %s",
03116                       progpath, _dbus_strerror (errno));
03117       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03118                      progpath, _dbus_strerror (errno));
03119       goto out;
03120     }
03121 
03122   if (pid == 0)
03123     {
03124       /* child process */
03125       int maxfds;
03126       int fd;
03127 
03128       fd = open ("/dev/null", O_RDWR);
03129       if (fd == -1)
03130         /* huh?! can't open /dev/null? */
03131         _exit (1);
03132 
03133       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03134 
03135       /* set-up stdXXX */
03136       close (result_pipe[READ_END]);
03137       close (errors_pipe[READ_END]);
03138       close (0);                /* close stdin */
03139       close (1);                /* close stdout */
03140       close (2);                /* close stderr */
03141 
03142       if (dup2 (fd, 0) == -1)
03143         _exit (1);
03144       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03145         _exit (1);
03146       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03147         _exit (1);
03148 
03149       maxfds = sysconf (_SC_OPEN_MAX);
03150       /* Pick something reasonable if for some reason sysconf
03151        * says unlimited.
03152        */
03153       if (maxfds < 0)
03154         maxfds = 1024;
03155       /* close all inherited fds */
03156       for (i = 3; i < maxfds; i++)
03157         close (i);
03158 
03159       sigprocmask (SIG_SETMASK, &old_set, NULL);
03160 
03161       /* If it looks fully-qualified, try execv first */
03162       if (progpath[0] == '/')
03163         {
03164           execv (progpath, argv);
03165           /* Ok, that failed.  Now if path_fallback is given, let's
03166            * try unqualified.  This is mostly a hack to work
03167            * around systems which ship dbus-launch in /usr/bin
03168            * but everything else in /bin (because dbus-launch
03169            * depends on X11).
03170            */
03171           if (path_fallback)
03172             /* We must have a slash, because we checked above */
03173             execvp (strrchr (progpath, '/')+1, argv);
03174         }
03175       else
03176         execvp (progpath, argv);
03177 
03178       /* still nothing, we failed */
03179       _exit (1);
03180     }
03181 
03182   /* parent process */
03183   close (result_pipe[WRITE_END]);
03184   close (errors_pipe[WRITE_END]);
03185   result_pipe[WRITE_END] = -1;
03186   errors_pipe[WRITE_END] = -1;
03187 
03188   ret = 0;
03189   do
03190     {
03191       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03192     }
03193   while (ret > 0);
03194 
03195   /* reap the child process to avoid it lingering as zombie */
03196   do
03197     {
03198       ret = waitpid (pid, &status, 0);
03199     }
03200   while (ret == -1 && errno == EINTR);
03201 
03202   /* We succeeded if the process exited with status 0 and
03203      anything was read */
03204   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03205     {
03206       /* The process ended with error */
03207       DBusString error_message;
03208       if (!_dbus_string_init (&error_message))
03209         {
03210           _DBUS_SET_OOM (error);
03211           goto out;
03212         }
03213 
03214       ret = 0;
03215       do
03216         {
03217           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03218         }
03219       while (ret > 0);
03220 
03221       _dbus_string_set_length (result, orig_len);
03222       if (_dbus_string_get_length (&error_message) > 0)
03223         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03224                         "%s terminated abnormally with the following error: %s",
03225                         progpath, _dbus_string_get_data (&error_message));
03226       else
03227         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03228                         "%s terminated abnormally without any error message",
03229                         progpath);
03230       goto out;
03231     }
03232 
03233   retval = TRUE;
03234 
03235  out:
03236   sigprocmask (SIG_SETMASK, &old_set, NULL);
03237 
03238   if (retval)
03239     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03240   else
03241     _DBUS_ASSERT_ERROR_IS_SET (error);
03242 
03243   if (result_pipe[0] != -1)
03244     close (result_pipe[0]);
03245   if (result_pipe[1] != -1)
03246     close (result_pipe[1]);
03247   if (errors_pipe[0] != -1)
03248     close (errors_pipe[0]);
03249   if (errors_pipe[1] != -1)
03250     close (errors_pipe[1]);
03251 
03252   return retval;
03253 }
03254 
03266 dbus_bool_t
03267 _dbus_get_autolaunch_address (const char *scope,
03268                               DBusString *address,
03269                               DBusError  *error)
03270 {
03271 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03272   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03273    * but that's done elsewhere, and if it worked, this function wouldn't
03274    * be called.) */
03275   const char *display;
03276   static char *argv[6];
03277   int i;
03278   DBusString uuid;
03279   dbus_bool_t retval;
03280 
03281   if (_dbus_check_setuid ())
03282     {
03283       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03284                             "Unable to autolaunch when setuid");
03285       return FALSE;
03286     }
03287 
03288   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03289   retval = FALSE;
03290 
03291   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03292    * dbus-launch-x11 is just going to fail. Rather than trying to
03293    * run it, we might as well bail out early with a nice error. */
03294   display = _dbus_getenv ("DISPLAY");
03295 
03296   if (display == NULL || display[0] == '\0')
03297     {
03298       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03299           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03300       return FALSE;
03301     }
03302 
03303   if (!_dbus_string_init (&uuid))
03304     {
03305       _DBUS_SET_OOM (error);
03306       return FALSE;
03307     }
03308 
03309   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03310     {
03311       _DBUS_SET_OOM (error);
03312       goto out;
03313     }
03314 
03315   i = 0;
03316   argv[i] = "dbus-launch";
03317   ++i;
03318   argv[i] = "--autolaunch";
03319   ++i;
03320   argv[i] = _dbus_string_get_data (&uuid);
03321   ++i;
03322   argv[i] = "--binary-syntax";
03323   ++i;
03324   argv[i] = "--close-stderr";
03325   ++i;
03326   argv[i] = NULL;
03327   ++i;
03328 
03329   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03330 
03331   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03332                                        TRUE,
03333                                        argv, address, error);
03334 
03335  out:
03336   _dbus_string_free (&uuid);
03337   return retval;
03338 #else
03339   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03340       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03341       "set your DBUS_SESSION_BUS_ADDRESS instead");
03342   return FALSE;
03343 #endif
03344 }
03345 
03364 dbus_bool_t
03365 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03366                                dbus_bool_t create_if_not_found,
03367                                DBusError  *error)
03368 {
03369   DBusString filename;
03370   dbus_bool_t b;
03371 
03372   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03373 
03374   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03375   if (b)
03376     return TRUE;
03377 
03378   dbus_error_free (error);
03379 
03380   /* Fallback to the system machine ID */
03381   _dbus_string_init_const (&filename, "/etc/machine-id");
03382   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03383 }
03384 
03385 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03386 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03387 
03394 dbus_bool_t
03395 _dbus_lookup_launchd_socket (DBusString *socket_path,
03396                              const char *launchd_env_var,
03397                              DBusError  *error)
03398 {
03399 #ifdef DBUS_ENABLE_LAUNCHD
03400   char *argv[4];
03401   int i;
03402 
03403   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03404 
03405   if (_dbus_check_setuid ())
03406     {
03407       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03408                             "Unable to find launchd socket when setuid");
03409       return FALSE;
03410     }
03411 
03412   i = 0;
03413   argv[i] = "launchctl";
03414   ++i;
03415   argv[i] = "getenv";
03416   ++i;
03417   argv[i] = (char*)launchd_env_var;
03418   ++i;
03419   argv[i] = NULL;
03420   ++i;
03421 
03422   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03423 
03424   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03425     {
03426       return FALSE;
03427     }
03428 
03429   /* no error, but no result either */
03430   if (_dbus_string_get_length(socket_path) == 0)
03431     {
03432       return FALSE;
03433     }
03434 
03435   /* strip the carriage-return */
03436   _dbus_string_shorten(socket_path, 1);
03437   return TRUE;
03438 #else /* DBUS_ENABLE_LAUNCHD */
03439   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03440                 "can't lookup socket from launchd; launchd support not compiled in");
03441   return FALSE;
03442 #endif
03443 }
03444 
03445 static dbus_bool_t
03446 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03447 {
03448 #ifdef DBUS_ENABLE_LAUNCHD
03449   dbus_bool_t valid_socket;
03450   DBusString socket_path;
03451 
03452   if (_dbus_check_setuid ())
03453     {
03454       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03455                             "Unable to find launchd socket when setuid");
03456       return FALSE;
03457     }
03458 
03459   if (!_dbus_string_init (&socket_path))
03460     {
03461       _DBUS_SET_OOM (error);
03462       return FALSE;
03463     }
03464 
03465   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03466 
03467   if (dbus_error_is_set(error))
03468     {
03469       _dbus_string_free(&socket_path);
03470       return FALSE;
03471     }
03472 
03473   if (!valid_socket)
03474     {
03475       dbus_set_error(error, "no socket path",
03476                 "launchd did not provide a socket path, "
03477                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03478       _dbus_string_free(&socket_path);
03479       return FALSE;
03480     }
03481   if (!_dbus_string_append (address, "unix:path="))
03482     {
03483       _DBUS_SET_OOM (error);
03484       _dbus_string_free(&socket_path);
03485       return FALSE;
03486     }
03487   if (!_dbus_string_copy (&socket_path, 0, address,
03488                           _dbus_string_get_length (address)))
03489     {
03490       _DBUS_SET_OOM (error);
03491       _dbus_string_free(&socket_path);
03492       return FALSE;
03493     }
03494 
03495   _dbus_string_free(&socket_path);
03496   return TRUE;
03497 #else
03498   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03499                 "can't lookup session address from launchd; launchd support not compiled in");
03500   return FALSE;
03501 #endif
03502 }
03503 
03523 dbus_bool_t
03524 _dbus_lookup_session_address (dbus_bool_t *supported,
03525                               DBusString  *address,
03526                               DBusError   *error)
03527 {
03528 #ifdef DBUS_ENABLE_LAUNCHD
03529   *supported = TRUE;
03530   return _dbus_lookup_session_address_launchd (address, error);
03531 #else
03532   /* On non-Mac Unix platforms, if the session address isn't already
03533    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03534    * fall back to the autolaunch: global default; see
03535    * init_session_address in dbus/dbus-bus.c. */
03536   *supported = FALSE;
03537   return TRUE;
03538 #endif
03539 }
03540 
03558 dbus_bool_t
03559 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03560 {
03561   const char *xdg_data_home;
03562   const char *xdg_data_dirs;
03563   DBusString servicedir_path;
03564 
03565   if (!_dbus_string_init (&servicedir_path))
03566     return FALSE;
03567 
03568   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03569   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03570 
03571   if (xdg_data_home != NULL)
03572     {
03573       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03574         goto oom;
03575     }
03576   else
03577     {
03578       const DBusString *homedir;
03579       DBusString local_share;
03580 
03581       if (!_dbus_homedir_from_current_process (&homedir))
03582         goto oom;
03583 
03584       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03585         goto oom;
03586 
03587       _dbus_string_init_const (&local_share, "/.local/share");
03588       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03589         goto oom;
03590     }
03591 
03592   if (!_dbus_string_append (&servicedir_path, ":"))
03593     goto oom;
03594 
03595   if (xdg_data_dirs != NULL)
03596     {
03597       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03598         goto oom;
03599 
03600       if (!_dbus_string_append (&servicedir_path, ":"))
03601         goto oom;
03602     }
03603   else
03604     {
03605       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03606         goto oom;
03607     }
03608 
03609   /*
03610    * add configured datadir to defaults
03611    * this may be the same as an xdg dir
03612    * however the config parser should take
03613    * care of duplicates
03614    */
03615   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03616     goto oom;
03617 
03618   if (!_dbus_split_paths_and_append (&servicedir_path,
03619                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03620                                      dirs))
03621     goto oom;
03622 
03623   _dbus_string_free (&servicedir_path);
03624   return TRUE;
03625 
03626  oom:
03627   _dbus_string_free (&servicedir_path);
03628   return FALSE;
03629 }
03630 
03631 
03650 dbus_bool_t
03651 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03652 {
03653   const char *xdg_data_dirs;
03654   DBusString servicedir_path;
03655 
03656   if (!_dbus_string_init (&servicedir_path))
03657     return FALSE;
03658 
03659   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03660 
03661   if (xdg_data_dirs != NULL)
03662     {
03663       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03664         goto oom;
03665 
03666       if (!_dbus_string_append (&servicedir_path, ":"))
03667         goto oom;
03668     }
03669   else
03670     {
03671       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03672         goto oom;
03673     }
03674 
03675   /*
03676    * Add configured datadir to defaults. This may be the same as one
03677    * of the XDG directories. However, the config parser should take
03678    * care of the duplicates.
03679    *
03680    * Also, append /lib as counterpart of /usr/share on the root
03681    * directory (the root directory does not know /share), in order to
03682    * facilitate early boot system bus activation where /usr might not
03683    * be available.
03684    */
03685   if (!_dbus_string_append (&servicedir_path,
03686                             DBUS_DATADIR":"
03687                             "/lib:"))
03688         goto oom;
03689 
03690   if (!_dbus_split_paths_and_append (&servicedir_path,
03691                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03692                                      dirs))
03693     goto oom;
03694 
03695   _dbus_string_free (&servicedir_path);
03696   return TRUE;
03697 
03698  oom:
03699   _dbus_string_free (&servicedir_path);
03700   return FALSE;
03701 }
03702 
03711 dbus_bool_t
03712 _dbus_append_system_config_file (DBusString *str)
03713 {
03714   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03715 }
03716 
03723 dbus_bool_t
03724 _dbus_append_session_config_file (DBusString *str)
03725 {
03726   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03727 }
03728 
03736 void
03737 _dbus_flush_caches (void)
03738 {
03739   _dbus_user_database_flush_system ();
03740 }
03741 
03755 dbus_bool_t
03756 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03757                                                 DBusCredentials *credentials)
03758 {
03759   DBusString homedir;
03760   DBusString dotdir;
03761   dbus_uid_t uid;
03762 
03763   _dbus_assert (credentials != NULL);
03764   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03765 
03766   if (!_dbus_string_init (&homedir))
03767     return FALSE;
03768 
03769   uid = _dbus_credentials_get_unix_uid (credentials);
03770   _dbus_assert (uid != DBUS_UID_UNSET);
03771 
03772   if (!_dbus_homedir_from_uid (uid, &homedir))
03773     goto failed;
03774 
03775 #ifdef DBUS_BUILD_TESTS
03776   {
03777     const char *override;
03778 
03779     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03780     if (override != NULL && *override != '\0')
03781       {
03782         _dbus_string_set_length (&homedir, 0);
03783         if (!_dbus_string_append (&homedir, override))
03784           goto failed;
03785 
03786         _dbus_verbose ("Using fake homedir for testing: %s\n",
03787                        _dbus_string_get_const_data (&homedir));
03788       }
03789     else
03790       {
03791         static dbus_bool_t already_warned = FALSE;
03792         if (!already_warned)
03793           {
03794             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03795             already_warned = TRUE;
03796           }
03797       }
03798   }
03799 #endif
03800 
03801   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03802   if (!_dbus_concat_dir_and_file (&homedir,
03803                                   &dotdir))
03804     goto failed;
03805 
03806   if (!_dbus_string_copy (&homedir, 0,
03807                           directory, _dbus_string_get_length (directory))) {
03808     goto failed;
03809   }
03810 
03811   _dbus_string_free (&homedir);
03812   return TRUE;
03813 
03814  failed:
03815   _dbus_string_free (&homedir);
03816   return FALSE;
03817 }
03818 
03819 //PENDING(kdab) docs
03820 dbus_bool_t
03821 _dbus_daemon_publish_session_bus_address (const char* addr,
03822                                           const char *scope)
03823 {
03824   return TRUE;
03825 }
03826 
03827 //PENDING(kdab) docs
03828 void
03829 _dbus_daemon_unpublish_session_bus_address (void)
03830 {
03831 
03832 }
03833 
03840 dbus_bool_t
03841 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03842 {
03843   return errno == EAGAIN || errno == EWOULDBLOCK;
03844 }
03845 
03853 dbus_bool_t
03854 _dbus_delete_directory (const DBusString *filename,
03855                         DBusError        *error)
03856 {
03857   const char *filename_c;
03858 
03859   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03860 
03861   filename_c = _dbus_string_get_const_data (filename);
03862 
03863   if (rmdir (filename_c) != 0)
03864     {
03865       dbus_set_error (error, DBUS_ERROR_FAILED,
03866                       "Failed to remove directory %s: %s\n",
03867                       filename_c, _dbus_strerror (errno));
03868       return FALSE;
03869     }
03870 
03871   return TRUE;
03872 }
03873 
03881 dbus_bool_t
03882 _dbus_socket_can_pass_unix_fd(int fd) {
03883 
03884 #ifdef SCM_RIGHTS
03885   union {
03886     struct sockaddr sa;
03887     struct sockaddr_storage storage;
03888     struct sockaddr_un un;
03889   } sa_buf;
03890 
03891   socklen_t sa_len = sizeof(sa_buf);
03892 
03893   _DBUS_ZERO(sa_buf);
03894 
03895   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03896     return FALSE;
03897 
03898   return sa_buf.sa.sa_family == AF_UNIX;
03899 
03900 #else
03901   return FALSE;
03902 
03903 #endif
03904 }
03905 
03906 
03907 /*
03908  * replaces the term DBUS_PREFIX in configure_time_path by the
03909  * current dbus installation directory. On unix this function is a noop
03910  *
03911  * @param configure_time_path
03912  * @return real path
03913  */
03914 const char *
03915 _dbus_replace_install_prefix (const char *configure_time_path)
03916 {
03917   return configure_time_path;
03918 }
03919 
03929 dbus_bool_t
03930 _dbus_check_setuid (void)
03931 {
03932   /* TODO: get __libc_enable_secure exported from glibc.
03933    * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
03934    */
03935 #if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
03936   {
03937     /* See glibc/include/unistd.h */
03938     extern int __libc_enable_secure;
03939     return __libc_enable_secure;
03940   }
03941 #elif defined(HAVE_ISSETUGID)
03942   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
03943   return issetugid ();
03944 #else
03945   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
03946   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
03947 
03948   static dbus_bool_t check_setuid_initialised;
03949   static dbus_bool_t is_setuid;
03950 
03951   if (_DBUS_UNLIKELY (!check_setuid_initialised))
03952     {
03953 #ifdef HAVE_GETRESUID
03954       if (getresuid (&ruid, &euid, &suid) != 0 ||
03955           getresgid (&rgid, &egid, &sgid) != 0)
03956 #endif /* HAVE_GETRESUID */
03957         {
03958           suid = ruid = getuid ();
03959           sgid = rgid = getgid ();
03960           euid = geteuid ();
03961           egid = getegid ();
03962         }
03963 
03964       check_setuid_initialised = TRUE;
03965       is_setuid = (ruid != euid || ruid != suid ||
03966                    rgid != egid || rgid != sgid);
03967 
03968     }
03969   return is_setuid;
03970 #endif
03971 }
03972 
03973 /* tests in dbus-sysdeps-util.c */