From dd422e75a52d197d9084b6a4415b58553460ae41 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 9 Jan 2009 08:42:28 -0500 Subject: Lots of little nasty bugs fixed. I was finally able to get a getpwnam() request go through sssd, hit the remote ldap server and get the answer back with 'getent passwd foo' Yupiee! --- server/monitor.c | 2 +- server/nss/nsssrv.c | 14 +++++- server/nss/nsssrv.h | 12 +++-- server/nss/nsssrv_cmd.c | 20 ++++----- server/nss/nsssrv_dp.c | 92 ++++++++++++++++++++++++++++++++++---- server/nss/nsssrv_packet.c | 2 +- server/providers/data_provider.c | 30 +++++++++---- server/sbus/sssd_dbus_connection.c | 8 ++-- 8 files changed, 138 insertions(+), 42 deletions(-) (limited to 'server') diff --git a/server/monitor.c b/server/monitor.c index 5a79c75cb..bddc0d488 100644 --- a/server/monitor.c +++ b/server/monitor.c @@ -39,7 +39,7 @@ static int start_service(const char *name, const char *command, pid_t *retpid); /* ping time cannot be less then once every few seconds or the * monitor will get crazy hammering children with messages */ -#define MONITOR_MIN_PING_TIME 15 +#define MONITOR_MIN_PING_TIME 10 struct mt_conn { struct sbus_conn_ctx *conn_ctx; diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c index bb5443f4f..5fc707f85 100644 --- a/server/nss/nsssrv.c +++ b/server/nss/nsssrv.c @@ -140,8 +140,18 @@ static void client_recv(struct event_context *ev, struct cli_ctx *cctx) /* need to read still some data, loop again */ break; + case EINVAL: + DEBUG(6, ("Invalid data from client, closing connection!\n")); + talloc_free(cctx); + break; + + case ENODATA: + DEBUG(5, ("Client disconnected!\n")); + talloc_free(cctx); + break; + default: - DEBUG(0, ("Failed to read request, aborting client!\n")); + DEBUG(6, ("Failed to read request, aborting client!\n")); talloc_free(cctx); } @@ -210,7 +220,7 @@ static void accept_fd_handler(struct event_context *ev, talloc_set_destructor(cctx, client_destructor); - DEBUG(2, ("Client connected!\n")); + DEBUG(4, ("Client connected!\n")); return; } diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h index 00508a8ed..51b0f535c 100644 --- a/server/nss/nsssrv.h +++ b/server/nss/nsssrv.h @@ -89,15 +89,13 @@ int nss_cmd_execute(struct cli_ctx *cctx); #define NSS_DP_USER 1 #define NSS_DP_GROUP 2 +typedef void (*nss_dp_callback_t)(uint16_t err_maj, uint32_t err_min, + const char *err_msg, void *ptr); + int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx, - DBusPendingCallNotifyFunction callback, - void *callback_ctx, - const char *domain, int type, + nss_dp_callback_t callback, void *callback_ctx, + int timeout, const char *domain, int type, const char *opt_name, uint32_t opt_id); -int nss_dp_get_reply(DBusPendingCall *pending, - dbus_uint16_t *err_maj, - dbus_uint32_t *err_min, - char **err_msg); int nss_dp_init(struct nss_ctx *nctx); #endif /* __NSSSRV_H__ */ diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c index 6838466e2..828bdb78c 100644 --- a/server/nss/nsssrv_cmd.c +++ b/server/nss/nsssrv_cmd.c @@ -212,7 +212,7 @@ static void nss_cmd_getpw_callback(void *ptr, int status, DEBUG(1, ("getpwnam call returned more than one result !?!\n")); } if (res->count == 0) { - DEBUG(2, ("No results for getpwnam call")); + DEBUG(2, ("No results for getpwnam call\n")); } ret = nss_packet_new(cctx->creq, 2*sizeof(uint32_t), nss_packet_get_cmd(cctx->creq->in), @@ -233,25 +233,24 @@ done: nss_cmd_done(nctx); } -static void nss_cmd_getpwnam_callback(DBusPendingCall *pending, void *ptr) +static void nss_cmd_getpwnam_callback(uint16_t err_maj, uint32_t err_min, + const char *err_msg, void *ptr) { struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx); struct cli_ctx *cctx = nctx->cctx; - dbus_uint16_t cli_err_maj; - dbus_uint32_t cli_err_min; - char *cli_err_msg; int ret; - ret = nss_dp_get_reply(pending, &cli_err_maj, &cli_err_min, &cli_err_msg); - if (ret != EOK) { + if (err_maj) { DEBUG(2, ("Unable to get information from Data Provider\n" - "Will try to return what we have in cache\n")); + "Error: %u, %u, %s\n" + "Will try to return what we have in cache\n", + (unsigned int)err_maj, (unsigned int)err_min, err_msg)); } ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->nctx->lctx, nctx->name, nss_cmd_getpw_callback, nctx); if (ret != EOK) { - DEBUG(1, ("Failed to make request to our cache!")); + DEBUG(1, ("Failed to make request to our cache!\n")); ret = nss_cmd_send_error(nctx, ret); if (ret != EOK) { @@ -289,7 +288,8 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx) ret = nss_dp_send_acct_req(cctx->nctx, nctx, nss_cmd_getpwnam_callback, nctx, - "*", NSS_DP_USER, nctx->name, 0); + SSS_NSS_SOCKET_TIMEOUT/2, "*", + NSS_DP_USER, nctx->name, 0); if (ret != EOK) { talloc_free(nctx); return ret; diff --git a/server/nss/nsssrv_dp.c b/server/nss/nsssrv_dp.c index f865e62b0..a0f31d573 100644 --- a/server/nss/nsssrv_dp.c +++ b/server/nss/nsssrv_dp.c @@ -19,16 +19,71 @@ along with this program. If not, see . */ +#include #include "util/util.h" #include "nss/nsssrv.h" #include "providers/data_provider.h" +struct nss_dp_req { + nss_dp_callback_t callback; + void *callback_ctx; + bool replied; + struct timed_event *te; +}; + +static void nss_dp_send_acct_timeout(struct event_context *ev, + struct timed_event *te, + struct timeval t, void *data) +{ + struct nss_dp_req *ndp_req; + dbus_uint16_t err_maj = DP_ERR_TIMEOUT; + dbus_uint32_t err_min = EIO; + const char *err_msg = "Request timed out"; + + ndp_req = talloc_get_type(data, struct nss_dp_req); + ndp_req->replied = true; + + ndp_req->callback(err_maj, err_min, err_msg, ndp_req->callback_ctx); +} + +static int nss_dp_get_reply(DBusPendingCall *pending, + dbus_uint16_t *err_maj, + dbus_uint32_t *err_min, + const char **err_msg); + +static void nss_dp_send_acct_callback(DBusPendingCall *pending, void *ptr) +{ + struct nss_dp_req *ndp_req; + dbus_uint16_t err_maj; + dbus_uint32_t err_min; + const char *err_msg; + int ret; + + ndp_req = talloc_get_type(ptr, struct nss_dp_req); + if (ndp_req->replied) { + DEBUG(5, ("Callback called, but the request was already timed out!\n")); + talloc_free(ndp_req); + return; + } + + ret = nss_dp_get_reply(pending, &err_maj, &err_min, &err_msg); + if (ret != EOK) { + err_maj = DP_ERR_FATAL; + err_min = ret; + err_msg = "Failed to get reply from Data Provider"; + } + + talloc_free(ndp_req->te); + + ndp_req->callback(err_maj, err_min, err_msg, ndp_req->callback_ctx); +} + int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx, - DBusPendingCallNotifyFunction callback, - void *callback_ctx, - const char *domain, int type, + nss_dp_callback_t callback, void *callback_ctx, + int timeout, const char *domain, int type, const char *opt_name, uint32_t opt_id) { + struct nss_dp_req *ndp_req; DBusMessage *msg; DBusPendingCall *pending_reply; DBusConnection *conn; @@ -37,6 +92,7 @@ int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx, uint32_t be_type; const char *attrs = "core"; char *filter; + struct timeval tv; /* either, or, not both */ if (opt_name && opt_id) { @@ -106,17 +162,34 @@ int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx, return EIO; } + /* setup the timeout handler */ + ndp_req = talloc(memctx, struct nss_dp_req); + if (!ndp_req) { + dbus_message_unref(msg); + return ENOMEM; + } + ndp_req->callback = callback; + ndp_req->callback_ctx = callback_ctx; + ndp_req->replied = false; + gettimeofday(&tv, NULL); + tv.tv_sec += timeout/1000; + tv.tv_usec += (timeout%1000) * 1000; + ndp_req->te = event_add_timed(nctx->ev, memctx, tv, + nss_dp_send_acct_timeout, ndp_req); + /* Set up the reply handler */ - dbus_pending_call_set_notify(pending_reply, callback, callback_ctx, NULL); + dbus_pending_call_set_notify(pending_reply, + nss_dp_send_acct_callback, + ndp_req, NULL); dbus_message_unref(msg); return EOK; } -int nss_dp_get_reply(DBusPendingCall *pending, - dbus_uint16_t *err_maj, - dbus_uint32_t *err_min, - char **err_msg) +static int nss_dp_get_reply(DBusPendingCall *pending, + dbus_uint16_t *err_maj, + dbus_uint32_t *err_min, + const char **err_msg) { DBusMessage *reply; DBusError dbus_error; @@ -154,6 +227,9 @@ int nss_dp_get_reply(DBusPendingCall *pending, goto done; } + DEBUG(4, ("Got reply (%u, %u, %s) from Data Provider\n", + (unsigned int)*err_maj, (unsigned int)*err_min, *err_msg)); + break; case DBUS_MESSAGE_TYPE_ERROR: diff --git a/server/nss/nsssrv_packet.c b/server/nss/nsssrv_packet.c index 13e27f41f..bdf453f6b 100644 --- a/server/nss/nsssrv_packet.c +++ b/server/nss/nsssrv_packet.c @@ -155,7 +155,7 @@ int nss_packet_recv(struct nss_packet *packet, int fd) } if (rb == 0) { - return EIO; + return ENODATA; } if (*packet->len > packet->memsize) { diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c index 7d282e05a..ee449a525 100644 --- a/server/providers/data_provider.c +++ b/server/providers/data_provider.c @@ -105,7 +105,7 @@ struct dp_request { struct dp_be_request { struct dp_request *req; - struct dp_client *be_cli; + struct dp_backend *be; }; static int service_identity(DBusMessage *message, void *data, DBusMessage **r) @@ -321,7 +321,7 @@ static void be_identity_check(DBusPendingCall *pending, void *data) goto done; } - switch (cli_type && DP_CLI_TYPE_MASK) { + switch (cli_type & DP_CLI_TYPE_MASK) { case DP_CLI_BACKEND: dpbe = talloc_zero(dpcli->dpctx, struct dp_backend); if (!dpbe) { @@ -342,6 +342,9 @@ static void be_identity_check(DBusPendingCall *pending, void *data) DLIST_ADD(dpcli->dpctx->be_list, dpbe); + DEBUG(4, ("Added Backend client [%s], for domain [%s]\n", + dpbe->name, dpbe->domain)); + talloc_set_destructor((TALLOC_CTX *)dpbe, dp_backend_destructor); break; @@ -364,6 +367,8 @@ static void be_identity_check(DBusPendingCall *pending, void *data) DLIST_ADD(dpcli->dpctx->fe_list, dpfe); + DEBUG(4, ("Added Frontend client [%s]\n", dpfe->name)); + talloc_set_destructor((TALLOC_CTX *)dpfe, dp_frontend_destructor); break; @@ -425,7 +430,7 @@ static void be_got_account_info(DBusPendingCall *pending, void *data) DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n")); /* Destroy this connection */ - sbus_disconnect(bereq->be_cli->conn_ctx); + sbus_disconnect(bereq->be->dpcli->conn_ctx); goto done; } @@ -439,10 +444,14 @@ static void be_got_account_info(DBusPendingCall *pending, void *data) DBUS_TYPE_INVALID); if (!ret) { DEBUG(1,("Failed to parse message, killing connection\n")); - sbus_disconnect(bereq->be_cli->conn_ctx); + sbus_disconnect(bereq->be->dpcli->conn_ctx); goto done; } + DEBUG(4, ("Got reply (%u, %u, %s) from %s(%s)\n", + (unsigned int)err_maj, (unsigned int)err_min, err_msg, + bereq->be->name, bereq->be->domain)); + break; case DBUS_MESSAGE_TYPE_ERROR: @@ -457,7 +466,7 @@ static void be_got_account_info(DBusPendingCall *pending, void *data) * know that this connection isn't trustworthy. * We'll destroy it now. */ - sbus_disconnect(bereq->be_cli->conn_ctx); + sbus_disconnect(bereq->be->dpcli->conn_ctx); } if (err_maj) { @@ -470,7 +479,7 @@ static void be_got_account_info(DBusPendingCall *pending, void *data) bereq->req->pending_replies--; talloc_free(bereq); } else { - conn = sbus_get_connection(bereq->be_cli->conn_ctx); + conn = sbus_get_connection(bereq->req->src_cli->conn_ctx); err_maj = 0; err_min = 0; err_msg = "Success"; @@ -505,7 +514,7 @@ static int dp_send_acct_req(struct dp_be_request *bereq, DBusError dbus_error; dbus_bool_t ret; - conn = sbus_get_connection(bereq->be_cli->conn_ctx); + conn = sbus_get_connection(bereq->be->dpcli->conn_ctx); dbus_error_init(&dbus_error); /* create the message */ @@ -633,7 +642,7 @@ static int dp_get_account_info(DBusMessage *message, void *data, DBusMessage **r continue; } bereq->req = dpreq; - bereq->be_cli = dpbe->dpcli; + bereq->be = dpbe; DEBUG(4, ("Sending wildcard request to [%s]\n", dpbe->domain)); ret = dp_send_acct_req(bereq, type, attrs, filter); if (ret != EOK) { @@ -689,7 +698,7 @@ static int dp_get_account_info(DBusMessage *message, void *data, DBusMessage **r goto respond; } bereq->req = dpreq; - bereq->be_cli = dpbe->dpcli; + bereq->be = dpbe; ret = dp_send_acct_req(bereq, type, attrs, filter); if (ret != EOK) { @@ -727,6 +736,8 @@ static int dp_backend_destructor(void *ctx) struct dp_backend *dpbe = talloc_get_type(ctx, struct dp_backend); if (dpbe->dpcli && dpbe->dpcli->dpctx && dpbe->dpcli->dpctx->be_list) { DLIST_REMOVE(dpbe->dpcli->dpctx->be_list, dpbe); + DEBUG(4, ("Removed Backend client [%s], for domain [%s]\n", + dpbe->name, dpbe->domain)); } return 0; } @@ -736,6 +747,7 @@ static int dp_frontend_destructor(void *ctx) struct dp_frontend *dpfe = talloc_get_type(ctx, struct dp_frontend); if (dpfe->dpcli && dpfe->dpcli->dpctx && dpfe->dpcli->dpctx->fe_list) { DLIST_REMOVE(dpfe->dpcli->dpctx->fe_list, dpfe); + DEBUG(4, ("Removed Frontend client [%s]\n", dpfe->name)); } return 0; } diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c index 33f751bd0..81d8aee1b 100644 --- a/server/sbus/sssd_dbus_connection.c +++ b/server/sbus/sssd_dbus_connection.c @@ -49,10 +49,10 @@ static void sbus_dispatch(struct event_context *ev, dct_ctx = talloc_get_type(data, struct sbus_conn_ctx); conn = dct_ctx->conn; - DEBUG(4, ("conn: %lX\n", conn)); + DEBUG(6, ("conn: %lX\n", conn)); if((dct_ctx->disconnect) || (!dbus_connection_get_is_connected(conn))) { - DEBUG(4,("Connection is not open for dispatching.\n")); + DEBUG(3,("Connection is not open for dispatching.\n")); /* * Free the connection object. * This will invoke the destructor for the connection @@ -67,7 +67,7 @@ static void sbus_dispatch(struct event_context *ev, */ ret = dbus_connection_get_dispatch_status(conn); if (ret != DBUS_DISPATCH_COMPLETE) { - DEBUG(4,("Dispatching.\n")); + DEBUG(6,("Dispatching.\n")); dbus_connection_dispatch(conn); } @@ -97,7 +97,7 @@ static void sbus_conn_read_write_handler(struct event_context *ev, struct sbus_conn_watch_ctx *conn_w_ctx; conn_w_ctx = talloc_get_type(data, struct sbus_conn_watch_ctx); - DEBUG(4,("Connection is open for read/write.\n")); + DEBUG(6,("Connection is open for read/write.\n")); dbus_connection_ref(conn_w_ctx->top->conn); if (flags & EVENT_FD_READ) { dbus_watch_handle(conn_w_ctx->watch, DBUS_WATCH_READABLE); -- cgit