/* * Copyright (C) Sumit Bose 2009 * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * */ #include #include #include "tevent.h" #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus_interfaces.h" #include "util/service_helpers.h" #include "providers/data_provider.h" struct pp_context { struct event_context *event_ctx; struct service_sbus_ctx *sbus_dp_ctx; }; static void task_check_for_new_policies(struct event_context *ev_ctx, struct timed_event *te, struct timeval tval, void *ptr); static void process_dp_reply(DBusPendingCall *pending, void *ptr); static void set_task_check_for_new_policies(struct pp_context *pp_ctx) { struct timed_event *te = NULL; struct timeval tv; gettimeofday(&tv, NULL); tv.tv_sec += 5; tv.tv_usec = 0; te = event_add_timed(pp_ctx->event_ctx, pp_ctx, tv, task_check_for_new_policies, pp_ctx); if (te == NULL) exit(1); } static void task_check_for_new_policies(struct event_context *ev_ctx, struct timed_event *te, struct timeval tval, void *ptr) { DBusMessage* msg; DBusConnection *conn; DBusPendingCall* pending; struct pp_context *pp_ctx = talloc_get_type(ptr, struct pp_context); DEBUG(0,("Hello, I'm task_check_for_new_policies.\n")); conn = sbus_get_connection(pp_ctx->sbus_dp_ctx->scon_ctx); msg = dbus_message_new_method_call(NULL, DP_CLI_PATH, DP_CLI_INTERFACE, DP_PP_GET_POLICIES); if (msg == NULL) { DEBUG(0, ("dbus_message_new_method_call returned NULL, I do not know what to do, aborting ...\n")); /* FIXME */ exit(1); } if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) { DEBUG(0, ("Out Of Memory!\n")); /* FIXME */ exit(1); } if ( pending == NULL ) { DEBUG(0, ("pending is NULL\n")); /* FIXME */ exit(1); } dbus_pending_call_set_notify(pending, process_dp_reply, pp_ctx, NULL); dbus_message_unref(msg); } static void process_dp_reply(DBusPendingCall *pending, void *ptr) { DBusError dbus_error; DBusMessage* msg; int ret; int type; dbus_uint32_t ans; dbus_error_init(&dbus_error); dbus_pending_call_block(pending); msg = dbus_pending_call_steal_reply(pending); if (msg == NULL) { DEBUG(0, ("Reply Null\n")); /* FIXME */ exit(1); } type = dbus_message_get_type(msg); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: ret = dbus_message_get_args(msg, &dbus_error, DBUS_TYPE_UINT32, &ans, DBUS_TYPE_INVALID); if (!ret) { DEBUG(0, ("Failed to parse reply.\n")); exit(1); } else { switch(ans) { case POL_ANS_OFFLINE: DEBUG(3, ("Got POL_ANS_OFFLINE\n")); break; case POL_ANS_NOTHING_TO_DO: DEBUG(3, ("Got POL_ANS_NOTHING_TO_DO\n")); break; case POL_ANS_NEW_POL_AVAIL: DEBUG(3, ("Got POL_ANS_NEW_POL_AVAIL\n")); break; case POL_ANS_ERROR: DEBUG(3, ("Got POL_ANS_ERROR\n")); break; default: DEBUG(3, ("Got unknow reply: %d\n", ans)); } } break; case DBUS_MESSAGE_TYPE_ERROR: DEBUG(0, ("Reply error.\n")); break; default: DEBUG(0, ("Default... what now?.\n")); } dbus_pending_call_unref(pending); dbus_message_unref(msg); set_task_check_for_new_policies(ptr); } static int service_identity(DBusMessage *message, void *data, DBusMessage **r); static int service_pong(DBusMessage *message, void *data, DBusMessage **r); static int dp_cli_identity(DBusMessage *message, void *data, DBusMessage **r); struct sbus_method sbus_monitor_methods[] = { {SERVICE_METHOD_IDENTITY, service_identity}, {SERVICE_METHOD_PING, service_pong}, {NULL, NULL} }; struct sbus_method sbus_dp_methods[] = { {DP_CLI_METHOD_IDENTITY, dp_cli_identity}, {NULL, NULL} }; static int dp_cli_identity(DBusMessage *message, void *data, DBusMessage **r) { dbus_uint16_t version = 0x0001; /*FIXME */ dbus_uint16_t clitype = DP_CLI_FRONTEND; DBusMessage *reply; dbus_bool_t ret; char *name="PolicyProcessor"; char *domain="IPA"; DEBUG(0, ("dp_cli_identity got called.\n")); reply = dbus_message_new_method_return(message); ret = dbus_message_append_args(reply, DBUS_TYPE_UINT16, &clitype, DBUS_TYPE_UINT16, &version, DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INVALID); if (!ret) { return EIO; } *r = reply; return EOK; } static int service_identity(DBusMessage *message, void *data, DBusMessage **r) { dbus_uint16_t version = 0x0001; const char *name = "PolicyProcessor"; DBusMessage *reply; dbus_bool_t ret; DEBUG(0, ("service_identity got called.\n")); reply = dbus_message_new_method_return(message); ret = dbus_message_append_args(reply, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); if (!ret) { return EIO; } *r = reply; return EOK; } static int service_pong(DBusMessage *message, void *data, DBusMessage **r) { DBusMessage *reply; dbus_bool_t ret; reply = dbus_message_new_method_return(message); ret = dbus_message_append_args(reply, DBUS_TYPE_INVALID); if (!ret) { return EIO; } *r = reply; return EOK; } static int sssd_dp_sbus_init(TALLOC_CTX *mem_ctx, struct event_context *ev, struct confdb_ctx *cdb, struct sbus_method *methods, struct service_sbus_ctx **srvs_ctx, sbus_conn_destructor_fn destructor) { struct service_sbus_ctx *ss_ctx; struct sbus_method_ctx *sm_ctx; TALLOC_CTX *ctx; char *default_dp_address; int ret; ctx = talloc_new(mem_ctx); if (ctx == NULL) { ret = ENOMEM; goto done; } ss_ctx = talloc_zero(ctx, struct service_sbus_ctx); if (ss_ctx == NULL) { ret = ENOMEM; goto done; } ss_ctx->ev = ev; default_dp_address = talloc_asprintf(ctx, "unix:path=%s/%s", PIPE_PATH, DATA_PROVIDER_PIPE); if (default_dp_address == NULL) { ret = ENOMEM; goto done; } ret = sbus_new_connection(ss_ctx, ss_ctx->ev, default_dp_address, &ss_ctx->scon_ctx, destructor); if (ret != EOK) goto done; sm_ctx = talloc_zero(ss_ctx, struct sbus_method_ctx); if (sm_ctx == NULL) { ret = ENOMEM; goto done; } sm_ctx->interface = talloc_strdup(sm_ctx, DATA_PROVIDER_INTERFACE); sm_ctx->path = talloc_strdup(sm_ctx, DATA_PROVIDER_PATH); if (!sm_ctx->interface || !sm_ctx->path) { ret = ENOMEM; goto done; } sm_ctx->methods = methods; sm_ctx->message_handler = sbus_message_handler; sbus_conn_add_method_ctx(ss_ctx->scon_ctx, sm_ctx); talloc_steal(mem_ctx,ss_ctx); *srvs_ctx = ss_ctx; ret = EOK; done: talloc_free(ctx); return ret; } int setup_sbus_and_server_loop(void) { int ret=0; struct main_context *main_ctx = NULL; struct service_sbus_ctx *sbus_ctx = NULL; struct service_sbus_ctx *sbus_dp_ctx = NULL; struct pp_context *pp_ctx; ret = server_setup("PolicyProcessor", 0, &main_ctx); if (ret != EOK ) { DEBUG(0, ("sever_setup failed.\n")); return ret; } sbus_ctx = sssd_service_sbus_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx, sbus_monitor_methods, NULL); if (sbus_ctx == NULL) return -1; ret = sssd_dp_sbus_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx, sbus_dp_methods, &sbus_dp_ctx, NULL); if (ret != EOK) goto done; pp_ctx = talloc_zero(main_ctx, struct pp_context); if (pp_ctx == NULL) { ret = ENOMEM; goto done; } pp_ctx->event_ctx = main_ctx->event_ctx; pp_ctx->sbus_dp_ctx = sbus_dp_ctx; set_task_check_for_new_policies(pp_ctx); server_loop(main_ctx); done: talloc_free(main_ctx); return ret; }