diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2013-04-05 17:02:20 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-04-08 23:47:23 +0200 |
commit | a28391f68a09eaedbe1a515f513ca56bbb94d7a5 (patch) | |
tree | 7c64db5073623d05c8ebe9bbc2ba08a08439f406 /src/responder/pam/pamsrv_dp.c | |
parent | 827e8dbc3c792ed34b0608c3bd3a4d7b0eedf4f5 (diff) | |
download | sssd-a28391f68a09eaedbe1a515f513ca56bbb94d7a5.tar.gz sssd-a28391f68a09eaedbe1a515f513ca56bbb94d7a5.tar.bz2 sssd-a28391f68a09eaedbe1a515f513ca56bbb94d7a5.zip |
Allocate PAM DP request data on responder context
https://fedorahosted.org/sssd/ticket/1869
Currently the private data passed to the PAM request is a structure
allocated on the client context. But in the odd case where the back end
would be stopped or stuck until the idle timeout hits, the DP callback
would access data that were freed when the client timed out.
This patch introduces a new structure allocated on responder context,
whose only purpose is to live as long as the request is active.
Diffstat (limited to 'src/responder/pam/pamsrv_dp.c')
-rw-r--r-- | src/responder/pam/pamsrv_dp.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/src/responder/pam/pamsrv_dp.c b/src/responder/pam/pamsrv_dp.c index afaca593..46c54dad 100644 --- a/src/responder/pam/pamsrv_dp.c +++ b/src/responder/pam/pamsrv_dp.c @@ -37,13 +37,26 @@ static void pam_dp_process_reply(DBusPendingCall *pending, void *ptr) DBusMessage* msg; int ret; int type; - struct pam_auth_req *preq; + struct pam_auth_req *preq = NULL; + struct pam_auth_dp_req *pdp_req; - preq = talloc_get_type(ptr, struct pam_auth_req); + pdp_req = talloc_get_type(ptr, struct pam_auth_dp_req); + preq = pdp_req->preq; + talloc_free(pdp_req); dbus_error_init(&dbus_error); - msg = dbus_pending_call_steal_reply(pending); + + /* Check if the client still exists. If not, simply free all the resources + * and quit */ + if (preq == NULL) { + DEBUG(SSSDBG_MINOR_FAILURE, ("Client already disconnected\n")); + dbus_pending_call_unref(pending); + dbus_message_unref(msg); + return; + } + + /* Sanity-check of message validity */ if (msg == NULL) { DEBUG(0, ("Severe error. A reply callback was called but no reply was" "received and no timeout occurred\n")); @@ -51,7 +64,6 @@ static void pam_dp_process_reply(DBusPendingCall *pending, void *ptr) goto done; } - type = dbus_message_get_type(msg); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: @@ -79,6 +91,16 @@ done: preq->callback(preq); } +static int pdp_req_destructor(struct pam_auth_dp_req *pdp_req) +{ + if (pdp_req && pdp_req->preq) { + /* If there is still a client waiting, reset the + * spy */ + pdp_req->preq->dpreq_spy = NULL; + } + return 0; +} + int pam_dp_send_req(struct pam_auth_req *preq, int timeout) { struct pam_data *pd = preq->pd; @@ -86,6 +108,7 @@ int pam_dp_send_req(struct pam_auth_req *preq, int timeout) DBusMessage *msg; dbus_bool_t ret; int res; + struct pam_auth_dp_req *pdp_req; /* double check dp_ctx has actually been initialized. * in some pathological cases it may happen that nss starts up before @@ -118,9 +141,17 @@ int pam_dp_send_req(struct pam_auth_req *preq, int timeout) return EIO; } + pdp_req = talloc(preq->cctx->rctx, struct pam_auth_dp_req); + if (pdp_req == NULL) { + return ENOMEM; + } + pdp_req->preq = preq; + preq->dpreq_spy = pdp_req; + talloc_set_destructor(pdp_req, pdp_req_destructor); + res = sbus_conn_send(be_conn->conn, msg, timeout, pam_dp_process_reply, - preq, NULL); + pdp_req, NULL); dbus_message_unref(msg); return res; } |