summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2009-01-09 08:42:28 -0500
committerSimo Sorce <idra@samba.org>2009-01-09 08:42:28 -0500
commitdd422e75a52d197d9084b6a4415b58553460ae41 (patch)
tree3567618ceb6b80e20d1bc6b94b5115f8163dd614
parentccd17380f5347d0c50fe5214de2e2cd077238f53 (diff)
downloadsssd-dd422e75a52d197d9084b6a4415b58553460ae41.tar.gz
sssd-dd422e75a52d197d9084b6a4415b58553460ae41.tar.bz2
sssd-dd422e75a52d197d9084b6a4415b58553460ae41.zip
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!
-rw-r--r--server/monitor.c2
-rw-r--r--server/nss/nsssrv.c14
-rw-r--r--server/nss/nsssrv.h12
-rw-r--r--server/nss/nsssrv_cmd.c20
-rw-r--r--server/nss/nsssrv_dp.c92
-rw-r--r--server/nss/nsssrv_packet.c2
-rw-r--r--server/providers/data_provider.c30
-rw-r--r--server/sbus/sssd_dbus_connection.c8
8 files changed, 138 insertions, 42 deletions
diff --git a/server/monitor.c b/server/monitor.c
index 5a79c75c..bddc0d48 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 bb5443f4..5fc707f8 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 00508a8e..51b0f535 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 6838466e..828bdb78 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 f865e62b..a0f31d57 100644
--- a/server/nss/nsssrv_dp.c
+++ b/server/nss/nsssrv_dp.c
@@ -19,16 +19,71 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <sys/time.h>
#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 13e27f41..bdf453f6 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 7d282e05..ee449a52 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 33f751bd..81d8aee1 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);