diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/monitor/monitor.c | 54 | ||||
-rw-r--r-- | src/monitor/monitor_interfaces.h | 6 | ||||
-rw-r--r-- | src/monitor/monitor_sbus.c | 26 | ||||
-rw-r--r-- | src/providers/data_provider_be.c | 512 | ||||
-rw-r--r-- | src/providers/proxy/proxy_child.c | 14 | ||||
-rw-r--r-- | src/providers/proxy/proxy_init.c | 38 | ||||
-rw-r--r-- | src/responder/autofs/autofssrv.c | 10 | ||||
-rw-r--r-- | src/responder/common/responder.h | 3 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 7 | ||||
-rw-r--r-- | src/responder/nss/nsssrv.c | 50 | ||||
-rw-r--r-- | src/sbus/sssd_dbus.h | 78 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_connection.c | 46 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_private.h | 6 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_request.c | 112 | ||||
-rw-r--r-- | src/tests/sbus_codegen_tests.c | 4 |
16 files changed, 469 insertions, 498 deletions
diff --git a/Makefile.am b/Makefile.am index 750f626d1..1c0b78e93 100644 --- a/Makefile.am +++ b/Makefile.am @@ -591,6 +591,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 ecfa95cfd..2e0f5230f 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -217,28 +217,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 { @@ -251,21 +236,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"); @@ -277,7 +260,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); @@ -285,7 +268,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; } @@ -306,7 +290,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; } @@ -321,20 +306,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 ef4254a5f..2970251df 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 b1550bcdd..92d483233 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 5207d19eb..cd51bd81c 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 }, @@ -396,14 +392,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; @@ -440,9 +434,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 @@ -450,28 +444,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); } @@ -551,9 +530,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; @@ -564,9 +541,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 @@ -584,39 +561,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; @@ -625,14 +585,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); @@ -642,9 +602,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"); @@ -671,7 +628,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; @@ -716,26 +673,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; - } - - 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_request_return_and_finish(dbus_req, + DBUS_TYPE_UINT16, &err_maj, + DBUS_TYPE_UINT32, &err_min, + DBUS_TYPE_STRING, &err_msg, + DBUS_TYPE_INVALID); - /* 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; @@ -746,16 +693,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 @@ -774,24 +719,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); @@ -1120,14 +1052,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; @@ -1140,14 +1070,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, @@ -1162,9 +1092,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 */ @@ -1174,19 +1101,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. * @@ -1196,7 +1123,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; @@ -1297,20 +1224,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; @@ -1322,9 +1247,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; @@ -1359,7 +1284,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"); @@ -1367,13 +1299,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, @@ -1383,7 +1309,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; @@ -1394,29 +1320,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); @@ -1494,6 +1412,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"); @@ -1503,7 +1428,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); @@ -1511,42 +1436,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 : "<NULL>"); - - 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, @@ -1554,18 +1463,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; @@ -1581,7 +1489,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; } @@ -1591,24 +1499,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) { @@ -1624,9 +1524,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. * @@ -1738,11 +1638,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; @@ -1757,7 +1655,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; @@ -1771,7 +1669,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); @@ -1781,13 +1679,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 */ @@ -1797,19 +1688,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. * @@ -1836,7 +1727,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; @@ -1892,20 +1783,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; @@ -1916,16 +1805,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 @@ -1944,24 +1831,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", @@ -1972,14 +1846,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; @@ -1990,14 +1862,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); @@ -2010,9 +1882,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 */ @@ -2022,20 +1891,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. * @@ -2045,7 +1914,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; @@ -2113,21 +1982,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; @@ -2162,18 +2029,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) { @@ -2187,7 +2055,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); @@ -2220,26 +2088,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; } @@ -3028,45 +2884,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 b99c35317..eb47ae1e0 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 60ae4a950..70fe337cd 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 5ce9ae023..b447a0634 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 81082c675..3cf801516 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -207,8 +207,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 298994a96..209bf5b01 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -990,17 +990,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 a385f2943..05bcdda07 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 7d00b94d0..dcb669079 100644 --- a/src/sbus/sssd_dbus.h +++ b/src/sbus/sssd_dbus.h @@ -24,9 +24,11 @@ struct sbus_connection; +struct sbus_request; + #include <dbus/dbus.h> -typedef int (*sbus_msg_handler_fn)(DBusMessage *, struct sbus_connection *); +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 d39f1c01f..5faf24949 100644 --- a/src/sbus/sssd_dbus_connection.c +++ b/src/sbus/sssd_dbus_connection.c @@ -416,7 +416,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) { @@ -436,10 +438,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); @@ -451,6 +454,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 */ @@ -459,11 +463,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 { @@ -473,21 +473,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; + } + } + + 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; } - else - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - return DBUS_HANDLER_RESULT_HANDLED; + return result; } /* Adds a new D-BUS path message handler to the connection @@ -786,4 +793,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 c62e0e3f6..eca5c8380 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 000000000..973089c4b --- /dev/null +++ b/src/sbus/sssd_dbus_request.c @@ -0,0 +1,112 @@ +/* + Authors: + Stef Walter <stefw@redhat.com> + + 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 <http://www.gnu.org/licenses/>. +*/ + +#include "util/util.h" +#include "sbus/sssd_dbus.h" + +#include <sys/time.h> +#include <dbus/dbus.h> + +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 7386756cd..146e18a85 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; |