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; }
/** * 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; } }
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; }
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; }