D-Bus  1.4.10
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       fd = -1;
00830 
00831       return -1;
00832     }
00833 
00834   if (!_dbus_set_fd_nonblocking (fd, error))
00835     {
00836       _DBUS_ASSERT_ERROR_IS_SET (error);
00837 
00838       _dbus_close (fd, NULL);
00839       fd = -1;
00840 
00841       return -1;
00842     }
00843 
00844   return fd;
00845 }
00846 
00856 static dbus_bool_t
00857 _dbus_set_local_creds (int fd, dbus_bool_t on)
00858 {
00859   dbus_bool_t retval = TRUE;
00860 
00861 #if defined(HAVE_CMSGCRED)
00862   /* NOOP just to make sure only one codepath is used
00863    *      and to prefer CMSGCRED
00864    */
00865 #elif defined(LOCAL_CREDS)
00866   int val = on ? 1 : 0;
00867   if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
00868     {
00869       _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
00870       retval = FALSE;
00871     }
00872   else
00873     _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
00874                    on ? "enabled" : "disabled", fd);
00875 #endif
00876 
00877   return retval;
00878 }
00879 
00897 int
00898 _dbus_listen_unix_socket (const char     *path,
00899                           dbus_bool_t     abstract,
00900                           DBusError      *error)
00901 {
00902   int listen_fd;
00903   struct sockaddr_un addr;
00904   size_t path_len;
00905   unsigned int reuseaddr;
00906 
00907   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00908 
00909   _dbus_verbose ("listening on unix socket %s abstract=%d\n",
00910                  path, abstract);
00911 
00912   if (!_dbus_open_unix_socket (&listen_fd, error))
00913     {
00914       _DBUS_ASSERT_ERROR_IS_SET(error);
00915       return -1;
00916     }
00917   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
00918 
00919   _DBUS_ZERO (addr);
00920   addr.sun_family = AF_UNIX;
00921   path_len = strlen (path);
00922 
00923   if (abstract)
00924     {
00925 #ifdef HAVE_ABSTRACT_SOCKETS
00926       /* remember that abstract names aren't nul-terminated so we rely
00927        * on sun_path being filled in with zeroes above.
00928        */
00929       addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
00930       path_len++; /* Account for the extra nul byte added to the start of sun_path */
00931 
00932       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00933         {
00934           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00935                       "Abstract socket name too long\n");
00936           _dbus_close (listen_fd, NULL);
00937           return -1;
00938         }
00939 
00940       strncpy (&addr.sun_path[1], path, path_len);
00941       /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
00942 #else /* HAVE_ABSTRACT_SOCKETS */
00943       dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
00944                       "Operating system does not support abstract socket namespace\n");
00945       _dbus_close (listen_fd, NULL);
00946       return -1;
00947 #endif /* ! HAVE_ABSTRACT_SOCKETS */
00948     }
00949   else
00950     {
00951       /* Discussed security implications of this with Nalin,
00952        * and we couldn't think of where it would kick our ass, but
00953        * it still seems a bit sucky. It also has non-security suckage;
00954        * really we'd prefer to exit if the socket is already in use.
00955        * But there doesn't seem to be a good way to do this.
00956        *
00957        * Just to be extra careful, I threw in the stat() - clearly
00958        * the stat() can't *fix* any security issue, but it at least
00959        * avoids inadvertent/accidental data loss.
00960        */
00961       {
00962         struct stat sb;
00963 
00964         if (stat (path, &sb) == 0 &&
00965             S_ISSOCK (sb.st_mode))
00966           unlink (path);
00967       }
00968 
00969       if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
00970         {
00971           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
00972                       "Abstract socket name too long\n");
00973           _dbus_close (listen_fd, NULL);
00974           return -1;
00975         }
00976 
00977       strncpy (addr.sun_path, path, path_len);
00978     }
00979 
00980   reuseaddr = 1;
00981   if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
00982     {
00983       _dbus_warn ("Failed to set socket option\"%s\": %s",
00984                   path, _dbus_strerror (errno));
00985     }
00986 
00987   if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
00988     {
00989       dbus_set_error (error, _dbus_error_from_errno (errno),
00990                       "Failed to bind socket \"%s\": %s",
00991                       path, _dbus_strerror (errno));
00992       _dbus_close (listen_fd, NULL);
00993       return -1;
00994     }
00995 
00996   if (listen (listen_fd, 30 /* backlog */) < 0)
00997     {
00998       dbus_set_error (error, _dbus_error_from_errno (errno),
00999                       "Failed to listen on socket \"%s\": %s",
01000                       path, _dbus_strerror (errno));
01001       _dbus_close (listen_fd, NULL);
01002       return -1;
01003     }
01004 
01005   if (!_dbus_set_local_creds (listen_fd, TRUE))
01006     {
01007       dbus_set_error (error, _dbus_error_from_errno (errno),
01008                       "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
01009                       path, _dbus_strerror (errno));
01010       close (listen_fd);
01011       return -1;
01012     }
01013 
01014   if (!_dbus_set_fd_nonblocking (listen_fd, error))
01015     {
01016       _DBUS_ASSERT_ERROR_IS_SET (error);
01017       _dbus_close (listen_fd, NULL);
01018       return -1;
01019     }
01020 
01021   /* Try opening up the permissions, but if we can't, just go ahead
01022    * and continue, maybe it will be good enough.
01023    */
01024   if (!abstract && chmod (path, 0777) < 0)
01025     _dbus_warn ("Could not set mode 0777 on socket %s\n",
01026                 path);
01027 
01028   return listen_fd;
01029 }
01030 
01041 int
01042 _dbus_listen_systemd_sockets (int       **fds,
01043                               DBusError *error)
01044 {
01045   int r, n;
01046   unsigned fd;
01047   int *new_fds;
01048 
01049   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01050 
01051   n = sd_listen_fds (TRUE);
01052   if (n < 0)
01053     {
01054       dbus_set_error (error, _dbus_error_from_errno (-n),
01055                       "Failed to acquire systemd socket: %s",
01056                       _dbus_strerror (-n));
01057       return -1;
01058     }
01059 
01060   if (n <= 0)
01061     {
01062       dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01063                       "No socket received.");
01064       return -1;
01065     }
01066 
01067   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01068     {
01069       r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
01070       if (r < 0)
01071         {
01072           dbus_set_error (error, _dbus_error_from_errno (-r),
01073                           "Failed to verify systemd socket type: %s",
01074                           _dbus_strerror (-r));
01075           return -1;
01076         }
01077 
01078       if (!r)
01079         {
01080           dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
01081                           "Passed socket has wrong type.");
01082           return -1;
01083         }
01084     }
01085 
01086   /* OK, the file descriptors are all good, so let's take posession of
01087      them then. */
01088 
01089   new_fds = dbus_new (int, n);
01090   if (!new_fds)
01091     {
01092       dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
01093                       "Failed to allocate file handle array.");
01094       goto fail;
01095     }
01096 
01097   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01098     {
01099       if (!_dbus_set_local_creds (fd, TRUE))
01100         {
01101           dbus_set_error (error, _dbus_error_from_errno (errno),
01102                           "Failed to enable LOCAL_CREDS on systemd socket: %s",
01103                           _dbus_strerror (errno));
01104           goto fail;
01105         }
01106 
01107       if (!_dbus_set_fd_nonblocking (fd, error))
01108         {
01109           _DBUS_ASSERT_ERROR_IS_SET (error);
01110           goto fail;
01111         }
01112 
01113       new_fds[fd - SD_LISTEN_FDS_START] = fd;
01114     }
01115 
01116   *fds = new_fds;
01117   return n;
01118 
01119  fail:
01120 
01121   for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
01122     {
01123       _dbus_close (fd, NULL);
01124     }
01125 
01126   dbus_free (new_fds);
01127   return -1;
01128 }
01129 
01143 int
01144 _dbus_connect_tcp_socket (const char     *host,
01145                           const char     *port,
01146                           const char     *family,
01147                           DBusError      *error)
01148 {
01149     return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
01150 }
01151 
01152 int
01153 _dbus_connect_tcp_socket_with_nonce (const char     *host,
01154                                      const char     *port,
01155                                      const char     *family,
01156                                      const char     *noncefile,
01157                                      DBusError      *error)
01158 {
01159   int saved_errno = 0;
01160   int fd = -1, res;
01161   struct addrinfo hints;
01162   struct addrinfo *ai, *tmp;
01163 
01164   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01165 
01166   if (!_dbus_open_tcp_socket (&fd, error))
01167     {
01168       _DBUS_ASSERT_ERROR_IS_SET(error);
01169       return -1;
01170     }
01171 
01172   _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01173 
01174   _DBUS_ZERO (hints);
01175 
01176   if (!family)
01177     hints.ai_family = AF_UNSPEC;
01178   else if (!strcmp(family, "ipv4"))
01179     hints.ai_family = AF_INET;
01180   else if (!strcmp(family, "ipv6"))
01181     hints.ai_family = AF_INET6;
01182   else
01183     {
01184       dbus_set_error (error,
01185                       DBUS_ERROR_BAD_ADDRESS,
01186                       "Unknown address family %s", family);
01187       return -1;
01188     }
01189   hints.ai_protocol = IPPROTO_TCP;
01190   hints.ai_socktype = SOCK_STREAM;
01191   hints.ai_flags = AI_ADDRCONFIG;
01192 
01193   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
01194     {
01195       dbus_set_error (error,
01196                       _dbus_error_from_errno (errno),
01197                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01198                       host, port, gai_strerror(res), res);
01199       _dbus_close (fd, NULL);
01200       return -1;
01201     }
01202 
01203   tmp = ai;
01204   while (tmp)
01205     {
01206       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01207         {
01208           freeaddrinfo(ai);
01209           _DBUS_ASSERT_ERROR_IS_SET(error);
01210           return -1;
01211         }
01212       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01213 
01214       if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01215         {
01216           saved_errno = errno;
01217           _dbus_close(fd, NULL);
01218           fd = -1;
01219           tmp = tmp->ai_next;
01220           continue;
01221         }
01222 
01223       break;
01224     }
01225   freeaddrinfo(ai);
01226 
01227   if (fd == -1)
01228     {
01229       dbus_set_error (error,
01230                       _dbus_error_from_errno (saved_errno),
01231                       "Failed to connect to socket \"%s:%s\" %s",
01232                       host, port, _dbus_strerror(saved_errno));
01233       return -1;
01234     }
01235 
01236   if (noncefile != NULL)
01237     {
01238       DBusString noncefileStr;
01239       dbus_bool_t ret;
01240       _dbus_string_init_const (&noncefileStr, noncefile);
01241       ret = _dbus_send_nonce (fd, &noncefileStr, error);
01242       _dbus_string_free (&noncefileStr);
01243 
01244       if (!ret)
01245     {
01246       _dbus_close (fd, NULL);
01247           return -1;
01248         }
01249     }
01250 
01251   if (!_dbus_set_fd_nonblocking (fd, error))
01252     {
01253       _dbus_close (fd, NULL);
01254       return -1;
01255     }
01256 
01257   return fd;
01258 }
01259 
01276 int
01277 _dbus_listen_tcp_socket (const char     *host,
01278                          const char     *port,
01279                          const char     *family,
01280                          DBusString     *retport,
01281                          int           **fds_p,
01282                          DBusError      *error)
01283 {
01284   int saved_errno;
01285   int nlisten_fd = 0, *listen_fd = NULL, res, i;
01286   struct addrinfo hints;
01287   struct addrinfo *ai, *tmp;
01288   unsigned int reuseaddr;
01289 
01290   *fds_p = NULL;
01291   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01292 
01293   _DBUS_ZERO (hints);
01294 
01295   if (!family)
01296     hints.ai_family = AF_UNSPEC;
01297   else if (!strcmp(family, "ipv4"))
01298     hints.ai_family = AF_INET;
01299   else if (!strcmp(family, "ipv6"))
01300     hints.ai_family = AF_INET6;
01301   else
01302     {
01303       dbus_set_error (error,
01304                       DBUS_ERROR_BAD_ADDRESS,
01305                       "Unknown address family %s", family);
01306       return -1;
01307     }
01308 
01309   hints.ai_protocol = IPPROTO_TCP;
01310   hints.ai_socktype = SOCK_STREAM;
01311   hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
01312 
01313  redo_lookup_with_port:
01314   if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
01315     {
01316       dbus_set_error (error,
01317                       _dbus_error_from_errno (errno),
01318                       "Failed to lookup host/port: \"%s:%s\": %s (%d)",
01319                       host ? host : "*", port, gai_strerror(res), res);
01320       return -1;
01321     }
01322 
01323   tmp = ai;
01324   while (tmp)
01325     {
01326       int fd = -1, *newlisten_fd;
01327       if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
01328         {
01329           _DBUS_ASSERT_ERROR_IS_SET(error);
01330           goto failed;
01331         }
01332       _DBUS_ASSERT_ERROR_IS_CLEAR(error);
01333 
01334       reuseaddr = 1;
01335       if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
01336         {
01337           _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
01338                       host ? host : "*", port, _dbus_strerror (errno));
01339         }
01340 
01341       if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
01342         {
01343           saved_errno = errno;
01344           _dbus_close(fd, NULL);
01345           if (saved_errno == EADDRINUSE)
01346             {
01347               /* Depending on kernel policy, it may or may not
01348                  be neccessary to bind to both IPv4 & 6 addresses
01349                  so ignore EADDRINUSE here */
01350               tmp = tmp->ai_next;
01351               continue;
01352             }
01353           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01354                           "Failed to bind socket \"%s:%s\": %s",
01355                           host ? host : "*", port, _dbus_strerror (saved_errno));
01356           goto failed;
01357         }
01358 
01359       if (listen (fd, 30 /* backlog */) < 0)
01360         {
01361           saved_errno = errno;
01362           _dbus_close (fd, NULL);
01363           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01364                           "Failed to listen on socket \"%s:%s\": %s",
01365                           host ? host : "*", port, _dbus_strerror (saved_errno));
01366           goto failed;
01367         }
01368 
01369       newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
01370       if (!newlisten_fd)
01371         {
01372           saved_errno = errno;
01373           _dbus_close (fd, NULL);
01374           dbus_set_error (error, _dbus_error_from_errno (saved_errno),
01375                           "Failed to allocate file handle array: %s",
01376                           _dbus_strerror (saved_errno));
01377           goto failed;
01378         }
01379       listen_fd = newlisten_fd;
01380       listen_fd[nlisten_fd] = fd;
01381       nlisten_fd++;
01382 
01383       if (!_dbus_string_get_length(retport))
01384         {
01385           /* If the user didn't specify a port, or used 0, then
01386              the kernel chooses a port. After the first address
01387              is bound to, we need to force all remaining addresses
01388              to use the same port */
01389           if (!port || !strcmp(port, "0"))
01390             {
01391               int result;
01392               struct sockaddr_storage addr;
01393               socklen_t addrlen;
01394               char portbuf[50];
01395 
01396               addrlen = sizeof(addr);
01397               result = getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01398 
01399               if (result == -1 ||
01400                   (res = getnameinfo ((struct sockaddr*)&addr, addrlen, NULL, 0,
01401                                       portbuf, sizeof(portbuf),
01402                                       NI_NUMERICHOST)) != 0)
01403                 {
01404                   dbus_set_error (error, _dbus_error_from_errno (errno),
01405                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01406                                   host ? host : "*", port, gai_strerror(res), res);
01407                   goto failed;
01408                 }
01409               if (!_dbus_string_append(retport, portbuf))
01410                 {
01411                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01412                   goto failed;
01413                 }
01414 
01415               /* Release current address list & redo lookup */
01416               port = _dbus_string_get_const_data(retport);
01417               freeaddrinfo(ai);
01418               goto redo_lookup_with_port;
01419             }
01420           else
01421             {
01422               if (!_dbus_string_append(retport, port))
01423                 {
01424                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01425                     goto failed;
01426                 }
01427             }
01428         }
01429 
01430       tmp = tmp->ai_next;
01431     }
01432   freeaddrinfo(ai);
01433   ai = NULL;
01434 
01435   if (!nlisten_fd)
01436     {
01437       errno = EADDRINUSE;
01438       dbus_set_error (error, _dbus_error_from_errno (errno),
01439                       "Failed to bind socket \"%s:%s\": %s",
01440                       host ? host : "*", port, _dbus_strerror (errno));
01441       goto failed;
01442     }
01443 
01444   for (i = 0 ; i < nlisten_fd ; i++)
01445     {
01446       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01447         {
01448           goto failed;
01449         }
01450     }
01451 
01452   *fds_p = listen_fd;
01453 
01454   return nlisten_fd;
01455 
01456  failed:
01457   if (ai)
01458     freeaddrinfo(ai);
01459   for (i = 0 ; i < nlisten_fd ; i++)
01460     _dbus_close(listen_fd[i], NULL);
01461   dbus_free(listen_fd);
01462   return -1;
01463 }
01464 
01465 static dbus_bool_t
01466 write_credentials_byte (int             server_fd,
01467                         DBusError      *error)
01468 {
01469   int bytes_written;
01470   char buf[1] = { '\0' };
01471 #if defined(HAVE_CMSGCRED)
01472   union {
01473           struct cmsghdr hdr;
01474           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01475   } cmsg;
01476   struct iovec iov;
01477   struct msghdr msg;
01478   iov.iov_base = buf;
01479   iov.iov_len = 1;
01480 
01481   _DBUS_ZERO(msg);
01482   msg.msg_iov = &iov;
01483   msg.msg_iovlen = 1;
01484 
01485   msg.msg_control = (caddr_t) &cmsg;
01486   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01487   _DBUS_ZERO(cmsg);
01488   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01489   cmsg.hdr.cmsg_level = SOL_SOCKET;
01490   cmsg.hdr.cmsg_type = SCM_CREDS;
01491 #endif
01492 
01493   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01494 
01495  again:
01496 
01497 #if defined(HAVE_CMSGCRED)
01498   bytes_written = sendmsg (server_fd, &msg, 0
01499 #if HAVE_DECL_MSG_NOSIGNAL
01500                            |MSG_NOSIGNAL
01501 #endif
01502                            );
01503 #else
01504   bytes_written = send (server_fd, buf, 1, 0
01505 #if HAVE_DECL_MSG_NOSIGNAL
01506                         |MSG_NOSIGNAL
01507 #endif
01508                         );
01509 #endif
01510 
01511   if (bytes_written < 0 && errno == EINTR)
01512     goto again;
01513 
01514   if (bytes_written < 0)
01515     {
01516       dbus_set_error (error, _dbus_error_from_errno (errno),
01517                       "Failed to write credentials byte: %s",
01518                      _dbus_strerror (errno));
01519       return FALSE;
01520     }
01521   else if (bytes_written == 0)
01522     {
01523       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01524                       "wrote zero bytes writing credentials byte");
01525       return FALSE;
01526     }
01527   else
01528     {
01529       _dbus_assert (bytes_written == 1);
01530       _dbus_verbose ("wrote credentials byte\n");
01531       return TRUE;
01532     }
01533 }
01534 
01556 dbus_bool_t
01557 _dbus_read_credentials_socket  (int              client_fd,
01558                                 DBusCredentials *credentials,
01559                                 DBusError       *error)
01560 {
01561   struct msghdr msg;
01562   struct iovec iov;
01563   char buf;
01564   dbus_uid_t uid_read;
01565   dbus_pid_t pid_read;
01566   int bytes_read;
01567 
01568 #ifdef HAVE_CMSGCRED
01569   union {
01570     struct cmsghdr hdr;
01571     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01572   } cmsg;
01573 
01574 #elif defined(LOCAL_CREDS)
01575   struct {
01576     struct cmsghdr hdr;
01577     struct sockcred cred;
01578   } cmsg;
01579 #endif
01580 
01581   uid_read = DBUS_UID_UNSET;
01582   pid_read = DBUS_PID_UNSET;
01583 
01584   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01585 
01586   /* The POSIX spec certainly doesn't promise this, but
01587    * we need these assertions to fail as soon as we're wrong about
01588    * it so we can do the porting fixups
01589    */
01590   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01591   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01592   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01593 
01594   _dbus_credentials_clear (credentials);
01595 
01596   /* Systems supporting LOCAL_CREDS are configured to have this feature
01597    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01598    * the connection.  Therefore, the received message must carry the
01599    * credentials information without doing anything special.
01600    */
01601 
01602   iov.iov_base = &buf;
01603   iov.iov_len = 1;
01604 
01605   _DBUS_ZERO(msg);
01606   msg.msg_iov = &iov;
01607   msg.msg_iovlen = 1;
01608 
01609 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01610   _DBUS_ZERO(cmsg);
01611   msg.msg_control = (caddr_t) &cmsg;
01612   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01613 #endif
01614 
01615  again:
01616   bytes_read = recvmsg (client_fd, &msg, 0);
01617 
01618   if (bytes_read < 0)
01619     {
01620       if (errno == EINTR)
01621         goto again;
01622 
01623       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01624        * normally only call read_credentials if the socket was ready
01625        * for reading
01626        */
01627 
01628       dbus_set_error (error, _dbus_error_from_errno (errno),
01629                       "Failed to read credentials byte: %s",
01630                       _dbus_strerror (errno));
01631       return FALSE;
01632     }
01633   else if (bytes_read == 0)
01634     {
01635       /* this should not happen unless we are using recvmsg wrong,
01636        * so is essentially here for paranoia
01637        */
01638       dbus_set_error (error, DBUS_ERROR_FAILED,
01639                       "Failed to read credentials byte (zero-length read)");
01640       return FALSE;
01641     }
01642   else if (buf != '\0')
01643     {
01644       dbus_set_error (error, DBUS_ERROR_FAILED,
01645                       "Credentials byte was not nul");
01646       return FALSE;
01647     }
01648 
01649 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01650   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01651                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01652     {
01653       dbus_set_error (error, DBUS_ERROR_FAILED,
01654                       "Message from recvmsg() was not SCM_CREDS");
01655       return FALSE;
01656     }
01657 #endif
01658 
01659   _dbus_verbose ("read credentials byte\n");
01660 
01661   {
01662 #ifdef SO_PEERCRED
01663 #ifdef __OpenBSD__
01664     struct sockpeercred cr;
01665 #else
01666     struct ucred cr;
01667 #endif
01668     int cr_len = sizeof (cr);
01669 
01670     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01671         cr_len == sizeof (cr))
01672       {
01673         pid_read = cr.pid;
01674         uid_read = cr.uid;
01675       }
01676     else
01677       {
01678         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01679                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01680       }
01681 #elif defined(HAVE_CMSGCRED)
01682     struct cmsgcred *cred;
01683 
01684     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01685     pid_read = cred->cmcred_pid;
01686     uid_read = cred->cmcred_euid;
01687 #elif defined(LOCAL_CREDS)
01688     pid_read = DBUS_PID_UNSET;
01689     uid_read = cmsg.cred.sc_uid;
01690     /* Since we have already got the credentials from this socket, we can
01691      * disable its LOCAL_CREDS flag if it was ever set. */
01692     _dbus_set_local_creds (client_fd, FALSE);
01693 #elif defined(HAVE_GETPEEREID)
01694     uid_t euid;
01695     gid_t egid;
01696     if (getpeereid (client_fd, &euid, &egid) == 0)
01697       {
01698         uid_read = euid;
01699       }
01700     else
01701       {
01702         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01703       }
01704 #elif defined(HAVE_GETPEERUCRED)
01705     ucred_t * ucred = NULL;
01706     if (getpeerucred (client_fd, &ucred) == 0)
01707       {
01708         pid_read = ucred_getpid (ucred);
01709         uid_read = ucred_geteuid (ucred);
01710 #ifdef HAVE_ADT
01711         /* generate audit session data based on socket ucred */
01712         adt_session_data_t *adth = NULL;
01713         adt_export_data_t *data = NULL;
01714         size_t size = 0;
01715         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01716           {
01717             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01718           }
01719         else
01720           {
01721             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01722               {
01723                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01724               }
01725             else
01726               {
01727                 size = adt_export_session_data (adth, &data);
01728                 if (size <= 0)
01729                   {
01730                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01731                   }
01732                 else
01733                   {
01734                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01735                     free (data);
01736                   }
01737               }
01738             (void) adt_end_session (adth);
01739           }
01740 #endif /* HAVE_ADT */
01741       }
01742     else
01743       {
01744         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01745       }
01746     if (ucred != NULL)
01747       ucred_free (ucred);
01748 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01749     _dbus_verbose ("Socket credentials not supported on this OS\n");
01750 #endif
01751   }
01752 
01753   _dbus_verbose ("Credentials:"
01754                  "  pid "DBUS_PID_FORMAT
01755                  "  uid "DBUS_UID_FORMAT
01756                  "\n",
01757                  pid_read,
01758                  uid_read);
01759 
01760   if (pid_read != DBUS_PID_UNSET)
01761     {
01762       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01763         {
01764           _DBUS_SET_OOM (error);
01765           return FALSE;
01766         }
01767     }
01768 
01769   if (uid_read != DBUS_UID_UNSET)
01770     {
01771       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01772         {
01773           _DBUS_SET_OOM (error);
01774           return FALSE;
01775         }
01776     }
01777 
01778   return TRUE;
01779 }
01780 
01798 dbus_bool_t
01799 _dbus_send_credentials_socket  (int              server_fd,
01800                                 DBusError       *error)
01801 {
01802   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01803 
01804   if (write_credentials_byte (server_fd, error))
01805     return TRUE;
01806   else
01807     return FALSE;
01808 }
01809 
01819 int
01820 _dbus_accept  (int listen_fd)
01821 {
01822   int client_fd;
01823   struct sockaddr addr;
01824   socklen_t addrlen;
01825 #ifdef HAVE_ACCEPT4
01826   dbus_bool_t cloexec_done;
01827 #endif
01828 
01829   addrlen = sizeof (addr);
01830 
01831  retry:
01832 
01833 #ifdef HAVE_ACCEPT4
01834   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01835   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01836   cloexec_done = client_fd >= 0;
01837 
01838   if (client_fd < 0 && errno == ENOSYS)
01839 #endif
01840     {
01841       client_fd = accept (listen_fd, &addr, &addrlen);
01842     }
01843 
01844   if (client_fd < 0)
01845     {
01846       if (errno == EINTR)
01847         goto retry;
01848     }
01849 
01850   _dbus_verbose ("client fd %d accepted\n", client_fd);
01851 
01852 #ifdef HAVE_ACCEPT4
01853   if (!cloexec_done)
01854 #endif
01855     {
01856       _dbus_fd_set_close_on_exec(client_fd);
01857     }
01858 
01859   return client_fd;
01860 }
01861 
01870 dbus_bool_t
01871 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01872 {
01873   const char *directory;
01874   struct stat sb;
01875 
01876   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01877 
01878   directory = _dbus_string_get_const_data (dir);
01879 
01880   if (stat (directory, &sb) < 0)
01881     {
01882       dbus_set_error (error, _dbus_error_from_errno (errno),
01883                       "%s", _dbus_strerror (errno));
01884 
01885       return FALSE;
01886     }
01887 
01888   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01889       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01890     {
01891       dbus_set_error (error, DBUS_ERROR_FAILED,
01892                      "%s directory is not private to the user", directory);
01893       return FALSE;
01894     }
01895 
01896   return TRUE;
01897 }
01898 
01899 static dbus_bool_t
01900 fill_user_info_from_passwd (struct passwd *p,
01901                             DBusUserInfo  *info,
01902                             DBusError     *error)
01903 {
01904   _dbus_assert (p->pw_name != NULL);
01905   _dbus_assert (p->pw_dir != NULL);
01906 
01907   info->uid = p->pw_uid;
01908   info->primary_gid = p->pw_gid;
01909   info->username = _dbus_strdup (p->pw_name);
01910   info->homedir = _dbus_strdup (p->pw_dir);
01911 
01912   if (info->username == NULL ||
01913       info->homedir == NULL)
01914     {
01915       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01916       return FALSE;
01917     }
01918 
01919   return TRUE;
01920 }
01921 
01922 static dbus_bool_t
01923 fill_user_info (DBusUserInfo       *info,
01924                 dbus_uid_t          uid,
01925                 const DBusString   *username,
01926                 DBusError          *error)
01927 {
01928   const char *username_c;
01929 
01930   /* exactly one of username/uid provided */
01931   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01932   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01933 
01934   info->uid = DBUS_UID_UNSET;
01935   info->primary_gid = DBUS_GID_UNSET;
01936   info->group_ids = NULL;
01937   info->n_group_ids = 0;
01938   info->username = NULL;
01939   info->homedir = NULL;
01940 
01941   if (username != NULL)
01942     username_c = _dbus_string_get_const_data (username);
01943   else
01944     username_c = NULL;
01945 
01946   /* For now assuming that the getpwnam() and getpwuid() flavors
01947    * are always symmetrical, if not we have to add more configure
01948    * checks
01949    */
01950 
01951 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01952   {
01953     struct passwd *p;
01954     int result;
01955     size_t buflen;
01956     char *buf;
01957     struct passwd p_str;
01958 
01959     /* retrieve maximum needed size for buf */
01960     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01961 
01962     /* sysconf actually returns a long, but everything else expects size_t,
01963      * so just recast here.
01964      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
01965      */
01966     if ((long) buflen <= 0)
01967       buflen = 1024;
01968 
01969     result = -1;
01970     while (1)
01971       {
01972         buf = dbus_malloc (buflen);
01973         if (buf == NULL)
01974           {
01975             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01976             return FALSE;
01977           }
01978 
01979         p = NULL;
01980 #ifdef HAVE_POSIX_GETPWNAM_R
01981         if (uid != DBUS_UID_UNSET)
01982           result = getpwuid_r (uid, &p_str, buf, buflen,
01983                                &p);
01984         else
01985           result = getpwnam_r (username_c, &p_str, buf, buflen,
01986                                &p);
01987 #else
01988         if (uid != DBUS_UID_UNSET)
01989           p = getpwuid_r (uid, &p_str, buf, buflen);
01990         else
01991           p = getpwnam_r (username_c, &p_str, buf, buflen);
01992         result = 0;
01993 #endif /* !HAVE_POSIX_GETPWNAM_R */
01994         //Try a bigger buffer if ERANGE was returned
01995         if (result == ERANGE && buflen < 512 * 1024)
01996           {
01997             dbus_free (buf);
01998             buflen *= 2;
01999           }
02000         else
02001           {
02002             break;
02003           }
02004       }
02005     if (result == 0 && p == &p_str)
02006       {
02007         if (!fill_user_info_from_passwd (p, info, error))
02008           {
02009             dbus_free (buf);
02010             return FALSE;
02011           }
02012         dbus_free (buf);
02013       }
02014     else
02015       {
02016         dbus_set_error (error, _dbus_error_from_errno (errno),
02017                         "User \"%s\" unknown or no memory to allocate password entry\n",
02018                         username_c ? username_c : "???");
02019         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02020         dbus_free (buf);
02021         return FALSE;
02022       }
02023   }
02024 #else /* ! HAVE_GETPWNAM_R */
02025   {
02026     /* I guess we're screwed on thread safety here */
02027     struct passwd *p;
02028 
02029     if (uid != DBUS_UID_UNSET)
02030       p = getpwuid (uid);
02031     else
02032       p = getpwnam (username_c);
02033 
02034     if (p != NULL)
02035       {
02036         if (!fill_user_info_from_passwd (p, info, error))
02037           {
02038             return FALSE;
02039           }
02040       }
02041     else
02042       {
02043         dbus_set_error (error, _dbus_error_from_errno (errno),
02044                         "User \"%s\" unknown or no memory to allocate password entry\n",
02045                         username_c ? username_c : "???");
02046         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02047         return FALSE;
02048       }
02049   }
02050 #endif  /* ! HAVE_GETPWNAM_R */
02051 
02052   /* Fill this in so we can use it to get groups */
02053   username_c = info->username;
02054 
02055 #ifdef HAVE_GETGROUPLIST
02056   {
02057     gid_t *buf;
02058     int buf_count;
02059     int i;
02060     int initial_buf_count;
02061 
02062     initial_buf_count = 17;
02063     buf_count = initial_buf_count;
02064     buf = dbus_new (gid_t, buf_count);
02065     if (buf == NULL)
02066       {
02067         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02068         goto failed;
02069       }
02070 
02071     if (getgrouplist (username_c,
02072                       info->primary_gid,
02073                       buf, &buf_count) < 0)
02074       {
02075         gid_t *new;
02076         /* Presumed cause of negative return code: buf has insufficient
02077            entries to hold the entire group list. The Linux behavior in this
02078            case is to pass back the actual number of groups in buf_count, but
02079            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02080            So as a hack, try to help out a bit by guessing a larger
02081            number of groups, within reason.. might still fail, of course,
02082            but we can at least print a more informative message.  I looked up
02083            the "right way" to do this by downloading Apple's own source code
02084            for the "id" command, and it turns out that they use an
02085            undocumented library function getgrouplist_2 (!) which is not
02086            declared in any header in /usr/include (!!). That did not seem
02087            like the way to go here.
02088         */
02089         if (buf_count == initial_buf_count)
02090           {
02091             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02092           }
02093         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02094         if (new == NULL)
02095           {
02096             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02097             dbus_free (buf);
02098             goto failed;
02099           }
02100 
02101         buf = new;
02102 
02103         errno = 0;
02104         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02105           {
02106             if (errno == 0)
02107               {
02108                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02109                             username_c, buf_count, buf_count);
02110               }
02111             else
02112               {
02113                 dbus_set_error (error,
02114                                 _dbus_error_from_errno (errno),
02115                                 "Failed to get groups for username \"%s\" primary GID "
02116                                 DBUS_GID_FORMAT ": %s\n",
02117                                 username_c, info->primary_gid,
02118                                 _dbus_strerror (errno));
02119                 dbus_free (buf);
02120                 goto failed;
02121               }
02122           }
02123       }
02124 
02125     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02126     if (info->group_ids == NULL)
02127       {
02128         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02129         dbus_free (buf);
02130         goto failed;
02131       }
02132 
02133     for (i = 0; i < buf_count; ++i)
02134       info->group_ids[i] = buf[i];
02135 
02136     info->n_group_ids = buf_count;
02137 
02138     dbus_free (buf);
02139   }
02140 #else  /* HAVE_GETGROUPLIST */
02141   {
02142     /* We just get the one group ID */
02143     info->group_ids = dbus_new (dbus_gid_t, 1);
02144     if (info->group_ids == NULL)
02145       {
02146         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02147         goto failed;
02148       }
02149 
02150     info->n_group_ids = 1;
02151 
02152     (info->group_ids)[0] = info->primary_gid;
02153   }
02154 #endif /* HAVE_GETGROUPLIST */
02155 
02156   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02157 
02158   return TRUE;
02159 
02160  failed:
02161   _DBUS_ASSERT_ERROR_IS_SET (error);
02162   return FALSE;
02163 }
02164 
02173 dbus_bool_t
02174 _dbus_user_info_fill (DBusUserInfo     *info,
02175                       const DBusString *username,
02176                       DBusError        *error)
02177 {
02178   return fill_user_info (info, DBUS_UID_UNSET,
02179                          username, error);
02180 }
02181 
02190 dbus_bool_t
02191 _dbus_user_info_fill_uid (DBusUserInfo *info,
02192                           dbus_uid_t    uid,
02193                           DBusError    *error)
02194 {
02195   return fill_user_info (info, uid,
02196                          NULL, error);
02197 }
02198 
02206 dbus_bool_t
02207 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02208 {
02209   /* The POSIX spec certainly doesn't promise this, but
02210    * we need these assertions to fail as soon as we're wrong about
02211    * it so we can do the porting fixups
02212    */
02213   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02214   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02215   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02216 
02217   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02218     return FALSE;
02219   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02220     return FALSE;
02221 
02222   return TRUE;
02223 }
02224 
02236 dbus_bool_t
02237 _dbus_append_user_from_current_process (DBusString *str)
02238 {
02239   return _dbus_string_append_uint (str,
02240                                    _dbus_geteuid ());
02241 }
02242 
02247 dbus_pid_t
02248 _dbus_getpid (void)
02249 {
02250   return getpid ();
02251 }
02252 
02256 dbus_uid_t
02257 _dbus_getuid (void)
02258 {
02259   return getuid ();
02260 }
02261 
02265 dbus_uid_t
02266 _dbus_geteuid (void)
02267 {
02268   return geteuid ();
02269 }
02270 
02277 unsigned long
02278 _dbus_pid_for_log (void)
02279 {
02280   return getpid ();
02281 }
02282 
02290 dbus_bool_t
02291 _dbus_parse_uid (const DBusString      *uid_str,
02292                  dbus_uid_t            *uid)
02293 {
02294   int end;
02295   long val;
02296 
02297   if (_dbus_string_get_length (uid_str) == 0)
02298     {
02299       _dbus_verbose ("UID string was zero length\n");
02300       return FALSE;
02301     }
02302 
02303   val = -1;
02304   end = 0;
02305   if (!_dbus_string_parse_int (uid_str, 0, &val,
02306                                &end))
02307     {
02308       _dbus_verbose ("could not parse string as a UID\n");
02309       return FALSE;
02310     }
02311 
02312   if (end != _dbus_string_get_length (uid_str))
02313     {
02314       _dbus_verbose ("string contained trailing stuff after UID\n");
02315       return FALSE;
02316     }
02317 
02318   *uid = val;
02319 
02320   return TRUE;
02321 }
02322 
02323 #if !DBUS_USE_SYNC
02324 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02325 #endif
02326 
02333 dbus_int32_t
02334 _dbus_atomic_inc (DBusAtomic *atomic)
02335 {
02336 #if DBUS_USE_SYNC
02337   return __sync_add_and_fetch(&atomic->value, 1)-1;
02338 #else
02339   dbus_int32_t res;
02340   _DBUS_LOCK (atomic);
02341   res = atomic->value;
02342   atomic->value += 1;
02343   _DBUS_UNLOCK (atomic);
02344   return res;
02345 #endif
02346 }
02347 
02354 dbus_int32_t
02355 _dbus_atomic_dec (DBusAtomic *atomic)
02356 {
02357 #if DBUS_USE_SYNC
02358   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02359 #else
02360   dbus_int32_t res;
02361 
02362   _DBUS_LOCK (atomic);
02363   res = atomic->value;
02364   atomic->value -= 1;
02365   _DBUS_UNLOCK (atomic);
02366   return res;
02367 #endif
02368 }
02369 
02370 #ifdef DBUS_BUILD_TESTS
02371 
02374 dbus_gid_t
02375 _dbus_getgid (void)
02376 {
02377   return getgid ();
02378 }
02379 #endif
02380 
02389 int
02390 _dbus_poll (DBusPollFD *fds,
02391             int         n_fds,
02392             int         timeout_milliseconds)
02393 {
02394 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02395   /* This big thing is a constant expression and should get optimized
02396    * out of existence. So it's more robust than a configure check at
02397    * no cost.
02398    */
02399   if (_DBUS_POLLIN == POLLIN &&
02400       _DBUS_POLLPRI == POLLPRI &&
02401       _DBUS_POLLOUT == POLLOUT &&
02402       _DBUS_POLLERR == POLLERR &&
02403       _DBUS_POLLHUP == POLLHUP &&
02404       _DBUS_POLLNVAL == POLLNVAL &&
02405       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02406       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02407       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02408       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02409       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02410       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02411       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02412     {
02413       return poll ((struct pollfd*) fds,
02414                    n_fds,
02415                    timeout_milliseconds);
02416     }
02417   else
02418     {
02419       /* We have to convert the DBusPollFD to an array of
02420        * struct pollfd, poll, and convert back.
02421        */
02422       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02423       return -1;
02424     }
02425 #else /* ! HAVE_POLL */
02426 
02427   fd_set read_set, write_set, err_set;
02428   int max_fd = 0;
02429   int i;
02430   struct timeval tv;
02431   int ready;
02432 
02433   FD_ZERO (&read_set);
02434   FD_ZERO (&write_set);
02435   FD_ZERO (&err_set);
02436 
02437   for (i = 0; i < n_fds; i++)
02438     {
02439       DBusPollFD *fdp = &fds[i];
02440 
02441       if (fdp->events & _DBUS_POLLIN)
02442         FD_SET (fdp->fd, &read_set);
02443 
02444       if (fdp->events & _DBUS_POLLOUT)
02445         FD_SET (fdp->fd, &write_set);
02446 
02447       FD_SET (fdp->fd, &err_set);
02448 
02449       max_fd = MAX (max_fd, fdp->fd);
02450     }
02451 
02452   tv.tv_sec = timeout_milliseconds / 1000;
02453   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02454 
02455   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02456                   timeout_milliseconds < 0 ? NULL : &tv);
02457 
02458   if (ready > 0)
02459     {
02460       for (i = 0; i < n_fds; i++)
02461         {
02462           DBusPollFD *fdp = &fds[i];
02463 
02464           fdp->revents = 0;
02465 
02466           if (FD_ISSET (fdp->fd, &read_set))
02467             fdp->revents |= _DBUS_POLLIN;
02468 
02469           if (FD_ISSET (fdp->fd, &write_set))
02470             fdp->revents |= _DBUS_POLLOUT;
02471 
02472           if (FD_ISSET (fdp->fd, &err_set))
02473             fdp->revents |= _DBUS_POLLERR;
02474         }
02475     }
02476 
02477   return ready;
02478 #endif
02479 }
02480 
02488 void
02489 _dbus_get_current_time (long *tv_sec,
02490                         long *tv_usec)
02491 {
02492   struct timeval t;
02493 
02494 #ifdef HAVE_MONOTONIC_CLOCK
02495   struct timespec ts;
02496   clock_gettime (CLOCK_MONOTONIC, &ts);
02497 
02498   if (tv_sec)
02499     *tv_sec = ts.tv_sec;
02500   if (tv_usec)
02501     *tv_usec = ts.tv_nsec / 1000;
02502 #else
02503   gettimeofday (&t, NULL);
02504 
02505   if (tv_sec)
02506     *tv_sec = t.tv_sec;
02507   if (tv_usec)
02508     *tv_usec = t.tv_usec;
02509 #endif
02510 }
02511 
02520 dbus_bool_t
02521 _dbus_create_directory (const DBusString *filename,
02522                         DBusError        *error)
02523 {
02524   const char *filename_c;
02525 
02526   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02527 
02528   filename_c = _dbus_string_get_const_data (filename);
02529 
02530   if (mkdir (filename_c, 0700) < 0)
02531     {
02532       if (errno == EEXIST)
02533         return TRUE;
02534 
02535       dbus_set_error (error, DBUS_ERROR_FAILED,
02536                       "Failed to create directory %s: %s\n",
02537                       filename_c, _dbus_strerror (errno));
02538       return FALSE;
02539     }
02540   else
02541     return TRUE;
02542 }
02543 
02554 dbus_bool_t
02555 _dbus_concat_dir_and_file (DBusString       *dir,
02556                            const DBusString *next_component)
02557 {
02558   dbus_bool_t dir_ends_in_slash;
02559   dbus_bool_t file_starts_with_slash;
02560 
02561   if (_dbus_string_get_length (dir) == 0 ||
02562       _dbus_string_get_length (next_component) == 0)
02563     return TRUE;
02564 
02565   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02566                                                     _dbus_string_get_length (dir) - 1);
02567 
02568   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02569 
02570   if (dir_ends_in_slash && file_starts_with_slash)
02571     {
02572       _dbus_string_shorten (dir, 1);
02573     }
02574   else if (!(dir_ends_in_slash || file_starts_with_slash))
02575     {
02576       if (!_dbus_string_append_byte (dir, '/'))
02577         return FALSE;
02578     }
02579 
02580   return _dbus_string_copy (next_component, 0, dir,
02581                             _dbus_string_get_length (dir));
02582 }
02583 
02585 #define NANOSECONDS_PER_SECOND       1000000000
02586 
02587 #define MICROSECONDS_PER_SECOND      1000000
02588 
02589 #define MILLISECONDS_PER_SECOND      1000
02590 
02591 #define NANOSECONDS_PER_MILLISECOND  1000000
02592 
02593 #define MICROSECONDS_PER_MILLISECOND 1000
02594 
02599 void
02600 _dbus_sleep_milliseconds (int milliseconds)
02601 {
02602 #ifdef HAVE_NANOSLEEP
02603   struct timespec req;
02604   struct timespec rem;
02605 
02606   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02607   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02608   rem.tv_sec = 0;
02609   rem.tv_nsec = 0;
02610 
02611   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02612     req = rem;
02613 #elif defined (HAVE_USLEEP)
02614   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02615 #else /* ! HAVE_USLEEP */
02616   sleep (MAX (milliseconds / 1000, 1));
02617 #endif
02618 }
02619 
02620 static dbus_bool_t
02621 _dbus_generate_pseudorandom_bytes (DBusString *str,
02622                                    int         n_bytes)
02623 {
02624   int old_len;
02625   char *p;
02626 
02627   old_len = _dbus_string_get_length (str);
02628 
02629   if (!_dbus_string_lengthen (str, n_bytes))
02630     return FALSE;
02631 
02632   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02633 
02634   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02635 
02636   return TRUE;
02637 }
02638 
02647 dbus_bool_t
02648 _dbus_generate_random_bytes (DBusString *str,
02649                              int         n_bytes)
02650 {
02651   int old_len;
02652   int fd;
02653 
02654   /* FALSE return means "no memory", if it could
02655    * mean something else then we'd need to return
02656    * a DBusError. So we always fall back to pseudorandom
02657    * if the I/O fails.
02658    */
02659 
02660   old_len = _dbus_string_get_length (str);
02661   fd = -1;
02662 
02663   /* note, urandom on linux will fall back to pseudorandom */
02664   fd = open ("/dev/urandom", O_RDONLY);
02665   if (fd < 0)
02666     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02667 
02668   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02669 
02670   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02671     {
02672       _dbus_close (fd, NULL);
02673       _dbus_string_set_length (str, old_len);
02674       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02675     }
02676 
02677   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02678                  n_bytes);
02679 
02680   _dbus_close (fd, NULL);
02681 
02682   return TRUE;
02683 }
02684 
02690 void
02691 _dbus_exit (int code)
02692 {
02693   _exit (code);
02694 }
02695 
02704 const char*
02705 _dbus_strerror (int error_number)
02706 {
02707   const char *msg;
02708 
02709   msg = strerror (error_number);
02710   if (msg == NULL)
02711     msg = "unknown";
02712 
02713   return msg;
02714 }
02715 
02719 void
02720 _dbus_disable_sigpipe (void)
02721 {
02722   signal (SIGPIPE, SIG_IGN);
02723 }
02724 
02732 void
02733 _dbus_fd_set_close_on_exec (intptr_t fd)
02734 {
02735   int val;
02736 
02737   val = fcntl (fd, F_GETFD, 0);
02738 
02739   if (val < 0)
02740     return;
02741 
02742   val |= FD_CLOEXEC;
02743 
02744   fcntl (fd, F_SETFD, val);
02745 }
02746 
02754 dbus_bool_t
02755 _dbus_close (int        fd,
02756              DBusError *error)
02757 {
02758   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02759 
02760  again:
02761   if (close (fd) < 0)
02762     {
02763       if (errno == EINTR)
02764         goto again;
02765 
02766       dbus_set_error (error, _dbus_error_from_errno (errno),
02767                       "Could not close fd %d", fd);
02768       return FALSE;
02769     }
02770 
02771   return TRUE;
02772 }
02773 
02781 int
02782 _dbus_dup(int        fd,
02783           DBusError *error)
02784 {
02785   int new_fd;
02786 
02787 #ifdef F_DUPFD_CLOEXEC
02788   dbus_bool_t cloexec_done;
02789 
02790   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02791   cloexec_done = new_fd >= 0;
02792 
02793   if (new_fd < 0 && errno == EINVAL)
02794 #endif
02795     {
02796       new_fd = fcntl(fd, F_DUPFD, 3);
02797     }
02798 
02799   if (new_fd < 0) {
02800 
02801     dbus_set_error (error, _dbus_error_from_errno (errno),
02802                     "Could not duplicate fd %d", fd);
02803     return -1;
02804   }
02805 
02806 #ifdef F_DUPFD_CLOEXEC
02807   if (!cloexec_done)
02808 #endif
02809     {
02810       _dbus_fd_set_close_on_exec(new_fd);
02811     }
02812 
02813   return new_fd;
02814 }
02815 
02823 dbus_bool_t
02824 _dbus_set_fd_nonblocking (int             fd,
02825                           DBusError      *error)
02826 {
02827   int val;
02828 
02829   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02830 
02831   val = fcntl (fd, F_GETFL, 0);
02832   if (val < 0)
02833     {
02834       dbus_set_error (error, _dbus_error_from_errno (errno),
02835                       "Failed to get flags from file descriptor %d: %s",
02836                       fd, _dbus_strerror (errno));
02837       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02838                      _dbus_strerror (errno));
02839       return FALSE;
02840     }
02841 
02842   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02843     {
02844       dbus_set_error (error, _dbus_error_from_errno (errno),
02845                       "Failed to set nonblocking flag of file descriptor %d: %s",
02846                       fd, _dbus_strerror (errno));
02847       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02848                      fd, _dbus_strerror (errno));
02849 
02850       return FALSE;
02851     }
02852 
02853   return TRUE;
02854 }
02855 
02861 void
02862 _dbus_print_backtrace (void)
02863 {
02864 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02865   void *bt[500];
02866   int bt_size;
02867   int i;
02868   char **syms;
02869 
02870   bt_size = backtrace (bt, 500);
02871 
02872   syms = backtrace_symbols (bt, bt_size);
02873 
02874   i = 0;
02875   while (i < bt_size)
02876     {
02877       /* don't use dbus_warn since it can _dbus_abort() */
02878       fprintf (stderr, "  %s\n", syms[i]);
02879       ++i;
02880     }
02881   fflush (stderr);
02882 
02883   free (syms);
02884 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02885   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02886 #else
02887   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02888 #endif
02889 }
02890 
02908 dbus_bool_t
02909 _dbus_full_duplex_pipe (int        *fd1,
02910                         int        *fd2,
02911                         dbus_bool_t blocking,
02912                         DBusError  *error)
02913 {
02914 #ifdef HAVE_SOCKETPAIR
02915   int fds[2];
02916   int retval;
02917 
02918 #ifdef SOCK_CLOEXEC
02919   dbus_bool_t cloexec_done;
02920 
02921   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02922   cloexec_done = retval >= 0;
02923 
02924   if (retval < 0 && errno == EINVAL)
02925 #endif
02926     {
02927       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02928     }
02929 
02930   if (retval < 0)
02931     {
02932       dbus_set_error (error, _dbus_error_from_errno (errno),
02933                       "Could not create full-duplex pipe");
02934       return FALSE;
02935     }
02936 
02937   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02938 
02939 #ifdef SOCK_CLOEXEC
02940   if (!cloexec_done)
02941 #endif
02942     {
02943       _dbus_fd_set_close_on_exec (fds[0]);
02944       _dbus_fd_set_close_on_exec (fds[1]);
02945     }
02946 
02947   if (!blocking &&
02948       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02949        !_dbus_set_fd_nonblocking (fds[1], NULL)))
02950     {
02951       dbus_set_error (error, _dbus_error_from_errno (errno),
02952                       "Could not set full-duplex pipe nonblocking");
02953 
02954       _dbus_close (fds[0], NULL);
02955       _dbus_close (fds[1], NULL);
02956 
02957       return FALSE;
02958     }
02959 
02960   *fd1 = fds[0];
02961   *fd2 = fds[1];
02962 
02963   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02964                  *fd1, *fd2);
02965 
02966   return TRUE;
02967 #else
02968   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02969   dbus_set_error (error, DBUS_ERROR_FAILED,
02970                   "_dbus_full_duplex_pipe() not implemented on this OS");
02971   return FALSE;
02972 #endif
02973 }
02974 
02983 int
02984 _dbus_printf_string_upper_bound (const char *format,
02985                                  va_list     args)
02986 {
02987   char c;
02988   return vsnprintf (&c, 1, format, args);
02989 }
02990 
02997 const char*
02998 _dbus_get_tmpdir(void)
02999 {
03000   static const char* tmpdir = NULL;
03001 
03002   if (tmpdir == NULL)
03003     {
03004       /* TMPDIR is what glibc uses, then
03005        * glibc falls back to the P_tmpdir macro which
03006        * just expands to "/tmp"
03007        */
03008       if (tmpdir == NULL)
03009         tmpdir = getenv("TMPDIR");
03010 
03011       /* These two env variables are probably
03012        * broken, but maybe some OS uses them?
03013        */
03014       if (tmpdir == NULL)
03015         tmpdir = getenv("TMP");
03016       if (tmpdir == NULL)
03017         tmpdir = getenv("TEMP");
03018 
03019       /* And this is the sane fallback. */
03020       if (tmpdir == NULL)
03021         tmpdir = "/tmp";
03022     }
03023 
03024   _dbus_assert(tmpdir != NULL);
03025 
03026   return tmpdir;
03027 }
03028 
03048 static dbus_bool_t
03049 _read_subprocess_line_argv (const char *progpath,
03050                             dbus_bool_t path_fallback,
03051                             char       * const *argv,
03052                             DBusString *result,
03053                             DBusError  *error)
03054 {
03055   int result_pipe[2] = { -1, -1 };
03056   int errors_pipe[2] = { -1, -1 };
03057   pid_t pid;
03058   int ret;
03059   int status;
03060   int orig_len;
03061   int i;
03062 
03063   dbus_bool_t retval;
03064   sigset_t new_set, old_set;
03065 
03066   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03067   retval = FALSE;
03068 
03069   /* We need to block any existing handlers for SIGCHLD temporarily; they
03070    * will cause waitpid() below to fail.
03071    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03072    */
03073   sigemptyset (&new_set);
03074   sigaddset (&new_set, SIGCHLD);
03075   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03076 
03077   orig_len = _dbus_string_get_length (result);
03078 
03079 #define READ_END        0
03080 #define WRITE_END       1
03081   if (pipe (result_pipe) < 0)
03082     {
03083       dbus_set_error (error, _dbus_error_from_errno (errno),
03084                       "Failed to create a pipe to call %s: %s",
03085                       progpath, _dbus_strerror (errno));
03086       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03087                      progpath, _dbus_strerror (errno));
03088       goto out;
03089     }
03090   if (pipe (errors_pipe) < 0)
03091     {
03092       dbus_set_error (error, _dbus_error_from_errno (errno),
03093                       "Failed to create a pipe to call %s: %s",
03094                       progpath, _dbus_strerror (errno));
03095       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03096                      progpath, _dbus_strerror (errno));
03097       goto out;
03098     }
03099 
03100   pid = fork ();
03101   if (pid < 0)
03102     {
03103       dbus_set_error (error, _dbus_error_from_errno (errno),
03104                       "Failed to fork() to call %s: %s",
03105                       progpath, _dbus_strerror (errno));
03106       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03107                      progpath, _dbus_strerror (errno));
03108       goto out;
03109     }
03110 
03111   if (pid == 0)
03112     {
03113       /* child process */
03114       int maxfds;
03115       int fd;
03116 
03117       fd = open ("/dev/null", O_RDWR);
03118       if (fd == -1)
03119         /* huh?! can't open /dev/null? */
03120         _exit (1);
03121 
03122       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03123 
03124       /* set-up stdXXX */
03125       close (result_pipe[READ_END]);
03126       close (errors_pipe[READ_END]);
03127       close (0);                /* close stdin */
03128       close (1);                /* close stdout */
03129       close (2);                /* close stderr */
03130 
03131       if (dup2 (fd, 0) == -1)
03132         _exit (1);
03133       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03134         _exit (1);
03135       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03136         _exit (1);
03137 
03138       maxfds = sysconf (_SC_OPEN_MAX);
03139       /* Pick something reasonable if for some reason sysconf
03140        * says unlimited.
03141        */
03142       if (maxfds < 0)
03143         maxfds = 1024;
03144       /* close all inherited fds */
03145       for (i = 3; i < maxfds; i++)
03146         close (i);
03147 
03148       sigprocmask (SIG_SETMASK, &old_set, NULL);
03149 
03150       /* If it looks fully-qualified, try execv first */
03151       if (progpath[0] == '/')
03152         {
03153           execv (progpath, argv);
03154           /* Ok, that failed.  Now if path_fallback is given, let's
03155            * try unqualified.  This is mostly a hack to work
03156            * around systems which ship dbus-launch in /usr/bin
03157            * but everything else in /bin (because dbus-launch
03158            * depends on X11).
03159            */
03160           if (path_fallback)
03161             /* We must have a slash, because we checked above */
03162             execvp (strrchr (progpath, '/')+1, argv);
03163         }
03164       else
03165         execvp (progpath, argv);
03166 
03167       /* still nothing, we failed */
03168       _exit (1);
03169     }
03170 
03171   /* parent process */
03172   close (result_pipe[WRITE_END]);
03173   close (errors_pipe[WRITE_END]);
03174   result_pipe[WRITE_END] = -1;
03175   errors_pipe[WRITE_END] = -1;
03176 
03177   ret = 0;
03178   do
03179     {
03180       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03181     }
03182   while (ret > 0);
03183 
03184   /* reap the child process to avoid it lingering as zombie */
03185   do
03186     {
03187       ret = waitpid (pid, &status, 0);
03188     }
03189   while (ret == -1 && errno == EINTR);
03190 
03191   /* We succeeded if the process exited with status 0 and
03192      anything was read */
03193   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03194     {
03195       /* The process ended with error */
03196       DBusString error_message;
03197       if (!_dbus_string_init (&error_message))
03198         {
03199           _DBUS_SET_OOM (error);
03200           goto out;
03201         }
03202 
03203       ret = 0;
03204       do
03205         {
03206           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03207         }
03208       while (ret > 0);
03209 
03210       _dbus_string_set_length (result, orig_len);
03211       if (_dbus_string_get_length (&error_message) > 0)
03212         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03213                         "%s terminated abnormally with the following error: %s",
03214                         progpath, _dbus_string_get_data (&error_message));
03215       else
03216         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03217                         "%s terminated abnormally without any error message",
03218                         progpath);
03219       goto out;
03220     }
03221 
03222   retval = TRUE;
03223 
03224  out:
03225   sigprocmask (SIG_SETMASK, &old_set, NULL);
03226 
03227   if (retval)
03228     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03229   else
03230     _DBUS_ASSERT_ERROR_IS_SET (error);
03231 
03232   if (result_pipe[0] != -1)
03233     close (result_pipe[0]);
03234   if (result_pipe[1] != -1)
03235     close (result_pipe[1]);
03236   if (errors_pipe[0] != -1)
03237     close (errors_pipe[0]);
03238   if (errors_pipe[1] != -1)
03239     close (errors_pipe[1]);
03240 
03241   return retval;
03242 }
03243 
03255 dbus_bool_t
03256 _dbus_get_autolaunch_address (const char *scope,
03257                               DBusString *address,
03258                               DBusError  *error)
03259 {
03260 #ifdef DBUS_ENABLE_X11_AUTOLAUNCH
03261   /* Perform X11-based autolaunch. (We also support launchd-based autolaunch,
03262    * but that's done elsewhere, and if it worked, this function wouldn't
03263    * be called.) */
03264   const char *display;
03265   static char *argv[6];
03266   int i;
03267   DBusString uuid;
03268   dbus_bool_t retval;
03269 
03270   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03271   retval = FALSE;
03272 
03273   /* fd.o #19997: if $DISPLAY isn't set to something useful, then
03274    * dbus-launch-x11 is just going to fail. Rather than trying to
03275    * run it, we might as well bail out early with a nice error. */
03276   display = _dbus_getenv ("DISPLAY");
03277 
03278   if (display == NULL || display[0] == '\0')
03279     {
03280       dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03281           "Unable to autolaunch a dbus-daemon without a $DISPLAY for X11");
03282       return FALSE;
03283     }
03284 
03285   if (!_dbus_string_init (&uuid))
03286     {
03287       _DBUS_SET_OOM (error);
03288       return FALSE;
03289     }
03290 
03291   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03292     {
03293       _DBUS_SET_OOM (error);
03294       goto out;
03295     }
03296 
03297   i = 0;
03298   argv[i] = "dbus-launch";
03299   ++i;
03300   argv[i] = "--autolaunch";
03301   ++i;
03302   argv[i] = _dbus_string_get_data (&uuid);
03303   ++i;
03304   argv[i] = "--binary-syntax";
03305   ++i;
03306   argv[i] = "--close-stderr";
03307   ++i;
03308   argv[i] = NULL;
03309   ++i;
03310 
03311   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03312 
03313   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03314                                        TRUE,
03315                                        argv, address, error);
03316 
03317  out:
03318   _dbus_string_free (&uuid);
03319   return retval;
03320 #else
03321   dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
03322       "Using X11 for dbus-daemon autolaunch was disabled at compile time, "
03323       "set your DBUS_SESSION_BUS_ADDRESS instead");
03324   return FALSE;
03325 #endif
03326 }
03327 
03346 dbus_bool_t
03347 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03348                                dbus_bool_t create_if_not_found,
03349                                DBusError  *error)
03350 {
03351   DBusString filename;
03352   dbus_bool_t b;
03353 
03354   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03355 
03356   b = _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03357   if (b)
03358     return TRUE;
03359 
03360   dbus_error_free (error);
03361 
03362   /* Fallback to the system machine ID */
03363   _dbus_string_init_const (&filename, "/etc/machine-id");
03364   return _dbus_read_uuid_file (&filename, machine_id, FALSE, error);
03365 }
03366 
03367 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03368 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03369 
03376 dbus_bool_t
03377 _dbus_lookup_launchd_socket (DBusString *socket_path,
03378                              const char *launchd_env_var,
03379                              DBusError  *error)
03380 {
03381 #ifdef DBUS_ENABLE_LAUNCHD
03382   char *argv[4];
03383   int i;
03384 
03385   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03386 
03387   i = 0;
03388   argv[i] = "launchctl";
03389   ++i;
03390   argv[i] = "getenv";
03391   ++i;
03392   argv[i] = (char*)launchd_env_var;
03393   ++i;
03394   argv[i] = NULL;
03395   ++i;
03396 
03397   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03398 
03399   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03400     {
03401       return FALSE;
03402     }
03403 
03404   /* no error, but no result either */
03405   if (_dbus_string_get_length(socket_path) == 0)
03406     {
03407       return FALSE;
03408     }
03409 
03410   /* strip the carriage-return */
03411   _dbus_string_shorten(socket_path, 1);
03412   return TRUE;
03413 #else /* DBUS_ENABLE_LAUNCHD */
03414   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03415                 "can't lookup socket from launchd; launchd support not compiled in");
03416   return FALSE;
03417 #endif
03418 }
03419 
03420 static dbus_bool_t
03421 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03422 {
03423 #ifdef DBUS_ENABLE_LAUNCHD
03424   dbus_bool_t valid_socket;
03425   DBusString socket_path;
03426 
03427   if (!_dbus_string_init (&socket_path))
03428     {
03429       _DBUS_SET_OOM (error);
03430       return FALSE;
03431     }
03432 
03433   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03434 
03435   if (dbus_error_is_set(error))
03436     {
03437       _dbus_string_free(&socket_path);
03438       return FALSE;
03439     }
03440 
03441   if (!valid_socket)
03442     {
03443       dbus_set_error(error, "no socket path",
03444                 "launchd did not provide a socket path, "
03445                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03446       _dbus_string_free(&socket_path);
03447       return FALSE;
03448     }
03449   if (!_dbus_string_append (address, "unix:path="))
03450     {
03451       _DBUS_SET_OOM (error);
03452       _dbus_string_free(&socket_path);
03453       return FALSE;
03454     }
03455   if (!_dbus_string_copy (&socket_path, 0, address,
03456                           _dbus_string_get_length (address)))
03457     {
03458       _DBUS_SET_OOM (error);
03459       _dbus_string_free(&socket_path);
03460       return FALSE;
03461     }
03462 
03463   _dbus_string_free(&socket_path);
03464   return TRUE;
03465 #else
03466   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03467                 "can't lookup session address from launchd; launchd support not compiled in");
03468   return FALSE;
03469 #endif
03470 }
03471 
03491 dbus_bool_t
03492 _dbus_lookup_session_address (dbus_bool_t *supported,
03493                               DBusString  *address,
03494                               DBusError   *error)
03495 {
03496 #ifdef DBUS_ENABLE_LAUNCHD
03497   *supported = TRUE;
03498   return _dbus_lookup_session_address_launchd (address, error);
03499 #else
03500   /* On non-Mac Unix platforms, if the session address isn't already
03501    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03502    * fall back to the autolaunch: global default; see
03503    * init_session_address in dbus/dbus-bus.c. */
03504   *supported = FALSE;
03505   return TRUE;
03506 #endif
03507 }
03508 
03526 dbus_bool_t
03527 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03528 {
03529   const char *xdg_data_home;
03530   const char *xdg_data_dirs;
03531   DBusString servicedir_path;
03532 
03533   if (!_dbus_string_init (&servicedir_path))
03534     return FALSE;
03535 
03536   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03537   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03538 
03539   if (xdg_data_home != NULL)
03540     {
03541       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03542         goto oom;
03543     }
03544   else
03545     {
03546       const DBusString *homedir;
03547       DBusString local_share;
03548 
03549       if (!_dbus_homedir_from_current_process (&homedir))
03550         goto oom;
03551 
03552       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03553         goto oom;
03554 
03555       _dbus_string_init_const (&local_share, "/.local/share");
03556       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03557         goto oom;
03558     }
03559 
03560   if (!_dbus_string_append (&servicedir_path, ":"))
03561     goto oom;
03562 
03563   if (xdg_data_dirs != NULL)
03564     {
03565       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03566         goto oom;
03567 
03568       if (!_dbus_string_append (&servicedir_path, ":"))
03569         goto oom;
03570     }
03571   else
03572     {
03573       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03574         goto oom;
03575     }
03576 
03577   /*
03578    * add configured datadir to defaults
03579    * this may be the same as an xdg dir
03580    * however the config parser should take
03581    * care of duplicates
03582    */
03583   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
03584     goto oom;
03585 
03586   if (!_dbus_split_paths_and_append (&servicedir_path,
03587                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03588                                      dirs))
03589     goto oom;
03590 
03591   _dbus_string_free (&servicedir_path);
03592   return TRUE;
03593 
03594  oom:
03595   _dbus_string_free (&servicedir_path);
03596   return FALSE;
03597 }
03598 
03599 
03618 dbus_bool_t
03619 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03620 {
03621   const char *xdg_data_dirs;
03622   DBusString servicedir_path;
03623 
03624   if (!_dbus_string_init (&servicedir_path))
03625     return FALSE;
03626 
03627   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03628 
03629   if (xdg_data_dirs != NULL)
03630     {
03631       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03632         goto oom;
03633 
03634       if (!_dbus_string_append (&servicedir_path, ":"))
03635         goto oom;
03636     }
03637   else
03638     {
03639       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03640         goto oom;
03641     }
03642 
03643   /*
03644    * add configured datadir to defaults
03645    * this may be the same as an xdg dir
03646    * however the config parser should take
03647    * care of duplicates
03648    */
03649   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03650         goto oom;
03651 
03652   if (!_dbus_split_paths_and_append (&servicedir_path,
03653                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03654                                      dirs))
03655     goto oom;
03656 
03657   _dbus_string_free (&servicedir_path);
03658   return TRUE;
03659 
03660  oom:
03661   _dbus_string_free (&servicedir_path);
03662   return FALSE;
03663 }
03664 
03673 dbus_bool_t
03674 _dbus_append_system_config_file (DBusString *str)
03675 {
03676   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03677 }
03678 
03685 dbus_bool_t
03686 _dbus_append_session_config_file (DBusString *str)
03687 {
03688   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03689 }
03690 
03698 void
03699 _dbus_flush_caches (void)
03700 {
03701   _dbus_user_database_flush_system ();
03702 }
03703 
03717 dbus_bool_t
03718 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03719                                                 DBusCredentials *credentials)
03720 {
03721   DBusString homedir;
03722   DBusString dotdir;
03723   dbus_uid_t uid;
03724 
03725   _dbus_assert (credentials != NULL);
03726   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03727 
03728   if (!_dbus_string_init (&homedir))
03729     return FALSE;
03730 
03731   uid = _dbus_credentials_get_unix_uid (credentials);
03732   _dbus_assert (uid != DBUS_UID_UNSET);
03733 
03734   if (!_dbus_homedir_from_uid (uid, &homedir))
03735     goto failed;
03736 
03737 #ifdef DBUS_BUILD_TESTS
03738   {
03739     const char *override;
03740 
03741     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03742     if (override != NULL && *override != '\0')
03743       {
03744         _dbus_string_set_length (&homedir, 0);
03745         if (!_dbus_string_append (&homedir, override))
03746           goto failed;
03747 
03748         _dbus_verbose ("Using fake homedir for testing: %s\n",
03749                        _dbus_string_get_const_data (&homedir));
03750       }
03751     else
03752       {
03753         static dbus_bool_t already_warned = FALSE;
03754         if (!already_warned)
03755           {
03756             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03757             already_warned = TRUE;
03758           }
03759       }
03760   }
03761 #endif
03762 
03763   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03764   if (!_dbus_concat_dir_and_file (&homedir,
03765                                   &dotdir))
03766     goto failed;
03767 
03768   if (!_dbus_string_copy (&homedir, 0,
03769                           directory, _dbus_string_get_length (directory))) {
03770     goto failed;
03771   }
03772 
03773   _dbus_string_free (&homedir);
03774   return TRUE;
03775 
03776  failed:
03777   _dbus_string_free (&homedir);
03778   return FALSE;
03779 }
03780 
03781 //PENDING(kdab) docs
03782 dbus_bool_t
03783 _dbus_daemon_publish_session_bus_address (const char* addr,
03784                                           const char *scope)
03785 {
03786   return TRUE;
03787 }
03788 
03789 //PENDING(kdab) docs
03790 void
03791 _dbus_daemon_unpublish_session_bus_address (void)
03792 {
03793 
03794 }
03795 
03802 dbus_bool_t
03803 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03804 {
03805   return errno == EAGAIN || errno == EWOULDBLOCK;
03806 }
03807 
03815 dbus_bool_t
03816 _dbus_delete_directory (const DBusString *filename,
03817                         DBusError        *error)
03818 {
03819   const char *filename_c;
03820 
03821   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03822 
03823   filename_c = _dbus_string_get_const_data (filename);
03824 
03825   if (rmdir (filename_c) != 0)
03826     {
03827       dbus_set_error (error, DBUS_ERROR_FAILED,
03828                       "Failed to remove directory %s: %s\n",
03829                       filename_c, _dbus_strerror (errno));
03830       return FALSE;
03831     }
03832 
03833   return TRUE;
03834 }
03835 
03843 dbus_bool_t
03844 _dbus_socket_can_pass_unix_fd(int fd) {
03845 
03846 #ifdef SCM_RIGHTS
03847   union {
03848     struct sockaddr sa;
03849     struct sockaddr_storage storage;
03850     struct sockaddr_un un;
03851   } sa_buf;
03852 
03853   socklen_t sa_len = sizeof(sa_buf);
03854 
03855   _DBUS_ZERO(sa_buf);
03856 
03857   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03858     return FALSE;
03859 
03860   return sa_buf.sa.sa_family == AF_UNIX;
03861 
03862 #else
03863   return FALSE;
03864 
03865 #endif
03866 }
03867 
03868 
03869 /*
03870  * replaces the term DBUS_PREFIX in configure_time_path by the
03871  * current dbus installation directory. On unix this function is a noop
03872  *
03873  * @param configure_time_path
03874  * @return real path
03875  */
03876 const char *
03877 _dbus_replace_install_prefix (const char *configure_time_path)
03878 {
03879   return configure_time_path;
03880 }
03881 
03882 /* tests in dbus-sysdeps-util.c */