sssd_dbus_interface.c revision 80d0bd38268c02fd32f62b02ae59f19229ca1a79
/*
Authors:
Pavel Březina <pbrezina@redhat.com>
Copyright (C) 2014 Red Hat
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <talloc.h>
#include <dhash.h>
#include "sbus/sssd_dbus.h"
#include "sbus/sssd_dbus_meta.h"
#include "sbus/sssd_dbus_private.h"
static struct sbus_interface *
const char *iface)
{
struct sbus_interface_list *item;
}
}
return NULL;
}
static errno_t
struct sbus_interface_list *list,
struct sbus_interface_list **_copy)
{
struct sbus_interface_list *new_item;
struct sbus_interface_list *item;
return EOK;
}
return ENOMEM;
}
/* already in list */
continue;
}
goto done;
}
}
done:
}
return ret;
}
/**
* Object paths that represent all objects under the path:
*/
static bool sbus_opath_is_subtree(const char *path)
{
if (len < 2) {
return false;
}
}
/**
* If the path represents a subtree object path, this function will
* remove /~* from the end.
*/
const char *object_path)
{
char *tree_path;
return NULL;
}
if (!sbus_opath_is_subtree(tree_path)) {
return tree_path;
}
/* replace / only if it is not a root path (only slash) */
return tree_path;
}
const char *path)
{
char *subtree;
char *slash;
/* first remove /~* from the end, stop when we have reached the root i.e.
* subtree == "/" */
return NULL;
}
/* Find the first separator and replace the part with asterisk. */
/* we cannot continue up */
return NULL;
}
/* this object path is invalid since it cannot end with slash */
return NULL;
}
/* because object path cannot end with / there is enough space for
* asterisk and terminating zero */
return subtree;
}
static void
void *pvt)
{
struct sbus_connection *conn;
char *path;
}
struct sbus_connection *conn,
{
}
static errno_t
const char *object_path,
struct sbus_interface *iface,
bool *_path_known)
{
bool path_known;
int hret;
return ENOMEM;
}
/* create new list item */
return ENOMEM;
}
/* first lookup existing list in hash table */
goto done;
}
if (hret == HASH_SUCCESS) {
/* This object path has already some interface registered. We will
* check for existence of the interface currently being added and
* add it if missing. */
path_known = true;
goto done;
}
goto done;
} else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
goto done;
}
/* otherwise create new hash entry and new list */
path_known = false;
if (hret != HASH_SUCCESS) {
goto done;
}
done:
} else {
}
return ret;
}
static bool
const char *object_path)
{
}
/**
* First @object_path is looked up in @table, if it is not found it steps up
* in the path hierarchy and try to lookup the parent node. This continues
* until the root is reached.
*/
static struct sbus_interface *
const char *object_path,
const char *iface_name)
{
char *lookup_path = NULL;
int hret;
return NULL;
}
if (lookup_path == NULL) {
goto done;
}
while (lookup_path != NULL) {
if (hret == HASH_SUCCESS) {
goto done;
}
} else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
"Unable to search hash table: hret=%d\n", hret);
goto done;
}
/* we will not free lookup path since it is freed with tmp_ctx
* and the object paths are supposed to be small */
}
done:
return iface;
}
/**
* Acquire list of all interfaces that are supported on given object path.
*/
const char *object_path,
struct sbus_interface_list **_list)
{
char *lookup_path = NULL;
int hret;
return ENOMEM;
}
goto done;
}
if (lookup_path == NULL) {
goto done;
}
while (lookup_path != NULL) {
if (hret == HASH_SUCCESS) {
goto done;
}
} else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
"Unable to search hash table: hret=%d\n", hret);
goto done;
}
/* we will not free lookup path since it is freed with tmp_ctx
* and the object paths are supposed to be small */
}
done:
return ret;
}
static struct sbus_interface *
const char *object_path,
struct sbus_vtable *iface_vtable,
void *instance_data)
{
struct sbus_interface *intf;
return NULL;
}
return NULL;
}
return intf;
}
static DBusHandlerResult
void *user_data);
static errno_t
const char *path)
{
"connection\n", path);
if (sbus_opath_is_subtree(path)) {
return ENOMEM;
}
/* D-Bus does not allow to have both object path and fallback
* registered. Since we handle the real message handlers ourselves
* we will register fallback only in this case. */
}
} else {
if (dbus_error_is_set(&error) &&
/* A fallback is probably already registered. Just return. */
return EOK;
}
}
if (!dbret) {
"%s with D-Bus connection.\n", path);
return ENOMEM;
}
return EOK;
}
struct sbus_vtable *iface_vtable,
const char *object_path,
void *pvt)
{
bool path_known;
return EINVAL;
}
return ENOMEM;
}
&path_known);
return ret;
}
if (path_known) {
/* this object path is already registered */
return EOK;
}
/* if ret != EOK we will still leave iface in the table, since
* we probably don't have enough memory to remove it correctly anyway */
return ret;
}
/* register standard interfaces with this object path as well */
object_path, conn);
return ret;
}
{
unsigned long count;
unsigned long i;
int hret;
if (hret != HASH_SUCCESS) {
goto done;
}
for (i = 0; i < count; i++) {
goto done;
}
}
done:
return ret;
}
static void
static DBusHandlerResult
void *user_data)
{
struct tevent_req *req;
struct sbus_connection *conn;
struct sbus_interface *iface;
struct sbus_request *sbus_req;
const struct sbus_method_meta *method;
const char *iface_name;
const char *method_name;
const char *path;
const char *sender;
/* header information */
/* try to find the interface */
path, iface_name);
goto fail;
}
goto fail;
}
/* we have a valid handler, create D-Bus request */
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
/* now get the sender ID */
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
return DBUS_HANDLER_RESULT_HANDLED;
fail: ;
return DBUS_HANDLER_RESULT_HANDLED;
}
static void
{
struct sbus_request *sbus_req;
const struct sbus_method_meta *method;
void *pvt;
return;
}
return;
}