X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev.c;h=67b86e5916ced757a921bbbd442bee3e876c6298;hb=5aebfbcb62614fc2bf2b1579d62e3fe272c6751a;hp=ed42862c00881d195e10012b8ca2dd964501dcfa;hpb=c2f17c9ea8a90d1c12158b947b3f8096404afe33;p=elogind.git diff --git a/udev.c b/udev.c index ed42862c0..67b86e591 100644 --- a/udev.c +++ b/udev.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -38,14 +39,6 @@ char **main_argv; char **main_envp; -char sysfs_path[SYSFS_PATH_MAX]; -char *udev_config_dir = UDEV_CONFIG_DIR; -char *udev_root = UDEV_ROOT; -char udev_db_filename[PATH_MAX+NAME_MAX]; -char udev_config_permission_filename[PATH_MAX+NAME_MAX]; -char udev_config_filename[PATH_MAX+NAME_MAX]; - - static inline char *get_action(void) { char *action; @@ -70,53 +63,60 @@ static inline char *get_seqnum(void) return seqnum; } -static void get_dirs(void) +#ifdef USE_DBUS + +/** Global variable for the connection the to system message bus or #NULL + * if we cannot connect or acquire the org.kernel.udev service + */ +DBusConnection* sysbus_connection; + +/** Disconnect from the system message bus */ +static void sysbus_disconnect() { - char *temp; - char *udev_db = UDEV_DB; - char *udev_config = NAMEDEV_CONFIG_FILE; - char *udev_permission = NAMEDEV_CONFIG_PERMISSION_FILE; - int retval; - - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - if (retval) - dbg("sysfs_get_mnt_path failed"); - - /* see if we should try to override any of the default values */ - temp = getenv("UDEV_TEST"); - if (temp != NULL) { - /* hm testing is happening, use the specified values, if they are present */ - temp = getenv("UDEV_SYSFS_PATH"); - if (temp) - strncpy(sysfs_path, temp, sizeof(sysfs_path)); - temp = getenv("UDEV_CONFIG_DIR"); - if (temp) - udev_config_dir = temp; - temp = getenv("UDEV_ROOT"); - if (temp) - udev_root = temp; - temp = getenv("UDEV_DB"); - if (temp) - udev_db = temp; - temp = getenv("UDEV_CONFIG_FILE"); - if (temp) - udev_config = temp; - temp = getenv("UDEV_PERMISSION_FILE"); - if (temp) - udev_permission = temp; - } - dbg("sysfs_path = %s", sysfs_path); + if (sysbus_connection == NULL) + return; - strncpy(udev_db_filename, udev_config_dir, sizeof(udev_db_filename)); - strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); + dbus_connection_disconnect(sysbus_connection); + sysbus_connection = NULL; +} - strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); - strncat(udev_config_filename, udev_config, sizeof(udev_config_filename)); - - strncpy(udev_config_permission_filename, udev_config_dir, sizeof(udev_config_permission_filename)); - strncat(udev_config_permission_filename, udev_permission, sizeof(udev_config_permission_filename)); +/** Connect to the system message bus */ +static void sysbus_connect() +{ + DBusError error; + + /* Connect to a well-known bus instance, the system bus */ + dbus_error_init(&error); + sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (sysbus_connection == NULL) { + dbg("cannot connect to system message bus, error %s: %s", + error.name, error.message); + dbus_error_free(&error); + return; + } + + /* Acquire the org.kernel.udev service such that listeners + * know that the message is really from us and not from a + * random attacker. See the file udev_sysbus_policy.conf for + * details. + * + * Note that a service can have multiple owners (though there + * is a concept of a primary owner for reception of messages) + * so no race is introduced if two copies of udev is running + * at the same time. + */ + dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, + &error); + if (dbus_error_is_set(&error)) { + printf("cannot acquire org.kernel.udev service, error %s: %s'", + error.name, error.message); + sysbus_disconnect(); + return; + } } +#endif /* USE_DBUS */ + int main(int argc, char **argv, char **envp) { char *action; @@ -141,12 +141,12 @@ int main(int argc, char **argv, char **envp) dbg ("no devpath?"); goto exit; } - dbg("looking at %s", devpath); + dbg("looking at '%s'", devpath); /* we only care about class devices and block stuff */ if (!strstr(devpath, "class") && !strstr(devpath, "block")) { - dbg("not block or class"); + dbg("not a block or class device"); goto exit; } @@ -162,11 +162,18 @@ int main(int argc, char **argv, char **envp) goto exit; } + /* initialize our configuration */ + udev_init_config(); + +#ifdef USE_DBUS + /* connect to the system message bus */ + sysbus_connect(); +#endif /* USE_DBUS */ + /* initialize udev database */ - get_dirs(); retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { - dbg("Unable to initialize database."); + dbg("unable to initialize database"); goto exit; } @@ -180,12 +187,16 @@ int main(int argc, char **argv, char **envp) retval = udev_remove_device(devpath, subsystem); else { - dbg("Unknown action: %s", action); + dbg("unknown action '%s'", action); retval = -EINVAL; } udevdb_exit(); +#ifdef USE_DBUS + /* disconnect from the system message bus */ + sysbus_disconnect(); +#endif /* USE_DBUS */ + exit: return retval; } -