Example #1
0
BusService*
bus_registry_ensure (BusRegistry               *registry,
                     const DBusString          *service_name,
                     DBusConnection            *owner_connection_if_created,
                     dbus_uint32_t              flags,
                     BusTransaction            *transaction,
                     DBusError                 *error)
{
  BusService *service;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  _dbus_assert (owner_connection_if_created != NULL);
  _dbus_assert (transaction != NULL);

  service = _dbus_hash_table_lookup_string (registry->service_hash,
                                            _dbus_string_get_const_data (service_name));
  if (service != NULL)
    return service;
  
  service = _dbus_mem_pool_alloc (registry->service_pool);
  if (service == NULL)
    {
      BUS_SET_OOM (error);
      return NULL;
    }

  service->registry = registry;  
  service->refcount = 1;

  _dbus_verbose ("copying string %p '%s' to service->name\n",
                 service_name, _dbus_string_get_const_data (service_name));
  if (!_dbus_string_copy_data (service_name, &service->name))
    {
      _dbus_mem_pool_dealloc (registry->service_pool, service);
      BUS_SET_OOM (error);
      return NULL;
    }
  _dbus_verbose ("copied string %p '%s' to '%s'\n",
                 service_name, _dbus_string_get_const_data (service_name),
                 service->name);

  if (!bus_driver_send_service_owner_changed (service->name, 
					      NULL,
					      bus_connection_get_name (owner_connection_if_created),
					      transaction, error))
    {
      bus_service_unref (service);
      return NULL;
    }

  if (!bus_activation_service_created (bus_context_get_activation (registry->context),
				       service->name, transaction, error))
    {
      bus_service_unref (service);
      return NULL;
    }
  
  if (!bus_service_add_owner (service, owner_connection_if_created, flags,
                                              transaction, error))
    {
      bus_service_unref (service);
      return NULL;
    }
  
  if (!_dbus_hash_table_insert_string (registry->service_hash,
                                       service->name,
                                       service))
    {
      /* The add_owner gets reverted on transaction cancel */
      BUS_SET_OOM (error);
      return NULL;
    }
  
  return service;
}
Example #2
0
/**
 * Looks up a gid or group name in the user database.  Only one of
 * name or GID can be provided. There are wrapper functions for this
 * that are better to use, this one does no locking or anything on the
 * database and otherwise sort of sucks.
 *
 * @param db the database
 * @param gid the group ID or #DBUS_GID_UNSET
 * @param groupname group name or #NULL 
 * @param error error to fill in
 * @returns the entry in the database
 */
