>From 21d9ffb58d21c34e3e0f4d24fb86ef0b30ffccd1 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 a9f9669b288c99df43c742df9553d25a068e1897..f05559f769d9481ec49aa2b7696dd1be348d3455 100644
--- a/proxy/src/gp_conv.c
+++ b/proxy/src/gp_conv.c
@@ -356,7 +356,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;
@@ -364,6 +364,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 = { .display_name.octet_string_len = 0 };
     int ret;
 
     ret_maj = gss_display_name(&ret_min, in, &name_buffer, &name_type);
@@ -371,13 +372,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;
@@ -386,7 +387,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;
@@ -403,7 +404,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;
@@ -413,7 +414,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;
         }
     }
@@ -428,10 +430,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

