Blame SOURCES/Expand-use-of-global-static-mechs-to-conform-to-SPI.patch

651382
From 2ca80c193ffa13c89b9b63fb9cb690a9789d5842 Mon Sep 17 00:00:00 2001
651382
From: Simo Sorce <simo@redhat.com>
651382
Date: Thu, 27 Aug 2020 11:34:45 -0400
651382
Subject: [PATCH] Expand use of global static mechs to conform to SPI
651382
651382
GSSAPI requires some specific APIs to return "static" OIDs that the user
651382
does not have to free.  The krb5 mechglue in fact requires mechanisms to
651382
also honor this or the mech oid will be irretrievably leaked in some
651382
cases.
651382
651382
To accomodate this, expand use of global mechs structure we already
651382
allocate for the gss_inidicate_mechs case so we can return "static" OIDs
651382
from calls like ISC and ASC.
651382
651382
Signed-off-by: Simo Sorce <simo@redhat.com>
651382
[rharwood@redhat.com: commit message fixups]
651382
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
651382
(cherry picked from commit a3f13b30ef3c90ff7344c3913f6e26e55b82451f)
651382
(cherry picked from commit b7ccb627f4663ca949e3483486478add8f61cb27)
651382
---
651382
 src/client/gpm_accept_sec_context.c | 22 ++++++-------------
651382
 src/client/gpm_common.c             |  1 -
651382
 src/client/gpm_indicate_mechs.c     | 34 +++++++++++++++++++++++++++++
651382
 src/client/gpm_init_sec_context.c   | 19 +++++-----------
651382
 src/client/gssapi_gpm.h             |  3 +++
651382
 src/mechglue/gss_plugin.c           |  5 +++++
651382
 6 files changed, 55 insertions(+), 29 deletions(-)
651382
651382
diff --git a/src/client/gpm_accept_sec_context.c b/src/client/gpm_accept_sec_context.c
651382
index ef5e79c..ab20b03 100644
651382
--- a/src/client/gpm_accept_sec_context.c
651382
+++ b/src/client/gpm_accept_sec_context.c
651382
@@ -21,7 +21,6 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status,
651382
     gssx_res_accept_sec_context *res = &ures.accept_sec_context;
651382
     gssx_ctx *ctx = NULL;
651382
     gssx_name *name = NULL;
651382
-    gss_OID_desc *mech = NULL;
651382
     gss_buffer_t outbuf = NULL;
651382
     uint32_t ret_maj;
651382
     int ret;
651382
@@ -70,15 +69,6 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status,
651382
         goto done;
651382
     }
651382
 
651382
-    if (mech_type) {
651382
-        if (res->status.mech.octet_string_len) {
651382
-            ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech);
651382
-            if (ret) {
651382
-                goto done;
651382
-            }
651382
-        }
651382
-    }
651382
-
651382
     ctx = res->context_handle;
651382
     /* we are stealing the delegated creds on success, so we do not want
651382
      * it to be freed by xdr_free */
651382
@@ -101,8 +91,14 @@ OM_uint32 gpm_accept_sec_context(OM_uint32 *minor_status,
651382
     }
651382
 
651382
     if (mech_type) {
651382
-        *mech_type = mech;
651382
+        gss_OID_desc mech;
651382
+        gp_conv_gssx_to_oid(&res->status.mech, &mech);
651382
+        ret = gpm_mech_to_static(&mech, mech_type);
651382
+        if (ret) {
651382
+            goto done;
651382
+        }
651382
     }
651382
+
651382
     if (src_name) {
651382
         *src_name = name;
651382
     }
651382
@@ -145,10 +141,6 @@ done:
651382
             xdr_free((xdrproc_t)xdr_gssx_name, (char *)name);
651382
             free(name);
651382
         }
651382
-        if (mech) {
651382
-            free(mech->elements);
651382
-            free(mech);
651382
-        }
651382
         if (outbuf) {
651382
             free(outbuf->value);
651382
             free(outbuf);
651382
diff --git a/src/client/gpm_common.c b/src/client/gpm_common.c
651382
index d932ba2..02325c4 100644
651382
--- a/src/client/gpm_common.c
651382
+++ b/src/client/gpm_common.c
651382
@@ -795,4 +795,3 @@ void gpm_free_xdrs(int proc, union gp_rpc_arg *arg, union gp_rpc_res *res)
651382
     xdr_free(gpm_xdr_set[proc].arg_fn, (char *)arg);
651382
     xdr_free(gpm_xdr_set[proc].res_fn, (char *)res);
651382
 }
651382
-
651382
diff --git a/src/client/gpm_indicate_mechs.c b/src/client/gpm_indicate_mechs.c
651382
index b019a96..86c7de3 100644
651382
--- a/src/client/gpm_indicate_mechs.c
651382
+++ b/src/client/gpm_indicate_mechs.c
651382
@@ -300,6 +300,40 @@ static int gpmint_init_global_mechs(void)
651382
     return 0;
651382
 }
651382
 
