+static uint
+get_ancestral_uid (uint pid)
+{
+ FILE *fp;
+ char buf [80];
+ int ppid = 0;
+ int uid = 0;
+ gboolean got_ppid = 0;
+ gboolean got_uid = 0;
+
+ sprintf (buf, "/proc/%d/status", pid);
+ fp = fopen (buf, "r");
+ if (!fp)
+ return 0;
+ while ((!got_ppid || !got_uid) && fgets (buf, sizeof (buf), fp))
+ {
+ if (sscanf (buf, "PPid:\t%d", &ppid) == 1)
+ got_ppid = TRUE;
+ else if (sscanf (buf, "Uid:\t%d", &uid) == 1)
+ got_uid = TRUE;
+ }
+ fclose (fp);
+
+ if (!got_ppid || !got_uid)
+ return 0;
+ if (uid != 0)
+ return uid;
+ if (ppid == 0 || ppid == 1)
+ return 0;
+ return get_ancestral_uid (ppid);
+}
+
+static dbus_bool_t
+user_check (DBusConnection *bus, unsigned long uid)
+{
+ if (uid == getuid () || uid == geteuid ())
+ return TRUE;
+ if (getuid () == 0)
+ return get_ancestral_uid (getpid ()) == uid;
+ return FALSE;
+}
+
+static void
+new_connection_cb (DBusServer *server, DBusConnection *con, void *data)
+{
+ GList *new_list;
+
+ dbus_connection_set_unix_user_function (con, user_check, NULL, NULL);
+ dbus_connection_ref(con);
+ dbus_connection_setup_with_g_main(con, NULL);
+ droute_intercept_dbus (con);
+ droute_context_register (spi_global_app_data->droute, con);
+
+ new_list = g_list_append (spi_global_app_data->direct_connections, con);
+ if (new_list)
+ spi_global_app_data->direct_connections = new_list;
+}
+
+static int
+setup_bus (void)
+{
+#ifndef DISABLE_P2P
+ DBusServer *server;
+ DBusError err;
+
+ dbus_error_init(&err);
+ server = dbus_server_listen(spi_global_app_data->app_bus_addr, &err);
+ if (server == NULL)
+ {
+ g_warning (_("atk-bridge: Couldn't listen on dbus server: %s"), err.message);
+ dbus_error_init (&err);
+ spi_global_app_data->app_bus_addr [0] = '\0';
+ g_main_context_unref (spi_global_app_data->main_context);
+ spi_global_app_data->main_context = NULL;
+ return -1;
+ }
+
+ dbus_server_setup_with_g_main(server, NULL);
+ dbus_server_set_new_connection_function(server, new_connection_cb, NULL, NULL);
+
+ spi_global_app_data->server = server;
+#endif
+
+ return 0;
+}
+
+