summaryrefslogtreecommitdiffstats
path: root/server/tests/infopipe-tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/tests/infopipe-tests.c')
-rw-r--r--server/tests/infopipe-tests.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/server/tests/infopipe-tests.c b/server/tests/infopipe-tests.c
new file mode 100644
index 000000000..2aaa653a6
--- /dev/null
+++ b/server/tests/infopipe-tests.c
@@ -0,0 +1,320 @@
+/*
+ SSSD
+
+ InfoPipe
+
+ Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009
+
+ 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 <stdlib.h>
+#include <check.h>
+#include <talloc.h>
+#include <tevent.h>
+#include <popt.h>
+#include <dbus/dbus.h>
+#include "util/util.h"
+#include "confdb/confdb.h"
+#include "sbus/sssd_dbus.h"
+#include "infopipe/infopipe.h"
+
+#define INFP_TEST_DBUS_NAME "org.freeipa.sssd.infopipe1.test"
+#define TEST_TIMEOUT 30000 /* 30 seconds */
+
+static int setup_infp_tests(DBusConnection **bus)
+{
+ DBusError error;
+ int ret;
+
+ /* Connect to the system bus */
+ dbus_error_init(&error);
+ *bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (*bus == NULL) {
+ fail("Could not connect to the system bus. %s:%s", error.name, error.message);
+ dbus_error_free(&error);
+ return EIO;
+ }
+
+ /* Abort the tests if disconnect occurs */
+ dbus_connection_set_exit_on_disconnect(*bus, TRUE);
+
+ ret = dbus_bus_request_name(*bus,
+ INFP_TEST_DBUS_NAME,
+ /* We want exclusive access */
+ DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ &error);
+ if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ /* We were unable to register on the system bus */
+ fail("Unable to request name on the system bus. Error: %s:%s\n", error.name, error.message);
+ dbus_error_free(&error);
+ return EIO;
+ }
+ return EOK;
+}
+
+static int teardown_infp_tests(DBusConnection *bus)
+{
+ dbus_connection_unref(bus);
+ return EOK;
+}
+
+#define INTROSPECT_CHUNK_SIZE 4096
+START_TEST(test_infp_introspect)
+{
+ TALLOC_CTX *tmp_ctx;
+ DBusConnection *bus;
+ DBusError error;
+ DBusMessage *introspect_req;
+ DBusMessage *reply;
+ FILE *xml_stream;
+ char *chunk;
+ char *introspect_xml;
+ char *returned_xml;
+ unsigned long xml_size;
+ size_t chunk_size;
+ int type;
+
+ if (setup_infp_tests(&bus) != EOK) {
+ fail("Could not set up the tests");
+ return;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ fail("Could not create temporary talloc context");
+ goto done;
+ }
+
+ /* Create introspection method call */
+ introspect_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME,
+ INFOPIPE_PATH,
+ DBUS_INTROSPECT_INTERFACE,
+ DBUS_INTROSPECT_METHOD);
+ if(!introspect_req) {
+ fail("Could not create new method call message");
+ goto done;
+ }
+
+ /* Send the message */
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(bus,
+ introspect_req,
+ TEST_TIMEOUT,
+ &error);
+ if(!reply) {
+ fail("Could not send message. Error: %s:%s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ /* Read in the reference Introspection XML */
+ xml_stream = fopen("introspect.ref", "r");
+ if(xml_stream == NULL) {
+ DEBUG(0, ("Could not open the introspection XML for reading: [%d].\n", errno));
+ return;
+ }
+
+ chunk = talloc_size(tmp_ctx, INTROSPECT_CHUNK_SIZE);
+ if (chunk == NULL) goto done;
+
+ xml_size = 0;
+ introspect_xml = NULL;
+ do {
+ chunk_size = fread(chunk, 1, INTROSPECT_CHUNK_SIZE, xml_stream);
+ introspect_xml = talloc_realloc_size(tmp_ctx, introspect_xml, xml_size+chunk_size+1);
+ if (introspect_xml == NULL) goto done;
+
+ memcpy(introspect_xml+xml_size, chunk, chunk_size);
+ xml_size += chunk_size;
+ } while(chunk_size == INTROSPECT_CHUNK_SIZE);
+ introspect_xml[xml_size] = '\0';
+ talloc_free(chunk);
+
+ /* Get the XML from the message */
+ dbus_message_get_args(reply, &error,
+ DBUS_TYPE_STRING, &returned_xml,
+ DBUS_TYPE_INVALID);
+
+ /* Verify that the reply matches the reference file */
+ if (strcmp(introspect_xml, returned_xml) != 0) {
+ fail("Verify Introspection XML: FAILED");
+ }
+ break;
+ case DBUS_MESSAGE_TYPE_ERROR:
+ fail("Error: %s\n", dbus_message_get_error_name(reply));
+ goto done;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ teardown_infp_tests(bus);
+}
+END_TEST
+
+START_TEST(test_infp_check_permissions)
+{
+ TALLOC_CTX *tmp_ctx;
+ DBusConnection *bus;
+ DBusError error;
+ DBusMessage *permission_req;
+ DBusMessage *reply;
+ DBusMessageIter msg_iter;
+ DBusMessageIter array_iter;
+ DBusMessageIter struct_iter;
+ dbus_bool_t *permission_array;
+ int permission_count;
+ char *domain;
+ char *object;
+ char *instance;
+ char *action;
+ char *attribute;
+ int type, i;
+
+ if (setup_infp_tests(&bus) != EOK) {
+ fail("Could not set up the tests");
+ return;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ fail("Could not create temporary talloc context");
+ goto done;
+ }
+
+ /* Create permission request message */
+ permission_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME,
+ INFOPIPE_PATH,
+ INFOPIPE_INTERFACE,
+ INFP_CHECK_PERMISSIONS);
+ if(!permission_req) {
+ fail("Could not create new method call message");
+ goto done;
+ }
+
+ /* Add arguments */
+ domain = talloc_strdup(tmp_ctx, "LOCAL");
+ object = talloc_strdup(tmp_ctx, "user");
+ instance = talloc_strdup(tmp_ctx, "testuser1");
+ action = talloc_strdup(tmp_ctx, "modify");
+ attribute = talloc_strdup(tmp_ctx, "userpic");
+
+ dbus_message_append_args(permission_req,
+ DBUS_TYPE_STRING, &domain,
+ DBUS_TYPE_STRING, &object,
+ DBUS_TYPE_STRING, &instance,
+ DBUS_TYPE_INVALID);
+
+ dbus_message_iter_init_append(permission_req, &msg_iter);
+ dbus_message_iter_open_container(&msg_iter,
+ DBUS_TYPE_ARRAY, "(ss)", /* Array of structs */
+ &array_iter);
+ dbus_message_iter_open_container(&array_iter,
+ DBUS_TYPE_STRUCT, NULL,
+ &struct_iter);
+ dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &action);
+ dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_STRING, &attribute);
+ dbus_message_iter_close_container(&array_iter, &struct_iter);
+ dbus_message_iter_close_container(&msg_iter, &array_iter);
+
+
+ /* Send the message */
+ dbus_error_init(&error);
+ reply = dbus_connection_send_with_reply_and_block(bus,
+ permission_req,
+ TEST_TIMEOUT,
+ &error);
+ if(!reply) {
+ fail("Could not send message. Error: %s:%s", error.name, error.message);
+ dbus_error_free(&error);
+ goto done;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_ERROR:
+ fail("Error: %s\n", dbus_message_get_error_name(reply));
+ goto done;
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ dbus_message_get_args(reply, &error,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &permission_array, &permission_count,
+ DBUS_TYPE_INVALID);
+ }
+
+ i = 0;
+ while(i < permission_count) {
+ if (permission_array[i] == true) {
+ fail("User was granted permission unexpectedly");
+ goto done;
+ }
+ i++;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ teardown_infp_tests(bus);
+}
+END_TEST
+
+Suite *create_infopipe_suite(void)
+{
+ Suite *s = suite_create("infopipe");
+
+ TCase *tc_infp = tcase_create("InfoPipe Tests");
+
+ /* Test the Introspection XML */
+ tcase_add_test(tc_infp, test_infp_introspect);
+ tcase_add_test(tc_infp, test_infp_check_permissions);
+
+/* Add all test cases to the test suite */
+ suite_add_tcase(s, tc_infp);
+
+ return s;
+}
+
+int main(int argc, const char *argv[]) {
+ int opt;
+ poptContext pc;
+ int failure_count;
+ Suite *infopipe_suite;
+ SRunner *sr;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_MAIN_OPTS
+ { NULL }
+ };
+
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch(opt) {
+ default:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ }
+ poptFreeContext(pc);
+
+ infopipe_suite = create_infopipe_suite();
+ sr = srunner_create(infopipe_suite);
+ srunner_run_all(sr, CK_VERBOSE);
+ failure_count = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE);
+}