Simple D-Bus API wrapper library¶
Related ticket(s):
Problem Statement¶
Using D-Bus requires a significant amount of knowledge of D-Bus and its underlying library API. Libraries like libdbus or libdbus_glib are quite complex and requires a lot of code to do even the simplest things. The purpose of this document is to describe a new public API to access most fundamental parts of SSSD’s D-Bus responder in a simple way so that a user doesn’t have to deal with D-Bus at all.
Prerequisites¶
- Each attribute of every D-Bus object accessible via this API is represented as string.
- Naming convention of D-Bus methods:
- List<class><condition>(arg1, …) returning array of object
paths
- ListUsers()
- ListDomains()
- ListUsersByName(filter)
- ListGroupsByName(filter)
- Find<class><condition>(arg1, …) returning single object path
- FindUserById(id)
- FindDomainByName(name)
- List<class><condition>(arg1, …) returning array of object
paths
The API¶
/** * @defgroup sss_dbus Simple interface to SSSD InfoPipe responder. * Libsss_dbus provides a synchronous interface to simplify basic communication * with SSSD InfoPipe responder. * @{ */ /** SSSD InfoPipe bus address */ #define SSS_DBUS_IFP "org.freedesktop.sssd.infopipe" /** SSSD InfoPipe interface */ #define SSS_DBUS_IFACE_IFP SSS_DBUS_IFP #define SSS_DBUS_IFACE_COMPONENTS "org.freedesktop.sssd.infopipe.Components" #define SSS_DBUS_IFACE_SERVICES "org.freedesktop.sssd.infopipe.Services" #define SSS_DBUS_IFACE_DOMAINS "org.freedesktop.sssd.infopipe.Domains" #define SSS_DBUS_IFACE_USERS "org.freedesktop.sssd.infopipe.Users" #define SSS_DBUS_IFACE_GROUPS "org.freedesktop.sssd.infopipe.Groups" /** * Opaque libsss_dbus context. One context shall not be used by multiple * threads. Each thread needs to create and use its own context. * * @see sss_dbus_init * @see sss_dbus_init_ex */ typedef struct sss_dbus_ctx sss_dbus_ctx; /** * Typedef for memory allocation functions */ typedef void (sss_dbus_free_func)(void *ptr, void *pvt); typedef void *(sss_dbus_alloc_func)(size_t size, void *pvt); /** * Error codes used by libsss_dbus */ typedef enum sss_dbus_error { /** Success */ SSS_DBUS_OK = 0, /** Ran out of memory during processing */ SSS_DBUS_OUT_OF_MEMORY, /** Invalid argument */ SSS_DBUS_INVALID_ARGUMENT, /** * Input/output error * * @see sss_dbus_get_last_io_error() to get more information */ SSS_DBUS_IO_ERROR, /** Internal error */ SSS_DBUS_INTERNAL_ERROR, /** Operation not supported */ SSS_DBUS_NOT_SUPPORTED, /** Attribute does not exist */ SSS_DBUS_ATTR_MISSING, /** Attribute does not have any value set */ SSS_DBUS_ATTR_NULL, /** Incorrect attribute type */ SSS_DBUS_INCORRECT_TYPE, /** Always last */ SSS_DBUS_ERROR_SENTINEL } sss_dbus_error; /** * Boolean type */ typedef uint32_t sss_dbus_bool; /** * D-Bus object attribute */ typedef struct sss_dbus_attr sss_dbus_attr; /** * String dictionary */ typedef struct { char *key; char **values; unsigned int num_values; } sss_dbus_str_dict; /** * D-Bus object */ typedef struct sss_dbus_object { char *name; char *object_path; char *interface; sss_dbus_attr **attrs; } sss_dbus_object; /** * @brief Initialize sss_dbus context using default allocator (malloc) * * @param[out] _ctx sss_dbus context */ sss_dbus_error sss_dbus_init(sss_dbus_ctx **_ctx); /** * @brief Initialize sss_dbus context * * @param[in] alloc_pvt Private data for allocation routine * @param[in] alloc_func Function to allocate memory for the context, if * NULL malloc() is used * @param[in] free_func Function to free the memory of the context, if * NULL free() is used * @param[out] _ctx sss_dbus context */ sss_dbus_error sss_dbus_init_ex(void *alloc_pvt, sss_dbus_alloc_func *alloc_func, sss_dbus_free_func *free_func, sss_dbus_ctx **_ctx); /** * @brief Return last error message from underlying D-Bus communication * * @param[in] ctx sss_dbus context * @return Error message or NULL if no error occurred during last D-Bus call. */ const char * sss_dbus_get_last_io_error(sss_dbus_ctx *ctx); /** * @brief Return default interface for object with path @object_path. * * @param[in] ctx object_path D-Bus object path * @return Interface name or NULL if the object path is unknown. */ const char * sss_dbus_get_iface_for_object(const char *object_path); /** * @brief Create message for SSSD InfoPipe bus. * * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[in] method D-Bus method * * @return D-Bus message. */ DBusMessage * sss_dbus_create_message(const char *object_path, const char *interface, const char *method); /** * @brief Send D-Bus message to SSSD InfoPipe bus. * * @param[in] ctx sss_dbus context * @param[in] interface D-Bus interface * @param[in] object_path D-Bus object path * @param[in] method D-Bus method * * @return D-Bus message. */ sss_dbus_error sss_dbus_send_message(sss_dbus_ctx *ctx, DBusMessage *msg, DBusMessage **_reply); /** * @brief Fetch selected attributes of given object. * * @param[in] ctx sss_dbus context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[in] name Name of desired attribute * @param[out] _attrs List of acquired attributes */ sss_dbus_error sss_dbus_fetch_attr(sss_dbus_ctx *ctx, const char *object_path, const char *name, const char *interface, sss_dbus_attr ***_attrs); /** * @brief Fetch all attributes of given object. * * @param[in] ctx sss_dbus context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[out] _attrs Acquired attributes */ sss_dbus_error sss_dbus_fetch_all_attrs(sss_dbus_ctx *ctx, const char *object_path, const char *interface, sss_dbus_attr ***_attrs); /** * @brief Fetch D-Bus object. * * @param[in] ctx sss_dbus context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[out] _object Object and its attributes */ sss_dbus_error sss_dbus_fetch_object(sss_dbus_ctx *ctx, const char *object_path, const char *interface, sss_dbus_object **_object); /** * @brief List objects that satisfies given conditions. This routine will * invoke List<method> D-Bus method on SSSD InfoPipe interface. Arguments * to this method are given as standard variadic D-Bus arguments. * * @param[in] ctx sss_dbus context * @param[in] method D-Bus method to call without the 'List' prefix * @param[out] _object_paths List of object paths * @param[in] first_arg_type Type of the first D-Bus argument * @param[in] ... D-Bus arguments */ sss_dbus_error sss_dbus_invoke_list(sss_dbus_ctx *ctx, const char *method, char ***_object_paths, int first_arg_type, ...); /** * @brief Find single object that satisfies given conditions. This routine will * invoke Find<method> D-Bus method on SSSD InfoPipe interface. Arguments * to this method are given as standard variadic D-Bus arguments. * * @param[in] ctx sss_dbus context * @param[in] method D-Bus method to call without the 'Find' prefix * @param[out] _object_path Object path * @param[in] first_arg_type Type of the first D-Bus argument * @param[in] ... D-Bus arguments */ sss_dbus_error sss_dbus_invoke_find(sss_dbus_ctx *ctx, const char *method, char **_object_path, int first_arg_type, ...); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_bool(sss_dbus_attr **attrs, const char *name, sss_dbus_bool *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_int16(sss_dbus_attr **attrs, const char *name, int16_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_uint16(sss_dbus_attr **attrs, const char *name, uint16_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_int32(sss_dbus_attr **attrs, const char *name, int32_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_uint32(sss_dbus_attr **attrs, const char *name, uint32_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_int64(sss_dbus_attr **attrs, const char *name, int64_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_uint64(sss_dbus_attr **attrs, const char *name, uint64_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_string(sss_dbus_attr **attrs, const char *name, const char **_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_dbus_error sss_dbus_find_attr_as_string_dict(sss_dbus_attr **attrs, const char *name, sss_dbus_str_dict *_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_bool_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, sss_dbus_bool **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_int16_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, int16_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_uint16_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, uint16_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_int32_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, int32_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_uint32_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, uint32_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_int64_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, int64_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_uint64_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, uint64_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_string_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, const char * const **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _values Output array */ sss_dbus_error sss_dbus_find_attr_as_string_dict_array(sss_dbus_attr **attrs, const char *name, unsigned int *_num_values, sss_dbus_str_dict **_value); /** * @brief Free sss_dbus context and set it to NULL. * * @param[in,out] _ctx sss_dbus context */ void sss_dbus_free(sss_dbus_ctx **_ctx); /** * @brief Free attribute list and set it to NULL. * * @param[in,out] _attrs Attributes */ void sss_dbus_free_attrs(sss_dbus_ctx *ctx, sss_dbus_attr ***_attrs); /** * @brief Free sss_dbus object and set it to NULL. * * @param[in,out] _object Object */ void sss_dbus_free_object(sss_dbus_ctx *ctx, sss_dbus_object **_object); /** * @brief Free string and set it to NULL. * * @param[in,out] _str String */ void sss_dbus_free_string(sss_dbus_ctx *ctx, char **_str); /** * @brief Free array of strings and set it to NULL. * * @param[in,out] _str_array Array of strings */ void sss_dbus_free_string_array(sss_dbus_ctx *ctx, char ***_str_array); /** * @} */ /** * @defgroup common Most common use cases of SSSD InfoPipe responder. * @{ */ /** * @brief List names of available domains. * * @param[in] ctx sss_dbus context * @param[out] _domains List of domain names */ sss_dbus_error sss_dbus_list_domains(sss_dbus_ctx *ctx, char ***_domains); /** * @brief Fetch all information about domain by name. * * @param[in] ctx sss_dbus context * @param[in] name Domain name * @param[out] _domain Domain object */ sss_dbus_error sss_dbus_fetch_domain_by_name(sss_dbus_ctx *ctx, const char *name, sss_dbus_object **_domain); /** * @brief Fetch all information about user by uid. * * @param[in] ctx sss_dbus context * @param[in] uid User ID * @param[out] _user User object */ sss_dbus_error sss_dbus_fetch_user_by_uid(sss_dbus_ctx *ctx, uid_t uid, sss_dbus_object **_user); /** * @brief Fetch all information about user by name. * * @param[in] ctx sss_dbus context * @param[in] name User name * @param[out] _user User object */ sss_dbus_error sss_dbus_fetch_user_by_name(sss_dbus_ctx *ctx, const char *name, sss_dbus_object **_user); /** * @} */
Authors¶
- Pavel Březina <pbrezina@redhat.com>