DBusGroupInfo*
_dbus_user_database_lookup_group (DBusUserDatabase *db,
                                  dbus_gid_t        gid,
                                  const DBusString *groupname,
                                  DBusError        *error)
{
  DBusGroupInfo *info;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

   /* See if the group is really a number */
   if (gid == DBUS_UID_UNSET)
    {
      unsigned long n;

      if (_dbus_is_a_number (groupname, &n))
        gid = n;
    }

#ifdef DBUS_ENABLE_USERDB_CACHE
  if (gid != DBUS_GID_UNSET)
    info = _dbus_hash_table_lookup_ulong (db->groups, gid);
  else
    info = _dbus_hash_table_lookup_string (db->groups_by_name,
                                           _dbus_string_get_const_data (groupname));
  if (info)
    {
      _dbus_verbose ("Using cache for GID "DBUS_GID_FORMAT" information\n",
                     info->gid);
      return info;
    }
  else
#else
  if (1)
#endif
    {
      if (gid != DBUS_GID_UNSET)
	_dbus_verbose ("No cache for GID "DBUS_GID_FORMAT"\n",
		       gid);
      else
	_dbus_verbose ("No cache for groupname \"%s\"\n",
		       _dbus_string_get_const_data (groupname));
      
      info = dbus_new0 (DBusGroupInfo, 1);
      if (info == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }

      if (gid != DBUS_GID_UNSET)
        {
          if (!_dbus_group_info_fill_gid (info, gid, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_group_info_free_allocated (info);
              return NULL;
            }
        }
      else
        {
          if (!_dbus_group_info_fill (info, groupname, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_group_info_free_allocated (info);
              return NULL;
            }
        }

      /* don't use these past here */
      gid = DBUS_GID_UNSET;
      groupname = NULL;

      if (!_dbus_hash_table_insert_ulong (db->groups, info->gid, info))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          _dbus_group_info_free_allocated (info);
          return NULL;
        }


      if (!_dbus_hash_table_insert_string (db->groups_by_name,
                                           info->groupname,
                                           info))
        {
          _dbus_hash_table_remove_ulong (db->groups, info->gid);
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }
      
      return info;
    }
}
Example #3
0
static int
run_session (const char *dbus_daemon,
             const char *config_file,
             char       *bus_address,
             char      **argv,
             int         prog_arg)
{
  char *dbus_daemon_argv[3];
  int ret = 127;
  HANDLE server_handle = NULL;
  HANDLE app_handle = NULL;
  DWORD exit_code;
  DBusString argv_strings[4];
  DBusString address;
  char **env = NULL;
  DBusHashTable *env_table = NULL;
  long sec,usec;
  dbus_bool_t result = TRUE;
  char *key = NULL;
  char *value = NULL;

  if (!_dbus_string_init (&argv_strings[0]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[1]))
    result = FALSE;
  if (!_dbus_string_init (&argv_strings[2]))
    result = FALSE;
  if (!_dbus_string_init (&address))
    result = FALSE;
  if (!result)
    goto out;

  /* run dbus daemon */
  _dbus_get_real_time (&sec, &usec);
  /* On Windows it's difficult to make use of --print-address to
   * convert a listenable address into a connectable address, so instead
   * we tell the temporary dbus-daemon to use the Windows autolaunch
   * mechanism, with a unique scope that is shared by this dbus-daemon,
   * the app process that defines its lifetime, and any other child
   * processes they might have. */
  _dbus_string_append_printf (&address, "autolaunch:scope=dbus-tmp-session-%ld%ld-" DBUS_PID_FORMAT, sec, usec, _dbus_getpid ());
  _dbus_string_append_printf (&argv_strings[0], "%s", dbus_daemon);
  if (config_file != NULL)
    _dbus_string_append_printf (&argv_strings[1], "--config-file=%s", config_file);
  else
    _dbus_string_append_printf (&argv_strings[1], "--session");
  _dbus_string_append_printf (&argv_strings[2], "--address=%s", _dbus_string_get_const_data (&address));
  dbus_daemon_argv[0] = _dbus_string_get_data (&argv_strings[0]);
  dbus_daemon_argv[1] = _dbus_string_get_data (&argv_strings[1]);
  dbus_daemon_argv[2] = _dbus_string_get_data (&argv_strings[2]);
  dbus_daemon_argv[3] = NULL;

  server_handle = _dbus_spawn_program (dbus_daemon, dbus_daemon_argv, NULL);
  if (!server_handle)
    {
      _dbus_win_stderr_win_error (me, "Could not start dbus daemon", GetLastError ());
      goto out;
    }

  /* run app */
  env = _dbus_get_environment ();
  env_table = _dbus_hash_table_new (DBUS_HASH_STRING,
                                    dbus_free,
                                    dbus_free);
  if (!_dbus_hash_table_from_array (env_table, env, '='))
    {
      goto out;
    }

  /* replace DBUS_SESSION_BUS_ADDRESS in environment */
  if (!_dbus_string_steal_data (&address, &value))
    goto out;

  key = _dbus_strdup ("DBUS_SESSION_BUS_ADDRESS");

  if (key == NULL)
    goto out;

  if (_dbus_hash_table_insert_string (env_table, key, value))
    {
      /* env_table took ownership, do not free separately */
      key = NULL;
      value = NULL;
    }
  else
    {
      /* we still own key and value, the cleanup code will free them */
      goto out;
    }

  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_ADDRESS");
  _dbus_hash_table_remove_string (env_table, "DBUS_STARTER_BUS_TYPE");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_PID");
  _dbus_hash_table_remove_string (env_table, "DBUS_SESSION_BUS_WINDOWID");

  dbus_free_string_array (env);
  env = _dbus_hash_table_to_array (env_table, '=');
  if (!env)
    goto out;

  app_handle = _dbus_spawn_program (argv[prog_arg], argv + prog_arg, env);
  if (!app_handle)
    {
      _dbus_win_stderr_win_error (me, "unable to start child process", GetLastError ());
      goto out;
    }

  WaitForSingleObject (app_handle, INFINITE);
  if (!GetExitCodeProcess (app_handle, &exit_code))
    {
      _dbus_win_stderr_win_error (me, "could not fetch exit code", GetLastError ());
      goto out;
    }
  ret = exit_code;

out:
  TerminateProcess (server_handle, 0);
  if (server_handle != NULL)
    CloseHandle (server_handle);
  if (app_handle != NULL)
    CloseHandle (app_handle);
  _dbus_string_free (&argv_strings[0]);
  _dbus_string_free (&argv_strings[1]);
  _dbus_string_free (&argv_strings[2]);
  _dbus_string_free (&address);
  dbus_free_string_array (env);
  if (env_table != NULL)
    _dbus_hash_table_unref (env_table);
  dbus_free (key);
  dbus_free (value);
  return ret;
}
Example #4
0
DBusUserInfo*
_dbus_user_database_lookup (DBusUserDatabase *db,
                            dbus_uid_t        uid,
                            const DBusString *username,
                            DBusError        *error)
{
  DBusUserInfo *info;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  _dbus_assert (uid != DBUS_UID_UNSET || username != NULL);

  /* See if the username is really a number */
  if (uid == DBUS_UID_UNSET)
    {
      unsigned long n;

      if (_dbus_is_a_number (username, &n))
        uid = n;
    }

  if (uid != DBUS_UID_UNSET)
    info = _dbus_hash_table_lookup_ulong (db->users, uid);
  else
    info = _dbus_hash_table_lookup_string (db->users_by_name, _dbus_string_get_const_data (username));
  
  if (info)
    {
      _dbus_verbose ("Using cache for UID "DBUS_UID_FORMAT" information\n",
                     info->uid);
      return info;
    }
  else
    {
      if (uid != DBUS_UID_UNSET)
	_dbus_verbose ("No cache for UID "DBUS_UID_FORMAT"\n",
		       uid);
      else
	_dbus_verbose ("No cache for user \"%s\"\n",
		       _dbus_string_get_const_data (username));
      
      info = dbus_new0 (DBusUserInfo, 1);
      if (info == NULL)
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }

      if (uid != DBUS_UID_UNSET)
        {
          if (!_dbus_user_info_fill_uid (info, uid, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_user_info_free_allocated (info);
              return NULL;
            }
        }
      else
        {
          if (!_dbus_user_info_fill (info, username, error))
            {
              _DBUS_ASSERT_ERROR_IS_SET (error);
              _dbus_user_info_free_allocated (info);
              return NULL;
            }
        }

      /* be sure we don't use these after here */
      uid = DBUS_UID_UNSET;
      username = NULL;

      /* insert into hash */
      if (!_dbus_hash_table_insert_ulong (db->users, info->uid, info))
        {
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          _dbus_user_info_free_allocated (info);
          return NULL;
        }

      if (!_dbus_hash_table_insert_string (db->users_by_name,
                                           info->username,
                                           info))
        {
          _dbus_hash_table_remove_ulong (db->users, info->uid);
          dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
          return NULL;
        }
      
      return info;
    }
}
/**
 * Creates a new debug server using an in-process pipe
 *
 * @param server_name the name of the server.
 * @param error address where an error can be returned.
 * @returns a new server, or #NULL on failure.
 */
DBusServer*
_dbus_server_debug_pipe_new (const char     *server_name,
                             DBusError      *error)
{
    DBusServerDebugPipe *debug_server;
    DBusString address;
    DBusString name_str;

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (!pipe_hash_ref ())
        return NULL;

    if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL)
    {
        dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL);
        pipe_hash_unref ();
        return NULL;
    }

    debug_server = dbus_new0 (DBusServerDebugPipe, 1);
    if (debug_server == NULL)
        goto nomem_0;

    if (!_dbus_string_init (&address))
        goto nomem_1;

    _dbus_string_init_const (&name_str, server_name);
    if (!_dbus_string_append (&address, "debug-pipe:name=") ||
            !_dbus_address_append_escaped (&address, &name_str))
        goto nomem_2;

    debug_server->name = _dbus_strdup (server_name);
    if (debug_server->name == NULL)
        goto nomem_2;

    if (!_dbus_server_init_base (&debug_server->base,
                                 &debug_vtable, &address))
        goto nomem_3;

    if (!_dbus_hash_table_insert_string (server_pipe_hash,
                                         debug_server->name,
                                         debug_server))
        goto nomem_4;

    _dbus_string_free (&address);

    /* server keeps the pipe hash ref */

    return (DBusServer *)debug_server;

nomem_4:
    _dbus_server_finalize_base (&debug_server->base);
nomem_3:
    dbus_free (debug_server->name);
nomem_2:
    _dbus_string_free (&address);
nomem_1:
    dbus_free (debug_server);
nomem_0:
    pipe_hash_unref ();
    dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
    return NULL;
}