summaryrefslogtreecommitdiffstats
path: root/server/nss
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 /server/nss
parentccd17380f5347d0c50fe5214de2e2cd077238f53 (diff)
downloadsssd-dd422e75a52d197d9084b6a4415b58553460ae41.tar.gz
sssd-dd422e75a52d197d9084b6a4415b58553460ae41.tar.xz
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!
Diffstat (limited to 'server/nss')
-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
5 files changed, 112 insertions, 28 deletions
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 <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 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) {