1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2/* dbus-sysdeps-unix.c Wrappers around UNIX system/libc features (internal to D-Bus implementation)
3 *
4 * Copyright (C) 2002, 2003, 2006  Red Hat, Inc.
5 * Copyright (C) 2003 CodeFactory AB
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 */
24
25#include <config.h>
26
27#include "dbus-internals.h"
28#include "dbus-sysdeps.h"
29#include "dbus-sysdeps-unix.h"
30#include "dbus-threads.h"
31#include "dbus-protocol.h"
32#include "dbus-transport.h"
33#include "dbus-string.h"
34#include "dbus-userdb.h"
35#include "dbus-list.h"
36#include "dbus-credentials.h"
37#include "dbus-nonce.h"
38
39#include <sys/types.h>
40#include <stdlib.h>
41#include <string.h>
42#include <signal.h>
43#include <unistd.h>
44#include <stdio.h>
45#include <fcntl.h>
46#include <sys/socket.h>
47#include <dirent.h>
48#include <sys/un.h>
49#include <pwd.h>
50#include <time.h>
51#include <locale.h>
52#include <sys/time.h>
53#include <sys/stat.h>
54#include <sys/wait.h>
55#include <netinet/in.h>
56#include <netdb.h>
57#include <grp.h>
58#include <cutils/sockets.h>
59
60#ifdef HAVE_ERRNO_H
61#include <errno.h>
62#endif
63#ifdef HAVE_WRITEV
64#include <sys/uio.h>
65#endif
66#ifdef HAVE_POLL
67#include <sys/poll.h>
68#endif
69#ifdef HAVE_BACKTRACE
70#include <execinfo.h>
71#endif
72#ifdef HAVE_GETPEERUCRED
73#include <ucred.h>
74#endif
75
76#ifdef HAVE_ADT
77#include <bsm/adt.h>
78#endif
79
80// Android specific atomic operation header.
81#ifdef ANDROID_ATOMIC
82#include <cutils/atomic.h>
83#endif
84
85#include "sd-daemon.h"
86
87#ifndef O_BINARY
88#define O_BINARY 0
89#endif
90
91#ifndef AI_ADDRCONFIG
92#define AI_ADDRCONFIG 0
93#endif
94
95#ifndef HAVE_SOCKLEN_T
96#define socklen_t int
97#endif
98
99static dbus_bool_t
100_dbus_open_socket (int              *fd_p,
101                   int               domain,
102                   int               type,
103                   int               protocol,
104                   DBusError        *error)
105{
106#ifdef SOCK_CLOEXEC
107  dbus_bool_t cloexec_done;
108
109  *fd_p = socket (domain, type | SOCK_CLOEXEC, protocol);
110  cloexec_done = *fd_p >= 0;
111
112  /* Check if kernel seems to be too old to know SOCK_CLOEXEC */
113  if (*fd_p < 0 && errno == EINVAL)
114#endif
115    {
116      *fd_p = socket (domain, type, protocol);
117    }
118
119  if (*fd_p >= 0)
120    {
121#ifdef SOCK_CLOEXEC
122      if (!cloexec_done)
123#endif
124        {
125          _dbus_fd_set_close_on_exec(*fd_p);
126        }
127
128      _dbus_verbose ("socket fd %d opened\n", *fd_p);
129      return TRUE;
130    }
131  else
132    {
133      dbus_set_error(error,
134                     _dbus_error_from_errno (errno),
135                     "Failed to open socket: %s",
136                     _dbus_strerror (errno));
137      return FALSE;
138    }
139}
140
141dbus_bool_t
142_dbus_open_tcp_socket (int              *fd,
143                       DBusError        *error)
144{
145  return _dbus_open_socket(fd, AF_INET, SOCK_STREAM, 0, error);
146}
147
148/**
149 * Opens a UNIX domain socket (as in the socket() call).
150 * Does not bind the socket.
151 *
152 * This will set FD_CLOEXEC for the socket returned
153 *
154 * @param fd return location for socket descriptor
155 * @param error return location for an error
156 * @returns #FALSE if error is set
157 */
158dbus_bool_t
159_dbus_open_unix_socket (int              *fd,
160                        DBusError        *error)
161{
162  return _dbus_open_socket(fd, PF_UNIX, SOCK_STREAM, 0, error);
163}
164
165/**
166 * Closes a socket. Should not be used on non-socket
167 * file descriptors or handles.
168 *
169 * @param fd the socket
170 * @param error return location for an error
171 * @returns #FALSE if error is set
172 */
173dbus_bool_t
174_dbus_close_socket (int               fd,
175                    DBusError        *error)
176{
177  return _dbus_close (fd, error);
178}
179
180/**
181 * Like _dbus_read(), but only works on sockets so is
182 * available on Windows.
183 *
184 * @param fd the socket
185 * @param buffer string to append data to
186 * @param count max amount of data to read
187 * @returns number of bytes appended to the string
188 */
189int
190_dbus_read_socket (int               fd,
191                   DBusString       *buffer,
192                   int               count)
193{
194  return _dbus_read (fd, buffer, count);
195}
196
197/**
198 * Like _dbus_write(), but only supports sockets
199 * and is thus available on Windows.
200 *
201 * @param fd the file descriptor to write
202 * @param buffer the buffer to write data from
203 * @param start the first byte in the buffer to write
204 * @param len the number of bytes to try to write
205 * @returns the number of bytes written or -1 on error
206 */
207int
208_dbus_write_socket (int               fd,
209                    const DBusString *buffer,
210                    int               start,
211                    int               len)
212{
213#ifdef MSG_NOSIGNAL
214  const char *data;
215  int bytes_written;
216
217  data = _dbus_string_get_const_data_len (buffer, start, len);
218
219 again:
220
221  bytes_written = send (fd, data, len, MSG_NOSIGNAL);
222
223  if (bytes_written < 0 && errno == EINTR)
224    goto again;
225
226  return bytes_written;
227
228#else
229  return _dbus_write (fd, buffer, start, len);
230#endif
231}
232
233/**
234 * Like _dbus_read_socket() but also tries to read unix fds from the
235 * socket. When there are more fds to read than space in the array
236 * passed this function will fail with ENOSPC.
237 *
238 * @param fd the socket
239 * @param buffer string to append data to
240 * @param count max amount of data to read
241 * @param fds array to place read file descriptors in
242 * @param n_fds on input space in fds array, on output how many fds actually got read
243 * @returns number of bytes appended to string
244 */
245int
246_dbus_read_socket_with_unix_fds (int               fd,
247                                 DBusString       *buffer,
248                                 int               count,
249                                 int              *fds,
250                                 int              *n_fds) {
251#ifndef HAVE_UNIX_FD_PASSING
252  int r;
253
254  if ((r = _dbus_read_socket(fd, buffer, count)) < 0)
255    return r;
256
257  *n_fds = 0;
258  return r;
259
260#else
261  int bytes_read;
262  int start;
263  struct msghdr m;
264  struct iovec iov;
265
266  _dbus_assert (count >= 0);
267  _dbus_assert (*n_fds >= 0);
268
269  start = _dbus_string_get_length (buffer);
270
271  if (!_dbus_string_lengthen (buffer, count))
272    {
273      errno = ENOMEM;
274      return -1;
275    }
276
277  _DBUS_ZERO(iov);
278  iov.iov_base = _dbus_string_get_data_len (buffer, start, count);
279  iov.iov_len = count;
280
281  _DBUS_ZERO(m);
282  m.msg_iov = &iov;
283  m.msg_iovlen = 1;
284
285  /* Hmm, we have no clue how long the control data will actually be
286     that is queued for us. The least we can do is assume that the
287     caller knows. Hence let's make space for the number of fds that
288     we shall read at max plus the cmsg header. */
289  m.msg_controllen = CMSG_SPACE(*n_fds * sizeof(int));
290
291  /* It's probably safe to assume that systems with SCM_RIGHTS also
292     know alloca() */
293  m.msg_control = alloca(m.msg_controllen);
294  memset(m.msg_control, 0, m.msg_controllen);
295
296 again:
297
298  bytes_read = recvmsg(fd, &m, 0
299#ifdef MSG_CMSG_CLOEXEC
300                       |MSG_CMSG_CLOEXEC
301#endif
302                       );
303
304  if (bytes_read < 0)
305    {
306      if (errno == EINTR)
307        goto again;
308      else
309        {
310          /* put length back (note that this doesn't actually realloc anything) */
311          _dbus_string_set_length (buffer, start);
312          return -1;
313        }
314    }
315  else
316    {
317      struct cmsghdr *cm;
318      dbus_bool_t found = FALSE;
319
320      if (m.msg_flags & MSG_CTRUNC)
321        {
322          /* Hmm, apparently the control data was truncated. The bad
323             thing is that we might have completely lost a couple of fds
324             without chance to recover them. Hence let's treat this as a
325             serious error. */
326
327          errno = ENOSPC;
328          _dbus_string_set_length (buffer, start);
329          return -1;
330        }
331
332      for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
333        if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
334          {
335            unsigned i;
336
337            _dbus_assert(cm->cmsg_len <= CMSG_LEN(*n_fds * sizeof(int)));
338            *n_fds = (cm->cmsg_len - CMSG_LEN(0)) / sizeof(int);
339
340            memcpy(fds, CMSG_DATA(cm), *n_fds * sizeof(int));
341            found = TRUE;
342
343            /* Linux doesn't tell us whether MSG_CMSG_CLOEXEC actually
344               worked, hence we need to go through this list and set
345               CLOEXEC everywhere in any case */
346            for (i = 0; i < *n_fds; i++)
347              _dbus_fd_set_close_on_exec(fds[i]);
348
349            break;
350          }
351
352      if (!found)
353        *n_fds = 0;
354
355      /* put length back (doesn't actually realloc) */
356      _dbus_string_set_length (buffer, start + bytes_read);
357
358#if 0
359      if (bytes_read > 0)
360        _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
361#endif
362
363      return bytes_read;
364    }
365#endif
366}
367
368int
369_dbus_write_socket_with_unix_fds(int               fd,
370                                 const DBusString *buffer,
371                                 int               start,
372                                 int               len,
373                                 const int        *fds,
374                                 int               n_fds) {
375
376#ifndef HAVE_UNIX_FD_PASSING
377
378  if (n_fds > 0) {
379    errno = ENOTSUP;
380    return -1;
381  }
382
383  return _dbus_write_socket(fd, buffer, start, len);
384#else
385  return _dbus_write_socket_with_unix_fds_two(fd, buffer, start, len, NULL, 0, 0, fds, n_fds);
386#endif
387}
388
389int
390_dbus_write_socket_with_unix_fds_two(int               fd,
391                                     const DBusString *buffer1,
392                                     int               start1,
393                                     int               len1,
394                                     const DBusString *buffer2,
395                                     int               start2,
396                                     int               len2,
397                                     const int        *fds,
398                                     int               n_fds) {
399
400#ifndef HAVE_UNIX_FD_PASSING
401
402  if (n_fds > 0) {
403    errno = ENOTSUP;
404    return -1;
405  }
406
407  return _dbus_write_socket_two(fd,
408                                buffer1, start1, len1,
409                                buffer2, start2, len2);
410#else
411
412  struct msghdr m;
413  struct cmsghdr *cm;
414  struct iovec iov[2];
415  int bytes_written;
416
417  _dbus_assert (len1 >= 0);
418  _dbus_assert (len2 >= 0);
419  _dbus_assert (n_fds >= 0);
420
421  _DBUS_ZERO(iov);
422  iov[0].iov_base = (char*) _dbus_string_get_const_data_len (buffer1, start1, len1);
423  iov[0].iov_len = len1;
424
425  if (buffer2)
426    {
427      iov[1].iov_base = (char*) _dbus_string_get_const_data_len (buffer2, start2, len2);
428      iov[1].iov_len = len2;
429    }
430
431  _DBUS_ZERO(m);
432  m.msg_iov = iov;
433  m.msg_iovlen = buffer2 ? 2 : 1;
434
435  if (n_fds > 0)
436    {
437      m.msg_controllen = CMSG_SPACE(n_fds * sizeof(int));
438      m.msg_control = alloca(m.msg_controllen);
439      memset(m.msg_control, 0, m.msg_controllen);
440
441      cm = CMSG_FIRSTHDR(&m);
442      cm->cmsg_level = SOL_SOCKET;
443      cm->cmsg_type = SCM_RIGHTS;
444      cm->cmsg_len = CMSG_LEN(n_fds * sizeof(int));
445      memcpy(CMSG_DATA(cm), fds, n_fds * sizeof(int));
446    }
447
448 again:
449
450  bytes_written = sendmsg (fd, &m, 0
451#ifdef MSG_NOSIGNAL
452                           |MSG_NOSIGNAL
453#endif
454                           );
455
456  if (bytes_written < 0 && errno == EINTR)
457    goto again;
458
459#if 0
460  if (bytes_written > 0)
461    _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
462#endif
463
464  return bytes_written;
465#endif
466}
467
468/**
469 * Like _dbus_write_two() but only works on sockets and is thus
470 * available on Windows.
471 *
472 * @param fd the file descriptor
473 * @param buffer1 first buffer
474 * @param start1 first byte to write in first buffer
475 * @param len1 number of bytes to write from first buffer
476 * @param buffer2 second buffer, or #NULL
477 * @param start2 first byte to write in second buffer
478 * @param len2 number of bytes to write in second buffer
479 * @returns total bytes written from both buffers, or -1 on error
480 */
481int
482_dbus_write_socket_two (int               fd,
483                        const DBusString *buffer1,
484                        int               start1,
485                        int               len1,
486                        const DBusString *buffer2,
487                        int               start2,
488                        int               len2)
489{
490#ifdef MSG_NOSIGNAL
491  struct iovec vectors[2];
492  const char *data1;
493  const char *data2;
494  int bytes_written;
495  struct msghdr m;
496
497  _dbus_assert (buffer1 != NULL);
498  _dbus_assert (start1 >= 0);
499  _dbus_assert (start2 >= 0);
500  _dbus_assert (len1 >= 0);
501  _dbus_assert (len2 >= 0);
502
503  data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
504
505  if (buffer2 != NULL)
506    data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
507  else
508    {
509      data2 = NULL;
510      start2 = 0;
511      len2 = 0;
512    }
513
514  vectors[0].iov_base = (char*) data1;
515  vectors[0].iov_len = len1;
516  vectors[1].iov_base = (char*) data2;
517  vectors[1].iov_len = len2;
518
519  _DBUS_ZERO(m);
520  m.msg_iov = vectors;
521  m.msg_iovlen = data2 ? 2 : 1;
522
523 again:
524
525  bytes_written = sendmsg (fd, &m, MSG_NOSIGNAL);
526
527  if (bytes_written < 0 && errno == EINTR)
528    goto again;
529
530  return bytes_written;
531
532#else
533  return _dbus_write_two (fd, buffer1, start1, len1,
534                          buffer2, start2, len2);
535#endif
536}
537
538dbus_bool_t
539_dbus_socket_is_invalid (int fd)
540{
541    return fd < 0 ? TRUE : FALSE;
542}
543
544/**
545 * Thin wrapper around the read() system call that appends
546 * the data it reads to the DBusString buffer. It appends
547 * up to the given count, and returns the same value
548 * and same errno as read(). The only exception is that
549 * _dbus_read() handles EINTR for you. Also, _dbus_read() can
550 * return ENOMEM, even though regular UNIX read doesn't.
551 *
552 * Unlike _dbus_read_socket(), _dbus_read() is not available
553 * on Windows.
554 *
555 * @param fd the file descriptor to read from
556 * @param buffer the buffer to append data to
557 * @param count the amount of data to read
558 * @returns the number of bytes read or -1
559 */
560int
561_dbus_read (int               fd,
562            DBusString       *buffer,
563            int               count)
564{
565  int bytes_read;
566  int start;
567  char *data;
568
569  _dbus_assert (count >= 0);
570
571  start = _dbus_string_get_length (buffer);
572
573  if (!_dbus_string_lengthen (buffer, count))
574    {
575      errno = ENOMEM;
576      return -1;
577    }
578
579  data = _dbus_string_get_data_len (buffer, start, count);
580
581 again:
582
583  bytes_read = read (fd, data, count);
584
585  if (bytes_read < 0)
586    {
587      if (errno == EINTR)
588        goto again;
589      else
590        {
591          /* put length back (note that this doesn't actually realloc anything) */
592          _dbus_string_set_length (buffer, start);
593          return -1;
594        }
595    }
596  else
597    {
598      /* put length back (doesn't actually realloc) */
599      _dbus_string_set_length (buffer, start + bytes_read);
600
601#if 0
602      if (bytes_read > 0)
603        _dbus_verbose_bytes_of_string (buffer, start, bytes_read);
604#endif
605
606      return bytes_read;
607    }
608}
609
610/**
611 * Thin wrapper around the write() system call that writes a part of a
612 * DBusString and handles EINTR for you.
613 *
614 * @param fd the file descriptor to write
615 * @param buffer the buffer to write data from
616 * @param start the first byte in the buffer to write
617 * @param len the number of bytes to try to write
618 * @returns the number of bytes written or -1 on error
619 */
620int
621_dbus_write (int               fd,
622             const DBusString *buffer,
623             int               start,
624             int               len)
625{
626  const char *data;
627  int bytes_written;
628
629  data = _dbus_string_get_const_data_len (buffer, start, len);
630
631 again:
632
633  bytes_written = write (fd, data, len);
634
635  if (bytes_written < 0 && errno == EINTR)
636    goto again;
637
638#if 0
639  if (bytes_written > 0)
640    _dbus_verbose_bytes_of_string (buffer, start, bytes_written);
641#endif
642
643  return bytes_written;
644}
645
646/**
647 * Like _dbus_write() but will use writev() if possible
648 * to write both buffers in sequence. The return value
649 * is the number of bytes written in the first buffer,
650 * plus the number written in the second. If the first
651 * buffer is written successfully and an error occurs
652 * writing the second, the number of bytes in the first
653 * is returned (i.e. the error is ignored), on systems that
654 * don't have writev. Handles EINTR for you.
655 * The second buffer may be #NULL.
656 *
657 * @param fd the file descriptor
658 * @param buffer1 first buffer
659 * @param start1 first byte to write in first buffer
660 * @param len1 number of bytes to write from first buffer
661 * @param buffer2 second buffer, or #NULL
662 * @param start2 first byte to write in second buffer
663 * @param len2 number of bytes to write in second buffer
664 * @returns total bytes written from both buffers, or -1 on error
665 */
666int
667_dbus_write_two (int               fd,
668                 const DBusString *buffer1,
669                 int               start1,
670                 int               len1,
671                 const DBusString *buffer2,
672                 int               start2,
673                 int               len2)
674{
675  _dbus_assert (buffer1 != NULL);
676  _dbus_assert (start1 >= 0);
677  _dbus_assert (start2 >= 0);
678  _dbus_assert (len1 >= 0);
679  _dbus_assert (len2 >= 0);
680
681#ifdef HAVE_WRITEV
682  {
683    struct iovec vectors[2];
684    const char *data1;
685    const char *data2;
686    int bytes_written;
687
688    data1 = _dbus_string_get_const_data_len (buffer1, start1, len1);
689
690    if (buffer2 != NULL)
691      data2 = _dbus_string_get_const_data_len (buffer2, start2, len2);
692    else
693      {
694        data2 = NULL;
695        start2 = 0;
696        len2 = 0;
697      }
698
699    vectors[0].iov_base = (char*) data1;
700    vectors[0].iov_len = len1;
701    vectors[1].iov_base = (char*) data2;
702    vectors[1].iov_len = len2;
703
704  again:
705
706    bytes_written = writev (fd,
707                            vectors,
708                            data2 ? 2 : 1);
709
710    if (bytes_written < 0 && errno == EINTR)
711      goto again;
712
713    return bytes_written;
714  }
715#else /* HAVE_WRITEV */
716  {
717    int ret1;
718
719    ret1 = _dbus_write (fd, buffer1, start1, len1);
720    if (ret1 == len1 && buffer2 != NULL)
721      {
722        ret2 = _dbus_write (fd, buffer2, start2, len2);
723        if (ret2 < 0)
724          ret2 = 0; /* we can't report an error as the first write was OK */
725
726        return ret1 + ret2;
727      }
728    else
729      return ret1;
730  }
731#endif /* !HAVE_WRITEV */
732}
733
734#define _DBUS_MAX_SUN_PATH_LENGTH 99
735
736/**
737 * @def _DBUS_MAX_SUN_PATH_LENGTH
738 *
739 * Maximum length of the path to a UNIX domain socket,
740 * sockaddr_un::sun_path member. POSIX requires that all systems
741 * support at least 100 bytes here, including the nul termination.
742 * We use 99 for the max value to allow for the nul.
743 *
744 * We could probably also do sizeof (addr.sun_path)
745 * but this way we are the same on all platforms
746 * which is probably a good idea.
747 */
748
749/**
750 * Creates a socket and connects it to the UNIX domain socket at the
751 * given path.  The connection fd is returned, and is set up as
752 * nonblocking.
753 *
754 * Uses abstract sockets instead of filesystem-linked sockets if
755 * requested (it's possible only on Linux; see "man 7 unix" on Linux).
756 * On non-Linux abstract socket usage always fails.
757 *
758 * This will set FD_CLOEXEC for the socket returned.
759 *
760 * @param path the path to UNIX domain socket
761 * @param abstract #TRUE to use abstract namespace
762 * @param error return location for error code
763 * @returns connection file descriptor or -1 on error
764 */
765int
766_dbus_connect_unix_socket (const char     *path,
767                           dbus_bool_t     abstract,
768                           DBusError      *error)
769{
770  int fd;
771  size_t path_len;
772  struct sockaddr_un addr;
773
774  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
775
776  _dbus_verbose ("connecting to unix socket %s abstract=%d\n",
777                 path, abstract);
778
779
780  if (!_dbus_open_unix_socket (&fd, error))
781    {
782      _DBUS_ASSERT_ERROR_IS_SET(error);
783      return -1;
784    }
785  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
786
787  _DBUS_ZERO (addr);
788  addr.sun_family = AF_UNIX;
789  path_len = strlen (path);
790
791  if (abstract)
792    {
793#ifdef HAVE_ABSTRACT_SOCKETS
794      addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
795      path_len++; /* Account for the extra nul byte added to the start of sun_path */
796
797      if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
798        {
799          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
800                      "Abstract socket name too long\n");
801          _dbus_close (fd, NULL);
802          return -1;
803	}
804
805      strncpy (&addr.sun_path[1], path, path_len);
806      /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
807#else /* HAVE_ABSTRACT_SOCKETS */
808      dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
809                      "Operating system does not support abstract socket namespace\n");
810      _dbus_close (fd, NULL);
811      return -1;
812#endif /* ! HAVE_ABSTRACT_SOCKETS */
813    }
814  else
815    {
816      if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
817        {
818          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
819                      "Socket name too long\n");
820          _dbus_close (fd, NULL);
821          return -1;
822	}
823
824      strncpy (addr.sun_path, path, path_len);
825    }
826
827  if (connect (fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
828    {
829      dbus_set_error (error,
830                      _dbus_error_from_errno (errno),
831                      "Failed to connect to socket %s: %s",
832                      path, _dbus_strerror (errno));
833
834      _dbus_close (fd, NULL);
835      fd = -1;
836
837      return -1;
838    }
839
840  if (!_dbus_set_fd_nonblocking (fd, error))
841    {
842      _DBUS_ASSERT_ERROR_IS_SET (error);
843
844      _dbus_close (fd, NULL);
845      fd = -1;
846
847      return -1;
848    }
849
850  return fd;
851}
852
853/**
854 * Enables or disables the reception of credentials on the given socket during
855 * the next message transmission.  This is only effective if the #LOCAL_CREDS
856 * system feature exists, in which case the other side of the connection does
857 * not have to do anything special to send the credentials.
858 *
859 * @param fd socket on which to change the #LOCAL_CREDS flag.
860 * @param on whether to enable or disable the #LOCAL_CREDS flag.
861 */
862static dbus_bool_t
863_dbus_set_local_creds (int fd, dbus_bool_t on)
864{
865  dbus_bool_t retval = TRUE;
866
867#if defined(HAVE_CMSGCRED)
868  /* NOOP just to make sure only one codepath is used
869   *      and to prefer CMSGCRED
870   */
871#elif defined(LOCAL_CREDS)
872  int val = on ? 1 : 0;
873  if (setsockopt (fd, 0, LOCAL_CREDS, &val, sizeof (val)) < 0)
874    {
875      _dbus_verbose ("Unable to set LOCAL_CREDS socket option on fd %d\n", fd);
876      retval = FALSE;
877    }
878  else
879    _dbus_verbose ("LOCAL_CREDS %s for further messages on fd %d\n",
880                   on ? "enabled" : "disabled", fd);
881#endif
882
883  return retval;
884}
885
886/**
887 * Creates a socket and binds it to the given path,
888 * then listens on the socket. The socket is
889 * set to be nonblocking.
890 *
891 * Uses abstract sockets instead of filesystem-linked
892 * sockets if requested (it's possible only on Linux;
893 * see "man 7 unix" on Linux).
894 * On non-Linux abstract socket usage always fails.
895 *
896 * This will set FD_CLOEXEC for the socket returned
897 *
898 * @param path the socket name
899 * @param abstract #TRUE to use abstract namespace
900 * @param error return location for errors
901 * @returns the listening file descriptor or -1 on error
902 */
903int
904_dbus_listen_unix_socket (const char     *path,
905                          dbus_bool_t     abstract,
906                          DBusError      *error)
907{
908  int listen_fd;
909  struct sockaddr_un addr;
910  size_t path_len;
911  unsigned int reuseaddr;
912
913  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
914
915  _dbus_verbose ("listening on unix socket %s abstract=%d\n",
916                 path, abstract);
917#ifdef ANDROID_MANAGED_SOCKET
918  if (strncmp (path, ANDROID_SOCKET_DIR"/", strlen(ANDROID_SOCKET_DIR"/")) == 0)
919    {
920      const char* suffix;
921      /* init has created a socket for us, pick it up from environ */
922      suffix = &path[strlen (ANDROID_SOCKET_DIR"/")];
923      listen_fd = android_get_control_socket (suffix);
924      if (listen_fd == -1)
925        {
926          dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
927                "Could not obtain fd for android socket %s\n", suffix);
928          return -1;
929        }
930
931      _dbus_verbose ("Obtained fd for android socket %s\n", suffix);
932    }
933  else
934    {
935      dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
936            "Not an android socket: %s\n", path);
937      return -1;
938    }
939#else
940
941  if (!_dbus_open_unix_socket (&listen_fd, error))
942    {
943      _DBUS_ASSERT_ERROR_IS_SET(error);
944      return -1;
945    }
946  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
947
948  _DBUS_ZERO (addr);
949  addr.sun_family = AF_UNIX;
950  path_len = strlen (path);
951
952  if (abstract)
953    {
954#ifdef HAVE_ABSTRACT_SOCKETS
955      /* remember that abstract names aren't nul-terminated so we rely
956       * on sun_path being filled in with zeroes above.
957       */
958      addr.sun_path[0] = '\0'; /* this is what says "use abstract" */
959      path_len++; /* Account for the extra nul byte added to the start of sun_path */
960
961      if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
962        {
963          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
964                      "Abstract socket name too long\n");
965          _dbus_close (listen_fd, NULL);
966          return -1;
967	}
968
969      strncpy (&addr.sun_path[1], path, path_len);
970      /* _dbus_verbose_bytes (addr.sun_path, sizeof (addr.sun_path)); */
971#else /* HAVE_ABSTRACT_SOCKETS */
972      dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
973                      "Operating system does not support abstract socket namespace\n");
974      _dbus_close (listen_fd, NULL);
975      return -1;
976#endif /* ! HAVE_ABSTRACT_SOCKETS */
977    }
978  else
979    {
980      /* Discussed security implications of this with Nalin,
981       * and we couldn't think of where it would kick our ass, but
982       * it still seems a bit sucky. It also has non-security suckage;
983       * really we'd prefer to exit if the socket is already in use.
984       * But there doesn't seem to be a good way to do this.
985       *
986       * Just to be extra careful, I threw in the stat() - clearly
987       * the stat() can't *fix* any security issue, but it at least
988       * avoids inadvertent/accidental data loss.
989       */
990      {
991        struct stat sb;
992
993        if (stat (path, &sb) == 0 &&
994            S_ISSOCK (sb.st_mode))
995          unlink (path);
996      }
997
998      if (path_len > _DBUS_MAX_SUN_PATH_LENGTH)
999        {
1000          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1001                      "Abstract socket name too long\n");
1002          _dbus_close (listen_fd, NULL);
1003          return -1;
1004	}
1005
1006      strncpy (addr.sun_path, path, path_len);
1007    }
1008
1009  reuseaddr = 1;
1010  if (setsockopt  (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1011    {
1012      _dbus_warn ("Failed to set socket option\"%s\": %s",
1013                  path, _dbus_strerror (errno));
1014    }
1015
1016  if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
1017    {
1018      dbus_set_error (error, _dbus_error_from_errno (errno),
1019                      "Failed to bind socket \"%s\": %s",
1020                      path, _dbus_strerror (errno));
1021      _dbus_close (listen_fd, NULL);
1022      return -1;
1023    }
1024
1025#endif  /* android init managed sockets */
1026
1027  if (listen (listen_fd, 30 /* backlog */) < 0)
1028    {
1029      dbus_set_error (error, _dbus_error_from_errno (errno),
1030                      "Failed to listen on socket \"%s\": %s",
1031                      path, _dbus_strerror (errno));
1032      _dbus_close (listen_fd, NULL);
1033      return -1;
1034    }
1035
1036  if (!_dbus_set_local_creds (listen_fd, TRUE))
1037    {
1038      dbus_set_error (error, _dbus_error_from_errno (errno),
1039                      "Failed to enable LOCAL_CREDS on socket \"%s\": %s",
1040                      path, _dbus_strerror (errno));
1041      close (listen_fd);
1042      return -1;
1043    }
1044
1045  if (!_dbus_set_fd_nonblocking (listen_fd, error))
1046    {
1047      _DBUS_ASSERT_ERROR_IS_SET (error);
1048      _dbus_close (listen_fd, NULL);
1049      return -1;
1050    }
1051
1052#ifndef ANDROID_MANAGED_SOCKET
1053  /* Try opening up the permissions, but if we can't, just go ahead
1054   * and continue, maybe it will be good enough.
1055   */
1056  if (!abstract && chmod (path, 0777) < 0)
1057    _dbus_warn ("Could not set mode 0777 on socket %s\n",
1058                path);
1059#endif
1060
1061  return listen_fd;
1062}
1063
1064/**
1065 * Acquires one or more sockets passed in from systemd. The sockets
1066 * are set to be nonblocking.
1067 *
1068 * This will set FD_CLOEXEC for the sockets returned.
1069 *
1070 * @oaram fds the file descriptors
1071 * @param error return location for errors
1072 * @returns the number of file descriptors
1073 */
1074int
1075_dbus_listen_systemd_sockets (int       **fds,
1076                              DBusError *error)
1077{
1078  int r, n;
1079  unsigned fd;
1080  int *new_fds;
1081
1082  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1083
1084  n = sd_listen_fds (TRUE);
1085  if (n < 0)
1086    {
1087      dbus_set_error (error, _dbus_error_from_errno (-n),
1088                      "Failed to acquire systemd socket: %s",
1089                      _dbus_strerror (-n));
1090      return -1;
1091    }
1092
1093  if (n <= 0)
1094    {
1095      dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1096                      "No socket received.");
1097      return -1;
1098    }
1099
1100  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1101    {
1102      r = sd_is_socket (fd, AF_UNSPEC, SOCK_STREAM, 1);
1103      if (r < 0)
1104        {
1105          dbus_set_error (error, _dbus_error_from_errno (-r),
1106                          "Failed to verify systemd socket type: %s",
1107                          _dbus_strerror (-r));
1108          return -1;
1109        }
1110
1111      if (!r)
1112        {
1113          dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
1114                          "Passed socket has wrong type.");
1115          return -1;
1116        }
1117    }
1118
1119  /* OK, the file descriptors are all good, so let's take posession of
1120     them then. */
1121
1122  new_fds = dbus_new (int, n);
1123  if (!new_fds)
1124    {
1125      dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
1126                      "Failed to allocate file handle array.");
1127      goto fail;
1128    }
1129
1130  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1131    {
1132      if (!_dbus_set_local_creds (fd, TRUE))
1133        {
1134          dbus_set_error (error, _dbus_error_from_errno (errno),
1135                          "Failed to enable LOCAL_CREDS on systemd socket: %s",
1136                          _dbus_strerror (errno));
1137          goto fail;
1138        }
1139
1140      if (!_dbus_set_fd_nonblocking (fd, error))
1141        {
1142          _DBUS_ASSERT_ERROR_IS_SET (error);
1143          goto fail;
1144        }
1145
1146      new_fds[fd - SD_LISTEN_FDS_START] = fd;
1147    }
1148
1149  *fds = new_fds;
1150  return n;
1151
1152 fail:
1153
1154  for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
1155    {
1156      _dbus_close (fd, NULL);
1157    }
1158
1159  dbus_free (new_fds);
1160  return -1;
1161}
1162
1163/**
1164 * Creates a socket and connects to a socket at the given host
1165 * and port. The connection fd is returned, and is set up as
1166 * nonblocking.
1167 *
1168 * This will set FD_CLOEXEC for the socket returned
1169 *
1170 * @param host the host name to connect to
1171 * @param port the port to connect to
1172 * @param family the address family to listen on, NULL for all
1173 * @param error return location for error code
1174 * @returns connection file descriptor or -1 on error
1175 */
1176int
1177_dbus_connect_tcp_socket (const char     *host,
1178                          const char     *port,
1179                          const char     *family,
1180                          DBusError      *error)
1181{
1182    return _dbus_connect_tcp_socket_with_nonce (host, port, family, (const char*)NULL, error);
1183}
1184
1185int
1186_dbus_connect_tcp_socket_with_nonce (const char     *host,
1187                                     const char     *port,
1188                                     const char     *family,
1189                                     const char     *noncefile,
1190                                     DBusError      *error)
1191{
1192  int saved_errno = 0;
1193  int fd = -1, res;
1194  struct addrinfo hints;
1195  struct addrinfo *ai, *tmp;
1196
1197  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1198
1199  if (!_dbus_open_tcp_socket (&fd, error))
1200    {
1201      _DBUS_ASSERT_ERROR_IS_SET(error);
1202      return -1;
1203    }
1204
1205  _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1206
1207  _DBUS_ZERO (hints);
1208
1209  if (!family)
1210    hints.ai_family = AF_UNSPEC;
1211  else if (!strcmp(family, "ipv4"))
1212    hints.ai_family = AF_INET;
1213  else if (!strcmp(family, "ipv6"))
1214    hints.ai_family = AF_INET6;
1215  else
1216    {
1217      dbus_set_error (error,
1218                      DBUS_ERROR_BAD_ADDRESS,
1219                      "Unknown address family %s", family);
1220      return -1;
1221    }
1222  hints.ai_protocol = IPPROTO_TCP;
1223  hints.ai_socktype = SOCK_STREAM;
1224  hints.ai_flags = AI_ADDRCONFIG;
1225
1226  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0)
1227    {
1228      dbus_set_error (error,
1229                      _dbus_error_from_errno (errno),
1230                      "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1231                      host, port, gai_strerror(res), res);
1232      _dbus_close (fd, NULL);
1233      return -1;
1234    }
1235
1236  tmp = ai;
1237  while (tmp)
1238    {
1239      if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1240        {
1241          freeaddrinfo(ai);
1242          _DBUS_ASSERT_ERROR_IS_SET(error);
1243          return -1;
1244        }
1245      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1246
1247      if (connect (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1248        {
1249          saved_errno = errno;
1250          _dbus_close(fd, NULL);
1251          fd = -1;
1252          tmp = tmp->ai_next;
1253          continue;
1254        }
1255
1256      break;
1257    }
1258  freeaddrinfo(ai);
1259
1260  if (fd == -1)
1261    {
1262      dbus_set_error (error,
1263                      _dbus_error_from_errno (saved_errno),
1264                      "Failed to connect to socket \"%s:%s\" %s",
1265                      host, port, _dbus_strerror(saved_errno));
1266      return -1;
1267    }
1268
1269  if (noncefile != NULL)
1270    {
1271      DBusString noncefileStr;
1272      dbus_bool_t ret;
1273      _dbus_string_init_const (&noncefileStr, noncefile);
1274      ret = _dbus_send_nonce (fd, &noncefileStr, error);
1275      _dbus_string_free (&noncefileStr);
1276
1277      if (!ret)
1278    {
1279      _dbus_close (fd, NULL);
1280          return -1;
1281        }
1282    }
1283
1284  if (!_dbus_set_fd_nonblocking (fd, error))
1285    {
1286      _dbus_close (fd, NULL);
1287      return -1;
1288    }
1289
1290  return fd;
1291}
1292
1293/**
1294 * Creates a socket and binds it to the given path, then listens on
1295 * the socket. The socket is set to be nonblocking.  In case of port=0
1296 * a random free port is used and returned in the port parameter.
1297 * If inaddr_any is specified, the hostname is ignored.
1298 *
1299 * This will set FD_CLOEXEC for the socket returned
1300 *
1301 * @param host the host name to listen on
1302 * @param port the port to listen on, if zero a free port will be used
1303 * @param family the address family to listen on, NULL for all
1304 * @param retport string to return the actual port listened on
1305 * @param fds_p location to store returned file descriptors
1306 * @param error return location for errors
1307 * @returns the number of listening file descriptors or -1 on error
1308 */
1309int
1310_dbus_listen_tcp_socket (const char     *host,
1311                         const char     *port,
1312                         const char     *family,
1313                         DBusString     *retport,
1314                         int           **fds_p,
1315                         DBusError      *error)
1316{
1317  int saved_errno;
1318  int nlisten_fd = 0, *listen_fd = NULL, res, i;
1319  struct addrinfo hints;
1320  struct addrinfo *ai, *tmp;
1321  unsigned int reuseaddr;
1322
1323  *fds_p = NULL;
1324  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1325
1326  _DBUS_ZERO (hints);
1327
1328  if (!family)
1329    hints.ai_family = AF_UNSPEC;
1330  else if (!strcmp(family, "ipv4"))
1331    hints.ai_family = AF_INET;
1332  else if (!strcmp(family, "ipv6"))
1333    hints.ai_family = AF_INET6;
1334  else
1335    {
1336      dbus_set_error (error,
1337                      DBUS_ERROR_BAD_ADDRESS,
1338                      "Unknown address family %s", family);
1339      return -1;
1340    }
1341
1342  hints.ai_protocol = IPPROTO_TCP;
1343  hints.ai_socktype = SOCK_STREAM;
1344  hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE;
1345
1346 redo_lookup_with_port:
1347  if ((res = getaddrinfo(host, port, &hints, &ai)) != 0 || !ai)
1348    {
1349      dbus_set_error (error,
1350                      _dbus_error_from_errno (errno),
1351                      "Failed to lookup host/port: \"%s:%s\": %s (%d)",
1352                      host ? host : "*", port, gai_strerror(res), res);
1353      return -1;
1354    }
1355
1356  tmp = ai;
1357  while (tmp)
1358    {
1359      int fd = -1, *newlisten_fd;
1360      if (!_dbus_open_socket (&fd, tmp->ai_family, SOCK_STREAM, 0, error))
1361        {
1362          _DBUS_ASSERT_ERROR_IS_SET(error);
1363          goto failed;
1364        }
1365      _DBUS_ASSERT_ERROR_IS_CLEAR(error);
1366
1367      reuseaddr = 1;
1368      if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
1369        {
1370          _dbus_warn ("Failed to set socket option \"%s:%s\": %s",
1371                      host ? host : "*", port, _dbus_strerror (errno));
1372        }
1373
1374      if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
1375        {
1376          saved_errno = errno;
1377          _dbus_close(fd, NULL);
1378          if (saved_errno == EADDRINUSE)
1379            {
1380              /* Depending on kernel policy, it may or may not
1381                 be neccessary to bind to both IPv4 & 6 addresses
1382                 so ignore EADDRINUSE here */
1383              tmp = tmp->ai_next;
1384              continue;
1385            }
1386          dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1387                          "Failed to bind socket \"%s:%s\": %s",
1388                          host ? host : "*", port, _dbus_strerror (saved_errno));
1389          goto failed;
1390        }
1391
1392      if (listen (fd, 30 /* backlog */) < 0)
1393        {
1394          saved_errno = errno;
1395          _dbus_close (fd, NULL);
1396          dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1397                          "Failed to listen on socket \"%s:%s\": %s",
1398                          host ? host : "*", port, _dbus_strerror (saved_errno));
1399          goto failed;
1400        }
1401
1402      newlisten_fd = dbus_realloc(listen_fd, sizeof(int)*(nlisten_fd+1));
1403      if (!newlisten_fd)
1404        {
1405          saved_errno = errno;
1406          _dbus_close (fd, NULL);
1407          dbus_set_error (error, _dbus_error_from_errno (saved_errno),
1408                          "Failed to allocate file handle array: %s",
1409                          _dbus_strerror (saved_errno));
1410          goto failed;
1411        }
1412      listen_fd = newlisten_fd;
1413      listen_fd[nlisten_fd] = fd;
1414      nlisten_fd++;
1415
1416      if (!_dbus_string_get_length(retport))
1417        {
1418          /* If the user didn't specify a port, or used 0, then
1419             the kernel chooses a port. After the first address
1420             is bound to, we need to force all remaining addresses
1421             to use the same port */
1422          if (!port || !strcmp(port, "0"))
1423            {
1424              struct sockaddr_storage addr;
1425              socklen_t addrlen;
1426              char portbuf[50];
1427
1428              addrlen = sizeof(addr);
1429              getsockname(fd, (struct sockaddr*) &addr, &addrlen);
1430
1431              if ((res = getnameinfo((struct sockaddr*)&addr, addrlen, NULL, 0,
1432                                     portbuf, sizeof(portbuf),
1433                                     NI_NUMERICHOST)) != 0)
1434                {
1435                  dbus_set_error (error, _dbus_error_from_errno (errno),
1436                                  "Failed to resolve port \"%s:%s\": %s (%s)",
1437                                  host ? host : "*", port, gai_strerror(res), res);
1438                  goto failed;
1439                }
1440              if (!_dbus_string_append(retport, portbuf))
1441                {
1442                  dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1443                  goto failed;
1444                }
1445
1446              /* Release current address list & redo lookup */
1447              port = _dbus_string_get_const_data(retport);
1448              freeaddrinfo(ai);
1449              goto redo_lookup_with_port;
1450            }
1451          else
1452            {
1453              if (!_dbus_string_append(retport, port))
1454                {
1455                    dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1456                    goto failed;
1457                }
1458            }
1459        }
1460
1461      tmp = tmp->ai_next;
1462    }
1463  freeaddrinfo(ai);
1464  ai = NULL;
1465
1466  if (!nlisten_fd)
1467    {
1468      errno = EADDRINUSE;
1469      dbus_set_error (error, _dbus_error_from_errno (errno),
1470                      "Failed to bind socket \"%s:%s\": %s",
1471                      host ? host : "*", port, _dbus_strerror (errno));
1472      return -1;
1473    }
1474
1475  for (i = 0 ; i < nlisten_fd ; i++)
1476    {
1477      if (!_dbus_set_fd_nonblocking (listen_fd[i], error))
1478        {
1479          goto failed;
1480        }
1481    }
1482
1483  *fds_p = listen_fd;
1484
1485  return nlisten_fd;
1486
1487 failed:
1488  if (ai)
1489    freeaddrinfo(ai);
1490  for (i = 0 ; i < nlisten_fd ; i++)
1491    _dbus_close(listen_fd[i], NULL);
1492  dbus_free(listen_fd);
1493  return -1;
1494}
1495
1496static dbus_bool_t
1497write_credentials_byte (int             server_fd,
1498                        DBusError      *error)
1499{
1500  int bytes_written;
1501  char buf[1] = { '\0' };
1502#if defined(HAVE_CMSGCRED)
1503  union {
1504	  struct cmsghdr hdr;
1505	  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1506  } cmsg;
1507  struct iovec iov;
1508  struct msghdr msg;
1509  iov.iov_base = buf;
1510  iov.iov_len = 1;
1511
1512  _DBUS_ZERO(msg);
1513  msg.msg_iov = &iov;
1514  msg.msg_iovlen = 1;
1515
1516  msg.msg_control = (caddr_t) &cmsg;
1517  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1518  _DBUS_ZERO(cmsg);
1519  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
1520  cmsg.hdr.cmsg_level = SOL_SOCKET;
1521  cmsg.hdr.cmsg_type = SCM_CREDS;
1522#endif
1523
1524  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1525
1526 again:
1527
1528#if defined(HAVE_CMSGCRED)
1529  bytes_written = sendmsg (server_fd, &msg, 0);
1530#else
1531  bytes_written = write (server_fd, buf, 1);
1532#endif
1533
1534  if (bytes_written < 0 && errno == EINTR)
1535    goto again;
1536
1537  if (bytes_written < 0)
1538    {
1539      dbus_set_error (error, _dbus_error_from_errno (errno),
1540                      "Failed to write credentials byte: %s",
1541                     _dbus_strerror (errno));
1542      return FALSE;
1543    }
1544  else if (bytes_written == 0)
1545    {
1546      dbus_set_error (error, DBUS_ERROR_IO_ERROR,
1547                      "wrote zero bytes writing credentials byte");
1548      return FALSE;
1549    }
1550  else
1551    {
1552      _dbus_assert (bytes_written == 1);
1553      _dbus_verbose ("wrote credentials byte\n");
1554      return TRUE;
1555    }
1556}
1557
1558/**
1559 * Reads a single byte which must be nul (an error occurs otherwise),
1560 * and reads unix credentials if available. Clears the credentials
1561 * object, then adds pid/uid if available, so any previous credentials
1562 * stored in the object are lost.
1563 *
1564 * Return value indicates whether a byte was read, not whether
1565 * we got valid credentials. On some systems, such as Linux,
1566 * reading/writing the byte isn't actually required, but we do it
1567 * anyway just to avoid multiple codepaths.
1568 *
1569 * Fails if no byte is available, so you must select() first.
1570 *
1571 * The point of the byte is that on some systems we have to
1572 * use sendmsg()/recvmsg() to transmit credentials.
1573 *
1574 * @param client_fd the client file descriptor
1575 * @param credentials object to add client credentials to
1576 * @param error location to store error code
1577 * @returns #TRUE on success
1578 */
1579dbus_bool_t
1580_dbus_read_credentials_socket  (int              client_fd,
1581                                DBusCredentials *credentials,
1582                                DBusError       *error)
1583{
1584  struct msghdr msg;
1585  struct iovec iov;
1586  char buf;
1587  dbus_uid_t uid_read;
1588  dbus_pid_t pid_read;
1589  int bytes_read;
1590
1591#ifdef HAVE_CMSGCRED
1592  union {
1593    struct cmsghdr hdr;
1594    char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
1595  } cmsg;
1596
1597#elif defined(LOCAL_CREDS)
1598  struct {
1599    struct cmsghdr hdr;
1600    struct sockcred cred;
1601  } cmsg;
1602#endif
1603
1604  uid_read = DBUS_UID_UNSET;
1605  pid_read = DBUS_PID_UNSET;
1606
1607  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1608
1609  /* The POSIX spec certainly doesn't promise this, but
1610   * we need these assertions to fail as soon as we're wrong about
1611   * it so we can do the porting fixups
1612   */
1613  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
1614  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
1615  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
1616
1617  _dbus_credentials_clear (credentials);
1618
1619  /* Systems supporting LOCAL_CREDS are configured to have this feature
1620   * enabled (if it does not conflict with HAVE_CMSGCRED) prior accepting
1621   * the connection.  Therefore, the received message must carry the
1622   * credentials information without doing anything special.
1623   */
1624
1625  iov.iov_base = &buf;
1626  iov.iov_len = 1;
1627
1628  _DBUS_ZERO(msg);
1629  msg.msg_iov = &iov;
1630  msg.msg_iovlen = 1;
1631
1632#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1633  _DBUS_ZERO(cmsg);
1634  msg.msg_control = (caddr_t) &cmsg;
1635  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
1636#endif
1637
1638 again:
1639  bytes_read = recvmsg (client_fd, &msg, 0);
1640
1641  if (bytes_read < 0)
1642    {
1643      if (errno == EINTR)
1644	goto again;
1645
1646      /* EAGAIN or EWOULDBLOCK would be unexpected here since we would
1647       * normally only call read_credentials if the socket was ready
1648       * for reading
1649       */
1650
1651      dbus_set_error (error, _dbus_error_from_errno (errno),
1652                      "Failed to read credentials byte: %s",
1653                      _dbus_strerror (errno));
1654      return FALSE;
1655    }
1656  else if (bytes_read == 0)
1657    {
1658      /* this should not happen unless we are using recvmsg wrong,
1659       * so is essentially here for paranoia
1660       */
1661      dbus_set_error (error, DBUS_ERROR_FAILED,
1662                      "Failed to read credentials byte (zero-length read)");
1663      return FALSE;
1664    }
1665  else if (buf != '\0')
1666    {
1667      dbus_set_error (error, DBUS_ERROR_FAILED,
1668                      "Credentials byte was not nul");
1669      return FALSE;
1670    }
1671
1672#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
1673  if (cmsg.hdr.cmsg_len < CMSG_LEN (sizeof (struct cmsgcred))
1674		  || cmsg.hdr.cmsg_type != SCM_CREDS)
1675    {
1676      dbus_set_error (error, DBUS_ERROR_FAILED,
1677                      "Message from recvmsg() was not SCM_CREDS");
1678      return FALSE;
1679    }
1680#endif
1681
1682  _dbus_verbose ("read credentials byte\n");
1683
1684  {
1685#ifdef SO_PEERCRED
1686    struct ucred cr;
1687    int cr_len = sizeof (cr);
1688
1689    if (getsockopt (client_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
1690	cr_len == sizeof (cr))
1691      {
1692	pid_read = cr.pid;
1693	uid_read = cr.uid;
1694      }
1695    else
1696      {
1697	_dbus_verbose ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
1698		       cr_len, (int) sizeof (cr), _dbus_strerror (errno));
1699      }
1700#elif defined(HAVE_CMSGCRED)
1701    struct cmsgcred *cred;
1702
1703    cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
1704    pid_read = cred->cmcred_pid;
1705    uid_read = cred->cmcred_euid;
1706#elif defined(LOCAL_CREDS)
1707    pid_read = DBUS_PID_UNSET;
1708    uid_read = cmsg.cred.sc_uid;
1709    /* Since we have already got the credentials from this socket, we can
1710     * disable its LOCAL_CREDS flag if it was ever set. */
1711    _dbus_set_local_creds (client_fd, FALSE);
1712#elif defined(HAVE_GETPEEREID)
1713    uid_t euid;
1714    gid_t egid;
1715    if (getpeereid (client_fd, &euid, &egid) == 0)
1716      {
1717        uid_read = euid;
1718      }
1719    else
1720      {
1721        _dbus_verbose ("Failed to getpeereid() credentials: %s\n", _dbus_strerror (errno));
1722      }
1723#elif defined(HAVE_GETPEERUCRED)
1724    ucred_t * ucred = NULL;
1725    if (getpeerucred (client_fd, &ucred) == 0)
1726      {
1727        pid_read = ucred_getpid (ucred);
1728        uid_read = ucred_geteuid (ucred);
1729#ifdef HAVE_ADT
1730        /* generate audit session data based on socket ucred */
1731        adt_session_data_t *adth = NULL;
1732        adt_export_data_t *data = NULL;
1733        size_t size = 0;
1734        if (adt_start_session (&adth, NULL, 0) || (adth == NULL))
1735          {
1736            _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno));
1737          }
1738        else
1739          {
1740            if (adt_set_from_ucred (adth, ucred, ADT_NEW))
1741              {
1742                _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno));
1743              }
1744            else
1745              {
1746                size = adt_export_session_data (adth, &data);
1747                if (size <= 0)
1748                  {
1749                    _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno));
1750                  }
1751                else
1752                  {
1753                    _dbus_credentials_add_adt_audit_data (credentials, data, size);
1754                    free (data);
1755                  }
1756              }
1757            (void) adt_end_session (adth);
1758          }
1759#endif /* HAVE_ADT */
1760      }
1761    else
1762      {
1763        _dbus_verbose ("Failed to getpeerucred() credentials: %s\n", _dbus_strerror (errno));
1764      }
1765    if (ucred != NULL)
1766      ucred_free (ucred);
1767#else /* !SO_PEERCRED && !HAVE_CMSGCRED && !HAVE_GETPEEREID && !HAVE_GETPEERUCRED */
1768    _dbus_verbose ("Socket credentials not supported on this OS\n");
1769#endif
1770  }
1771
1772  _dbus_verbose ("Credentials:"
1773                 "  pid "DBUS_PID_FORMAT
1774                 "  uid "DBUS_UID_FORMAT
1775                 "\n",
1776		 pid_read,
1777		 uid_read);
1778
1779  if (pid_read != DBUS_PID_UNSET)
1780    {
1781      if (!_dbus_credentials_add_unix_pid (credentials, pid_read))
1782        {
1783          _DBUS_SET_OOM (error);
1784          return FALSE;
1785        }
1786    }
1787
1788  if (uid_read != DBUS_UID_UNSET)
1789    {
1790      if (!_dbus_credentials_add_unix_uid (credentials, uid_read))
1791        {
1792          _DBUS_SET_OOM (error);
1793          return FALSE;
1794        }
1795    }
1796
1797  return TRUE;
1798}
1799
1800/**
1801 * Sends a single nul byte with our UNIX credentials as ancillary
1802 * data.  Returns #TRUE if the data was successfully written.  On
1803 * systems that don't support sending credentials, just writes a byte,
1804 * doesn't send any credentials.  On some systems, such as Linux,
1805 * reading/writing the byte isn't actually required, but we do it
1806 * anyway just to avoid multiple codepaths.
1807 *
1808 * Fails if no byte can be written, so you must select() first.
1809 *
1810 * The point of the byte is that on some systems we have to
1811 * use sendmsg()/recvmsg() to transmit credentials.
1812 *
1813 * @param server_fd file descriptor for connection to server
1814 * @param error return location for error code
1815 * @returns #TRUE if the byte was sent
1816 */
1817dbus_bool_t
1818_dbus_send_credentials_socket  (int              server_fd,
1819                                DBusError       *error)
1820{
1821  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1822
1823  if (write_credentials_byte (server_fd, error))
1824    return TRUE;
1825  else
1826    return FALSE;
1827}
1828
1829/**
1830 * Accepts a connection on a listening socket.
1831 * Handles EINTR for you.
1832 *
1833 * This will enable FD_CLOEXEC for the returned socket.
1834 *
1835 * @param listen_fd the listen file descriptor
1836 * @returns the connection fd of the client, or -1 on error
1837 */
1838int
1839_dbus_accept  (int listen_fd)
1840{
1841  int client_fd;
1842  struct sockaddr addr;
1843  socklen_t addrlen;
1844#ifdef HAVE_ACCEPT4
1845  dbus_bool_t cloexec_done;
1846#endif
1847
1848  addrlen = sizeof (addr);
1849
1850 retry:
1851
1852#ifdef HAVE_ACCEPT4
1853  /* We assume that if accept4 is available SOCK_CLOEXEC is too */
1854  client_fd = accept4 (listen_fd, &addr, &addrlen, SOCK_CLOEXEC);
1855  cloexec_done = client_fd >= 0;
1856
1857  if (client_fd < 0 && errno == ENOSYS)
1858#endif
1859    {
1860      client_fd = accept (listen_fd, &addr, &addrlen);
1861    }
1862
1863  if (client_fd < 0)
1864    {
1865      if (errno == EINTR)
1866        goto retry;
1867    }
1868
1869  _dbus_verbose ("client fd %d accepted\n", client_fd);
1870
1871#ifdef HAVE_ACCEPT4
1872  if (!cloexec_done)
1873#endif
1874    {
1875      _dbus_fd_set_close_on_exec(client_fd);
1876    }
1877
1878  return client_fd;
1879}
1880
1881/**
1882 * Checks to make sure the given directory is
1883 * private to the user
1884 *
1885 * @param dir the name of the directory
1886 * @param error error return
1887 * @returns #FALSE on failure
1888 **/
1889dbus_bool_t
1890_dbus_check_dir_is_private_to_user (DBusString *dir, DBusError *error)
1891{
1892  const char *directory;
1893  struct stat sb;
1894
1895  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1896
1897  directory = _dbus_string_get_const_data (dir);
1898
1899  if (stat (directory, &sb) < 0)
1900    {
1901      dbus_set_error (error, _dbus_error_from_errno (errno),
1902                      "%s", _dbus_strerror (errno));
1903
1904      return FALSE;
1905    }
1906
1907  if ((S_IROTH & sb.st_mode) || (S_IWOTH & sb.st_mode) ||
1908      (S_IRGRP & sb.st_mode) || (S_IWGRP & sb.st_mode))
1909    {
1910      dbus_set_error (error, DBUS_ERROR_FAILED,
1911                     "%s directory is not private to the user", directory);
1912      return FALSE;
1913    }
1914
1915  return TRUE;
1916}
1917
1918static dbus_bool_t
1919fill_user_info_from_passwd (struct passwd *p,
1920                            DBusUserInfo  *info,
1921                            DBusError     *error)
1922{
1923  _dbus_assert (p->pw_name != NULL);
1924  _dbus_assert (p->pw_dir != NULL);
1925
1926  info->uid = p->pw_uid;
1927  info->primary_gid = p->pw_gid;
1928  info->username = _dbus_strdup (p->pw_name);
1929  info->homedir = _dbus_strdup (p->pw_dir);
1930
1931  if (info->username == NULL ||
1932      info->homedir == NULL)
1933    {
1934      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1935      return FALSE;
1936    }
1937
1938  return TRUE;
1939}
1940
1941static dbus_bool_t
1942fill_user_info (DBusUserInfo       *info,
1943                dbus_uid_t          uid,
1944                const DBusString   *username,
1945                DBusError          *error)
1946{
1947  const char *username_c;
1948
1949  /* exactly one of username/uid provided */
1950  _dbus_assert (username != NULL || uid != DBUS_UID_UNSET);
1951  _dbus_assert (username == NULL || uid == DBUS_UID_UNSET);
1952
1953  info->uid = DBUS_UID_UNSET;
1954  info->primary_gid = DBUS_GID_UNSET;
1955  info->group_ids = NULL;
1956  info->n_group_ids = 0;
1957  info->username = NULL;
1958  info->homedir = NULL;
1959
1960  if (username != NULL)
1961    username_c = _dbus_string_get_const_data (username);
1962  else
1963    username_c = NULL;
1964
1965  /* For now assuming that the getpwnam() and getpwuid() flavors
1966   * are always symmetrical, if not we have to add more configure
1967   * checks
1968   */
1969
1970#if defined (HAVE_POSIX_GETPWNAM_R) || defined (HAVE_NONPOSIX_GETPWNAM_R)
1971  {
1972    struct passwd *p;
1973    int result;
1974    size_t buflen;
1975    char *buf;
1976    struct passwd p_str;
1977
1978    /* retrieve maximum needed size for buf */
1979    buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
1980
1981    /* sysconf actually returns a long, but everything else expects size_t,
1982     * so just recast here.
1983     * https://bugs.freedesktop.org/show_bug.cgi?id=17061
1984     */
1985    if ((long) buflen <= 0)
1986      buflen = 1024;
1987
1988    result = -1;
1989    while (1)
1990      {
1991        buf = dbus_malloc (buflen);
1992        if (buf == NULL)
1993          {
1994            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1995            return FALSE;
1996          }
1997
1998        p = NULL;
1999#ifdef HAVE_POSIX_GETPWNAM_R
2000        if (uid != DBUS_UID_UNSET)
2001          result = getpwuid_r (uid, &p_str, buf, buflen,
2002                               &p);
2003        else
2004          result = getpwnam_r (username_c, &p_str, buf, buflen,
2005                               &p);
2006#else
2007        if (uid != DBUS_UID_UNSET)
2008          p = getpwuid_r (uid, &p_str, buf, buflen);
2009        else
2010          p = getpwnam_r (username_c, &p_str, buf, buflen);
2011        result = 0;
2012#endif /* !HAVE_POSIX_GETPWNAM_R */
2013        //Try a bigger buffer if ERANGE was returned
2014        if (result == ERANGE && buflen < 512 * 1024)
2015          {
2016            dbus_free (buf);
2017            buflen *= 2;
2018          }
2019        else
2020          {
2021            break;
2022          }
2023      }
2024    if (result == 0 && p == &p_str)
2025      {
2026        if (!fill_user_info_from_passwd (p, info, error))
2027          {
2028            dbus_free (buf);
2029            return FALSE;
2030          }
2031        dbus_free (buf);
2032      }
2033    else
2034      {
2035        dbus_set_error (error, _dbus_error_from_errno (errno),
2036                        "User \"%s\" unknown or no memory to allocate password entry\n",
2037                        username_c ? username_c : "???");
2038        _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2039        dbus_free (buf);
2040        return FALSE;
2041      }
2042  }
2043#else /* ! HAVE_GETPWNAM_R */
2044  {
2045    /* I guess we're screwed on thread safety here */
2046    struct passwd *p;
2047
2048    if (uid != DBUS_UID_UNSET)
2049      p = getpwuid (uid);
2050    else
2051      p = getpwnam (username_c);
2052
2053    if (p != NULL)
2054      {
2055        if (!fill_user_info_from_passwd (p, info, error))
2056          {
2057            return FALSE;
2058          }
2059      }
2060    else
2061      {
2062        dbus_set_error (error, _dbus_error_from_errno (errno),
2063                        "User \"%s\" unknown or no memory to allocate password entry\n",
2064                        username_c ? username_c : "???");
2065        _dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
2066        return FALSE;
2067      }
2068  }
2069#endif  /* ! HAVE_GETPWNAM_R */
2070
2071  /* Fill this in so we can use it to get groups */
2072  username_c = info->username;
2073
2074#ifdef HAVE_GETGROUPLIST
2075  {
2076    gid_t *buf;
2077    int buf_count;
2078    int i;
2079    int initial_buf_count;
2080
2081    initial_buf_count = 17;
2082    buf_count = initial_buf_count;
2083    buf = dbus_new (gid_t, buf_count);
2084    if (buf == NULL)
2085      {
2086        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2087        goto failed;
2088      }
2089
2090    if (getgrouplist (username_c,
2091                      info->primary_gid,
2092                      buf, &buf_count) < 0)
2093      {
2094        gid_t *new;
2095        /* Presumed cause of negative return code: buf has insufficient
2096           entries to hold the entire group list. The Linux behavior in this
2097           case is to pass back the actual number of groups in buf_count, but
2098           on Mac OS X 10.5, buf_count is unhelpfully left alone.
2099           So as a hack, try to help out a bit by guessing a larger
2100           number of groups, within reason.. might still fail, of course,
2101           but we can at least print a more informative message.  I looked up
2102           the "right way" to do this by downloading Apple's own source code
2103           for the "id" command, and it turns out that they use an
2104           undocumented library function getgrouplist_2 (!) which is not
2105           declared in any header in /usr/include (!!). That did not seem
2106           like the way to go here.
2107        */
2108        if (buf_count == initial_buf_count)
2109          {
2110            buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
2111          }
2112        new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
2113        if (new == NULL)
2114          {
2115            dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2116            dbus_free (buf);
2117            goto failed;
2118          }
2119
2120        buf = new;
2121
2122        errno = 0;
2123        if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
2124          {
2125            if (errno == 0)
2126              {
2127                _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
2128                            username_c, buf_count, buf_count);
2129              }
2130            else
2131              {
2132                dbus_set_error (error,
2133                                _dbus_error_from_errno (errno),
2134                                "Failed to get groups for username \"%s\" primary GID "
2135                                DBUS_GID_FORMAT ": %s\n",
2136                                username_c, info->primary_gid,
2137                                _dbus_strerror (errno));
2138                dbus_free (buf);
2139                goto failed;
2140              }
2141          }
2142      }
2143
2144    info->group_ids = dbus_new (dbus_gid_t, buf_count);
2145    if (info->group_ids == NULL)
2146      {
2147        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2148        dbus_free (buf);
2149        goto failed;
2150      }
2151
2152    for (i = 0; i < buf_count; ++i)
2153      info->group_ids[i] = buf[i];
2154
2155    info->n_group_ids = buf_count;
2156
2157    dbus_free (buf);
2158  }
2159#else  /* HAVE_GETGROUPLIST */
2160  {
2161    /* We just get the one group ID */
2162    info->group_ids = dbus_new (dbus_gid_t, 1);
2163    if (info->group_ids == NULL)
2164      {
2165        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
2166        goto failed;
2167      }
2168
2169    info->n_group_ids = 1;
2170
2171    (info->group_ids)[0] = info->primary_gid;
2172  }
2173#endif /* HAVE_GETGROUPLIST */
2174
2175  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2176
2177  return TRUE;
2178
2179 failed:
2180  _DBUS_ASSERT_ERROR_IS_SET (error);
2181  return FALSE;
2182}
2183
2184/**
2185 * Gets user info for the given username.
2186 *
2187 * @param info user info object to initialize
2188 * @param username the username
2189 * @param error error return
2190 * @returns #TRUE on success
2191 */
2192dbus_bool_t
2193_dbus_user_info_fill (DBusUserInfo     *info,
2194                      const DBusString *username,
2195                      DBusError        *error)
2196{
2197  return fill_user_info (info, DBUS_UID_UNSET,
2198                         username, error);
2199}
2200
2201/**
2202 * Gets user info for the given user ID.
2203 *
2204 * @param info user info object to initialize
2205 * @param uid the user ID
2206 * @param error error return
2207 * @returns #TRUE on success
2208 */
2209dbus_bool_t
2210_dbus_user_info_fill_uid (DBusUserInfo *info,
2211                          dbus_uid_t    uid,
2212                          DBusError    *error)
2213{
2214  return fill_user_info (info, uid,
2215                         NULL, error);
2216}
2217
2218/**
2219 * Adds the credentials of the current process to the
2220 * passed-in credentials object.
2221 *
2222 * @param credentials credentials to add to
2223 * @returns #FALSE if no memory; does not properly roll back on failure, so only some credentials may have been added
2224 */
2225dbus_bool_t
2226_dbus_credentials_add_from_current_process (DBusCredentials *credentials)
2227{
2228  /* The POSIX spec certainly doesn't promise this, but
2229   * we need these assertions to fail as soon as we're wrong about
2230   * it so we can do the porting fixups
2231   */
2232  _dbus_assert (sizeof (pid_t) <= sizeof (dbus_pid_t));
2233  _dbus_assert (sizeof (uid_t) <= sizeof (dbus_uid_t));
2234  _dbus_assert (sizeof (gid_t) <= sizeof (dbus_gid_t));
2235
2236  if (!_dbus_credentials_add_unix_pid(credentials, _dbus_getpid()))
2237    return FALSE;
2238  if (!_dbus_credentials_add_unix_uid(credentials, _dbus_geteuid()))
2239    return FALSE;
2240
2241  return TRUE;
2242}
2243
2244/**
2245 * Append to the string the identity we would like to have when we
2246 * authenticate, on UNIX this is the current process UID and on
2247 * Windows something else, probably a Windows SID string.  No escaping
2248 * is required, that is done in dbus-auth.c. The username here
2249 * need not be anything human-readable, it can be the machine-readable
2250 * form i.e. a user id.
2251 *
2252 * @param str the string to append to
2253 * @returns #FALSE on no memory
2254 */
2255dbus_bool_t
2256_dbus_append_user_from_current_process (DBusString *str)
2257{
2258  return _dbus_string_append_uint (str,
2259                                   _dbus_geteuid ());
2260}
2261
2262/**
2263 * Gets our process ID
2264 * @returns process ID
2265 */
2266dbus_pid_t
2267_dbus_getpid (void)
2268{
2269  return getpid ();
2270}
2271
2272/** Gets our UID
2273 * @returns process UID
2274 */
2275dbus_uid_t
2276_dbus_getuid (void)
2277{
2278  return getuid ();
2279}
2280
2281/** Gets our effective UID
2282 * @returns process effective UID
2283 */
2284dbus_uid_t
2285_dbus_geteuid (void)
2286{
2287  return geteuid ();
2288}
2289
2290/**
2291 * The only reason this is separate from _dbus_getpid() is to allow it
2292 * on Windows for logging but not for other purposes.
2293 *
2294 * @returns process ID to put in log messages
2295 */
2296unsigned long
2297_dbus_pid_for_log (void)
2298{
2299  return getpid ();
2300}
2301
2302/**
2303 * Gets a UID from a UID string.
2304 *
2305 * @param uid_str the UID in string form
2306 * @param uid UID to fill in
2307 * @returns #TRUE if successfully filled in UID
2308 */
2309dbus_bool_t
2310_dbus_parse_uid (const DBusString      *uid_str,
2311                 dbus_uid_t            *uid)
2312{
2313  int end;
2314  long val;
2315
2316  if (_dbus_string_get_length (uid_str) == 0)
2317    {
2318      _dbus_verbose ("UID string was zero length\n");
2319      return FALSE;
2320    }
2321
2322  val = -1;
2323  end = 0;
2324  if (!_dbus_string_parse_int (uid_str, 0, &val,
2325                               &end))
2326    {
2327      _dbus_verbose ("could not parse string as a UID\n");
2328      return FALSE;
2329    }
2330
2331  if (end != _dbus_string_get_length (uid_str))
2332    {
2333      _dbus_verbose ("string contained trailing stuff after UID\n");
2334      return FALSE;
2335    }
2336
2337  *uid = val;
2338
2339  return TRUE;
2340}
2341
2342#if !DBUS_USE_SYNC
2343_DBUS_DEFINE_GLOBAL_LOCK (atomic);
2344#endif
2345
2346/**
2347 * Atomically increments an integer
2348 *
2349 * @param atomic pointer to the integer to increment
2350 * @returns the value before incrementing
2351 */
2352dbus_int32_t
2353_dbus_atomic_inc (DBusAtomic *atomic)
2354{
2355#if DBUS_USE_SYNC
2356  return __sync_add_and_fetch(&atomic->value, 1)-1;
2357#elif defined(ANDROID_ATOMIC)
2358  return android_atomic_inc (&(atomic->value));
2359#else
2360  dbus_int32_t res;
2361  _DBUS_LOCK (atomic);
2362  res = atomic->value;
2363  atomic->value += 1;
2364  _DBUS_UNLOCK (atomic);
2365  return res;
2366#endif
2367}
2368
2369/**
2370 * Atomically decrement an integer
2371 *
2372 * @param atomic pointer to the integer to decrement
2373 * @returns the value before decrementing
2374 */
2375dbus_int32_t
2376_dbus_atomic_dec (DBusAtomic *atomic)
2377{
2378#if DBUS_USE_SYNC
2379  return __sync_sub_and_fetch(&atomic->value, 1)+1;
2380#elif defined(ANDROID_ATOMIC)
2381  return android_atomic_dec (&(atomic->value));
2382#else
2383  dbus_int32_t res;
2384
2385  _DBUS_LOCK (atomic);
2386  res = atomic->value;
2387  atomic->value -= 1;
2388  _DBUS_UNLOCK (atomic);
2389  return res;
2390#endif
2391}
2392
2393#ifdef DBUS_BUILD_TESTS
2394/** Gets our GID
2395 * @returns process GID
2396 */
2397dbus_gid_t
2398_dbus_getgid (void)
2399{
2400  return getgid ();
2401}
2402#endif
2403
2404/**
2405 * Wrapper for poll().
2406 *
2407 * @param fds the file descriptors to poll
2408 * @param n_fds number of descriptors in the array
2409 * @param timeout_milliseconds timeout or -1 for infinite
2410 * @returns numbers of fds with revents, or <0 on error
2411 */
2412int
2413_dbus_poll (DBusPollFD *fds,
2414            int         n_fds,
2415            int         timeout_milliseconds)
2416{
2417#if defined(HAVE_POLL) && !defined(BROKEN_POLL)
2418  /* This big thing is a constant expression and should get optimized
2419   * out of existence. So it's more robust than a configure check at
2420   * no cost.
2421   */
2422  if (_DBUS_POLLIN == POLLIN &&
2423      _DBUS_POLLPRI == POLLPRI &&
2424      _DBUS_POLLOUT == POLLOUT &&
2425      _DBUS_POLLERR == POLLERR &&
2426      _DBUS_POLLHUP == POLLHUP &&
2427      _DBUS_POLLNVAL == POLLNVAL &&
2428      sizeof (DBusPollFD) == sizeof (struct pollfd) &&
2429      _DBUS_STRUCT_OFFSET (DBusPollFD, fd) ==
2430      _DBUS_STRUCT_OFFSET (struct pollfd, fd) &&
2431      _DBUS_STRUCT_OFFSET (DBusPollFD, events) ==
2432      _DBUS_STRUCT_OFFSET (struct pollfd, events) &&
2433      _DBUS_STRUCT_OFFSET (DBusPollFD, revents) ==
2434      _DBUS_STRUCT_OFFSET (struct pollfd, revents))
2435    {
2436      return poll ((struct pollfd*) fds,
2437                   n_fds,
2438                   timeout_milliseconds);
2439    }
2440  else
2441    {
2442      /* We have to convert the DBusPollFD to an array of
2443       * struct pollfd, poll, and convert back.
2444       */
2445      _dbus_warn ("didn't implement poll() properly for this system yet\n");
2446      return -1;
2447    }
2448#else /* ! HAVE_POLL */
2449
2450  fd_set read_set, write_set, err_set;
2451  int max_fd = 0;
2452  int i;
2453  struct timeval tv;
2454  int ready;
2455
2456  FD_ZERO (&read_set);
2457  FD_ZERO (&write_set);
2458  FD_ZERO (&err_set);
2459
2460  for (i = 0; i < n_fds; i++)
2461    {
2462      DBusPollFD *fdp = &fds[i];
2463
2464      if (fdp->events & _DBUS_POLLIN)
2465	FD_SET (fdp->fd, &read_set);
2466
2467      if (fdp->events & _DBUS_POLLOUT)
2468	FD_SET (fdp->fd, &write_set);
2469
2470      FD_SET (fdp->fd, &err_set);
2471
2472      max_fd = MAX (max_fd, fdp->fd);
2473    }
2474
2475  tv.tv_sec = timeout_milliseconds / 1000;
2476  tv.tv_usec = (timeout_milliseconds % 1000) * 1000;
2477
2478  ready = select (max_fd + 1, &read_set, &write_set, &err_set,
2479                  timeout_milliseconds < 0 ? NULL : &tv);
2480
2481  if (ready > 0)
2482    {
2483      for (i = 0; i < n_fds; i++)
2484	{
2485	  DBusPollFD *fdp = &fds[i];
2486
2487	  fdp->revents = 0;
2488
2489	  if (FD_ISSET (fdp->fd, &read_set))
2490	    fdp->revents |= _DBUS_POLLIN;
2491
2492	  if (FD_ISSET (fdp->fd, &write_set))
2493	    fdp->revents |= _DBUS_POLLOUT;
2494
2495	  if (FD_ISSET (fdp->fd, &err_set))
2496	    fdp->revents |= _DBUS_POLLERR;
2497	}
2498    }
2499
2500  return ready;
2501#endif
2502}
2503
2504/**
2505 * Get current time, as in gettimeofday(). Use the monotonic clock if
2506 * available, to avoid problems when the system time changes.
2507 *
2508 * @param tv_sec return location for number of seconds
2509 * @param tv_usec return location for number of microseconds (thousandths)
2510 */
2511void
2512_dbus_get_current_time (long *tv_sec,
2513                        long *tv_usec)
2514{
2515  struct timeval t;
2516
2517#ifdef HAVE_MONOTONIC_CLOCK
2518  struct timespec ts;
2519  clock_gettime (CLOCK_MONOTONIC, &ts);
2520
2521  if (tv_sec)
2522    *tv_sec = ts.tv_sec;
2523  if (tv_usec)
2524    *tv_usec = ts.tv_nsec / 1000;
2525#else
2526  gettimeofday (&t, NULL);
2527
2528  if (tv_sec)
2529    *tv_sec = t.tv_sec;
2530  if (tv_usec)
2531    *tv_usec = t.tv_usec;
2532#endif
2533}
2534
2535/**
2536 * Creates a directory; succeeds if the directory
2537 * is created or already existed.
2538 *
2539 * @param filename directory filename
2540 * @param error initialized error object
2541 * @returns #TRUE on success
2542 */
2543dbus_bool_t
2544_dbus_create_directory (const DBusString *filename,
2545                        DBusError        *error)
2546{
2547  const char *filename_c;
2548
2549  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2550
2551  filename_c = _dbus_string_get_const_data (filename);
2552
2553  if (mkdir (filename_c, 0700) < 0)
2554    {
2555      if (errno == EEXIST)
2556        return TRUE;
2557
2558      dbus_set_error (error, DBUS_ERROR_FAILED,
2559                      "Failed to create directory %s: %s\n",
2560                      filename_c, _dbus_strerror (errno));
2561      return FALSE;
2562    }
2563  else
2564    return TRUE;
2565}
2566
2567/**
2568 * Appends the given filename to the given directory.
2569 *
2570 * @todo it might be cute to collapse multiple '/' such as "foo//"
2571 * concat "//bar"
2572 *
2573 * @param dir the directory name
2574 * @param next_component the filename
2575 * @returns #TRUE on success
2576 */
2577dbus_bool_t
2578_dbus_concat_dir_and_file (DBusString       *dir,
2579                           const DBusString *next_component)
2580{
2581  dbus_bool_t dir_ends_in_slash;
2582  dbus_bool_t file_starts_with_slash;
2583
2584  if (_dbus_string_get_length (dir) == 0 ||
2585      _dbus_string_get_length (next_component) == 0)
2586    return TRUE;
2587
2588  dir_ends_in_slash = '/' == _dbus_string_get_byte (dir,
2589                                                    _dbus_string_get_length (dir) - 1);
2590
2591  file_starts_with_slash = '/' == _dbus_string_get_byte (next_component, 0);
2592
2593  if (dir_ends_in_slash && file_starts_with_slash)
2594    {
2595      _dbus_string_shorten (dir, 1);
2596    }
2597  else if (!(dir_ends_in_slash || file_starts_with_slash))
2598    {
2599      if (!_dbus_string_append_byte (dir, '/'))
2600        return FALSE;
2601    }
2602
2603  return _dbus_string_copy (next_component, 0, dir,
2604                            _dbus_string_get_length (dir));
2605}
2606
2607/** nanoseconds in a second */
2608#define NANOSECONDS_PER_SECOND       1000000000
2609/** microseconds in a second */
2610#define MICROSECONDS_PER_SECOND      1000000
2611/** milliseconds in a second */
2612#define MILLISECONDS_PER_SECOND      1000
2613/** nanoseconds in a millisecond */
2614#define NANOSECONDS_PER_MILLISECOND  1000000
2615/** microseconds in a millisecond */
2616#define MICROSECONDS_PER_MILLISECOND 1000
2617
2618/**
2619 * Sleeps the given number of milliseconds.
2620 * @param milliseconds number of milliseconds
2621 */
2622void
2623_dbus_sleep_milliseconds (int milliseconds)
2624{
2625#ifdef HAVE_NANOSLEEP
2626  struct timespec req;
2627  struct timespec rem;
2628
2629  req.tv_sec = milliseconds / MILLISECONDS_PER_SECOND;
2630  req.tv_nsec = (milliseconds % MILLISECONDS_PER_SECOND) * NANOSECONDS_PER_MILLISECOND;
2631  rem.tv_sec = 0;
2632  rem.tv_nsec = 0;
2633
2634  while (nanosleep (&req, &rem) < 0 && errno == EINTR)
2635    req = rem;
2636#elif defined (HAVE_USLEEP)
2637  usleep (milliseconds * MICROSECONDS_PER_MILLISECOND);
2638#else /* ! HAVE_USLEEP */
2639  sleep (MAX (milliseconds / 1000, 1));
2640#endif
2641}
2642
2643static dbus_bool_t
2644_dbus_generate_pseudorandom_bytes (DBusString *str,
2645                                   int         n_bytes)
2646{
2647  int old_len;
2648  char *p;
2649
2650  old_len = _dbus_string_get_length (str);
2651
2652  if (!_dbus_string_lengthen (str, n_bytes))
2653    return FALSE;
2654
2655  p = _dbus_string_get_data_len (str, old_len, n_bytes);
2656
2657  _dbus_generate_pseudorandom_bytes_buffer (p, n_bytes);
2658
2659  return TRUE;
2660}
2661
2662/**
2663 * Generates the given number of random bytes,
2664 * using the best mechanism we can come up with.
2665 *
2666 * @param str the string
2667 * @param n_bytes the number of random bytes to append to string
2668 * @returns #TRUE on success, #FALSE if no memory
2669 */
2670dbus_bool_t
2671_dbus_generate_random_bytes (DBusString *str,
2672                             int         n_bytes)
2673{
2674  int old_len;
2675  int fd;
2676
2677  /* FALSE return means "no memory", if it could
2678   * mean something else then we'd need to return
2679   * a DBusError. So we always fall back to pseudorandom
2680   * if the I/O fails.
2681   */
2682
2683  old_len = _dbus_string_get_length (str);
2684  fd = -1;
2685
2686  /* note, urandom on linux will fall back to pseudorandom */
2687  fd = open ("/dev/urandom", O_RDONLY);
2688  if (fd < 0)
2689    return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2690
2691  _dbus_verbose ("/dev/urandom fd %d opened\n", fd);
2692
2693  if (_dbus_read (fd, str, n_bytes) != n_bytes)
2694    {
2695      _dbus_close (fd, NULL);
2696      _dbus_string_set_length (str, old_len);
2697      return _dbus_generate_pseudorandom_bytes (str, n_bytes);
2698    }
2699
2700  _dbus_verbose ("Read %d bytes from /dev/urandom\n",
2701                 n_bytes);
2702
2703  _dbus_close (fd, NULL);
2704
2705  return TRUE;
2706}
2707
2708/**
2709 * Exit the process, returning the given value.
2710 *
2711 * @param code the exit code
2712 */
2713void
2714_dbus_exit (int code)
2715{
2716  _exit (code);
2717}
2718
2719/**
2720 * A wrapper around strerror() because some platforms
2721 * may be lame and not have strerror(). Also, never
2722 * returns NULL.
2723 *
2724 * @param error_number errno.
2725 * @returns error description.
2726 */
2727const char*
2728_dbus_strerror (int error_number)
2729{
2730  const char *msg;
2731
2732  msg = strerror (error_number);
2733  if (msg == NULL)
2734    msg = "unknown";
2735
2736  return msg;
2737}
2738
2739/**
2740 * signal (SIGPIPE, SIG_IGN);
2741 */
2742void
2743_dbus_disable_sigpipe (void)
2744{
2745  signal (SIGPIPE, SIG_IGN);
2746}
2747
2748/**
2749 * Sets the file descriptor to be close
2750 * on exec. Should be called for all file
2751 * descriptors in D-Bus code.
2752 *
2753 * @param fd the file descriptor
2754 */
2755void
2756_dbus_fd_set_close_on_exec (intptr_t fd)
2757{
2758  int val;
2759
2760  val = fcntl (fd, F_GETFD, 0);
2761
2762  if (val < 0)
2763    return;
2764
2765  val |= FD_CLOEXEC;
2766
2767  fcntl (fd, F_SETFD, val);
2768}
2769
2770/**
2771 * Closes a file descriptor.
2772 *
2773 * @param fd the file descriptor
2774 * @param error error object
2775 * @returns #FALSE if error set
2776 */
2777dbus_bool_t
2778_dbus_close (int        fd,
2779             DBusError *error)
2780{
2781  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2782
2783 again:
2784  if (close (fd) < 0)
2785    {
2786      if (errno == EINTR)
2787        goto again;
2788
2789      dbus_set_error (error, _dbus_error_from_errno (errno),
2790                      "Could not close fd %d", fd);
2791      return FALSE;
2792    }
2793
2794  return TRUE;
2795}
2796
2797/**
2798 * Duplicates a file descriptor. Makes sure the fd returned is >= 3
2799 * (i.e. avoids stdin/stdout/stderr). Sets O_CLOEXEC.
2800 *
2801 * @param fd the file descriptor to duplicate
2802 * @returns duplicated file descriptor
2803 * */
2804int
2805_dbus_dup(int        fd,
2806          DBusError *error)
2807{
2808  int new_fd;
2809
2810#ifdef F_DUPFD_CLOEXEC
2811  dbus_bool_t cloexec_done;
2812
2813  new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2814  cloexec_done = new_fd >= 0;
2815
2816  if (new_fd < 0 && errno == EINVAL)
2817#endif
2818    {
2819      new_fd = fcntl(fd, F_DUPFD, 3);
2820    }
2821
2822  if (new_fd < 0) {
2823
2824    dbus_set_error (error, _dbus_error_from_errno (errno),
2825                    "Could not duplicate fd %d", fd);
2826    return -1;
2827  }
2828
2829#ifdef F_DUPFD_CLOEXEC
2830  if (!cloexec_done)
2831#endif
2832    {
2833      _dbus_fd_set_close_on_exec(new_fd);
2834    }
2835
2836  return new_fd;
2837}
2838
2839/**
2840 * Sets a file descriptor to be nonblocking.
2841 *
2842 * @param fd the file descriptor.
2843 * @param error address of error location.
2844 * @returns #TRUE on success.
2845 */
2846dbus_bool_t
2847_dbus_set_fd_nonblocking (int             fd,
2848                          DBusError      *error)
2849{
2850  int val;
2851
2852  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2853
2854  val = fcntl (fd, F_GETFL, 0);
2855  if (val < 0)
2856    {
2857      dbus_set_error (error, _dbus_error_from_errno (errno),
2858                      "Failed to get flags from file descriptor %d: %s",
2859                      fd, _dbus_strerror (errno));
2860      _dbus_verbose ("Failed to get flags for fd %d: %s\n", fd,
2861                     _dbus_strerror (errno));
2862      return FALSE;
2863    }
2864
2865  if (fcntl (fd, F_SETFL, val | O_NONBLOCK) < 0)
2866    {
2867      dbus_set_error (error, _dbus_error_from_errno (errno),
2868                      "Failed to set nonblocking flag of file descriptor %d: %s",
2869                      fd, _dbus_strerror (errno));
2870      _dbus_verbose ("Failed to set fd %d nonblocking: %s\n",
2871                     fd, _dbus_strerror (errno));
2872
2873      return FALSE;
2874    }
2875
2876  return TRUE;
2877}
2878
2879/**
2880 * On GNU libc systems, print a crude backtrace to stderr.  On other
2881 * systems, print "no backtrace support" and block for possible gdb
2882 * attachment if an appropriate environment variable is set.
2883 */
2884void
2885_dbus_print_backtrace (void)
2886{
2887#if defined (HAVE_BACKTRACE) && defined (DBUS_BUILT_R_DYNAMIC)
2888  void *bt[500];
2889  int bt_size;
2890  int i;
2891  char **syms;
2892
2893  bt_size = backtrace (bt, 500);
2894
2895  syms = backtrace_symbols (bt, bt_size);
2896
2897  i = 0;
2898  while (i < bt_size)
2899    {
2900      /* don't use dbus_warn since it can _dbus_abort() */
2901      fprintf (stderr, "  %s\n", syms[i]);
2902      ++i;
2903    }
2904  fflush (stderr);
2905
2906  free (syms);
2907#elif defined (HAVE_BACKTRACE) && ! defined (DBUS_BUILT_R_DYNAMIC)
2908  fprintf (stderr, "  D-Bus not built with -rdynamic so unable to print a backtrace\n");
2909#else
2910  fprintf (stderr, "  D-Bus not compiled with backtrace support so unable to print a backtrace\n");
2911#endif
2912}
2913
2914/**
2915 * Creates a full-duplex pipe (as in socketpair()).
2916 * Sets both ends of the pipe nonblocking.
2917 *
2918 * Marks both file descriptors as close-on-exec
2919 *
2920 * @todo libdbus only uses this for the debug-pipe server, so in
2921 * principle it could be in dbus-sysdeps-util.c, except that
2922 * dbus-sysdeps-util.c isn't in libdbus when tests are enabled and the
2923 * debug-pipe server is used.
2924 *
2925 * @param fd1 return location for one end
2926 * @param fd2 return location for the other end
2927 * @param blocking #TRUE if pipe should be blocking
2928 * @param error error return
2929 * @returns #FALSE on failure (if error is set)
2930 */
2931dbus_bool_t
2932_dbus_full_duplex_pipe (int        *fd1,
2933                        int        *fd2,
2934                        dbus_bool_t blocking,
2935                        DBusError  *error)
2936{
2937#ifdef HAVE_SOCKETPAIR
2938  int fds[2];
2939  int retval;
2940
2941#ifdef SOCK_CLOEXEC
2942  dbus_bool_t cloexec_done;
2943
2944  retval = socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, fds);
2945  cloexec_done = retval >= 0;
2946
2947  if (retval < 0 && errno == EINVAL)
2948#endif
2949    {
2950      retval = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
2951    }
2952
2953  if (retval < 0)
2954    {
2955      dbus_set_error (error, _dbus_error_from_errno (errno),
2956                      "Could not create full-duplex pipe");
2957      return FALSE;
2958    }
2959
2960  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
2961
2962#ifdef SOCK_CLOEXEC
2963  if (!cloexec_done)
2964#endif
2965    {
2966      _dbus_fd_set_close_on_exec (fds[0]);
2967      _dbus_fd_set_close_on_exec (fds[1]);
2968    }
2969
2970  if (!blocking &&
2971      (!_dbus_set_fd_nonblocking (fds[0], NULL) ||
2972       !_dbus_set_fd_nonblocking (fds[1], NULL)))
2973    {
2974      dbus_set_error (error, _dbus_error_from_errno (errno),
2975                      "Could not set full-duplex pipe nonblocking");
2976
2977      _dbus_close (fds[0], NULL);
2978      _dbus_close (fds[1], NULL);
2979
2980      return FALSE;
2981    }
2982
2983  *fd1 = fds[0];
2984  *fd2 = fds[1];
2985
2986  _dbus_verbose ("full-duplex pipe %d <-> %d\n",
2987                 *fd1, *fd2);
2988
2989  return TRUE;
2990#else
2991  _dbus_warn ("_dbus_full_duplex_pipe() not implemented on this OS\n");
2992  dbus_set_error (error, DBUS_ERROR_FAILED,
2993                  "_dbus_full_duplex_pipe() not implemented on this OS");
2994  return FALSE;
2995#endif
2996}
2997
2998/**
2999 * Measure the length of the given format string and arguments,
3000 * not including the terminating nul.
3001 *
3002 * @param format a printf-style format string
3003 * @param args arguments for the format string
3004 * @returns length of the given format string and args
3005 */
3006int
3007_dbus_printf_string_upper_bound (const char *format,
3008                                 va_list     args)
3009{
3010  char c;
3011  return vsnprintf (&c, 1, format, args);
3012}
3013
3014/**
3015 * Gets the temporary files directory by inspecting the environment variables
3016 * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
3017 *
3018 * @returns location of temp directory
3019 */
3020const char*
3021_dbus_get_tmpdir(void)
3022{
3023  static const char* tmpdir = NULL;
3024
3025  if (tmpdir == NULL)
3026    {
3027      /* TMPDIR is what glibc uses, then
3028       * glibc falls back to the P_tmpdir macro which
3029       * just expands to "/tmp"
3030       */
3031      if (tmpdir == NULL)
3032        tmpdir = getenv("TMPDIR");
3033
3034      /* These two env variables are probably
3035       * broken, but maybe some OS uses them?
3036       */
3037      if (tmpdir == NULL)
3038        tmpdir = getenv("TMP");
3039      if (tmpdir == NULL)
3040        tmpdir = getenv("TEMP");
3041
3042      /* And this is the sane fallback. */
3043      if (tmpdir == NULL)
3044        tmpdir = "/tmp";
3045    }
3046
3047  _dbus_assert(tmpdir != NULL);
3048
3049  return tmpdir;
3050}
3051
3052/**
3053 * Execute a subprocess, returning up to 1024 bytes of output
3054 * into @p result.
3055 *
3056 * If successful, returns #TRUE and appends the output to @p
3057 * result. If a failure happens, returns #FALSE and
3058 * sets an error in @p error.
3059 *
3060 * @note It's not an error if the subprocess terminates normally
3061 * without writing any data to stdout. Verify the @p result length
3062 * before and after this function call to cover this case.
3063 *
3064 * @param progname initial path to exec (may or may not be absolute)
3065 * @param path_fallback if %TRUE, search PATH for executable
3066 * @param argv NULL-terminated list of arguments
3067 * @param result a DBusString where the output can be append
3068 * @param error a DBusError to store the error in case of failure
3069 * @returns #TRUE on success, #FALSE if an error happened
3070 */
3071static dbus_bool_t
3072_read_subprocess_line_argv (const char *progpath,
3073                            dbus_bool_t path_fallback,
3074                            char       * const *argv,
3075                            DBusString *result,
3076                            DBusError  *error)
3077{
3078  int result_pipe[2] = { -1, -1 };
3079  int errors_pipe[2] = { -1, -1 };
3080  pid_t pid;
3081  int ret;
3082  int status;
3083  int orig_len;
3084  int i;
3085
3086  dbus_bool_t retval;
3087  sigset_t new_set, old_set;
3088
3089  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3090  retval = FALSE;
3091
3092  /* We need to block any existing handlers for SIGCHLD temporarily; they
3093   * will cause waitpid() below to fail.
3094   * https://bugs.freedesktop.org/show_bug.cgi?id=21347
3095   */
3096  sigemptyset (&new_set);
3097  sigaddset (&new_set, SIGCHLD);
3098  sigprocmask (SIG_BLOCK, &new_set, &old_set);
3099
3100  orig_len = _dbus_string_get_length (result);
3101
3102#define READ_END        0
3103#define WRITE_END       1
3104  if (pipe (result_pipe) < 0)
3105    {
3106      dbus_set_error (error, _dbus_error_from_errno (errno),
3107                      "Failed to create a pipe to call %s: %s",
3108                      progpath, _dbus_strerror (errno));
3109      _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3110                     progpath, _dbus_strerror (errno));
3111      goto out;
3112    }
3113  if (pipe (errors_pipe) < 0)
3114    {
3115      dbus_set_error (error, _dbus_error_from_errno (errno),
3116                      "Failed to create a pipe to call %s: %s",
3117                      progpath, _dbus_strerror (errno));
3118      _dbus_verbose ("Failed to create a pipe to call %s: %s\n",
3119                     progpath, _dbus_strerror (errno));
3120      goto out;
3121    }
3122
3123  pid = fork ();
3124  if (pid < 0)
3125    {
3126      dbus_set_error (error, _dbus_error_from_errno (errno),
3127                      "Failed to fork() to call %s: %s",
3128                      progpath, _dbus_strerror (errno));
3129      _dbus_verbose ("Failed to fork() to call %s: %s\n",
3130                     progpath, _dbus_strerror (errno));
3131      goto out;
3132    }
3133
3134  if (pid == 0)
3135    {
3136      /* child process */
3137      int maxfds;
3138      int fd;
3139
3140      fd = open ("/dev/null", O_RDWR);
3141      if (fd == -1)
3142        /* huh?! can't open /dev/null? */
3143        _exit (1);
3144
3145      _dbus_verbose ("/dev/null fd %d opened\n", fd);
3146
3147      /* set-up stdXXX */
3148      close (result_pipe[READ_END]);
3149      close (errors_pipe[READ_END]);
3150      close (0);                /* close stdin */
3151      close (1);                /* close stdout */
3152      close (2);                /* close stderr */
3153
3154      if (dup2 (fd, 0) == -1)
3155        _exit (1);
3156      if (dup2 (result_pipe[WRITE_END], 1) == -1)
3157        _exit (1);
3158      if (dup2 (errors_pipe[WRITE_END], 2) == -1)
3159        _exit (1);
3160
3161      maxfds = sysconf (_SC_OPEN_MAX);
3162      /* Pick something reasonable if for some reason sysconf
3163       * says unlimited.
3164       */
3165      if (maxfds < 0)
3166        maxfds = 1024;
3167      /* close all inherited fds */
3168      for (i = 3; i < maxfds; i++)
3169        close (i);
3170
3171      sigprocmask (SIG_SETMASK, &old_set, NULL);
3172
3173      /* If it looks fully-qualified, try execv first */
3174      if (progpath[0] == '/')
3175        {
3176          execv (progpath, argv);
3177          /* Ok, that failed.  Now if path_fallback is given, let's
3178           * try unqualified.  This is mostly a hack to work
3179           * around systems which ship dbus-launch in /usr/bin
3180           * but everything else in /bin (because dbus-launch
3181           * depends on X11).
3182           */
3183          if (path_fallback)
3184            /* We must have a slash, because we checked above */
3185            execvp (strrchr (progpath, '/')+1, argv);
3186        }
3187      else
3188        execvp (progpath, argv);
3189
3190      /* still nothing, we failed */
3191      _exit (1);
3192    }
3193
3194  /* parent process */
3195  close (result_pipe[WRITE_END]);
3196  close (errors_pipe[WRITE_END]);
3197  result_pipe[WRITE_END] = -1;
3198  errors_pipe[WRITE_END] = -1;
3199
3200  ret = 0;
3201  do
3202    {
3203      ret = _dbus_read (result_pipe[READ_END], result, 1024);
3204    }
3205  while (ret > 0);
3206
3207  /* reap the child process to avoid it lingering as zombie */
3208  do
3209    {
3210      ret = waitpid (pid, &status, 0);
3211    }
3212  while (ret == -1 && errno == EINTR);
3213
3214  /* We succeeded if the process exited with status 0 and
3215     anything was read */
3216  if (!WIFEXITED (status) || WEXITSTATUS (status) != 0 )
3217    {
3218      /* The process ended with error */
3219      DBusString error_message;
3220      _dbus_string_init (&error_message);
3221      ret = 0;
3222      do
3223        {
3224          ret = _dbus_read (errors_pipe[READ_END], &error_message, 1024);
3225        }
3226      while (ret > 0);
3227
3228      _dbus_string_set_length (result, orig_len);
3229      if (_dbus_string_get_length (&error_message) > 0)
3230        dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3231                        "%s terminated abnormally with the following error: %s",
3232                        progpath, _dbus_string_get_data (&error_message));
3233      else
3234        dbus_set_error (error, DBUS_ERROR_SPAWN_EXEC_FAILED,
3235                        "%s terminated abnormally without any error message",
3236                        progpath);
3237      goto out;
3238    }
3239
3240  retval = TRUE;
3241
3242 out:
3243  sigprocmask (SIG_SETMASK, &old_set, NULL);
3244
3245  if (retval)
3246    _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3247  else
3248    _DBUS_ASSERT_ERROR_IS_SET (error);
3249
3250  if (result_pipe[0] != -1)
3251    close (result_pipe[0]);
3252  if (result_pipe[1] != -1)
3253    close (result_pipe[1]);
3254  if (errors_pipe[0] != -1)
3255    close (errors_pipe[0]);
3256  if (errors_pipe[1] != -1)
3257    close (errors_pipe[1]);
3258
3259  return retval;
3260}
3261
3262/**
3263 * Returns the address of a new session bus.
3264 *
3265 * If successful, returns #TRUE and appends the address to @p
3266 * address. If a failure happens, returns #FALSE and
3267 * sets an error in @p error.
3268 *
3269 * @param address a DBusString where the address can be stored
3270 * @param error a DBusError to store the error in case of failure
3271 * @returns #TRUE on success, #FALSE if an error happened
3272 */
3273dbus_bool_t
3274_dbus_get_autolaunch_address (DBusString *address,
3275                              DBusError  *error)
3276{
3277  static char *argv[6];
3278  int i;
3279  DBusString uuid;
3280  dbus_bool_t retval;
3281
3282  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3283  retval = FALSE;
3284
3285  if (!_dbus_string_init (&uuid))
3286    {
3287      _DBUS_SET_OOM (error);
3288      return FALSE;
3289    }
3290
3291  if (!_dbus_get_local_machine_uuid_encoded (&uuid))
3292    {
3293      _DBUS_SET_OOM (error);
3294      goto out;
3295    }
3296
3297  i = 0;
3298  argv[i] = "dbus-launch";
3299  ++i;
3300  argv[i] = "--autolaunch";
3301  ++i;
3302  argv[i] = _dbus_string_get_data (&uuid);
3303  ++i;
3304  argv[i] = "--binary-syntax";
3305  ++i;
3306  argv[i] = "--close-stderr";
3307  ++i;
3308  argv[i] = NULL;
3309  ++i;
3310
3311  _dbus_assert (i == _DBUS_N_ELEMENTS (argv));
3312
3313  retval = _read_subprocess_line_argv (DBUS_BINDIR "/dbus-launch",
3314                                       TRUE,
3315                                       argv, address, error);
3316
3317 out:
3318  _dbus_string_free (&uuid);
3319  return retval;
3320}
3321
3322/**
3323 * Reads the uuid of the machine we're running on from
3324 * the dbus configuration. Optionally try to create it
3325 * (only root can do this usually).
3326 *
3327 * On UNIX, reads a file that gets created by dbus-uuidgen
3328 * in a post-install script. On Windows, if there's a standard
3329 * machine uuid we could just use that, but I can't find one
3330 * with the right properties (the hardware profile guid can change
3331 * without rebooting I believe). If there's no standard one
3332 * we might want to use the registry instead of a file for
3333 * this, and I'm not sure how we'd ensure the uuid gets created.
3334 *
3335 * @param machine_id guid to init with the machine's uuid
3336 * @param create_if_not_found try to create the uuid if it doesn't exist
3337 * @param error the error return
3338 * @returns #FALSE if the error is set
3339 */
3340dbus_bool_t
3341_dbus_read_local_machine_uuid (DBusGUID   *machine_id,
3342                               dbus_bool_t create_if_not_found,
3343                               DBusError  *error)
3344{
3345  DBusString filename;
3346  _dbus_string_init_const (&filename, DBUS_MACHINE_UUID_FILE);
3347  return _dbus_read_uuid_file (&filename, machine_id, create_if_not_found, error);
3348}
3349
3350#define DBUS_UNIX_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
3351#define DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
3352
3353/**
3354 * Determines the address of the session bus by querying a
3355 * platform-specific method.
3356 *
3357 * The first parameter will be a boolean specifying whether
3358 * or not a dynamic session lookup is supported on this platform.
3359 *
3360 * If supported is TRUE and the return value is #TRUE, the
3361 * address will be  appended to @p address.
3362 * If a failure happens, returns #FALSE and sets an error in
3363 * @p error.
3364 *
3365 * If supported is FALSE, ignore the return value.
3366 *
3367 * @param supported returns whether this method is supported
3368 * @param address a DBusString where the address can be stored
3369 * @param error a DBusError to store the error in case of failure
3370 * @returns #TRUE on success, #FALSE if an error happened
3371 */
3372dbus_bool_t
3373_dbus_lookup_session_address (dbus_bool_t *supported,
3374                              DBusString  *address,
3375                              DBusError   *error)
3376{
3377  /* On non-Mac Unix platforms, if the session address isn't already
3378   * set in DBUS_SESSION_BUS_ADDRESS environment variable, we punt and
3379   * fall back to the autolaunch: global default; see
3380   * init_session_address in dbus/dbus-bus.c. */
3381  *supported = FALSE;
3382  return TRUE;
3383}
3384
3385/**
3386 * Returns the standard directories for a session bus to look for service
3387 * activation files
3388 *
3389 * On UNIX this should be the standard xdg freedesktop.org data directories:
3390 *
3391 * XDG_DATA_HOME=${XDG_DATA_HOME-$HOME/.local/share}
3392 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3393 *
3394 * and
3395 *
3396 * DBUS_DATADIR
3397 *
3398 * @param dirs the directory list we are returning
3399 * @returns #FALSE on OOM
3400 */
3401
3402dbus_bool_t
3403_dbus_get_standard_session_servicedirs (DBusList **dirs)
3404{
3405  const char *xdg_data_home;
3406  const char *xdg_data_dirs;
3407  DBusString servicedir_path;
3408
3409  if (!_dbus_string_init (&servicedir_path))
3410    return FALSE;
3411
3412  xdg_data_home = _dbus_getenv ("XDG_DATA_HOME");
3413  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3414
3415  if (xdg_data_dirs != NULL)
3416    {
3417      if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3418        goto oom;
3419
3420      if (!_dbus_string_append (&servicedir_path, ":"))
3421        goto oom;
3422    }
3423  else
3424    {
3425      if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3426        goto oom;
3427    }
3428
3429  /*
3430   * add configured datadir to defaults
3431   * this may be the same as an xdg dir
3432   * however the config parser should take
3433   * care of duplicates
3434   */
3435  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3436        goto oom;
3437
3438  if (xdg_data_home != NULL)
3439    {
3440      if (!_dbus_string_append (&servicedir_path, xdg_data_home))
3441        goto oom;
3442    }
3443  else
3444    {
3445      const DBusString *homedir;
3446      DBusString local_share;
3447
3448      if (!_dbus_homedir_from_current_process (&homedir))
3449        goto oom;
3450
3451      if (!_dbus_string_append (&servicedir_path, _dbus_string_get_const_data (homedir)))
3452        goto oom;
3453
3454      _dbus_string_init_const (&local_share, "/.local/share");
3455      if (!_dbus_concat_dir_and_file (&servicedir_path, &local_share))
3456        goto oom;
3457    }
3458
3459  if (!_dbus_split_paths_and_append (&servicedir_path,
3460                                     DBUS_UNIX_STANDARD_SESSION_SERVICEDIR,
3461                                     dirs))
3462    goto oom;
3463
3464  _dbus_string_free (&servicedir_path);
3465  return TRUE;
3466
3467 oom:
3468  _dbus_string_free (&servicedir_path);
3469  return FALSE;
3470}
3471
3472
3473/**
3474 * Returns the standard directories for a system bus to look for service
3475 * activation files
3476 *
3477 * On UNIX this should be the standard xdg freedesktop.org data directories:
3478 *
3479 * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
3480 *
3481 * and
3482 *
3483 * DBUS_DATADIR
3484 *
3485 * On Windows there is no system bus and this function can return nothing.
3486 *
3487 * @param dirs the directory list we are returning
3488 * @returns #FALSE on OOM
3489 */
3490
3491dbus_bool_t
3492_dbus_get_standard_system_servicedirs (DBusList **dirs)
3493{
3494  const char *xdg_data_dirs;
3495  DBusString servicedir_path;
3496
3497  if (!_dbus_string_init (&servicedir_path))
3498    return FALSE;
3499
3500  xdg_data_dirs = _dbus_getenv ("XDG_DATA_DIRS");
3501
3502  if (xdg_data_dirs != NULL)
3503    {
3504      if (!_dbus_string_append (&servicedir_path, xdg_data_dirs))
3505        goto oom;
3506
3507      if (!_dbus_string_append (&servicedir_path, ":"))
3508        goto oom;
3509    }
3510  else
3511    {
3512      if (!_dbus_string_append (&servicedir_path, "/usr/local/share:/usr/share:"))
3513        goto oom;
3514    }
3515
3516  /*
3517   * add configured datadir to defaults
3518   * this may be the same as an xdg dir
3519   * however the config parser should take
3520   * care of duplicates
3521   */
3522  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR":"))
3523        goto oom;
3524
3525  if (!_dbus_split_paths_and_append (&servicedir_path,
3526                                     DBUS_UNIX_STANDARD_SYSTEM_SERVICEDIR,
3527                                     dirs))
3528    goto oom;
3529
3530  _dbus_string_free (&servicedir_path);
3531  return TRUE;
3532
3533 oom:
3534  _dbus_string_free (&servicedir_path);
3535  return FALSE;
3536}
3537
3538/**
3539 * Append the absolute path of the system.conf file
3540 * (there is no system bus on Windows so this can just
3541 * return FALSE and print a warning or something)
3542 *
3543 * @param str the string to append to
3544 * @returns #FALSE if no memory
3545 */
3546dbus_bool_t
3547_dbus_append_system_config_file (DBusString *str)
3548{
3549  return _dbus_string_append (str, DBUS_SYSTEM_CONFIG_FILE);
3550}
3551
3552/**
3553 * Append the absolute path of the session.conf file.
3554 *
3555 * @param str the string to append to
3556 * @returns #FALSE if no memory
3557 */
3558dbus_bool_t
3559_dbus_append_session_config_file (DBusString *str)
3560{
3561  return _dbus_string_append (str, DBUS_SESSION_CONFIG_FILE);
3562}
3563
3564/**
3565 * Called when the bus daemon is signaled to reload its configuration; any
3566 * caches should be nuked. Of course any caches that need explicit reload
3567 * are probably broken, but c'est la vie.
3568 *
3569 *
3570 */
3571void
3572_dbus_flush_caches (void)
3573{
3574  _dbus_user_database_flush_system ();
3575}
3576
3577/**
3578 * Appends the directory in which a keyring for the given credentials
3579 * should be stored.  The credentials should have either a Windows or
3580 * UNIX user in them.  The directory should be an absolute path.
3581 *
3582 * On UNIX the directory is ~/.dbus-keyrings while on Windows it should probably
3583 * be something else, since the dotfile convention is not normal on Windows.
3584 *
3585 * @param directory string to append directory to
3586 * @param credentials credentials the directory should be for
3587 *
3588 * @returns #FALSE on no memory
3589 */
3590dbus_bool_t
3591_dbus_append_keyring_directory_for_credentials (DBusString      *directory,
3592                                                DBusCredentials *credentials)
3593{
3594  DBusString homedir;
3595  DBusString dotdir;
3596  dbus_uid_t uid;
3597
3598  _dbus_assert (credentials != NULL);
3599  _dbus_assert (!_dbus_credentials_are_anonymous (credentials));
3600
3601  if (!_dbus_string_init (&homedir))
3602    return FALSE;
3603
3604  uid = _dbus_credentials_get_unix_uid (credentials);
3605  _dbus_assert (uid != DBUS_UID_UNSET);
3606
3607  if (!_dbus_homedir_from_uid (uid, &homedir))
3608    goto failed;
3609
3610#ifdef DBUS_BUILD_TESTS
3611  {
3612    const char *override;
3613
3614    override = _dbus_getenv ("DBUS_TEST_HOMEDIR");
3615    if (override != NULL && *override != '\0')
3616      {
3617        _dbus_string_set_length (&homedir, 0);
3618        if (!_dbus_string_append (&homedir, override))
3619          goto failed;
3620
3621        _dbus_verbose ("Using fake homedir for testing: %s\n",
3622                       _dbus_string_get_const_data (&homedir));
3623      }
3624    else
3625      {
3626        static dbus_bool_t already_warned = FALSE;
3627        if (!already_warned)
3628          {
3629            _dbus_warn ("Using your real home directory for testing, set DBUS_TEST_HOMEDIR to avoid\n");
3630            already_warned = TRUE;
3631          }
3632      }
3633  }
3634#endif
3635
3636  _dbus_string_init_const (&dotdir, ".dbus-keyrings");
3637  if (!_dbus_concat_dir_and_file (&homedir,
3638                                  &dotdir))
3639    goto failed;
3640
3641  if (!_dbus_string_copy (&homedir, 0,
3642                          directory, _dbus_string_get_length (directory))) {
3643    goto failed;
3644  }
3645
3646  _dbus_string_free (&homedir);
3647  return TRUE;
3648
3649 failed:
3650  _dbus_string_free (&homedir);
3651  return FALSE;
3652}
3653
3654//PENDING(kdab) docs
3655void
3656_dbus_daemon_publish_session_bus_address (const char* addr)
3657{
3658
3659}
3660
3661//PENDING(kdab) docs
3662void
3663_dbus_daemon_unpublish_session_bus_address (void)
3664{
3665
3666}
3667
3668/**
3669 * See if errno is EAGAIN or EWOULDBLOCK (this has to be done differently
3670 * for Winsock so is abstracted)
3671 *
3672 * @returns #TRUE if errno == EAGAIN or errno == EWOULDBLOCK
3673 */
3674dbus_bool_t
3675_dbus_get_is_errno_eagain_or_ewouldblock (void)
3676{
3677  return errno == EAGAIN || errno == EWOULDBLOCK;
3678}
3679
3680/**
3681 * Removes a directory; Directory must be empty
3682 *
3683 * @param filename directory filename
3684 * @param error initialized error object
3685 * @returns #TRUE on success
3686 */
3687dbus_bool_t
3688_dbus_delete_directory (const DBusString *filename,
3689                        DBusError        *error)
3690{
3691  const char *filename_c;
3692
3693  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
3694
3695  filename_c = _dbus_string_get_const_data (filename);
3696
3697  if (rmdir (filename_c) != 0)
3698    {
3699      dbus_set_error (error, DBUS_ERROR_FAILED,
3700                      "Failed to remove directory %s: %s\n",
3701                      filename_c, _dbus_strerror (errno));
3702      return FALSE;
3703    }
3704
3705  return TRUE;
3706}
3707
3708/**
3709 *  Checks whether file descriptors may be passed via the socket
3710 *
3711 *  @param fd the socket
3712 *  @return TRUE when fd passing over this socket is supported
3713 *
3714 */
3715dbus_bool_t
3716_dbus_socket_can_pass_unix_fd(int fd) {
3717
3718#ifdef SCM_RIGHTS
3719  union {
3720    struct sockaddr sa;
3721    struct sockaddr_storage storage;
3722    struct sockaddr_un un;
3723  } sa_buf;
3724
3725  socklen_t sa_len = sizeof(sa_buf);
3726
3727  _DBUS_ZERO(sa_buf);
3728
3729  if (getsockname(fd, &sa_buf.sa, &sa_len) < 0)
3730    return FALSE;
3731
3732  return sa_buf.sa.sa_family == AF_UNIX;
3733
3734#else
3735  return FALSE;
3736
3737#endif
3738}
3739
3740
3741/*
3742 * replaces the term DBUS_PREFIX in configure_time_path by the
3743 * current dbus installation directory. On unix this function is a noop
3744 *
3745 * @param configure_time_path
3746 * @return real path
3747 */
3748const char *
3749_dbus_replace_install_prefix (const char *configure_time_path)
3750{
3751  return configure_time_path;
3752}
3753
3754/* tests in dbus-sysdeps-util.c */
3755