diff options
-rw-r--r-- | server/infopipe/infopipe_groups.c | 193 | ||||
-rw-r--r-- | server/infopipe/infopipe_users.c | 4 |
2 files changed, 193 insertions, 4 deletions
diff --git a/server/infopipe/infopipe_groups.c b/server/infopipe/infopipe_groups.c index 7ec85296..ac652761 100644 --- a/server/infopipe/infopipe_groups.c +++ b/server/infopipe/infopipe_groups.c @@ -20,20 +20,209 @@ */ #include <dbus/dbus.h> +#include <ldb.h> +#include <time.h> #include "util/util.h" -#include "infopipe.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_req *sysdb_req; +}; + +static void infp_do_group_create(struct sysdb_req *req, 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->sysdb_req, 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); + 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->sysdb_req, grcreate_req); + return; + } + + /* We have no more usernames to add, so commit the transaction */ + sysdb_transaction_done(grcreate_req->sysdb_req, status); + reply = + dbus_message_new_method_return(grcreate_req->infp_req->req_message); + if (reply) sbus_conn_send_reply(grcreate_req->infp_req->sconn, reply); + talloc_free(grcreate_req); + return; +} + +static void infp_do_group_create(struct sysdb_req *req, void *pvt) +{ + int ret; + struct infp_creategroup_ctx *grcreate_req = + talloc_get_type(pvt, struct infp_creategroup_ctx); + + grcreate_req->sysdb_req = req; + + ret = sysdb_add_group(grcreate_req->sysdb_req, + 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->sysdb_req, ret); + 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; - reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, "Not yet implemented"); + /* 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 = + btreemap_get_value(grcreate_req->infp_req->infp->domain_map, + (const void *)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); + talloc_free(grcreate_req); + return ret; } int infp_groups_delete(DBusMessage *message, struct sbus_conn_ctx *sconn) diff --git a/server/infopipe/infopipe_users.c b/server/infopipe/infopipe_users.c index e65090e9..82b7c047 100644 --- a/server/infopipe/infopipe_users.c +++ b/server/infopipe/infopipe_users.c @@ -259,7 +259,7 @@ static void infp_do_user_create(struct sysdb_req *req, void *pvt) infp_do_user_create_callback, infp_createuser_req); if (ret != EOK) { - DEBUG(0, ("Could not invoke sysdb_add_user")); + DEBUG(0, ("Could not invoke sysdb_add_user\n")); sysdb_transaction_done(infp_createuser_req->sysdb_req, ret); talloc_free(infp_createuser_req); return; @@ -359,7 +359,7 @@ int infp_users_create(DBusMessage *message, struct sbus_conn_ctx *sconn) INFP_OBJ_TYPE_USER, NULL, INFP_ACTION_TYPE_CREATE, - INFP_ACTION_TYPE_INVALID)) goto denied; + INFP_ATTR_TYPE_INVALID)) goto denied; ret = sysdb_transaction(infp_createuser_req, infp_createuser_req->infp_req->infp->sysdb, |