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