? config.cache
? test/data/valid-config-files/session.d
? test/name-test/run-with-tmp-session-bus.conf
Index: ChangeLog
===================================================================
RCS file: /cvs/dbus/dbus/ChangeLog,v
retrieving revision 1.1307
diff -u -p -r1.1307 ChangeLog
--- ChangeLog	9 Jun 2007 21:53:18 -0000	1.1307
+++ ChangeLog	9 Jun 2007 23:40:43 -0000
@@ -1,5 +1,24 @@
 2007-06-09  Havoc Pennington  <hp@redhat.com>
 
+	* bus/policy.c (bus_policy_create_client_policy): gracefully
+	continue if the connection has no unix user - just don't apply 
+	any unix user dependent rules.
+
+	* bus/config-parser.c: remove dbus-userdb.h usage
+
+	* bus/bus.c: remove dbus-userdb.h usage
+
+	* dbus/dbus-transport.c (_dbus_transport_get_is_authenticated):
+	support Windows user function; also, fix the logic for checking
+	auth as root in the default auth code (broken in the previous
+	commit)
+
+	* dbus/dbus-connection.c
+	(dbus_connection_set_windows_user_function): new function
+	(dbus_connection_get_windows_user): new function
+
+2007-06-09  Havoc Pennington  <hp@redhat.com>
+
 	* bus/dispatch.c (check_get_connection_unix_process_id): adapt
 	since sysdeps-unix.h stuff isn't included anymore
 
Index: bus/bus.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/bus.c,v
retrieving revision 1.78
diff -u -p -r1.78 bus.c
--- bus/bus.c	9 Jun 2007 21:53:18 -0000	1.78
+++ bus/bus.c	9 Jun 2007 23:40:44 -0000
@@ -34,7 +34,6 @@
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-hash.h>
 #include <dbus/dbus-internals.h>
