hal: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Sun Feb 18 14:44:27 PST 2007


 fdi/policy/10osvendor/20-acl-management.fdi |   51 +++++++++++++++++++++++---
 hald/create_cache.c                         |    2 +
 hald/device_info.c                          |   54 ++++++++++++++++++++++++++++
 hald/rule.h                                 |    1 
 4 files changed, 103 insertions(+), 5 deletions(-)

New commits:
diff-tree e94e5d6bbe489a1269d0e2a5152a1a1f167c7674 (from 04ff0ba613b2dc3d9c3ffabac2399d992a8d7363)
Author: David Zeuthen <davidz at redhat.com>
Date:   Sun Feb 18 17:44:23 2007 -0500

    add ACL management for remaining devices recognized by HAL
    
    Ugh, had to introduce a new matching directive to make this work
    
     <!-- usb cameras -->
     <match key="info.capabilities" contains="usbraw">
      <match key="info.capabilities" sibling_contains="camera">
       <append key="info.capabilities" type="strlist">access_control</append>
       <merge key="access_control.file" type="copy_property">usbraw.device</merge>
      </match>
     </match>
    
    So right now this works because of these two assumptions
    
     - for coldplug we get the usbraw interface *after* the usb devices and
       usb interfaces - this is probably because we sort the sysfs paths -
       see hald/linux/coldplug.c:coldplug_synthesize_events()
    
     - for hotplug we seem to be getting the usbraw interfaces as the last
       one too. This may just be pure luck.
    
    The whole way that USB device nodes are handed out by the Linux kernel
    is, sorta-kinda, on crack and makes it hard for user space.
    
    Really, the usbraw class device needs to go and we need to get the
    device file for the entire USB device along with the first usb_device
    uevent. Interfaces too could have separate device files and they too
    could give you a device file.
    
    The latter would be nice for multi-function USB devices, such as some
    multi-function printer/scanner/thumbdrive combos from HP (these exist,
    my mom got one where it's one USB device and sevaral USB interfaces) -
    this would enable us to give access to the scanning USB interface to
    unprivileged users without, at the same time, give them raw access to
    the USB storage device interface.
    
    I'll poke Kay and Greg KH about this. For now, it seems to work
    nicely. End of rant.

diff --git a/fdi/policy/10osvendor/20-acl-management.fdi b/fdi/policy/10osvendor/20-acl-management.fdi
index 8033521..41b9ebd 100644
--- a/fdi/policy/10osvendor/20-acl-management.fdi
+++ b/fdi/policy/10osvendor/20-acl-management.fdi
@@ -3,21 +3,61 @@
 <deviceinfo version="0.2">
   <device>
 
-    <!-- allow local sessions to access ALSA device files -->
+
+    <!-- classification of devices where access can be controlled goes here -->
+
+    <!-- sound card (ALSA) -->
     <match key="info.capabilities" contains="alsa">
       <append key="info.capabilities" type="strlist">access_control</append>
-      <merge key="access_control.grant_local_session" type="bool">true</merge>
       <merge key="access_control.file" type="copy_property">alsa.device_file</merge>
     </match>
 
-    <!-- allow local sessions to access OSS device files -->
+    <!-- sound card (OSS) -->
     <match key="info.capabilities" contains="oss">
       <append key="info.capabilities" type="strlist">access_control</append>
-      <merge key="access_control.grant_local_session" type="bool">true</merge>
       <merge key="access_control.file" type="copy_property">oss.device_file</merge>
     </match>
 
-    <!-- TODO: add more rules for adding/removing ACL's (e.g. webcam, cd drive etc.) -->
+    <!-- video4linux devices -->
+    <match key="info.capabilities" contains="video4linux">
+      <append key="info.capabilities" type="strlist">access_control</append>
+      <merge key="access_control.file" type="copy_property">video4linux.device</merge>
+    </match>
+
+    <!-- optical drives -->
+    <match key="info.capabilities" contains="storage.cdrom">
+      <append key="info.capabilities" type="strlist">access_control</append>
+      <merge key="access_control.file" type="copy_property">block.device</merge>
+    </match>
+
+    <!-- DVB cards -->
+    <match key="info.capabilities" contains="dvb">
+      <append key="info.capabilities" type="strlist">access_control</append>
+      <merge key="access_control.file" type="copy_property">dvb.device</merge>
+    </match>
+
+    <!-- usb cameras -->
+    <match key="info.capabilities" contains="usbraw">
+      <match key="info.capabilities" sibling_contains="camera">
+	<append key="info.capabilities" type="strlist">access_control</append>
+	<merge key="access_control.file" type="copy_property">usbraw.device</merge>
+      </match>
+    </match>
+
+
+    <!-- policy goes here - this can be amended by 3rd party packages,
+         e.g.  the flumotion package may provide a fdi-file that
+         appends the 'flumotion' user to access_control.grant_user for
+         e.g. webcam's or audio devices - see RH bug #140853 for
+         details. -->
+
+    <!-- grant access to local session whether it's active or not -->
+    <match key="info.capabilities" contains="access_control">
+      <merge key="access_control.grant_local_session" type="bool">true</merge>
+    </match>
+
+
+    <!-- enforcement of policy goes here -->
 
     <!-- add / remove ACL's when devices are added and removed -->
     <match key="info.capabilities" contains="access_control">
@@ -26,6 +66,7 @@
     </match>
 
     <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
+
       <!-- remove all previously added ACL's on start-up -->
       <append key="info.callouts.add" type="strlist">hal-acl-tool --remove-all</append>
 
diff --git a/hald/create_cache.c b/hald/create_cache.c
index 4d016d1..2b40d3d 100644
--- a/hald/create_cache.c
+++ b/hald/create_cache.c
@@ -107,6 +107,8 @@ match_type get_match_type(const char *st
 		return MATCH_ISASCII;
 	if (strcmp (str, "is_absolute_path") == 0)
 		return MATCH_IS_ABS_PATH;
+	if (strcmp (str, "sibling_contains") == 0)
+		return MATCH_SIBLING_CONTAINS;
 	if (strcmp (str, "contains") == 0)
 		return MATCH_CONTAINS;
 	if (strcmp (str, "contains_ncase") == 0)
diff --git a/hald/device_info.c b/hald/device_info.c
index c4891cf..5d68f17 100644
--- a/hald/device_info.c
+++ b/hald/device_info.c
@@ -78,6 +78,8 @@ get_match_type_str (enum match_type type
 		return "is_ascii";
 	case MATCH_IS_ABS_PATH:
 		return "is_absolute_path";
+	case MATCH_SIBLING_CONTAINS:
+		return "sibling_contains";
 	case MATCH_CONTAINS:
 		return "contains";
 	case MATCH_CONTAINS_NCASE:
@@ -465,6 +467,58 @@ handle_match (struct rule *rule, HalDevi
 		return contains;
 	}
 
+	case MATCH_SIBLING_CONTAINS:
+	{
+		dbus_bool_t contains = FALSE;
+		const char *parent_udi;
+
+		parent_udi = hal_device_property_get_string (d, "info.parent");
+		if (parent_udi != NULL) {
+			GSList *i;
+			GSList *siblings;
+
+			siblings = hal_device_store_match_multiple_key_value_string (hald_get_gdl (),
+										     "info.parent",
+										     parent_udi);
+			for (i = siblings; i != NULL; i = g_slist_next (i)) {
+				HalDevice *sib = HAL_DEVICE (i->data);
+
+				if (sib == d)
+					continue;
+
+				HAL_INFO (("Checking sibling '%s' of '%s' whether '%s' contains '%s'",
+					   hal_device_get_udi (sib), hal_device_get_udi (d), prop_to_check, value));
+
+				if (hal_device_property_get_type (sib, prop_to_check) == HAL_PROPERTY_TYPE_STRING) {
+					if (hal_device_has_property (sib, prop_to_check)) {
+						const char *haystack;
+						
+						haystack = hal_device_property_get_string (sib, prop_to_check);
+						if (value != NULL && haystack != NULL && strstr (haystack, value))
+							contains = TRUE;
+					}
+				} else if (hal_device_property_get_type (sib, prop_to_check) == HAL_PROPERTY_TYPE_STRLIST && value != NULL) {
+					HalDeviceStrListIter iter;
+					for (hal_device_property_strlist_iter_init (sib, prop_to_check, &iter);
+					     hal_device_property_strlist_iter_is_valid (&iter);
+					     hal_device_property_strlist_iter_next (&iter)) {
+						const char *str = hal_device_property_strlist_iter_get_value (&iter);
+						if (strcmp (str, value) == 0) {
+							contains = TRUE;
+							break;
+						}
+					}
+				}
+
+				if (contains)
+					break;
+
+			} /* for all siblings */
+		}
+
+		return contains;
+	}
+
 	case MATCH_CONTAINS_NCASE:
 	{
 		dbus_bool_t contains_ncase = FALSE;
diff --git a/hald/rule.h b/hald/rule.h
index cb82e62..b386fc9 100644
--- a/hald/rule.h
+++ b/hald/rule.h
@@ -78,6 +78,7 @@ match_type {
 	MATCH_COMPARE_LE,
 	MATCH_COMPARE_GT,
 	MATCH_COMPARE_GE,
+	MATCH_SIBLING_CONTAINS
 };
 
 /* a "rule" structure that is a generic node of the fdi file */


More information about the hal-commit mailing list