CVE-2022-37966 param: Add support for new option "kdc supported enctypes"
authorStefan Metzmacher <metze@samba.org>
Tue, 29 Nov 2022 13:13:36 +0000 (14:13 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 13 Dec 2022 13:07:30 +0000 (13:07 +0000)
This allows admins to disable enctypes completely if required.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15237

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
docs-xml/smbdotconf/security/kdcsupportedenctypes.xml [new file with mode: 0644]
lib/param/loadparm.c

diff --git a/docs-xml/smbdotconf/security/kdcsupportedenctypes.xml b/docs-xml/smbdotconf/security/kdcsupportedenctypes.xml
new file mode 100644 (file)
index 0000000..5e028bb
--- /dev/null
@@ -0,0 +1,40 @@
+<samba:parameter name="kdc supported enctypes"
+                 type="integer"
+                 context="G"
+                 handler="handle_kdc_supported_enctypes"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+  <para>
+    On an active directory domain controller, this is the list of supported encryption types for local running kdc.
+  </para>
+
+  <para>
+    This allows Samba administrators to remove support for weak/unused encryption types, similar
+    the configuration flexibility provided by the <constant>Network security: Configure encryption types allowed for Kerberos</constant>
+    GPO/Local Policies/Security Options Value, which results in the
+    <constant>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters\SupportedEncryptionTypes</constant> Registry Value on Windows.
+  </para>
+  <para>
+    Unlike the Windows registry key (which only takes an base-10 number), in Samba this may also be expressed as hexadecimal or a list of Kerberos encryption type names.
+  </para>
+  <para>
+    Specified values are ORed together bitwise, and those currently supported consist of:
+    </para><itemizedlist>
+   <listitem>
+       <para><constant>arcfour-hmac-md5</constant>, <constant>rc4-hmac</constant>, <constant>0x4</constant>, or <constant>4</constant></para>
+       <para>Known on Windows as Kerberos RC4 encryption</para>
+   </listitem>
+   <listitem>
+       <para><constant>aes128-cts-hmac-sha1-96</constant>, <constant>aes128-cts</constant>, <constant>0x8</constant>, or <constant>8</constant></para>
+       <para>Known on Windows as Kerberos AES 128 bit encryption</para>
+   </listitem>
+   <listitem>
+       <para><constant>aes256-cts-hmac-sha1-96</constant>, <constant>aes256-cts</constant>, <constant>0x10</constant>, or <constant>16</constant></para>
+       <para>Known on Windows as Kerberos AES 256 bit encryption</para>
+   </listitem>
+</itemizedlist>
+
+</description>
+
+<value type="default">0<comment>maps to what the software supports currently: arcfour-hmac-md5 aes128-cts-hmac-sha1-96 aes256-cts-hmac-sha1-96</comment></value>
+</samba:parameter>
index 8387242c25f51c8e097a004e767e97b723a04900..fc0dc4df83fe3dc6613e196d2389d3c4f91127e5 100644 (file)
@@ -1779,6 +1779,75 @@ out:
        return ok;
 }
 
+bool handle_kdc_supported_enctypes(struct loadparm_context *lp_ctx,
+                                  struct loadparm_service *service,
+                                  const char *pszParmValue, char **ptr)
+{
+       char **enctype_list = NULL;
+       char **enctype = NULL;
+       uint32_t result = 0;
+       bool ok = true;
+
+       enctype_list = str_list_make(NULL, pszParmValue, NULL);
+       if (enctype_list == NULL) {
+               DBG_ERR("OOM: failed to make string list from %s\n",
+                       pszParmValue);
+               ok = false;
+               goto out;
+       }
+
+       for (enctype = enctype_list; *enctype != NULL; ++enctype) {
+               if (strwicmp(*enctype, "arcfour-hmac-md5") == 0 ||
+                   strwicmp(*enctype, "rc4-hmac") == 0)
+               {
+                       result |= KERB_ENCTYPE_RC4_HMAC_MD5;
+               }
+               else if (strwicmp(*enctype, "aes128-cts-hmac-sha1-96") == 0 ||
+                        strwicmp(*enctype, "aes128-cts") == 0)
+               {
+                       result |= KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96;
+               }
+               else if (strwicmp(*enctype, "aes256-cts-hmac-sha1-96") == 0 ||
+                        strwicmp(*enctype, "aes256-cts") == 0)
+               {
+                       result |= KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96;
+               }
+               else {
+                       const char *bitstr = *enctype;
+                       int base;
+                       int error;
+                       unsigned long bit;
+
+                       /* See if the bit's specified in hexadecimal. */
+                       if (bitstr[0] == '0' &&
+                           (bitstr[1] == 'x' || bitstr[2] == 'X'))
+                       {
+                               base = 16;
+                               bitstr += 2;
+                       }
+                       else {
+                               base = 10;
+                       }
+
+                       bit = smb_strtoul(bitstr, NULL, base, &error, SMB_STR_FULL_STR_CONV);
+                       if (error) {
+                               DBG_ERR("WARNING: Ignoring invalid value '%s' "
+                                       "for parameter 'kdc default domain supported enctypes'\n",
+                                       *enctype);
+                               ok = false;
+                       } else {
+                               result |= bit;
+                       }
+               }
+       }
+
+       *(int *)ptr = result;
+out:
+       TALLOC_FREE(enctype_list);
+
+       return ok;
+}
+
 static bool set_variable(TALLOC_CTX *mem_ctx, struct loadparm_service *service,
                         int parmnum, void *parm_ptr,
                         const char *pszParmName, const char *pszParmValue,