[PATCH 1/3] adsldp: Map 1.2.840.113556.1.4.903 to ADSTYPE_DN_WITH_BINARY.

Dmitry Timoshkov dmitry at baikal.ru
Wed Apr 8 04:41:39 CDT 2020


Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
 dlls/adsldp/adsldp.c | 74 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/adsldp/schema.c |  2 ++
 2 files changed, 76 insertions(+)

diff --git a/dlls/adsldp/adsldp.c b/dlls/adsldp/adsldp.c
index 5504a376ba..e5310a9f4b 100644
--- a/dlls/adsldp/adsldp.c
+++ b/dlls/adsldp/adsldp.c
@@ -1583,6 +1583,78 @@ static HRESULT add_column_values(LDAP_namespace *ldap, struct ldap_search_contex
         break;
     }
 
+    case ADSTYPE_DN_WITH_BINARY:
+    {
+        static const BYTE hex2bin[] =
+        {
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x00 */
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x10 */
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x20 */
+            0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,        /* 0x30 */
+            0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,  /* 0x40 */
+            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x50 */
+            0,10,11,12,13,14,15                     /* 0x60 */
+        };
+        ADS_DN_WITH_BINARY *dnb;
+        WCHAR **values = ldap_get_valuesW(ldap->ld, ldap_ctx->entry, name);
+        if (!values)
+            return E_ADS_COLUMN_NOT_SET;
+        count = ldap_count_valuesW(values);
+
+        col->pADsValues = heap_alloc_zero(count * (sizeof(col->pADsValues[0]) + sizeof(col->pADsValues[0].u.pDNWithBinary[0])));
+        if (!col->pADsValues)
+        {
+            ldap_value_freeW(values);
+            return E_OUTOFMEMORY;
+        }
+
+        dnb = (ADS_DN_WITH_BINARY *)(col->pADsValues + count);
+
+        for (i = 0; i < count; i++)
+        {
+            WCHAR *p = values[i];
+            DWORD n;
+
+            col->pADsValues[i].dwType = type;
+            col->pADsValues[i].u.pDNWithBinary = dnb++;
+
+            if ((p[0] != 'b' && p[0] != 'B') || p[1] != ':')
+                FIXME("wrong DN with binary tag '%c%c'\n", p[0], p[1]);
+            p += 2;
+
+            col->pADsValues[i].u.pDNWithBinary->dwLength = wcstol(p, &p, 10) / 2;
+            if (*p != ':')
+                FIXME("wrong DN with binary separator '%c'\n", *p);
+            p++;
+            col->pADsValues[i].u.pDNWithBinary->lpBinaryValue = (BYTE *)p;
+            /* decode values in-place */
+            for (n = 0; n < col->pADsValues[i].u.pDNWithBinary->dwLength; n++, p += 2)
+            {
+                BYTE b;
+
+                if (p[0] > 'f' || (p[0] != '0' && !hex2bin[p[0]]) ||
+                    p[1] > 'f' || (p[1] != '0' && !hex2bin[p[1]]))
+                {
+                    FIXME("bad hex encoding at %s\n", debugstr_w(p));
+                    continue;
+                }
+
+                b = (hex2bin[p[0]] << 4) | hex2bin[p[1]];
+                col->pADsValues[i].u.pDNWithBinary->lpBinaryValue[n] = b;
+            }
+            if (*p != ':')
+                FIXME("wrong DN with binary separator '%c'\n", *p);
+            col->pADsValues[i].u.pDNWithBinary->pszDNString = p + 1;
+
+            TRACE("%s => %u,%s,%s\n", debugstr_w(values[i]),
+                  col->pADsValues[i].u.pDNWithBinary->dwLength,
+                  debugstr_an((char *)col->pADsValues[i].u.pDNWithBinary->lpBinaryValue, col->pADsValues[i].u.pDNWithBinary->dwLength),
+                  debugstr_w(col->pADsValues[i].u.pDNWithBinary->pszDNString));
+        }
+
+        col->hReserved = values;
+        break;
+    }
     }
 
     col->dwADsType = type;
@@ -1654,6 +1726,8 @@ static HRESULT WINAPI search_FreeColumn(IDirectorySearch *iface, PADS_SEARCH_COL
     if (!col) return E_ADS_BAD_PARAMETER;
 
     heap_free(col->pADsValues);
+    heap_free(col->pszAttrName);
+
     if (col->hReserved)
     {
         if (col->dwADsType == ADSTYPE_OCTET_STRING)
diff --git a/dlls/adsldp/schema.c b/dlls/adsldp/schema.c
index e997c6f98e..7f1f193bea 100644
--- a/dlls/adsldp/schema.c
+++ b/dlls/adsldp/schema.c
@@ -101,6 +101,8 @@ ADSTYPEENUM get_schema_type(const WCHAR *name, const struct attribute_type *at,
         return ADSTYPE_CASE_IGNORE_STRING;
     if (!wcscmp(type->syntax, L"1.3.6.1.4.1.1466.115.121.1.40"))
         return ADSTYPE_OCTET_STRING;
+    if (!wcscmp(type->syntax, L"1.2.840.113556.1.4.903"))
+        return ADSTYPE_DN_WITH_BINARY;
     if (!wcscmp(type->syntax, L"1.2.840.113556.1.4.906"))
         return ADSTYPE_LARGE_INTEGER;
     if (!wcscmp(type->syntax, L"1.2.840.113556.1.4.907"))
-- 
2.25.2




More information about the wine-devel mailing list