summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2014-03-21 13:12:37 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-05-29 09:08:40 +0200
commit0bb98b7700b1b61f5b0a20b93279d5c2c391007f (patch)
tree8e965a93cec984d7a8e3667e8111e162b5153a3b
parentefa6c1f75c4c18bcc148d6e7efd429c2d56499ad (diff)
downloadsssd-0bb98b7700b1b61f5b0a20b93279d5c2c391007f.tar.gz
sssd-0bb98b7700b1b61f5b0a20b93279d5c2c391007f.tar.xz
sssd-0bb98b7700b1b61f5b0a20b93279d5c2c391007f.zip
sss_sifp: add shortcuts for common use cases
https://fedorahosted.org/sssd/ticket/2254 Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r--Makefile.am2
-rw-r--r--src/lib/sifp/sss_sifp.h56
-rw-r--r--src/lib/sifp/sss_sifp_common.c178
-rw-r--r--src/lib/sifp/sss_simpleifp.exports4
-rw-r--r--src/tests/cmocka/test_sss_sifp.c168
5 files changed, 408 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index 536bdfa9c..ac466a329 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -739,6 +739,7 @@ libsss_simpleifp_la_SOURCES = \
src/lib/sifp/sss_sifp.c \
src/lib/sifp/sss_sifp_dbus.c \
src/lib/sifp/sss_sifp_attrs.c \
+ src/lib/sifp/sss_sifp_common.c \
src/lib/sifp/sss_sifp_parser.c \
src/lib/sifp/sss_sifp_utils.c
libsss_simpleifp_la_CFLAGS = \
@@ -1816,6 +1817,7 @@ ifp_tests_LDADD = \
sss_sifp_tests_SOURCES = \
src/tests/cmocka/test_sss_sifp.c \
src/lib/sifp/sss_sifp_attrs.c \
+ src/lib/sifp/sss_sifp_common.c \
src/lib/sifp/sss_sifp_parser.c \
src/lib/sifp/sss_sifp_utils.c \
src/lib/sifp/sss_sifp_dbus.c \
diff --git a/src/lib/sifp/sss_sifp.h b/src/lib/sifp/sss_sifp.h
index 6f897135c..6b997951b 100644
--- a/src/lib/sifp/sss_sifp.h
+++ b/src/lib/sifp/sss_sifp.h
@@ -481,4 +481,60 @@ sss_sifp_free_string_array(sss_sifp_ctx *ctx,
/**
* @}
*/
+
+/**
+ * @defgroup common Most common use cases of SSSD InfoPipe responder.
+ * @{
+ */
+
+/**
+ * @brief List names of available domains.
+ *
+ * @param[in] ctx sss_sifp context
+ * @param[out] _domains List of domain names
+ */
+sss_sifp_error
+sss_sifp_list_domains(sss_sifp_ctx *ctx,
+ char ***_domains);
+
+/**
+ * @brief Fetch all information about domain by name.
+ *
+ * @param[in] ctx sss_sifp context
+ * @param[in] name Domain name
+ * @param[out] _domain Domain object
+ */
+sss_sifp_error
+sss_sifp_fetch_domain_by_name(sss_sifp_ctx *ctx,
+ const char *name,
+ sss_sifp_object **_domain);
+
+/**
+ * @brief Fetch all information about user by uid.
+ *
+ * @param[in] ctx sss_sifp context
+ * @param[in] uid User ID
+ * @param[out] _user User object
+ */
+sss_sifp_error
+sss_sifp_fetch_user_by_uid(sss_sifp_ctx *ctx,
+ uid_t uid,
+ sss_sifp_object **_user);
+
+/**
+ * @brief Fetch all information about user by name.
+ *
+ * @param[in] ctx sss_sifp context
+ * @param[in] name User name
+ * @param[out] _user User object
+ */
+sss_sifp_error
+sss_sifp_fetch_user_by_name(sss_sifp_ctx *ctx,
+ const char *name,
+ sss_sifp_object **_user);
+
+/**
+ * @}
+ */
+
#endif /* SSS_SIFP_H_ */
diff --git a/src/lib/sifp/sss_sifp_common.c b/src/lib/sifp/sss_sifp_common.c
new file mode 100644
index 000000000..2acd6c5a5
--- /dev/null
+++ b/src/lib/sifp/sss_sifp_common.c
@@ -0,0 +1,178 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2014 Red Hat
+
+ 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 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 <dbus/dbus.h>
+
+#include "lib/sifp/sss_sifp.h"
+#include "lib/sifp/sss_sifp_dbus.h"
+#include "lib/sifp/sss_sifp_private.h"
+
+#define SSS_SIFP_ATTR_NAME "name"
+
+static sss_sifp_error
+sss_sifp_fetch_object_by_attr(sss_sifp_ctx *ctx,
+ const char *method,
+ int attr_type,
+ const void *attr,
+ sss_sifp_object **_object)
+{
+ sss_sifp_object *object = NULL;
+ char *object_path = NULL;
+ const char *interface = NULL;
+ sss_sifp_error ret;
+
+ if (method == NULL || attr == NULL || attr_type == DBUS_TYPE_INVALID) {
+ return SSS_SIFP_INVALID_ARGUMENT;
+ }
+
+ ret = sss_sifp_invoke_find(ctx, method, &object_path,
+ attr_type, attr,
+ DBUS_TYPE_INVALID);
+ if (ret != SSS_SIFP_OK) {
+ goto done;
+ }
+
+ interface = sss_sifp_get_iface_for_object(object_path);
+ if (interface == NULL) {
+ return SSS_SIFP_INTERNAL_ERROR;
+ }
+
+ ret = sss_sifp_fetch_object(ctx, object_path, interface, &object);
+ if (ret != SSS_SIFP_OK) {
+ goto done;
+ }
+
+ *_object = object;
+
+ ret = SSS_SIFP_OK;
+
+done:
+ sss_sifp_free_string(ctx, &object_path);
+
+ return ret;
+}
+
+static sss_sifp_error
+sss_sifp_fetch_object_by_name(sss_sifp_ctx *ctx,
+ const char *method,
+ const char *name,
+ sss_sifp_object **_object)
+{
+ return sss_sifp_fetch_object_by_attr(ctx, method, DBUS_TYPE_STRING, &name,
+ _object);
+}
+
+sss_sifp_error
+sss_sifp_list_domains(sss_sifp_ctx *ctx,
+ char ***_domains)
+{
+ sss_sifp_attr **attrs = NULL;
+ char **object_paths = NULL;
+ char **domains = NULL;
+ const char *name = NULL;
+ unsigned int size;
+ unsigned int i;
+ sss_sifp_error ret;
+
+ if (_domains == NULL) {
+ return SSS_SIFP_INVALID_ARGUMENT;
+ }
+
+ ret = sss_sifp_invoke_list(ctx, "Domains", &object_paths,
+ DBUS_TYPE_INVALID);
+ if (ret != SSS_SIFP_OK) {
+ goto done;
+ }
+
+ /* calculate number of paths acquired and allocate memory for domains */
+ for (size = 0; object_paths[size] != NULL; size++);
+
+ domains = _alloc_zero(ctx, char *, size + 1);
+ if (domains == NULL) {
+ ret = SSS_SIFP_OUT_OF_MEMORY;
+ goto done;
+ }
+
+ /* fetch domain name */
+ for (i = 0; i < size; i++) {
+ ret = sss_sifp_fetch_attr(ctx, object_paths[i],
+ SSS_SIFP_IFACE_DOMAINS,
+ SSS_SIFP_ATTR_NAME, &attrs);
+ if (ret != SSS_SIFP_OK) {
+ goto done;
+ }
+
+ ret = sss_sifp_find_attr_as_string(attrs, SSS_SIFP_ATTR_NAME, &name);
+ if (ret != SSS_SIFP_OK) {
+ goto done;
+ }
+
+ domains[i] = sss_sifp_strdup(ctx, name);
+ if (domains[i] == NULL) {
+ ret = SSS_SIFP_OUT_OF_MEMORY;
+ goto done;
+ }
+
+ sss_sifp_free_attrs(ctx, &attrs);
+ }
+
+ domains[i] = NULL;
+
+ *_domains = domains;
+
+ ret = SSS_SIFP_OK;
+
+done:
+ sss_sifp_free_attrs(ctx, &attrs);
+ sss_sifp_free_string_array(ctx, &object_paths);
+
+ if (ret != SSS_SIFP_OK) {
+ sss_sifp_free_string_array(ctx, &domains);
+ }
+
+ return ret;
+}
+
+sss_sifp_error
+sss_sifp_fetch_domain_by_name(sss_sifp_ctx *ctx,
+ const char *name,
+ sss_sifp_object **_domain)
+{
+ return sss_sifp_fetch_object_by_name(ctx, "DomainByName", name, _domain);
+}
+
+sss_sifp_error
+sss_sifp_fetch_user_by_uid(sss_sifp_ctx *ctx,
+ uid_t uid,
+ sss_sifp_object **_user)
+{
+ uint64_t _uid = uid;
+
+ return sss_sifp_fetch_object_by_attr(ctx, "UserByID",
+ DBUS_TYPE_UINT64, &_uid, _user);
+}
+
+sss_sifp_error
+sss_sifp_fetch_user_by_name(sss_sifp_ctx *ctx,
+ const char *name,
+ sss_sifp_object **_user)
+{
+ return sss_sifp_fetch_object_by_name(ctx, "UserByName", name, _user);
+}
diff --git a/src/lib/sifp/sss_simpleifp.exports b/src/lib/sifp/sss_simpleifp.exports
index 921b49d58..3d598fb28 100644
--- a/src/lib/sifp/sss_simpleifp.exports
+++ b/src/lib/sifp/sss_simpleifp.exports
@@ -37,6 +37,10 @@ SSS_SIMPLEIFP_0.0 {
sss_sifp_free_object;
sss_sifp_free_string;
sss_sifp_free_string_array;
+ sss_sifp_list_domains;
+ sss_sifp_fetch_domain_by_name;
+ sss_sifp_fetch_user_by_uid;
+ sss_sifp_fetch_user_by_name;
# everything else is local
local:
diff --git a/src/tests/cmocka/test_sss_sifp.c b/src/tests/cmocka/test_sss_sifp.c
index 4a5fd7265..190dd7629 100644
--- a/src/tests/cmocka/test_sss_sifp.c
+++ b/src/tests/cmocka/test_sss_sifp.c
@@ -1648,6 +1648,170 @@ void test_sss_sifp_invoke_find_withargs(void **state)
assert_null(path_out);
}
+void test_sss_sifp_list_domains(void **state)
+{
+ sss_sifp_ctx *ctx = test_ctx.dbus_ctx;
+ DBusMessage *msg_paths = NULL;
+ DBusMessage *msg_ldap = NULL;
+ DBusMessage *msg_ipa = NULL;
+ dbus_bool_t bret;
+ sss_sifp_error ret;
+ const char *in[] = {SSS_SIFP_PATH_IFP "/Domains/LDAP",
+ SSS_SIFP_PATH_IFP "/Domains/IPA"};
+ const char **paths = in;
+ const char *names[] = {"LDAP", "IPA"};
+ char **out = NULL;
+ int in_len = 2;
+ int i;
+
+ msg_paths = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ assert_non_null(msg_paths);
+
+ msg_ldap = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ assert_non_null(msg_ldap);
+
+ msg_ipa = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ assert_non_null(msg_ipa);
+
+ /* prepare message */
+ bret = dbus_message_append_args(msg_paths, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_OBJECT_PATH,
+ &paths, in_len,
+ DBUS_TYPE_INVALID);
+ assert_true(bret);
+
+ reply_variant_basic(msg_ldap, DBUS_TYPE_STRING_AS_STRING, &names[0]);
+ reply_variant_basic(msg_ipa, DBUS_TYPE_STRING_AS_STRING, &names[1]);
+
+ will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_paths);
+ will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_ldap);
+ will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_ipa);
+
+ /* test */
+ ret = sss_sifp_list_domains(ctx, &out);
+ assert_int_equal(ret, SSS_SIFP_OK);
+ assert_non_null(out);
+
+ for (i = 0; i < in_len; i++) {
+ assert_non_null(out[i]);
+ assert_string_equal(out[i], names[i]);
+ }
+
+ assert_null(out[i]);
+
+ sss_sifp_free_string_array(ctx, &out);
+ assert_null(out);
+
+ /* messages are unrefed in the library */
+}
+
+void test_sss_sifp_fetch_domain_by_name(void **state)
+{
+ sss_sifp_ctx *ctx = test_ctx.dbus_ctx;
+ DBusMessage *msg_path = NULL;
+ DBusMessage *msg_props = NULL;
+ DBusMessageIter iter;
+ DBusMessageIter array_iter;
+ DBusMessageIter dict_iter;
+ DBusMessageIter var_iter;
+ dbus_bool_t bret;
+ sss_sifp_error ret;
+ const char *in =SSS_SIFP_PATH_IFP "/Domains/LDAP";
+ const char *name = "LDAP";
+ const char *prop = NULL;
+ sss_sifp_object *out = NULL;
+ struct {
+ const char *name;
+ const char *value;
+ } props[] = {{"name", name}, {"a1", "a"}, {"a2", "b"}, {NULL, 0}};
+ int i;
+
+
+ msg_path = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ assert_non_null(msg_path);
+
+ msg_props = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
+ assert_non_null(msg_props);
+
+ /* prepare message */
+ bret = dbus_message_append_args(msg_path, DBUS_TYPE_OBJECT_PATH, &in,
+ DBUS_TYPE_INVALID);
+ assert_true(bret);
+
+ dbus_message_iter_init_append(msg_props, &iter);
+
+ bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &array_iter);
+ assert_true(bret);
+
+ for (i = 0; props[i].name != NULL; i++) {
+ bret = dbus_message_iter_open_container(&array_iter,
+ DBUS_TYPE_DICT_ENTRY,
+ NULL, &dict_iter);
+ assert_true(bret);
+
+ bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING,
+ &props[i].name);
+ assert_true(bret);
+
+ bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_STRING_AS_STRING,
+ &var_iter);
+ assert_true(bret);
+
+ bret = dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_STRING,
+ &props[i].value);
+ assert_true(bret);
+
+ bret = dbus_message_iter_close_container(&dict_iter, &var_iter);
+ assert_true(bret);
+
+ bret = dbus_message_iter_close_container(&array_iter, &dict_iter);
+ assert_true(bret);
+ }
+
+ bret = dbus_message_iter_close_container(&iter, &array_iter);
+ assert_true(bret);
+
+ will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_path);
+ will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_props);
+
+ /* test */
+ ret = sss_sifp_fetch_domain_by_name(ctx, name, &out);
+ assert_int_equal(ret, SSS_SIFP_OK);
+ assert_non_null(out);
+ assert_non_null(out->attrs);
+ assert_non_null(out->name);
+ assert_non_null(out->object_path);
+ assert_non_null(out->interface);
+
+ assert_string_equal(out->name, name);
+ assert_string_equal(out->object_path, in);
+ assert_string_equal(out->interface, SSS_SIFP_IFACE_DOMAINS);
+
+ for (i = 0; props[i].name != NULL; i++) {
+ assert_non_null(out->attrs[i]);
+ assert_int_equal(out->attrs[i]->num_values, 1);
+ assert_int_equal(out->attrs[i]->type, SSS_SIFP_ATTR_TYPE_STRING);
+ assert_string_equal(out->attrs[i]->name, props[i].name);
+
+ ret = sss_sifp_find_attr_as_string(out->attrs, props[i].name, &prop);
+ assert_int_equal(ret, SSS_SIFP_OK);
+ assert_string_equal(props[i].value, prop);
+ }
+
+ assert_null(out->attrs[i]);
+
+ sss_sifp_free_object(ctx, &out);
+ assert_null(out);
+
+ /* messages are unrefed in the library */
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -1738,6 +1902,10 @@ int main(int argc, const char *argv[])
test_setup, test_teardown_api),
unit_test_setup_teardown(test_sss_sifp_invoke_find_withargs,
test_setup, test_teardown_api),
+ unit_test_setup_teardown(test_sss_sifp_list_domains,
+ test_setup, test_teardown_api),
+ unit_test_setup_teardown(test_sss_sifp_fetch_domain_by_name,
+ test_setup, test_teardown_api),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */