D-Bus 1.4.1

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 #ifdef 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 #ifdef 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 #ifdef 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               struct sockaddr_storage addr;
01392               socklen_t addrlen;
01393               char portbuf[50];
01394 
01395               addrlen = sizeof(addr);
01396               getsockname(fd, (struct sockaddr*) &addr, &addrlen);
01397 
01398               if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
01399                                      portbuf, sizeof(portbuf),
01400                                      NI_NUMERICHOST)) != 0)
01401                 {
01402                   dbus_set_error (error, _dbus_error_from_errno (errno),
01403                                   "Failed to resolve port \"%s:%s\": %s (%s)",
01404                                   host ? host : "*", port, gai_strerror(res), res);
01405                   goto failed;
01406                 }
01407               if (!_dbus_string_append(retport, portbuf))
01408                 {
01409                   dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01410                   goto failed;
01411                 }
01412 
01413               /* Release current address list & redo lookup */
01414               port = _dbus_string_get_const_data(retport);
01415               freeaddrinfo(ai);
01416               goto redo_lookup_with_port;
01417             }
01418           else
01419             {
01420               if (!_dbus_string_append(retport, port))
01421                 {
01422                     dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01423                     goto failed;
01424                 }
01425             }
01426         }
01427 
01428       tmp = tmp->ai_next;
01429     }
01430   freeaddrinfo(ai);
01431   ai = NULL;
01432 
01433   if (!nlisten_fd)
01434     {
01435       errno = EADDRINUSE;
01436       dbus_set_error (error, _dbus_error_from_errno (errno),
01437                       "Failed to bind socket \"%s:%s\": %s",
01438                       host ? host : "*", port, _dbus_strerror (errno));
01439       return -1;
01440     }
01441 
01442   for (i = 0 ; i < nlisten_fd ; i++)
01443     {
01444       if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
01445         {
01446           goto failed;
01447         }
01448     }
01449 
01450   *fds_p = listen_fd;
01451 
01452   return nlisten_fd;
01453 
01454  failed:
01455   if (ai)
01456     freeaddrinfo(ai);
01457   for (i = 0 ; i < nlisten_fd ; i++)
01458     _dbus_close(listen_fd[i], NULL);
01459   dbus_free(listen_fd);
01460   return -1;
01461 }
01462 
01463 static dbus_bool_t
01464 write_credentials_byte (int             server_fd,
01465                         DBusError      *error)
01466 {
01467   int bytes_written;
01468   char buf[1] = { '\0' };
01469 #if defined(HAVE_CMSGCRED)
01470   union {
01471           struct cmsghdr hdr;
01472           char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01473   } cmsg;
01474   struct iovec iov;
01475   struct msghdr msg;
01476   iov.iov_base = buf;
01477   iov.iov_len = 1;
01478 
01479   _DBUS_ZERO(msg);
01480   msg.msg_iov = &iov;
01481   msg.msg_iovlen = 1;
01482 
01483   msg.msg_control = (caddr_t) &cmsg;
01484   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01485   _DBUS_ZERO(cmsg);
01486   cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
01487   cmsg.hdr.cmsg_level = SOL_SOCKET;
01488   cmsg.hdr.cmsg_type = SCM_CREDS;
01489 #endif
01490 
01491   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01492 
01493  again:
01494 
01495 #if defined(HAVE_CMSGCRED)
01496   bytes_written = sendmsg (server_fd, &msg, 0
01497 #ifdef HAVE_DECL_MSG_NOSIGNAL
01498                            |MSG_NOSIGNAL
01499 #endif
01500                            );
01501 #else
01502   bytes_written = send (server_fd, buf, 1, 0
01503 #ifdef HAVE_DECL_MSG_NOSIGNAL
01504                         |MSG_NOSIGNAL
01505 #endif
01506                         );
01507 #endif
01508 
01509   if (bytes_written < 0 && errno == EINTR)
01510     goto again;
01511 
01512   if (bytes_written < 0)
01513     {
01514       dbus_set_error (error, _dbus_error_from_errno (errno),
01515                       "Failed to write credentials byte: %s",
01516                      _dbus_strerror (errno));
01517       return FALSE;
01518     }
01519   else if (bytes_written == 0)
01520     {
01521       dbus_set_error (error, DBUS_ERROR_IO_ERROR,
01522                       "wrote zero bytes writing credentials byte");
01523       return FALSE;
01524     }
01525   else
01526     {
01527       _dbus_assert (bytes_written == 1);
01528       _dbus_verbose ("wrote credentials byte\n");
01529       return TRUE;
01530     }
01531 }
01532 
01554 dbus_bool_t
01555 _dbus_read_credentials_socket  (int              client_fd,
01556                                 DBusCredentials *credentials,
01557                                 DBusError       *error)
01558 {
01559   struct msghdr msg;
01560   struct iovec iov;
01561   char buf;
01562   dbus_uid_t uid_read;
01563   dbus_pid_t pid_read;
01564   int bytes_read;
01565 
01566 #ifdef HAVE_CMSGCRED
01567   union {
01568     struct cmsghdr hdr;
01569     char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
01570   } cmsg;
01571 
01572 #elif defined(LOCAL_CREDS)
01573   struct {
01574     struct cmsghdr hdr;
01575     struct sockcred cred;
01576   } cmsg;
01577 #endif
01578 
01579   uid_read = DBUS_UID_UNSET;
01580   pid_read = DBUS_PID_UNSET;
01581 
01582   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01583 
01584   /* The POSIX spec certainly doesn't promise this, but
01585    * we need these assertions to fail as soon as we're wrong about
01586    * it so we can do the porting fixups
01587    */
01588   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
01589   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
01590   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
01591 
01592   _dbus_credentials_clear (credentials);
01593 
01594   /* Systems supporting LOCAL_CREDS are configured to have this feature
01595    * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
01596    * the connection.  Therefore, the received message must carry the
01597    * credentials information without doing anything special.
01598    */
01599 
01600   iov.iov_base = &buf;
01601   iov.iov_len = 1;
01602 
01603   _DBUS_ZERO(msg);
01604   msg.msg_iov = &iov;
01605   msg.msg_iovlen = 1;
01606 
01607 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01608   _DBUS_ZERO(cmsg);
01609   msg.msg_control = (caddr_t) &cmsg;
01610   msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
01611 #endif
01612 
01613  again:
01614   bytes_read = recvmsg (client_fd, &msg, 0);
01615 
01616   if (bytes_read < 0)
01617     {
01618       if (errno == EINTR)
01619         goto again;
01620 
01621       /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
01622        * normally only call read_credentials if the socket was ready
01623        * for reading
01624        */
01625 
01626       dbus_set_error (error, _dbus_error_from_errno (errno),
01627                       "Failed to read credentials byte: %s",
01628                       _dbus_strerror (errno));
01629       return FALSE;
01630     }
01631   else if (bytes_read == 0)
01632     {
01633       /* this should not happen unless we are using recvmsg wrong,
01634        * so is essentially here for paranoia
01635        */
01636       dbus_set_error (error, DBUS_ERROR_FAILED,
01637                       "Failed to read credentials byte (zero-length read)");
01638       return FALSE;
01639     }
01640   else if (buf != '\0')
01641     {
01642       dbus_set_error (error, DBUS_ERROR_FAILED,
01643                       "Credentials byte was not nul");
01644       return FALSE;
01645     }
01646 
01647 #if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
01648   if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
01649                   || cmsg.hdr.cmsg_type != SCM_CREDS)
01650     {
01651       dbus_set_error (error, DBUS_ERROR_FAILED,
01652                       "Message from recvmsg() was not SCM_CREDS");
01653       return FALSE;
01654     }
01655 #endif
01656 
01657   _dbus_verbose ("read credentials byte\n");
01658 
01659   {
01660 #ifdef SO_PEERCRED
01661     struct ucred cr;
01662     int cr_len = sizeof (cr);
01663 
01664     if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
01665         cr_len == sizeof (cr))
01666       {
01667         pid_read = cr.pid;
01668         uid_read = cr.uid;
01669       }
01670     else
01671       {
01672         _dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
01673                        cr_len, (int) sizeof (cr), _dbus_strerror (errno));
01674       }
01675 #elif defined(HAVE_CMSGCRED)
01676     struct cmsgcred *cred;
01677 
01678     cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
01679     pid_read = cred->cmcred_pid;
01680     uid_read = cred->cmcred_euid;
01681 #elif defined(LOCAL_CREDS)
01682     pid_read = DBUS_PID_UNSET;
01683     uid_read = cmsg.cred.sc_uid;
01684     /* Since we have already got the credentials from this socket, we can
01685      * disable its LOCAL_CREDS flag if it was ever set. */
01686     _dbus_set_local_creds (client_fd, FALSE);
01687 #elif defined(HAVE_GETPEEREID)
01688     uid_t euid;
01689     gid_t egid;
01690     if (getpeereid (client_fd, &euid, &egid) == 0)
01691       {
01692         uid_read = euid;
01693       }
01694     else
01695       {
01696         _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
01697       }
01698 #elif defined(HAVE_GETPEERUCRED)
01699     ucred_t * ucred = NULL;
01700     if (getpeerucred (client_fd, &ucred) == 0)
01701       {
01702         pid_read = ucred_getpid (ucred);
01703         uid_read = ucred_geteuid (ucred);
01704 #ifdef HAVE_ADT
01705         /* generate audit session data based on socket ucred */
01706         adt_session_data_t *adth = NULL;
01707         adt_export_data_t *data = NULL;
01708         size_t size = 0;
01709         if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
01710           {
01711             _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
01712           }
01713         else
01714           {
01715             if (adt_set_from_ucred (adth, ucred, ADT_NEW))
01716               {
01717                 _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
01718               }
01719             else
01720               {
01721                 size = adt_export_session_data (adth, &data);
01722                 if (size <= 0)
01723                   {
01724                     _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
01725                   }
01726                 else
01727                   {
01728                     _dbus_credentials_add_adt_audit_data (credentials, data, size);
01729                     free (data);
01730                   }
01731               }
01732             (void) adt_end_session (adth);
01733           }
01734 #endif /* HAVE_ADT */
01735       }
01736     else
01737       {
01738         _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
01739       }
01740     if (ucred != NULL)
01741       ucred_free (ucred);
01742 #else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
01743     _dbus_verbose ("Socket credentials not supported on this OS\n");
01744 #endif
01745   }
01746 
01747   _dbus_verbose ("Credentials:"
01748                  "  pid "DBUS_PID_FORMAT
01749                  "  uid "DBUS_UID_FORMAT
01750                  "\n",
01751                  pid_read,
01752                  uid_read);
01753 
01754   if (pid_read != DBUS_PID_UNSET)
01755     {
01756       if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
01757         {
01758           _DBUS_SET_OOM (error);
01759           return FALSE;
01760         }
01761     }
01762 
01763   if (uid_read != DBUS_UID_UNSET)
01764     {
01765       if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
01766         {
01767           _DBUS_SET_OOM (error);
01768           return FALSE;
01769         }
01770     }
01771 
01772   return TRUE;
01773 }
01774 
01792 dbus_bool_t
01793 _dbus_send_credentials_socket  (int              server_fd,
01794                                 DBusError       *error)
01795 {
01796   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01797 
01798   if (write_credentials_byte (server_fd, error))
01799     return TRUE;
01800   else
01801     return FALSE;
01802 }
01803 
01813 int
01814 _dbus_accept  (int listen_fd)
01815 {
01816   int client_fd;
01817   struct sockaddr addr;
01818   socklen_t addrlen;
01819 #ifdef HAVE_ACCEPT4
01820   dbus_bool_t cloexec_done;
01821 #endif
01822 
01823   addrlen = sizeof (addr);
01824 
01825  retry:
01826 
01827 #ifdef HAVE_ACCEPT4
01828   /* We assume that if accept4 is available SOCK_CLOEXEC is too */
01829   client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
01830   cloexec_done = client_fd >= 0;
01831 
01832   if (client_fd < 0 && errno == ENOSYS)
01833 #endif
01834     {
01835       client_fd = accept (listen_fd, &addr, &addrlen);
01836     }
01837 
01838   if (client_fd < 0)
01839     {
01840       if (errno == EINTR)
01841         goto retry;
01842     }
01843 
01844   _dbus_verbose ("client fd %d accepted\n", client_fd);
01845 
01846 #ifdef HAVE_ACCEPT4
01847   if (!cloexec_done)
01848 #endif
01849     {
01850       _dbus_fd_set_close_on_exec(client_fd);
01851     }
01852 
01853   return client_fd;
01854 }
01855 
01864 dbus_bool_t
01865 _dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
01866 {
01867   const char *directory;
01868   struct stat sb;
01869 
01870   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01871 
01872   directory = _dbus_string_get_const_data (dir);
01873 
01874   if (stat (directory, &sb) < 0)
01875     {
01876       dbus_set_error (error, _dbus_error_from_errno (errno),
01877                       "%s", _dbus_strerror (errno));
01878 
01879       return FALSE;
01880     }
01881 
01882   if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
01883       (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
01884     {
01885       dbus_set_error (error, DBUS_ERROR_FAILED,
01886                      "%s directory is not private to the user", directory);
01887       return FALSE;
01888     }
01889 
01890   return TRUE;
01891 }
01892 
01893 static dbus_bool_t
01894 fill_user_info_from_passwd (struct passwd *p,
01895                             DBusUserInfo  *info,
01896                             DBusError     *error)
01897 {
01898   _dbus_assert (p->pw_name != NULL);
01899   _dbus_assert (p->pw_dir != NULL);
01900 
01901   info->uid = p->pw_uid;
01902   info->primary_gid = p->pw_gid;
01903   info->username = _dbus_strdup (p->pw_name);
01904   info->homedir = _dbus_strdup (p->pw_dir);
01905 
01906   if (info->username == NULL ||
01907       info->homedir == NULL)
01908     {
01909       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01910       return FALSE;
01911     }
01912 
01913   return TRUE;
01914 }
01915 
01916 static dbus_bool_t
01917 fill_user_info (DBusUserInfo       *info,
01918                 dbus_uid_t          uid,
01919                 const DBusString   *username,
01920                 DBusError          *error)
01921 {
01922   const char *username_c;
01923 
01924   /* exactly one of username/uid provided */
01925   _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
01926   _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
01927 
01928   info->uid = DBUS_UID_UNSET;
01929   info->primary_gid = DBUS_GID_UNSET;
01930   info->group_ids = NULL;
01931   info->n_group_ids = 0;
01932   info->username = NULL;
01933   info->homedir = NULL;
01934 
01935   if (username != NULL)
01936     username_c = _dbus_string_get_const_data (username);
01937   else
01938     username_c = NULL;
01939 
01940   /* For now assuming that the getpwnam() and getpwuid() flavors
01941    * are always symmetrical, if not we have to add more configure
01942    * checks
01943    */
01944 
01945 #if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
01946   {
01947     struct passwd *p;
01948     int result;
01949     size_t buflen;
01950     char *buf;
01951     struct passwd p_str;
01952 
01953     /* retrieve maximum needed size for buf */
01954     buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
01955 
01956     /* sysconf actually returns a long, but everything else expects size_t,
01957      * so just recast here.
01958      * https://bugs.freedesktop.org/show_bug.cgi?id=17061
01959      */
01960     if ((long) buflen <= 0)
01961       buflen = 1024;
01962 
01963     result = -1;
01964     while (1)
01965       {
01966         buf = dbus_malloc (buflen);
01967         if (buf == NULL)
01968           {
01969             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01970             return FALSE;
01971           }
01972 
01973         p = NULL;
01974 #ifdef HAVE_POSIX_GETPWNAM_R
01975         if (uid != DBUS_UID_UNSET)
01976           result = getpwuid_r (uid, &p_str, buf, buflen,
01977                                &p);
01978         else
01979           result = getpwnam_r (username_c, &p_str, buf, buflen,
01980                                &p);
01981 #else
01982         if (uid != DBUS_UID_UNSET)
01983           p = getpwuid_r (uid, &p_str, buf, buflen);
01984         else
01985           p = getpwnam_r (username_c, &p_str, buf, buflen);
01986         result = 0;
01987 #endif /* !HAVE_POSIX_GETPWNAM_R */
01988         //Try a bigger buffer if ERANGE was returned
01989         if (result == ERANGE && buflen < 512 * 1024)
01990           {
01991             dbus_free (buf);
01992             buflen *= 2;
01993           }
01994         else
01995           {
01996             break;
01997           }
01998       }
01999     if (result == 0 && p == &p_str)
02000       {
02001         if (!fill_user_info_from_passwd (p, info, error))
02002           {
02003             dbus_free (buf);
02004             return FALSE;
02005           }
02006         dbus_free (buf);
02007       }
02008     else
02009       {
02010         dbus_set_error (error, _dbus_error_from_errno (errno),
02011                         "User \"%s\" unknown or no memory to allocate password entry\n",
02012                         username_c ? username_c : "???");
02013         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02014         dbus_free (buf);
02015         return FALSE;
02016       }
02017   }
02018 #else /* ! HAVE_GETPWNAM_R */
02019   {
02020     /* I guess we're screwed on thread safety here */
02021     struct passwd *p;
02022 
02023     if (uid != DBUS_UID_UNSET)
02024       p = getpwuid (uid);
02025     else
02026       p = getpwnam (username_c);
02027 
02028     if (p != NULL)
02029       {
02030         if (!fill_user_info_from_passwd (p, info, error))
02031           {
02032             return FALSE;
02033           }
02034       }
02035     else
02036       {
02037         dbus_set_error (error, _dbus_error_from_errno (errno),
02038                         "User \"%s\" unknown or no memory to allocate password entry\n",
02039                         username_c ? username_c : "???");
02040         _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
02041         return FALSE;
02042       }
02043   }
02044 #endif  /* ! HAVE_GETPWNAM_R */
02045 
02046   /* Fill this in so we can use it to get groups */
02047   username_c = info->username;
02048 
02049 #ifdef HAVE_GETGROUPLIST
02050   {
02051     gid_t *buf;
02052     int buf_count;
02053     int i;
02054     int initial_buf_count;
02055 
02056     initial_buf_count = 17;
02057     buf_count = initial_buf_count;
02058     buf = dbus_new (gid_t, buf_count);
02059     if (buf == NULL)
02060       {
02061         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02062         goto failed;
02063       }
02064 
02065     if (getgrouplist (username_c,
02066                       info->primary_gid,
02067                       buf, &buf_count) < 0)
02068       {
02069         gid_t *new;
02070         /* Presumed cause of negative return code: buf has insufficient
02071            entries to hold the entire group list. The Linux behavior in this
02072            case is to pass back the actual number of groups in buf_count, but
02073            on Mac OS X 10.5, buf_count is unhelpfully left alone.
02074            So as a hack, try to help out a bit by guessing a larger
02075            number of groups, within reason.. might still fail, of course,
02076            but we can at least print a more informative message.  I looked up
02077            the "right way" to do this by downloading Apple's own source code
02078            for the "id" command, and it turns out that they use an
02079            undocumented library function getgrouplist_2 (!) which is not
02080            declared in any header in /usr/include (!!). That did not seem
02081            like the way to go here.
02082         */
02083         if (buf_count == initial_buf_count)
02084           {
02085             buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
02086           }
02087         new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
02088         if (new == NULL)
02089           {
02090             dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02091             dbus_free (buf);
02092             goto failed;
02093           }
02094 
02095         buf = new;
02096 
02097         errno = 0;
02098         if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
02099           {
02100             if (errno == 0)
02101               {
02102                 _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
02103                             username_c, buf_count, buf_count);
02104               }
02105             else
02106               {
02107                 dbus_set_error (error,
02108                                 _dbus_error_from_errno (errno),
02109                                 "Failed to get groups for username \"%s\" primary GID "
02110                                 DBUS_GID_FORMAT ": %s\n",
02111                                 username_c, info->primary_gid,
02112                                 _dbus_strerror (errno));
02113                 dbus_free (buf);
02114                 goto failed;
02115               }
02116           }
02117       }
02118 
02119     info->group_ids = dbus_new (dbus_gid_t, buf_count);
02120     if (info->group_ids == NULL)
02121       {
02122         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02123         dbus_free (buf);
02124         goto failed;
02125       }
02126 
02127     for (i = 0; i < buf_count; ++i)
02128       info->group_ids[i] = buf[i];
02129 
02130     info->n_group_ids = buf_count;
02131 
02132     dbus_free (buf);
02133   }
02134 #else  /* HAVE_GETGROUPLIST */
02135   {
02136     /* We just get the one group ID */
02137     info->group_ids = dbus_new (dbus_gid_t, 1);
02138     if (info->group_ids == NULL)
02139       {
02140         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
02141         goto failed;
02142       }
02143 
02144     info->n_group_ids = 1;
02145 
02146     (info->group_ids)[0] = info->primary_gid;
02147   }
02148 #endif /* HAVE_GETGROUPLIST */
02149 
02150   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02151 
02152   return TRUE;
02153 
02154  failed:
02155   _DBUS_ASSERT_ERROR_IS_SET (error);
02156   return FALSE;
02157 }
02158 
02167 dbus_bool_t
02168 _dbus_user_info_fill (DBusUserInfo     *info,
02169                       const DBusString *username,
02170                       DBusError        *error)
02171 {
02172   return fill_user_info (info, DBUS_UID_UNSET,
02173                          username, error);
02174 }
02175 
02184 dbus_bool_t
02185 _dbus_user_info_fill_uid (DBusUserInfo *info,
02186                           dbus_uid_t    uid,
02187                           DBusError    *error)
02188 {
02189   return fill_user_info (info, uid,
02190                          NULL, error);
02191 }
02192 
02200 dbus_bool_t
02201 _dbus_credentials_add_from_current_process (DBusCredentials *credentials)
02202 {
02203   /* The POSIX spec certainly doesn't promise this, but
02204    * we need these assertions to fail as soon as we're wrong about
02205    * it so we can do the porting fixups
02206    */
02207   _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
02208   _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
02209   _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
02210 
02211   if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
02212     return FALSE;
02213   if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
02214     return FALSE;
02215 
02216   return TRUE;
02217 }
02218 
02230 dbus_bool_t
02231 _dbus_append_user_from_current_process (DBusString *str)
02232 {
02233   return _dbus_string_append_uint (str,
02234                                    _dbus_geteuid ());
02235 }
02236 
02241 dbus_pid_t
02242 _dbus_getpid (void)
02243 {
02244   return getpid ();
02245 }
02246 
02250 dbus_uid_t
02251 _dbus_getuid (void)
02252 {
02253   return getuid ();
02254 }
02255 
02259 dbus_uid_t
02260 _dbus_geteuid (void)
02261 {
02262   return geteuid ();
02263 }
02264 
02271 unsigned long
02272 _dbus_pid_for_log (void)
02273 {
02274   return getpid ();
02275 }
02276 
02284 dbus_bool_t
02285 _dbus_parse_uid (const DBusString      *uid_str,
02286                  dbus_uid_t            *uid)
02287 {
02288   int end;
02289   long val;
02290 
02291   if (_dbus_string_get_length (uid_str) == 0)
02292     {
02293       _dbus_verbose ("UID string was zero length\n");
02294       return FALSE;
02295     }
02296 
02297   val = -1;
02298   end = 0;
02299   if (!_dbus_string_parse_int (uid_str, 0, &val,
02300                                &end))
02301     {
02302       _dbus_verbose ("could not parse string as a UID\n");
02303       return FALSE;
02304     }
02305 
02306   if (end != _dbus_string_get_length (uid_str))
02307     {
02308       _dbus_verbose ("string contained trailing stuff after UID\n");
02309       return FALSE;
02310     }
02311 
02312   *uid = val;
02313 
02314   return TRUE;
02315 }
02316 
02317 #if !DBUS_USE_SYNC
02318 _DBUS_DEFINE_GLOBAL_LOCK (atomic);
02319 #endif
02320 
02327 dbus_int32_t
02328 _dbus_atomic_inc (DBusAtomic *atomic)
02329 {
02330 #if DBUS_USE_SYNC
02331   return __sync_add_and_fetch(&atomic->value, 1)-1;
02332 #else
02333   dbus_int32_t res;
02334   _DBUS_LOCK (atomic);
02335   res = atomic->value;
02336   atomic->value += 1;
02337   _DBUS_UNLOCK (atomic);
02338   return res;
02339 #endif
02340 }
02341 
02348 dbus_int32_t
02349 _dbus_atomic_dec (DBusAtomic *atomic)
02350 {
02351 #if DBUS_USE_SYNC
02352   return __sync_sub_and_fetch(&atomic->value, 1)+1;
02353 #else
02354   dbus_int32_t res;
02355 
02356   _DBUS_LOCK (atomic);
02357   res = atomic->value;
02358   atomic->value -= 1;
02359   _DBUS_UNLOCK (atomic);
02360   return res;
02361 #endif
02362 }
02363 
02364 #ifdef DBUS_BUILD_TESTS
02365 
02368 dbus_gid_t
02369 _dbus_getgid (void)
02370 {
02371   return getgid ();
02372 }
02373 #endif
02374 
02383 int
02384 _dbus_poll (DBusPollFD *fds,
02385             int         n_fds,
02386             int         timeout_milliseconds)
02387 {
02388 #if defined(HAVE_POLL) && !defined(BROKEN_POLL)
02389   /* This big thing is a constant expression and should get optimized
02390    * out of existence. So it's more robust than a configure check at
02391    * no cost.
02392    */
02393   if (_DBUS_POLLIN == POLLIN &&
02394       _DBUS_POLLPRI == POLLPRI &&
02395       _DBUS_POLLOUT == POLLOUT &&
02396       _DBUS_POLLERR == POLLERR &&
02397       _DBUS_POLLHUP == POLLHUP &&
02398       _DBUS_POLLNVAL == POLLNVAL &&
02399       sizeof (DBusPollFD) == sizeof (struct pollfd) &&
02400       _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
02401       _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
02402       _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
02403       _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
02404       _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
02405       _DBUS_STRUCT_OFFSET (struct pollfd, revents))
02406     {
02407       return poll ((struct pollfd*) fds,
02408                    n_fds,
02409                    timeout_milliseconds);
02410     }
02411   else
02412     {
02413       /* We have to convert the DBusPollFD to an array of
02414        * struct pollfd, poll, and convert back.
02415        */
02416       _dbus_warn ("didn't implement poll() properly for this system yet\n");
02417       return -1;
02418     }
02419 #else /* ! HAVE_POLL */
02420 
02421   fd_set read_set, write_set, err_set;
02422   int max_fd = 0;
02423   int i;
02424   struct timeval tv;
02425   int ready;
02426 
02427   FD_ZERO (&read_set);
02428   FD_ZERO (&write_set);
02429   FD_ZERO (&err_set);
02430 
02431   for (i = 0; i < n_fds; i++)
02432     {
02433       DBusPollFD *fdp = &fds[i];
02434 
02435       if (fdp->events & _DBUS_POLLIN)
02436         FD_SET (fdp->fd, &read_set);
02437 
02438       if (fdp->events & _DBUS_POLLOUT)
02439         FD_SET (fdp->fd, &write_set);
02440 
02441       FD_SET (fdp->fd, &err_set);
02442 
02443       max_fd = MAX (max_fd, fdp->fd);
02444     }
02445 
02446   tv.tv_sec = timeout_milliseconds / 1000;
02447   tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
02448 
02449   ready = select (max_fd + 1, &read_set, &write_set, &err_set,
02450                   timeout_milliseconds < 0 ? NULL : &tv);
02451 
02452   if (ready > 0)
02453     {
02454       for (i = 0; i < n_fds; i++)
02455         {
02456           DBusPollFD *fdp = &fds[i];
02457 
02458           fdp->revents = 0;
02459 
02460           if (FD_ISSET (fdp->fd, &read_set))
02461             fdp->revents |= _DBUS_POLLIN;
02462 
02463           if (FD_ISSET (fdp->fd, &write_set))
02464             fdp->revents |= _DBUS_POLLOUT;
02465 
02466           if (FD_ISSET (fdp->fd, &err_set))
02467             fdp->revents |= _DBUS_POLLERR;
02468         }
02469     }
02470 
02471   return ready;
02472 #endif
02473 }
02474 
02482 void
02483 _dbus_get_current_time (long *tv_sec,
02484                         long *tv_usec)
02485 {
02486   struct timeval t;
02487 
02488 #ifdef HAVE_MONOTONIC_CLOCK
02489   struct timespec ts;
02490   clock_gettime (CLOCK_MONOTONIC, &ts);
02491 
02492   if (tv_sec)
02493     *tv_sec = ts.tv_sec;
02494   if (tv_usec)
02495     *tv_usec = ts.tv_nsec / 1000;
02496 #else
02497   gettimeofday (&t, NULL);
02498 
02499   if (tv_sec)
02500     *tv_sec = t.tv_sec;
02501   if (tv_usec)
02502     *tv_usec = t.tv_usec;
02503 #endif
02504 }
02505 
02514 dbus_bool_t
02515 _dbus_create_directory (const DBusString *filename,
02516                         DBusError        *error)
02517 {
02518   const char *filename_c;
02519 
02520   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02521 
02522   filename_c = _dbus_string_get_const_data (filename);
02523 
02524   if (mkdir (filename_c, 0700) < 0)
02525     {
02526       if (errno == EEXIST)
02527         return TRUE;
02528 
02529       dbus_set_error (error, DBUS_ERROR_FAILED,
02530                       "Failed to create directory %s: %s\n",
02531                       filename_c, _dbus_strerror (errno));
02532       return FALSE;
02533     }
02534   else
02535     return TRUE;
02536 }
02537 
02548 dbus_bool_t
02549 _dbus_concat_dir_and_file (DBusString       *dir,
02550                            const DBusString *next_component)
02551 {
02552   dbus_bool_t dir_ends_in_slash;
02553   dbus_bool_t file_starts_with_slash;
02554 
02555   if (_dbus_string_get_length (dir) == 0 ||
02556       _dbus_string_get_length (next_component) == 0)
02557     return TRUE;
02558 
02559   dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
02560                                                     _dbus_string_get_length (dir) - 1);
02561 
02562   file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
02563 
02564   if (dir_ends_in_slash && file_starts_with_slash)
02565     {
02566       _dbus_string_shorten (dir, 1);
02567     }
02568   else if (!(dir_ends_in_slash || file_starts_with_slash))
02569     {
02570       if (!_dbus_string_append_byte (dir, '/'))
02571         return FALSE;
02572     }
02573 
02574   return _dbus_string_copy (next_component, 0, dir,
02575                             _dbus_string_get_length (dir));
02576 }
02577 
02579 #define NANOSECONDS_PER_SECOND       1000000000
02580 
02581 #define MICROSECONDS_PER_SECOND      1000000
02582 
02583 #define MILLISECONDS_PER_SECOND      1000
02584 
02585 #define NANOSECONDS_PER_MILLISECOND  1000000
02586 
02587 #define MICROSECONDS_PER_MILLISECOND 1000
02588 
02593 void
02594 _dbus_sleep_milliseconds (int milliseconds)
02595 {
02596 #ifdef HAVE_NANOSLEEP
02597   struct timespec req;
02598   struct timespec rem;
02599 
02600   req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
02601   req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
02602   rem.tv_sec = 0;
02603   rem.tv_nsec = 0;
02604 
02605   while (nanosleep (&req, &rem) < 0 && errno == EINTR)
02606     req = rem;
02607 #elif defined (HAVE_USLEEP)
02608   usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
02609 #else /* ! HAVE_USLEEP */
02610   sleep (MAX (milliseconds / 1000, 1));
02611 #endif
02612 }
02613 
02614 static dbus_bool_t
02615 _dbus_generate_pseudorandom_bytes (DBusString *str,
02616                                    int         n_bytes)
02617 {
02618   int old_len;
02619   char *p;
02620 
02621   old_len = _dbus_string_get_length (str);
02622 
02623   if (!_dbus_string_lengthen (str, n_bytes))
02624     return FALSE;
02625 
02626   p = _dbus_string_get_data_len (str, old_len, n_bytes);
02627 
02628   _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
02629 
02630   return TRUE;
02631 }
02632 
02641 dbus_bool_t
02642 _dbus_generate_random_bytes (DBusString *str,
02643                              int         n_bytes)
02644 {
02645   int old_len;
02646   int fd;
02647 
02648   /* FALSE return means "no memory", if it could
02649    * mean something else then we'd need to return
02650    * a DBusError. So we always fall back to pseudorandom
02651    * if the I/O fails.
02652    */
02653 
02654   old_len = _dbus_string_get_length (str);
02655   fd = -1;
02656 
02657   /* note, urandom on linux will fall back to pseudorandom */
02658   fd = open ("/dev/urandom", O_RDONLY);
02659   if (fd < 0)
02660     return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02661 
02662   _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
02663 
02664   if (_dbus_read (fd, str, n_bytes) != n_bytes)
02665     {
02666       _dbus_close (fd, NULL);
02667       _dbus_string_set_length (str, old_len);
02668       return _dbus_generate_pseudorandom_bytes (str, n_bytes);
02669     }
02670 
02671   _dbus_verbose ("Read %d bytes from /dev/urandom\n",
02672                  n_bytes);
02673 
02674   _dbus_close (fd, NULL);
02675 
02676   return TRUE;
02677 }
02678 
02684 void
02685 _dbus_exit (int code)
02686 {
02687   _exit (code);
02688 }
02689 
02698 const char*
02699 _dbus_strerror (int error_number)
02700 {
02701   const char *msg;
02702 
02703   msg = strerror (error_number);
02704   if (msg == NULL)
02705     msg = "unknown";
02706 
02707   return msg;
02708 }
02709 
02713 void
02714 _dbus_disable_sigpipe (void)
02715 {
02716   signal (SIGPIPE, SIG_IGN);
02717 }
02718 
02726 void
02727 _dbus_fd_set_close_on_exec (intptr_t fd)
02728 {
02729   int val;
02730 
02731   val = fcntl (fd, F_GETFD, 0);
02732 
02733   if (val < 0)
02734     return;
02735 
02736   val |= FD_CLOEXEC;
02737 
02738   fcntl (fd, F_SETFD, val);
02739 }
02740 
02748 dbus_bool_t
02749 _dbus_close (int        fd,
02750              DBusError *error)
02751 {
02752   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02753 
02754  again:
02755   if (close (fd) < 0)
02756     {
02757       if (errno == EINTR)
02758         goto again;
02759 
02760       dbus_set_error (error, _dbus_error_from_errno (errno),
02761                       "Could not close fd %d", fd);
02762       return FALSE;
02763     }
02764 
02765   return TRUE;
02766 }
02767 
02775 int
02776 _dbus_dup(int        fd,
02777           DBusError *error)
02778 {
02779   int new_fd;
02780 
02781 #ifdef F_DUPFD_CLOEXEC
02782   dbus_bool_t cloexec_done;
02783 
02784   new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
02785   cloexec_done = new_fd >= 0;
02786 
02787   if (new_fd < 0 && errno == EINVAL)
02788 #endif
02789     {
02790       new_fd = fcntl(fd, F_DUPFD, 3);
02791     }
02792 
02793   if (new_fd < 0) {
02794 
02795     dbus_set_error (error, _dbus_error_from_errno (errno),
02796                     "Could not duplicate fd %d", fd);
02797     return -1;
02798   }
02799 
02800 #ifdef F_DUPFD_CLOEXEC
02801   if (!cloexec_done)
02802 #endif
02803     {
02804       _dbus_fd_set_close_on_exec(new_fd);
02805     }
02806 
02807   return new_fd;
02808 }
02809 
02817 dbus_bool_t
02818 _dbus_set_fd_nonblocking (int             fd,
02819                           DBusError      *error)
02820 {
02821   int val;
02822 
02823   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02824 
02825   val = fcntl (fd, F_GETFL, 0);
02826   if (val < 0)
02827     {
02828       dbus_set_error (error, _dbus_error_from_errno (errno),
02829                       "Failed to get flags from file descriptor %d: %s",
02830                       fd, _dbus_strerror (errno));
02831       _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
02832                      _dbus_strerror (errno));
02833       return FALSE;
02834     }
02835 
02836   if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
02837     {
02838       dbus_set_error (error, _dbus_error_from_errno (errno),
02839                       "Failed to set nonblocking flag of file descriptor %d: %s",
02840                       fd, _dbus_strerror (errno));
02841       _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
02842                      fd, _dbus_strerror (errno));
02843 
02844       return FALSE;
02845     }
02846 
02847   return TRUE;
02848 }
02849 
02855 void
02856 _dbus_print_backtrace (void)
02857 {
02858 #if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
02859   void *bt[500];
02860   int bt_size;
02861   int i;
02862   char **syms;
02863 
02864   bt_size = backtrace (bt, 500);
02865 
02866   syms = backtrace_symbols (bt, bt_size);
02867 
02868   i = 0;
02869   while (i < bt_size)
02870     {
02871       /* don't use dbus_warn since it can _dbus_abort() */
02872       fprintf (stderr, "  %s\n", syms[i]);
02873       ++i;
02874     }
02875   fflush (stderr);
02876 
02877   free (syms);
02878 #elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
02879   fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
02880 #else
02881   fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
02882 #endif
02883 }
02884 
02902 dbus_bool_t
02903 _dbus_full_duplex_pipe (int        *fd1,
02904                         int        *fd2,
02905                         dbus_bool_t blocking,
02906                         DBusError  *error)
02907 {
02908 #ifdef HAVE_SOCKETPAIR
02909   int fds[2];
02910   int retval;
02911 
02912 #ifdef SOCK_CLOEXEC
02913   dbus_bool_t cloexec_done;
02914 
02915   retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
02916   cloexec_done = retval >= 0;
02917 
02918   if (retval < 0 && errno == EINVAL)
02919 #endif
02920     {
02921       retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
02922     }
02923 
02924   if (retval < 0)
02925     {
02926       dbus_set_error (error, _dbus_error_from_errno (errno),
02927                       "Could not create full-duplex pipe");
02928       return FALSE;
02929     }
02930 
02931   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
02932 
02933 #ifdef SOCK_CLOEXEC
02934   if (!cloexec_done)
02935 #endif
02936     {
02937       _dbus_fd_set_close_on_exec (fds[0]);
02938       _dbus_fd_set_close_on_exec (fds[1]);
02939     }
02940 
02941   if (!blocking &&
02942       (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
02943        !_dbus_set_fd_nonblocking (fds[1], NULL)))
02944     {
02945       dbus_set_error (error, _dbus_error_from_errno (errno),
02946                       "Could not set full-duplex pipe nonblocking");
02947 
02948       _dbus_close (fds[0], NULL);
02949       _dbus_close (fds[1], NULL);
02950 
02951       return FALSE;
02952     }
02953 
02954   *fd1 = fds[0];
02955   *fd2 = fds[1];
02956 
02957   _dbus_verbose ("full-duplex pipe %d <-> %d\n",
02958                  *fd1, *fd2);
02959 
02960   return TRUE;
02961 #else
02962   _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
02963   dbus_set_error (error, DBUS_ERROR_FAILED,
02964                   "_dbus_full_duplex_pipe() not implemented on this OS");
02965   return FALSE;
02966 #endif
02967 }
02968 
02977 int
02978 _dbus_printf_string_upper_bound (const char *format,
02979                                  va_list     args)
02980 {
02981   char c;
02982   return vsnprintf (&c, 1, format, args);
02983 }
02984 
02991 const char*
02992 _dbus_get_tmpdir(void)
02993 {
02994   static const char* tmpdir = NULL;
02995 
02996   if (tmpdir == NULL)
02997     {
02998       /* TMPDIR is what glibc uses, then
02999        * glibc falls back to the P_tmpdir macro which
03000        * just expands to "/tmp"
03001        */
03002       if (tmpdir == NULL)
03003         tmpdir = getenv("TMPDIR");
03004 
03005       /* These two env variables are probably
03006        * broken, but maybe some OS uses them?
03007        */
03008       if (tmpdir == NULL)
03009         tmpdir = getenv("TMP");
03010       if (tmpdir == NULL)
03011         tmpdir = getenv("TEMP");
03012 
03013       /* And this is the sane fallback. */
03014       if (tmpdir == NULL)
03015         tmpdir = "/tmp";
03016     }
03017 
03018   _dbus_assert(tmpdir != NULL);
03019 
03020   return tmpdir;
03021 }
03022 
03042 static dbus_bool_t
03043 _read_subprocess_line_argv (const char *progpath,
03044                             dbus_bool_t path_fallback,
03045                             char       * const *argv,
03046                             DBusString *result,
03047                             DBusError  *error)
03048 {
03049   int result_pipe[2] = { -1, -1 };
03050   int errors_pipe[2] = { -1, -1 };
03051   pid_t pid;
03052   int ret;
03053   int status;
03054   int orig_len;
03055   int i;
03056 
03057   dbus_bool_t retval;
03058   sigset_t new_set, old_set;
03059 
03060   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03061   retval = FALSE;
03062 
03063   /* We need to block any existing handlers for SIGCHLD temporarily; they
03064    * will cause waitpid() below to fail.
03065    * https://bugs.freedesktop.org/show_bug.cgi?id=21347
03066    */
03067   sigemptyset (&new_set);
03068   sigaddset (&new_set, SIGCHLD);
03069   sigprocmask (SIG_BLOCK, &new_set, &old_set);
03070 
03071   orig_len = _dbus_string_get_length (result);
03072 
03073 #define READ_END        0
03074 #define WRITE_END       1
03075   if (pipe (result_pipe) < 0)
03076     {
03077       dbus_set_error (error, _dbus_error_from_errno (errno),
03078                       "Failed to create a pipe to call %s: %s",
03079                       progpath, _dbus_strerror (errno));
03080       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03081                      progpath, _dbus_strerror (errno));
03082       goto out;
03083     }
03084   if (pipe (errors_pipe) < 0)
03085     {
03086       dbus_set_error (error, _dbus_error_from_errno (errno),
03087                       "Failed to create a pipe to call %s: %s",
03088                       progpath, _dbus_strerror (errno));
03089       _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
03090                      progpath, _dbus_strerror (errno));
03091       goto out;
03092     }
03093 
03094   pid = fork ();
03095   if (pid < 0)
03096     {
03097       dbus_set_error (error, _dbus_error_from_errno (errno),
03098                       "Failed to fork() to call %s: %s",
03099                       progpath, _dbus_strerror (errno));
03100       _dbus_verbose ("Failed to fork() to call %s: %s\n",
03101                      progpath, _dbus_strerror (errno));
03102       goto out;
03103     }
03104 
03105   if (pid == 0)
03106     {
03107       /* child process */
03108       int maxfds;
03109       int fd;
03110 
03111       fd = open ("/dev/null", O_RDWR);
03112       if (fd == -1)
03113         /* huh?! can't open /dev/null? */
03114         _exit (1);
03115 
03116       _dbus_verbose ("/dev/null fd %d opened\n", fd);
03117 
03118       /* set-up stdXXX */
03119       close (result_pipe[READ_END]);
03120       close (errors_pipe[READ_END]);
03121       close (0);                /* close stdin */
03122       close (1);                /* close stdout */
03123       close (2);                /* close stderr */
03124 
03125       if (dup2 (fd, 0) == -1)
03126         _exit (1);
03127       if (dup2 (result_pipe[WRITE_END], 1) == -1)
03128         _exit (1);
03129       if (dup2 (errors_pipe[WRITE_END], 2) == -1)
03130         _exit (1);
03131 
03132       maxfds = sysconf (_SC_OPEN_MAX);
03133       /* Pick something reasonable if for some reason sysconf
03134        * says unlimited.
03135        */
03136       if (maxfds < 0)
03137         maxfds = 1024;
03138       /* close all inherited fds */
03139       for (i = 3; i < maxfds; i++)
03140         close (i);
03141 
03142       sigprocmask (SIG_SETMASK, &old_set, NULL);
03143 
03144       /* If it looks fully-qualified, try execv first */
03145       if (progpath[0] == '/')
03146         {
03147           execv (progpath, argv);
03148           /* Ok, that failed.  Now if path_fallback is given, let's
03149            * try unqualified.  This is mostly a hack to work
03150            * around systems which ship dbus-launch in /usr/bin
03151            * but everything else in /bin (because dbus-launch
03152            * depends on X11).
03153            */
03154           if (path_fallback)
03155             /* We must have a slash, because we checked above */
03156             execvp (strrchr (progpath, '/')+1, argv);
03157         }
03158       else
03159         execvp (progpath, argv);
03160 
03161       /* still nothing, we failed */
03162       _exit (1);
03163     }
03164 
03165   /* parent process */
03166   close (result_pipe[WRITE_END]);
03167   close (errors_pipe[WRITE_END]);
03168   result_pipe[WRITE_END] = -1;
03169   errors_pipe[WRITE_END] = -1;
03170 
03171   ret = 0;
03172   do
03173     {
03174       ret = _dbus_read (result_pipe[READ_END], result, 1024);
03175     }
03176   while (ret > 0);
03177 
03178   /* reap the child process to avoid it lingering as zombie */
03179   do
03180     {
03181       ret = waitpid (pid, &status, 0);
03182     }
03183   while (ret == -1 && errno == EINTR);
03184 
03185   /* We succeeded if the process exited with status 0 and
03186      anything was read */
03187   if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
03188     {
03189       /* The process ended with error */
03190       DBusString error_message;
03191       _dbus_string_init (&error_message);
03192       ret = 0;
03193       do
03194         {
03195           ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
03196         }
03197       while (ret > 0);
03198 
03199       _dbus_string_set_length (result, orig_len);
03200       if (_dbus_string_get_length (&error_message) > 0)
03201         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03202                         "%s terminated abnormally with the following error: %s",
03203                         progpath, _dbus_string_get_data (&error_message));
03204       else
03205         dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
03206                         "%s terminated abnormally without any error message",
03207                         progpath);
03208       goto out;
03209     }
03210 
03211   retval = TRUE;
03212 
03213  out:
03214   sigprocmask (SIG_SETMASK, &old_set, NULL);
03215 
03216   if (retval)
03217     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03218   else
03219     _DBUS_ASSERT_ERROR_IS_SET (error);
03220 
03221   if (result_pipe[0] != -1)
03222     close (result_pipe[0]);
03223   if (result_pipe[1] != -1)
03224     close (result_pipe[1]);
03225   if (errors_pipe[0] != -1)
03226     close (errors_pipe[0]);
03227   if (errors_pipe[1] != -1)
03228     close (errors_pipe[1]);
03229 
03230   return retval;
03231 }
03232 
03244 dbus_bool_t
03245 _dbus_get_autolaunch_address (const char *scope,
03246                               DBusString *address,
03247                               DBusError  *error)
03248 {
03249   static char *argv[6];
03250   int i;
03251   DBusString uuid;
03252   dbus_bool_t retval;
03253 
03254   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03255   retval = FALSE;
03256 
03257   if (!_dbus_string_init (&uuid))
03258     {
03259       _DBUS_SET_OOM (error);
03260       return FALSE;
03261     }
03262 
03263   if (!_dbus_get_local_machine_uuid_encoded (&uuid))
03264     {
03265       _DBUS_SET_OOM (error);
03266       goto out;
03267     }
03268 
03269   i = 0;
03270   argv[i] = "dbus-launch";
03271   ++i;
03272   argv[i] = "--autolaunch";
03273   ++i;
03274   argv[i] = _dbus_string_get_data (&uuid);
03275   ++i;
03276   argv[i] = "--binary-syntax";
03277   ++i;
03278   argv[i] = "--close-stderr";
03279   ++i;
03280   argv[i] = NULL;
03281   ++i;
03282 
03283   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03284 
03285   retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
03286                                        TRUE,
03287                                        argv, address, error);
03288 
03289  out:
03290   _dbus_string_free (&uuid);
03291   return retval;
03292 }
03293 
03312 dbus_bool_t
03313 _dbus_read_local_machine_uuid (DBusGUID   *machine_id,
03314                                dbus_bool_t create_if_not_found,
03315                                DBusError  *error)
03316 {
03317   DBusString filename;
03318   _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
03319   return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
03320 }
03321 
03322 #define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
03323 #define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
03324 
03331 dbus_bool_t
03332 _dbus_lookup_launchd_socket (DBusString *socket_path,
03333                              const char *launchd_env_var,
03334                              DBusError  *error)
03335 {
03336 #ifdef DBUS_ENABLE_LAUNCHD
03337   char *argv[4];
03338   int i;
03339 
03340   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03341 
03342   i = 0;
03343   argv[i] = "launchctl";
03344   ++i;
03345   argv[i] = "getenv";
03346   ++i;
03347   argv[i] = (char*)launchd_env_var;
03348   ++i;
03349   argv[i] = NULL;
03350   ++i;
03351 
03352   _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
03353 
03354   if (!_read_subprocess_line_argv(argv[0], TRUE, argv, socket_path, error))
03355     {
03356       return FALSE;
03357     }
03358 
03359   /* no error, but no result either */
03360   if (_dbus_string_get_length(socket_path) == 0)
03361     {
03362       return FALSE;
03363     }
03364 
03365   /* strip the carriage-return */
03366   _dbus_string_shorten(socket_path, 1);
03367   return TRUE;
03368 #else /* DBUS_ENABLE_LAUNCHD */
03369   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03370                 "can't lookup socket from launchd; launchd support not compiled in");
03371   return FALSE;
03372 #endif
03373 }
03374 
03375 static dbus_bool_t
03376 _dbus_lookup_session_address_launchd (DBusString *address, DBusError  *error)
03377 {
03378 #ifdef DBUS_ENABLE_LAUNCHD
03379   dbus_bool_t valid_socket;
03380   DBusString socket_path;
03381 
03382   if (!_dbus_string_init (&socket_path))
03383     {
03384       _DBUS_SET_OOM (error);
03385       return FALSE;
03386     }
03387 
03388   valid_socket = _dbus_lookup_launchd_socket (&socket_path, "DBUS_LAUNCHD_SESSION_BUS_SOCKET", error);
03389 
03390   if (dbus_error_is_set(error))
03391     {
03392       _dbus_string_free(&socket_path);
03393       return FALSE;
03394     }
03395 
03396   if (!valid_socket)
03397     {
03398       dbus_set_error(error, "no socket path",
03399                 "launchd did not provide a socket path, "
03400                 "verify that org.freedesktop.dbus-session.plist is loaded!");
03401       _dbus_string_free(&socket_path);
03402       return FALSE;
03403     }
03404   if (!_dbus_string_append (address, "unix:path="))
03405     {
03406       _DBUS_SET_OOM (error);
03407       _dbus_string_free(&socket_path);
03408       return FALSE;
03409     }
03410   if (!_dbus_string_copy (&socket_path, 0, address,
03411                           _dbus_string_get_length (address)))
03412     {
03413       _DBUS_SET_OOM (error);
03414       _dbus_string_free(&socket_path);
03415       return FALSE;
03416     }
03417 
03418   _dbus_string_free(&socket_path);
03419   return TRUE;
03420 #else
03421   dbus_set_error(error, DBUS_ERROR_NOT_SUPPORTED,
03422                 "can't lookup session address from launchd; launchd support not compiled in");
03423   return FALSE;
03424 #endif
03425 }
03426 
03446 dbus_bool_t
03447 _dbus_lookup_session_address (dbus_bool_t *supported,
03448                               DBusString  *address,
03449                               DBusError   *error)
03450 {
03451 #ifdef DBUS_ENABLE_LAUNCHD
03452   *supported = TRUE;
03453   return _dbus_lookup_session_address_launchd (address, error);
03454 #else
03455   /* On non-Mac Unix platforms, if the session address isn't already
03456    * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
03457    * fall back to the autolaunch: global default; see
03458    * init_session_address in dbus/dbus-bus.c. */
03459   *supported = FALSE;
03460   return TRUE;
03461 #endif
03462 }
03463 
03481 dbus_bool_t
03482 _dbus_get_standard_session_servicedirs (DBusList **dirs)
03483 {
03484   const char *xdg_data_home;
03485   const char *xdg_data_dirs;
03486   DBusString servicedir_path;
03487 
03488   if (!_dbus_string_init (&servicedir_path))
03489     return FALSE;
03490 
03491   xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
03492   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03493 
03494   if (xdg_data_dirs != NULL)
03495     {
03496       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03497         goto oom;
03498 
03499       if (!_dbus_string_append (&servicedir_path, ":"))
03500         goto oom;
03501     }
03502   else
03503     {
03504       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03505         goto oom;
03506     }
03507 
03508   /*
03509    * add configured datadir to defaults
03510    * this may be the same as an xdg dir
03511    * however the config parser should take
03512    * care of duplicates
03513    */
03514   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03515         goto oom;
03516 
03517   if (xdg_data_home != NULL)
03518     {
03519       if (!_dbus_string_append (&servicedir_path, xdg_data_home))
03520         goto oom;
03521     }
03522   else
03523     {
03524       const DBusString *homedir;
03525       DBusString local_share;
03526 
03527       if (!_dbus_homedir_from_current_process (&homedir))
03528         goto oom;
03529 
03530       if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
03531         goto oom;
03532 
03533       _dbus_string_init_const (&local_share, "/.local/share");
03534       if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
03535         goto oom;
03536     }
03537 
03538   if (!_dbus_split_paths_and_append (&servicedir_path,
03539                                      DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
03540                                      dirs))
03541     goto oom;
03542 
03543   _dbus_string_free (&servicedir_path);
03544   return TRUE;
03545 
03546  oom:
03547   _dbus_string_free (&servicedir_path);
03548   return FALSE;
03549 }
03550 
03551 
03570 dbus_bool_t
03571 _dbus_get_standard_system_servicedirs (DBusList **dirs)
03572 {
03573   const char *xdg_data_dirs;
03574   DBusString servicedir_path;
03575 
03576   if (!_dbus_string_init (&servicedir_path))
03577     return FALSE;
03578 
03579   xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
03580 
03581   if (xdg_data_dirs != NULL)
03582     {
03583       if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
03584         goto oom;
03585 
03586       if (!_dbus_string_append (&servicedir_path, ":"))
03587         goto oom;
03588     }
03589   else
03590     {
03591       if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
03592         goto oom;
03593     }
03594 
03595   /*
03596    * add configured datadir to defaults
03597    * this may be the same as an xdg dir
03598    * however the config parser should take
03599    * care of duplicates
03600    */
03601   if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
03602         goto oom;
03603 
03604   if (!_dbus_split_paths_and_append (&servicedir_path,
03605                                      DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
03606                                      dirs))
03607     goto oom;
03608 
03609   _dbus_string_free (&servicedir_path);
03610   return TRUE;
03611 
03612  oom:
03613   _dbus_string_free (&servicedir_path);
03614   return FALSE;
03615 }
03616 
03625 dbus_bool_t
03626 _dbus_append_system_config_file (DBusString *str)
03627 {
03628   return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
03629 }
03630 
03637 dbus_bool_t
03638 _dbus_append_session_config_file (DBusString *str)
03639 {
03640   return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
03641 }
03642 
03650 void
03651 _dbus_flush_caches (void)
03652 {
03653   _dbus_user_database_flush_system ();
03654 }
03655 
03669 dbus_bool_t
03670 _dbus_append_keyring_directory_for_credentials (DBusString      *directory,
03671                                                 DBusCredentials *credentials)
03672 {
03673   DBusString homedir;
03674   DBusString dotdir;
03675   dbus_uid_t uid;
03676 
03677   _dbus_assert (credentials != NULL);
03678   _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
03679 
03680   if (!_dbus_string_init (&homedir))
03681     return FALSE;
03682 
03683   uid = _dbus_credentials_get_unix_uid (credentials);
03684   _dbus_assert (uid != DBUS_UID_UNSET);
03685 
03686   if (!_dbus_homedir_from_uid (uid, &homedir))
03687     goto failed;
03688 
03689 #ifdef DBUS_BUILD_TESTS
03690   {
03691     const char *override;
03692 
03693     override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
03694     if (override != NULL && *override != '\0')
03695       {
03696         _dbus_string_set_length (&homedir, 0);
03697         if (!_dbus_string_append (&homedir, override))
03698           goto failed;
03699 
03700         _dbus_verbose ("Using fake homedir for testing: %s\n",
03701                        _dbus_string_get_const_data (&homedir));
03702       }
03703     else
03704       {
03705         static dbus_bool_t already_warned = FALSE;
03706         if (!already_warned)
03707           {
03708             _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
03709             already_warned = TRUE;
03710           }
03711       }
03712   }
03713 #endif
03714 
03715   _dbus_string_init_const (&dotdir, ".dbus-keyrings");
03716   if (!_dbus_concat_dir_and_file (&homedir,
03717                                   &dotdir))
03718     goto failed;
03719 
03720   if (!_dbus_string_copy (&homedir, 0,
03721                           directory, _dbus_string_get_length (directory))) {
03722     goto failed;
03723   }
03724 
03725   _dbus_string_free (&homedir);
03726   return TRUE;
03727 
03728  failed:
03729   _dbus_string_free (&homedir);
03730   return FALSE;
03731 }
03732 
03733 //PENDING(kdab) docs
03734 dbus_bool_t
03735 _dbus_daemon_publish_session_bus_address (const char* addr,
03736                                           const char *scope)
03737 {
03738   return TRUE;
03739 }
03740 
03741 //PENDING(kdab) docs
03742 void
03743 _dbus_daemon_unpublish_session_bus_address (void)
03744 {
03745 
03746 }
03747 
03754 dbus_bool_t
03755 _dbus_get_is_errno_eagain_or_ewouldblock (void)
03756 {
03757   return errno == EAGAIN || errno == EWOULDBLOCK;
03758 }
03759 
03767 dbus_bool_t
03768 _dbus_delete_directory (const DBusString *filename,
03769                         DBusError        *error)
03770 {
03771   const char *filename_c;
03772 
03773   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
03774 
03775   filename_c = _dbus_string_get_const_data (filename);
03776 
03777   if (rmdir (filename_c) != 0)
03778     {
03779       dbus_set_error (error, DBUS_ERROR_FAILED,
03780                       "Failed to remove directory %s: %s\n",
03781                       filename_c, _dbus_strerror (errno));
03782       return FALSE;
03783     }
03784 
03785   return TRUE;
03786 }
03787 
03795 dbus_bool_t
03796 _dbus_socket_can_pass_unix_fd(int fd) {
03797 
03798 #ifdef SCM_RIGHTS
03799   union {
03800     struct sockaddr sa;
03801     struct sockaddr_storage storage;
03802     struct sockaddr_un un;
03803   } sa_buf;
03804 
03805   socklen_t sa_len = sizeof(sa_buf);
03806 
03807   _DBUS_ZERO(sa_buf);
03808 
03809   if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
03810     return FALSE;
03811 
03812   return sa_buf.sa.sa_family == AF_UNIX;
03813 
03814 #else
03815   return FALSE;
03816 
03817 #endif
03818 }
03819 
03820 
03821 /*
03822  * replaces the term DBUS_PREFIX in configure_time_path by the
03823  * current dbus installation directory. On unix this function is a noop
03824  *
03825  * @param configure_time_path
03826  * @return real path
03827  */
03828 const char *
03829 _dbus_replace_install_prefix (const char *configure_time_path)
03830 {
03831   return configure_time_path;
03832 }
03833 
03834 /* tests in dbus-sysdeps-util.c */