From bb4570d2f3ed0c9b780010623de82c4c76d15a2c Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Mon, 20 Jul 2009 13:57:04 -0400 Subject: Remove unused InfoPipe and PolicyKit code --- server/Makefile.am | 66 +- server/conf_macros.m4 | 34 - server/configure.ac | 2 - server/infopipe/infopipe.c | 748 -------- server/infopipe/infopipe.h | 116 -- server/infopipe/infopipe_groups.c | 832 --------- server/infopipe/infopipe_private.h | 98 -- server/infopipe/infopipe_users.c | 1846 -------------------- .../org.freedesktop.sssd.infopipe.Introspect.xml | 277 --- server/infopipe/org.freedesktop.sssd.infopipe.conf | 24 - server/infopipe/sysbus.c | 198 --- server/infopipe/sysbus.h | 37 - server/polkit/sssd_polkit.c | 206 --- server/polkit/sssd_polkit.h | 28 - server/tests/infopipe-privileged-tests.c | 615 ------- server/tests/infopipe-tests.c | 405 ----- 16 files changed, 2 insertions(+), 5530 deletions(-) delete mode 100644 server/infopipe/infopipe.c delete mode 100644 server/infopipe/infopipe.h delete mode 100644 server/infopipe/infopipe_groups.c delete mode 100644 server/infopipe/infopipe_private.h delete mode 100644 server/infopipe/infopipe_users.c delete mode 100644 server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml delete mode 100644 server/infopipe/org.freedesktop.sssd.infopipe.conf delete mode 100644 server/infopipe/sysbus.c delete mode 100644 server/infopipe/sysbus.h delete mode 100644 server/polkit/sssd_polkit.c delete mode 100644 server/polkit/sssd_polkit.h delete mode 100644 server/tests/infopipe-privileged-tests.c delete mode 100644 server/tests/infopipe-tests.c (limited to 'server') diff --git a/server/Makefile.am b/server/Makefile.am index 63d98bcd..539c9006 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -41,23 +41,6 @@ sbin_PROGRAMS = \ sss_usermod \ sss_groupmod -if BUILD_POLICYKIT -sssd_pk = sssd_pk -polkit_headers = \ - polkit/sssd_polkit.h -endif - -if BUILD_INFOPIPE -infpintrospectdir = $(dbusintrospectdir)/infopipe -sssd_info = sssd_info -infopipe_tests = infopipe-tests -infopipe_privileged_tests = infopipe-privileged-tests -infopipe_headers = \ - infopipe/infopipe_private.h \ - infopipe/sysbus.h \ - infopipe/infopipe.h -endif - sssdlibexec_PROGRAMS = \ sssd_nss \ sssd_pam \ @@ -69,9 +52,7 @@ sssdlibexec_PROGRAMS = \ if BUILD_TESTS noinst_PROGRAMS = \ sysdb-tests \ - stress-tests \ - $(infopipe_tests) \ - $(infopipe_privileged_tests) + stress-tests endif sssdlib_LTLIBRARIES = \ @@ -215,9 +196,7 @@ dist_noinst_HEADERS = \ providers/ldap/sdap.h \ providers/ldap/sdap_async.h \ tools/tools_util.h \ - krb5_plugin/sssd_krb5_locator_plugin.h \ - $(infopipe_headers) \ - $(polkit_headers) + krb5_plugin/sssd_krb5_locator_plugin.h #################### # Program Binaries # @@ -264,27 +243,6 @@ sssd_be_LDFLAGS = \ -Wl,--version-script,$(srcdir)/providers/sssd_be.exports \ -export-dynamic -if BUILD_POLICYKIT -sssd_pk_SOURCES = \ - polkit/sssd_polkit.c \ - $(SSSD_UTIL_OBJ) -sssd_pk_LDADD = $(SSSD_LIBS) -endif - -if BUILD_INFOPIPE -sssd_info_SOURCES = \ - infopipe/infopipe.c \ - infopipe/infopipe_groups.c \ - infopipe/infopipe_users.c \ - infopipe/sysbus.c \ - $(SSSD_UTIL_OBJ) -sssd_info_LDADD = $(SSSD_LIBS) -dbuspolicy_DATA = \ - infopipe/org.freedesktop.sssd.infopipe.conf -infpintrospect_DATA = \ - infopipe/org.freedesktop.sssd.infopipe.Introspect.xml -endif - dist_noinst_DATA = \ examples/sssd.conf \ examples/sssdproxylocal \ @@ -356,26 +314,6 @@ stress_tests_SOURCES = \ stress_tests_LDADD = \ $(SSSD_LIBS) -if BUILD_INFOPIPE -infopipe_tests_SOURCES = \ - tests/infopipe-tests.c \ - $(SSSD_UTIL_OBJ) -infopipe_tests_CFLAGS = \ - $(CHECK_CFLAGS) -infopipe_tests_LDADD = \ - $(SSSD_LIBS) \ - $(CHECK_LIBS) - -infopipe_privileged_tests_SOURCES = \ - tests/infopipe-privileged-tests.c \ - $(SSSD_UTIL_OBJ) -infopipe_privileged_tests_CFLAGS = \ - $(CHECK_CFLAGS) -infopipe_privileged_tests_LDADD = \ - $(SSSD_LIBS) \ - $(CHECK_LIBS) -endif #BUILD_INFOPIPE - endif #BUILD_TESTS #################### diff --git a/server/conf_macros.m4 b/server/conf_macros.m4 index c67b47b0..2613bfb3 100644 --- a/server/conf_macros.m4 +++ b/server/conf_macros.m4 @@ -66,40 +66,6 @@ AC_DEFUN([WITH_PIPE_PATH], AC_DEFINE_UNQUOTED(PIPE_PATH, "$config_pipepath", [Where to store pipe files for the SSSD interconnects]) ]) -AC_DEFUN([WITH_POLICYKIT], - [ AC_ARG_WITH([policykit], - [AC_HELP_STRING([--with-policykit], - [Whether to include PolicyKit support [yes]] - ) - ], - [], - with_policykit=yes - ) - if test x"$with_policykit" == xyes; then - AC_DEFINE(HAVE_POLICYKIT, 1, [Include PolicyKit support]) - HAVE_POLICYKIT=1 - AC_SUBST(HAVE_POLICYKIT) - fi - ]) -AM_CONDITIONAL([BUILD_POLICYKIT], [test x$with_policykit = xyes]) - -AC_DEFUN([WITH_INFOPIPE], - [ AC_ARG_WITH([infopipe], - [AC_HELP_STRING([--with-infopipe], - [Whether to include InfoPipe support [yes]] - ) - ], - [], - with_infopipe=yes - ) - if test x"$with_infopipe" == xyes; then - AC_DEFINE(HAVE_INFOPIPE, 1, [Include InfoPipe support]) - HAVE_INFOPIPE=1 - AC_SUBST(HAVE_INFOPIPE) - fi - ]) -AM_CONDITIONAL([BUILD_INFOPIPE], [test x$with_infopipe = xyes]) - AC_DEFUN([WITH_TESTS], [ AC_ARG_WITH([tests], [AC_HELP_STRING([--with-tests], diff --git a/server/configure.ac b/server/configure.ac index facefe27..084ef3bc 100644 --- a/server/configure.ac +++ b/server/configure.ac @@ -42,8 +42,6 @@ WITH_DB_PATH WITH_PLUGIN_PATH WITH_PID_PATH WITH_PIPE_PATH -WITH_INFOPIPE -WITH_POLICYKIT WITH_TESTS WITH_INIT_DIR WITH_SHADOW_UTILS_PATH diff --git a/server/infopipe/infopipe.c b/server/infopipe/infopipe.c deleted file mode 100644 index 72998301..00000000 --- a/server/infopipe/infopipe.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ -#define _GNU_SOURCE -#include -#include -#include "popt.h" -#include "util/util.h" -#include "util/btreemap.h" -#include "sbus/sssd_dbus.h" -#include "sbus/sbus_client.h" -#include "db/sysdb.h" -#include "confdb/confdb.h" -#include "monitor/monitor_sbus.h" -#include "monitor/monitor_interfaces.h" -#include "infopipe/sysbus.h" -#include "infopipe/infopipe.h" -#include "infopipe/infopipe_private.h" - -#define INFP_CONF_ENTRY "config/services/info" - -static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - dbus_uint16_t version = INFOPIPE_VERSION; - const char *name = INFOPIPE_SERVICE_NAME; - DBusMessage *reply; - dbus_bool_t ret; - - DEBUG(4, ("Sending identity data [%s,%d]\n", name, version)); - - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - ret = dbus_message_append_args(reply, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); - if (!ret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - return EOK; -} - -static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - dbus_bool_t ret; - - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - ret = dbus_message_append_args(reply, DBUS_TYPE_INVALID); - if (!ret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - return EOK; -} - -static int service_reload(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - /* Monitor calls this function when we need to reload - * our configuration information. Perform whatever steps - * are needed to update the configuration objects. - */ - - /* Send an empty reply to acknowledge receipt */ - return service_pong(message, sconn); -} - -struct sbus_method mon_sbus_methods[] = { - { SERVICE_METHOD_IDENTITY, service_identity }, - { SERVICE_METHOD_PING, service_pong }, - { SERVICE_METHOD_RELOAD, service_reload }, - { NULL, NULL } -}; - -static int infp_monitor_init(struct infp_ctx *infp_ctx) -{ - int ret; - char *sbus_address; - struct service_sbus_ctx *ss_ctx; - struct sbus_method_ctx *sm_ctx; - - /* Set up SBUS connection to the monitor */ - ret = monitor_get_sbus_address(infp_ctx, infp_ctx->cdb, &sbus_address); - if (ret != EOK) { - DEBUG(0, ("Could not locate monitor address.\n")); - return ret; - } - - ret = monitor_init_sbus_methods(infp_ctx, mon_sbus_methods, &sm_ctx); - if (ret != EOK) { - DEBUG(0, ("Could not initialize SBUS methods.\n")); - return ret; - } - - ret = sbus_client_init(infp_ctx, infp_ctx->ev, - sbus_address, sm_ctx, - NULL /* Private Data */, - NULL /* Destructor */, - &ss_ctx); - if (ret != EOK) { - DEBUG(0, ("Failed to connect to monitor services.\n")); - return ret; - } - - /* Set up InfoPipe-specific listeners */ - /* None currently used */ - - infp_ctx->ss_ctx = ss_ctx; - - return EOK; -} - -/* Helper function to return an immediate error message in the event - * of internal error in the InfoPipe to avoid forcing the clients to - * time out waiting for a reply. - * This function will make a best effort to send a reply, but if it - * fails, clients will simply have to handle the timeout. - */ -void infp_return_failure(struct infp_req_ctx *infp_req, const char *message) -{ - DBusMessage *reply; - - if(infp_req == NULL) return; - - reply = dbus_message_new_error(infp_req->req_message, - DBUS_ERROR_FAILED, - message); - /* If the reply was NULL, we ran out of memory, so we won't - * bother trying to queue the message to send. In this case, - * our safest move is to allow the client to time out waiting - * for a reply. - */ - if(reply) { - sbus_conn_send_reply(infp_req->sconn, reply); - dbus_message_unref(reply); - } -} - -/* Helper function to return an ack to the caller to indicate - * that the internal process completed succesfully. An ack in - * InfoPipe is simply an empty D-BUS method return (as opposed - * to a D-BUS error or signal) - */ -void infp_return_success(struct infp_req_ctx *infp_req) -{ - DBusMessage *reply; - - if (infp_req == NULL) return; - - reply = dbus_message_new_method_return(infp_req->req_message); - /* If the reply was NULL, we ran out of memory, so we won't - * bother trying to queue the message to send. In this case, - * our safest move is to allow the client to time out waiting - * for a reply. - */ - if(reply) { - sbus_conn_send_reply(infp_req->sconn, reply); - dbus_message_unref(reply); - } -} - -struct sbus_method infp_methods[] = { - INFP_PERMISSION_METHODS - INFP_USER_METHODS - INFP_GROUP_METHODS - { NULL, NULL } -}; - -int infp_introspect(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - FILE *xml_stream = NULL; - struct infp_ctx *infp; - long xml_size, read_size; - int ret; - dbus_bool_t dbret; - - infp = talloc_get_type(sbus_conn_get_private_data(sconn), struct infp_ctx); - - if (infp->introspect_xml == NULL) { - - /* Read in the Introspection XML the first time */ - xml_stream = fopen(SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, "r"); - if(xml_stream == NULL) { - ret = errno; - DEBUG(0, ("Could not open [%s] for reading. [%d:%s]\n", - SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, - ret, strerror(ret))); - return ret; - } - - if (fseek(xml_stream, 0L, SEEK_END) != 0) { - ret = errno; - DEBUG(0, ("Could not seek into [%s]. [%d:%s]\n", - SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, - ret, strerror(ret))); - goto done; - } - - errno = 0; - xml_size = ftell(xml_stream); - if (xml_size <= 0) { - ret = errno; - DEBUG(0, ("Could not get [%s] length (or file is empty). [%d:%s]\n", - SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, - ret, strerror(ret))); - goto done; - } - - if (fseek(xml_stream, 0L, SEEK_SET) != 0) { - ret = errno; - DEBUG(0, ("Could not seek into [%s]. [%d:%s]\n", - SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, - ret, strerror(ret))); - goto done; - } - - infp->introspect_xml = talloc_size(infp, xml_size+1); - if (!(infp->introspect_xml)) { - ret = ENOMEM; - goto done; - } - - read_size = fread(infp->introspect_xml, 1, xml_size, xml_stream); - if (read_size < xml_size) { - if (!feof(xml_stream)) { - ret = ferror(xml_stream); - DEBUG(0, ("Error occurred while reading [%s]. [%d:%s]\n", - SSSD_INTROSPECT_PATH"/"INFP_INTROSPECT_XML, - ret, strerror(ret))); - - talloc_free(infp->introspect_xml); - infp->introspect_xml = NULL; - goto done; - } - } - - /* Copy the introspection XML to the infp_ctx */ - infp->introspect_xml[xml_size+1] = '\0'; - } - - /* Return the Introspection XML */ - reply = dbus_message_new_method_return(message); - if (reply == NULL) { - ret = ENOMEM; - goto done; - } - dbret = dbus_message_append_args(reply, - DBUS_TYPE_STRING, &infp->introspect_xml, - DBUS_TYPE_INVALID); - if (!dbret) { - ret = ENOMEM; - goto done; - } - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - DEBUG(9, ("%s\n", infp->introspect_xml)); - ret = EOK; - -done: - if (xml_stream) fclose(xml_stream); - return ret; -} - -struct infp_req_ctx *infp_req_init(TALLOC_CTX *mem_ctx, DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - struct infp_req_ctx *infp_req; - - /* Create an infp_req_ctx */ - infp_req = talloc_zero(mem_ctx, struct infp_req_ctx); - if (infp_req == NULL) { - return NULL; - } - - infp_req->infp = talloc_get_type(sbus_conn_get_private_data(sconn), struct infp_ctx); - infp_req->sconn = sconn; - infp_req->req_message = message; - infp_req->caller = sysbus_get_caller(infp_req, - infp_req->req_message, - infp_req->sconn); - if (infp_req->caller == NULL) { - talloc_free(infp_req); - return NULL; - } - - return infp_req; -} - -static int infp_process_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct confdb_ctx *cdb) -{ - struct infp_ctx *infp_ctx; - int ret; - - infp_ctx = talloc_zero(mem_ctx, struct infp_ctx); - if (infp_ctx == NULL) { - DEBUG(0, ("Fatal error initializing infp_ctx\n")); - return ENOMEM; - } - infp_ctx->ev = ev; - infp_ctx->cdb = cdb; - - /* Connect to the monitor */ - ret = infp_monitor_init(infp_ctx); - if (ret != EOK) { - DEBUG(0, ("Fatal error setting up monitor bus\n")); - talloc_free(infp_ctx); - return EIO; - } - - /* Connect to the D-BUS system bus and set up methods */ - ret = sysbus_init(infp_ctx, &infp_ctx->sysbus, - infp_ctx->ev, INFOPIPE_DBUS_NAME, - INFOPIPE_INTERFACE, INFOPIPE_PATH, - infp_methods, infp_introspect); - if (ret != EOK) { - DEBUG(0, ("Failed to connect to the system message bus\n")); - talloc_free(infp_ctx); - return EIO; - } - - /* Connect to the sysdb */ - ret = sysdb_init(infp_ctx, infp_ctx->ev, infp_ctx->cdb, - NULL, &infp_ctx->sysdb); - if (ret != EOK) { - DEBUG(0, ("Failed to connect to the cache database\n")); - talloc_free(infp_ctx); - return EIO; - } - - /* Read in the domain map */ - ret = confdb_get_domains(cdb, infp_ctx, &infp_ctx->domains); - if (ret != EOK) { - DEBUG(0, ("Failed to populate the domain map\n")); - talloc_free(infp_ctx); - return EIO; - } - - infp_ctx->cache_timeout = 600; /* FIXME: read from confdb */ - - /* Add the infp_ctx to the sbus_conn_ctx private data - * so we can pass it into message handler functions - */ - sbus_conn_set_private_data(sysbus_get_sbus_conn(infp_ctx->sysbus), infp_ctx); - - return EOK; -} - -int infp_get_object_type(const char *obj) -{ - int object_type = INFP_OBJ_TYPE_INVALID; - - if (strcasecmp(obj, "user") == 0) - object_type = INFP_OBJ_TYPE_USER; - else if (strcasecmp(obj, "group") == 0) - object_type = INFP_OBJ_TYPE_GROUP; - - return object_type; -} - -int infp_get_action_type(const char *action) -{ - int action_type = INFP_ACTION_TYPE_INVALID; - - if (strcasecmp(action, "read") == 0) - action_type = INFP_ACTION_TYPE_READ; - else if (strcasecmp(action, "create") == 0) - action_type = INFP_ACTION_TYPE_CREATE; - else if ((strcasecmp(action, "delete") == 0)) - action_type = INFP_ACTION_TYPE_DELETE; - else if ((strcasecmp(action, "modify") == 0)) - action_type = INFP_ACTION_TYPE_MODIFY; - else if ((strcasecmp(action, "addmember") == 0)) - action_type = INFP_ACTION_TYPE_ADDMEMBER; - else if ((strcasecmp(action, "removemember") == 0)) - action_type = INFP_ACTION_TYPE_REMOVEMEMBER; - - return action_type; -} - -int infp_get_attribute_type(const char *attribute) -{ - int attribute_type = INFP_ATTR_TYPE_INVALID; - - if(attribute == NULL) - return INFP_ATTR_TYPE_INVALID; - - if(strcasecmp(attribute, "defaultgroup") == 0) - attribute_type = INFP_ATTR_TYPE_DEFAULTGROUP; - else if (strcasecmp(attribute, "gecos") == 0) { - attribute_type = INFP_ATTR_TYPE_GECOS; - } - else if (strcasecmp(attribute, "homedir") == 0) { - attribute_type = INFP_ATTR_TYPE_HOMEDIR; - } - else if (strcasecmp(attribute, "shell") == 0) { - attribute_type = INFP_ATTR_TYPE_SHELL; - } - else if (strcasecmp(attribute, "fullname") == 0) { - attribute_type = INFP_ATTR_TYPE_FULLNAME; - } - else if (strcasecmp(attribute, "locale") == 0) { - attribute_type = INFP_ATTR_TYPE_LOCALE; - } - else if (strcasecmp(attribute, "keyboard") == 0) { - attribute_type = INFP_ATTR_TYPE_KEYBOARD; - } - else if (strcasecmp(attribute, "session") == 0) { - attribute_type = INFP_ATTR_TYPE_SESSION; - } - else if (strcasecmp(attribute, "last_login") == 0) { - attribute_type = INFP_ATTR_TYPE_LAST_LOGIN; - } - else if (strcasecmp(attribute, "userpic") == 0) { - attribute_type = INFP_ATTR_TYPE_USERPIC; - } - - return attribute_type; -} - -bool infp_get_permissions(const char *caller, - struct sss_domain_info *domain, - int object_type, - const char *instance, - int action_type, - int action_attribute) -{ - /* TODO: have a real ACL mechanism. - * For right now, root is God and no one else can do anything. - * Note: this is buggy. It will return true for ALL requests, - * even the nonsensical ones. - */ - if (strcmp(caller, "root") == 0) - return true; - return false; -} - -struct sss_domain_info *infp_get_domain_obj(struct infp_ctx *infp, - const char *domain_name) -{ - struct sss_domain_info *dom; - - for (dom = infp->domains; dom; dom = dom->next) { - if (strcasecmp(dom->name, domain_name) == 0) break; - } - return dom; -} - -/* CheckPermissions(STRING domain, STRING object, STRING instance - * ARRAY(STRING action_type, STRING attribute) actions) - */ -int infp_check_permissions(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - TALLOC_CTX *tmp_ctx; - struct infp_ctx *infp; - int current_type; - char *caller; - DBusMessageIter iter; - DBusMessageIter action_array_iter; - DBusMessageIter action_struct_iter; - int object_type; - const char *einval_msg; - const char *domain_name; - struct sss_domain_info *domain; - const char *object; - const char *instance; - const char *action; - const char *attribute; - int action_type, attribute_type; - dbus_bool_t *permissions; - size_t count; - - tmp_ctx = talloc_new(NULL); - if(tmp_ctx == NULL) { - return ENOMEM; - } - - infp = talloc_get_type(sbus_conn_get_private_data(sconn), struct infp_ctx); - - /* Get the caller */ - caller = sysbus_get_caller(tmp_ctx, message, sconn); - if (caller == NULL) { - return EIO; - } - - if (!dbus_message_iter_init(message, &iter)) { - einval_msg = talloc_strdup(tmp_ctx, "No arguments received."); - goto einval; - } - - /* domain */ - current_type = dbus_message_iter_get_arg_type (&iter); - if (current_type != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(tmp_ctx, "Expected domain"); - goto einval; - } - dbus_message_iter_get_basic(&iter, &domain_name); - DEBUG(9, ("Domain: %s\n", domain_name)); - domain = infp_get_domain_obj(infp, domain_name); - - /* Object */ - dbus_message_iter_next(&iter); - current_type = dbus_message_iter_get_arg_type (&iter); - if (current_type != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(tmp_ctx, "Expected object"); - goto einval; - } - dbus_message_iter_get_basic(&iter, &object); - DEBUG(9, ("Object: %s\n", object)); - object_type = infp_get_object_type(object); - if (object_type == INFP_OBJ_TYPE_INVALID) { - einval_msg = talloc_strdup(tmp_ctx, "Invalid object type"); - goto einval; - } - - /* Instance */ - dbus_message_iter_next(&iter); - current_type = dbus_message_iter_get_arg_type (&iter); - if (current_type != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(tmp_ctx, "Expected instance"); - goto einval; - } - dbus_message_iter_get_basic(&iter, &instance); - DEBUG(9, ("Instance: %s\n", instance)); - if(strcmp(instance,"")==0) { - instance = NULL; - } - - /* Actions */ - dbus_message_iter_next(&iter); - current_type = dbus_message_iter_get_arg_type (&iter); - if (current_type != DBUS_TYPE_ARRAY) { - einval_msg = talloc_strdup(tmp_ctx, "Expected array of actions"); - goto einval; - } - - dbus_message_iter_recurse(&iter, &action_array_iter); - count = 0; - permissions = NULL; - while((current_type=dbus_message_iter_get_arg_type(&action_array_iter)) != DBUS_TYPE_INVALID) { - if (current_type != DBUS_TYPE_STRUCT) { - einval_msg = talloc_strdup(tmp_ctx, "Action array entry was not a struct"); - goto einval; - } - dbus_message_iter_recurse(&action_array_iter, &action_struct_iter); - /* action_type */ - if (dbus_message_iter_get_arg_type(&action_struct_iter) != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(tmp_ctx, "Missing action_type"); - goto einval; - } - dbus_message_iter_get_basic(&action_struct_iter, &action); - DEBUG(9, ("Action type: %s\n", action)); - action_type = infp_get_action_type(action); - if(action_type == INFP_ACTION_TYPE_INVALID) { - einval_msg = talloc_asprintf(tmp_ctx, "Action type [%s] is not valid", action); - goto einval; - } - - /* attribute */ - dbus_message_iter_next(&action_struct_iter); - if (dbus_message_iter_get_arg_type(&action_struct_iter) != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(tmp_ctx, "Missing attribute"); - goto einval; - } - dbus_message_iter_get_basic(&action_struct_iter, &attribute); - DEBUG(9, ("Action attribute: %s\n", attribute)); - attribute_type = infp_get_attribute_type(attribute); - if(attribute_type == INFP_ATTR_TYPE_INVALID) { - einval_msg = talloc_asprintf(tmp_ctx, "Attribute [%s] is not valid", attribute); - goto einval; - } - - if (dbus_message_iter_has_next(&action_struct_iter)) { - einval_msg = talloc_strdup(tmp_ctx, "Unexpected value in action struct"); - goto einval; - } - - /* Process the actions */ - count++; - permissions=talloc_realloc(tmp_ctx, permissions, dbus_bool_t, count); - permissions[count-1] = infp_get_permissions(caller, domain, - object_type, instance, - action_type, attribute_type); - - dbus_message_iter_next(&action_array_iter); - } - - /* Create response message */ - reply = dbus_message_new_method_return(message); - if (reply == NULL) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - dbus_message_append_args(reply, - DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &permissions, count, - DBUS_TYPE_INVALID); - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(tmp_ctx); - return EOK; - -einval: - reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, einval_msg); - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(tmp_ctx); - return EOK; -} - -int infp_get_ldb_val_from_dbus(TALLOC_CTX *mem_ctx, DBusMessageIter *iter, struct ldb_val **value, int dbus_type, int subtype) -{ - struct ldb_val *val = NULL; - void *tmp; - size_t element_size; - int num_elements; - int ret; - - val = talloc_zero(mem_ctx, struct ldb_val); - if (val == NULL) { - ret = ENOMEM; - goto done; - } - - /* Fixed-size types */ - if (sbus_is_dbus_fixed_type(dbus_type)) { - dbus_message_iter_get_basic(iter, &tmp); - val->length = sbus_get_dbus_type_size(dbus_type); - } - - else if (sbus_is_dbus_string_type(dbus_type)) { - dbus_message_iter_get_basic(iter, &tmp); - val->length = strlen((const char *)tmp); - } - - else if (dbus_type == DBUS_TYPE_ARRAY) { - if (!sbus_is_dbus_fixed_type(subtype)) { - ret = EINVAL; - goto done; - } - - element_size = sbus_get_dbus_type_size(subtype); - dbus_message_iter_get_fixed_array(iter, &tmp, &num_elements); - val->length = num_elements * element_size; - } - else { - /* Unsupported type */ - ret = EINVAL; - goto done; - } - - val->data = talloc_memdup(val, tmp, val->length); - if (val->data == NULL) { - ret = ENOMEM; - goto done; - } - - *value = val; - ret = EOK; - -done: - if (ret != EOK) { - talloc_free(val); - *value = NULL; - } - return ret; -} - -int main(int argc, const char *argv[]) -{ - int opt; - poptContext pc; - struct main_context *main_ctx; - int ret; - - 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); - - /* set up things like debug , signals, daemonization, etc... */ - ret = server_setup("sssd[info]", 0, INFP_CONF_ENTRY, &main_ctx); - if (ret != EOK) return 2; - - ret = infp_process_init(main_ctx, - main_ctx->event_ctx, - main_ctx->confdb_ctx); - if (ret != EOK) return 3; - - /* loop on main */ - server_loop(main_ctx); - - return 0; -} diff --git a/server/infopipe/infopipe.h b/server/infopipe/infopipe.h deleted file mode 100644 index 51670376..00000000 --- a/server/infopipe/infopipe.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ - -#ifndef INFOPIPE_H_ -#define INFOPIPE_H_ - -#include -#include "sbus/sssd_dbus.h" - -#define INFP_INTROSPECT_XML "infopipe/org.freedesktop.sssd.infopipe.Introspect.xml" - -#define INFOPIPE_DBUS_NAME "org.freedesktop.sssd.infopipe1" -#define INFOPIPE_INTERFACE "org.freedesktop.sssd.infopipe1" -#define INFOPIPE_PATH "/org/freedesktop/sssd/infopipe1" -#define INFOPIPE_VERSION 0x0001 -#define INFOPIPE_SERVICE_NAME "info" - -/* InfoPipe Methods - * NOTE: Any changes to the method names and arguments for these calls - * must also be updated in the org.freedesktop.sssd.infopipe.Introspect.xml - * or clients may not behave properly. - */ - -/********************************************************** - * Introspection Methods (from infopipe.c) * - **********************************************************/ - -/* This function must be exposed through the - * org.freedesktop.DBus.Introspectable interface - */ -#define INFP_INTROSPECT "Introspect" -int infp_introspect(DBusMessage *message, struct sbus_conn_ctx *sconn); - -/********************************************************** - * Permission Methods (from infopipe.c) * - **********************************************************/ -#define INFP_CHECK_PERMISSIONS "CheckPermissions1" -int infp_check_permissions(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_PERMISSION_METHODS \ - {INFP_CHECK_PERMISSIONS,infp_check_permissions}, - -/********************************************************** - * User Methods (from infopipe_users.c) * - **********************************************************/ -#define INFP_USERS_GET_CACHED "GetCachedUsers1" -int infp_users_get_cached(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USERS_CREATE "CreateUser1" -int infp_users_create(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USERS_DELETE "DeleteUser1" -int infp_users_delete(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USERS_GET_ATTR "GetUserAttributes1" -int infp_users_get_attr(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USERS_SET_ATTR "SetUserAttributes1" -int infp_users_set_attr(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USERS_SET_UID "Set_YouReallyDoNotWantToUseThisFunction_UserUID1" -int infp_users_set_uid(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_USER_METHODS \ - {INFP_USERS_GET_CACHED, infp_users_get_cached}, \ - {INFP_USERS_CREATE, infp_users_create}, \ - {INFP_USERS_DELETE, infp_users_delete}, \ - {INFP_USERS_GET_ATTR, infp_users_get_attr}, \ - {INFP_USERS_SET_ATTR, infp_users_set_attr}, \ - {INFP_USERS_SET_UID, infp_users_set_uid}, - -/********************************************************** - * Group Methods (from infopipe_groups.c) * - **********************************************************/ - -#define INFP_GROUPS_CREATE "CreateGroup1" -int infp_groups_create(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_GROUPS_DELETE "DeleteGroup1" -int infp_groups_delete(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_GROUPS_ADD_MEMBERS "AddGroupMembers1" -int infp_groups_add_members(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_GROUPS_REMOVE_MEMBERS "RemoveGroupMembers1" -int infp_groups_remove_members(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_GROUPS_SET_GID "Set_YouReallyDoNotWantToUseThisFunction_GroupGID1" -int infp_groups_set_gid(DBusMessage *message, struct sbus_conn_ctx *sconn); - -#define INFP_GROUP_METHODS \ - {INFP_GROUPS_CREATE, infp_groups_create}, \ - {INFP_GROUPS_DELETE, infp_groups_delete}, \ - {INFP_GROUPS_ADD_MEMBERS, infp_groups_add_members}, \ - {INFP_GROUPS_REMOVE_MEMBERS, infp_groups_remove_members}, \ - {INFP_GROUPS_SET_GID, infp_groups_set_gid}, - -#endif /* INFOPIPE_H_ */ diff --git a/server/infopipe/infopipe_groups.c b/server/infopipe/infopipe_groups.c deleted file mode 100644 index a2fe5a40..00000000 --- a/server/infopipe/infopipe_groups.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ - -#include -#include -#include -#include "util/util.h" -#include "util/btreemap.h" -#include "confdb/confdb.h" -#include "infopipe/infopipe.h" -#include "infopipe/infopipe_private.h" -#include "infopipe/sysbus.h" -#include "db/sysdb.h" - -struct infp_creategroup_ctx { - struct infp_req_ctx *infp_req; - char **groupnames; - uint32_t name_count; - uint32_t index; - struct sysdb_handle *handle; -}; - -static void infp_do_group_create(struct sysdb_handle *handle, void *pvt); -static void infp_do_group_create_callback(void *pvt, int status, - struct ldb_result *res) -{ - char *error_msg = NULL; - DBusMessage *reply = NULL; - struct infp_creategroup_ctx *grcreate_req = - talloc_get_type(pvt, struct infp_creategroup_ctx); - - if (status != EOK) { - sysdb_transaction_done(grcreate_req->handle, status); - - if (status == EEXIST) { - error_msg = - talloc_asprintf(grcreate_req, - "Group [%s] already exists on domain [%s]", - grcreate_req->groupnames[grcreate_req->index], - grcreate_req->infp_req->domain->name); - reply = dbus_message_new_error(grcreate_req->infp_req->req_message, - DBUS_ERROR_FILE_EXISTS, - error_msg); - if (reply) - sbus_conn_send_reply(grcreate_req->infp_req->sconn, reply); - } - else { - infp_return_failure(grcreate_req->infp_req, NULL); - } - talloc_free(grcreate_req); - return; - } - - /* Status is okay, add the next group */ - grcreate_req->index++; - if (grcreate_req->index < grcreate_req->name_count) { - infp_do_group_create(grcreate_req->handle, grcreate_req); - return; - } - - /* We have no more usernames to add, so commit the transaction */ - sysdb_transaction_done(grcreate_req->handle, status); - - infp_return_success(grcreate_req->infp_req); - talloc_free(grcreate_req); - return; -} - -static void infp_do_group_create(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct infp_creategroup_ctx *grcreate_req = - talloc_get_type(pvt, struct infp_creategroup_ctx); - - grcreate_req->handle = handle; - - ret = sysdb_add_group(grcreate_req->handle, - grcreate_req->infp_req->domain, - grcreate_req->groupnames[grcreate_req->index], 0, - infp_do_group_create_callback, grcreate_req); - if (ret != EOK) { - DEBUG(0, ("Could not invoke sysdb_add_group\n")); - sysdb_transaction_done(grcreate_req->handle, ret); - infp_return_failure(grcreate_req->infp_req, NULL); - talloc_free(grcreate_req); - return; - } -} - -int infp_groups_create(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - struct infp_creategroup_ctx *grcreate_req; - char *einval_msg; - int ret, i; - - /* Arguments */ - char **arg_grnames = NULL; - int arg_grnames_count; - const char *arg_domain; - - grcreate_req = talloc_zero(NULL, struct infp_creategroup_ctx); - if(grcreate_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - grcreate_req->infp_req = infp_req_init(grcreate_req, message, sconn); - if(grcreate_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &arg_grnames, &arg_grnames_count, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_INVALID)) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_GROUPS_CREATE, error.name, error.message)); - einval_msg = talloc_strdup(grcreate_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow creating groups on domains other than LOCAL */ - if (strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - grcreate_req->infp_req->domain = - infp_get_domain_obj(grcreate_req->infp_req->infp, arg_domain); - if (grcreate_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(grcreate_req, "Invalid domain."); - goto einval; - } - - /* Check permissions */ - if (!infp_get_permissions(grcreate_req->infp_req->caller, - grcreate_req->infp_req->domain, - INFP_OBJ_TYPE_GROUP, - NULL, - INFP_ACTION_TYPE_CREATE, - INFP_ATTR_TYPE_INVALID)) goto denied; - - grcreate_req->groupnames = talloc_array(grcreate_req, - char *, - arg_grnames_count); - if (grcreate_req->groupnames == NULL) { - ret = ENOMEM; - goto error; - } - - grcreate_req->name_count = arg_grnames_count; - for (i = 0; i < arg_grnames_count; i++) { - grcreate_req->groupnames[i] = talloc_strdup(grcreate_req->groupnames, - arg_grnames[i]); - if (grcreate_req->groupnames[i] == NULL) { - ret = ENOMEM; - goto error; - } - } - dbus_free_string_array(arg_grnames); - arg_grnames = NULL; - - grcreate_req->index = 0; - ret = sysdb_transaction(grcreate_req, - grcreate_req->infp_req->infp->sysdb, - infp_do_group_create, - grcreate_req); - - if (ret != EOK) goto error; - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(grcreate_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - if (arg_grnames) dbus_free_string_array(arg_grnames); - talloc_free(grcreate_req); - return EOK; - -error: - if (arg_grnames) dbus_free_string_array(arg_grnames); - if(grcreate_req) infp_return_failure(grcreate_req->infp_req, NULL); - talloc_free(grcreate_req); - return ret; -} - -struct infp_deletegroup_ctx { - struct infp_req_ctx *infp_req; - struct ldb_dn *gr_dn; - struct sysdb_handle *handle; -}; - -static void infp_do_group_delete_callback(void *pvt, int status, - struct ldb_result *res) -{ - struct infp_deletegroup_ctx *grdel_req = - talloc_get_type(pvt, struct infp_deletegroup_ctx); - - /* Commit or cancel the transaction, based on the status */ - sysdb_transaction_done(grdel_req->handle, status); - - if (status != EOK) { - DEBUG(0, ("Failed to delete group from sysdb. Error code %d\n", - status)); - infp_return_failure(grdel_req->infp_req, NULL); - talloc_free(grdel_req); - return; - } - - infp_return_success(grdel_req->infp_req); - talloc_free(grdel_req); -} - -static void infp_do_group_delete(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct infp_deletegroup_ctx *grdel_req = - talloc_get_type(pvt, struct infp_deletegroup_ctx); - - grdel_req->handle = handle; - - ret = sysdb_delete_entry(grdel_req->handle, - grdel_req->gr_dn, - infp_do_group_delete_callback, - grdel_req); - if (ret != EOK) { - DEBUG(0, ("Could not delete group entry\n")); - infp_return_failure(grdel_req->infp_req, NULL); - talloc_free(grdel_req); - return; - } -} - -int infp_groups_delete(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - char *einval_msg; - int ret; - struct infp_deletegroup_ctx *grdel_req; - - /* Arguments */ - const char *arg_grname; - const char *arg_domain; - - grdel_req = talloc_zero(NULL, struct infp_deletegroup_ctx); - if(grdel_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - grdel_req->infp_req = infp_req_init(grdel_req, message, sconn); - if(grdel_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - if(!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_grname, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_INVALID)) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_GROUPS_DELETE, error.name, error.message)); - einval_msg = talloc_strdup(grdel_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow deleting groups from domains other than LOCAL */ - if(strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - grdel_req->infp_req->domain = - infp_get_domain_obj(grdel_req->infp_req->infp, arg_domain); - if (grdel_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(grdel_req, "Invalid domain."); - goto einval; - } - - /* Check permissions */ - if (!infp_get_permissions(grdel_req->infp_req->caller, - grdel_req->infp_req->domain, - INFP_OBJ_TYPE_GROUP, - NULL, - INFP_ACTION_TYPE_CREATE, - INFP_ATTR_TYPE_INVALID)) goto denied; - - grdel_req->gr_dn = sysdb_group_dn(grdel_req->infp_req->infp->sysdb, - grdel_req, - grdel_req->infp_req->domain->name, - arg_grname); - if(grdel_req->gr_dn == NULL) { - DEBUG(0, ("Could not construct a group_dn for deletion.\n")); - ret = EIO; - goto error; - } - - ret = sysdb_transaction(grdel_req, - grdel_req->infp_req->infp->sysdb, - infp_do_group_delete, - grdel_req); - if (ret != EOK) { - DEBUG(0, ("Unable to start transaction to delete group\n")); - goto error; - } - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(grdel_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - talloc_free(grdel_req); - return EOK; - -error: - if (grdel_req) infp_return_failure(grdel_req->infp_req, NULL); - talloc_free(grdel_req); - return ret; -} - -enum infp_gr_member_types { - INFP_GR_MEM_USER = 0, - INFP_GR_MEM_GROUP -}; - -struct infp_groupmember_ctx { - struct infp_req_ctx *infp_req; - struct ldb_dn *group_dn; - char **membernames; - uint32_t member_count; - uint32_t index; - uint8_t member_type; - uint8_t modify_type; - struct sysdb_handle *handle; -}; - -static void infp_do_member(struct sysdb_handle *handle, void *pvt); - -static void infp_do_member_callback(void *pvt, int status, - struct ldb_result *res) -{ - char *fail_msg; - DBusMessage *reply = NULL; - struct infp_groupmember_ctx *grmod_req = - talloc_get_type(pvt, struct infp_groupmember_ctx); - - /* Check the results of the current add */ - if(status != EOK) goto fail; - - /* Check if there are more members to process */ - grmod_req->index++; - if(grmod_req->index < grmod_req->member_count) { - infp_do_member(grmod_req->handle, grmod_req); - return; - } - - /* This was the last member. Commit the transaction */ - sysdb_transaction_done(grmod_req->handle, EOK); - - /* Send an ack reply */ - reply = dbus_message_new_method_return(grmod_req->infp_req->req_message); - if(reply) { - sbus_conn_send_reply(grmod_req->infp_req->sconn, reply); - dbus_message_unref(reply); - } - - talloc_free(grmod_req); - return; - -fail: -sysdb_transaction_done(grmod_req->handle, status); - fail_msg = talloc_asprintf(grmod_req, "Could not modify group"); - infp_return_failure(grmod_req->infp_req, fail_msg); - talloc_free(grmod_req); - return; -} - -static void infp_do_member(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct ldb_dn *member_dn; - struct infp_groupmember_ctx *grmod_req = - talloc_get_type(pvt, struct infp_groupmember_ctx); - - grmod_req->handle = handle; - - if (grmod_req->member_type == INFP_GR_MEM_USER) { - member_dn = - sysdb_user_dn(grmod_req->infp_req->infp->sysdb, - grmod_req, - grmod_req->infp_req->domain->name, - grmod_req->membernames[grmod_req->index]); - if (member_dn == NULL) goto error; - } - else if (grmod_req->member_type == INFP_GR_MEM_GROUP) { - member_dn = - sysdb_group_dn(grmod_req->infp_req->infp->sysdb, - grmod_req, - grmod_req->infp_req->domain->name, - grmod_req->membernames[grmod_req->index]); - if (member_dn == NULL) goto error; - } - else goto error; - - if (grmod_req->modify_type == INFP_ACTION_TYPE_ADDMEMBER) { - ret = sysdb_add_group_member(grmod_req->handle, - member_dn, - grmod_req->group_dn, - infp_do_member_callback, - grmod_req); - } - else if (grmod_req->modify_type == INFP_ACTION_TYPE_REMOVEMEMBER) { - ret = sysdb_remove_group_member(grmod_req->handle, - member_dn, - grmod_req->group_dn, - infp_do_member_callback, - grmod_req); - } - if (ret != EOK) goto error; - - return; - -error: - infp_return_failure(grmod_req->infp_req, NULL); - talloc_free(grmod_req); - return; -} - -static int infp_groups_modify_members(DBusMessage *message, - struct sbus_conn_ctx *sconn, - uint8_t modify_type) -{ - DBusMessage *reply; - DBusError error; - struct infp_groupmember_ctx *grmod_req; - char *einval_msg; - int ret, i; - - /* Arguments */ - const char *arg_group; - const char *arg_domain; - char **arg_members = NULL; - int arg_member_count; - uint8_t arg_membertype; - - grmod_req = talloc_zero(NULL, struct infp_groupmember_ctx); - if (grmod_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - grmod_req->infp_req = infp_req_init(grmod_req, message, sconn); - if(grmod_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_group, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, - &arg_members, &arg_member_count, - DBUS_TYPE_BYTE, &arg_membertype, - DBUS_TYPE_INVALID)) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_GROUPS_ADD_MEMBERS, error.name, error.message)); - einval_msg = talloc_strdup(grmod_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow modifying groups on domains other than LOCAL */ - if (strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - grmod_req->infp_req->domain = - infp_get_domain_obj(grmod_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (grmod_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(grmod_req, "Invalid domain."); - goto einval; - } - - /* Check permissions */ - if (!infp_get_permissions(grmod_req->infp_req->caller, - grmod_req->infp_req->domain, - INFP_OBJ_TYPE_GROUP, - arg_group, - modify_type, - INFP_ATTR_TYPE_INVALID)) goto denied; - - grmod_req->member_count = arg_member_count; - grmod_req->membernames = talloc_array(grmod_req, char *, - arg_member_count); - if (grmod_req == NULL) { - ret = ENOMEM; - goto error; - } - for (i = 0; i < arg_member_count; i++) { - grmod_req->membernames[i] = talloc_strdup(grmod_req->membernames, - arg_members[i]); - if(grmod_req->membernames[i] == NULL) { - ret = ENOMEM; - goto error; - } - } - dbus_free_string_array(arg_members); - arg_members = NULL; - - grmod_req->group_dn = - sysdb_group_dn(grmod_req->infp_req->infp->sysdb, - grmod_req, - grmod_req->infp_req->domain->name, - arg_group); - if (grmod_req->group_dn == NULL) { - ret = EIO; - goto error; - } - - grmod_req->index = 0; - grmod_req->modify_type = modify_type; - grmod_req->member_type = arg_membertype; - if ((grmod_req->member_type != INFP_GR_MEM_USER) && - (grmod_req->member_type != INFP_GR_MEM_GROUP)) { - einval_msg = talloc_strdup(grmod_req, - "Invalid member type"); - goto einval; - } - - ret = sysdb_transaction(grmod_req, - grmod_req->infp_req->infp->sysdb, - infp_do_member, - grmod_req); - if (ret != EOK) goto error; - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - if (arg_members) dbus_free_string_array(arg_members); - talloc_free(grmod_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - if (arg_members) dbus_free_string_array(arg_members); - talloc_free(grmod_req); - return EOK; - -error: - if (arg_members) dbus_free_string_array(arg_members); - talloc_free(grmod_req); - return ret; -} - -int infp_groups_add_members(DBusMessage *message, - struct sbus_conn_ctx *sconn) -{ - return infp_groups_modify_members(message, sconn, - INFP_ACTION_TYPE_ADDMEMBER); -} - -int infp_groups_remove_members(DBusMessage *message, - struct sbus_conn_ctx *sconn) -{ - return infp_groups_modify_members(message, sconn, - INFP_ACTION_TYPE_REMOVEMEMBER); -} - -struct infp_setgid_ctx { - struct infp_req_ctx *infp_req; - char *group_name; - gid_t gid; - struct sysdb_handle *handle; -}; - -static void infp_do_gid_callback(void *ptr, - int status, - struct ldb_result *res) -{ - char *error_msg = NULL; - struct infp_setgid_ctx *grmod_req = - talloc_get_type(ptr, struct infp_setgid_ctx); - - /* Commit or cancel the transaction, based on the - * return status - */ - sysdb_transaction_done(grmod_req->handle, status); - - if(status != EOK) { - if (status == ENOENT) { - error_msg = talloc_strdup(grmod_req, "No such group"); - } - infp_return_failure(grmod_req->infp_req, error_msg); - talloc_free(grmod_req); - return; - } - - infp_return_success(grmod_req->infp_req); - talloc_free(grmod_req); -} - -static void infp_do_gid(struct sysdb_handle *handle, void *pvt) -{ - int ret; - DBusMessage *reply; - char *error_msg; - gid_t max; - struct infp_setgid_ctx *grmod_req = - talloc_get_type(pvt, struct infp_setgid_ctx); - grmod_req->handle = handle; - - ret = sysdb_set_group_gid(grmod_req->handle, - grmod_req->infp_req->domain, - grmod_req->group_name, - grmod_req->gid, - infp_do_gid_callback, - grmod_req); - if (ret != EOK) { - if(ret == EDOM) { - /* GID was out of range */ - max = grmod_req->infp_req->domain->id_max? - grmod_req->infp_req->domain->id_max: - (gid_t)-1; - error_msg = talloc_asprintf(grmod_req, - "GID %u outside the range [%u..%u]", - grmod_req->gid, - grmod_req->infp_req->domain->id_min, - max); - reply = dbus_message_new_error(grmod_req->infp_req->req_message, - DBUS_ERROR_LIMITS_EXCEEDED, - error_msg); - if (reply) sbus_conn_send_reply(grmod_req->infp_req->sconn, reply); - } - infp_return_failure(grmod_req->infp_req, NULL); - talloc_free(grmod_req); - return; - } -} - -int infp_groups_set_gid(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - char *einval_msg; - struct infp_setgid_ctx *grmod_req; - int ret; - - /* Arguments */ - const char *arg_group; - const char *arg_domain; - const gid_t arg_gid; - - grmod_req = talloc_zero(NULL, struct infp_setgid_ctx); - if (grmod_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - grmod_req->infp_req = infp_req_init(grmod_req, message, sconn); - if(grmod_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - if (!dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_group, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_UINT32, &arg_gid, - DBUS_TYPE_INVALID)) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_GROUPS_SET_GID, error.name, error.message)); - einval_msg = talloc_strdup(grmod_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow modifying groups on domains other than LOCAL */ - if (strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - grmod_req->infp_req->domain = - infp_get_domain_obj(grmod_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (grmod_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(grmod_req, "Invalid domain."); - goto einval; - } - - /* Check permissions */ - if (!infp_get_permissions(grmod_req->infp_req->caller, - grmod_req->infp_req->domain, - INFP_OBJ_TYPE_GROUP, - arg_group, - INFP_ACTION_TYPE_MODIFY, - INFP_ATTR_TYPE_GROUPID)) goto denied; - - grmod_req->gid = arg_gid; - grmod_req->group_name = talloc_strdup(grmod_req, arg_group); - if (grmod_req->group_name == NULL) { - ret = ENOMEM; - goto error; - } - - ret = sysdb_transaction(grmod_req, - grmod_req->infp_req->infp->sysdb, - infp_do_gid, - grmod_req); - if (ret != EOK) goto error; - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(grmod_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - talloc_free(grmod_req); - return EOK; - -error: - if(grmod_req) infp_return_failure(grmod_req->infp_req, NULL); - talloc_free(grmod_req); - return ret; -} diff --git a/server/infopipe/infopipe_private.h b/server/infopipe/infopipe_private.h deleted file mode 100644 index 7317f7a6..00000000 --- a/server/infopipe/infopipe_private.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ - -#ifndef INFOPIPE_PRIVATE_H_ -#define INFOPIPE_PRIVATE_H_ - -struct infp_ctx { - struct tevent_context *ev; - struct confdb_ctx *cdb; - struct service_sbus_ctx *ss_ctx; - struct sysbus_ctx *sysbus; - struct sysdb_ctx *sysdb; - struct sss_domain_info *domains; - char *introspect_xml; - - int cache_timeout; -}; - -struct infp_req_ctx { - struct infp_ctx *infp; - struct sbus_conn_ctx *sconn; - DBusMessage *req_message; - struct sss_domain_info *domain; - char *caller; -}; - -enum infp_object_types { - INFP_OBJ_TYPE_INVALID = 0, - INFP_OBJ_TYPE_USER, - INFP_OBJ_TYPE_GROUP -}; -int infp_get_object_type(const char *obj); - -enum infp_action_types { - INFP_ACTION_TYPE_INVALID = 0, - INFP_ACTION_TYPE_READ, - INFP_ACTION_TYPE_CREATE, - INFP_ACTION_TYPE_DELETE, - INFP_ACTION_TYPE_MODIFY, - INFP_ACTION_TYPE_ADDMEMBER, - INFP_ACTION_TYPE_REMOVEMEMBER -}; -int infp_get_action_type(const char *action); - -enum infp_attribute_types { - INFP_ATTR_TYPE_INVALID = 0, - INFP_ATTR_TYPE_DEFAULTGROUP, - INFP_ATTR_TYPE_GECOS, - INFP_ATTR_TYPE_HOMEDIR, - INFP_ATTR_TYPE_SHELL, - INFP_ATTR_TYPE_FULLNAME, - INFP_ATTR_TYPE_LOCALE, - INFP_ATTR_TYPE_KEYBOARD, - INFP_ATTR_TYPE_SESSION, - INFP_ATTR_TYPE_LAST_LOGIN, - INFP_ATTR_TYPE_USERPIC, - INFP_ATTR_TYPE_USERID, - INFP_ATTR_TYPE_GROUPID -}; -int infp_get_attribute_type(const char *attribute); - -int infp_get_user_attr_dbus_type(int attr_type, int *subtype); - -bool infp_get_permissions(const char *caller, - struct sss_domain_info *domain, - int object_type, - const char *instance, - int action_type, - int action_attribute); - -struct sss_domain_info *infp_get_domain_obj(struct infp_ctx *infp, const char *domain_name); - -int infp_get_ldb_val_from_dbus(TALLOC_CTX *mem_ctx, DBusMessageIter *iter, struct ldb_val **value, int dbus_type, int subtype); - -struct infp_req_ctx *infp_req_init(TALLOC_CTX *mem_ctx, DBusMessage *message, struct sbus_conn_ctx *sconn); - -void infp_return_success(struct infp_req_ctx *infp_req); -void infp_return_failure(struct infp_req_ctx *infp_req, const char *message); - -#endif /* INFOPIPE_PRIVATE_H_ */ diff --git a/server/infopipe/infopipe_users.c b/server/infopipe/infopipe_users.c deleted file mode 100644 index aac79f7f..00000000 --- a/server/infopipe/infopipe_users.c +++ /dev/null @@ -1,1846 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ -#include -#include -#include -#include "util/util.h" -#include "util/btreemap.h" -#include "confdb/confdb.h" -#include "infopipe/infopipe.h" -#include "infopipe/infopipe_private.h" -#include "infopipe/sysbus.h" -#include "db/sysdb.h" -#include "responder/common/responder.h" - -static int attr_comparator(const void *key1, const void *key2); -static int username_comparator(const void *key1, const void *key2); - -struct infp_getcached_ctx { - struct infp_req_ctx *infp_req; - struct sysdb_handle *handle; - char **usernames; - uint64_t min_last_login; -}; -static void infp_users_get_cached_callback(void *ptr, - int status, - struct ldb_result *res) -{ - DBusMessage *reply; - DBusMessageIter iter, array_iter; - dbus_bool_t dbret; - int i; - char *username; - struct infp_getcached_ctx *infp_getcached_req = - talloc_get_type(ptr, struct infp_getcached_ctx); - - if (status != LDB_SUCCESS) { - DEBUG(0, ("Failed to enumerate users in the cache db.\n")); - infp_return_failure(infp_getcached_req->infp_req, NULL); - talloc_free(infp_getcached_req); - return; - } - - /* Construct a reply */ - reply = dbus_message_new_method_return(infp_getcached_req->infp_req->req_message); - if(reply == NULL) { - infp_return_failure(infp_getcached_req->infp_req, NULL); - talloc_free(infp_getcached_req); - return; - } - - dbus_message_iter_init_append(reply, &iter); - dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - "s", &array_iter); - if (!dbret) goto error; - - for (i = 0; i < res->count; i++) { - username = talloc_strdup(infp_getcached_req, - ldb_msg_find_attr_as_string(res->msgs[i], - SYSDB_NAME, - NULL)); - if (username != NULL) { - dbret = dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, &username); - if (!dbret) goto error; - } - } - dbret = dbus_message_iter_close_container(&iter, &array_iter); - if(!dbret) goto error; - - sbus_conn_send_reply(infp_getcached_req->infp_req->sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_getcached_req); - return; - -error: - DEBUG(0, - ("Critical error constructing reply message for %s\n", - INFP_USERS_GET_CACHED)); - dbus_message_unref(reply); - infp_return_failure(infp_getcached_req->infp_req, NULL); - talloc_free(infp_getcached_req); - return; -} - -int infp_users_get_cached(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - dbus_bool_t dbret; - char *einval_msg; - char *search_expression; - struct infp_getcached_ctx *infp_getcached_req; - int ret; - - /* Arguments */ - const char *arg_domain; - const uint64_t arg_minlastlogin; - - infp_getcached_req = talloc_zero(NULL, struct infp_getcached_ctx); - if (infp_getcached_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - infp_getcached_req->infp_req = infp_req_init(infp_getcached_req, - message, sconn); - if (infp_getcached_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - dbret = dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_UINT64, &arg_minlastlogin, - DBUS_TYPE_INVALID); - if(!dbret) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_USERS_GET_CACHED, error.name, error.message)); - einval_msg = talloc_strdup(infp_getcached_req, error.message); - dbus_error_free(&error); - goto einval; - } - - infp_getcached_req->min_last_login = arg_minlastlogin; - - infp_getcached_req->infp_req->domain = - infp_get_domain_obj(infp_getcached_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (infp_getcached_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(infp_getcached_req, "Invalid domain."); - goto einval; - } - - /* NOTE: not checking permissions since the - * information here is all visible in NSS as well - */ - - /* Call sysdb_enumpwent with special search parameters */ - search_expression = talloc_asprintf(infp_getcached_req, - SYSDB_GETCACHED_FILTER, - infp_getcached_req->min_last_login); - ret = sysdb_enumpwent(infp_getcached_req, - infp_getcached_req->infp_req->infp->sysdb, - infp_getcached_req->infp_req->domain, - search_expression, - infp_users_get_cached_callback, infp_getcached_req); - if(ret != EOK) { - DEBUG(0, ("Could not read from the cache database.\n")); - goto error; - } - - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - talloc_free(infp_getcached_req); - return EOK; - -error: - if (infp_getcached_req) - infp_return_failure(infp_getcached_req->infp_req, NULL); - talloc_free(infp_getcached_req); - return ret; -} - -struct infp_createuser_ctx { - struct infp_req_ctx *infp_req; - struct sysdb_handle *handle; - - char *username; - char *fullname; - char *homedir; - char *shell; -}; - -static void infp_do_user_create_callback(void *pvt, - int status, - struct ldb_result *res) -{ - char *error_msg = NULL; - DBusMessage *reply = NULL; - struct infp_createuser_ctx *infp_createuser_req = talloc_get_type(pvt, struct infp_createuser_ctx); - - /* Commit the transaction if it we got a successful response, or cancel it if we did not */ - sysdb_transaction_done(infp_createuser_req->handle, status); - - /* Verify that the addition completed successfully - * If LDB returned an error, run a search to determine - * if it was due the requested username already being - * in use - */ - if (status == EOK) { - /* Return reply ack */ - infp_return_success(infp_createuser_req->infp_req); - } - else if (status == EEXIST) { - /* Return error, user already exists */ - error_msg = talloc_asprintf(infp_createuser_req, - "User [%s] already exists on domain [%s]", - infp_createuser_req->username, - infp_createuser_req->infp_req->domain->name); - reply = dbus_message_new_error(infp_createuser_req->infp_req->req_message, - DBUS_ERROR_FILE_EXISTS, - error_msg); - if (reply) { - sbus_conn_send_reply(infp_createuser_req->infp_req->sconn, reply); - dbus_message_unref(reply); - } - } - else { - /* Unknown error occurred. Print DEBUG message */ - DEBUG(0, ("Failed to create user in the sysdb. Error code %d\n", status)); - infp_return_failure(infp_createuser_req->infp_req, NULL); - } - - talloc_free(infp_createuser_req); -} - -static void infp_do_user_create(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct infp_createuser_ctx *infp_createuser_req = talloc_get_type(pvt, struct infp_createuser_ctx); - infp_createuser_req->handle = handle; - - ret = sysdb_add_user(infp_createuser_req->handle, - infp_createuser_req->infp_req->domain, - infp_createuser_req->username, - 0, 0, - infp_createuser_req->fullname, - infp_createuser_req->homedir, - infp_createuser_req->shell, - infp_do_user_create_callback, - infp_createuser_req); - if (ret != EOK) { - DEBUG(0, ("Could not invoke sysdb_add_user\n")); - sysdb_transaction_done(infp_createuser_req->handle, ret); - infp_return_failure(infp_createuser_req->infp_req, NULL); - talloc_free(infp_createuser_req); - return; - } -} - -int infp_users_create(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - dbus_bool_t dbret; - char *einval_msg; - struct infp_createuser_ctx *infp_createuser_req; - int ret; - - /* Arguments */ - const char *arg_domain; - const char *arg_username; - const char *arg_fullname; - const char *arg_homedir; - const char *arg_shell; - - infp_createuser_req = talloc_zero(NULL, struct infp_createuser_ctx); - if (infp_createuser_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - infp_createuser_req->infp_req = infp_req_init(infp_createuser_req, - message, sconn); - if (infp_createuser_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - dbret = dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_username, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_STRING, &arg_fullname, - DBUS_TYPE_STRING, &arg_homedir, - DBUS_TYPE_STRING, &arg_shell, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", INFP_USERS_CREATE, error.name, error.message)); - einval_msg = talloc_strdup(infp_createuser_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow creating users on domains other than LOCAL */ - if (strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - infp_createuser_req->infp_req->domain = - infp_get_domain_obj(infp_createuser_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (infp_createuser_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(infp_createuser_req, "Invalid domain."); - goto einval; - } - - if (strlen(arg_username)) { - infp_createuser_req->username = talloc_strdup(infp_createuser_req, arg_username); - if (infp_createuser_req->username == NULL) { - ret = ENOMEM; - goto error; - } - } else { - einval_msg = talloc_strdup(infp_createuser_req, "No username provided"); - goto einval; - } - - infp_createuser_req->fullname = NULL; - if (strlen(arg_fullname)) { - infp_createuser_req->fullname = talloc_strdup(infp_createuser_req, arg_fullname); - if(infp_createuser_req->fullname == NULL) { - ret = ENOMEM; - goto error; - } - } - - infp_createuser_req->homedir = NULL; - if (strlen(arg_homedir)) { - infp_createuser_req->homedir = talloc_strdup(infp_createuser_req, arg_homedir); - if(infp_createuser_req->homedir == NULL) { - ret = ENOMEM; - goto error; - } - } - - infp_createuser_req->shell = NULL; - if (strlen(arg_shell)) { - infp_createuser_req->shell = talloc_strdup(infp_createuser_req, arg_shell); - if(infp_createuser_req->shell == NULL) { - ret = ENOMEM; - goto error; - } - } - - /* Check permissions */ - if(!infp_get_permissions(infp_createuser_req->infp_req->caller, - infp_createuser_req->infp_req->domain, - INFP_OBJ_TYPE_USER, - NULL, - INFP_ACTION_TYPE_CREATE, - INFP_ATTR_TYPE_INVALID)) goto denied; - - ret = sysdb_transaction(infp_createuser_req, - infp_createuser_req->infp_req->infp->sysdb, - infp_do_user_create, - infp_createuser_req); - if (ret != EOK) { - DEBUG(0,("Unable to start transaction to create user\n")); - goto error; - } - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_createuser_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - talloc_free(infp_createuser_req); - return EOK; - -error: - if(infp_createuser_req) - infp_return_failure(infp_createuser_req->infp_req, NULL); - talloc_free(infp_createuser_req); - return ret; -} - -struct infp_deleteuser_ctx { - struct infp_req_ctx *infp_req; - char *username; - struct sysdb_handle *handle; - struct ldb_dn *user_dn; -}; - -static void infp_do_user_delete_callback(void *pvt, int status, - struct ldb_result *res) -{ - struct infp_deleteuser_ctx *infp_deleteuser_req = - talloc_get_type(pvt, struct infp_deleteuser_ctx); - - /* Commit the transaction if it we got a successful response, or cancel it if we did not */ - sysdb_transaction_done(infp_deleteuser_req->handle, status); - - if (status != EOK) { - DEBUG(0, ("Failed to delete user from sysdb. Error code %d\n", status)); - infp_return_failure(infp_deleteuser_req->infp_req, NULL); - talloc_free(infp_deleteuser_req); - return; - } - - infp_return_success(infp_deleteuser_req->infp_req); - talloc_free(infp_deleteuser_req); -} - -static void infp_do_user_delete(struct sysdb_handle *req, void *pvt) -{ - int ret; - struct infp_deleteuser_ctx *infp_deleteuser_req = talloc_get_type(pvt, struct infp_deleteuser_ctx); - - infp_deleteuser_req->handle = handle; - - infp_deleteuser_req->user_dn = sysdb_user_dn(infp_deleteuser_req->infp_req->infp->sysdb, - infp_deleteuser_req, - infp_deleteuser_req->infp_req->domain->name, - infp_deleteuser_req->username); - if(infp_deleteuser_req->user_dn == NULL) { - DEBUG(0, ("Could not construct a user_dn for deletion.\n")); - infp_return_failure(infp_deleteuser_req->infp_req, NULL); - talloc_free(infp_deleteuser_req); - return; - } - - ret = sysdb_delete_entry(infp_deleteuser_req->handle, - infp_deleteuser_req->user_dn, - infp_do_user_delete_callback, - infp_deleteuser_req); - if(ret != EOK) { - DEBUG(0,("Could not delete user entry.\n")); - infp_return_failure(infp_deleteuser_req->infp_req, NULL); - talloc_free(infp_deleteuser_req); - return; - } -} - -int infp_users_delete(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply = NULL; - DBusError error; - dbus_bool_t dbret; - char *einval_msg = NULL; - struct infp_deleteuser_ctx *infp_deleteuser_req; - int ret; - - /* Arguments */ - const char *arg_username; - const char *arg_domain; - - infp_deleteuser_req = talloc_zero(NULL, struct infp_deleteuser_ctx); - if (infp_deleteuser_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - infp_deleteuser_req->infp_req = infp_req_init(infp_deleteuser_req, - message, - sconn); - if (infp_deleteuser_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - /* Process the arguments */ - dbus_error_init(&error); - dbret = dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_username, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(0, ("Parsing arguments to %s failed: %s:%s\n", - INFP_USERS_DELETE, error.name, error.message)); - einval_msg = talloc_strdup(infp_deleteuser_req, error.message); - dbus_error_free(&error); - goto einval; - } - - /* FIXME: Allow deleting users from domains other than local */ - if(strcasecmp(arg_domain, "LOCAL") != 0) { - goto denied; - } - - infp_deleteuser_req->infp_req->domain = - infp_get_domain_obj(infp_deleteuser_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (infp_deleteuser_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(infp_deleteuser_req, "Invalid domain."); - goto einval; - } - - if (strlen(arg_username)) { - infp_deleteuser_req->username = talloc_strdup(infp_deleteuser_req, arg_username); - if (infp_deleteuser_req->username == NULL) { - ret = ENOMEM; - goto error; - } - } else { - einval_msg = talloc_strdup(infp_deleteuser_req, "No username provided"); - goto einval; - } - - /* Check permissions */ - if(!infp_get_permissions(infp_deleteuser_req->infp_req->caller, - infp_deleteuser_req->infp_req->domain, - INFP_OBJ_TYPE_USER, - NULL, - INFP_ACTION_TYPE_DELETE, - INFP_ACTION_TYPE_INVALID)) goto denied; - - ret = sysdb_transaction(infp_deleteuser_req, - infp_deleteuser_req->infp_req->infp->sysdb, - infp_do_user_delete, - infp_deleteuser_req); - if (ret != EOK) { - DEBUG(0, ("Unable to start transaction to delete user\n")); - goto error; - } - - return EOK; - -denied: - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_deleteuser_req); - return EOK; - -einval: - reply = dbus_message_new_error(message, - DBUS_ERROR_INVALID_ARGS, - einval_msg); - if (reply == NULL) { - ret = ENOMEM; - goto error; - } - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - talloc_free(infp_deleteuser_req); - return EOK; - -error: - if(infp_deleteuser_req) - infp_return_failure(infp_deleteuser_req->infp_req, NULL); - talloc_free(infp_deleteuser_req); - return ret; -} - -struct infp_getattr_ctx { - struct infp_req_ctx *infp_req; - char **usernames; - uint32_t username_count; - const char **attributes; - uint32_t attr_count; - uint32_t index; - bool check_provider; - - /* The results array must have username_count elements */ - struct btreemap **results; -}; - -static int infp_get_attr_lookup(struct infp_getattr_ctx *infp_getattr_req); - -struct infp_attr_variant { - int dbus_type; - int subtype; - int count; - void *data; -}; - -/* We are restricting variants to three basic types: - * Fixed (Numeric) types - * Strings - * Arrays of fixed (numeric) types - */ -static int infp_user_getattr_append_dict(TALLOC_CTX *mem_ctx, - DBusMessageIter *iter, - struct btreemap *map) -{ - int ret, i; - char **attrs; - struct infp_attr_variant *value; - char *vartype; - char *subtype; - int attr_count; - DBusMessageIter array_iter; - DBusMessageIter dict_iter; - DBusMessageIter variant_iter; - DBusMessageIter fixed_array_iter; - dbus_bool_t dbret; - - ret = btreemap_get_keys(mem_ctx, map, (const void ***)&attrs, &attr_count); - if (ret != EOK) { - return ret; - } - - /* DICTs are an array of dict pairs */ - dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &array_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - - i = 0; - while (i < attr_count) { - if (strcasecmp(attrs[i], SYSDB_LAST_UPDATE) == 0) { - /* Skip lastUpdate. We shouldn't be returning this */ - i++; - continue; - } - - /* Create the variant value */ - value = talloc_get_type(btreemap_get_value(map, attrs[i]), struct infp_attr_variant); - if (value == NULL) { - /* Skip any entries that returned an empty value */ - i++; - continue; - } - - /* Open a dict container for this pair */ - dbret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - /* Write the dict key */ - dbret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &attrs[i]); - if (!dbret) { - ret = ENOMEM; - goto error; - } - - vartype = NULL; - subtype = NULL; - if (sbus_is_dbus_string_type(value->dbus_type)) { - /* String types are strings, object paths and signatures */ - vartype = talloc_asprintf(mem_ctx, "%c", value->dbus_type); - if (vartype == NULL) { - ret = ENOMEM; - goto error; - } - dbret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, vartype, &variant_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - dbret = dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &value->data); - if (!dbret) { - ret = ENOMEM; - goto error; - } - talloc_free(vartype); - vartype = NULL; - } - - else if (sbus_is_dbus_fixed_type(value->dbus_type)) { - /* Fixed types are booleans, bytes, the integral types and the floating-point types */ - vartype = talloc_asprintf(mem_ctx, "%c", value->dbus_type); - if (vartype == NULL) { - ret = ENOMEM; - goto error; - } - dbret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, vartype, &variant_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - dbret = dbus_message_iter_append_basic(&variant_iter, value->dbus_type, value->data); - if (!dbret) { - ret = ENOMEM; - goto error; - } - talloc_free(vartype); - vartype = NULL; - } - - else if (value->dbus_type == DBUS_TYPE_ARRAY) { - if(sbus_is_dbus_fixed_type(value->subtype)) { - /* Only support adding arrays of fixed types or strings for now */ - - subtype = talloc_asprintf(mem_ctx, "a%c", value->subtype); - if (subtype == NULL) { - ret = ENOMEM; - goto error; - } - dbret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, subtype, &variant_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - - dbret = dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, subtype, &fixed_array_iter); - if (!dbret) { - ret = ENOMEM; - goto error; - } - - dbret = dbus_message_iter_append_fixed_array(&fixed_array_iter, value->subtype, &value->data, value->count); - if(!dbret) { - ret = ENOMEM; - goto error; - } - - dbret = dbus_message_iter_close_container(&variant_iter, &fixed_array_iter); - if(!dbret) { - ret = ENOMEM; - goto error; - } - } - else { - ret = EINVAL; - goto error; - } - } - - else { - /* Value type not yet supported */ - DEBUG(0, ("Attempted to create DICT value for something not a basic type or fixed array [%d]\n", value->dbus_type)); - ret = EINVAL; - goto error; - } - - /* Close the variant */ - dbret = dbus_message_iter_close_container(&dict_iter, &variant_iter); - if(!dbret) { - ret = ENOMEM; - goto error; - } - - /* Close the dict */ - dbret = dbus_message_iter_close_container(&array_iter, &dict_iter); - if(!dbret) { - ret = ENOMEM; - goto error; - } - i++; - } - - /* Close the dict array */ - dbret = dbus_message_iter_close_container(iter, &array_iter); - if(!dbret) { - ret = ENOMEM; - goto error; - } - - return EOK; - -error: - talloc_free(attrs); - talloc_free(vartype); - talloc_free(subtype); - return ret; -} - -static int create_getattr_result_map(TALLOC_CTX *mem_ctx, struct infp_getattr_ctx *infp_getattr_req, - struct ldb_result *res, struct btreemap **results) -{ - int i, ret; - int attr_type; - struct infp_attr_variant *variant; - const struct ldb_val *val; - - /* Iterate through the requested attributes */ - for (i=0; i < infp_getattr_req->attr_count; i++) { - /* Ignore any attributes we don't care about */ - attr_type = infp_get_attribute_type(infp_getattr_req->attributes[i]); - if (attr_type != INFP_ATTR_TYPE_INVALID) { - variant = talloc_zero(mem_ctx, struct infp_attr_variant); - if (variant == NULL) { - ret = ENOMEM; - goto end; - } - - variant->dbus_type = infp_get_user_attr_dbus_type(attr_type, &variant->subtype); - if (sbus_is_dbus_string_type(variant->dbus_type)) { - variant->data = (void *)talloc_strdup(variant, ldb_msg_find_attr_as_string(res->msgs[0], - infp_getattr_req->attributes[i], NULL)); - if (variant->data == NULL) { - talloc_free(variant); - continue; - } - } - else if (sbus_is_dbus_fixed_type(variant->dbus_type)) { - /* We'll treat all fixed(numeric) types as UINT64 internally - * These will be correctly converted to their true types - * when being marshalled on the wire. - */ - variant->data = (void *)talloc(variant, uint64_t); - if (variant->data == NULL) { - talloc_free(variant); - continue; - } - - *(uint64_t *)variant->data = ldb_msg_find_attr_as_uint64(res->msgs[0], infp_getattr_req->attributes[i], 0); - } - else if (variant->dbus_type == DBUS_TYPE_ARRAY) { - switch(variant->subtype) { - case DBUS_TYPE_BYTE: - /* Byte array (binary data) */ - val = ldb_msg_find_ldb_val(res->msgs[0], infp_getattr_req->attributes[i]); - if (val == NULL || val->length <= 0) { - talloc_free(variant); - continue; - } - variant->data = talloc_memdup(variant, val->data, val->length); - if (variant->data == NULL) { - talloc_free(variant); - continue; - } - variant->count = val->length; - break; - - default: - /* Unsupported array type */ - talloc_free(variant); - continue; - } - - } - else { - /* Unsupported type */ - talloc_free(variant); - continue; - } - - /* Add the variant to the map */ - ret = btreemap_set_value(mem_ctx, results, (const void *)infp_getattr_req->attributes[i], variant, attr_comparator); - if (ret != EOK) { - talloc_free(variant); - } - } - } - - ret = EOK; - -end: - return ret; -} - -static void infp_get_attr_lookup_callback(void *ptr, int ldb_status, struct ldb_result *res) -{ - int ret; - int i; - bool call_provider = false; - int timeout; - uint64_t lastUpdate; - DBusMessage *reply = NULL; - DBusMessageIter iter; - DBusMessageIter array_iter; - struct infp_getattr_ctx *infp_getattr_req = talloc_get_type(ptr, struct infp_getattr_ctx); - - DEBUG(9, ("Processing results for user [%s]\n", infp_getattr_req->usernames[infp_getattr_req->index])); - - /* Process the current results */ - if (ldb_status != LDB_SUCCESS) { - DEBUG(0, ("Critical error reading from sysdb.\n")); - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - - if(infp_getattr_req->check_provider) { - switch(res->count) { - case 0: - call_provider = true; - break; - - case 1: - timeout = infp_getattr_req->infp_req->infp->cache_timeout; - lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0], - SYSDB_LAST_UPDATE, 0); - if (lastUpdate + timeout < time(NULL)) { - call_provider = true; - } - break; - - default: - DEBUG(0, ("GetUser call returned more than one result. This probably means the sysdb is corrupt!\n")); - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - } - - if (call_provider) { - /* FIXME call the provider */ - } - - switch (res->count) { - case 0: - DEBUG(2, ("No results for GetUser")); - infp_getattr_req->results[infp_getattr_req->index] = NULL; - break; - - case 1: - /* Create the result map */ - ret = create_getattr_result_map(infp_getattr_req, infp_getattr_req, res, - &infp_getattr_req->results[infp_getattr_req->index]); - if (ret != EOK) { - DEBUG(0, ("Unable to create result map!\n")); - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - break; - default: - /* We received more than one result. This is bad */ - DEBUG(0, ("GetUser call returned more than one result. This probably means the sysdb is corrupt!\n")); - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - - /* If there are more usernames remaining in the list, re-enter the loop */ - infp_getattr_req->index++; - if (infp_getattr_req->index < infp_getattr_req->username_count) { - ret = infp_get_attr_lookup(infp_getattr_req); - if (ret != EOK) { - DEBUG(0, ("Could not read from cache database\n")); - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - return; - } - - /* No more names remain, return the result DICTs */ - reply = dbus_message_new_method_return(infp_getattr_req->infp_req->req_message); - if (reply == NULL) { - infp_return_failure(infp_getattr_req->infp_req, NULL); - goto done; - } - - dbus_message_iter_init_append(reply, &iter); - - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "a{sv}", &array_iter); - i = 0; - while (i < infp_getattr_req->username_count) { - ret = infp_user_getattr_append_dict(infp_getattr_req, &array_iter, infp_getattr_req->results[i]); - if (ret != EOK) { - DEBUG(0, ("Unable to append response DICT\n")); - goto done; - } - i++; - } - dbus_message_iter_close_container(&iter, &array_iter); - - sbus_conn_send_reply(infp_getattr_req->infp_req->sconn, reply); - -done: - if(reply) dbus_message_unref(reply); - talloc_free(infp_getattr_req); -} - -int infp_get_user_attr_dbus_type(int attr_type, int *subtype) -{ - int dbus_type; - *subtype = DBUS_TYPE_INVALID; - - switch(attr_type) { - case INFP_ATTR_TYPE_DEFAULTGROUP: - case INFP_ATTR_TYPE_GECOS: - case INFP_ATTR_TYPE_HOMEDIR: - case INFP_ATTR_TYPE_SHELL: - case INFP_ATTR_TYPE_FULLNAME: - case INFP_ATTR_TYPE_LOCALE: - case INFP_ATTR_TYPE_KEYBOARD: - case INFP_ATTR_TYPE_SESSION: - dbus_type = DBUS_TYPE_STRING; - break; - case INFP_ATTR_TYPE_LAST_LOGIN: - dbus_type = DBUS_TYPE_UINT64; - break; - case INFP_ATTR_TYPE_USERPIC: - dbus_type = DBUS_TYPE_ARRAY; - *subtype = DBUS_TYPE_BYTE; - break; - default: - dbus_type = DBUS_TYPE_INVALID; - } - return dbus_type; -} - -static int attr_comparator(const void *key1, const void *key2) -{ - return strcmp((const char *)key1, (const char *)key2); -} - -static int infp_get_attr_lookup(struct infp_getattr_ctx *infp_getattr_req) -{ - uint32_t i; - int ret; - char **attributes; - const char *last_update; - int attr_count; - - DEBUG(9, ("Processing lookup for user [%s]\n", infp_getattr_req->usernames[infp_getattr_req->index])); - - if (infp_getattr_req->index >= infp_getattr_req->username_count) { - /* Avoid index bound issues */ - return EINVAL; - } - - /* Check permissions */ - i=0; - infp_getattr_req->results[infp_getattr_req->index] = NULL; - while(i < infp_getattr_req->attr_count) { - if(infp_get_permissions(infp_getattr_req->infp_req->caller, - infp_getattr_req->infp_req->domain, - INFP_OBJ_TYPE_USER, - infp_getattr_req->usernames[infp_getattr_req->index], - INFP_ACTION_TYPE_READ, - infp_get_attribute_type(infp_getattr_req->attributes[i])) - ) { - /* Add this attribute as a key to the result map - * This will guarantee that we are requesting only unique attributes - * that we have permission to read - */ - ret = btreemap_set_value(infp_getattr_req, &infp_getattr_req->results[infp_getattr_req->index], - infp_getattr_req->attributes[i], NULL, attr_comparator); - if (ret != EOK) { - return ret; - } - } - i++; - } - - /* Always add SYSDB_LAST_UPDATE to the list, we won't return it */ - last_update = talloc_strdup(infp_getattr_req, SYSDB_LAST_UPDATE); - ret = btreemap_set_value(infp_getattr_req, &infp_getattr_req->results[infp_getattr_req->index], - last_update, NULL, attr_comparator); - if (ret != EOK) { - return ret; - } - - /* Prepare the list of attributes to request from the sysdb */ - attr_count = 0; - ret = btreemap_get_keys(infp_getattr_req, - infp_getattr_req->results[infp_getattr_req->index], - (const void ***)&attributes, &attr_count); - if (ret != EOK) { - return ret; - } - - if (attr_count == 1) { - /* There were zero authorized attributes in the list - * No need to call sysdb, just move to the next username - * The single attribute was SYSDB_LAST_UPDATE which we - * added manually. - */ - infp_getattr_req->index++; - return infp_get_attr_lookup(infp_getattr_req); - } - - /* Add a trailing NULL entry (required for sysdb) */ - attributes = talloc_realloc(infp_getattr_req, attributes, char *, attr_count+1); - if (attributes == NULL) { - return ENOMEM; - } - attributes[attr_count] = NULL; - - /* Call into the sysdb for the requested attributes */ - ret = sysdb_get_user_attr(infp_getattr_req, - infp_getattr_req->infp_req->infp->sysdb, - infp_getattr_req->infp_req->domain, - infp_getattr_req->usernames[infp_getattr_req->index], - (const char **)attributes, - infp_get_attr_lookup_callback, infp_getattr_req); - - return EOK; -} - -static const char **infp_get_all_attributes(TALLOC_CTX *mem_ctx, - uint32_t *attr_count) -{ - const char **attributes; - int offset = 0; - - *attr_count = 10; - attributes = talloc_array(mem_ctx, const char *, *attr_count); - if (attributes == NULL) { - return NULL; - } - - attributes[offset++] = SYSDB_DEFAULTGROUP; - attributes[offset++] = SYSDB_GECOS; - attributes[offset++] = SYSDB_HOMEDIR; - attributes[offset++] = SYSDB_SHELL; - attributes[offset++] = SYSDB_FULLNAME; - attributes[offset++] = SYSDB_LOCALE; - attributes[offset++] = SYSDB_KEYBOARD; - attributes[offset++] = SYSDB_SESSION; - attributes[offset++] = SYSDB_LAST_LOGIN; - attributes[offset++] = SYSDB_USERPIC; - - return attributes; -} - -/* GetUserAttributes(ARRAY(STRING) usernames, - * STRING domain, - * ARRAY(STRING) filter) - */ -int infp_users_get_attr(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - int ret, i; - DBusMessage *reply; - DBusError error; - dbus_bool_t dbret; - char **usernames; - uint32_t username_count; - char *domain; - char **attributes; - uint32_t attr_count; - struct infp_getattr_ctx *infp_getattr_req; - - usernames = NULL; - attributes = NULL; - /* Get the arguments to GetAttributes */ - dbus_error_init(&error); - dbret = dbus_message_get_args(message, &error, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &usernames, &username_count, - DBUS_TYPE_STRING, &domain, - DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &attributes, &attr_count, - DBUS_TYPE_INVALID); - if(!dbret) { - DEBUG(0, ("Parsing arguments failed: %s:%s\n", error.name, error.message)); - dbus_free_string_array(usernames); - dbus_free_string_array(attributes); - - reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, error.message); - if (reply == NULL) { - return ENOMEM; - } - sbus_conn_send_reply(sconn, reply); - - dbus_message_unref(reply); - dbus_error_free(&error); - - return EOK; - } - - if (username_count < 1) { - /* No usernames received. Return an error */ - reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, "No usernames specified."); - if (reply == NULL) { - ret = ENOMEM; - goto end; - } - sbus_conn_send_reply(sconn, reply); - - dbus_free_string_array(usernames); - dbus_free_string_array(attributes); - dbus_message_unref(reply); - ret = EOK; - goto end; - } - - /* Create a infp_getattr_ctx */ - infp_getattr_req = talloc_zero(NULL, struct infp_getattr_ctx); - if (infp_getattr_req == NULL) { - ret = ENOMEM; - goto end; - } - - /* Create an infp_req_ctx */ - infp_getattr_req->infp_req = infp_req_init(infp_getattr_req, - message, sconn); - if (infp_getattr_req->infp_req == NULL) { - ret = EIO; - goto end; - } - - infp_getattr_req->infp_req->domain = - infp_get_domain_obj(infp_getattr_req->infp_req->infp, domain); - infp_getattr_req->check_provider = - NEED_CHECK_PROVIDER(infp_getattr_req->infp_req->domain->provider); - - /* Copy the username list */ - infp_getattr_req->usernames = talloc_array(infp_getattr_req, char *, username_count); - if (infp_getattr_req->usernames == NULL) { - ret = ENOMEM; - goto end; - } - - i = 0; - while (i < username_count) { - DEBUG(9, ("Request for user [%s]\n", usernames[i])); - infp_getattr_req->usernames[i] = talloc_strdup(infp_getattr_req->usernames, usernames[i]); - if (infp_getattr_req == NULL) { - ret = ENOMEM; - goto end; - } - i++; - } - infp_getattr_req->username_count = username_count; - - /* Copy the attribute list */ - if (attr_count > 0) { - infp_getattr_req->attributes = talloc_array(infp_getattr_req, - const char *, attr_count); - if (infp_getattr_req->attributes == NULL) { - ret = ENOMEM; - goto end; - } - i = 0; - while (i < attr_count) { - infp_getattr_req->attributes[i] = talloc_strdup(infp_getattr_req, attributes[i]); - if (infp_getattr_req == NULL) { - ret = ENOMEM; - goto end; - } - i++; - } - infp_getattr_req->attr_count = attr_count; - } else { - /* No attributes specified in the call means retrieve all possible */ - infp_getattr_req->attributes = infp_get_all_attributes(infp_getattr_req, &infp_getattr_req->attr_count); - if (infp_getattr_req->attributes == NULL) { - ret = ENOMEM; - goto end; - } - } - - infp_getattr_req->index = 0; - - /* Prepare the result list */ - infp_getattr_req->results = talloc_array(infp_getattr_req, struct btreemap *, attr_count); - if (infp_getattr_req->results == NULL) { - ret = ENOMEM; - goto end; - } - - /* Look up the first username and start the async loop */ - ret = infp_get_attr_lookup(infp_getattr_req); - if (ret != EOK) { - DEBUG(0, ("Could not read from cache database\n")); - } - -end: - dbus_free_string_array(usernames); - dbus_free_string_array(attributes); - if (ret != EOK) { - infp_return_failure(infp_getattr_req->infp_req, NULL); - talloc_free(infp_getattr_req); - } - return ret; -} - -static int username_comparator(const void *key1, const void *key2) -{ - return strcmp((const char *)key1, (const char *)key2); -} - -struct infp_setattr_ctx { - struct infp_req_ctx *infp_req; - const char **usernames; - int username_count; - uint32_t index; - struct sysdb_handle *handle; - - /* Array of sysdb_attrs objects - * The number of elements in this array - * is equal to the username count; - */ - struct sysdb_attrs **changes; -}; -static void infp_do_user_set_attr(struct sysdb_handle *req, void *pvt); -static void infp_do_user_set_attr_callback(void *ptr, int ldb_status, struct ldb_result *res) -{ - struct infp_setattr_ctx *infp_setattr_req; - - infp_setattr_req = talloc_get_type(ptr, struct infp_setattr_ctx); - - /* Check the ldb_result */ - if (ldb_status != LDB_SUCCESS) { - DEBUG(0, ("Failed to store user attributes to the sysdb\n")); - /* Cancel the transaction */ - sysdb_transaction_done(infp_setattr_req->handle, sysdb_error_to_errno(ldb_status)); - infp_return_failure(infp_setattr_req->infp_req, NULL); - talloc_free(infp_setattr_req); - return; - } - - /* Process any remaining users */ - infp_setattr_req->index++; - if(infp_setattr_req->index < infp_setattr_req->username_count) { - infp_do_user_set_attr(infp_setattr_req->handle, infp_setattr_req); - return; - } - - /* This was the last user. Commit the transaction */ - sysdb_transaction_done(infp_setattr_req->handle, EOK); - - /* Send reply ack */ - infp_return_success(infp_setattr_req->infp_req); - - talloc_free(infp_setattr_req); -} - -static void infp_do_user_set_attr(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct infp_setattr_ctx *infp_setattr_req; - - infp_setattr_req = talloc_get_type(pvt, struct infp_setattr_ctx); - infp_setattr_req->handle = handle; - - DEBUG(9, ("Setting attributes for user [%s]\n", infp_setattr_req->usernames[infp_setattr_req->index])); - ret = sysdb_set_user_attr(infp_setattr_req->handle, - infp_setattr_req->infp_req->domain, - infp_setattr_req->usernames[infp_setattr_req->index], - infp_setattr_req->changes[infp_setattr_req->index], - infp_do_user_set_attr_callback, infp_setattr_req); - if(ret != EOK) { - DEBUG(0, ("Failed to set attributes for user [%s]. Cancelling transaction\n", infp_setattr_req->usernames[infp_setattr_req->index])); - sysdb_transaction_done(req, ret); - infp_return_failure(infp_setattr_req->infp_req, NULL); - talloc_free(infp_setattr_req); - } -} - -int infp_users_set_attr(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - TALLOC_CTX *dict_ctx; - DBusMessage *reply; - DBusMessageIter iter, array_iter, dict_array_iter; - DBusMessageIter dict_iter, variant_iter; - dbus_bool_t dbret; - char *domain_name; - char *einval_msg; - const char *recv_username; - const char *dict_key; - char *username; - char *val_key; - char *values; - char **attributes; - int user_count, change_count; - int change_map_count, dict_entry_count; - int added_entries; - int current_type; - int attr_type, variant_type; - int subtype; - struct infp_setattr_ctx *infp_setattr_req; - struct btreemap *username_map; - struct btreemap *value_map; - struct btreemap *change_map; - struct btreemap **change_array; - struct btreemap **tmp_array; - struct ldb_val *val; - int ret, i, j; - - /* Create a infp_setattr_ctx */ - infp_setattr_req = talloc_zero(NULL, struct infp_setattr_ctx); - if(infp_setattr_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - infp_setattr_req->infp_req = infp_req_init(infp_setattr_req, - message, sconn); - if (infp_setattr_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - /* Process the arguments to SetUserAttributes */ - dbret = dbus_message_iter_init(message, &iter); - if (!dbret) { - einval_msg = talloc_strdup(infp_setattr_req, "No arguments received."); - goto einval; - } - - /* Get the list of usernames to process */ - current_type = dbus_message_iter_get_arg_type(&iter); - if (current_type != DBUS_TYPE_ARRAY) { - einval_msg = talloc_strdup(infp_setattr_req, "Expected username list."); - goto einval; - } - if(dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(infp_setattr_req, "Expected username list."); - goto einval; - } - /* Recurse into the array */ - user_count = 0; - dbus_message_iter_recurse(&iter, &array_iter); - username_map = NULL; - while((current_type=dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID) { - dbus_message_iter_get_basic(&array_iter, &recv_username); - username = talloc_strdup(infp_setattr_req, recv_username); - if (username == NULL) { - ret = ENOMEM; - goto error; - } - ret = btreemap_set_value(infp_setattr_req, &username_map, - (const void *)username, NULL, username_comparator); - if (ret != EOK) goto error; - - user_count++; - dbus_message_iter_next(&array_iter); - } - - if (user_count == 0) { - /* No users passed in */ - einval_msg = talloc_strdup(infp_setattr_req, "No usernames provided."); - goto einval; - } - - ret = btreemap_get_keys(infp_setattr_req, username_map, - (const void ***)&infp_setattr_req->usernames, &infp_setattr_req->username_count); - if (ret != EOK) goto error; - - /* Verify that the usernames were all unique. - * If the count of usernames we added differs from the count we're - * getting back, then at least one was a duplicate. - */ - if (infp_setattr_req->username_count != user_count) { - einval_msg = talloc_strdup(infp_setattr_req, "Usernames were not unique."); - goto einval; - } - - /* Get the domain name */ - dbus_message_iter_next(&iter); - if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(infp_setattr_req, "No domain provided.\n"); - goto einval; - } - dbus_message_iter_get_basic(&iter, &domain_name); - - infp_setattr_req->infp_req->domain = - infp_get_domain_obj(infp_setattr_req->infp_req->infp, domain_name); - if (infp_setattr_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(infp_setattr_req, "Invalid domain."); - goto einval; - } - - /* Get the array of change DICT entries */ - dbus_message_iter_next(&iter); - current_type = dbus_message_iter_get_arg_type(&iter); - if (current_type != DBUS_TYPE_ARRAY) { - einval_msg = talloc_strdup(infp_setattr_req, "Expected change list."); - goto einval; - } - if(dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) { - einval_msg = talloc_strdup(infp_setattr_req, "Expected array of DICT entry arrays."); - goto einval; - } - - change_count = 0; - change_array = NULL; - dbus_message_iter_recurse(&iter, &array_iter); - if(dbus_message_iter_get_element_type(&array_iter) != DBUS_TYPE_DICT_ENTRY) { - einval_msg = talloc_strdup(infp_setattr_req, "Expected array of DICT entries."); - goto einval; - } - while((current_type=dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID) { - /* Descend into the DICT array */ - dbus_message_iter_recurse(&array_iter, &dict_array_iter); - - /* Create a new talloc context to contain the values from this DICT array */ - dict_ctx = talloc_new(infp_setattr_req); - if(dict_ctx == NULL) { - ret = ENOMEM; - goto error; - } - value_map = NULL; - dict_entry_count = 0; - - while((current_type=dbus_message_iter_get_arg_type(&dict_array_iter)) != DBUS_TYPE_INVALID) { - change_count++; - /* Descend into the DICT entry */ - dbus_message_iter_recurse(&dict_array_iter, &dict_iter); - /* Key must be a string */ - if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) { - einval_msg = talloc_strdup(infp_setattr_req, "DICT entries must be keyed on strings."); - goto einval; - } - dbus_message_iter_get_basic(&dict_iter, &dict_key); - if((attr_type = infp_get_attribute_type(dict_key)) == INFP_ATTR_TYPE_INVALID) { - /* Continue to the next DICT entry (ignoring unrecognized attributes) */ - change_count--; /* Don't include ignored values in the count */ - dbus_message_iter_next(&dict_array_iter); - continue; - } - val_key = talloc_strdup(dict_ctx, dict_key); - if(val_key == NULL) { - ret = ENOMEM; - goto error; - } - - /* Value is a variant */ - variant_type = infp_get_user_attr_dbus_type(attr_type, &subtype); - if(variant_type == DBUS_TYPE_INVALID) { - /* This shouldn't happen since the attr_type is valid. - * If this failed, it's a coding error. - */ - DEBUG(0, ("Critical error, valid attribute type could not be paired with a D-BUS type.\n")); - ret = EIO; - goto error; - } - - dbus_message_iter_next(&dict_iter); - if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) { - einval_msg = talloc_strdup(infp_setattr_req, "DICT value must be a variant."); - goto einval; - } - dbus_message_iter_recurse(&dict_iter, &variant_iter); - - if (dbus_message_iter_get_arg_type(&variant_iter) != variant_type) { - einval_msg = talloc_asprintf(infp_setattr_req, "DICT value did not match required type of key [%s]. Expected [%c], received [%c]\n", dict_key, variant_type, dbus_message_iter_get_arg_type(&dict_iter)); - goto einval; - } - - if(variant_type == DBUS_TYPE_ARRAY) { - current_type=dbus_message_iter_get_element_type(&variant_iter); - if (!sbus_is_dbus_fixed_type(current_type)) { - /* We only support fixed-type arrays right now */ - einval_msg = talloc_asprintf(infp_setattr_req, "Invalid array type."); - } - } - - ret = infp_get_ldb_val_from_dbus(dict_ctx, &variant_iter, &val, variant_type, subtype); - if (ret != EOK) { - /* Could not create an LDB val from this variant */ - DEBUG(0, ("Error, valid attribute type could not be converted to an ldb_val.\n")); - goto error; - } - - ret = btreemap_set_value(dict_ctx, &value_map, - (const void *)val_key, val, - attr_comparator); - if (ret != EOK) { - DEBUG(0, ("Could not add change value to the value map.\n")); - goto error; - } - - dict_entry_count++; - dbus_message_iter_next(&dict_array_iter); - } - - /* Verify that all of the dict entries were unique */ - ret = btreemap_get_keys(dict_ctx, value_map, - (const void ***)&values, &added_entries); - if (ret != EOK) goto error; - - if (added_entries != dict_entry_count) { - einval_msg = talloc_strdup(infp_setattr_req, "Attributes to change were not unique."); - goto einval; - } - - /* Add the map to an array */ - tmp_array = talloc_realloc(infp_setattr_req, change_array, struct btreemap *, change_count); - if(tmp_array == NULL) { - ret = ENOMEM; - goto error; - } - change_array = tmp_array; - change_array[change_count-1] = value_map; - - dbus_message_iter_next(&array_iter); - } - - if (change_count != infp_setattr_req->username_count && change_count != 1) { - /* Change counts must be one-to-one with the number of users, - * or else exactly one for all users. - */ - einval_msg = talloc_strdup(infp_setattr_req, "Count of change DICTs not equal to one or count of usernames."); - goto einval; - } - - /* Check permissions and create the sysdb_attrs change list */ - infp_setattr_req->changes = talloc_array(infp_setattr_req, struct sysdb_attrs *, infp_setattr_req->username_count); - for (i = 0; i < infp_setattr_req->username_count; i++) { - if (change_count == 1) - change_map = change_array[0]; - else - change_map = change_array[i]; - - ret = btreemap_get_keys(dict_ctx, change_map, - (const void ***)&attributes, &change_map_count); - if (ret != EOK) goto error; - - infp_setattr_req->changes[i] = sysdb_new_attrs(infp_setattr_req); - if (infp_setattr_req->changes[i] == NULL) { - ret = ENOMEM; - goto error; - } - for (j = 0; j < change_map_count; j++) { - /* Add it to the sydb_attrs change list if permission is granted */ - if (infp_get_permissions(infp_setattr_req->infp_req->caller, - infp_setattr_req->infp_req->domain, - INFP_OBJ_TYPE_USER, - infp_setattr_req->usernames[i], - INFP_ACTION_TYPE_MODIFY, - infp_get_attribute_type(attributes[j]))) - { - ret = sysdb_attrs_add_val(infp_setattr_req->changes[i], attributes[j], - btreemap_get_value(change_map, attributes[j])); - if (ret != EOK) { - goto error; - } - } - } - } - - infp_setattr_req->index = 0; - ret = sysdb_transaction(infp_setattr_req, infp_setattr_req->infp_req->infp->sysdb, - infp_do_user_set_attr, infp_setattr_req); - if (ret != EOK) { - DEBUG(0, ("Could not write to the cache database.\n")) - goto error; - } - - return EOK; - -einval: - reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, einval_msg); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_setattr_req); - return EOK; - -error: - if(infp_setattr_req) - infp_return_failure(infp_setattr_req->infp_req, NULL); - talloc_free(infp_setattr_req); - return ret; -} - -struct infp_setuid_ctx { - struct infp_req_ctx *infp_req; - struct sysdb_handle *handle; - struct sysdb_attrs *uid_attr; - char *username; -}; - -static void infp_do_user_set_uid_callback(void *ptr, int ldb_status, struct ldb_result *res) -{ - struct infp_setuid_ctx *infp_setuid_req = talloc_get_type(ptr, struct infp_setuid_ctx); - - /* Commit or cancel the transaction, based on the ldb_status */ - sysdb_transaction_done(infp_setuid_req->handle, sysdb_error_to_errno(ldb_status)); - - /* Check the LDB result */ - if (ldb_status != LDB_SUCCESS) { - DEBUG(0, ("Failed to store user uid to the sysdb\n")); - infp_return_failure(infp_setuid_req->infp_req, NULL); - talloc_free(infp_setuid_req); - return; - } - - /* Send reply ack */ - infp_return_success(infp_setuid_req->infp_req); - - talloc_free(infp_setuid_req); -} - -static void infp_do_user_set_uid(struct sysdb_handle *handle, void *pvt) -{ - int ret; - struct infp_setuid_ctx *infp_setuid_req; - - infp_setuid_req = talloc_get_type(pvt, struct infp_setuid_ctx); - infp_setuid_req->handle = handle; - - DEBUG(9, ("Setting UID for user [%s]\n", infp_setuid_req->username)); - ret = sysdb_set_user_attr(infp_setuid_req->handle, - infp_setuid_req->infp_req->domain, - infp_setuid_req->username, - infp_setuid_req->uid_attr, - infp_do_user_set_uid_callback, infp_setuid_req); - if (ret != EOK) { - DEBUG(0, ("Could not invoke sysdb_set_user_attr")); - sysdb_transaction_done(infp_setuid_req->handle, ret); - infp_return_failure(infp_setuid_req->infp_req, NULL); - talloc_free(infp_setuid_req); - return; - } -} - -int infp_users_set_uid(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - DBusError error; - dbus_bool_t dbret; - char *einval_msg; - struct infp_setuid_ctx *infp_setuid_req; - int ret; - - /* Arguments */ - const char *arg_username; - const char *arg_domain; - const int arg_uid; - - infp_setuid_req = talloc_zero(NULL, struct infp_setuid_ctx); - if (infp_setuid_req == NULL) { - ret = ENOMEM; - goto error; - } - - /* Create an infp_req_ctx */ - infp_setuid_req->infp_req = infp_req_init(infp_setuid_req, - message, sconn); - if (infp_setuid_req->infp_req == NULL) { - ret = EIO; - goto error; - } - - dbus_error_init(&error); - dbret = dbus_message_get_args(message, &error, - DBUS_TYPE_STRING, &arg_username, - DBUS_TYPE_STRING, &arg_domain, - DBUS_TYPE_UINT32, &arg_uid, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(0, ("Parsing arguments to SetUserUID failed: %s:%s\n", error.name, error.message)); - einval_msg = talloc_strdup(infp_setuid_req, error.message); - dbus_error_free(&error); - goto einval; - } - - infp_setuid_req->username = talloc_strdup(infp_setuid_req, arg_username); - - infp_setuid_req->infp_req->domain = - infp_get_domain_obj(infp_setuid_req->infp_req->infp, arg_domain); - /* Check for a valid domain */ - if (infp_setuid_req->infp_req->domain == NULL) { - einval_msg = talloc_strdup(infp_setuid_req, "Invalid domain."); - goto einval; - } - - /* Check the domain MIN and MAX */ - if((arg_uid < infp_setuid_req->infp_req->domain->id_min) || /* Requested UID < than minimum */ - ((infp_setuid_req->infp_req->domain->id_max > infp_setuid_req->infp_req->domain->id_min) && /* Maximum exists and is greater than minimum */ - (arg_uid > infp_setuid_req->infp_req->domain->id_max))) { /* Requested UID > maximum */ - einval_msg = talloc_asprintf(infp_setuid_req, "UID out of range for this domain. Minimum: %u Maximum: %u\n", - infp_setuid_req->infp_req->domain->id_min, - infp_setuid_req->infp_req->domain->id_max?infp_setuid_req->infp_req->domain->id_max:(uid_t)-1); - goto einval; - } - - /* Check permissions */ - if(!infp_get_permissions(infp_setuid_req->infp_req->caller, - infp_setuid_req->infp_req->domain, - INFP_OBJ_TYPE_USER, - infp_setuid_req->username, - INFP_ACTION_TYPE_MODIFY, - INFP_ATTR_TYPE_USERID)) - { - reply = dbus_message_new_error(message, DBUS_ERROR_ACCESS_DENIED, NULL); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_setuid_req); - return EOK; - } - - infp_setuid_req->uid_attr = sysdb_new_attrs(infp_setuid_req); - if (infp_setuid_req->uid_attr == NULL) { - ret = ENOMEM; - goto error; - } - sysdb_attrs_add_long(infp_setuid_req->uid_attr, SYSDB_UIDNUM, arg_uid); - - ret = sysdb_transaction(infp_setuid_req, infp_setuid_req->infp_req->infp->sysdb, - infp_do_user_set_uid, infp_setuid_req); - if(ret != EOK) { - DEBUG(0, ("Could not write to the cache database.\n")); - goto error; - } - - return EOK; - -einval: - reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, einval_msg); - if(reply == NULL) { - ret = ENOMEM; - goto error; - } - - /* send reply */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - talloc_free(infp_setuid_req); - return EOK; - -error: - if(infp_setuid_req) - infp_return_failure(infp_setuid_req->infp_req, NULL); - talloc_free(infp_setuid_req); - return ret; -} diff --git a/server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml b/server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml deleted file mode 100644 index c35b1405..00000000 --- a/server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/server/infopipe/org.freedesktop.sssd.infopipe.conf b/server/infopipe/org.freedesktop.sssd.infopipe.conf deleted file mode 100644 index ab623208..00000000 --- a/server/infopipe/org.freedesktop.sssd.infopipe.conf +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/server/infopipe/sysbus.c b/server/infopipe/sysbus.c deleted file mode 100644 index efb43b34..00000000 --- a/server/infopipe/sysbus.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - SSSD - - SystemBus Helpers - - Copyright (C) Stephen Gallagher 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 . -*/ - -#include "talloc.h" -#include "tevent.h" -#include "util/util.h" -#include "dbus/dbus.h" -#include "sbus/sssd_dbus.h" -#include "sysbus.h" -#include "infopipe/infopipe.h" - -struct sysbus_ctx { - struct sbus_conn_ctx *sconn; - struct sbus_method_ctx *service_methods; - void *pvt_data; -}; - -static int sysbus_destructor(TALLOC_CTX *ctx) { - struct sysbus_ctx *system_bus = talloc_get_type(ctx, struct sysbus_ctx); - dbus_connection_unref(sbus_get_connection(system_bus->sconn)); - return EOK; -} - -static int sysbus_init_methods(TALLOC_CTX *mem_ctx, - struct sysbus_ctx *sysbus, - const char *interface, - const char *path, - struct sbus_method *methods, - sbus_msg_handler_fn introspect_method, - struct sbus_method_ctx **sm_ctx) -{ - int ret; - TALLOC_CTX *tmp_ctx; - struct sbus_method_ctx *method_ctx; - - tmp_ctx = talloc_new(mem_ctx); - if(!tmp_ctx) { - return ENOMEM; - } - - method_ctx = talloc_zero(tmp_ctx, struct sbus_method_ctx); - if (!method_ctx) { - ret = ENOMEM; - goto done; - } - - method_ctx->interface = talloc_strdup(method_ctx, interface); - if (method_ctx->interface == NULL) { - ret = ENOMEM; - goto done; - } - - method_ctx->path = talloc_strdup(method_ctx, path); - if (method_ctx->path == NULL) { - ret = ENOMEM; - goto done; - } - - method_ctx->methods = methods; - method_ctx->introspect_fn = introspect_method; - method_ctx->message_handler = sbus_message_handler; - - *sm_ctx = method_ctx; - talloc_steal(mem_ctx, method_ctx); - - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; -} - -int sysbus_init(TALLOC_CTX *mem_ctx, struct sysbus_ctx **sysbus, - struct tevent_context *ev, const char *dbus_name, - const char *interface, const char *path, - struct sbus_method *methods, - sbus_msg_handler_fn introspect_method) -{ - DBusError dbus_error; - DBusConnection *conn; - struct sysbus_ctx *system_bus; - int ret; - - system_bus = talloc_zero(mem_ctx, struct sysbus_ctx); - if (system_bus == NULL) { - return ENOMEM; - } - - dbus_error_init(&dbus_error); - - /* Connect to the well-known system bus */ - conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); - if (conn == NULL) { - DEBUG(0, ("Failed to connect to D-BUS system bus.\n")); - talloc_free(system_bus); - return EIO; - } - dbus_connection_set_exit_on_disconnect(conn, FALSE); - - ret = dbus_bus_request_name(conn, - dbus_name, - /* We want exclusive access */ - DBUS_NAME_FLAG_DO_NOT_QUEUE, - &dbus_error - ); - if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - /* We were unable to register on the system bus */ - DEBUG(0, ("Unable to request name on the system bus. Error: %s\n", dbus_error.message)); - if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); - dbus_connection_unref(conn); - talloc_free(system_bus); - return EIO; - } - - DEBUG(1, ("Listening on %s\n", dbus_name)); - - /* Integrate with TEvent loop */ - ret = sbus_add_connection(system_bus, ev, conn, &system_bus->sconn, SBUS_CONN_TYPE_SHARED); - if (ret != EOK) { - DEBUG(0, ("Could not integrate D-BUS into mainloop.\n")); - dbus_connection_unref(conn); - talloc_free(system_bus); - return ret; - } - talloc_set_destructor((TALLOC_CTX *)system_bus, - sysbus_destructor); - - /* Set up methods */ - ret = sysbus_init_methods(system_bus, system_bus, interface, path, - methods, introspect_method, - &system_bus->service_methods); - if (ret != EOK) { - DEBUG(0, ("Could not set up service methods.\n")); - talloc_free(system_bus); - return ret; - } - - ret = sbus_conn_add_method_ctx(system_bus->sconn, system_bus->service_methods); - if (ret != EOK) { - DEBUG(0, ("Could not add service methods to the connection.\n")); - talloc_free(system_bus); - return ret; - } - - *sysbus = system_bus; - return EOK; -} - -struct sbus_conn_ctx *sysbus_get_sbus_conn(struct sysbus_ctx *sysbus) -{ - return sysbus->sconn; -} - -char *sysbus_get_caller(TALLOC_CTX *mem_ctx, DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - char *caller; - const char *conn_name; - DBusError error; - uid_t uid; - - /* Get the connection UID */ - conn_name = dbus_message_get_sender(message); - if (conn_name == NULL) { - DEBUG(0, ("Critical error: D-BUS client has no unique name\n")); - return NULL; - } - dbus_error_init(&error); - uid = dbus_bus_get_unix_user(sbus_get_connection(sconn), conn_name, &error); - if (uid == -1) { - DEBUG(0, ("Could not identify unix user. Error message was '%s:%s'\n", error.name, error.message)); - dbus_error_free(&error); - return NULL; - } - caller = get_username_from_uid(mem_ctx, uid); - if (caller == NULL) { - DEBUG(0, ("No username matched the connected UID\n")); - return NULL; - } - - return caller; -} diff --git a/server/infopipe/sysbus.h b/server/infopipe/sysbus.h deleted file mode 100644 index cb45fa7e..00000000 --- a/server/infopipe/sysbus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - SSSD - - SystemBus Helpers - - Copyright (C) Stephen Gallagher 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 . -*/ - -#ifndef SYSBUS_H_ -#define SYSBUS_H_ - -struct sysbus_ctx; - -int sysbus_init(TALLOC_CTX *mem_ctx, struct sysbus_ctx **sysbus, - struct tevent_context *ev, const char *dbus_name, - const char *interface, const char *path, - struct sbus_method *methods, - sbus_msg_handler_fn introspect_method); - -struct sbus_conn_ctx *sysbus_get_sbus_conn(struct sysbus_ctx *sysbus); - -char *sysbus_get_caller(TALLOC_CTX *mem_ctx, DBusMessage *message, struct sbus_conn_ctx *sconn); - -#endif /* SYSBUS_H_ */ diff --git a/server/polkit/sssd_polkit.c b/server/polkit/sssd_polkit.c deleted file mode 100644 index a7a3d89d..00000000 --- a/server/polkit/sssd_polkit.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - SSSD - - PolicyKit - - Copyright (C) Stephen Gallagher 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 . -*/ -#define _GNU_SOURCE -#include -#include -#include "popt.h" -#include "sssd_polkit.h" -#include "util/util.h" -#include "sbus/sbus_client.h" -#include "monitor/monitor_sbus.h" -#include "monitor/monitor_interfaces.h" - -#define SPK_CONF_ENTRY "config/services/pk" - -struct spk_ctx { - struct tevent_context *ev; - struct confdb_ctx *cdb; - struct service_sbus_ctx *ss_ctx; - struct sbus_srv_ctx *sbus_srv; -}; - -static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - dbus_uint16_t version = POLKIT_VERSION; - const char *name = POLKIT_SERVICE_NAME; - DBusMessage *reply; - dbus_bool_t ret; - - DEBUG(4, ("Sending identity data [%s,%d]\n", name, version)); - - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - ret = dbus_message_append_args(reply, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); - if (!ret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - return EOK; -} - -static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - DBusMessage *reply; - dbus_bool_t ret; - - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - ret = dbus_message_append_args(reply, DBUS_TYPE_INVALID); - if (!ret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(sconn, reply); - dbus_message_unref(reply); - - return EOK; -} - -static int service_reload(DBusMessage *message, struct sbus_conn_ctx *sconn) -{ - /* Monitor calls this function when we need to reload - * our configuration information. Perform whatever steps - * are needed to update the configuration objects. - */ - - /* Send an empty reply to acknowledge receipt */ - return service_pong(message, sconn); -} - -struct sbus_method mon_sbus_methods[] = { - { SERVICE_METHOD_IDENTITY, service_identity }, - { SERVICE_METHOD_PING, service_pong }, - { SERVICE_METHOD_RELOAD, service_reload }, - { NULL, NULL } -}; - -static int spk_monitor_init(struct spk_ctx *spk_ctx) -{ - int ret; - char *sbus_address; - struct service_sbus_ctx *ss_ctx; - struct sbus_method_ctx *sm_ctx; - - /* Set up SBUS connection to the monitor */ - ret = monitor_get_sbus_address(spk_ctx, spk_ctx->cdb, &sbus_address); - if (ret != EOK) { - DEBUG(0, ("Could not locate monitor address.\n")); - return ret; - } - - ret = monitor_init_sbus_methods(spk_ctx, mon_sbus_methods, &sm_ctx); - if (ret != EOK) { - DEBUG(0, ("Could not initialize SBUS methods.\n")); - return ret; - } - - ret = sbus_client_init(spk_ctx, spk_ctx->ev, - sbus_address, sm_ctx, - NULL /* Private Data */, - NULL /* Destructor */, - &ss_ctx); - if (ret != EOK) { - DEBUG(0, ("Failed to connect to monitor services.\n")); - return ret; - } - - /* Set up PolicyKit-specific listeners */ - /* None currently used */ - - spk_ctx->ss_ctx = ss_ctx; - - return EOK; -} - -static int spk_process_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct confdb_ctx *cdb) -{ - struct spk_ctx *spk_ctx; - int ret; - - spk_ctx = talloc_zero(mem_ctx, struct spk_ctx); - if (spk_ctx == NULL) { - DEBUG(0, ("Fatal error initializing spk_ctx\n")); - return ENOMEM; - } - spk_ctx->ev = ev; - spk_ctx->cdb = cdb; - - ret = spk_monitor_init(spk_ctx); - if (ret != EOK) { - DEBUG(0, ("Fatal error setting up monitor bus\n")); - } - return ret; -} - -int main(int argc, const char *argv[]) -{ - int opt; - poptContext pc; - struct main_context *main_ctx; - int ret; - - 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); - - /* set up things like debug , signals, daemonization, etc... */ - ret = server_setup("sssd[pk]", 0, SPK_CONF_ENTRY, &main_ctx); - if (ret != EOK) return 2; - - ret = spk_process_init(main_ctx, - main_ctx->event_ctx, - main_ctx->confdb_ctx); - if (ret != EOK) return 3; - - /* loop on main */ - server_loop(main_ctx); - - return 0; -} diff --git a/server/polkit/sssd_polkit.h b/server/polkit/sssd_polkit.h deleted file mode 100644 index f9441409..00000000 --- a/server/polkit/sssd_polkit.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - SSSD - - Policy Kit Helper - - Copyright (C) Stephen Gallagher 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 . -*/ - -#ifndef POLKIT_H_ -#define POLKIT_H_ - -#define POLKIT_VERSION 0x0001 -#define POLKIT_SERVICE_NAME "spk" - -#endif /* POLKIT_H_ */ diff --git a/server/tests/infopipe-privileged-tests.c b/server/tests/infopipe-privileged-tests.c deleted file mode 100644 index d5c40662..00000000 --- a/server/tests/infopipe-privileged-tests.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Jakub Hrozek 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 . -*/ - -#include -#include -#include -#include -#include -#include -#include "util/util.h" -#include "confdb/confdb.h" -#include "sbus/sssd_dbus.h" -#include "infopipe/infopipe.h" -#include "db/sysdb.h" - -#define INFP_TEST_DBUS_NAME "org.freedesktop.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; -} - -START_TEST(test_infp_users_delete) -{ - DBusConnection *bus; - DBusMessage *delete_req; - DBusMessageIter iter; - DBusError error; - DBusMessage *reply; - const char *username = "testuser1"; - const char *domain = "LOCAL"; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - delete_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_USERS_DELETE); - if (!delete_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(delete_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &username); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - delete_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_users_set_uid) -{ - DBusConnection *bus; - DBusMessage *setuid_req; - DBusMessageIter iter; - DBusError error; - DBusMessage *reply; - const char *username = "testuser1"; - const char *domain = "LOCAL"; - u_int32_t new_id = 1666; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - setuid_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_USERS_SET_UID); - if (!setuid_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(setuid_req, &iter); - - dbus_message_iter_init_append(setuid_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &username); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &new_id); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - setuid_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_users_get_attr) -{ - DBusConnection *bus; - DBusMessage *get_attr_req; - DBusMessageIter iter, user_iter, attr_iter; - DBusError error; - DBusMessage *reply; - const char *username = "testuser1"; - const char *domain = "LOCAL"; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - get_attr_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_USERS_GET_ATTR); - if (!get_attr_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(get_attr_req, &iter); - - /* append the username */ - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "s", - &user_iter); /* Array of usernames */ - dbus_message_iter_append_basic(&user_iter, DBUS_TYPE_STRING, &username); - dbus_message_iter_close_container(&iter, &user_iter); - - /* append the domain */ - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - /* no attributes specified means retrieve all possible */ - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "s", - &attr_iter); /* Array of attributes */ - dbus_message_iter_close_container(&iter, &attr_iter); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - get_attr_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* Retreive the result */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_users_create) -{ - DBusConnection *bus; - DBusMessage *create_req; - const char *username = "testuser1"; - const char *fullname = "test create user"; - const char *domain = "LOCAL"; - const char *homedir = "/home/test_create_user"; - const char *shell = "/bin/sh"; - DBusMessageIter iter; - DBusError error; - DBusMessage *reply; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - create_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_USERS_CREATE); - if (!create_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(create_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &username); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &fullname); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &homedir); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &shell); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - create_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_groups_create) -{ - DBusConnection *bus; - DBusMessage *create_req; - const char *groupname = "testgroup1"; - const char *domain = "LOCAL"; - DBusMessageIter iter, group_iter; - DBusError error; - DBusMessage *reply; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - create_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_GROUPS_CREATE); - if (!create_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(create_req, &iter); - - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "s", - &group_iter); /* Array of groupnames */ - dbus_message_iter_append_basic(&group_iter, DBUS_TYPE_STRING, &groupname); - dbus_message_iter_close_container(&iter, &group_iter); - - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - create_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_groups_set_gid) -{ - DBusConnection *bus; - DBusMessage *setgid_req; - DBusMessageIter iter; - DBusError error; - DBusMessage *reply; - const char *groupname = "testgroup1"; - const char *domain = "LOCAL"; - u_int32_t new_id = 1666; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - setgid_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_GROUPS_SET_GID); - if (!setgid_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(setgid_req, &iter); - - dbus_message_iter_init_append(setgid_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &groupname); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &new_id); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - setgid_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_groups_add_members) -{ - DBusConnection *bus; - DBusMessage *add_member_req; - const char *groupname = "testgroup1"; - const char *membername = "testuser1"; - const char *domain = "LOCAL"; - DBusMessageIter iter, array_iter; - DBusError error; - DBusMessage *reply; - int type; - int membertype = 0; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - add_member_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_GROUPS_ADD_MEMBERS); - if (!add_member_req) { - fail("Could not create new method call message"); - goto done; - } - - /* Add the parameters */ - dbus_message_iter_init_append(add_member_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &groupname); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "(ss)", /* Array of members */ - &array_iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &membername); - dbus_message_iter_close_container(&iter, &array_iter); - - dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE, &membertype); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - add_member_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_groups_del_members) -{ - DBusConnection *bus; - DBusMessage *del_member_req; - DBusError error; - DBusMessage *reply; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - del_member_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_GROUPS_REMOVE_MEMBERS); - if (!del_member_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, - del_member_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -START_TEST(test_infp_groups_delete) -{ - DBusConnection *bus; - DBusMessage *delete_req; - const char *groupname = "testgroup1"; - const char *domain = "LOCAL"; - DBusMessageIter iter; - DBusError error; - DBusMessage *reply; - int type; - - if (setup_infp_tests(&bus) != EOK) { - fail("Could not set up the tests"); - return; - } - - delete_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_GROUPS_DELETE); - if (!delete_req) { - fail("Could not create new method call message"); - goto done; - } - - dbus_message_iter_init_append(delete_req, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &groupname); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - delete_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - - /* assert that the reply is an empty return message */ - type = dbus_message_get_type(reply); - fail_unless(type == DBUS_MESSAGE_TYPE_METHOD_RETURN, - "Method call returned %d instead of METHOD_RETURN", type); - -done: - teardown_infp_tests(bus); -} -END_TEST - -Suite *create_infopipe_suite(void) -{ - Suite *s = suite_create("infopipe"); - - TCase *tc_infp = tcase_create("InfoPipe Privileged Tests"); - - /* Test user methods */ - tcase_add_test(tc_infp, test_infp_users_create); - tcase_add_test(tc_infp, test_infp_users_set_uid); - tcase_add_test(tc_infp, test_infp_users_get_attr); - - /* Test group methods */ - tcase_add_test(tc_infp, test_infp_groups_create); - tcase_add_test(tc_infp, test_infp_groups_set_gid); - - /* Clean up */ - tcase_add_test(tc_infp, test_infp_users_delete); - tcase_add_test(tc_infp, test_infp_groups_delete); - -/* 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); -} diff --git a/server/tests/infopipe-tests.c b/server/tests/infopipe-tests.c deleted file mode 100644 index 171e58d4..00000000 --- a/server/tests/infopipe-tests.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher 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 . -*/ - -#include -#include -#include -#include -#include -#include -#include "util/util.h" -#include "confdb/confdb.h" -#include "sbus/sssd_dbus.h" -#include "infopipe/infopipe.h" -#include "db/sysdb.h" - -#define INFP_TEST_DBUS_NAME "org.freedesktop.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 */ - int c; - if ((c = strcmp(introspect_xml, returned_xml)) != 0) { - DEBUG(0, ("Verify Introspection XML: FAILED %d\nstrlen: %d, %d\n", c, strlen(introspect_xml), strlen(returned_xml))); - fail("");//"Verify Introspection XML: FAILED %d\n %s\nstrlen: %d", c, returned_xml, strlen(returned_xml)); - } - 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 - -START_TEST(test_infp_set_user_attrs) -{ - TALLOC_CTX *tmp_ctx; - DBusConnection *bus; - DBusMessage *setattr_req; - const char *username = "testuser1"; - const char *domain = "LOCAL"; - const char *shell_attr = SYSDB_SHELL; - const char *shell_value = "/usr/bin/testshell"; - DBusMessageIter iter, array_iter, dict_array_iter, dict_iter, variant_iter; - DBusError error; - DBusMessage *reply; - - 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; - } - - setattr_req = dbus_message_new_method_call(INFOPIPE_DBUS_NAME, - INFOPIPE_PATH, - INFOPIPE_INTERFACE, - INFP_USERS_SET_ATTR); - if (!setattr_req) { - fail("Could not create new method call message"); - goto done; - } - - /* Usernames */ - dbus_message_iter_init_append(setattr_req, &iter); - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "s", - &array_iter); /* Array of dict array of string->variant pairs */ - dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &username); - dbus_message_iter_close_container(&iter, &array_iter); - - /* Domain */ - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &domain); - - dbus_message_iter_open_container(&iter, - DBUS_TYPE_ARRAY, "a{sv}", - &array_iter); /* Array of dict array of string->variant pairs */ - dbus_message_iter_open_container(&array_iter, - DBUS_TYPE_ARRAY, "{sv}", - &dict_array_iter); /* Array of dict of string->variant pairs */ - dbus_message_iter_open_container(&dict_array_iter, - DBUS_TYPE_DICT_ENTRY, NULL, - &dict_iter); /* Dict entry of string->variant pair */ - dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &shell_attr); - dbus_message_iter_open_container(&dict_iter, - DBUS_TYPE_VARIANT, "s", - &variant_iter); /* Variant */ - dbus_message_iter_append_basic(&variant_iter, DBUS_TYPE_STRING, &shell_value); - dbus_message_iter_close_container(&dict_iter, &variant_iter); - dbus_message_iter_close_container(&dict_array_iter, &dict_iter); - dbus_message_iter_close_container(&array_iter, &dict_array_iter); - dbus_message_iter_close_container(&iter, &array_iter); - - /* Send the message */ - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(bus, - setattr_req, - TEST_TIMEOUT, - &error); - if(!reply) { - fail("Could not send message. Error: %s:%s", error.name, error.message); - dbus_error_free(&error); - goto done; - } - -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); - tcase_add_test(tc_infp, test_infp_set_user_attrs); - -/* 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); -} -- cgit