Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
      2 /* dbus-transport.c DBusTransport object (internal to D-Bus implementation)
      3  *
      4  * Copyright (C) 2002, 2003  Red Hat Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21  *
     22  */
     23 
     24 #include <config.h>
     25 #include "dbus-transport-protected.h"
     26 #include "dbus-transport-unix.h"
     27 #include "dbus-transport-socket.h"
     28 #include "dbus-connection-internal.h"
     29 #include "dbus-watch.h"
     30 #include "dbus-auth.h"
     31 #include "dbus-address.h"
     32 #include "dbus-credentials.h"
     33 #include "dbus-message-private.h"
     34 #include "dbus-marshal-header.h"
     35 #ifdef DBUS_BUILD_TESTS
     36 #include "dbus-server-debug-pipe.h"
     37 #endif
     38 
     39 /**
     40  * @defgroup DBusTransport DBusTransport object
     41  * @ingroup  DBusInternals
     42  * @brief "Backend" for a DBusConnection.
     43  *
     44  * Types and functions related to DBusTransport.  A transport is an
     45  * abstraction that can send and receive data via various kinds of
     46  * network connections or other IPC mechanisms.
     47  *
     48  * @{
     49  */
     50 
     51 /**
     52  * @typedef DBusTransport
     53  *
     54  * Opaque object representing a way message stream.
     55  * DBusTransport abstracts various kinds of actual
     56  * transport mechanism, such as different network protocols,
     57  * or encryption schemes.
     58  */
     59 
     60 static void
     61 live_messages_notify (DBusCounter *counter,
     62                            void        *user_data)
     63 {
     64   DBusTransport *transport = user_data;
     65 
     66   _dbus_transport_ref (transport);
     67 
     68 #if 0
     69   _dbus_verbose ("Size counter value is now %d\n",
     70                  (int) _dbus_counter_get_size_value (counter));
     71   _dbus_verbose ("Unix FD counter value is now %d\n",
     72                  (int) _dbus_counter_get_unix_fd_value (counter));
     73 #endif
     74 
     75   /* disable or re-enable the read watch for the transport if
     76    * required.
     77    */
     78   if (transport->vtable->live_messages_changed)
     79     (* transport->vtable->live_messages_changed) (transport);
     80 
     81   _dbus_transport_unref (transport);
     82 }
     83 
     84 /**
     85  * Initializes the base class members of DBusTransport.  Chained up to
     86  * by subclasses in their constructor.  The server GUID is the
     87  * globally unique ID for the server creating this connection
     88  * and will be #NULL for the client side of a connection. The GUID
     89  * is in hex format.
     90  *
     91  * @param transport the transport being created.
     92  * @param vtable the subclass vtable.
     93  * @param server_guid non-#NULL if this transport is on the server side of a connection
     94  * @param address the address of the transport
     95  * @returns #TRUE on success.
     96  */
     97 dbus_bool_t
     98 _dbus_transport_init_base (DBusTransport             *transport,
     99                            const DBusTransportVTable *vtable,
    100                            const DBusString          *server_guid,
    101                            const DBusString          *address)
    102 {
    103   DBusMessageLoader *loader;
    104   DBusAuth *auth;
    105   DBusCounter *counter;
    106   char *address_copy;
    107   DBusCredentials *creds;
    108 
    109   loader = _dbus_message_loader_new ();
    110   if (loader == NULL)
    111     return FALSE;
    112 
    113   if (server_guid)
    114     auth = _dbus_auth_server_new (server_guid);
    115   else
    116     auth = _dbus_auth_client_new ();
    117   if (auth == NULL)
    118     {
    119       _dbus_message_loader_unref (loader);
    120       return FALSE;
    121     }
    122 
    123   counter = _dbus_counter_new ();
    124   if (counter == NULL)
    125     {
    126       _dbus_auth_unref (auth);
    127       _dbus_message_loader_unref (loader);
    128       return FALSE;
    129     }
    130 
    131   creds = _dbus_credentials_new ();
    132   if (creds == NULL)
    133     {
    134       _dbus_counter_unref (counter);
    135       _dbus_auth_unref (auth);
    136       _dbus_message_loader_unref (loader);
    137       return FALSE;
    138     }
    139 
    140   if (server_guid)
    141     {
    142       _dbus_assert (address == NULL);
    143       address_copy = NULL;
    144     }
    145   else
    146     {
    147       _dbus_assert (address != NULL);
    148 
    149       if (!_dbus_string_copy_data (address, &address_copy))
    150         {
    151           _dbus_credentials_unref (creds);
    152           _dbus_counter_unref (counter);
    153           _dbus_auth_unref (auth);
    154           _dbus_message_loader_unref (loader);
    155           return FALSE;
    156         }
    157     }
    158 
    159   transport->refcount = 1;
    160   transport->vtable = vtable;
    161   transport->loader = loader;
    162   transport->auth = auth;
    163   transport->live_messages = counter;
    164   transport->authenticated = FALSE;
    165   transport->disconnected = FALSE;
    166   transport->is_server = (server_guid != NULL);
    167   transport->send_credentials_pending = !transport->is_server;
    168   transport->receive_credentials_pending = transport->is_server;
    169   transport->address = address_copy;
    170 
    171   transport->unix_user_function = NULL;
    172   transport->unix_user_data = NULL;
    173   transport->free_unix_user_data = NULL;
    174 
    175   transport->windows_user_function = NULL;
    176   transport->windows_user_data = NULL;
    177   transport->free_windows_user_data = NULL;
    178 
    179   transport->expected_guid = NULL;
    180 
    181   /* Try to default to something that won't totally hose the system,
    182    * but doesn't impose too much of a limitation.
    183    */
    184   transport->max_live_messages_size = _DBUS_ONE_MEGABYTE * 63;
    185 
    186   /* On Linux RLIMIT_NOFILE defaults to 1024, so allowing 4096 fds live
    187      should be more than enough */
    188   transport->max_live_messages_unix_fds = 4096;
    189 
    190   /* credentials read from socket if any */
    191   transport->credentials = creds;
    192 
    193   _dbus_counter_set_notify (transport->live_messages,
    194                             transport->max_live_messages_size,
    195                             transport->max_live_messages_unix_fds,
    196                             live_messages_notify,
    197                             transport);
    198 
    199   if (transport->address)
    200     _dbus_verbose ("Initialized transport on address %s\n", transport->address);
    201 
    202   return TRUE;
    203 }
    204 
    205 /**
    206  * Finalizes base class members of DBusTransport.
    207  * Chained up to from subclass finalizers.
    208  *
    209  * @param transport the transport.
    210  */
    211 void
    212 _dbus_transport_finalize_base (DBusTransport *transport)
    213 {
    214   if (!transport->disconnected)
    215     _dbus_transport_disconnect (transport);
    216 
    217   if (transport->free_unix_user_data != NULL)
    218     (* transport->free_unix_user_data) (transport->unix_user_data);
    219 
    220   if (transport->free_windows_user_data != NULL)
    221     (* transport->free_windows_user_data) (transport->windows_user_data);
    222 
    223   _dbus_message_loader_unref (transport->loader);
    224   _dbus_auth_unref (transport->auth);
    225   _dbus_counter_set_notify (transport->live_messages,
    226                             0, 0, NULL, NULL);
    227   _dbus_counter_unref (transport->live_messages);
    228   dbus_free (transport->address);
    229   dbus_free (transport->expected_guid);
    230   if (transport->credentials)
    231     _dbus_credentials_unref (transport->credentials);
    232 }
    233 
    234 
    235 /**
    236  * Verifies if a given D-Bus address is a valid address
    237  * by attempting to connect to it. If it is, returns the
    238  * opened DBusTransport object. If it isn't, returns #NULL
    239  * and sets @p error.
    240  *
    241  * @param error address where an error can be returned.
    242  * @returns a new transport, or #NULL on failure.
    243  */
    244 static DBusTransport*
    245 check_address (const char *address, DBusError *error)
    246 {
    247   DBusAddressEntry **entries;
    248   DBusTransport *transport = NULL;
    249   int len, i;
    250 
    251   _dbus_assert (address != NULL);
    252   _dbus_assert (*address != '\0');
    253 
    254   if (!dbus_parse_address (address, &entries, &len, error))
    255     return NULL;              /* not a valid address */
    256 
    257   for (i = 0; i < len; i++)
    258     {
    259       transport = _dbus_transport_open (entries[i], error);
    260       if (transport != NULL)
    261         break;
    262     }
    263 
    264   dbus_address_entries_free (entries);
    265   return transport;
    266 }
    267 
    268 /**
    269  * Creates a new transport for the "autostart" method.
    270  * This creates a client-side of a transport.
    271  *
    272  * @param error address where an error can be returned.
    273  * @returns a new transport, or #NULL on failure.
    274  */
    275 static DBusTransport*
    276 _dbus_transport_new_for_autolaunch (DBusError      *error)
    277 {
    278   DBusString address;
    279   DBusTransport *result = NULL;
    280 
    281   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    282 
    283   if (!_dbus_string_init (&address))
    284     {
    285       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
    286       return NULL;
    287     }
    288 
    289   if (!_dbus_get_autolaunch_address (&address, error))
    290     {
    291       _DBUS_ASSERT_ERROR_IS_SET (error);
    292       goto out;
    293     }
    294 
    295   result = check_address (_dbus_string_get_const_data (&address), error);
    296   if (result == NULL)
    297     _DBUS_ASSERT_ERROR_IS_SET (error);
    298   else
    299     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    300 
    301  out:
    302   _dbus_string_free (&address);
    303   return result;
    304 }
    305 
    306 static DBusTransportOpenResult
    307 _dbus_transport_open_autolaunch (DBusAddressEntry  *entry,
    308                                  DBusTransport    **transport_p,
    309                                  DBusError         *error)
    310 {
    311   const char *method;
    312 
    313   method = dbus_address_entry_get_method (entry);
    314   _dbus_assert (method != NULL);
    315 
    316   if (strcmp (method, "autolaunch") == 0)
    317     {
    318       *transport_p = _dbus_transport_new_for_autolaunch (error);
    319 
    320       if (*transport_p == NULL)
    321         {
    322           _DBUS_ASSERT_ERROR_IS_SET (error);
    323           return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT;
    324         }
    325       else
    326         {
    327           _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    328           return DBUS_TRANSPORT_OPEN_OK;
    329         }
    330     }
    331   else
    332     {
    333       _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    334       return DBUS_TRANSPORT_OPEN_NOT_HANDLED;
    335     }
    336 }
    337 
    338 static const struct {
    339   DBusTransportOpenResult (* func) (DBusAddressEntry *entry,
    340                                     DBusTransport   **transport_p,
    341                                     DBusError        *error);
    342 } open_funcs[] = {
    343   { _dbus_transport_open_socket },
    344   { _dbus_transport_open_platform_specific },
    345   { _dbus_transport_open_autolaunch }
    346 #ifdef DBUS_BUILD_TESTS
    347   , { _dbus_transport_open_debug_pipe }
    348 #endif
    349 };
    350 
    351 /**
    352  * Try to open a new transport for the given address entry.  (This
    353  * opens a client-side-of-the-connection transport.)
    354  *
    355  * @param entry the address entry
    356  * @param error location to store reason for failure.
    357  * @returns new transport of #NULL on failure.
    358  */
    359 DBusTransport*
    360 _dbus_transport_open (DBusAddressEntry *entry,
    361                       DBusError        *error)
    362 {
    363   DBusTransport *transport;
    364   const char *expected_guid_orig;
    365   char *expected_guid;
    366   int i;
    367   DBusError tmp_error = DBUS_ERROR_INIT;
    368 
    369   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
    370 
    371   transport = NULL;
    372   expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
    373   expected_guid = _dbus_strdup (expected_guid_orig);
    374 
    375   if (expected_guid_orig != NULL && expected_guid == NULL)
    376     {
    377       _DBUS_SET_OOM (error);
    378       return NULL;
    379     }
    380 
    381   for (i = 0; i < (int) _DBUS_N_ELEMENTS (open_funcs); ++i)
    382     {
    383       DBusTransportOpenResult result;
    384 
    385       _DBUS_ASSERT_ERROR_CONTENT_IS_CLEAR (&tmp_error);
    386       result = (* open_funcs[i].func) (entry, &transport, &tmp_error);
    387 
    388       switch (result)
    389         {
    390         case DBUS_TRANSPORT_OPEN_OK:
    391           _DBUS_ASSERT_ERROR_CONTENT_IS_CLEAR (&tmp_error);
    392           goto out;
    393           break;
    394         case DBUS_TRANSPORT_OPEN_NOT_HANDLED:
    395           _DBUS_ASSERT_ERROR_CONTENT_IS_CLEAR (&tmp_error);
    396           /* keep going through the loop of open funcs */
    397           break;
    398         case DBUS_TRANSPORT_OPEN_BAD_ADDRESS:
    399           _DBUS_ASSERT_ERROR_CONTENT_IS_SET (&tmp_error);
    400           goto out;
    401           break;
    402         case DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT:
    403           _DBUS_ASSERT_ERROR_CONTENT_IS_SET (&tmp_error);
    404           goto out;
    405           break;
    406         }
    407     }
    408 
    409  out:
    410 
    411   if (transport == NULL)
    412     {
    413       if (!dbus_error_is_set (&tmp_error))
    414         _dbus_set_bad_address (&tmp_error,
    415                                NULL, NULL,
    416                                "Unknown address type (examples of valid types are \"tcp\" and on UNIX \"unix\")");
    417 
    418       _DBUS_ASSERT_ERROR_CONTENT_IS_SET (&tmp_error);
    419       dbus_move_error(&tmp_error, error);
    420       dbus_free (expected_guid);
    421     }
    422   else
    423     {
    424       _DBUS_ASSERT_ERROR_CONTENT_IS_CLEAR (&tmp_error);
    425 
    426       /* In the case of autostart the initial guid is NULL
    427        * and the autostart transport recursively calls
    428        * _dbus_open_transport wich returns a transport
    429        * with a guid.  That guid is the definitive one.
    430        *
    431        * FIXME: if more transports are added they may have
    432        * an effect on the expected_guid semantics (i.e.
    433        * expected_guid and transport->expected_guid may
    434        * both have values).  This is very unlikely though
    435        * we should either throw asserts here for those
    436        * corner cases or refactor the code so it is
    437        * clearer on what is expected and what is not
    438        */
    439       if(expected_guid)
    440         transport->expected_guid = expected_guid;
    441     }
    442 
    443   return transport;
    444 }
    445 
    446 /**
    447  * Increments the reference count for the transport.
    448  *
    449  * @param transport the transport.
    450  * @returns the transport.
    451  */
    452 DBusTransport *
    453 _dbus_transport_ref (DBusTransport *transport)
    454 {
    455   _dbus_assert (transport->refcount > 0);
    456 
    457   transport->refcount += 1;
    458 
    459   return transport;
    460 }
    461 
    462 /**
    463  * Decrements the reference count for the transport.
    464  * Disconnects and finalizes the transport if
    465  * the reference count reaches zero.
    466  *
    467  * @param transport the transport.
    468  */
    469 void
    470 _dbus_transport_unref (DBusTransport *transport)
    471 {
    472   _dbus_assert (transport != NULL);
    473   _dbus_assert (transport->refcount > 0);
    474 
    475   transport->refcount -= 1;
    476   if (transport->refcount == 0)
    477     {
    478       _dbus_verbose ("finalizing\n");
    479 
    480       _dbus_assert (transport->vtable->finalize != NULL);
    481 
    482       (* transport->vtable->finalize) (transport);
    483     }
    484 }
    485 
    486 /**
    487  * Closes our end of the connection to a remote application. Further
    488  * attempts to use this transport will fail. Only the first call to
    489  * _dbus_transport_disconnect() will have an effect.
    490  *
    491  * @param transport the transport.
    492  *
    493  */
    494 void
    495 _dbus_transport_disconnect (DBusTransport *transport)
    496 {
    497   _dbus_verbose ("start\n");
    498 
    499   _dbus_assert (transport->vtable->disconnect != NULL);
    500 
    501   if (transport->disconnected)
    502     return;
    503 
    504   (* transport->vtable->disconnect) (transport);
    505 
    506   transport->disconnected = TRUE;
    507 
    508   _dbus_verbose ("end\n");
    509 }
    510 
    511 /**
    512  * Returns #TRUE if the transport has not been disconnected.
    513  * Disconnection can result from _dbus_transport_disconnect()
    514  * or because the server drops its end of the connection.
    515  *
    516  * @param transport the transport.
    517  * @returns whether we're connected
    518  */
    519 dbus_bool_t
    520 _dbus_transport_get_is_connected (DBusTransport *transport)
    521 {
    522   return !transport->disconnected;
    523 }
    524 
    525 static dbus_bool_t
    526 auth_via_unix_user_function (DBusTransport *transport)
    527 {
    528   DBusCredentials *auth_identity;
    529   dbus_bool_t allow;
    530   DBusConnection *connection;
    531   DBusAllowUnixUserFunction unix_user_function;
    532   void *unix_user_data;
    533   dbus_uid_t uid;
    534 
    535   /* Dropping the lock here probably isn't that safe. */
    536 
    537   auth_identity = _dbus_auth_get_identity (transport->auth);
    538   _dbus_assert (auth_identity != NULL);
    539 
    540   connection = transport->connection;
    541   unix_user_function = transport->unix_user_function;
    542   unix_user_data = transport->unix_user_data;
    543   uid = _dbus_credentials_get_unix_uid (auth_identity);
    544 
    545   _dbus_verbose ("unlock\n");
    546   _dbus_connection_unlock (connection);
    547 
    548   allow = (* unix_user_function) (connection,
    549                                   uid,
    550                                   unix_user_data);
    551 
    552   _dbus_verbose ("lock post unix user function\n");
    553   _dbus_connection_lock (connection);
    554 
    555   if (allow)
    556     {
    557       _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
    558     }
    559   else
    560     {
    561       _dbus_verbose ("Client UID "DBUS_UID_FORMAT
    562                      " was rejected, disconnecting\n",
    563                      _dbus_credentials_get_unix_uid (auth_identity));
    564       _dbus_transport_disconnect (transport);
    565     }
    566 
    567   return allow;
    568 }
    569 
    570 static dbus_bool_t
    571 auth_via_windows_user_function (DBusTransport *transport)
    572 {
    573   DBusCredentials *auth_identity;
    574   dbus_bool_t allow;
    575   DBusConnection *connection;
    576   DBusAllowWindowsUserFunction windows_user_function;
    577   void *windows_user_data;
    578   char *windows_sid;
    579 
    580   /* Dropping the lock here probably isn't that safe. */
    581 
    582   auth_identity = _dbus_auth_get_identity (transport->auth);
    583   _dbus_assert (auth_identity != NULL);
    584 
    585   connection = transport->connection;
    586   windows_user_function = transport->windows_user_function;
    587   windows_user_data = transport->unix_user_data;
    588   windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
    589 
    590   if (windows_sid == NULL)
    591     {
    592       /* OOM */
    593       return FALSE;
    594     }
    595 
    596   _dbus_verbose ("unlock\n");
    597   _dbus_connection_unlock (connection);
    598 
    599   allow = (* windows_user_function) (connection,
    600                                      windows_sid,
    601                                      windows_user_data);
    602 
    603   _dbus_verbose ("lock post windows user function\n");
    604   _dbus_connection_lock (connection);
    605 
    606   if (allow)
    607     {
    608       _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
    609     }
    610   else
    611     {
    612       _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
    613                      _dbus_credentials_get_windows_sid (auth_identity));
    614       _dbus_transport_disconnect (transport);
    615     }
    616 
    617   return allow;
    618 }
    619 
    620 static dbus_bool_t
    621 auth_via_default_rules (DBusTransport *transport)
    622 {
    623   DBusCredentials *auth_identity;
    624   DBusCredentials *our_identity;
    625   dbus_bool_t allow;
    626 
    627   auth_identity = _dbus_auth_get_identity (transport->auth);
    628   _dbus_assert (auth_identity != NULL);
    629 
    630   /* By default, connection is allowed if the client is 1) root or 2)
    631    * has the same UID as us or 3) anonymous is allowed.
    632    */
    633 
    634   our_identity = _dbus_credentials_new_from_current_process ();
    635   if (our_identity == NULL)
    636     {
    637       /* OOM */
    638       return FALSE;
    639     }
    640 
    641   if (transport->allow_anonymous ||
    642       _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
    643       _dbus_credentials_same_user (our_identity,
    644                                    auth_identity))
    645     {
    646       if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
    647           _dbus_verbose ("Client authorized as SID '%s'"
    648                          "matching our SID '%s'\n",
    649                          _dbus_credentials_get_windows_sid(auth_identity),
    650                          _dbus_credentials_get_windows_sid(our_identity));
    651       else
    652           _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
    653                          " matching our UID "DBUS_UID_FORMAT"\n",
    654                          _dbus_credentials_get_unix_uid(auth_identity),
    655                          _dbus_credentials_get_unix_uid(our_identity));
    656       /* We have authenticated! */
    657       allow = TRUE;
    658     }
    659   else
    660     {
    661       if (_dbus_credentials_include(our_identity,DBUS_CREDENTIAL_WINDOWS_SID))
    662           _dbus_verbose ("Client authorized as SID '%s'"
    663                          " but our SID is '%s', disconnecting\n",
    664                          (_dbus_credentials_get_windows_sid(auth_identity) ?
    665                           _dbus_credentials_get_windows_sid(auth_identity) : "<null>"),
    666                          (_dbus_credentials_get_windows_sid(our_identity) ?
    667                           _dbus_credentials_get_windows_sid(our_identity) : "<null>"));
    668       else
    669           _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
    670                          " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
    671                          _dbus_credentials_get_unix_uid(auth_identity),
    672                          _dbus_credentials_get_unix_uid(our_identity));
    673       _dbus_transport_disconnect (transport);
    674       allow = FALSE;
    675     }
    676 
    677   _dbus_credentials_unref (our_identity);
    678 
    679   return allow;
    680 }
    681 
    682 
    683 /**
    684  * Returns #TRUE if we have been authenticated.  Will return #TRUE
    685  * even if the transport is disconnected.
    686  *
    687  * @todo we drop connection->mutex when calling the unix_user_function,
    688  * and windows_user_function, which may not be safe really.
    689  *
    690  * @param transport the transport
    691  * @returns whether we're authenticated
    692  */
    693 dbus_bool_t
    694 _dbus_transport_get_is_authenticated (DBusTransport *transport)
    695 {
    696   if (transport->authenticated)
    697     return TRUE;
    698   else
    699     {
    700       dbus_bool_t maybe_authenticated;
    701 
    702       if (transport->disconnected)
    703         return FALSE;
    704 
    705       /* paranoia ref since we call user callbacks sometimes */
    706       _dbus_connection_ref_unlocked (transport->connection);
    707 
    708       maybe_authenticated =
    709         (!(transport->send_credentials_pending ||
    710            transport->receive_credentials_pending));
    711 
    712       if (maybe_authenticated)
    713         {
    714           switch (_dbus_auth_do_work (transport->auth))
    715             {
    716             case DBUS_AUTH_STATE_AUTHENTICATED:
    717               /* leave as maybe_authenticated */
    718               break;
    719             default:
    720               maybe_authenticated = FALSE;
    721             }
    722         }
    723 
    724       /* If we're the client, verify the GUID
    725        */
    726       if (maybe_authenticated && !transport->is_server)
    727         {
    728           const char *server_guid;
    729 
    730           server_guid = _dbus_auth_get_guid_from_server (transport->auth);
    731           _dbus_assert (server_guid != NULL);
    732 
    733           if (transport->expected_guid &&
    734               strcmp (transport->expected_guid, server_guid) != 0)
    735             {
    736               _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
    737                              transport->expected_guid, server_guid);
    738               _dbus_transport_disconnect (transport);
    739               _dbus_connection_unref_unlocked (transport->connection);
    740               return FALSE;
    741             }
    742 
    743           if (transport->expected_guid == NULL)
    744             {
    745               transport->expected_guid = _dbus_strdup (server_guid);
    746 
    747               if (transport->expected_guid == NULL)
    748                 {
    749                   _dbus_verbose ("No memory to complete auth\n");
    750                   return FALSE;
    751                 }
    752             }
    753         }
    754 
    755       /* If we're the server, see if we want to allow this identity to proceed.
    756        */
    757       if (maybe_authenticated && transport->is_server)
    758         {
    759           dbus_bool_t allow;
    760           DBusCredentials *auth_identity;
    761 
    762           auth_identity = _dbus_auth_get_identity (transport->auth);
    763           _dbus_assert (auth_identity != NULL);
    764 
    765           /* If we have an auth'd user and a user function, delegate
    766            * deciding whether auth credentials are good enough to the
    767            * app; otherwise, use our default decision process.
    768            */
    769           if (transport->unix_user_function != NULL &&
    770               _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
    771             {
    772               allow = auth_via_unix_user_function (transport);
    773             }
    774           else if (transport->windows_user_function != NULL &&
    775                    _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
    776             {
    777               allow = auth_via_windows_user_function (transport);
    778             }
    779           else
    780             {
    781               allow = auth_via_default_rules (transport);
    782             }
    783 
    784           if (!allow)
    785             maybe_authenticated = FALSE;
    786         }
    787 
    788       transport->authenticated = maybe_authenticated;
    789 
    790       _dbus_connection_unref_unlocked (transport->connection);
    791       return maybe_authenticated;
    792     }
    793 }
    794 
    795 /**
    796  * See dbus_connection_get_is_anonymous().
    797  *
    798  * @param transport the transport
    799  * @returns #TRUE if not authenticated or authenticated as anonymous
    800  */
    801 dbus_bool_t
    802 _dbus_transport_get_is_anonymous (DBusTransport *transport)
    803 {
    804   DBusCredentials *auth_identity;
    805 
    806   if (!transport->authenticated)
    807     return TRUE;
    808 
    809   auth_identity = _dbus_auth_get_identity (transport->auth);
    810 
    811   if (_dbus_credentials_are_anonymous (auth_identity))
    812     return TRUE;
    813   else
    814     return FALSE;
    815 }
    816 
    817 /**
    818  * Returns TRUE if the transport supports sending unix fds.
    819  *
    820  * @param transport the transport
    821  * @returns #TRUE if TRUE it is possible to send unix fds across the transport.
    822  */
    823 dbus_bool_t
    824 _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
    825 {
    826   return DBUS_TRANSPORT_CAN_SEND_UNIX_FD(transport);
    827 }
    828 
    829 /**
    830  * Gets the address of a transport. It will be
    831  * #NULL for a server-side transport.
    832  *
    833  * @param transport the transport
    834  * @returns transport's address
    835  */
    836 const char*
    837 _dbus_transport_get_address (DBusTransport *transport)
    838 {
    839   return transport->address;
    840 }
    841 
    842 /**
    843  * Gets the id of the server we are connected to (see
    844  * dbus_server_get_id()). Only works on client side.
    845  *
    846  * @param transport the transport
    847  * @returns transport's server's id or #NULL if we are the server side
    848  */
    849 const char*
    850 _dbus_transport_get_server_id (DBusTransport *transport)
    851 {
    852   if (transport->is_server)
    853     return NULL;
    854   else
    855     return transport->expected_guid;
    856 }
    857 
    858 /**
    859  * Handles a watch by reading data, writing data, or disconnecting
    860  * the transport, as appropriate for the given condition.
    861  *
    862  * @param transport the transport.
    863  * @param watch the watch.
    864  * @param condition the current state of the watched file descriptor.
    865  * @returns #FALSE if not enough memory to fully handle the watch
    866  */
    867 dbus_bool_t
    868 _dbus_transport_handle_watch (DBusTransport           *transport,
    869                               DBusWatch               *watch,
    870                               unsigned int             condition)
    871 {
    872   dbus_bool_t retval;
    873 
    874   _dbus_assert (transport->vtable->handle_watch != NULL);
    875 
    876   if (transport->disconnected)
    877     return TRUE;
    878 
    879   if (dbus_watch_get_socket (watch) < 0)
    880     {
    881       _dbus_warn_check_failed ("Tried to handle an invalidated watch; this watch should have been removed\n");
    882       return TRUE;
    883     }
    884 
    885   _dbus_watch_sanitize_condition (watch, &condition);
    886 
    887   _dbus_transport_ref (transport);
    888   _dbus_watch_ref (watch);
    889   retval = (* transport->vtable->handle_watch) (transport, watch, condition);
    890   _dbus_watch_unref (watch);
    891   _dbus_transport_unref (transport);
    892 
    893   return retval;
    894 }
    895 
    896 /**
    897  * Sets the connection using this transport. Allows the transport
    898  * to add watches to the connection, queue incoming messages,
    899  * and pull outgoing messages.
    900  *
    901  * @param transport the transport.
    902  * @param connection the connection.
    903  * @returns #FALSE if not enough memory
    904  */
    905 dbus_bool_t
    906 _dbus_transport_set_connection (DBusTransport  *transport,
    907                                 DBusConnection *connection)
    908 {
    909   _dbus_assert (transport->vtable->connection_set != NULL);
    910   _dbus_assert (transport->connection == NULL);
    911 
    912   transport->connection = connection;
    913 
    914   _dbus_transport_ref (transport);
    915   if (!(* transport->vtable->connection_set) (transport))
    916     transport->connection = NULL;
    917   _dbus_transport_unref (transport);
    918 
    919   return transport->connection != NULL;
    920 }
    921 
    922 /**
    923  * Get the socket file descriptor, if any.
    924  *
    925  * @param transport the transport
    926  * @param fd_p pointer to fill in with the descriptor
    927  * @returns #TRUE if a descriptor was available
    928  */
    929 dbus_bool_t
    930 _dbus_transport_get_socket_fd (DBusTransport *transport,
    931                                int           *fd_p)
    932 {
    933   dbus_bool_t retval;
    934 
    935   if (transport->vtable->get_socket_fd == NULL)
    936     return FALSE;
    937 
    938   if (transport->disconnected)
    939     return FALSE;
    940 
    941   _dbus_transport_ref (transport);
    942 
    943   retval = (* transport->vtable->get_socket_fd) (transport,
    944                                                  fd_p);
    945 
    946   _dbus_transport_unref (transport);
    947 
    948   return retval;
    949 }
    950 
    951 /**
    952  * Performs a single poll()/select() on the transport's file
    953  * descriptors and then reads/writes data as appropriate,
    954  * queueing incoming messages and sending outgoing messages.
    955  * This is the backend for _dbus_connection_do_iteration().
    956  * See _dbus_connection_do_iteration() for full details.
    957  *
    958  * @param transport the transport.
    959  * @param flags indicates whether to read or write, and whether to block.
    960  * @param timeout_milliseconds if blocking, timeout or -1 for no timeout.
    961  */
    962 void
    963 _dbus_transport_do_iteration (DBusTransport  *transport,
    964                               unsigned int    flags,
    965                               int             timeout_milliseconds)
    966 {
    967   _dbus_assert (transport->vtable->do_iteration != NULL);
    968 
    969   _dbus_verbose ("Transport iteration flags 0x%x timeout %d connected = %d\n",
    970                  flags, timeout_milliseconds, !transport->disconnected);
    971 
    972   if ((flags & (DBUS_ITERATION_DO_WRITING |
    973                 DBUS_ITERATION_DO_READING)) == 0)
    974     return; /* Nothing to do */
    975 
    976   if (transport->disconnected)
    977     return;
    978 
    979   _dbus_transport_ref (transport);
    980   (* transport->vtable->do_iteration) (transport, flags,
    981                                        timeout_milliseconds);
    982   _dbus_transport_unref (transport);
    983 
    984   _dbus_verbose ("end\n");
    985 }
    986 
    987 static dbus_bool_t
    988 recover_unused_bytes (DBusTransport *transport)
    989 {
    990   if (_dbus_auth_needs_decoding (transport->auth))
    991     {
    992       DBusString plaintext;
    993       const DBusString *encoded;
    994       DBusString *buffer;
    995       int orig_len;
    996 
    997       if (!_dbus_string_init (&plaintext))
    998         goto nomem;
    999 
   1000       _dbus_auth_get_unused_bytes (transport->auth,
   1001                                    &encoded);
   1002 
   1003       if (!_dbus_auth_decode_data (transport->auth,
   1004                                    encoded, &plaintext))
   1005         {
   1006           _dbus_string_free (&plaintext);
   1007           goto nomem;
   1008         }
   1009 
   1010       _dbus_message_loader_get_buffer (transport->loader,
   1011                                        &buffer);
   1012 
   1013       orig_len = _dbus_string_get_length (buffer);
   1014 
   1015       if (!_dbus_string_move (&plaintext, 0, buffer,
   1016                               orig_len))
   1017         {
   1018           _dbus_string_free (&plaintext);
   1019           goto nomem;
   1020         }
   1021 
   1022       _dbus_verbose (" %d unused bytes sent to message loader\n",
   1023                      _dbus_string_get_length (buffer) -
   1024                      orig_len);
   1025 
   1026       _dbus_message_loader_return_buffer (transport->loader,
   1027                                           buffer,
   1028                                           _dbus_string_get_length (buffer) -
   1029                                           orig_len);
   1030 
   1031       _dbus_auth_delete_unused_bytes (transport->auth);
   1032 
   1033       _dbus_string_free (&plaintext);
   1034     }
   1035   else
   1036     {
   1037       const DBusString *bytes;
   1038       DBusString *buffer;
   1039       int orig_len;
   1040       dbus_bool_t succeeded;
   1041 
   1042       _dbus_message_loader_get_buffer (transport->loader,
   1043                                        &buffer);
   1044 
   1045       orig_len = _dbus_string_get_length (buffer);
   1046 
   1047       _dbus_auth_get_unused_bytes (transport->auth,
   1048                                    &bytes);
   1049 
   1050       succeeded = TRUE;
   1051       if (!_dbus_string_copy (bytes, 0, buffer, _dbus_string_get_length (buffer)))
   1052         succeeded = FALSE;
   1053 
   1054       _dbus_verbose (" %d unused bytes sent to message loader\n",
   1055                      _dbus_string_get_length (buffer) -
   1056                      orig_len);
   1057 
   1058       _dbus_message_loader_return_buffer (transport->loader,
   1059                                           buffer,
   1060                                           _dbus_string_get_length (buffer) -
   1061                                           orig_len);
   1062 
   1063       if (succeeded)
   1064         _dbus_auth_delete_unused_bytes (transport->auth);
   1065       else
   1066         goto nomem;
   1067     }
   1068 
   1069   return TRUE;
   1070 
   1071  nomem:
   1072   _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
   1073   return FALSE;
   1074 }
   1075 
   1076 /**
   1077  * Reports our current dispatch status (whether there's buffered
   1078  * data to be queued as messages, or not, or we need memory).
   1079  *
   1080  * @param transport the transport
   1081  * @returns current status
   1082  */
   1083 DBusDispatchStatus
   1084 _dbus_transport_get_dispatch_status (DBusTransport *transport)
   1085 {
   1086   if (_dbus_counter_get_size_value (transport->live_messages) >= transport->max_live_messages_size ||
   1087       _dbus_counter_get_unix_fd_value (transport->live_messages) >= transport->max_live_messages_unix_fds)
   1088     return DBUS_DISPATCH_COMPLETE; /* complete for now */
   1089 
   1090   if (!_dbus_transport_get_is_authenticated (transport))
   1091     {
   1092       if (_dbus_auth_do_work (transport->auth) ==
   1093           DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
   1094         return DBUS_DISPATCH_NEED_MEMORY;
   1095       else if (!_dbus_transport_get_is_authenticated (transport))
   1096         return DBUS_DISPATCH_COMPLETE;
   1097     }
   1098 
   1099   if (!transport->unused_bytes_recovered &&
   1100       !recover_unused_bytes (transport))
   1101     return DBUS_DISPATCH_NEED_MEMORY;
   1102 
   1103   transport->unused_bytes_recovered = TRUE;
   1104 
   1105   if (!_dbus_message_loader_queue_messages (transport->loader))
   1106     return DBUS_DISPATCH_NEED_MEMORY;
   1107 
   1108   if (_dbus_message_loader_peek_message (transport->loader) != NULL)
   1109     return DBUS_DISPATCH_DATA_REMAINS;
   1110   else
   1111     return DBUS_DISPATCH_COMPLETE;
   1112 }
   1113 
   1114 /**
   1115  * Processes data we've read while handling a watch, potentially
   1116  * converting some of it to messages and queueing those messages on
   1117  * the connection.
   1118  *
   1119  * @param transport the transport
   1120  * @returns #TRUE if we had enough memory to queue all messages
   1121  */
   1122 dbus_bool_t
   1123 _dbus_transport_queue_messages (DBusTransport *transport)
   1124 {
   1125   DBusDispatchStatus status;
   1126 
   1127 #if 0
   1128   _dbus_verbose ("_dbus_transport_queue_messages()\n");
   1129 #endif
   1130 
   1131   /* Queue any messages */
   1132   while ((status = _dbus_transport_get_dispatch_status (transport)) == DBUS_DISPATCH_DATA_REMAINS)
   1133     {
   1134       DBusMessage *message;
   1135       DBusList *link;
   1136 
   1137       link = _dbus_message_loader_pop_message_link (transport->loader);
   1138       _dbus_assert (link != NULL);
   1139 
   1140       message = link->data;
   1141 
   1142       _dbus_verbose ("queueing received message %p\n", message);
   1143 
   1144       if (!_dbus_message_add_counter (message, transport->live_messages))
   1145         {
   1146           _dbus_message_loader_putback_message_link (transport->loader,
   1147                                                      link);
   1148           status = DBUS_DISPATCH_NEED_MEMORY;
   1149           break;
   1150         }
   1151       else
   1152         {
   1153           /* pass ownership of link and message ref to connection */
   1154           _dbus_connection_queue_received_message_link (transport->connection,
   1155                                                         link);
   1156         }
   1157     }
   1158 
   1159   if (_dbus_message_loader_get_is_corrupted (transport->loader))
   1160     {
   1161       _dbus_verbose ("Corrupted message stream, disconnecting\n");
   1162       _dbus_transport_disconnect (transport);
   1163     }
   1164 
   1165   return status != DBUS_DISPATCH_NEED_MEMORY;
   1166 }
   1167 
   1168 /**
   1169  * See dbus_connection_set_max_message_size().
   1170  *
   1171  * @param transport the transport
   1172  * @param size the max size of a single message
   1173  */
   1174 void
   1175 _dbus_transport_set_max_message_size (DBusTransport  *transport,
   1176                                       long            size)
   1177 {
   1178   _dbus_message_loader_set_max_message_size (transport->loader, size);
   1179 }
   1180 
   1181 /**
   1182  * See dbus_connection_set_max_message_unix_fds().
   1183  *
   1184  * @param transport the transport
   1185  * @param n the max number of unix fds of a single message
   1186  */
   1187 void
   1188 _dbus_transport_set_max_message_unix_fds (DBusTransport  *transport,
   1189                                           long            n)
   1190 {
   1191   _dbus_message_loader_set_max_message_unix_fds (transport->loader, n);
   1192 }
   1193 
   1194 /**
   1195  * See dbus_connection_get_max_message_size().
   1196  *
   1197  * @param transport the transport
   1198  * @returns max message size
   1199  */
   1200 long
   1201 _dbus_transport_get_max_message_size (DBusTransport  *transport)
   1202 {
   1203   return _dbus_message_loader_get_max_message_size (transport->loader);
   1204 }
   1205 
   1206 /**
   1207  * See dbus_connection_get_max_message_unix_fds().
   1208  *
   1209  * @param transport the transport
   1210  * @returns max message unix fds
   1211  */
   1212 long
   1213 _dbus_transport_get_max_message_unix_fds (DBusTransport  *transport)
   1214 {
   1215   return _dbus_message_loader_get_max_message_unix_fds (transport->loader);
   1216 }
   1217 
   1218 /**
   1219  * See dbus_connection_set_max_received_size().
   1220  *
   1221  * @param transport the transport
   1222  * @param size the max size of all incoming messages
   1223  */
   1224 void
   1225 _dbus_transport_set_max_received_size (DBusTransport  *transport,
   1226                                        long            size)
   1227 {
   1228   transport->max_live_messages_size = size;
   1229   _dbus_counter_set_notify (transport->live_messages,
   1230                             transport->max_live_messages_size,
   1231                             transport->max_live_messages_unix_fds,
   1232                             live_messages_notify,
   1233                             transport);
   1234 }
   1235 
   1236 /**
   1237  * See dbus_connection_set_max_received_unix_fds().
   1238  *
   1239  * @param transport the transport
   1240  * @param n the max unix fds of all incoming messages
   1241  */
   1242 void
   1243 _dbus_transport_set_max_received_unix_fds (DBusTransport  *transport,
   1244                                            long            n)
   1245 {
   1246   transport->max_live_messages_unix_fds = n;
   1247   _dbus_counter_set_notify (transport->live_messages,
   1248                             transport->max_live_messages_size,
   1249                             transport->max_live_messages_unix_fds,
   1250                             live_messages_notify,
   1251                             transport);
   1252 }
   1253 
   1254 /**
   1255  * See dbus_connection_get_max_received_size().
   1256  *
   1257  * @param transport the transport
   1258  * @returns max bytes for all live messages
   1259  */
   1260 long
   1261 _dbus_transport_get_max_received_size (DBusTransport  *transport)
   1262 {
   1263   return transport->max_live_messages_size;
   1264 }
   1265 
   1266 /**
   1267  * See dbus_connection_set_max_received_unix_fds().
   1268  *
   1269  * @param transport the transport
   1270  * @returns max unix fds for all live messages
   1271  */
   1272 long
   1273 _dbus_transport_get_max_received_unix_fds (DBusTransport  *transport)
   1274 {
   1275   return transport->max_live_messages_unix_fds;
   1276 }
   1277 
   1278 /**
   1279  * See dbus_connection_get_unix_user().
   1280  *
   1281  * @param transport the transport
   1282  * @param uid return location for the user ID
   1283  * @returns #TRUE if uid is filled in with a valid user ID
   1284  */
   1285 dbus_bool_t
   1286 _dbus_transport_get_unix_user (DBusTransport *transport,
   1287                                unsigned long *uid)
   1288 {
   1289   DBusCredentials *auth_identity;
   1290 
   1291   *uid = _DBUS_INT32_MAX; /* better than some root or system user in
   1292                            * case of bugs in the caller. Caller should
   1293                            * never use this value on purpose, however.
   1294                            */
   1295 
   1296   if (!transport->authenticated)
   1297     return FALSE;
   1298 
   1299   auth_identity = _dbus_auth_get_identity (transport->auth);
   1300 
   1301   if (_dbus_credentials_include (auth_identity,
   1302                                  DBUS_CREDENTIAL_UNIX_USER_ID))
   1303     {
   1304       *uid = _dbus_credentials_get_unix_uid (auth_identity);
   1305       return TRUE;
   1306     }
   1307   else
   1308     return FALSE;
   1309 }
   1310 
   1311 /**
   1312  * See dbus_connection_get_unix_process_id().
   1313  *
   1314  * @param transport the transport
   1315  * @param pid return location for the process ID
   1316  * @returns #TRUE if uid is filled in with a valid process ID
   1317  */
   1318 dbus_bool_t
   1319 _dbus_transport_get_unix_process_id (DBusTransport *transport,
   1320 				     unsigned long *pid)
   1321 {
   1322   DBusCredentials *auth_identity;
   1323 
   1324   *pid = DBUS_PID_UNSET; /* Caller should never use this value on purpose,
   1325 			  * but we set it to a safe number, INT_MAX,
   1326 			  * just to root out possible bugs in bad callers.
   1327 			  */
   1328 
   1329   if (!transport->authenticated)
   1330     return FALSE;
   1331 
   1332   auth_identity = _dbus_auth_get_identity (transport->auth);
   1333 
   1334   if (_dbus_credentials_include (auth_identity,
   1335                                  DBUS_CREDENTIAL_UNIX_PROCESS_ID))
   1336     {
   1337       *pid = _dbus_credentials_get_unix_pid (auth_identity);
   1338       return TRUE;
   1339     }
   1340   else
   1341     return FALSE;
   1342 }
   1343 
   1344 /**
   1345  * See dbus_connection_get_adt_audit_session_data().
   1346  *
   1347  * @param transport the transport
   1348  * @param data return location for the ADT audit data
   1349  * @param data_size return length of audit data
   1350  * @returns #TRUE if audit data is filled in with a valid ucred
   1351  */
   1352 dbus_bool_t
   1353 _dbus_transport_get_adt_audit_session_data (DBusTransport      *transport,
   1354                                             void              **data,
   1355                                             int                *data_size)
   1356 {
   1357   DBusCredentials *auth_identity;
   1358 
   1359   *data = NULL;
   1360   *data_size = 0;
   1361 
   1362   if (!transport->authenticated)
   1363     return FALSE;
   1364 
   1365   auth_identity = _dbus_auth_get_identity (transport->auth);
   1366 
   1367   if (_dbus_credentials_include (auth_identity,
   1368                                  DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID))
   1369     {
   1370       *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
   1371       *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
   1372       return TRUE;
   1373     }
   1374   else
   1375     return FALSE;
   1376 }
   1377 
   1378 /**
   1379  * See dbus_connection_set_unix_user_function().
   1380  *
   1381  * @param transport the transport
   1382  * @param function the predicate
   1383  * @param data data to pass to the predicate
   1384  * @param free_data_function function to free the data
   1385  * @param old_data the old user data to be freed
   1386  * @param old_free_data_function old free data function to free it with
   1387  */
   1388 void
   1389 _dbus_transport_set_unix_user_function (DBusTransport             *transport,
   1390                                         DBusAllowUnixUserFunction  function,
   1391                                         void                      *data,
   1392                                         DBusFreeFunction           free_data_function,
   1393                                         void                     **old_data,
   1394                                         DBusFreeFunction          *old_free_data_function)
   1395 {
   1396   *old_data = transport->unix_user_data;
   1397   *old_free_data_function = transport->free_unix_user_data;
   1398 
   1399   transport->unix_user_function = function;
   1400   transport->unix_user_data = data;
   1401   transport->free_unix_user_data = free_data_function;
   1402 }
   1403 
   1404 /**
   1405  * See dbus_connection_get_windows_user().
   1406  *
   1407  * @param transport the transport
   1408  * @param windows_sid_p return location for the user ID
   1409  * @returns #TRUE if user is available; the returned value may still be #NULL if no memory to copy it
   1410  */
   1411 dbus_bool_t
   1412 _dbus_transport_get_windows_user (DBusTransport              *transport,
   1413                                   char                      **windows_sid_p)
   1414 {
   1415   DBusCredentials *auth_identity;
   1416 
   1417   *windows_sid_p = NULL;
   1418 
   1419   if (!transport->authenticated)
   1420     return FALSE;
   1421 
   1422   auth_identity = _dbus_auth_get_identity (transport->auth);
   1423 
   1424   if (_dbus_credentials_include (auth_identity,
   1425                                  DBUS_CREDENTIAL_WINDOWS_SID))
   1426     {
   1427       /* If no memory, we are supposed to return TRUE and set NULL */
   1428       *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
   1429 
   1430       return TRUE;
   1431     }
   1432   else
   1433     return FALSE;
   1434 }
   1435 
   1436 /**
   1437  * See dbus_connection_set_windows_user_function().
   1438  *
   1439  * @param transport the transport
   1440  * @param function the predicate
   1441  * @param data data to pass to the predicate
   1442  * @param free_data_function function to free the data
   1443  * @param old_data the old user data to be freed
   1444  * @param old_free_data_function old free data function to free it with
   1445  */
   1446 
   1447 void
   1448 _dbus_transport_set_windows_user_function (DBusTransport              *transport,
   1449                                            DBusAllowWindowsUserFunction   function,
   1450                                            void                       *data,
   1451                                            DBusFreeFunction            free_data_function,
   1452                                            void                      **old_data,
   1453                                            DBusFreeFunction           *old_free_data_function)
   1454 {
   1455   *old_data = transport->windows_user_data;
   1456   *old_free_data_function = transport->free_windows_user_data;
   1457 
   1458   transport->windows_user_function = function;
   1459   transport->windows_user_data = data;
   1460   transport->free_windows_user_data = free_data_function;
   1461 }
   1462 
   1463 /**
   1464  * Sets the SASL authentication mechanisms supported by this transport.
   1465  *
   1466  * @param transport the transport
   1467  * @param mechanisms the #NULL-terminated array of mechanisms
   1468  *
   1469  * @returns #FALSE if no memory
   1470  */
   1471 dbus_bool_t
   1472 _dbus_transport_set_auth_mechanisms (DBusTransport  *transport,
   1473                                      const char    **mechanisms)
   1474 {
   1475   return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
   1476 }
   1477 
   1478 /**
   1479  * See dbus_connection_set_allow_anonymous()
   1480  *
   1481  * @param transport the transport
   1482  * @param value #TRUE to allow anonymous connection
   1483  */
   1484 void
   1485 _dbus_transport_set_allow_anonymous (DBusTransport              *transport,
   1486                                      dbus_bool_t                 value)
   1487 {
   1488   transport->allow_anonymous = value != FALSE;
   1489 }
   1490 
   1491 /** @} */
   1492