>From 0e5514bc5267e56def5dd2e08a3130640947c0fb Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 17 Jan 2014 12:54:42 +0100 Subject: [PATCH 1/5] sbus: Add struct sbus_request to represent a DBus invocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit struct sbus_request represents a request from a dbus client being handled by a dbus server implementation. The struct contains the message, connection and method (and in the future teh property) which is being requested. In the future it will contain caller information as well. sbus_request is a talloc memory context, and is a good place to attach any allocations and memory specific to the request. Each handler accepts an sbus_request. If a handler returns EOK, it is assumed that the handler will finish the request. Any of the sbus_request_*finish() methods can be used to complete the request and send back a reply. sbus_request_return_and_finish() uses the same argument varargs syntax as dbus_message_append_args(), which isn't a great syntax. Document it a bit, but don't try to redesign: The marshalling work (will follow this patch set) will remove the need to use varargs for most DBus implementation code. This patch migrates the monitor and data provider dbus code to use sbus_request, but does not try to rework the talloc context's to use it. Reviewed-by: Jakub Hrozek Reviewed-by: Pavel Březina Reviewed-by: Lukáš Slebodník (cherry picked from commit d9577dbd92555b0755881e37724019ef9c578404) Conflicts: src/sbus/sssd_dbus.h --- Makefile.am | 1 + src/monitor/monitor.c | 54 +--- src/monitor/monitor_interfaces.h | 6 +- src/monitor/monitor_sbus.c | 26 +- src/providers/data_provider_be.c | 512 ++++++++++++-------------------- src/providers/proxy/proxy_child.c | 14 +- src/providers/proxy/proxy_init.c | 38 +-- src/responder/autofs/autofssrv.c | 10 +- src/responder/common/responder.h | 3 +- src/responder/common/responder_common.c | 7 +- src/responder/nss/nsssrv.c | 50 +--- src/sbus/sssd_dbus.h | 80 ++++- src/sbus/sssd_dbus_connection.c | 46 +-- src/sbus/sssd_dbus_private.h | 6 + src/sbus/sssd_dbus_request.c | 112 +++++++ src/tests/sbus_codegen_tests.c | 4 +- 16 files changed, 470 insertions(+), 499 deletions(-) create mode 100644 src/sbus/sssd_dbus_request.c diff --git a/Makefile.am b/Makefile.am index 0289645c9d52616938f6d693a7857f06837f0f08..01d199ace430ea42e7af1003eb0eb8498243b30d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -568,6 +568,7 @@ libsss_util_la_SOURCES = \ src/sbus/sssd_dbus_common.c \ src/sbus/sssd_dbus_connection.c \ src/sbus/sssd_dbus_meta.c \ + src/sbus/sssd_dbus_request.c \ src/sbus/sssd_dbus_server.c \ src/util/util.c \ src/util/memory.c \ diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 12c3a7702787fafcc1ea2244935f2213b46f6953..956e754254af37cb9ccb0df58ddd3d4269daab1d 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -219,28 +219,13 @@ static void network_status_change_cb(void *cb_data) /* dbus_get_monitor_version * Return the monitor version over D-BUS */ -static int get_monitor_version(DBusMessage *message, - struct sbus_connection *conn) +static int get_monitor_version(struct sbus_request *dbus_req) { dbus_uint16_t version = MONITOR_VERSION; - 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_UINT16, &version, - DBUS_TYPE_INVALID); - if (!ret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - - return EOK; + return sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &version, + DBUS_TYPE_INVALID); } struct mon_init_conn { @@ -253,21 +238,19 @@ static int add_svc_conn_spy(struct mt_svc *svc); /* registers a new client. * if operation is successful also sends back the Monitor version */ -static int client_registration(DBusMessage *message, - struct sbus_connection *conn) +static int client_registration(struct sbus_request *dbus_req) { dbus_uint16_t version = MONITOR_VERSION; struct mon_init_conn *mini; struct mt_svc *svc; void *data; - DBusMessage *reply; DBusError dbus_error; dbus_uint16_t svc_ver; char *svc_name; dbus_bool_t dbret; int ret; - data = sbus_conn_get_private_data(conn); + data = sbus_conn_get_private_data(dbus_req->conn); mini = talloc_get_type(data, struct mon_init_conn); if (!mini) { DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n"); @@ -279,7 +262,7 @@ static int client_registration(DBusMessage *message, dbus_error_init(&dbus_error); - dbret = dbus_message_get_args(message, &dbus_error, + dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_STRING, &svc_name, DBUS_TYPE_UINT16, &svc_ver, DBUS_TYPE_INVALID); @@ -287,7 +270,8 @@ static int client_registration(DBusMessage *message, DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message, killing connection\n"); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); - sbus_disconnect(conn); + sbus_disconnect(dbus_req->conn); + sbus_request_finish(dbus_req, NULL); /* FIXME: should we just talloc_zfree(conn) ? */ goto done; } @@ -308,7 +292,8 @@ static int client_registration(DBusMessage *message, DEBUG(SSSDBG_FATAL_FAILURE, "Unable to find peer [%s] in list of services," " killing connection!\n", svc_name); - sbus_disconnect(conn); + sbus_disconnect(dbus_req->conn); + sbus_request_finish(dbus_req, NULL); /* FIXME: should we just talloc_zfree(conn) ? */ goto done; } @@ -323,20 +308,9 @@ static int client_registration(DBusMessage *message, } /* reply that all is ok */ - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); - if (!dbret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &version, + DBUS_TYPE_INVALID); done: /* init complete, get rid of temp init context */ diff --git a/src/monitor/monitor_interfaces.h b/src/monitor/monitor_interfaces.h index ef4254a5f59620fe1789135248358bfa6ffe7530..2970251df94e75e5b1f5f746792a6eaf11f9577d 100644 --- a/src/monitor/monitor_interfaces.h +++ b/src/monitor/monitor_interfaces.h @@ -38,10 +38,8 @@ int monitor_get_sbus_address(TALLOC_CTX *mem_ctx, char **address); int monitor_common_send_id(struct sbus_connection *conn, const char *name, uint16_t version); -int monitor_common_pong(DBusMessage *message, - struct sbus_connection *conn); -int monitor_common_res_init(DBusMessage *message, - struct sbus_connection *conn); +int monitor_common_pong(struct sbus_request *dbus_req); +int monitor_common_res_init(struct sbus_request *dbus_req); int monitor_common_rotate_logs(struct confdb_ctx *confdb, const char *conf_entry); diff --git a/src/monitor/monitor_sbus.c b/src/monitor/monitor_sbus.c index b1550bcdd1927d62c55e85d0cca66aad0523c3ab..92d483233bd1cae45949dad1cd84b596cb099cec 100644 --- a/src/monitor/monitor_sbus.c +++ b/src/monitor/monitor_sbus.c @@ -144,30 +144,12 @@ int monitor_common_send_id(struct sbus_connection *conn, return retval; } -int monitor_common_pong(DBusMessage *message, - struct sbus_connection *conn) +int monitor_common_pong(struct sbus_request *dbus_req) { - 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(conn, reply); - dbus_message_unref(reply); - - return EOK; + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } -int monitor_common_res_init(DBusMessage *message, - struct sbus_connection *conn) +int monitor_common_res_init(struct sbus_request *dbus_req) { int ret; @@ -177,7 +159,7 @@ int monitor_common_res_init(DBusMessage *message, } /* Send an empty reply to acknowledge receipt */ - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } errno_t monitor_common_rotate_logs(struct confdb_ctx *confdb, diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 15b0d1d966cd01f114bfc4e56920f23e4a7866d1..ea3939f7e99d15da50ddc697b58217980dd7712b 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -54,14 +54,10 @@ #define ACCESS_DENY "deny" #define NO_PROVIDER "none" -static int data_provider_res_init(DBusMessage *message, - struct sbus_connection *conn); -static int data_provider_go_offline(DBusMessage *message, - struct sbus_connection *conn); -static int data_provider_reset_offline(DBusMessage *message, - struct sbus_connection *conn); -static int data_provider_logrotate(DBusMessage *message, - struct sbus_connection *conn); +static int data_provider_res_init(struct sbus_request *dbus_req); +static int data_provider_go_offline(struct sbus_request *dbus_req); +static int data_provider_reset_offline(struct sbus_request *dbus_req); +static int data_provider_logrotate(struct sbus_request *dbus_req); struct mon_cli_iface monitor_be_methods = { { &mon_cli_iface_meta, 0 }, @@ -81,13 +77,13 @@ struct sbus_interface monitor_be_interface = { NULL }; -static int client_registration(DBusMessage *message, struct sbus_connection *conn); -static int be_get_account_info(DBusMessage *message, struct sbus_connection *conn); -static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn); -static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn); -static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn); -static int be_host_handler(DBusMessage *message, struct sbus_connection *conn); -static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn); +static int client_registration(struct sbus_request *dbus_req); +static int be_get_account_info(struct sbus_request *dbus_req); +static int be_pam_handler(struct sbus_request *dbus_req); +static int be_sudo_handler(struct sbus_request *dbus_req); +static int be_autofs_handler(struct sbus_request *dbus_req); +static int be_host_handler(struct sbus_request *dbus_req); +static int be_get_subdomains(struct sbus_request *dbus_req); struct data_provider_iface be_methods = { { &data_provider_iface_meta, 0 }, @@ -401,14 +397,12 @@ static void be_queue_next_request(struct be_req *be_req, enum bet_type type) struct bet_queue_item *item; struct bet_queue_item *current = NULL; struct bet_queue_item **req_queue; + struct sbus_request *dbus_req; int ret; - DBusMessage *reply; uint16_t err_maj; uint32_t err_min; const char *err_msg = "Cannot file back end request"; struct be_req *next_be_req = NULL; - dbus_bool_t dbret; - DBusConnection *dbus_conn; req_queue = &be_req->becli->bectx->bet_info[type].req_queue; @@ -445,9 +439,9 @@ static void be_queue_next_request(struct be_req *be_req, enum bet_type type) be_queue_next_request(next_be_req, type); - reply = (DBusMessage *) next_be_req->pvt; + dbus_req = (struct sbus_request *) next_be_req->pvt; - if (reply) { + if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline @@ -455,28 +449,13 @@ static void be_queue_next_request(struct be_req *be_req, enum bet_type type) err_maj = DP_ERR_FATAL; err_min = ret; - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - dbus_message_unref(reply); - goto done; - } - - dbus_conn = sbus_get_connection(next_be_req->becli->conn); - if (dbus_conn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - goto done; - } - dbus_connection_send(dbus_conn, reply, NULL); - dbus_message_unref(reply); + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); } -done: talloc_free(next_be_req); } @@ -545,9 +524,7 @@ static void get_subdomains_callback(struct be_req *req, int errnum, const char *errstr) { - DBusMessage *reply; - DBusConnection *dbus_conn; - dbus_bool_t dbret; + struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; @@ -558,9 +535,9 @@ static void get_subdomains_callback(struct be_req *req, be_queue_next_request(req, BET_SUBDOMAINS); - reply = (DBusMessage *)req->pvt; + dbus_req = (struct sbus_request *)req->pvt; - if (reply) { + if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline @@ -578,39 +555,22 @@ static void get_subdomains_callback(struct be_req *req, err_msg = "OOM"; } - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - dbus_message_unref(reply); - goto done; - } - - dbus_conn = sbus_get_connection(req->becli->conn); - if (dbus_conn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - goto done; - } - dbus_connection_send(dbus_conn, reply, NULL); - dbus_message_unref(reply); + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); } -done: talloc_free(req); } -static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) +static int be_get_subdomains(struct sbus_request *dbus_req) { struct be_subdom_req *req; struct be_req *be_req = NULL; struct be_client *becli; - DBusMessage *reply; DBusError dbus_error; - dbus_bool_t dbret; void *user_data; dbus_bool_t force; char *domain_hint; @@ -619,14 +579,14 @@ static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) const char *err_msg; int ret; - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (!user_data) return EINVAL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; dbus_error_init(&dbus_error); - ret = dbus_message_get_args(message, &dbus_error, + ret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_BOOLEAN, &force, DBUS_TYPE_STRING, &domain_hint, DBUS_TYPE_INVALID); @@ -636,9 +596,6 @@ static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) return EIO; } - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - /* return an error if corresponding backend target is not configured */ if (becli->bectx->bet_info[BET_SUBDOMAINS].bet_ops == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "Undefined backend target.\n"); @@ -665,7 +622,7 @@ static int be_get_subdomains(DBusMessage *message, struct sbus_connection *conn) /* process request */ be_req = be_req_create(becli, becli, becli->bectx, - get_subdomains_callback, reply); + get_subdomains_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; @@ -710,26 +667,16 @@ immediate: talloc_free(be_req); } - if (reply) { - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - dbus_message_unref(reply); - return EIO; - } + /* send reply back */ + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); - if (!(err_maj == DP_ERR_FATAL && err_min == ENODEV)) { - DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", - err_maj, err_min, err_msg); - } - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); + if (!(err_maj == DP_ERR_FATAL && err_min == ENODEV)) { + DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", + err_maj, err_min, err_msg); } return EOK; @@ -740,16 +687,14 @@ static void acctinfo_callback(struct be_req *req, int errnum, const char *errstr) { - DBusMessage *reply; - DBusConnection *dbus_conn; - dbus_bool_t dbret; + struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; - reply = (DBusMessage *)req->pvt; + dbus_req = (struct sbus_request *)req->pvt; - if (reply) { + if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline @@ -768,24 +713,11 @@ static void acctinfo_callback(struct be_req *req, err_msg = "OOM"; } - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - return; - } - - dbus_conn = sbus_get_connection(req->becli->conn); - if (!dbus_conn) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - return; - } - - dbus_connection_send(dbus_conn, reply, NULL); - dbus_message_unref(reply); + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); @@ -1114,14 +1046,12 @@ errno_t be_get_account_info_recv(struct tevent_req *req, return EOK; } -static int be_get_account_info(DBusMessage *message, struct sbus_connection *conn) +static int be_get_account_info(struct sbus_request *dbus_req) { struct be_acct_req *req; struct be_req *be_req; struct be_client *becli; - DBusMessage *reply; DBusError dbus_error; - dbus_bool_t dbret; void *user_data; uint32_t type; char *filter; @@ -1134,14 +1064,14 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con be_req = NULL; - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (!user_data) return EINVAL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; dbus_error_init(&dbus_error); - ret = dbus_message_get_args(message, &dbus_error, + ret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT32, &type, DBUS_TYPE_UINT32, &attr_type, DBUS_TYPE_STRING, &filter, @@ -1156,9 +1086,6 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con DEBUG(SSSDBG_CONF_SETTINGS, "Got request for [%u][%d][%s]\n", type, attr_type, filter); - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - /* If we are offline and fast reply was requested * return offline immediately */ @@ -1168,19 +1095,19 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con err_min = EAGAIN; err_msg = "Fast reply - offline"; - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - reply = NULL; + dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * @@ -1190,7 +1117,7 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con } be_req = be_req_create(becli, becli, becli->bectx, - acctinfo_callback, reply); + acctinfo_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; @@ -1291,20 +1218,18 @@ done: talloc_free(be_req); } - if (reply) { - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + if (dbus_req) { + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); } return EOK; @@ -1316,9 +1241,9 @@ static void be_pam_handler_callback(struct be_req *req, const char *errstr) { struct be_client *becli = req->becli; + struct sbus_request *dbus_req; struct pam_data *pd; DBusMessage *reply; - DBusConnection *dbus_conn; dbus_bool_t dbret; errno_t ret; @@ -1353,7 +1278,14 @@ static void be_pam_handler_callback(struct be_req *req, DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n", pd->pam_status, pd->domain); - reply = (DBusMessage *)req->pvt; + dbus_req = (struct sbus_request *)req->pvt; + reply = dbus_message_new_method_return(dbus_req->message); + if (reply == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "dbus_message_new_method_return failed, cannot send reply.\n"); + goto done; + } + dbret = dp_pack_pam_response(reply, pd); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); @@ -1361,13 +1293,7 @@ static void be_pam_handler_callback(struct be_req *req, goto done; } - dbus_conn = sbus_get_connection(req->becli->conn); - if (!dbus_conn) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - goto done; - } - - dbus_connection_send(dbus_conn, reply, NULL); + sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); DEBUG(SSSDBG_CONF_SETTINGS, @@ -1377,7 +1303,7 @@ done: talloc_free(req); } -static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn) +static int be_pam_handler(struct sbus_request *dbus_req) { DBusError dbus_error; DBusMessage *reply; @@ -1388,29 +1314,21 @@ static int be_pam_handler(DBusMessage *message, struct sbus_connection *conn) struct be_req *be_req = NULL; enum bet_type target = BET_NULL; - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (!user_data) return EINVAL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; - reply = dbus_message_new_method_return(message); - if (!reply) { - DEBUG(SSSDBG_CRIT_FAILURE, - "dbus_message_new_method_return failed, cannot send reply.\n"); - return ENOMEM; - } - be_req = be_req_create(becli, becli, becli->bectx, - be_pam_handler_callback, reply); + be_pam_handler_callback, dbus_req); if (!be_req) { DEBUG(SSSDBG_TRACE_LIBS, "talloc_zero failed.\n"); - dbus_message_unref(reply); return ENOMEM; } dbus_error_init(&dbus_error); - ret = dp_unpack_pam_request(message, be_req, &pd, &dbus_error); + ret = dp_unpack_pam_request(dbus_req->message, be_req, &pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE,"Failed, to parse message!\n"); talloc_free(be_req); @@ -1488,6 +1406,13 @@ done: DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n", pd->pam_status, pd->domain); + reply = dbus_message_new_method_return(dbus_req->message); + if (reply == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "dbus_message_new_method_return failed, cannot send reply.\n"); + return ENOMEM; + } + ret = dp_pack_pam_response(reply, pd); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); @@ -1497,7 +1422,7 @@ done: } /* send reply back immediately */ - sbus_conn_send_reply(conn, reply); + sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); talloc_free(be_req); @@ -1505,42 +1430,26 @@ done: return EOK; } -static void be_sudo_handler_reply(struct sbus_connection *conn, - DBusMessage *reply, +static void be_sudo_handler_reply(struct sbus_request *dbus_req, dbus_uint16_t dp_err, dbus_uint32_t dp_ret, const char *errstr) { - DBusConnection *dbus_conn = NULL; - dbus_bool_t dbret; const char *err_msg = NULL; - if (reply == NULL) { + if (dbus_req == NULL) { return; } err_msg = errstr ? errstr : "No errmsg set\n"; - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &dp_err, - DBUS_TYPE_UINT32, &dp_ret, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - return; - } + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &dp_err, + DBUS_TYPE_UINT32, &dp_ret, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); DEBUG(SSSDBG_FUNC_DATA, "SUDO Backend returned: (%d, %d, %s)\n", dp_err, dp_ret, errstr ? errstr : ""); - - dbus_conn = sbus_get_connection(conn); - if (!dbus_conn) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - return; - } - - dbus_connection_send(dbus_conn, reply, NULL); - dbus_message_unref(reply); } static void be_sudo_handler_callback(struct be_req *req, @@ -1548,18 +1457,17 @@ static void be_sudo_handler_callback(struct be_req *req, int dp_ret, const char *errstr) { - DBusMessage *reply = NULL; - reply = (DBusMessage*)(req->pvt); + struct sbus_request *dbus_req; + dbus_req = (struct sbus_request *)(req->pvt); - be_sudo_handler_reply(req->becli->conn, reply, dp_err, dp_ret, errstr); + be_sudo_handler_reply(dbus_req, dp_err, dp_ret, errstr); talloc_free(req); } -static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) +static int be_sudo_handler(struct sbus_request *dbus_req) { DBusError dbus_error; - DBusMessage *reply = NULL; DBusMessageIter iter; dbus_bool_t iter_next = FALSE; struct be_client *be_cli = NULL; @@ -1575,7 +1483,7 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) DEBUG(SSSDBG_TRACE_FUNC, "Entering be_sudo_handler()\n"); - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (user_data == NULL) { return EINVAL; } @@ -1585,24 +1493,16 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) return EINVAL; } - reply = dbus_message_new_method_return(message); - if (!reply) { - DEBUG(SSSDBG_CRIT_FAILURE, - "dbus_message_new_method_return failed, cannot send reply.\n"); - return ENOMEM; - } - /* create be request */ be_req = be_req_create(be_cli, be_cli, be_cli->bectx, - be_sudo_handler_callback, reply); + be_sudo_handler_callback, dbus_req); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); - dbus_message_unref(reply); return ENOMEM; } dbus_error_init(&dbus_error); - dbus_message_iter_init(message, &iter); + dbus_message_iter_init(dbus_req->message, &iter); /* get type of the request */ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { @@ -1618,9 +1518,9 @@ static int be_sudo_handler(DBusMessage *message, struct sbus_connection *conn) * return offline immediately */ if ((type & BE_REQ_FAST) && be_cli->bectx->offstat.offline) { - be_sudo_handler_reply(conn, reply, DP_ERR_OFFLINE, EAGAIN, + be_sudo_handler_reply(dbus_req, DP_ERR_OFFLINE, EAGAIN, "Fast reply - offline"); - reply = NULL; + be_req->pvt = dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * @@ -1732,11 +1632,9 @@ static void be_autofs_handler_callback(struct be_req *req, int errnum, const char *errstr); -static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) +static int be_autofs_handler(struct sbus_request *dbus_req) { DBusError dbus_error; - DBusMessage *reply = NULL; - dbus_bool_t dbret; struct be_client *be_cli = NULL; struct be_req *be_req = NULL; struct be_autofs_req *be_autofs_req = NULL; @@ -1751,7 +1649,7 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) DEBUG(SSSDBG_TRACE_FUNC, "Entering be_autofs_handler()\n"); - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (user_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get SBUS private data\n"); return EINVAL; @@ -1765,7 +1663,7 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) dbus_error_init(&dbus_error); - ret = dbus_message_get_args(message, &dbus_error, + ret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT32, &type, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID); @@ -1775,13 +1673,6 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) return EIO; } - reply = dbus_message_new_method_return(message); - if (!reply) { - DEBUG(SSSDBG_CRIT_FAILURE, - "dbus_message_new_method_return failed, cannot send reply.\n"); - return ENOMEM; - } - /* If we are offline and fast reply was requested * return offline immediately */ @@ -1791,19 +1682,19 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) err_min = EAGAIN; err_msg = "Fast reply - offline"; - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - reply = NULL; + dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * @@ -1830,7 +1721,7 @@ static int be_autofs_handler(DBusMessage *message, struct sbus_connection *conn) /* create be request */ be_req = be_req_create(be_cli, be_cli, be_cli->bectx, - be_autofs_handler_callback, reply); + be_autofs_handler_callback, dbus_req); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); err_maj = DP_ERR_FATAL; @@ -1893,20 +1784,18 @@ done: talloc_free(be_req); } - if (reply) { - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + if (dbus_req) { + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); } return EOK; @@ -1917,16 +1806,14 @@ static void be_autofs_handler_callback(struct be_req *req, int errnum, const char *errstr) { - DBusMessage *reply; - DBusConnection *dbus_conn; - dbus_bool_t dbret; + struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; - reply = (DBusMessage *)req->pvt; + dbus_req = (struct sbus_request *)req->pvt; - if (reply) { + if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline @@ -1945,24 +1832,11 @@ static void be_autofs_handler_callback(struct be_req *req, err_msg = "OOM"; } - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); - return; - } - - dbus_conn = sbus_get_connection(req->becli->conn); - if (!dbus_conn) { - DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); - return; - } - - dbus_connection_send(dbus_conn, reply, NULL); - dbus_message_unref(reply); + sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", @@ -1973,14 +1847,12 @@ static void be_autofs_handler_callback(struct be_req *req, talloc_free(req); } -static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) +static int be_host_handler(struct sbus_request *dbus_req) { struct be_host_req *req; struct be_req *be_req; struct be_client *becli; - DBusMessage *reply; DBusError dbus_error; - dbus_bool_t dbret; void *user_data; uint32_t flags; char *filter; @@ -1991,14 +1863,14 @@ static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) be_req = NULL; - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (!user_data) return EINVAL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; dbus_error_init(&dbus_error); - ret = dbus_message_get_args(message, &dbus_error, + ret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID); @@ -2011,9 +1883,6 @@ static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) DEBUG(SSSDBG_TRACE_LIBS, "Got request for [%u][%s]\n", flags, filter); - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - /* If we are offline and fast reply was requested * return offline immediately */ @@ -2023,20 +1892,20 @@ static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) err_min = EAGAIN; err_msg = "Fast reply - offline"; - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - reply = NULL; + dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * @@ -2046,7 +1915,7 @@ static int be_host_handler(DBusMessage *message, struct sbus_connection *conn) } be_req = be_req_create(becli, becli, becli->bectx, - acctinfo_callback, reply); + acctinfo_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; @@ -2114,21 +1983,19 @@ done: talloc_free(be_req); } - if (reply) { - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &err_maj, - DBUS_TYPE_UINT32, &err_min, - DBUS_TYPE_STRING, &err_msg, - DBUS_TYPE_INVALID); - if (!dbret) return EIO; + if (dbus_req) { + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); + if (ret != EOK) { + return ret; + } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); } return EOK; @@ -2163,18 +2030,19 @@ static int be_client_destructor(void *ctx) return 0; } -static int client_registration(DBusMessage *message, - struct sbus_connection *conn) +static int client_registration(struct sbus_request *dbus_req) { dbus_uint16_t version = DATA_PROVIDER_VERSION; + struct sbus_connection *conn; struct be_client *becli; - DBusMessage *reply; DBusError dbus_error; dbus_uint16_t cli_ver; char *cli_name; dbus_bool_t dbret; void *data; + int ret; + conn = dbus_req->conn; data = sbus_conn_get_private_data(conn); becli = talloc_get_type(data, struct be_client); if (!becli) { @@ -2188,7 +2056,7 @@ static int client_registration(DBusMessage *message, dbus_error_init(&dbus_error); - dbret = dbus_message_get_args(message, &dbus_error, + dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT16, &cli_ver, DBUS_TYPE_STRING, &cli_name, DBUS_TYPE_INVALID); @@ -2221,26 +2089,14 @@ static int client_registration(DBusMessage *message, DEBUG(SSSDBG_CONF_SETTINGS, "Added Frontend client [%s]\n", cli_name); /* reply that all is ok */ - reply = dbus_message_new_method_return(message); - if (!reply) { - DEBUG(SSSDBG_FATAL_FAILURE, "Dbus Out of memory!\n"); - return ENOMEM; - } - - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_FATAL_FAILURE, "Failed to build dbus reply\n"); - dbus_message_unref(reply); + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &version, + DBUS_TYPE_INVALID); + if (ret != EOK) { sbus_disconnect(conn); - return EIO; + return ret; } - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - becli->initialized = true; return EOK; } @@ -3023,45 +2879,41 @@ int main(int argc, const char *argv[]) } #endif -static int data_provider_res_init(DBusMessage *message, - struct sbus_connection *conn) +static int data_provider_res_init(struct sbus_request *dbus_req) { struct be_ctx *be_ctx; - be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); + be_ctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct be_ctx); resolv_reread_configuration(be_ctx->be_res->resolv); check_if_online(be_ctx); - return monitor_common_res_init(message, conn); + return monitor_common_res_init(dbus_req); } -static int data_provider_go_offline(DBusMessage *message, - struct sbus_connection *conn) +static int data_provider_go_offline(struct sbus_request *dbus_req) { struct be_ctx *be_ctx; - be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); + be_ctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct be_ctx); be_mark_offline(be_ctx); - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } -static int data_provider_reset_offline(DBusMessage *message, - struct sbus_connection *conn) +static int data_provider_reset_offline(struct sbus_request *dbus_req) { struct be_ctx *be_ctx; - be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), struct be_ctx); + be_ctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct be_ctx); check_if_online(be_ctx); - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } -static int data_provider_logrotate(DBusMessage *message, - struct sbus_connection *conn) +static int data_provider_logrotate(struct sbus_request *dbus_req) { errno_t ret; - struct be_ctx *be_ctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct be_ctx *be_ctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct be_ctx); ret = monitor_common_rotate_logs(be_ctx->cdb, be_ctx->conf_path); if (ret != EOK) return ret; - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c index 46b55b9b84a232db752360466933679ebfc3583f..44d4fd6623e2ab4dc8dc6c7c7caf5d3029ec25b5 100644 --- a/src/providers/proxy/proxy_child.c +++ b/src/providers/proxy/proxy_child.c @@ -47,7 +47,7 @@ #include "providers/dp_backend.h" -static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn); +static int pc_pam_handler(struct sbus_request *dbus_req); struct data_provider_iface pc_methods = { { &data_provider_iface_meta, 0 }, @@ -310,7 +310,7 @@ fail: return ret; } -static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn) +static int pc_pam_handler(struct sbus_request *dbus_req) { DBusError dbus_error; DBusMessage *reply; @@ -319,7 +319,7 @@ static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn) void *user_data; struct pam_data *pd = NULL; - user_data = sbus_conn_get_private_data(conn); + user_data = sbus_conn_get_private_data(dbus_req->conn); if (!user_data) { ret = EINVAL; goto done; @@ -330,7 +330,7 @@ static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn) goto done; } - reply = dbus_message_new_method_return(message); + reply = dbus_message_new_method_return(dbus_req->message); if (!reply) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_return failed, " "cannot send reply.\n"); @@ -340,7 +340,7 @@ static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn) dbus_error_init(&dbus_error); - ret = dp_unpack_pam_request(message, pc_ctx, &pd, &dbus_error); + ret = dp_unpack_pam_request(dbus_req->message, pc_ctx, &pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE,"Failed, to parse message!\n"); ret = EIO; @@ -375,14 +375,14 @@ static int pc_pam_handler(DBusMessage *message, struct sbus_connection *conn) goto done; } - sbus_conn_send_reply(conn, reply); + ret = sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); talloc_free(pd); /* We'll return the message and let the * parent process kill us. */ - return EOK; + return ret; done: exit(ret); diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c index 60ae4a950fd18648d13b7fe50ef73d9a398ad8d5..70fe337cde7925311295f0b682860aa3d5de0a94 100644 --- a/src/providers/proxy/proxy_init.c +++ b/src/providers/proxy/proxy_init.c @@ -27,8 +27,7 @@ #include "util/sss_format.h" #include "providers/proxy/proxy.h" -static int client_registration(DBusMessage *message, - struct sbus_connection *conn); +static int client_registration(struct sbus_request *dbus_req); static struct data_provider_iface proxy_methods = { { &data_provider_iface_meta, 0 }, @@ -395,12 +394,11 @@ static void init_timeout(struct tevent_context *ev, */ } -static int client_registration(DBusMessage *message, - struct sbus_connection *conn) +static int client_registration(struct sbus_request *dbus_req) { dbus_uint16_t version = DATA_PROVIDER_VERSION; + struct sbus_connection *conn; struct proxy_client *proxy_cli; - DBusMessage *reply; DBusError dbus_error; dbus_uint16_t cli_ver; uint32_t cli_id; @@ -412,7 +410,9 @@ static int client_registration(DBusMessage *message, struct tevent_req *req; struct proxy_child_ctx *child_ctx; struct pc_init_ctx *init_ctx; + int ret; + conn = dbus_req->conn; data = sbus_conn_get_private_data(conn); proxy_cli = talloc_get_type(data, struct proxy_client); if (!proxy_cli) { @@ -427,7 +427,7 @@ static int client_registration(DBusMessage *message, dbus_error_init(&dbus_error); - dbret = dbus_message_get_args(message, &dbus_error, + dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT16, &cli_ver, DBUS_TYPE_UINT32, &cli_id, DBUS_TYPE_INVALID); @@ -453,31 +453,19 @@ static int client_registration(DBusMessage *message, } /* reply that all is ok */ - reply = dbus_message_new_method_return(message); - if (!reply) { - DEBUG(SSSDBG_FATAL_FAILURE, "Dbus Out of memory!\n"); - return ENOMEM; - } - - dbret = dbus_message_append_args(reply, - DBUS_TYPE_UINT16, &version, - DBUS_TYPE_INVALID); - if (!dbret) { - DEBUG(SSSDBG_FATAL_FAILURE, "Failed to build dbus reply\n"); - dbus_message_unref(reply); + ret = sbus_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &version, + DBUS_TYPE_INVALID); + if (ret != EOK) { sbus_disconnect(conn); - return EIO; + return ret; } - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - hret = hash_lookup(proxy_cli->proxy_auth_ctx->request_table, &key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Hash error [%d][%s]\n", hret, hash_error_string(hret)); - sbus_disconnect(conn); + sbus_disconnect(dbus_req->conn); } /* Signal that the child is up and ready to receive the request */ @@ -496,7 +484,7 @@ static int client_registration(DBusMessage *message, } init_ctx = tevent_req_data(child_ctx->init_req, struct pc_init_ctx); - init_ctx->conn = conn; + init_ctx->conn = dbus_req->conn; tevent_req_done(child_ctx->init_req); child_ctx->init_req = NULL; diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c index 5ce9ae0236d61b6b643cbc0682dc4bb53774b87f..b447a063448e420dac0b0ad6e9210a26b96d9c79 100644 --- a/src/responder/autofs/autofssrv.c +++ b/src/responder/autofs/autofssrv.c @@ -29,8 +29,7 @@ #include "providers/data_provider.h" #include "responder/autofs/autofs_private.h" -static int autofs_clean_hash_table(DBusMessage *message, - struct sbus_connection *conn); +static int autofs_clean_hash_table(struct sbus_request *dbus_req); struct mon_cli_iface monitor_autofs_methods = { { &mon_cli_iface_meta, 0 }, @@ -112,10 +111,9 @@ autofs_dp_reconnect_init(struct sbus_connection *conn, be_conn->domain->name); } -static int autofs_clean_hash_table(DBusMessage *message, - struct sbus_connection *conn) +static int autofs_clean_hash_table(struct sbus_request *dbus_req) { - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); struct autofs_ctx *actx = talloc_get_type(rctx->pvt_ctx, struct autofs_ctx); @@ -127,7 +125,7 @@ static int autofs_clean_hash_table(DBusMessage *message, return ret; } - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static int diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 5331d5b759059c1a78f3ce70adf4d5a309079efb..9d7cf3b54cefe339dcafce9a54b5e085d37212ae 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -214,8 +214,7 @@ struct dp_callback_ctx { void handle_requests_after_reconnect(struct resp_ctx *rctx); -int responder_logrotate(DBusMessage *message, - struct sbus_connection *conn); +int responder_logrotate(struct sbus_request *dbus_req); /* Each responder-specific request must create a constructor * function that creates a DBus Message that would be sent to diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 37c2ebe3a550ae9c787c82f4556eec32ed374edf..dabf5c053904d0e3df84b849bd0033bc78c1392e 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -989,17 +989,16 @@ done: return ret; } -int responder_logrotate(DBusMessage *message, - struct sbus_connection *conn) +int responder_logrotate(struct sbus_request *dbus_req) { errno_t ret; - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); ret = monitor_common_rotate_logs(rctx->cdb, rctx->confdb_service_path); if (ret != EOK) return ret; - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } void responder_set_fd_limit(rlim_t fd_limit) diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c index 05408db59fad12c4475ef796f8a4b6975ec50b6d..db4e18762c05ed5c36fbe18da3c6e5a80d8083ce 100644 --- a/src/responder/nss/nsssrv.c +++ b/src/responder/nss/nsssrv.c @@ -55,10 +55,8 @@ #define SHELL_REALLOC_INCREMENT 5 #define SHELL_REALLOC_MAX 50 -static int nss_clear_memcache(DBusMessage *message, - struct sbus_connection *conn); -static int nss_clear_netgroup_hash_table(DBusMessage *message, - struct sbus_connection *conn); +static int nss_clear_memcache(struct sbus_request *dbus_req); +static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req); struct mon_cli_iface monitor_nss_methods = { { &mon_cli_iface_meta, 0 }, @@ -75,15 +73,14 @@ struct mon_cli_iface monitor_nss_methods = { struct sbus_interface monitor_nss_interface = { MONITOR_PATH, &monitor_nss_methods.vtable, - NULL + NULL, }; -static int nss_clear_memcache(DBusMessage *message, - struct sbus_connection *conn) +static int nss_clear_memcache(struct sbus_request *dbus_req) { errno_t ret; int memcache_timeout; - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx; @@ -134,14 +131,13 @@ static int nss_clear_memcache(DBusMessage *message, } done: - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } -static int nss_clear_netgroup_hash_table(DBusMessage *message, - struct sbus_connection *conn) +static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req) { errno_t ret; - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx; @@ -152,7 +148,7 @@ static int nss_clear_netgroup_hash_table(DBusMessage *message, return ret; } - return monitor_common_pong(message, conn); + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells) @@ -308,10 +304,9 @@ done: return ret; } -static int nss_update_memcache(DBusMessage *message, - struct sbus_connection *conn) +static int nss_update_memcache(struct sbus_request *dbus_req) { - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); struct nss_ctx *nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); @@ -321,15 +316,13 @@ static int nss_update_memcache(DBusMessage *message, return EOK; } -static int nss_memcache_initgr_check(DBusMessage *message, - struct sbus_connection *conn) +static int nss_memcache_initgr_check(struct sbus_request *dbus_req) { - struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn), + struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(dbus_req->conn), struct resp_ctx); struct nss_ctx *nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); DBusError dbus_error; dbus_bool_t dbret; - DBusMessage *reply; char *user; char *domain; uint32_t *groups; @@ -337,7 +330,7 @@ static int nss_memcache_initgr_check(DBusMessage *message, dbus_error_init(&dbus_error); - dbret = dbus_message_get_args(message, &dbus_error, + dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_STRING, &user, DBUS_TYPE_STRING, &domain, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, @@ -357,20 +350,7 @@ static int nss_memcache_initgr_check(DBusMessage *message, nss_update_initgr_memcache(nctx, user, domain, gnum, groups); - reply = dbus_message_new_method_return(message); - if (!reply) return ENOMEM; - - dbret = dbus_message_append_args(reply, DBUS_TYPE_INVALID); - if (!dbret) { - dbus_message_unref(reply); - return EIO; - } - - /* send reply back */ - sbus_conn_send_reply(conn, reply); - dbus_message_unref(reply); - - return EOK; + return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static struct data_provider_rev_iface nss_dp_methods = { diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h index 3c99b3100e77a259fbdd7f209d2049b855b4bca9..dcb66907916606baede8a9744d775d7cce8a6e68 100644 --- a/src/sbus/sssd_dbus.h +++ b/src/sbus/sssd_dbus.h @@ -24,9 +24,11 @@ struct sbus_connection; -#include "dbus/dbus.h" +struct sbus_request; -typedef int (*sbus_msg_handler_fn)(DBusMessage *, struct sbus_connection *); +#include + +typedef int (*sbus_msg_handler_fn)(struct sbus_request *dbus_req); /* * sbus_conn_destructor_fn @@ -170,4 +172,78 @@ int sbus_conn_send(struct sbus_connection *conn, void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply); +/* + * This structure is passed to all dbus method and property + * handlers. It is a talloc context which will be valid until + * the request is completed with either the sbus_request_complete() + * or sbus_request_fail() functions. + */ +struct sbus_request { + struct sbus_connection *conn; + DBusMessage *message; + struct sbus_interface *intf; + const struct sbus_method_meta *method; +}; + +/* + * Complete a DBus request, and free the @dbus_req context. The @dbus_req + * and associated talloc context are no longer valid after this function + * returns. + * + * If @reply is non-NULL then the reply is sent to the caller. Not sending + * a reply when the caller is expecting one is fairly rude behavior. + * + * The return value is useful for logging, but not much else. In particular + * even if this function return !EOK, @dbus_req is still unusable after this + * function returns. + */ +int sbus_request_finish(struct sbus_request *dbus_req, + DBusMessage *reply); + +/* + * Return a reply for a DBus method call request. The variable + * arguments are (unfortunately) formatted exactly the same as those of the + * dbus_message_append_args() function. Documented here: + * + * http://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html + * + * Important: don't pass int or bool or such types as + * values to this function. That's not portable. Use actual dbus types. + * You must also pass pointers as the values: + * + * dbus_bool_t val1 = TRUE; + * dbus_int32_t val2 = 5; + * ret = sbus_request_finish(dbus_req, + * DBUS_TYPE_BOOLEAN, &val1, + * DBUS_TYPE_INT32, &val2, + * DBUS_TYPE_INVALID); + * + * To pass arrays to this function, use the following syntax. Never + * pass actual C arrays with [] syntax to this function. The C standard is + * rather vague with C arrays and varargs, and it just plain doesn't work. + * + * const char *array[] = { "one", "two", "three" }; + * int count = 3; // yes, a plain int + * const char **ptr = array; + * ret = sbus_request_finish(dbus_req, + * DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &ptr, 3, + * DBUS_TYPE_INVALID); + * + * The @dbus_req and associated talloc context are no longer valid after this + * function returns, even if this function returns an error code. + */ +int sbus_request_return_and_finish(struct sbus_request *dbus_req, + int first_arg_type, + ...); + +/* + * Return an error for a DBus method call request. The @error is a normal + * DBusError. + * + * The @dbus_req and associated talloc context are no longer valid after this + * function returns, even if this function returns an error code. + */ +int sbus_request_fail_and_finish(struct sbus_request *dbus_req, + const DBusError *error); + #endif /* _SSSD_DBUS_H_*/ diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c index e3f5e163df1609b1d9fea3540d3eff6c07ea868d..6535bc90e66e81d5c30ccd9fc598ca9b64a498be 100644 --- a/src/sbus/sssd_dbus_connection.c +++ b/src/sbus/sssd_dbus_connection.c @@ -415,7 +415,9 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, DBusMessage *reply = NULL; const struct sbus_method_meta *method; const struct sbus_interface_meta *interface; - sbus_msg_handler_fn handler_fn; + struct sbus_request *dbus_req = NULL; + sbus_msg_handler_fn handler_fn = NULL; + DBusHandlerResult result; int ret; if (!user_data) { @@ -435,10 +437,11 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, if (strcmp(path, intf_p->intf->path) != 0) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* Validate the method interface */ interface = intf_p->intf->vtable->meta; if (strcmp(msg_interface, interface->name) == 0) { - handler_fn = NULL; method = sbus_meta_find_method(interface, msg_method); if (method && method->vtable_offset) handler_fn = VTABLE_FUNC(intf_p->intf->vtable, method->vtable_offset); @@ -450,6 +453,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, reply = dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, NULL); sbus_conn_send_reply(intf_p->conn, reply); dbus_message_unref(reply); + result = DBUS_HANDLER_RESULT_HANDLED; } else if (!handler_fn) { /* Reply DBUS_ERROR_NOT_SUPPORTED */ @@ -458,11 +462,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, reply = dbus_message_new_error(message, DBUS_ERROR_NOT_SUPPORTED, NULL); sbus_conn_send_reply(intf_p->conn, reply); dbus_message_unref(reply); - - } else { - ret = handler_fn(message, intf_p->conn); - if (ret != EOK) - return sbus_reply_internal_error(message, intf_p->conn); + result = DBUS_HANDLER_RESULT_HANDLED; } } else { @@ -472,21 +472,28 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, if (strcmp(msg_interface, DBUS_INTROSPECT_INTERFACE) == 0 && strcmp(msg_method, DBUS_INTROSPECT_METHOD) == 0) { - if (intf_p->intf->introspect_fn) { - /* If we have been asked for introspection data and we have - * an introspection function registered, user that. - */ - ret = intf_p->intf->introspect_fn(message, intf_p->conn); - if (ret != EOK) { - return sbus_reply_internal_error(message, intf_p->conn); - } - } + handler_fn = intf_p->intf->introspect_fn; } - else - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - return DBUS_HANDLER_RESULT_HANDLED; + if (handler_fn) { + dbus_req = sbus_new_request(intf_p->conn, intf_p->intf, message); + if (!dbus_req) { + ret = ENOMEM; + } else { + dbus_req->method = method; + ret = handler_fn(dbus_req); + } + if (ret != EOK) { + if (dbus_req) + talloc_free(dbus_req); + result = sbus_reply_internal_error(message, intf_p->conn); + } else { + result = DBUS_HANDLER_RESULT_HANDLED; + } + } + + return result; } /* Adds a new D-BUS path message handler to the connection @@ -785,4 +792,3 @@ void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply) { dbus_connection_send(conn->dbus.conn, reply, NULL); } - diff --git a/src/sbus/sssd_dbus_private.h b/src/sbus/sssd_dbus_private.h index c62e0e3f60772dabc0a486e02eabf9eb017e12e8..eca5c8380493754bb6fd55ef47f1740c5f095021 100644 --- a/src/sbus/sssd_dbus_private.h +++ b/src/sbus/sssd_dbus_private.h @@ -96,4 +96,10 @@ dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data); void sbus_toggle_timeout(DBusTimeout *dbus_timeout, void *data); void sbus_remove_timeout(DBusTimeout *dbus_timeout, void *data); +/* =Requests============================================================== */ + +struct sbus_request * +sbus_new_request(struct sbus_connection *conn, struct sbus_interface *intf, + DBusMessage *message); + #endif /* _SSSD_DBUS_PRIVATE_H_ */ diff --git a/src/sbus/sssd_dbus_request.c b/src/sbus/sssd_dbus_request.c new file mode 100644 index 0000000000000000000000000000000000000000..973089c4bbc5d766edfe5792a366d0548c3c3855 --- /dev/null +++ b/src/sbus/sssd_dbus_request.c @@ -0,0 +1,112 @@ +/* + Authors: + Stef Walter + + Copyright (C) 2014 Red Hat + + 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 "util/util.h" +#include "sbus/sssd_dbus.h" + +#include +#include + +static int sbus_request_destructor(struct sbus_request *dbus_req) +{ + dbus_message_unref(dbus_req->message); + return 0; +} + +struct sbus_request * +sbus_new_request(struct sbus_connection *conn, + struct sbus_interface *intf, + DBusMessage *message) +{ + struct sbus_request *dbus_req; + + dbus_req = talloc_zero(conn, struct sbus_request); + if (!dbus_req) { + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus request\n"); + return NULL; + } + + dbus_req->intf = intf; + dbus_req->conn = conn; + dbus_req->message = dbus_message_ref(message); + talloc_set_destructor(dbus_req, sbus_request_destructor); + + return dbus_req; +} + +int sbus_request_finish(struct sbus_request *dbus_req, + DBusMessage *reply) +{ + if (reply) { + sbus_conn_send_reply(dbus_req->conn, reply); + } + return talloc_free(dbus_req); +} + +int sbus_request_return_and_finish(struct sbus_request *dbus_req, + int first_arg_type, + ...) +{ + DBusMessage *reply; + dbus_bool_t dbret; + va_list va; + int ret; + + reply = dbus_message_new_method_return(dbus_req->message); + if (!reply) { + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n"); + sbus_request_finish(dbus_req, NULL); + return ENOMEM; + } + + va_start(va, first_arg_type); + dbret = dbus_message_append_args_valist(reply, first_arg_type, va); + va_end(va); + + if (dbret) { + ret = sbus_request_finish(dbus_req, reply); + + } else { + DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't build DBus message\n"); + sbus_request_finish(dbus_req, NULL); + ret = EINVAL; + } + + dbus_message_unref(reply); + return ret; +} + +int sbus_request_fail_and_finish(struct sbus_request *dbus_req, + const DBusError *error) +{ + DBusMessage *reply; + int ret; + + reply = dbus_message_new_error(dbus_req->message, error->name, error->message); + if (!reply) { + DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n"); + sbus_request_finish(dbus_req, NULL); + return ENOMEM; + } + + ret = sbus_request_finish(dbus_req, reply); + dbus_message_unref(reply); + return ret; +} diff --git a/src/tests/sbus_codegen_tests.c b/src/tests/sbus_codegen_tests.c index 7386756cd1ed37fe5362634e9432bba5893d6ee3..146e18a850ad8dc322a379bdbb5c70ec95153277 100644 --- a/src/tests/sbus_codegen_tests.c +++ b/src/tests/sbus_codegen_tests.c @@ -113,14 +113,14 @@ START_TEST(test_signals) END_TEST static int -mock_move_universe(DBusMessage *msg, struct sbus_connection *conn) +mock_move_universe(struct sbus_request *dbus_req) { /* not called */ return 0; } static int -mock_crash_now(DBusMessage *msg, struct sbus_connection *conn) +mock_crash_now(struct sbus_request *dbus_req) { /* not called */ return 0; -- 1.9.0