diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2009-07-20 13:57:04 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2009-07-20 14:29:43 -0400 |
commit | bb4570d2f3ed0c9b780010623de82c4c76d15a2c (patch) | |
tree | 57d9e2f20e02bd73525e1c0cbc0d48f422de7834 /server | |
parent | a4aa051dbf8dd6087307186bb86d0f30154a29b3 (diff) | |
download | sssd-bb4570d2f3ed0c9b780010623de82c4c76d15a2c.tar.gz sssd-bb4570d2f3ed0c9b780010623de82c4c76d15a2c.tar.xz sssd-bb4570d2f3ed0c9b780010623de82c4c76d15a2c.zip |
Remove unused InfoPipe and PolicyKit code
Diffstat (limited to 'server')
-rw-r--r-- | server/Makefile.am | 66 | ||||
-rw-r--r-- | server/conf_macros.m4 | 34 | ||||
-rw-r--r-- | server/configure.ac | 2 | ||||
-rw-r--r-- | server/infopipe/infopipe.c | 748 | ||||
-rw-r--r-- | server/infopipe/infopipe.h | 116 | ||||
-rw-r--r-- | server/infopipe/infopipe_groups.c | 832 | ||||
-rw-r--r-- | server/infopipe/infopipe_private.h | 98 | ||||
-rw-r--r-- | server/infopipe/infopipe_users.c | 1846 | ||||
-rw-r--r-- | server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml | 277 | ||||
-rw-r--r-- | server/infopipe/org.freedesktop.sssd.infopipe.conf | 24 | ||||
-rw-r--r-- | server/infopipe/sysbus.c | 198 | ||||
-rw-r--r-- | server/infopipe/sysbus.h | 37 | ||||
-rw-r--r-- | server/polkit/sssd_polkit.c | 206 | ||||
-rw-r--r-- | server/polkit/sssd_polkit.h | 28 | ||||
-rw-r--r-- | server/tests/infopipe-privileged-tests.c | 615 | ||||
-rw-r--r-- | server/tests/infopipe-tests.c | 405 |
16 files changed, 2 insertions, 5530 deletions
diff --git a/server/Makefile.am b/server/Makefile.am index 63d98bcde..539c90063 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 c67b47b08..2613bfb3b 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 facefe27a..084ef3bce 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 729983019..000000000 --- a/server/infopipe/infopipe.c +++ /dev/null @@ -1,748 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdio.h> -#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 516703762..000000000 --- a/server/infopipe/infopipe.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef INFOPIPE_H_ -#define INFOPIPE_H_ - -#include <dbus/dbus.h> -#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 a2fe5a405..000000000 --- a/server/infopipe/infopipe_groups.c +++ /dev/null @@ -1,832 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <dbus/dbus.h> -#include <ldb.h> -#include <time.h> -#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 7317f7a62..000000000 --- a/server/infopipe/infopipe_private.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#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 aac79f7f9..000000000 --- a/server/infopipe/infopipe_users.c +++ /dev/null @@ -1,1846 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include <dbus/dbus.h> -#include <ldb.h> -#include <time.h> -#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 c35b14053..000000000 --- a/server/infopipe/org.freedesktop.sssd.infopipe.Introspect.xml +++ /dev/null @@ -1,277 +0,0 @@ -<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node name="/org/freedesktop/sssd/infopipe1"> - <interface name="org.freedesktop.sssd.infopipe"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString.Summary" - value="InfoPipe Interface version 1" - /> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="This is a D-BUS interface used for reading and writing POSIX and extended user attributes within the System Security Services Daemon." - /> - -<!-- -************************************************************************** -* Permission Methods * -************************************************************************** ---> - <method name="CheckPermissions1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Determine whether the caller has permissions on one or more instances of domain objects - @param domain The domain to query - @param object An object type in the domain - Object Types: - user - group - @param instance A particular instance of an object (a username or group name). An empty string will be interpreted as all instances. - @param actions A list of actions to check the permissions of. Each action is described as a pair of (action_type, attribute). If attribute is left as an empty string, the query is for a global value (such as create or delete user) If the attribute value does not make sense for a particular object/instance/action, it will be ignored. Action types not applicable to an object/instance will return false (such as addmember on users). - Available action types: - read - create - delete - modify - addmember - removemember - @return permissions A list of boolean values returned in the same order as the action list, one for each requested action. True means permission on that action is granted. - @note some examples: - Can I create new users in domain LOCAL?: - CheckPermissions(domain=>'LOCAL', object=>'user', instance=>'', actions=>[('create','')]) - returns permissions=>[0] - Can I create new groups in domain LOCAL? - CheckPermissions(domain=>'LOCAL', object=>'group', instance=>'', actions=>[('create','')]) - returns permissions=>[0] - Can I modify user testuser1's userpic and full name? - CheckPermissions(domain=>'LOCAL', object=>'user', instance=>'testuser1', actions=>[('modify','userpic'),('modify','fullname')]) - returns permissions=>[1,0] - Can I add members to group wheel? - CheckPermissions(domain=>'LOCAL', object=>'group', instance=>'wheel', actions=>[('addmember','somearg')]) - returns permissions=>[1] - The argument 'somearg' is ignored, since it does not apply to addmember." - /> - <arg name="domain" type="s" direction="in" /> - <arg name="object" type="s" direction="in" /> - <arg name="instance" type="s" direction="in" /> - <arg name="actions" type="a(ss)" direction="in" /> - <arg name="permissions" type="ab" direction="out" /> - </method> -<!-- -************************************************************************** -* User Methods * -************************************************************************** ---> - <method name="GetCachedUsers1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Get a list of users stored locally in SSSD for this system. This is not a complete user listing for remote domains, only a listing of domain members that have logged in locally. - @param domain The domain to query. - @param minlastlogin Return only users who have logged in successfully since this UNIX timestamp. For all cached users in a domain, set to 0. - @return users Returns a string array of usernames. - @error DBUS_ERROR_INVALID_ARGS One or more specified domains do not exist." - /> - <arg name="domain" type="s" direction="in" /> - <arg name="minlastlogin" type="t" direction="in" /> - <arg name="users" type="as" direction="out"/> - </method> - - <method name="CreateUser1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Create a new user in a particular domain. User will initially have a disabled password. - @param username Username for the new user. Must be unique within a domain. - @param domain The domain in which to add the user - @param fullname Full (display) name for the user. Will set both 'fullname' and 'gecos' to this value initially. - @param homedir Home directory path for the user. Must be a parsable path, but does not need to exist or be mounted. - @param shell Login shell. Must exist in /etc/shells. - @return Returns an empty D-BUS reply to indicate success. Failure will return an error. - @error DBUS_ERROR_INVALID_ARGS See parameter requirements. Reason will be included in the error message. - @error DBUS_ERROR_ACCESS_DENIED Caller did not have permission to create a new user on the specified domain - @note CreateUser will ignore users that already exist. - @note This function will automatically generate an appropriate UID for the user." - /> - <arg name="username" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="fullname" type="s" direction="in" /> - <arg name="homedir" type="s" direction="in" /> - <arg name="shell" type="s" direction="in" /> - </method> - - <method name="DeleteUser1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Delete a user by UID from a specified domain. - @param username The user to delete. - @param domain The domain from which to delete the user. - @return Returns an empty D-BUS reply if the deletion was successful. Failure will return an error. - @error DBUS_ERROR_INVALID_ARGS No such domain. See error message for details. - @error DBUS_ACCESS_DENIED Caller did not have permission to delete this user. - @note DeleteUser ignores groups that don't exist." - /> - <arg name="username" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - </method> - - <method name="GetUserAttributes1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Get user information - @param usernames An array of unique usernames. - @param domain The domain from which to query user information. - @param filter An array of strings containing a list of requested attributes. A zero-length array will indicate to return all authorized parameters. - attributes(value type): - defaultgroup(STRING) - gecos(STRING) - homedir(STRING) - shell(STRING) - fullname(STRING) - locale(STRING) - keyboard(STRING) - session(STRING) - last_login(UINT64) - userpic(BYTE ARRAY) - @return attributes An array of extended user information dicts, one for each requested username. Only attributes that the caller had read authorization for will be returned. - @error DBUS_ERROR_INVALID_ARGS Usernames or filter entries were not unique or one or more filter entries were invalid. - @note For standard POSIX attributes, use getpwnam(). - @note The attribute userpic may contain very large binary data. It is advisable to request this data separately from other attributes to avoid D-BUS message size limits." - /> - <arg name="usernames" type="as" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="filter" type="as" direction="in" /> - <arg name="attributes" type="aa{sv}" direction="out" /> - </method> - - <method name="SetUserAttributes1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Set user attributes for one or more users - @param usernames An array of unique usernames. - @param domain The domain of the users to edit. - @param attributes An array of dict(string, variant), either exactly one dict (meaning use the same values for all UIDs), or one dict for each username. An empty value for the variant means delete the attribute. - attributes(value type): - defaultgroup(STRING) - gecos(STRING) - homedir(STRING) - shell(STRING) - fullname(STRING) - locale(STRING) - keyboard(STRING) - session(STRING) - last_login(UINT64) - userpic(BYTE ARRAY) - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS Usernames were not unique - @note The attribute userpic may contain very large binary data. It is advisable to set this data separately from other attributes to avoid D-BUS message size limits." - /> - <arg name="usernames" type="as" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="attributes" type="aa{sv}" direction="in" /> - </method> - - <method name="Set_YouReallyDoNotWantToUseThisFunction_UserUID1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Change the User ID for a user. - @param username The username - @param domain The user's domain - @param uid The new UID - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS Domain or user did not exist - @error DBUS_ERROR_ACCESS_DENIED Caller did not have permission to edit this user - @note This function should be used sparingly. The automatically-generated user id from CreateUser should be sufficient for most cases." - /> - <arg name="username" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="uid" type="u" direction="in" /> - </method> - -<!-- -************************************************************************** -* Group Methods * -************************************************************************** ---> - <method name="CreateGroup1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Create new user groups - @param groupnames A list of new groups to add. - @param domain The domain in which to create the groups. - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS Domain does not exist. - @error DBUS_ERROR_ACCESS_DENIED The caller does not have authorization to create groups in the specified domain. - @note CreateGroup ignores groups that already exist. - @note This function will automatically generate an appropriate group ID for this group." - /> - <arg name="groupnames" type="as" direction="in" /> - <arg name="domain" type="s" direction="in" /> - </method> - - <method name="DeleteGroup1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Delete a user group - @param groupname A group to delete. - @param domain The domain from which to delete the group. - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS Domain does not exist. - @error DBUS_ERROR_ACCESS_DENIED The caller does not have authorization to delete groups from the specified domain. - @note DeleteGroup ignores groups that don't exist." - /> - <arg name="groupname" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - </method> - - <method name="AddGroupMembers1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Add members to a group - @param group Group being modified. - @param domain The domain the group belongs to. - @param members Array of member strings to add to the group. - @param membertype 0: Users, 1: Groups - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS The domain does not exist - @error DBUS_ERROR_ACCESS_DENIED The caller does not have authorization to modify the group." - /> - <arg name="group" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="members" type="as" direction="in" /> - <arg name="membertype" type="y" direction="in" /> - </method> - - <method name="RemoveGroupMembers1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Remove members from a group - @param group Group being modified. - @param domain The domain the group belongs to. - @param members Array of member strings to remove from the group. - @param membertype 0: Users, 1: Groups - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS The domain does not exist - @error DBUS_ERROR_ACCESS_DENIED The caller does not have authorization to modify the group." - /> - <arg name="group" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="members" type="as" direction="in" /> - <arg name="membertype" type="y" direction="in" /> - </method> - - <method name="Set_YouReallyDoNotWantToUseThisFunction_GroupGID1"> - <annotation - name="org.freedesktop.sssd.infopipe.DocString" - value="Change the User ID for a user. - @param group The group name - @param domain The group's domain - @param gid The new GID - @return Returns an empty D-BUS reply on success. Will return an error on failure. - @error DBUS_ERROR_INVALID_ARGS Domain or group did not exist - @error DBUS_ERROR_ACCESS_DENIED Caller did not have permission to edit this group - @note This function should be used sparingly. The automatically-generated group id from CreateGroup should be sufficient for most cases." - /> - <arg name="group" type="s" direction="in" /> - <arg name="domain" type="s" direction="in" /> - <arg name="gid" type="t" direction="in" /> - </method> - </interface> -</node> diff --git a/server/infopipe/org.freedesktop.sssd.infopipe.conf b/server/infopipe/org.freedesktop.sssd.infopipe.conf deleted file mode 100644 index ab623208f..000000000 --- a/server/infopipe/org.freedesktop.sssd.infopipe.conf +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE busconfig PUBLIC - "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - - <!-- This configuration file specifies the required security policies - for the HAL to work. --> - - <!-- Only root can own the SSSD service --> - <policy user="root"> - <allow own="org.freedesktop.sssd.infopipe1"/> - <allow send_interface="org.freedesktop.sssd.infopipe1"/> - </policy> - - <!-- Allow all methods on the interface --> - <!-- Right now, this will be handled by a limited ACL - within the InfoPipe Daemon. --> - <policy context="default"> - <allow own="org.freedesktop.sssd.infopipe1.test"/> - <allow send_interface="org.freedesktop.sssd.infopipe1"/> - </policy> - -</busconfig> - diff --git a/server/infopipe/sysbus.c b/server/infopipe/sysbus.c deleted file mode 100644 index efb43b344..000000000 --- a/server/infopipe/sysbus.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - SSSD - - SystemBus Helpers - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "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 cb45fa7ef..000000000 --- a/server/infopipe/sysbus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - SSSD - - SystemBus Helpers - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#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 a7a3d89de..000000000 --- a/server/polkit/sssd_polkit.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - SSSD - - PolicyKit - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#define _GNU_SOURCE -#include <stdlib.h> -#include <stdio.h> -#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 f9441409c..000000000 --- a/server/polkit/sssd_polkit.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - SSSD - - Policy Kit Helper - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#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 d5c406624..000000000 --- a/server/tests/infopipe-privileged-tests.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdlib.h> -#include <check.h> -#include <talloc.h> -#include <tevent.h> -#include <popt.h> -#include <dbus/dbus.h> -#include "util/util.h" -#include "confdb/confdb.h" -#include "sbus/sssd_dbus.h" -#include "infopipe/infopipe.h" -#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 171e58d46..000000000 --- a/server/tests/infopipe-tests.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - SSSD - - InfoPipe - - Copyright (C) Stephen Gallagher <sgallagh@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <stdlib.h> -#include <check.h> -#include <talloc.h> -#include <tevent.h> -#include <popt.h> -#include <dbus/dbus.h> -#include "util/util.h" -#include "confdb/confdb.h" -#include "sbus/sssd_dbus.h" -#include "infopipe/infopipe.h" -#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); -} |