[SSSD] [PATCH] Allocate PAM DP request data on responder context (1.5 backport)

Jakub Hrozek jhrozek at redhat.com
Wed Apr 24 20:33:54 UTC 2013


We backported the patch to RHEL5, so we should play nice and push it to
the upstream sssd-1-5 branch, too.
-------------- next part --------------
>From a4a38d191d95c38f7d1a81cf4740b0c4c9329301 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 8 Apr 2013 23:59:12 +0200
Subject: [PATCH] Allocate PAM DP request data on responder context

---
 src/responder/pam/pamsrv.h     |  6 ++++++
 src/responder/pam/pamsrv_cmd.c | 12 ++++++++++++
 src/responder/pam/pamsrv_dp.c  | 41 ++++++++++++++++++++++++++++++++++++-----
 3 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 3ffc17087445a5314d5a85f471bb557fdbc94e7b..c47d4bb166d4c3193018747c35c86c243dfc7059 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -38,6 +38,10 @@ struct pam_ctx {
     time_t id_timeout;
 };
 
+struct pam_auth_dp_req {
+    struct pam_auth_req *preq;
+};
+
 struct pam_auth_req {
     struct cli_ctx *cctx;
     struct sss_domain_info *domain;
@@ -49,6 +53,8 @@ struct pam_auth_req {
     struct ldb_result *res;
     bool check_provider;
     void *data;
+
+    struct pam_auth_dp_req *dpreq_spy;
 };
 
 struct sss_cmd_table *get_pam_cmds(void);
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index b7c6fe2c2b202f08016c189cb793ea62e6495556..5c614e33293e4559aafd785359bf955a519ea4cd 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -697,6 +697,17 @@ static int pam_check_user_search(struct pam_auth_req *preq);
 static int pam_check_user_done(struct pam_auth_req *preq, int ret);
 static void pam_dom_forwarder(struct pam_auth_req *preq);
 
+static int pam_auth_req_destructor(struct pam_auth_req *preq)
+{
+    if (preq && preq->dpreq_spy) {
+        /* If there is still a request pending, tell the spy
+         * the client is going away
+         */
+        preq->dpreq_spy->preq = NULL;
+    }
+    return 0;
+}
+
 /* TODO: we should probably return some sort of cookie that is set in the
  * PAM_ENVIRONMENT, so that we can save performing some calls and cache
  * data. */
@@ -717,6 +728,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
     if (!preq) {
         return ENOMEM;
     }
+    talloc_set_destructor(preq, pam_auth_req_destructor);
     preq->cctx = cctx;
 
     preq->pd = talloc_zero(preq, struct pam_data);
diff --git a/src/responder/pam/pamsrv_dp.c b/src/responder/pam/pamsrv_dp.c
index 40d4f3031381672130a49406e08de74fdffdfaf0..fc6c1600875533008bdb73f42f2f55109216a1fe 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(4, ("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;
 }
-- 
1.8.1.4



More information about the sssd-devel mailing list