2003-04-14 Havoc Pennington <hp@redhat.com>
authorHavoc Pennington <hp@redhat.com>
Mon, 14 Apr 2003 23:52:40 +0000 (23:52 +0000)
committerHavoc Pennington <hp@redhat.com>
Mon, 14 Apr 2003 23:52:40 +0000 (23:52 +0000)
* 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

12 files changed:
ChangeLog
bus/dispatch.c
bus/test-main.c
bus/test.h
configure.in
dbus/Makefile.am
dbus/dbus-test.c
dbus/dbus-test.h
dbus/dbus-userdb.c [new file with mode: 0644]
dbus/dbus-userdb.h [new file with mode: 0644]
doc/dbus-specification.sgml
test/data/valid-config-files/debug-allow-all-sha1.conf.in [new file with mode: 0644]

index d0da9f0..f143706 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2003-04-14  Havoc Pennington  <hp@redhat.com>
+
+       * 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  <hp@pobox.com>
        
         * tools/dbus-send.c, tools/dbus-monitor.c: two utility programs
 
 2003-04-11  Havoc Pennington  <hp@redhat.com>
 
+       * 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  <hp@redhat.com>
+
        * configure.in: add another directory to look for qt in.
 
 2003-04-11  Havoc Pennington  <hp@redhat.com>
index 3ce7731..595db33 100644 (file)
@@ -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 */
index a8efc50..c433075 100644 (file)
@@ -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))
index 3d2a6fd..36a69e6 100644 (file)
@@ -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);
index 615a75d..12d8d8e 100644 (file)
@@ -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
 ])
index d99ff1c..9528b54 100644 (file)
@@ -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
index f7d1c4e..6f7431a 100644 (file)
@@ -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 ())
index 68304ef..e97fd85 100644 (file)
@@ -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 (file)
index 0000000..871fa5b
--- /dev/null
@@ -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 <string.h>
+
+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 (file)
index 0000000..b1df458
--- /dev/null
@@ -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/dbus-sysdeps.h>
+
+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 */
index a464a0d..c14e9cd 100644 (file)
         messages are routed to the owner of the named service.
         Messages may also be <firstterm>broadcast</firstterm>
         by sending them to the special service 
-        <literal>org.freedesktop.Broadcast</literal>. Broadcast messages are
+        <literal>org.freedesktop.DBus.Broadcast</literal>. Broadcast messages are
         sent to all applications with <firstterm>message matching
           rules</firstterm> that match the message.
       </para>
         <para>
           As a method:
           <programlisting>
-            UINT32 ServiceExists (in STRING service_name)
+            BOOLEAN ServiceExists (in STRING service_name)
           </programlisting>
           Message arguments:
           <informaltable>
               <tbody>
                 <row>
                   <entry>0</entry>
-                  <entry>UINT32</entry>
-                  <entry>Return value, 1 if the service exists and 0 otherwise</entry>
+                  <entry>BOOLEAN</entry>
+                  <entry>Return value, true if the service exists</entry>
                 </row>
               </tbody>
             </tgroup>
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 (file)
index 0000000..6db93f0
--- /dev/null
@@ -0,0 +1,16 @@
+<!-- Bus that listens on a debug pipe and requires SHA1 auth, used to test SHA1 -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <listen>debug-pipe:name=test-server</listen>
+  <listen>unix:tmpdir=@TEST_SOCKET_DIR@</listen>
+  <servicedir>@TEST_SERVICE_DIR@</servicedir>
+  <auth>DBUS_COOKIE_SHA1</auth>
+  <policy context="default">
+    <allow send="*"/>
+    <allow receive="*"/>
+    <allow own="*"/>
+    <allow user="*"/>
+  </policy>
+</busconfig>