>From 235fb0023e550f50ca047f3992b271bb2040abe3 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Sun, 12 Jan 2014 15:30:56 -0500
Subject: [PATCH] Make name conversion more robust to failure

NTLMSSP does not have export_name functions yet, this was causing
gss_export_composite_name() to fail with a GSS_S_UNAVAILABLE error.

This should be ignored, however it wasn't and on top of that the output
structure was initialized but held pointers to memory freed at exit (due to the
error).

Make the function not failed if a mechanism do not have composite export
function, but if it does make sure the output is not littered with invalid
pointers.

Signed-off-by: Simo Sorce <simo@redhat.com>
---
 proxy/src/gp_conv.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/proxy/src/gp_conv.c b/proxy/src/gp_conv.c
index 0b177eebe90eefc4bf8241f39e910618a6b73d1f..998f3be621f748cb303d236bb0473e3e8c3d4a62 100644
--- a/proxy/src/gp_conv.c
+++ b/proxy/src/gp_conv.c
@@ -335,7 +335,7 @@ done:
     return ret;
 }
 
-uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
+uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *_out)
 {
     uint32_t ret_maj;
     uint32_t ret_min;
@@ -343,6 +343,7 @@ uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
     gss_OID name_type;
     gss_buffer_desc exported_name = GSS_C_EMPTY_BUFFER;
     gss_buffer_desc exported_composite_name = GSS_C_EMPTY_BUFFER;
+    gssx_name out = { 0 };
     int ret;
 
     ret_maj = gss_display_name(&ret_min, in, &name_buffer, &name_type);
@@ -350,13 +351,13 @@ uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
         goto done;
     }
 
-    ret = gp_conv_buffer_to_gssx(&name_buffer, &out->display_name);
+    ret = gp_conv_buffer_to_gssx(&name_buffer, &out.display_name);
     if (ret) {
         ret_maj = GSS_S_FAILURE;
         ret_min = ret;
         goto done;
     }
-    ret = gp_conv_oid_to_gssx(name_type, &out->name_type);
+    ret = gp_conv_oid_to_gssx(name_type, &out.name_type);
     if (ret) {
         ret_maj = GSS_S_FAILURE;
         ret_min = ret;
@@ -365,7 +366,7 @@ uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
 
     ret_maj = gss_export_name(&ret_min, in, &exported_name);
     if (ret_maj == 0) {
-        ret = gp_conv_buffer_to_gssx(&exported_name, &out->exported_name);
+        ret = gp_conv_buffer_to_gssx(&exported_name, &out.exported_name);
         if (ret) {
             ret_maj = GSS_S_FAILURE;
             ret_min = ret;
@@ -382,7 +383,7 @@ uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
 
     ret_maj = gss_export_name_composite(&ret_min, in, &exported_composite_name);
     if (ret_maj == 0) {
-        ret = gp_conv_buffer_to_gssx(&exported_composite_name, &out->exported_composite_name);
+        ret = gp_conv_buffer_to_gssx(&exported_composite_name, &out.exported_composite_name);
         if (ret) {
             ret_maj = GSS_S_FAILURE;
             ret_min = ret;
@@ -392,7 +393,8 @@ uint32_t gp_conv_name_to_gssx(uint32_t *min, gss_name_t in, gssx_name *out)
         /* In case the error is GSS_S_NAME_NOT_MN the name was not
          * canonicalized but that is ok we simply do not export the name
          * in this case */
-        if (ret_maj != GSS_S_NAME_NOT_MN) {
+        if (ret_maj != GSS_S_NAME_NOT_MN &&
+            ret_maj != GSS_S_UNAVAILABLE) {
             goto done;
         }
     }
@@ -407,10 +409,12 @@ done:
     gss_release_buffer(&ret_min, &exported_name);
     gss_release_buffer(&ret_min, &exported_composite_name);
     if (ret_maj) {
-        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->display_name);
-        xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&out->name_type);
-        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->exported_name);
-        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out->exported_composite_name);
+        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.display_name);
+        xdr_free((xdrproc_t)xdr_gssx_OID, (char *)&out.name_type);
+        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.exported_name);
+        xdr_free((xdrproc_t)xdr_gssx_buffer, (char *)&out.exported_composite_name);
+    } else {
+        *_out = out;
     }
     return ret_maj;
 }
-- 
1.8.4.2