651382
+/* GSSAPI requires some APIs to return "static" mechs that callers do not need
651382
+ * to free. So match a radom mech and return from our global "static" array */
651382
+int gpm_mech_to_static(gss_OID mech_type, gss_OID *mech_static)
651382
+{
651382
+    int ret;
651382
+
651382
+    ret = gpmint_init_global_mechs();
651382
+    if (ret) {
651382
+        return ret;
651382
+    }
651382
+
651382
+    *mech_static = GSS_C_NO_OID;
651382
+    for (size_t i = 0; i < global_mechs.mech_set->count; i++) {
651382
+        if (gpm_equal_oids(&global_mechs.mech_set->elements[i], mech_type)) {
651382
+            *mech_static = &global_mechs.mech_set->elements[i];
651382
+            return 0;
651382
+        }
651382
+    }
651382
+    /* TODO: potentially in future add the mech to the list if missing */
651382
+    return ENOENT;
651382
+}
651382
+
651382
+bool gpm_mech_is_static(gss_OID mech_type)
651382
+{
651382
+    if (global_mechs.mech_set) {
651382
+        for (size_t i = 0; i < global_mechs.mech_set->count; i++) {
651382
+            if (&global_mechs.mech_set->elements[i] == mech_type) {
651382
+                return true;
651382
+            }
651382
+        }
651382
+    }
651382
+    return false;
651382
+}
651382
+
651382
 OM_uint32 gpm_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set)
651382
 {
651382
     uint32_t ret_min;
651382
diff --git a/src/client/gpm_init_sec_context.c b/src/client/gpm_init_sec_context.c
651382
index bea2010..b84ff94 100644
651382
--- a/src/client/gpm_init_sec_context.c
651382
+++ b/src/client/gpm_init_sec_context.c
651382
@@ -43,7 +43,6 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
651382
     gssx_arg_init_sec_context *arg = &uarg.init_sec_context;
651382
     gssx_res_init_sec_context *res = &ures.init_sec_context;
651382
     gssx_ctx *ctx = NULL;
651382
-    gss_OID_desc *mech = NULL;
651382
     gss_buffer_t outbuf = NULL;
651382
     uint32_t ret_maj = GSS_S_COMPLETE;
651382
     uint32_t ret_min = 0;
651382
@@ -100,11 +99,12 @@ OM_uint32 gpm_init_sec_context(OM_uint32 *minor_status,
651382
 
651382
     /* return values */
651382
     if (actual_mech_type) {
651382
-        if (res->status.mech.octet_string_len) {
651382
-            ret = gp_conv_gssx_to_oid_alloc(&res->status.mech, &mech);
651382
-            if (ret) {
651382
-                goto done;
651382
-            }
651382
+        gss_OID_desc mech;
651382
+        gp_conv_gssx_to_oid(&res->status.mech, &mech);
651382
+        ret = gpm_mech_to_static(&mech, actual_mech_type);
651382
+        if (ret) {
651382
+            gpm_save_internal_status(ret, gp_strerror(ret));
651382
+            goto done;
651382
         }
651382
     }
651382
 
651382
@@ -151,9 +151,6 @@ done:
651382
     gpm_free_xdrs(GSSX_INIT_SEC_CONTEXT, &uarg, &ures);
651382
 
651382
     if (ret_maj == GSS_S_COMPLETE || ret_maj == GSS_S_CONTINUE_NEEDED) {
651382
-        if (actual_mech_type) {
651382
-            *actual_mech_type = mech;
651382
-        }
651382
         if (outbuf) {
651382
             *output_token = *outbuf;
651382
             free(outbuf);
651382
@@ -170,10 +167,6 @@ done:
651382
             free(ctx);
651382
             ctx = NULL;
651382
         }
651382
-        if (mech) {
651382
-            free(mech->elements);
651382
-            free(mech);
651382
-        }
651382
         if (outbuf) {
651382
             free(outbuf->value);
651382
             free(outbuf);
651382
diff --git a/src/client/gssapi_gpm.h b/src/client/gssapi_gpm.h
651382
index 61124e0..b7ba04b 100644
651382
--- a/src/client/gssapi_gpm.h
651382
+++ b/src/client/gssapi_gpm.h
651382
@@ -27,6 +27,9 @@ void gpm_display_status_init_once(void);
651382
 void gpm_save_status(gssx_status *status);
651382
 void gpm_save_internal_status(uint32_t err, char *err_str);
651382
 
651382
+int gpm_mech_to_static(gss_OID mech_type, gss_OID *mech_static);
651382
+bool gpm_mech_is_static(gss_OID mech_type);
651382
+
651382
 OM_uint32 gpm_display_status(OM_uint32 *minor_status,
651382
                              OM_uint32 status_value,
651382
                              int status_type,
651382
diff --git a/src/mechglue/gss_plugin.c b/src/mechglue/gss_plugin.c
651382
index 8b799cf..bf70d87 100644
651382
--- a/src/mechglue/gss_plugin.c
651382
+++ b/src/mechglue/gss_plugin.c
651382
@@ -377,6 +377,11 @@ OM_uint32 gssi_internal_release_oid(OM_uint32 *minor_status, gss_OID *oid)
651382
         item = gpp_next_special_oids(item);
651382
     }
651382
 
651382
+    if (gpm_mech_is_static(*oid)) {
651382
+        *oid = GSS_C_NO_OID;
651382
+        return GSS_S_COMPLETE;
651382
+    }
651382
+
651382
     /* none matched, it's not ours */
651382
     return GSS_S_CONTINUE_NEEDED;
651382
 }