static void string_squash_nonprintable (DBusString *str) { unsigned char *buf; int i, len; buf = _dbus_string_get_data (str); len = _dbus_string_get_length (str); for (i = 0; i < len; i++) { unsigned char c = (unsigned char) buf[i]; if (c == '\0') buf[i] = ' '; else if (c < 0x20 || c > 127) buf[i] = '?'; } }
static dbus_bool_t delimit_token (DBusString *token, DBusList **retval, DBusError *error) { char *str; str = _dbus_strdup (_dbus_string_get_data (token)); if (!str) { _DBUS_SET_OOM (error); return FALSE; } if (!_dbus_list_append (retval, str)) { dbus_free (str); _DBUS_SET_OOM (error); return FALSE; } return TRUE; }
static char * get_test_exec (const char *exe, DBusString *scratch_space) { const char *dbus_test_exec; dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC"); if (dbus_test_exec == NULL) dbus_test_exec = DBUS_TEST_EXEC; if (!_dbus_string_init (scratch_space)) return NULL; if (!_dbus_string_append_printf (scratch_space, "%s/%s%s", dbus_test_exec, exe, DBUS_EXEEXT)) { _dbus_string_free (scratch_space); return NULL; } return _dbus_string_get_data (scratch_space); }
static dbus_bool_t handle_reload_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusError error; DBusString str; char *action_str; char action = '\0'; while (!_dbus_string_init (&str)) _dbus_wait_for_memory (); if ((reload_pipe[RELOAD_READ_END] > 0) && _dbus_read_socket (reload_pipe[RELOAD_READ_END], &str, 1) != 1) { _dbus_warn ("Couldn't read from reload pipe.\n"); close_reload_pipe (&watch); return TRUE; } action_str = _dbus_string_get_data (&str); if (action_str != NULL) { action = action_str[0]; } _dbus_string_free (&str); /* this can only fail if we don't understand the config file * or OOM. Either way we should just stick with the currently * loaded config. */ dbus_error_init (&error); switch (action) { case ACTION_RELOAD: if (! bus_context_reload_config (context, &error)) { _DBUS_ASSERT_ERROR_IS_SET (&error); _dbus_assert (dbus_error_has_name (&error, DBUS_ERROR_FAILED) || dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)); _dbus_warn ("Unable to reload configuration: %s\n", error.message); dbus_error_free (&error); } break; case ACTION_QUIT: { DBusLoop *loop; /* * On OSs without abstract sockets, we want to quit * gracefully rather than being killed by SIGTERM, * so that DBusServer gets a chance to clean up the * sockets from the filesystem. fd.o #38656 */ loop = bus_context_get_loop (context); if (loop != NULL) { _dbus_loop_quit (loop); } } break; default: break; } return TRUE; }
static BusDesktopFile * desktop_file_for_name (BusConfigParser *parser, const char *name, DBusError *error) { BusDesktopFile *desktop_file; DBusList **service_dirs; DBusList *link; DBusError tmp_error; DBusString full_path; DBusString filename; const char *dir; _DBUS_ASSERT_ERROR_IS_CLEAR (error); desktop_file = NULL; if (!_dbus_string_init (&filename)) { BUS_SET_OOM (error); goto out_all; } if (!_dbus_string_init (&full_path)) { BUS_SET_OOM (error); goto out_filename; } if (!_dbus_string_append (&filename, name) || !_dbus_string_append (&filename, ".service")) { BUS_SET_OOM (error); goto out; } service_dirs = bus_config_parser_get_service_dirs (parser); for (link = _dbus_list_get_first_link (service_dirs); link != NULL; link = _dbus_list_get_next_link (service_dirs, link)) { dir = link->data; _dbus_verbose ("Looking at '%s'\n", dir); dbus_error_init (&tmp_error); /* clear the path from last time */ _dbus_string_set_length (&full_path, 0); /* build the full path */ if (!_dbus_string_append (&full_path, dir) || !_dbus_concat_dir_and_file (&full_path, &filename)) { BUS_SET_OOM (error); goto out; } _dbus_verbose ("Trying to load file '%s'\n", _dbus_string_get_data (&full_path)); desktop_file = bus_desktop_file_load (&full_path, &tmp_error); if (desktop_file == NULL) { _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); _dbus_verbose ("Could not load %s: %s: %s\n", _dbus_string_get_const_data (&full_path), tmp_error.name, tmp_error.message); /* we may have failed if the file is not found; this is not fatal */ if (dbus_error_has_name (&tmp_error, DBUS_ERROR_NO_MEMORY)) { dbus_move_error (&tmp_error, error); /* we only bail out on OOM */ goto out; } dbus_error_free (&tmp_error); } /* did we find the desktop file we want? */ if (desktop_file != NULL) break; } /* Didn't find desktop file; set error */ if (desktop_file == NULL) { dbus_set_error (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND, "The name %s was not provided by any .service files", name); } out: _dbus_string_free (&full_path); out_filename: _dbus_string_free (&filename); out_all: return desktop_file; }
static dbus_bool_t test_command_line (const char *arg1, ...) { int i, original_argc, shell_argc; char **shell_argv; char **original_argv; char *command_line, *tmp; DBusString str; DBusList *list = NULL, *node; va_list var_args; DBusError error; va_start (var_args, arg1); _dbus_list_append (&list, (char *)arg1); do { tmp = va_arg (var_args, char *); if (!tmp) break; _dbus_list_append (&list, tmp); } while (tmp); va_end (var_args); original_argc = _dbus_list_get_length (&list); original_argv = dbus_new (char *, original_argc); _dbus_string_init (&str); for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node; i++, node = _dbus_list_get_next_link (&list, node)) { original_argv[i] = node->data; if (i > 0) _dbus_string_append_byte (&str, ' '); _dbus_string_append (&str, original_argv[i]); } _dbus_list_clear (&list); command_line = _dbus_string_get_data (&str); printf ("\n\nTesting command line '%s'\n", command_line); dbus_error_init (&error); if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error)) { fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : ""); return FALSE; } else { if (shell_argc != original_argc) { printf ("Number of arguments returned (%d) don't match original (%d)\n", shell_argc, original_argc); return FALSE; } printf ("Number of arguments: %d\n", shell_argc); for (i = 0; i < shell_argc; i++) { char *unquoted; unquoted = _dbus_shell_unquote (original_argv[i]); if (strcmp (unquoted ? unquoted : "", shell_argv[i] ? shell_argv[i] : "")) { printf ("Position %d, returned argument (%s) does not match original (%s)\n", i, shell_argv[i], unquoted); dbus_free (unquoted); return FALSE; } dbus_free (unquoted); if (shell_argv[i]) printf ("Argument %d = %s\n", i, shell_argv[i]); } dbus_free_string_array (shell_argv); } _dbus_string_free (&str); return TRUE; }
/** * Unquotes a string as the shell (/bin/sh) would. Only handles * quotes; if a string contains file globs, arithmetic operators, * variables, backticks, redirections, or other special-to-the-shell * features, the result will be different from the result a real shell * would produce (the variables, backticks, etc. will be passed * through literally instead of being expanded). This function is * guaranteed to succeed if applied to the result of * _dbus_shell_quote(). If it fails, it returns %NULL. * The @quoted_string need not actually contain quoted or * escaped text; _dbus_shell_unquote() simply goes through the string and * unquotes/unescapes anything that the shell would. Both single and * double quotes are handled, as are escapes including escaped * newlines. The return value must be freed with dbus_free(). * * Shell quoting rules are a bit strange. Single quotes preserve the * literal string exactly. escape sequences are not allowed; not even * \' - if you want a ' in the quoted text, you have to do something * like 'foo'\''bar'. Double quotes allow $, `, ", \, and newline to * be escaped with backslash. Otherwise double quotes preserve things * literally. * * @quoted_string: shell-quoted string **/ char* _dbus_shell_unquote (const char *quoted_string) { char *unquoted; char *end; char *start; char *ret; DBusString retval; unquoted = _dbus_strdup (quoted_string); if (unquoted == NULL) return NULL; start = unquoted; end = unquoted; if (!_dbus_string_init (&retval)) { dbus_free (unquoted); return NULL; } /* The loop allows cases such as * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo' */ while (*start) { /* Append all non-quoted chars, honoring backslash escape */ while (*start && !(*start == '"' || *start == '\'')) { if (*start == '\\') { /* all characters can get escaped by backslash, * except newline, which is removed if it follows * a backslash outside of quotes */ ++start; if (*start) { if (*start != '\n') { if (!_dbus_string_append_byte (&retval, *start)) goto error; } ++start; } } else { if (!_dbus_string_append_byte (&retval, *start)) goto error; ++start; } } if (*start) { if (!unquote_string_inplace (start, &end)) goto error; else { if (!_dbus_string_append (&retval, start)) goto error; start = end; } } } ret = _dbus_strdup (_dbus_string_get_data (&retval)); if (!ret) goto error; dbus_free (unquoted); _dbus_string_free (&retval); return ret; error: dbus_free (unquoted); _dbus_string_free (&retval); return NULL; }
/** * @ingroup DBusStringInternals * Unit test for DBusString. * * @todo Need to write tests for _dbus_string_copy() and * _dbus_string_move() moving to/from each of start/middle/end of a * string. Also need tests for _dbus_string_move_len () * * @returns #TRUE on success. */ dbus_bool_t _dbus_string_test (void) { DBusString str; DBusString other; int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; dbus_unichar_t ch; i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); test_max_len (&str, lens[i]); _dbus_string_free (&str); ++i; } /* Test shortening and setting length */ i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { int j; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); j = lens[i]; while (j > 0) { _dbus_assert (_dbus_string_get_length (&str) == j); if (j > 0) { _dbus_string_shorten (&str, 1); _dbus_assert (_dbus_string_get_length (&str) == (j - 1)); } --j; } _dbus_string_free (&str); ++i; } /* Test equality */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("oom"); _dbus_string_init_const (&other, "H"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1)); _dbus_string_init_const (&other, "Hello"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5)); _dbus_string_init_const (&other, "World"); _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11)); _dbus_string_free (&str); /* Test appending data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); i = 0; while (i < 10) { if (!_dbus_string_append (&str, "a")) _dbus_assert_not_reached ("failed to append string to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); if (!_dbus_string_append_byte (&str, 'b')) _dbus_assert_not_reached ("failed to append byte to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); ++i; } _dbus_string_free (&str); /* Check steal_data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_steal_data (&str, &s)) _dbus_assert_not_reached ("failed to steal data"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (((int)strlen (s)) == i); dbus_free (s); /* Check move */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_move (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 2); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_string_free (&other); /* Check copy */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_copy (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello World")); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello WorldHello World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check replace */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 0, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not replace"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 5, 1)) _dbus_assert_not_reached ("could not replace center space"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorld")); if (!_dbus_string_replace_len (&str, 1, 1, &other, _dbus_string_get_length (&other) - 1, 1)) _dbus_assert_not_reached ("could not replace end character"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check append/get unichar */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); ch = 0; if (!_dbus_string_append_unichar (&str, 0xfffc)) _dbus_assert_not_reached ("failed to append unichar"); _dbus_string_get_unichar (&str, 0, &ch, &i); _dbus_assert (ch == 0xfffc); _dbus_assert (i == _dbus_string_get_length (&str)); _dbus_string_free (&str); /* Check insert/set/get byte */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("failed to append Hello"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o'); _dbus_string_set_byte (&str, 1, 'q'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q'); if (!_dbus_string_insert_bytes (&str, 0, 1, 255)) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) _dbus_assert_not_reached ("can't insert byte"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 255); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q'); _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o'); _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W'); _dbus_string_free (&str); /* Check append/parse int/double */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_int (&str, 27)) _dbus_assert_not_reached ("failed to append int"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_int (&str, 0, &v, &end)) _dbus_assert_not_reached ("failed to parse int"); _dbus_assert (v == 27); _dbus_assert (end == i); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_double (&str, 50.3)) _dbus_assert_not_reached ("failed to append float"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_double (&str, 0, &d, &end)) _dbus_assert_not_reached ("failed to parse float"); _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6)); _dbus_assert (end == i); _dbus_string_free (&str); /* Test find */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("couldn't append to string"); if (!_dbus_string_find (&str, 0, "He", &i)) _dbus_assert_not_reached ("didn't find 'He'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "Hello", &i)) _dbus_assert_not_reached ("didn't find 'Hello'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "ello", &i)) _dbus_assert_not_reached ("didn't find 'ello'"); _dbus_assert (i == 1); if (!_dbus_string_find (&str, 0, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (!_dbus_string_find (&str, 2, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (_dbus_string_find (&str, 4, "lo", &i)) _dbus_assert_not_reached ("did find 'lo'"); if (!_dbus_string_find (&str, 0, "l", &i)) _dbus_assert_not_reached ("didn't find 'l'"); _dbus_assert (i == 2); if (!_dbus_string_find (&str, 0, "H", &i)) _dbus_assert_not_reached ("didn't find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "", &i)) _dbus_assert_not_reached ("didn't find ''"); _dbus_assert (i == 0); if (_dbus_string_find (&str, 0, "Hello!", NULL)) _dbus_assert_not_reached ("Did find 'Hello!'"); if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) _dbus_assert_not_reached ("Did find 'Oh, Hello'"); if (_dbus_string_find (&str, 0, "ill", NULL)) _dbus_assert_not_reached ("Did find 'ill'"); if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) _dbus_assert_not_reached ("Didn't find 'He'"); if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) _dbus_assert_not_reached ("Did not find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) _dbus_assert_not_reached ("Did not find 'o'"); _dbus_assert (i == _dbus_string_get_length (&str) - 1); if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) _dbus_assert_not_reached ("Did find 'o'"); _dbus_assert (i == -1); if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) _dbus_assert_not_reached ("Did find 'e'"); _dbus_assert (i == -1); if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) _dbus_assert_not_reached ("Didn't find 'e'"); _dbus_assert (i == 1); _dbus_string_free (&str); /* Hex encoding */ _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) _dbus_assert_not_reached ("deccoded bogus hex string with no error"); _dbus_assert (end == 8); _dbus_string_free (&other); test_roundtrips (test_hex_roundtrip); _dbus_string_free (&str); { int found, found_len; _dbus_string_init_const (&str, "012\r\n567\n90"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) _dbus_assert_not_reached ("Did not find '\\r\\n'"); if (found != 3 || found_len != 2) _dbus_assert_not_reached ("invalid return values"); if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) _dbus_assert_not_reached ("Did not find '\\n'"); if (found != 8 || found_len != 1) _dbus_assert_not_reached ("invalid return values"); if (_dbus_string_find_eol (&str, 9, &found, &found_len)) _dbus_assert_not_reached ("Found not expected '\\n'"); else if (found != 11 || found_len != 0) _dbus_assert_not_reached ("invalid return values '\\n'"); found = -1; found_len = -1; _dbus_string_init_const (&str, ""); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found an eol in an empty string"); _dbus_assert (found == 0); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar"); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found eol in string that lacks one"); _dbus_assert (found == 6); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar\n"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("did not find eol in string that has one at end"); _dbus_assert (found == 6); _dbus_assert (found_len == 1); } { DBusString line; #define FIRST_LINE "this is a line" #define SECOND_LINE "this is a second line" /* third line is empty */ #define THIRD_LINE "" #define FOURTH_LINE "this is a fourth line" if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&line)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop first line"); _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop second line"); _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop third line"); _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop fourth line"); _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); _dbus_string_free (&str); _dbus_string_free (&line); } { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); for (i = 0; i < 10000; i++) if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_set_length (&str, 10)) _dbus_assert_not_reached ("failed to set length"); /* actually compact */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact after set_length"); /* peek inside to make sure it worked */ if (((DBusRealString *)&str)->allocated > 30) _dbus_assert_not_reached ("compacting string didn't do anything"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after compact"); /* compact nothing */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact 2nd time"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after 2nd compact"); /* and make sure it still works...*/ if (!_dbus_string_append (&str, "123456")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content after append"); /* after growing automatically, this should do nothing */ if (!_dbus_string_compact (&str, 20000)) _dbus_assert_not_reached ("failed to compact after grow"); /* but this one will do something */ if (!_dbus_string_compact (&str, 0)) _dbus_assert_not_reached ("failed to compact after grow"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content"); if (!_dbus_string_append (&str, "!@#$%")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) _dbus_assert_not_reached ("unexpected content"); _dbus_string_free (&str); } { const char two_strings[] = "one\ttwo"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, two_strings)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_split_on_byte (&str, '\t', &other)) _dbus_assert_not_reached ("no memory or delimiter not found"); if (strcmp (_dbus_string_get_data (&str), "one") != 0) _dbus_assert_not_reached ("left side after split on tab is wrong"); if (strcmp (_dbus_string_get_data (&other), "two") != 0) _dbus_assert_not_reached ("right side after split on tab is wrong"); _dbus_string_free (&str); _dbus_string_free (&other); } return TRUE; }
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; }
/** * Check if Apparmor security controls allow the message to be sent to a * particular connection based on the security context of the sender and * that of the receiver. The destination connection need not be the * addressed recipient, it could be an "eavesdropper" * * @param sender the sender of the message. * @param proposed_recipient the connection the message is to be sent to. * @param requested_reply TRUE if the message is a reply requested by * proposed_recipient * @param bustype name of the bus * @param msgtype message type (DBUS_MESSAGE_TYPE_METHOD_CALL, etc.) * @param path object path the message should be sent to * @param interface the type of the object instance * @param member the member of the object * @param error_name the name of the error if the message type is error * @param destination name that the message should be sent to * @param source name that the message should be sent from * @param error the reason for failure when FALSE is returned * @returns TRUE if the message is permitted */ dbus_bool_t bus_apparmor_allows_send (DBusConnection *sender, DBusConnection *proposed_recipient, dbus_bool_t requested_reply, const char *bustype, int msgtype, const char *path, const char *interface, const char *member, const char *error_name, const char *destination, const char *source, BusActivationEntry *activation_entry, DBusError *error) { #ifdef HAVE_APPARMOR BusAppArmorConfinement *src_con = NULL, *dst_con = NULL; DBusString qstr, auxdata; int src_allow = FALSE, dst_allow = FALSE; int src_audit = TRUE, dst_audit = TRUE; dbus_bool_t free_auxdata = FALSE; unsigned long pid; int len, res, src_errno = 0, dst_errno = 0; uint32_t src_perm = AA_DBUS_SEND, dst_perm = AA_DBUS_RECEIVE; const char *msgtypestr = dbus_message_type_to_string(msgtype); const char *dst_label = NULL; const char *dst_mode = NULL; if (!apparmor_enabled) return TRUE; _dbus_assert (sender != NULL); src_con = bus_connection_dup_apparmor_confinement (sender); if (proposed_recipient) { dst_con = bus_connection_dup_apparmor_confinement (proposed_recipient); } else if (activation_entry != NULL) { dst_label = bus_activation_entry_get_assumed_apparmor_label (activation_entry); } else { dst_con = bus_con; bus_apparmor_confinement_ref (dst_con); } if (dst_con != NULL) { dst_label = dst_con->label; dst_mode = dst_con->mode; } /* map reply messages to initial send and receive permission. That is * permission to receive a message from X grants permission to reply to X. * And permission to send a message to Y grants permission to receive a reply * from Y. Note that this only applies to requested replies. Unrequested * replies still require a policy query. */ if (requested_reply) { /* ignore requested reply messages and let dbus reply mapping handle them * as the send was already allowed */ src_allow = TRUE; dst_allow = TRUE; goto out; } if (is_unconfined (src_con->label, src_con->mode)) { src_allow = TRUE; src_audit = FALSE; } else { if (!_dbus_string_init (&qstr)) goto oom; if (!build_message_query (&qstr, src_con->label, bustype, destination, dst_label, path, interface, member)) { _dbus_string_free (&qstr); goto oom; } res = aa_query_label (src_perm, _dbus_string_get_data (&qstr), _dbus_string_get_length (&qstr), &src_allow, &src_audit); _dbus_string_free (&qstr); if (res == -1) { src_errno = errno; set_error_from_query_errno (error, src_errno); goto audit; } } /* When deciding whether we can activate a service, we only check that * we are allowed to send a message to it, not that it is allowed to * receive that message from us. */ if (activation_entry != NULL || is_unconfined (dst_label, dst_mode)) { dst_allow = TRUE; dst_audit = FALSE; } else { if (!_dbus_string_init (&qstr)) goto oom; if (!build_message_query (&qstr, dst_label, bustype, source, src_con->label, path, interface, member)) { _dbus_string_free (&qstr); goto oom; } res = aa_query_label (dst_perm, _dbus_string_get_data (&qstr), _dbus_string_get_length (&qstr), &dst_allow, &dst_audit); _dbus_string_free (&qstr); if (res == -1) { dst_errno = errno; set_error_from_query_errno (error, dst_errno); goto audit; } } /* Don't fail operations on profiles in complain mode */ if (modestr_is_complain (src_con->mode)) src_allow = TRUE; if (modestr_is_complain (dst_mode)) dst_allow = TRUE; if (!src_allow || !dst_allow) set_error_from_denied_message (error, sender, proposed_recipient, requested_reply, msgtypestr, path, interface, member, error_name, destination); /* Don't audit the message if one of the following conditions is true: * 1) The AppArmor query indicates that auditing should not happen. * 2) The message is a reply type. Reply message are not audited because * the AppArmor policy language does not have the notion of a reply * message. Unrequested replies will be silently discarded if the sender * does not have permission to send to the receiver or if the receiver * does not have permission to receive from the sender. */ if ((!src_audit && !dst_audit) || (msgtype == DBUS_MESSAGE_TYPE_METHOD_RETURN || msgtype == DBUS_MESSAGE_TYPE_ERROR)) goto out; audit: if (!_dbus_string_init (&auxdata)) goto oom; free_auxdata = TRUE; if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown")) goto oom; if (path && !_dbus_append_pair_str (&auxdata, "path", path)) goto oom; if (interface && !_dbus_append_pair_str (&auxdata, "interface", interface)) goto oom; if (member && !_dbus_append_pair_str (&auxdata, "member", member)) goto oom; if (error_name && !_dbus_append_pair_str (&auxdata, "error_name", error_name)) goto oom; len = _dbus_string_get_length (&auxdata); if (src_audit) { if (!_dbus_append_mask (&auxdata, src_perm)) goto oom; if (destination && !_dbus_append_pair_str (&auxdata, "name", destination)) goto oom; if (sender && dbus_connection_get_unix_process_id (sender, &pid) && !_dbus_append_pair_uint (&auxdata, "pid", pid)) goto oom; if (src_con->label && !_dbus_append_pair_str (&auxdata, "label", src_con->label)) goto oom; if (proposed_recipient && dbus_connection_get_unix_process_id (proposed_recipient, &pid) && !_dbus_append_pair_uint (&auxdata, "peer_pid", pid)) goto oom; if (dst_label && !_dbus_append_pair_str (&auxdata, "peer_label", dst_label)) goto oom; if (src_errno && !_dbus_append_pair_str (&auxdata, "info", strerror (src_errno))) goto oom; if (dst_errno && !_dbus_append_pair_str (&auxdata, "peer_info", strerror (dst_errno))) goto oom; log_message (src_allow, msgtypestr, &auxdata); } if (dst_audit) { _dbus_string_set_length (&auxdata, len); if (source && !_dbus_append_pair_str (&auxdata, "name", source)) goto oom; if (!_dbus_append_mask (&auxdata, dst_perm)) goto oom; if (proposed_recipient && dbus_connection_get_unix_process_id (proposed_recipient, &pid) && !_dbus_append_pair_uint (&auxdata, "pid", pid)) goto oom; if (dst_label && !_dbus_append_pair_str (&auxdata, "label", dst_label)) goto oom; if (sender && dbus_connection_get_unix_process_id (sender, &pid) && !_dbus_append_pair_uint (&auxdata, "peer_pid", pid)) goto oom; if (src_con->label && !_dbus_append_pair_str (&auxdata, "peer_label", src_con->label)) goto oom; if (dst_errno && !_dbus_append_pair_str (&auxdata, "info", strerror (dst_errno))) goto oom; if (src_errno && !_dbus_append_pair_str (&auxdata, "peer_info", strerror (src_errno))) goto oom; log_message (dst_allow, msgtypestr, &auxdata); } out: if (src_con != NULL) bus_apparmor_confinement_unref (src_con); if (dst_con != NULL) bus_apparmor_confinement_unref (dst_con); if (free_auxdata) _dbus_string_free (&auxdata); return src_allow && dst_allow; oom: if (error != NULL && !dbus_error_is_set (error)) BUS_SET_OOM (error); src_allow = FALSE; dst_allow = FALSE; goto out; #else return TRUE; #endif /* HAVE_APPARMOR */ }
/** * Returns true if the given connection can acquire a service, * using the tasks security context * * @param connection connection that wants to own the service * @param bustype name of the bus * @param service_name the name of the service to acquire * @param error the reason for failure when FALSE is returned * @returns TRUE if acquire is permitted */ dbus_bool_t bus_apparmor_allows_acquire_service (DBusConnection *connection, const char *bustype, const char *service_name, DBusError *error) { #ifdef HAVE_APPARMOR BusAppArmorConfinement *con = NULL; DBusString qstr, auxdata; dbus_bool_t free_auxdata = FALSE; /* the AppArmor API uses pointers to int for pointers to boolean, and * int is not strictly guaranteed to be the same as dbus_bool_t */ int allow = FALSE, audit = TRUE; unsigned long pid; int res, serrno = 0; if (!apparmor_enabled) return TRUE; _dbus_assert (connection != NULL); con = bus_connection_dup_apparmor_confinement (connection); if (is_unconfined (con->label, con->mode)) { allow = TRUE; audit = FALSE; goto out; } if (!_dbus_string_init (&qstr)) goto oom; if (!build_service_query (&qstr, con->label, bustype, service_name)) { _dbus_string_free (&qstr); goto oom; } res = aa_query_label (AA_DBUS_BIND, _dbus_string_get_data (&qstr), _dbus_string_get_length (&qstr), &allow, &audit); _dbus_string_free (&qstr); if (res == -1) { serrno = errno; set_error_from_query_errno (error, serrno); goto audit; } /* Don't fail operations on profiles in complain mode */ if (modestr_is_complain (con->mode)) allow = TRUE; if (!allow) dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Connection \"%s\" is not allowed to own the service " "\"%s\" due to AppArmor policy", bus_connection_is_active (connection) ? bus_connection_get_name (connection) : "(inactive)", service_name); if (!audit) goto out; audit: if (!_dbus_string_init (&auxdata)) goto oom; free_auxdata = TRUE; if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown")) goto oom; if (!_dbus_append_pair_str (&auxdata, "name", service_name)) goto oom; if (serrno && !_dbus_append_pair_str (&auxdata, "info", strerror (serrno))) goto oom; if (!_dbus_append_mask (&auxdata, AA_DBUS_BIND)) goto oom; if (connection && dbus_connection_get_unix_process_id (connection, &pid) && !_dbus_append_pair_uint (&auxdata, "pid", pid)) goto oom; if (con->label && !_dbus_append_pair_str (&auxdata, "label", con->label)) goto oom; log_message (allow, "bind", &auxdata); out: if (con != NULL) bus_apparmor_confinement_unref (con); if (free_auxdata) _dbus_string_free (&auxdata); return allow; oom: if (error != NULL && !dbus_error_is_set (error)) BUS_SET_OOM (error); allow = FALSE; goto out; #else return TRUE; #endif /* HAVE_APPARMOR */ }
/** * Check if Apparmor security controls allow the connection to eavesdrop on * other connections. * * @param connection the connection attempting to eavesdrop. * @param bustype name of the bus * @param error the reason for failure when FALSE is returned * @returns TRUE if eavesdropping is permitted */ dbus_bool_t bus_apparmor_allows_eavesdropping (DBusConnection *connection, const char *bustype, DBusError *error) { #ifdef HAVE_APPARMOR BusAppArmorConfinement *con = NULL; DBusString qstr, auxdata; int allow = FALSE, audit = TRUE; dbus_bool_t free_auxdata = FALSE; unsigned long pid; int res, serrno = 0; if (!apparmor_enabled) return TRUE; con = bus_connection_dup_apparmor_confinement (connection); if (is_unconfined (con->label, con->mode)) { allow = TRUE; audit = FALSE; goto out; } if (!_dbus_string_init (&qstr)) goto oom; if (!build_eavesdrop_query (&qstr, con->label, bustype)) { _dbus_string_free (&qstr); goto oom; } res = aa_query_label (AA_DBUS_EAVESDROP, _dbus_string_get_data (&qstr), _dbus_string_get_length (&qstr), &allow, &audit); _dbus_string_free (&qstr); if (res == -1) { serrno = errno; set_error_from_query_errno (error, serrno); goto audit; } /* Don't fail operations on profiles in complain mode */ if (modestr_is_complain (con->mode)) allow = TRUE; if (!allow) dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED, "Connection \"%s\" is not allowed to eavesdrop due to " "AppArmor policy", bus_connection_is_active (connection) ? bus_connection_get_name (connection) : "(inactive)"); if (!audit) goto out; audit: if (!_dbus_string_init (&auxdata)) goto oom; free_auxdata = TRUE; if (!_dbus_append_pair_str (&auxdata, "bus", bustype ? bustype : "unknown")) goto oom; if (serrno && !_dbus_append_pair_str (&auxdata, "info", strerror (serrno))) goto oom; if (!_dbus_append_pair_str (&auxdata, "mask", "eavesdrop")) goto oom; if (connection && dbus_connection_get_unix_process_id (connection, &pid) && !_dbus_append_pair_uint (&auxdata, "pid", pid)) goto oom; if (con->label && !_dbus_append_pair_str (&auxdata, "label", con->label)) goto oom; log_message (allow, "eavesdrop", &auxdata); out: if (con != NULL) bus_apparmor_confinement_unref (con); if (free_auxdata) _dbus_string_free (&auxdata); return allow; oom: if (error != NULL && !dbus_error_is_set (error)) BUS_SET_OOM (error); allow = FALSE; goto out; #else return TRUE; #endif /* HAVE_APPARMOR */ }