From fe1cb3a9a1fc6bcbfa1b3be74ac9d5867005210f Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Mon, 14 Apr 2003 23:52:40 +0000 Subject: 2003-04-14 Havoc Pennington * dbus/dbus-userdb.c: user database abstraction, mostly to get caching, but at some point we might want to be able to use a different database. * bus/dispatch.c (bus_dispatch_sha1_test): add a test that uses SHA1 conf file to test the sha1 auth mechanism, since the regular test always uses EXTERNAL when available. * configure.in, test/data/valid-config-files/debug-allow-all-sha1.conf.in: add conf file that requires use of sha1 auth --- ChangeLog | 19 ++ bus/dispatch.c | 50 ++++- bus/test-main.c | 6 + bus/test.h | 1 + configure.in | 1 + dbus/Makefile.am | 4 +- dbus/dbus-test.c | 6 + dbus/dbus-test.h | 1 + dbus/dbus-userdb.c | 228 +++++++++++++++++++++ dbus/dbus-userdb.h | 44 ++++ doc/dbus-specification.sgml | 8 +- .../debug-allow-all-sha1.conf.in | 16 ++ 12 files changed, 376 insertions(+), 8 deletions(-) create mode 100644 dbus/dbus-userdb.c create mode 100644 dbus/dbus-userdb.h create mode 100644 test/data/valid-config-files/debug-allow-all-sha1.conf.in diff --git a/ChangeLog b/ChangeLog index d0da9f0f..f1437068 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2003-04-14 Havoc Pennington + + * dbus/dbus-userdb.c: user database abstraction, mostly to get + caching, but at some point we might want to be able to use a + different database. + + * bus/dispatch.c (bus_dispatch_sha1_test): add a test that uses + SHA1 conf file to test the sha1 auth mechanism, since the regular + test always uses EXTERNAL when available. + + * configure.in, + test/data/valid-config-files/debug-allow-all-sha1.conf.in: + add conf file that requires use of sha1 auth + 2003-04-13 Havoc Pennington * tools/dbus-send.c, tools/dbus-monitor.c: two utility programs @@ -64,6 +78,11 @@ * dbus/dbus-internals.h: mark assert_not_reached as __attribute((noreturn))__ +2003-04-11 Havoc Pennington + + * doc/dbus-specification.sgml: fix a spot with the wrong name for + the broadcast service. Use boolean return for ServiceExists. + 2003-04-11 Havoc Pennington * configure.in: add another directory to look for qt in. diff --git a/bus/dispatch.c b/bus/dispatch.c index 3ce7731c..595db33b 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -1878,13 +1878,13 @@ bus_dispatch_test (const DBusString *test_data_dir) DBusConnection *bar; DBusConnection *baz; DBusError error; + + dbus_error_init (&error); context = bus_context_new_test (test_data_dir, "valid-config-files/debug-allow-all.conf"); if (context == NULL) return FALSE; - - dbus_error_init (&error); foo = dbus_connection_open ("debug-pipe:name=test-server", &error); if (foo == NULL) @@ -1922,7 +1922,7 @@ bus_dispatch_test (const DBusString *test_data_dir) _dbus_assert_not_reached ("initial connection setup failed"); } - check1_try_iterations (context, "create_and_hello", + check1_try_iterations (context, "create_and_hello_sha1", check_hello_connection); check2_try_iterations (context, foo, "nonexistent_service_activation", @@ -1944,4 +1944,48 @@ bus_dispatch_test (const DBusString *test_data_dir) return TRUE; } + +dbus_bool_t +bus_dispatch_sha1_test (const DBusString *test_data_dir) +{ + BusContext *context; + DBusConnection *foo; + DBusError error; + + dbus_error_init (&error); + + /* Test SHA1 authentication */ + _dbus_verbose ("Testing SHA1 context\n"); + + context = bus_context_new_test (test_data_dir, + "valid-config-files/debug-allow-all.conf"); + if (context == NULL) + return FALSE; + + foo = dbus_connection_open ("debug-pipe:name=test-server", &error); + if (foo == NULL) + _dbus_assert_not_reached ("could not alloc connection"); + + if (!bus_setup_debug_client (foo)) + _dbus_assert_not_reached ("could not set up connection"); + + if (!check_hello_message (context, foo)) + _dbus_assert_not_reached ("hello message failed"); + + if (!check_no_leftovers (context)) + { + _dbus_warn ("Messages were left over after setting up initial SHA-1 connection"); + _dbus_assert_not_reached ("initial connection setup failed"); + } + + check1_try_iterations (context, "create_and_hello", + check_hello_connection); + + kill_client_connection_unchecked (foo); + + bus_context_unref (context); + + return TRUE; +} + #endif /* DBUS_BUILD_TESTS */ diff --git a/bus/test-main.c b/bus/test-main.c index a8efc507..c433075f 100644 --- a/bus/test-main.c +++ b/bus/test-main.c @@ -88,6 +88,12 @@ main (int argc, char **argv) die ("policy"); check_memleaks (argv[0]); + + printf ("%s: Running SHA1 connection test\n", argv[0]); + if (!bus_dispatch_sha1_test (&test_data_dir)) + die ("sha1"); + + check_memleaks (argv[0]); printf ("%s: Running message dispatch test\n", argv[0]); if (!bus_dispatch_test (&test_data_dir)) diff --git a/bus/test.h b/bus/test.h index 3d2a6fda..36a69e6c 100644 --- a/bus/test.h +++ b/bus/test.h @@ -33,6 +33,7 @@ #include "connection.h" dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir); +dbus_bool_t bus_dispatch_sha1_test (const DBusString *test_data_dir); dbus_bool_t bus_policy_test (const DBusString *test_data_dir); dbus_bool_t bus_config_parser_test (const DBusString *test_data_dir); dbus_bool_t bus_setup_debug_client (DBusConnection *connection); diff --git a/configure.in b/configure.in index 615a75d8..12d8d8ea 100644 --- a/configure.in +++ b/configure.in @@ -530,6 +530,7 @@ doc/Makefile dbus-1.0.pc dbus-glib-1.0.pc test/data/valid-config-files/debug-allow-all.conf +test/data/valid-config-files/debug-allow-all-sha1.conf test/data/valid-service-files/debug-echo.service test/data/valid-service-files/debug-segfault.service ]) diff --git a/dbus/Makefile.am b/dbus/Makefile.am index d99ff1c1..9528b547 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -94,7 +94,9 @@ DBUS_SHARED_SOURCES= \ dbus-string.h \ dbus-string-private.h \ dbus-sysdeps.c \ - dbus-sysdeps.h + dbus-sysdeps.h \ + dbus-userdb.c \ + dbus-userdb.h ### source code that is generic utility functionality used ### by the bus daemon or test apps, but is NOT included diff --git a/dbus/dbus-test.c b/dbus/dbus-test.c index f7d1c4ef..6f7431a8 100644 --- a/dbus/dbus-test.c +++ b/dbus/dbus-test.c @@ -135,6 +135,12 @@ dbus_internal_do_not_use_run_tests (const char *test_data_dir) die ("hash tables"); check_memleaks (); + + printf ("%s: running user database tests\n", "dbus-test"); + if (!_dbus_userdb_test (test_data_dir)) + die ("user database"); + + check_memleaks (); printf ("%s: running keyring tests\n", "dbus-test"); if (!_dbus_keyring_test ()) diff --git a/dbus/dbus-test.h b/dbus/dbus-test.h index 68304efa..e97fd85a 100644 --- a/dbus/dbus-test.h +++ b/dbus/dbus-test.h @@ -50,6 +50,7 @@ dbus_bool_t _dbus_keyring_test (void); dbus_bool_t _dbus_data_slot_test (void); dbus_bool_t _dbus_sysdeps_test (void); dbus_bool_t _dbus_spawn_test (const char *test_data_dir); +dbus_bool_t _dbus_userdb_test (const char *test_data_dir); void dbus_internal_do_not_use_run_tests (const char *test_data_dir); dbus_bool_t dbus_internal_do_not_use_try_message_file (const DBusString *filename, diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c new file mode 100644 index 00000000..871fa5bd --- /dev/null +++ b/dbus/dbus-userdb.c @@ -0,0 +1,228 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-userdb.c User database abstraction + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "dbus-userdb.h" +#include "dbus-hash.h" +#include "dbus-test.h" +#include "dbus-internals.h" +#include + +typedef struct DBusUserEntry DBusUserEntry; + +struct DBusUserEntry +{ + dbus_uid_t uid; + + dbus_gid_t *group_ids; + int n_group_ids; +}; + +struct DBusUserDatabase +{ + int refcount; + + DBusHashTable *users; +}; + +static void +free_user_entry (void *data) +{ + DBusUserEntry *entry = data; + + if (entry == NULL) /* hash table will pass NULL */ + return; + + dbus_free (entry->group_ids); + + dbus_free (entry); +} + +static DBusUserEntry* +_dbus_user_database_lookup (DBusUserDatabase *db, + dbus_uid_t uid, + DBusError *error) +{ + DBusUserEntry *entry; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + entry = _dbus_hash_table_lookup_ulong (db->users, uid); + if (entry) + return entry; + else + { + entry = dbus_new0 (DBusUserEntry, 1); + if (entry == NULL) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_get_groups (uid, &entry->group_ids, &entry->n_group_ids, error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + free_user_entry (entry); + return NULL; + } + + if (!_dbus_hash_table_insert_ulong (db->users, entry->uid, entry)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + free_user_entry (entry); + return NULL; + } + + return entry; + } +} + +/** + * @addtogroup DBusInternalsUtils + * @{ + */ + +/** + * Creates a new user database object used to look up and + * cache user information. + * @returns new database, or #NULL on out of memory + */ +DBusUserDatabase* +_dbus_user_database_new (void) +{ + DBusUserDatabase *db; + + db = dbus_new0 (DBusUserDatabase, 1); + if (db == NULL) + return NULL; + + db->refcount = 1; + + db->users = _dbus_hash_table_new (DBUS_HASH_ULONG, + NULL, free_user_entry); + + if (db->users == NULL) + goto failed; + + return db; + + failed: + _dbus_user_database_unref (db); + return NULL; +} + +/** + * Increments refcount of user database. + * @param db the database + */ +void +_dbus_user_database_ref (DBusUserDatabase *db) +{ + _dbus_assert (db->refcount > 0); + + db->refcount += 1; +} + +/** + * Decrements refcount of user database. + * @param db the database + */ +void +_dbus_user_database_unref (DBusUserDatabase *db) +{ + _dbus_assert (db->refcount > 0); + + db->refcount -= 1; + if (db->refcount == 0) + { + if (db->users) + _dbus_hash_table_unref (db->users); + + dbus_free (db); + } +} + +/** + * Gets all groups for a particular user. Returns #FALSE + * if no memory, or user isn't known, but always initializes + * group_ids to a NULL array. Sets error to the reason + * for returning #FALSE. + * + * @param db the user database object + * @param uid the user ID + * @param group_ids return location for array of group IDs + * @param n_group_ids return location for length of returned array + * @param error return location for error + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_user_database_get_groups (DBusUserDatabase *db, + dbus_uid_t uid, + dbus_gid_t **group_ids, + int *n_group_ids, + DBusError *error) +{ + DBusUserEntry *entry; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + *group_ids = NULL; + *n_group_ids = 0; + + entry = _dbus_user_database_lookup (db, uid, error); + if (entry == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return FALSE; + } + + if (entry->n_group_ids > 0) + { + *group_ids = dbus_new (dbus_gid_t, entry->n_group_ids); + if (*group_ids == NULL) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return FALSE; + } + + *n_group_ids = entry->n_group_ids; + + memcpy (*group_ids, entry->group_ids, entry->n_group_ids * sizeof (dbus_gid_t)); + } + + return TRUE; +} + +/** @} */ + +#ifdef DBUS_BUILD_TESTS +/** + * Unit test for dbus-userdb.c. + * + * @returns #TRUE on success. + */ +dbus_bool_t +_dbus_userdb_test (const char *test_data_dir) +{ + + return TRUE; +} +#endif /* DBUS_BUILD_TESTS */ diff --git a/dbus/dbus-userdb.h b/dbus/dbus-userdb.h new file mode 100644 index 00000000..b1df4588 --- /dev/null +++ b/dbus/dbus-userdb.h @@ -0,0 +1,44 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-userdb.h User database abstraction + * + * Copyright (C) 2003 Red Hat, Inc. + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef DBUS_USERDB_H +#define DBUS_USERDB_H + +#include + +DBUS_BEGIN_DECLS; + +typedef struct DBusUserDatabase DBusUserDatabase; + +DBusUserDatabase* _dbus_user_database_new (void); +void _dbus_user_database_ref (DBusUserDatabase *db); +void _dbus_user_database_unref (DBusUserDatabase *db); +dbus_bool_t _dbus_user_database_get_groups (DBusUserDatabase *db, + dbus_uid_t uid, + dbus_gid_t **group_ids, + int *n_group_ids, + DBusError *error); + +DBUS_END_DECLS; + +#endif /* DBUS_USERDB_H */ diff --git a/doc/dbus-specification.sgml b/doc/dbus-specification.sgml index a464a0d6..c14e9cdf 100644 --- a/doc/dbus-specification.sgml +++ b/doc/dbus-specification.sgml @@ -1113,7 +1113,7 @@ messages are routed to the owner of the named service. Messages may also be broadcast by sending them to the special service - org.freedesktop.Broadcast. Broadcast messages are + org.freedesktop.DBus.Broadcast. Broadcast messages are sent to all applications with message matching rules that match the message. @@ -1415,7 +1415,7 @@ As a method: - UINT32 ServiceExists (in STRING service_name) + BOOLEAN ServiceExists (in STRING service_name) Message arguments: @@ -1449,8 +1449,8 @@ 0 - UINT32 - Return value, 1 if the service exists and 0 otherwise + BOOLEAN + Return value, true if the service exists diff --git a/test/data/valid-config-files/debug-allow-all-sha1.conf.in b/test/data/valid-config-files/debug-allow-all-sha1.conf.in new file mode 100644 index 00000000..6db93f0c --- /dev/null +++ b/test/data/valid-config-files/debug-allow-all-sha1.conf.in @@ -0,0 +1,16 @@ + + + + + debug-pipe:name=test-server + unix:tmpdir=@TEST_SOCKET_DIR@ + @TEST_SERVICE_DIR@ + DBUS_COOKIE_SHA1 + + + + + + + -- cgit