-#include <dbus/dbus-userdb.h>
 
 struct BusContext
 {
@@ -794,7 +793,7 @@ bus_context_reload_config (BusContext *c
   dbus_bool_t ret;
 
   /* Flush the user database cache */
-  _dbus_user_database_flush_system ();
+  _dbus_flush_caches ();
 
   ret = FALSE;
   _dbus_string_init_const (&config_file, context->config_file);
@@ -995,11 +994,23 @@ bus_context_get_loop (BusContext *contex
 }
 
 dbus_bool_t
-bus_context_allow_user (BusContext   *context,
-                        unsigned long uid)
+bus_context_allow_unix_user (BusContext   *context,
+                             unsigned long uid)
 {
-  return bus_policy_allow_user (context->policy,
-                                uid);
+  return bus_policy_allow_unix_user (context->policy,
+                                     uid);
+}
+
+/* For now this is never actually called because the default
+ * DBusConnection behavior of 'same user that owns the bus can connect'
+ * is all it would do.
+ */
+dbus_bool_t
+bus_context_allow_windows_user (BusContext       *context,
+                                const char       *windows_sid)
+{
+  return bus_policy_allow_windows_user (context->policy,
+                                        windows_sid);
 }
 
 BusPolicy *
Index: bus/bus.h
===================================================================
RCS file: /cvs/dbus/dbus/bus/bus.h,v
retrieving revision 1.30
diff -u -p -r1.30 bus.h
--- bus/bus.h	12 Mar 2007 22:52:39 -0000	1.30
+++ bus/bus.h	9 Jun 2007 23:40:44 -0000
@@ -85,8 +85,10 @@ BusConnections*   bus_context_get_connec
 BusActivation*    bus_context_get_activation                     (BusContext       *context);
 BusMatchmaker*    bus_context_get_matchmaker                     (BusContext       *context);
 DBusLoop*         bus_context_get_loop                           (BusContext       *context);
-dbus_bool_t       bus_context_allow_user                         (BusContext       *context,
+dbus_bool_t       bus_context_allow_unix_user                    (BusContext       *context,
                                                                   unsigned long     uid);
+dbus_bool_t       bus_context_allow_windows_user                 (BusContext       *context,
+                                                                  const char       *windows_sid);
 BusPolicy*        bus_context_get_policy                         (BusContext       *context);
 
 BusClientPolicy*  bus_context_create_client_policy               (BusContext       *context,
Index: bus/config-parser.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/config-parser.c,v
retrieving revision 1.51
diff -u -p -r1.51 config-parser.c
--- bus/config-parser.c	24 May 2007 08:07:28 -0000	1.51
+++ bus/config-parser.c	9 Jun 2007 23:40:46 -0000
@@ -27,7 +27,6 @@
 #include "selinux.h"
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-internals.h>
-#include <dbus/dbus-userdb.h>
 #include <string.h>
 
 typedef enum
@@ -983,8 +982,8 @@ start_busconfig_child (BusConfigParser  
           DBusString username;
           _dbus_string_init_const (&username, user);
 
-          if (_dbus_get_user_id (&username,
-                                 &e->d.policy.gid_uid_or_at_console))
+          if (_dbus_parse_unix_user_from_config (&username,
+                                                 &e->d.policy.gid_uid_or_at_console))
             e->d.policy.type = POLICY_USER;
           else
             _dbus_warn ("Unknown username \"%s\" in message bus configuration file\n",
@@ -995,8 +994,8 @@ start_busconfig_child (BusConfigParser  
           DBusString group_name;
           _dbus_string_init_const (&group_name, group);
 
-          if (_dbus_get_group_id (&group_name,
-                                  &e->d.policy.gid_uid_or_at_console))
+          if (_dbus_parse_unix_group_from_config (&group_name,
+                                                  &e->d.policy.gid_uid_or_at_console))
             e->d.policy.type = POLICY_GROUP;
           else
             _dbus_warn ("Unknown group \"%s\" in message bus configuration file\n",
@@ -1469,7 +1468,7 @@ append_rule_from_element (BusConfigParse
           
           _dbus_string_init_const (&username, user);
       
-          if (_dbus_get_user_id (&username, &uid))
+          if (_dbus_parse_unix_user_from_config (&username, &uid))
             {
               rule = bus_policy_rule_new (BUS_POLICY_RULE_USER, allow); 
               if (rule == NULL)
@@ -1501,7 +1500,7 @@ append_rule_from_element (BusConfigParse
           
           _dbus_string_init_const (&groupname, group);
           
-          if (_dbus_get_user_id (&groupname, &gid))
+          if (_dbus_parse_unix_group_from_config (&groupname, &gid))
             {
               rule = bus_policy_rule_new (BUS_POLICY_RULE_GROUP, allow); 
               if (rule == NULL)
@@ -1571,7 +1570,7 @@ append_rule_from_element (BusConfigParse
 
         case POLICY_CONSOLE:
           if (!bus_policy_append_console_rule (parser->policy, pe->d.policy.gid_uid_or_at_console,
-                                             rule))
+                                               rule))
             goto nomem;
           break;
         }
Index: bus/connection.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/connection.c,v
retrieving revision 1.66
diff -u -p -r1.66 connection.c
--- bus/connection.c	12 Dec 2006 21:24:07 -0000	1.66
+++ bus/connection.c	9 Jun 2007 23:40:48 -0000
@@ -31,7 +31,6 @@
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-hash.h>
 #include <dbus/dbus-timeout.h>
-#include <dbus/dbus-userdb.h>
 
 static void bus_connection_remove_transactions (DBusConnection *connection);
 
@@ -243,7 +242,9 @@ bus_connection_disconnected (DBusConnect
   
   dbus_connection_set_unix_user_function (connection,
                                           NULL, NULL, NULL);
-
+  dbus_connection_set_windows_user_function (connection,
+                                             NULL, NULL, NULL);
+  
   dbus_connection_set_dispatch_status_function (connection,
                                                 NULL, NULL, NULL);
   
@@ -369,9 +370,9 @@ dispatch_status_function (DBusConnection
 }
 
 static dbus_bool_t
-allow_user_function (DBusConnection *connection,
-                     unsigned long   uid,
-                     void           *data)
+allow_unix_user_function (DBusConnection *connection,
+                          unsigned long   uid,
+                          void           *data)
 {
   BusConnectionData *d;
     
@@ -379,7 +380,7 @@ allow_user_function (DBusConnection *con
 
   _dbus_assert (d != NULL);
   
-  return bus_context_allow_user (d->connections->context, uid);
+  return bus_context_allow_unix_user (d->connections->context, uid);
 }
 
 static void
@@ -597,9 +598,14 @@ bus_connections_setup_connection (BusCon
                                               NULL,
                                               connection, NULL))
     goto out;
-  
+
+  /* For now we don't need to set a Windows user function because
+   * there are no policies in the config file controlling what
+   * Windows users can connect. The default 'same user that owns the
+   * bus can connect' behavior of DBusConnection is fine on Windows.
+   */
   dbus_connection_set_unix_user_function (connection,
-                                          allow_user_function,
+                                          allow_unix_user_function,
                                           NULL, NULL);
 
   dbus_connection_set_dispatch_status_function (connection,
@@ -679,6 +685,9 @@ bus_connections_setup_connection (BusCon
       dbus_connection_set_unix_user_function (connection,
                                               NULL, NULL, NULL);
 
+      dbus_connection_set_windows_user_function (connection,
+                                                 NULL, NULL, NULL);
+      
       dbus_connection_set_dispatch_status_function (connection,
                                                     NULL, NULL, NULL);
 
@@ -772,10 +781,10 @@ expire_incomplete_timeout (void *data)
 }
 
 dbus_bool_t
-bus_connection_get_groups  (DBusConnection   *connection,
-                            unsigned long   **groups,
-                            int              *n_groups,
-                            DBusError        *error)
+bus_connection_get_unix_groups  (DBusConnection   *connection,
+                                 unsigned long   **groups,
+                                 int              *n_groups,
+                                 DBusError        *error)
 {
   BusConnectionData *d;
   unsigned long uid;
@@ -789,7 +798,7 @@ bus_connection_get_groups  (DBusConnecti
 
   if (dbus_connection_get_unix_user (connection, &uid))
     {
-      if (!_dbus_groups_from_uid (uid, groups, n_groups))
+      if (!_dbus_unix_groups_from_uid (uid, groups, n_groups))
         {
           _dbus_verbose ("Did not get any groups for UID %lu\n",
                          uid);
@@ -807,15 +816,15 @@ bus_connection_get_groups  (DBusConnecti
 }
 
 dbus_bool_t
-bus_connection_is_in_group (DBusConnection *connection,
-                            unsigned long   gid)
+bus_connection_is_in_unix_group (DBusConnection *connection,
+                                 unsigned long   gid)
 {
   int i;
   unsigned long *group_ids;
   int n_group_ids;
 
-  if (!bus_connection_get_groups (connection, &group_ids, &n_group_ids,
-                                  NULL))
+  if (!bus_connection_get_unix_groups (connection, &group_ids, &n_group_ids,
+                                       NULL))
     return FALSE;
 
   i = 0;
Index: bus/connection.h
===================================================================
RCS file: /cvs/dbus/dbus/bus/connection.h,v
retrieving revision 1.21
diff -u -p -r1.21 connection.h
--- bus/connection.h	10 Aug 2004 03:06:59 -0000	1.21
+++ bus/connection.h	9 Jun 2007 23:40:48 -0000
@@ -105,12 +105,12 @@ dbus_bool_t bus_connection_complete (DBu
 /* called by dispatch.c when the connection is dropped */
 void        bus_connection_disconnected (DBusConnection *connection);
 
-dbus_bool_t      bus_connection_is_in_group (DBusConnection       *connection,
-                                             unsigned long         gid);
-dbus_bool_t      bus_connection_get_groups  (DBusConnection       *connection,
-                                             unsigned long       **groups,
-                                             int                  *n_groups,
-                                             DBusError            *error);
+dbus_bool_t      bus_connection_is_in_unix_group (DBusConnection       *connection,
+                                                  unsigned long         gid);
+dbus_bool_t      bus_connection_get_unix_groups  (DBusConnection       *connection,
+                                                  unsigned long       **groups,
+                                                  int                  *n_groups,
+                                                  DBusError            *error);
 BusClientPolicy* bus_connection_get_policy  (DBusConnection       *connection);
 
 /* transaction API so we can send or not send a block of messages as a whole */
Index: bus/policy.c
===================================================================
RCS file: /cvs/dbus/dbus/bus/policy.c,v
retrieving revision 1.28
diff -u -p -r1.28 policy.c
--- bus/policy.c	9 Jun 2007 21:53:18 -0000	1.28
+++ bus/policy.c	9 Jun 2007 23:40:48 -0000
@@ -28,7 +28,6 @@
 #include <dbus/dbus-list.h>
 #include <dbus/dbus-hash.h>
 #include <dbus/dbus-internals.h>
-#include <dbus/dbus-userdb.h>
 
 BusPolicyRule*
 bus_policy_rule_new (BusPolicyRuleType type,
@@ -296,7 +295,7 @@ bus_policy_create_client_policy (BusPoli
       int n_groups;
       int i;
       
-      if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
+      if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error))
         goto failed;
       
       i = 0;
@@ -321,43 +320,39 @@ bus_policy_create_client_policy (BusPoli
 
       dbus_free (groups);
     }
-
-  if (!dbus_connection_get_unix_user (connection, &uid))
+  
+  if (dbus_connection_get_unix_user (connection, &uid))
     {
-      dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "No user ID known for connection, cannot determine security policy\n");
-      goto failed;
-    }
+      if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
+        {
+          DBusList **list;
+          
+          list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
+                                                uid);
+          
+          if (list != NULL)
+            {
+              if (!add_list_to_client (list, client))
+                goto nomem;
+            }
+        }
 
-  if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
-    {
-      DBusList **list;
+      /* Add console rules */
+      at_console = _dbus_unix_user_is_at_console (uid, error);
       
-      list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
-                                            uid);
-
-      if (list != NULL)
+      if (at_console)
         {
-          if (!add_list_to_client (list, client))
+          if (!add_list_to_client (&policy->at_console_true_rules, client))
             goto nomem;
         }
-    }
-
-  /* Add console rules */
-  at_console = _dbus_is_console_user (uid, error);
-
-  if (at_console)
-    {
-      if (!add_list_to_client (&policy->at_console_true_rules, client))
-        goto nomem;
-    }
-  else if (dbus_error_is_set (error) == TRUE)
-    {
-      goto failed;
-    }
-  else if (!add_list_to_client (&policy->at_console_false_rules, client))
-    {
-      goto nomem;
+      else if (dbus_error_is_set (error) == TRUE)
+        {
+          goto failed;
+        }
+      else if (!add_list_to_client (&policy->at_console_false_rules, client))
+        {
+          goto nomem;
+        }
     }
 
   if (!add_list_to_client (&policy->mandatory_rules,
@@ -438,23 +433,23 @@ list_allows_user (dbus_bool_t           
 }
 
 dbus_bool_t
-bus_policy_allow_user (BusPolicy        *policy,
-                       unsigned long     uid)
+bus_policy_allow_unix_user (BusPolicy        *policy,
+                            unsigned long     uid)
 {
   dbus_bool_t allowed;
   unsigned long *group_ids;
   int n_group_ids;
 
   /* On OOM or error we always reject the user */
-  if (!_dbus_groups_from_uid (uid, &group_ids, &n_group_ids))
+  if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids))
     {
       _dbus_verbose ("Did not get any groups for UID %lu\n",
                      uid);
       return FALSE;
     }
 
-  /* Default to "user owning bus" or root can connect */
-  allowed = uid == _dbus_getuid ();
+  /* Default to "user owning bus" can connect */
+  allowed = _dbus_unix_user_is_process_owner (uid);
 
   allowed = list_allows_user (allowed,
                               &policy->default_rules,
@@ -473,6 +468,23 @@ bus_policy_allow_user (BusPolicy        
   return allowed;
 }
 
+/* For now this is never actually called because the default
+ * DBusConnection behavior of 'same user that owns the bus can
+ * connect' is all it would do. Set the windows user function in
+ * connection.c if the config file ever supports doing something
+ * interesting here.
+ */
+dbus_bool_t
+bus_policy_allow_windows_user (BusPolicy        *policy,
+                               const char       *windows_sid)
+{
+  /* Windows has no policies here since only the session bus
+   * is really used for now, so just checking that the
+   * connecting person is the same as the bus owner is fine.
+   */
+  return _dbus_windows_user_is_process_owner (windows_sid);
+}
+
 dbus_bool_t
 bus_policy_append_default_rule (BusPolicy      *policy,
                                 BusPolicyRule  *rule)
Index: bus/policy.h
===================================================================
RCS file: /cvs/dbus/dbus/bus/policy.h,v
retrieving revision 1.18
diff -u -p -r1.18 policy.h
--- bus/policy.h	15 Mar 2007 13:27:01 -0000	1.18
+++ bus/policy.h	9 Jun 2007 23:40:49 -0000
@@ -113,8 +113,10 @@ void             bus_policy_unref       
 BusClientPolicy* bus_policy_create_client_policy  (BusPolicy        *policy,
                                                    DBusConnection   *connection,
                                                    DBusError        *error);
-dbus_bool_t      bus_policy_allow_user            (BusPolicy        *policy,
+dbus_bool_t      bus_policy_allow_unix_user       (BusPolicy        *policy,
                                                    unsigned long     uid);
+dbus_bool_t      bus_policy_allow_windows_user    (BusPolicy        *policy,
+                                                   const char       *windows_sid);
 dbus_bool_t      bus_policy_append_default_rule   (BusPolicy        *policy,
                                                    BusPolicyRule    *rule);
 dbus_bool_t      bus_policy_append_mandatory_rule (BusPolicy        *policy,
Index: dbus/dbus-connection.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.c,v
retrieving revision 1.154
diff -u -p -r1.154 dbus-connection.c
--- dbus/dbus-connection.c	15 Nov 2006 03:07:59 -0000	1.154
+++ dbus/dbus-connection.c	9 Jun 2007 23:40:53 -0000
@@ -4763,8 +4763,10 @@ dbus_connection_get_socket(DBusConnectio
 
 /**
  * Gets the UNIX user ID of the connection if known.  Returns #TRUE if
- * the uid is filled in.  Always returns #FALSE on non-UNIX platforms.
- * Always returns #FALSE prior to authenticating the connection.
+ * the uid is filled in.  Always returns #FALSE on non-UNIX platforms
+ * for now, though in theory someone could hook Windows to NIS or
+ * something.  Always returns #FALSE prior to authenticating the
+ * connection.
  *
  * The UID is only read by servers from clients; clients can't usually
  * get the UID of servers, because servers do not authenticate to
@@ -4789,14 +4791,6 @@ dbus_connection_get_unix_user (DBusConne
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (uid != NULL, FALSE);
-
-#ifdef DBUS_WIN
-  /* FIXME this should be done at a lower level, but it's kind of hard,
-   * just want to be sure we don't ship with this API returning
-   * some weird internal fake uid for 1.0
-   */
-  return FALSE;
-#endif
   
   CONNECTION_LOCK (connection);
 
@@ -4805,6 +4799,11 @@ dbus_connection_get_unix_user (DBusConne
   else
     result = _dbus_transport_get_unix_user (connection->transport,
                                             uid);
+
+#ifdef DBUS_WIN
+  _dbus_assert (!result);
+#endif
+  
   CONNECTION_UNLOCK (connection);
 
   return result;
@@ -4812,7 +4811,7 @@ dbus_connection_get_unix_user (DBusConne
 
 /**
  * Gets the process ID of the connection if any.
- * Returns #TRUE if the uid is filled in.
+ * Returns #TRUE if the pid is filled in.
  * Always returns #FALSE prior to authenticating the
  * connection.
  *
@@ -4828,14 +4827,6 @@ dbus_connection_get_unix_process_id (DBu
 
   _dbus_return_val_if_fail (connection != NULL, FALSE);
   _dbus_return_val_if_fail (pid != NULL, FALSE);
-
-#ifdef DBUS_WIN
-  /* FIXME this should be done at a lower level, but it's kind of hard,
-   * just want to be sure we don't ship with this API returning
-   * some weird internal fake uid for 1.0
-   */
-  return FALSE;
-#endif
   
   CONNECTION_LOCK (connection);
 
@@ -4844,6 +4835,10 @@ dbus_connection_get_unix_process_id (DBu
   else
     result = _dbus_transport_get_unix_process_id (connection->transport,
 						  pid);
+#ifdef DBUS_WIN
+  _dbus_assert (!result);
+#endif
+  
   CONNECTION_UNLOCK (connection);
 
   return result;
@@ -4858,14 +4853,13 @@ dbus_connection_get_unix_process_id (DBu
  *
  * If the function is set to #NULL (as it is by default), then
  * only the same UID as the server process will be allowed to
- * connect.
+ * connect. Also, root is always allowed to connect.
  *
  * On Windows, the function will be set and its free_data_function will
  * be invoked when the connection is freed or a new function is set.
  * However, the function will never be called, because there are
- * no UNIX user ids to pass to it.
- * 
- * @todo add a Windows API analogous to dbus_connection_set_unix_user_function()
+ * no UNIX user ids to pass to it, or at least none of the existing
+ * auth protocols would allow authenticating as a UNIX user on Windows.
  * 
  * @param connection the connection
  * @param function the predicate
@@ -4890,7 +4884,106 @@ dbus_connection_set_unix_user_function (
   CONNECTION_UNLOCK (connection);
 
   if (old_free_function != NULL)
-    (* old_free_function) (old_data);    
+    (* old_free_function) (old_data);
+}
+
+/**
+ * Gets the Windows user SID of the connection if known.  Returns
+ * #TRUE if the ID is filled in.  Always returns #FALSE on non-Windows
+ * platforms for now, though in theory someone could hook UNIX to
+ * Active Directory or something.  Always returns #FALSE prior to
+ * authenticating the connection.
+ *
+ * The user is only read by servers from clients; clients can't usually
+ * get the user of servers, because servers do not authenticate to
+ * clients. The returned user is the user the connection authenticated
+ * as.
+ *
+ * The message bus is a server and the apps connecting to the bus
+ * are clients.
+ *
+ * The returned user string has to be freed with dbus_free().
+ *
+ * The return value indicates whether the user SID is available;
+ * if it's available but we don't have the memory to copy it,
+ * then the return value is #TRUE and #NULL is given as the SID.
+ * 
+ * @todo We would like to be able to say "You can ask the bus to tell
+ * you the user of another connection though if you like; this is done
+ * with dbus_bus_get_windows_user()." But this has to be implemented
+ * in bus/driver.c and dbus/dbus-bus.c, and is pointless anyway
+ * since on Windows we only use the session bus for now.
+ *
+ * @param connection the connection
+ * @param windows_sid_p return location for an allocated copy of the user ID, or #NULL if no memory
+ * @returns #TRUE if user is available (returned value may be #NULL anyway if no memory)
+ */
+dbus_bool_t
+dbus_connection_get_windows_user (DBusConnection             *connection,
+                                  char                      **windows_sid_p)
+{
+  dbus_bool_t result;
+
+  _dbus_return_val_if_fail (connection != NULL, FALSE);
+  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
+  
+  CONNECTION_LOCK (connection);
+
+  if (!_dbus_transport_get_is_authenticated (connection->transport))
+    result = FALSE;
+  else
+    result = _dbus_transport_get_windows_user (connection->transport,
+                                               windows_sid_p);
+
+#ifdef DBUS_UNIX
+  _dbus_assert (!result);
+#endif
+  
+  CONNECTION_UNLOCK (connection);
+
+  return result;
+}
+
+/**
+ * Sets a predicate function used to determine whether a given user ID
+ * is allowed to connect. When an incoming connection has
+ * authenticated with a particular user ID, this function is called;
+ * if it returns #TRUE, the connection is allowed to proceed,
+ * otherwise the connection is disconnected.
+ *
+ * If the function is set to #NULL (as it is by default), then
+ * only the same user owning the server process will be allowed to
+ * connect.
+ *
+ * On UNIX, the function will be set and its free_data_function will
+ * be invoked when the connection is freed or a new function is set.
+ * However, the function will never be called, because there is no
+ * way right now to authenticate as a Windows user on UNIX.
+ * 
+ * @param connection the connection
+ * @param function the predicate
+ * @param data data to pass to the predicate
+ * @param free_data_function function to free the data
+ */
+void
+dbus_connection_set_windows_user_function (DBusConnection              *connection,
+                                           DBusAllowWindowsUserFunction function,
+                                           void                        *data,
+                                           DBusFreeFunction             free_data_function)
+{
+  void *old_data = NULL;
+  DBusFreeFunction old_free_function = NULL;
+
+  _dbus_return_if_fail (connection != NULL);
+  
+  CONNECTION_LOCK (connection);
+  _dbus_transport_set_windows_user_function (connection->transport,
+                                             function, data, free_data_function,
+                                             &old_data, &old_free_function);
+  CONNECTION_UNLOCK (connection);
+
+  if (old_free_function != NULL)
+    (* old_free_function) (old_data);
 }
 
 /**
Index: dbus/dbus-connection.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.h,v
retrieving revision 1.49
diff -u -p -r1.49 dbus-connection.h
--- dbus/dbus-connection.h	15 Nov 2006 03:07:59 -0000	1.49
+++ dbus/dbus-connection.h	9 Jun 2007 23:40:53 -0000
@@ -132,14 +132,28 @@ typedef void        (* DBusDispatchStatu
  * to do. Set with dbus_connection_set_wakeup_main_function().
  */
 typedef void        (* DBusWakeupMainFunction)     (void           *data);
+
 /**
- * Called during authentication on UNIX systems to check whether the given
- * user ID is allowed to connect. Never called on Windows. Set with
+ * Called during authentication to check whether the given UNIX user
+ * ID is allowed to connect, if the client tried to auth as a UNIX
+ * user ID. Normally on Windows this would never happen. Set with
  * dbus_connection_set_unix_user_function().
  */ 
 typedef dbus_bool_t (* DBusAllowUnixUserFunction)  (DBusConnection *connection,
                                                     unsigned long   uid,
                                                     void           *data);
+
+/**
+ * Called during authentication to check whether the given Windows user
+ * ID is allowed to connect, if the client tried to auth as a Windows
+ * user ID. Normally on UNIX this would never happen. Set with
+ * dbus_connection_set_windows_user_function().
+ */ 
+typedef dbus_bool_t (* DBusAllowWindowsUserFunction)  (DBusConnection *connection,
+                                                       const char     *user_sid,
+                                                       void           *data);
+
+
 /**
  * Called when a pending call now has a reply available. Set with
  * dbus_pending_call_set_notify().
@@ -219,6 +233,12 @@ void               dbus_connection_set_u
                                                                  DBusAllowUnixUserFunction   function,
                                                                  void                       *data,
                                                                  DBusFreeFunction            free_data_function);
+dbus_bool_t        dbus_connection_get_windows_user             (DBusConnection             *connection,
+                                                                 char                      **windows_sid_p); 
+void               dbus_connection_set_windows_user_function    (DBusConnection             *connection,
+                                                                 DBusAllowWindowsUserFunction function,
+                                                                 void                       *data,
+                                                                 DBusFreeFunction            free_data_function);
 void               dbus_connection_set_route_peer_messages      (DBusConnection             *connection,
                                                                  dbus_bool_t                 value);
 
Index: dbus/dbus-sysdeps-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-unix.c,v
retrieving revision 1.27
diff -u -p -r1.27 dbus-sysdeps-unix.c
--- dbus/dbus-sysdeps-unix.c	9 Jun 2007 21:53:18 -0000	1.27
+++ dbus/dbus-sysdeps-unix.c	9 Jun 2007 23:40:55 -0000
@@ -2916,4 +2916,17 @@ _dbus_get_standard_session_servicedirs (
   return FALSE;
 }
 
+/**
+ * Called when the bus daemon is signaled to reload its configuration; any
+ * caches should be nuked. Of course any caches that need explicit reload
+ * are probably broken, but c'est la vie.
+ *
+ * 
+ */
+void
+_dbus_flush_caches (void)
+{
+  _dbus_user_database_flush_system ();
+}
+
 /* tests in dbus-sysdeps-util.c */
Index: dbus/dbus-sysdeps-unix.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-unix.h,v
retrieving revision 1.4
diff -u -p -r1.4 dbus-sysdeps-unix.h
--- dbus/dbus-sysdeps-unix.h	9 Jun 2007 21:53:18 -0000	1.4
+++ dbus/dbus-sysdeps-unix.h	9 Jun 2007 23:40:55 -0000
@@ -120,8 +120,6 @@ dbus_bool_t _dbus_group_info_fill_gid (D
                                        DBusError        *error);
 void        _dbus_group_info_free     (DBusGroupInfo    *info);
 
-
-dbus_pid_t    _dbus_getpid (void);
 dbus_uid_t    _dbus_getuid (void);
 dbus_gid_t    _dbus_getgid (void);
 
Index: dbus/dbus-sysdeps-util-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps-util-unix.c,v
retrieving revision 1.15
diff -u -p -r1.15 dbus-sysdeps-util-unix.c
--- dbus/dbus-sysdeps-util-unix.c	9 Jun 2007 21:53:18 -0000	1.15
+++ dbus/dbus-sysdeps-util-unix.c	9 Jun 2007 23:40:56 -0000
@@ -780,6 +780,98 @@ _dbus_group_info_fill_gid (DBusGroupInfo
   return fill_group_info (info, gid, NULL, error);
 }
 
+/**
+ * Parse a UNIX user from the bus config file. On Windows, this should
+ * simply always fail (just return #FALSE).
+ *
+ * @param username the username text
+ * @param uid_p place to return the uid
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_parse_unix_user_from_config (const DBusString  *username,
+                                   dbus_uid_t        *uid_p)
+{
+  return _dbus_get_user_id (username, uid_p);
+
+}
+
+/**
+ * Parse a UNIX group from the bus config file. On Windows, this should
+ * simply always fail (just return #FALSE).
+ *
+ * @param groupname the groupname text
+ * @param gid_p place to return the gid
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+_dbus_parse_unix_group_from_config (const DBusString  *groupname,
+                                    dbus_gid_t        *gid_p)
+{
+  return _dbus_get_group_id (groupname, gid_p);
+}
+
+/**
+ * Gets all groups corresponding to the given UNIX user ID. On UNIX,
+ * just calls _dbus_groups_from_uid(). On Windows, should always
+ * fail since we don't know any UNIX groups.
+ *
+ * @param uid the UID
+ * @param group_ids return location for array of group IDs
+ * @param n_group_ids return location for length of returned array
+ * @returns #TRUE if the UID existed and we got some credentials
+ */
+dbus_bool_t
+_dbus_unix_groups_from_uid (dbus_uid_t            uid,
+                            dbus_gid_t          **group_ids,
+                            int                  *n_group_ids)
+{
+  return _dbus_groups_from_uid (uid, group_ids, n_group_ids);
+}
+
+/**
+ * Checks to see if the UNIX user ID is at the console.
+ * Should always fail on Windows (set the error to
+ * #DBUS_ERROR_NOT_SUPPORTED).
+ *
+ * @param uid UID of person to check 
+ * @param error return location for errors
+ * @returns #TRUE if the UID is the same as the console user and there are no errors
+ */
+dbus_bool_t
+_dbus_unix_user_is_at_console (dbus_uid_t         uid,
+                               DBusError         *error)
+{
+  return _dbus_is_console_user (uid, error);
+
+}
+
+/**
+ * Checks to see if the UNIX user ID matches the UID of
+ * the process. Should always return #FALSE on Windows.
+ *
+ * @param uid the UNIX user ID
+ * @returns #TRUE if this uid owns the process.
+ */
+dbus_bool_t
+_dbus_unix_user_is_process_owner (dbus_uid_t uid)
+{
+  return uid == _dbus_getuid ();
+}
+
+/**
+ * Checks to see if the Windows user SID matches the owner of
+ * the process. Should always return #FALSE on UNIX.
+ *
+ * @param windows_sid the Windows user SID
+ * @returns #TRUE if this user owns the process.
+ */
+dbus_bool_t
+_dbus_windows_user_is_process_owner (const char *windows_sid)
+{
+  return FALSE;
+}
+
 /** @} */ /* End of DBusInternalsUtils functions */
 
 /**
Index: dbus/dbus-sysdeps.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.h,v
retrieving revision 1.74
diff -u -p -r1.74 dbus-sysdeps.h
--- dbus/dbus-sysdeps.h	9 Jun 2007 21:53:20 -0000	1.74
+++ dbus/dbus-sysdeps.h	9 Jun 2007 23:40:56 -0000
@@ -173,6 +173,18 @@ dbus_bool_t _dbus_append_desired_identit
 dbus_bool_t _dbus_homedir_from_current_process  (const DBusString **homedir);
 dbus_bool_t _dbus_homedir_from_username         (const DBusString  *username,
                                                  DBusString        *homedir);
+dbus_bool_t _dbus_parse_unix_user_from_config   (const DBusString  *username,
+                                                 dbus_uid_t        *uid_p);
+dbus_bool_t _dbus_parse_unix_group_from_config  (const DBusString  *groupname,
+                                                 dbus_gid_t        *gid_p);
+dbus_bool_t _dbus_unix_groups_from_uid          (dbus_uid_t         uid,
+                                                 dbus_gid_t       **group_ids,
+                                                 int               *n_group_ids);
+dbus_bool_t _dbus_unix_user_is_at_console       (dbus_uid_t         uid,
+                                                 DBusError         *error);
+dbus_bool_t _dbus_unix_user_is_process_owner    (dbus_uid_t         uid);
+dbus_bool_t _dbus_windows_user_is_process_owner (const char        *windows_sid);
+
 
 /** Opaque type representing an atomically-modifiable integer
  * that can be used from multiple threads.
@@ -420,6 +432,14 @@ dbus_bool_t _dbus_split_paths_and_append
 
 unsigned long _dbus_pid_for_log (void);
 
+/* FIXME move back to dbus-sysdeps-unix.h probably -
+ * the PID file handling just needs a little more abstraction
+ * in the bus daemon first.
+ */
+dbus_pid_t    _dbus_getpid (void);
+
+void _dbus_flush_caches (void);
+
 /** @} */
 
 DBUS_END_DECLS
Index: dbus/dbus-test.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-test.c,v
retrieving revision 1.46
diff -u -p -r1.46 dbus-test.c
--- dbus/dbus-test.c	9 Jun 2007 21:53:20 -0000	1.46
+++ dbus/dbus-test.c	9 Jun 2007 23:40:56 -0000
@@ -161,8 +161,10 @@ dbus_internal_do_not_use_run_tests (cons
 #endif
   
   run_data_test ("credentials", specific_test, _dbus_credentials_test, test_data_dir);
-  
+
+#ifdef DBUS_UNIX
   run_data_test ("userdb", specific_test, _dbus_userdb_test, test_data_dir);
+#endif
   
   run_test ("keyring", specific_test, _dbus_keyring_test);
   
Index: dbus/dbus-transport-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-protected.h,v
retrieving revision 1.21
diff -u -p -r1.21 dbus-transport-protected.h
--- dbus/dbus-transport-protected.h	9 Jun 2007 21:53:20 -0000	1.21
+++ dbus/dbus-transport-protected.h	9 Jun 2007 23:40:56 -0000
@@ -104,6 +104,11 @@ struct DBusTransport
   void *unix_user_data;                         /**< Data for unix_user_function */
   
   DBusFreeFunction free_unix_user_data;         /**< Function to free unix_user_data */
+
+  DBusAllowWindowsUserFunction windows_user_function; /**< Function for checking whether a user is authorized. */
+  void *windows_user_data;                            /**< Data for windows_user_function */
+  
+  DBusFreeFunction free_windows_user_data;            /**< Function to free windows_user_data */
   
   unsigned int disconnected : 1;              /**< #TRUE if we are disconnected. */
   unsigned int authenticated : 1;             /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */
Index: dbus/dbus-transport.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v
retrieving revision 1.55
diff -u -p -r1.55 dbus-transport.c
--- dbus/dbus-transport.c	9 Jun 2007 21:53:20 -0000	1.55
+++ dbus/dbus-transport.c	9 Jun 2007 23:40:57 -0000
@@ -167,6 +167,10 @@ _dbus_transport_init_base (DBusTransport
   transport->unix_user_data = NULL;
   transport->free_unix_user_data = NULL;
 
+  transport->windows_user_function = NULL;
+  transport->windows_user_data = NULL;
+  transport->free_windows_user_data = NULL;
+  
   transport->expected_guid = NULL;
   
   /* Try to default to something that won't totally hose the system,
@@ -202,6 +206,9 @@ _dbus_transport_finalize_base (DBusTrans
 
   if (transport->free_unix_user_data != NULL)
     (* transport->free_unix_user_data) (transport->unix_user_data);
+
+  if (transport->free_windows_user_data != NULL)
+    (* transport->free_windows_user_data) (transport->windows_user_data);
   
   _dbus_message_loader_unref (transport->loader);
   _dbus_auth_unref (transport->auth);
@@ -491,12 +498,157 @@ _dbus_transport_get_is_connected (DBusTr
   return !transport->disconnected;
 }
 
+static dbus_bool_t
+auth_via_unix_user_function (DBusTransport *transport)
+{
+  DBusCredentials *auth_identity;
+  dbus_bool_t allow;
+  DBusConnection *connection;
+  DBusAllowUnixUserFunction unix_user_function;
+  void *unix_user_data;
+  dbus_uid_t uid;
+
+  /* Dropping the lock here probably isn't that safe. */
+  
+  auth_identity = _dbus_auth_get_identity (transport->auth);
+  _dbus_assert (auth_identity != NULL);
+
+  connection = transport->connection;
+  unix_user_function = transport->unix_user_function;
+  unix_user_data = transport->unix_user_data;
+  uid = _dbus_credentials_get_unix_uid (auth_identity),
+              
+    _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
+  _dbus_connection_unlock (connection);
+
+  allow = (* unix_user_function) (connection,
+                                  uid,
+                                  unix_user_data);
+              
+  _dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
+  _dbus_connection_lock (connection);
+
+  if (allow)
+    {
+      _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
+    }
+  else
+    {
+      _dbus_verbose ("Client UID "DBUS_UID_FORMAT
+                     " was rejected, disconnecting\n",
+                     _dbus_credentials_get_unix_uid (auth_identity));
+      _dbus_transport_disconnect (transport);
+    }
+
+  return allow;
+}
+
+static dbus_bool_t
+auth_via_windows_user_function (DBusTransport *transport)
+{
+  DBusCredentials *auth_identity;  
+  dbus_bool_t allow;
+  DBusConnection *connection;
+  DBusAllowWindowsUserFunction windows_user_function;
+  void *windows_user_data;
+  char *windows_sid;
+
+  /* Dropping the lock here probably isn't that safe. */
+  
+  auth_identity = _dbus_auth_get_identity (transport->auth);
+  _dbus_assert (auth_identity != NULL);
+
+  connection = transport->connection;
+  windows_user_function = transport->windows_user_function;
+  windows_user_data = transport->unix_user_data;
+  windows_sid = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
+
+  if (windows_sid == NULL)
+    {
+      /* OOM */
+      return FALSE;
+    }
+                
+  _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
+  _dbus_connection_unlock (connection);
+
+  allow = (* windows_user_function) (connection,
+                                     windows_sid,
+                                     windows_user_data);
+              
+  _dbus_verbose ("lock %s post windows user function\n", _DBUS_FUNCTION_NAME);
+  _dbus_connection_lock (connection);
+
+  if (allow)
+    {
+      _dbus_verbose ("Client SID '%s' authorized\n", windows_sid);
+    }
+  else
+    {
+      _dbus_verbose ("Client SID '%s' was rejected, disconnecting\n",
+                     _dbus_credentials_get_windows_sid (auth_identity));
+      _dbus_transport_disconnect (transport);
+    }
+
+  return allow;
+}
+
+static dbus_bool_t
+auth_via_default_rules (DBusTransport *transport)
+{
+  DBusCredentials *auth_identity;
+  DBusCredentials *our_identity;
+  dbus_bool_t allow;
+  
+  auth_identity = _dbus_auth_get_identity (transport->auth);
+  _dbus_assert (auth_identity != NULL);
+
+  /* By default, connection is allowed if the client is
+   * 1) root or 2) has the same UID as us
+   */
+              
+  our_identity = _dbus_credentials_new_from_current_process ();
+  if (our_identity == NULL)
+    {
+      /* OOM */
+      return FALSE;
+    }
+              
+  if (_dbus_credentials_get_unix_uid (auth_identity) == 0 ||
+      _dbus_credentials_same_user (our_identity,
+                                   auth_identity))
+    {
+      /* FIXME the verbose spam here is unix-specific */                  
+      _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
+                     " matching our UID "DBUS_UID_FORMAT"\n",
+                     _dbus_credentials_get_unix_uid(auth_identity),
+                     _dbus_credentials_get_unix_uid(our_identity));
+      /* We have authenticated! */
+      allow = TRUE;
+    }
+  else
+    {
+      /* FIXME the verbose spam here is unix-specific */
+      _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
+                     " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
+                     _dbus_credentials_get_unix_uid(our_identity),
+                     _dbus_credentials_get_unix_uid(our_identity));
+      _dbus_transport_disconnect (transport);
+      allow = FALSE;
+    }  
+
+  _dbus_credentials_unref (our_identity);
+  
+  return allow;
+}
+
+
 /**
  * Returns #TRUE if we have been authenticated.  Will return #TRUE
  * even if the transport is disconnected.
  *
  * @todo we drop connection->mutex when calling the unix_user_function,
- * which may not be safe really.
+ * and windows_user_function, which may not be safe really.
  *
  * @param transport the transport
  * @returns whether we're authenticated
@@ -532,6 +684,8 @@ _dbus_transport_get_is_authenticated (DB
             }
         }
 
+      /* If we're the client, verify the GUID
+       */
       if (maybe_authenticated && !transport->is_server)
         {
           const char *server_guid;
@@ -560,106 +714,40 @@ _dbus_transport_get_is_authenticated (DB
                 }
             }
         }
-      
-      /* If we've authenticated as some identity, check that the auth
-       * identity is the same as our own identity.  In the future, we
-       * may have API allowing applications to specify how this is
-       * done, for example they may allow connection as any identity,
-       * but then impose restrictions on certain identities.
-       * Or they may give certain identities extra privileges.
+
+      /* If we're the server, see if we want to allow this identity to proceed.
        */
-      
       if (maybe_authenticated && transport->is_server)
         {
+          dbus_bool_t allow;
           DBusCredentials *auth_identity;
-
+          
           auth_identity = _dbus_auth_get_identity (transport->auth);
           _dbus_assert (auth_identity != NULL);
-
-          /* If we have a UNIX user and a unix user function, delegate
-           * deciding whether auth credentials are good enough to the app;
-           * otherwise, use our default decision process.
+          
+          /* If we have an auth'd user and a user function, delegate
+           * deciding whether auth credentials are good enough to the
+           * app; otherwise, use our default decision process.
            */
           if (transport->unix_user_function != NULL &&
               _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_UNIX_USER_ID))
             {
-              dbus_bool_t allow;
-              DBusConnection *connection;
-              DBusAllowUnixUserFunction unix_user_function;
-              void *unix_user_data;
-              dbus_uid_t uid;
-              
-              /* Dropping the lock here probably isn't that safe. */
-
-              connection = transport->connection;
-              unix_user_function = transport->unix_user_function;
-              unix_user_data = transport->unix_user_data;
-              uid = _dbus_credentials_get_unix_uid (auth_identity),
-              
-              _dbus_verbose ("unlock %s\n", _DBUS_FUNCTION_NAME);
-              _dbus_connection_unlock (connection);
-
-              allow = (* unix_user_function) (connection,
-                                              uid,
-                                              unix_user_data);
-              
-              _dbus_verbose ("lock %s post unix user function\n", _DBUS_FUNCTION_NAME);
-              _dbus_connection_lock (connection);
-
-              if (allow)
-                {
-                  _dbus_verbose ("Client UID "DBUS_UID_FORMAT" authorized\n", uid);
-                }
-              else
-                {
-                  _dbus_verbose ("Client UID "DBUS_UID_FORMAT
-                                 " was rejected, disconnecting\n",
-                                 _dbus_credentials_get_unix_uid (auth_identity));
-                  _dbus_transport_disconnect (transport);
-                  _dbus_connection_unref_unlocked (connection);
-                  return FALSE;
-                }
+              allow = auth_via_unix_user_function (transport);
             }
+          else if (transport->windows_user_function != NULL &&
+                   _dbus_credentials_include (auth_identity, DBUS_CREDENTIAL_WINDOWS_SID))
+            {
+              allow = auth_via_windows_user_function (transport);
+            }      
           else
             {
-              DBusCredentials *our_identity;
-
-              /* By default, connection is allowed if the client is
-               * 1) root or 2) has the same UID as us
-               */
-              
-              our_identity = _dbus_credentials_new_from_current_process ();
-              if (our_identity == NULL)
-                {
-                  /* OOM */
-                  _dbus_connection_unref_unlocked (transport->connection);
-                  return FALSE;
-                }
-              
-              if (_dbus_credentials_get_unix_uid (auth_identity) == 0 ||
-                  !_dbus_credentials_same_user (our_identity,
-                                                auth_identity))
-                {
-                  /* FIXME the verbose spam here is unix-specific */
-                  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
-                                 " but our UID is "DBUS_UID_FORMAT", disconnecting\n",
-                                 _dbus_credentials_get_unix_uid(our_identity),
-                                 _dbus_credentials_get_unix_uid(our_identity));
-                  _dbus_transport_disconnect (transport);
-                  _dbus_connection_unref_unlocked (transport->connection);
-                  return FALSE;
-                }
-              else
-                {
-                  /* FIXME the verbose spam here is unix-specific */                  
-                  _dbus_verbose ("Client authorized as UID "DBUS_UID_FORMAT
-                                 " matching our UID "DBUS_UID_FORMAT"\n",
-                                 _dbus_credentials_get_unix_uid(auth_identity),
-                                 _dbus_credentials_get_unix_uid(our_identity));
-                }
+              allow = auth_via_default_rules (transport);
             }
+          
+          if (!allow)
+            maybe_authenticated = FALSE;
         }
-      
+
       transport->authenticated = maybe_authenticated;
 
       _dbus_connection_unref_unlocked (transport->connection);
@@ -1137,6 +1225,65 @@ _dbus_transport_set_unix_user_function (
 }
 
 /**
+ * See dbus_connection_get_windows_user().
+ *
+ * @param transport the transport
+ * @param windows_sid_p return location for the user ID
+ * @returns #TRUE if user is available; the returned value may still be #NULL if no memory to copy it
+ */
+dbus_bool_t
+_dbus_transport_get_windows_user (DBusTransport              *transport,
+                                  char                      **windows_sid_p)
+{
+  DBusCredentials *auth_identity;
+
+  *windows_sid_p = NULL;
+  
+  if (!transport->authenticated)
+    return FALSE;
+  
+  auth_identity = _dbus_auth_get_identity (transport->auth);
+
+  if (_dbus_credentials_include (auth_identity,
+                                 DBUS_CREDENTIAL_WINDOWS_SID))
+    {
+      /* If no memory, we are supposed to return TRUE and set NULL */
+      *windows_sid_p = _dbus_strdup (_dbus_credentials_get_windows_sid (auth_identity));
+
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/**
+ * See dbus_connection_set_windows_user_function().
+ *
+ * @param transport the transport
+ * @param function the predicate
+ * @param data data to pass to the predicate
+ * @param free_data_function function to free the data
+ * @param old_data the old user data to be freed
+ * @param old_free_data_function old free data function to free it with
+ */
+
+void
+_dbus_transport_set_windows_user_function (DBusTransport              *transport,
+                                           DBusAllowWindowsUserFunction   function,
+                                           void                       *data,
+                                           DBusFreeFunction            free_data_function,
+                                           void                      **old_data,
+                                           DBusFreeFunction           *old_free_data_function)
+{
+  *old_data = transport->windows_user_data;
+  *old_free_data_function = transport->free_windows_user_data;
+
+  transport->windows_user_function = function;
+  transport->windows_user_data = data;
+  transport->free_windows_user_data = free_data_function;
+}
+
+/**
  * Sets the SASL authentication mechanisms supported by this transport.
  *
  * @param transport the transport
Index: dbus/dbus-transport.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.h,v
retrieving revision 1.21
diff -u -p -r1.21 dbus-transport.h
--- dbus/dbus-transport.h	16 Sep 2006 17:38:24 -0000	1.21
+++ dbus/dbus-transport.h	9 Jun 2007 23:40:57 -0000
@@ -68,6 +68,14 @@ void               _dbus_transport_set_u
                                                            DBusFreeFunction            free_data_function,
                                                            void                      **old_data,
                                                            DBusFreeFunction           *old_free_data_function);
+dbus_bool_t        _dbus_transport_get_windows_user       (DBusTransport              *transport,
+                                                           char                      **windows_sid_p);
+void               _dbus_transport_set_windows_user_function (DBusTransport              *transport,
+                                                              DBusAllowWindowsUserFunction   function,
+                                                              void                       *data,
+                                                              DBusFreeFunction            free_data_function,
+                                                              void                      **old_data,
+                                                              DBusFreeFunction           *old_free_data_function);
 dbus_bool_t        _dbus_transport_set_auth_mechanisms    (DBusTransport              *transport,
                                                            const char                **mechanisms);
 

