]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: Factor out PAC blob functions into new source file
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 8 May 2023 23:57:09 +0000 (11:57 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 18 May 2023 01:03:37 +0000 (01:03 +0000)
pac-glue.c has become rather large, and can do without these PAC
blob–handling functions.

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/kdc/pac-blobs.c [new file with mode: 0644]
source4/kdc/pac-blobs.h [new file with mode: 0644]
source4/kdc/pac-glue.c
source4/kdc/wscript_build

diff --git a/source4/kdc/pac-blobs.c b/source4/kdc/pac-blobs.c
new file mode 100644 (file)
index 0000000..2c0bce6
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   PAC Glue between Samba and the KDC
+
+   Copyright (C) Catalyst.Net Ltd 2023
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "source4/kdc/pac-blobs.h"
+
+#include "lib/util/debug.h"
+#include "lib/util/samba_util.h"
+
+void pac_blobs_init(struct pac_blobs *pac_blobs)
+{
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(pac_blobs->type_index); ++i) {
+               pac_blobs->type_index[i] = SIZE_MAX;
+       }
+
+       pac_blobs->type_blobs = NULL;
+       pac_blobs->num_types = 0;
+}
+
+void pac_blobs_destroy(struct pac_blobs *pac_blobs)
+{
+       TALLOC_FREE(pac_blobs->type_blobs);
+}
+
+static inline size_t *pac_blobs_get_index(struct pac_blobs *pac_blobs, size_t type)
+{
+       /* Ensure the type is valid. */
+       SMB_ASSERT(type >= PAC_TYPE_BEGIN);
+       SMB_ASSERT(type < PAC_TYPE_END);
+
+       return &pac_blobs->type_index[type - PAC_TYPE_BEGIN];
+}
+
+static inline struct type_data *pac_blobs_get(struct pac_blobs *pac_blobs, size_t type)
+{
+       size_t index = *pac_blobs_get_index(pac_blobs, type);
+       SMB_ASSERT(index < pac_blobs->num_types);
+
+       return &pac_blobs->type_blobs[index];
+}
+
+krb5_error_code pac_blobs_from_krb5_pac(struct pac_blobs *pac_blobs,
+                                       TALLOC_CTX *mem_ctx,
+                                       krb5_context context,
+                                       const krb5_const_pac pac)
+{
+       krb5_error_code code;
+       uint32_t *types = NULL;
+       size_t i;
+
+       code = krb5_pac_get_types(context, pac, &pac_blobs->num_types, &types);
+       if (code != 0) {
+               DBG_ERR("krb5_pac_get_types failed\n");
+               return code;
+       }
+
+       pac_blobs->type_blobs = talloc_array(mem_ctx, struct type_data, pac_blobs->num_types);
+       if (pac_blobs->type_blobs == NULL) {
+               DBG_ERR("Out of memory\n");
+               SAFE_FREE(types);
+               return ENOMEM;
+       }
+
+       for (i = 0; i < pac_blobs->num_types; ++i) {
+               uint32_t type = types[i];
+               size_t *type_index = NULL;
+
+               pac_blobs->type_blobs[i] = (struct type_data) {
+                       .type = type,
+                       .data = NULL,
+               };
+
+               switch (type) {
+                       /* PAC buffer types that we support. */
+               case PAC_TYPE_LOGON_INFO:
+               case PAC_TYPE_CREDENTIAL_INFO:
+               case PAC_TYPE_SRV_CHECKSUM:
+               case PAC_TYPE_KDC_CHECKSUM:
+               case PAC_TYPE_LOGON_NAME:
+               case PAC_TYPE_CONSTRAINED_DELEGATION:
+               case PAC_TYPE_UPN_DNS_INFO:
+               case PAC_TYPE_CLIENT_CLAIMS_INFO:
+               case PAC_TYPE_DEVICE_INFO:
+               case PAC_TYPE_DEVICE_CLAIMS_INFO:
+               case PAC_TYPE_TICKET_CHECKSUM:
+               case PAC_TYPE_ATTRIBUTES_INFO:
+               case PAC_TYPE_REQUESTER_SID:
+               case PAC_TYPE_FULL_CHECKSUM:
+                       type_index = pac_blobs_get_index(pac_blobs, type);
+                       if (*type_index != SIZE_MAX) {
+                               DBG_WARNING("PAC buffer type[%"PRIu32"] twice\n", type);
+                               pac_blobs_destroy(pac_blobs);
+                               SAFE_FREE(types);
+                               return EINVAL;
+                       }
+                       *type_index = i;
+
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       SAFE_FREE(types);
+       return 0;
+}
+
+krb5_error_code _pac_blobs_ensure_exists(struct pac_blobs *pac_blobs,
+                                        const uint32_t type,
+                                        const char *name,
+                                        const char *location,
+                                        const char *function)
+{
+       if (*pac_blobs_get_index(pac_blobs, type) == SIZE_MAX) {
+               DEBUGLF(DBGLVL_ERR, ("%s: %s missing\n", function, name), location, function);
+               return EINVAL;
+       }
+
+       return 0;
+}
+
+krb5_error_code _pac_blobs_replace_existing(struct pac_blobs *pac_blobs,
+                                           const uint32_t type,
+                                           const char *name,
+                                           const DATA_BLOB *blob,
+                                           const char *location,
+                                           const char *function)
+{
+       krb5_error_code code;
+
+       code = _pac_blobs_ensure_exists(pac_blobs,
+                                       type,
+                                       name,
+                                       location,
+                                       function);
+       if (code != 0) {
+               return code;
+       }
+
+       pac_blobs_get(pac_blobs, type)->data = blob;
+
+       return 0;
+}
+
+krb5_error_code pac_blobs_add_blob(struct pac_blobs *pac_blobs,
+                                  TALLOC_CTX *mem_ctx,
+                                  const uint32_t type,
+                                  const DATA_BLOB *blob)
+{
+       size_t *index = NULL;
+
+       if (blob == NULL) {
+               return 0;
+       }
+
+       index = pac_blobs_get_index(pac_blobs, type);
+       if (*index == SIZE_MAX) {
+               pac_blobs->type_blobs = talloc_realloc(mem_ctx,
+                                                      pac_blobs->type_blobs,
+                                                      struct type_data,
+                                                      pac_blobs->num_types + 1);
+               if (pac_blobs->type_blobs == NULL) {
+                       DBG_ERR("Out of memory\n");
+                       return ENOMEM;
+               }
+
+               *index = pac_blobs->num_types++;
+       }
+
+       *pac_blobs_get(pac_blobs, type) = (struct type_data) {
+               .type = type,
+               .data = blob,
+       };
+
+       return 0;
+}
+
+krb5_error_code pac_blobs_remove_blob(struct pac_blobs *pac_blobs,
+                                     TALLOC_CTX *mem_ctx,
+                                     const uint32_t type)
+{
+       size_t found_index;
+       size_t i;
+
+       /* Get the index of this PAC buffer type. */
+       found_index = *pac_blobs_get_index(pac_blobs, type);
+       if (found_index == SIZE_MAX) {
+               /* We don't have a PAC buffer of this type, so we're done. */
+               return 0;
+       }
+
+       /* Since the PAC buffer is present, there will be at least one type in the array. */
+       SMB_ASSERT(pac_blobs->num_types > 0);
+
+       /* The index should be valid. */
+       SMB_ASSERT(found_index < pac_blobs->num_types);
+
+       /*
+        * Even though a consistent ordering of PAC buffers is not to be relied
+        * upon, we must still maintain the ordering we are given.
+        */
+       for (i = found_index; i < pac_blobs->num_types - 1; ++i) {
+               size_t moved_type;
+
+               /* Shift each following element backwards by one. */
+               pac_blobs->type_blobs[i] = pac_blobs->type_blobs[i + 1];
+
+               /* Mark the new position of the moved element in the index. */
+               moved_type = pac_blobs->type_blobs[i].type;
+               if (moved_type >= PAC_TYPE_BEGIN && moved_type < PAC_TYPE_END) {
+                       *pac_blobs_get_index(pac_blobs, moved_type) = i;
+               }
+       }
+
+       /* Mark the removed element as no longer present. */
+       *pac_blobs_get_index(pac_blobs, type) = SIZE_MAX;
+
+       /* We do not free the removed data blob, as it may be statically allocated (e.g., a null blob). */
+
+       /* Remove the last element from the array. */
+       pac_blobs->type_blobs = talloc_realloc(mem_ctx,
+                                              pac_blobs->type_blobs,
+                                              struct type_data,
+                                              --pac_blobs->num_types);
+       if (pac_blobs->type_blobs == NULL) {
+               DBG_ERR("Out of memory\n");
+               return ENOMEM;
+       }
+
+       return 0;
+}
diff --git a/source4/kdc/pac-blobs.h b/source4/kdc/pac-blobs.h
new file mode 100644 (file)
index 0000000..7696849
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   PAC Glue between Samba and the KDC
+
+   Copyright (C) Catalyst.Net Ltd 2023
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lib/replace/replace.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
+#include <krb5/krb5.h>
+
+#include "lib/util/data_blob.h"
+#include "librpc/gen_ndr/ndr_krb5pac.h"
+
+struct type_data {
+       uint32_t type;
+       const DATA_BLOB *data;
+};
+
+struct pac_blobs {
+       size_t type_index[PAC_TYPE_COUNT];
+       struct type_data *type_blobs;
+       size_t num_types;
+};
+
+void pac_blobs_init(struct pac_blobs *pac_blobs);
+
+void pac_blobs_destroy(struct pac_blobs *pac_blobs);
+
+krb5_error_code pac_blobs_from_krb5_pac(struct pac_blobs *pac_blobs,
+                                       TALLOC_CTX *mem_ctx,
+                                       krb5_context context,
+                                       const krb5_const_pac pac);
+
+#define pac_blobs_ensure_exists(pac_blobs, type) \
+       _pac_blobs_ensure_exists(pac_blobs, \
+                                type, \
+                                #type, \
+                                __location__, \
+                                __func__)
+
+krb5_error_code _pac_blobs_ensure_exists(struct pac_blobs *pac_blobs,
+                                        const uint32_t type,
+                                        const char *name,
+                                        const char *location,
+                                        const char *function);
+
+#define pac_blobs_replace_existing(pac_blobs, type, blob) \
+       _pac_blobs_replace_existing(pac_blobs, \
+                                   type, \
+                                   #type, \
+                                   blob, \
+                                   __location__, \
+                                   __func__)
+
+krb5_error_code _pac_blobs_replace_existing(struct pac_blobs *pac_blobs,
+                                           const uint32_t type,
+                                           const char *name,
+                                           const DATA_BLOB *blob,
+                                           const char *location,
+                                           const char *function);
+
+krb5_error_code pac_blobs_add_blob(struct pac_blobs *pac_blobs,
+                                  TALLOC_CTX *mem_ctx,
+                                  const uint32_t type,
+                                  const DATA_BLOB *blob);
+
+krb5_error_code pac_blobs_remove_blob(struct pac_blobs *pac_blobs,
+                                     TALLOC_CTX *mem_ctx,
+                                     const uint32_t type);
index 1f94391af789ef3050044b8afc8298fdbdc78d7b..e09271bdb4386504ac354739a0a5083f136a797b 100644 (file)
 #include "source4/kdc/samba_kdc.h"
 #include "source4/kdc/pac-glue.h"
 #include "source4/kdc/ad_claims.h"
+#include "source4/kdc/pac-blobs.h"
 
 #include <ldb.h>
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_KERBEROS
 
-struct type_data {
-       uint32_t type;
-       const DATA_BLOB *data;
-};
-
-struct pac_blobs {
-       size_t type_index[PAC_TYPE_COUNT];
-       struct type_data *type_blobs;
-       size_t num_types;
-};
-
-static void pac_blobs_init(struct pac_blobs *pac_blobs)
-{
-       size_t i;
-
-       for (i = 0; i < ARRAY_SIZE(pac_blobs->type_index); ++i) {
-               pac_blobs->type_index[i] = SIZE_MAX;
-       }
-
-       pac_blobs->type_blobs = NULL;
-       pac_blobs->num_types = 0;
-}
-
-static void pac_blobs_destroy(struct pac_blobs *pac_blobs)
-{
-       TALLOC_FREE(pac_blobs->type_blobs);
-}
-
-static inline size_t *pac_blobs_get_index(struct pac_blobs *pac_blobs, size_t type)
-{
-       /* Ensure the type is valid. */
-       SMB_ASSERT(type >= PAC_TYPE_BEGIN);
-       SMB_ASSERT(type < PAC_TYPE_END);
-
-       return &pac_blobs->type_index[type - PAC_TYPE_BEGIN];
-}
-
-static inline struct type_data *pac_blobs_get(struct pac_blobs *pac_blobs, size_t type)
-{
-       size_t index = *pac_blobs_get_index(pac_blobs, type);
-       SMB_ASSERT(index < pac_blobs->num_types);
-
-       return &pac_blobs->type_blobs[index];
-}
-
-static krb5_error_code pac_blobs_from_krb5_pac(struct pac_blobs *pac_blobs,
-                                              TALLOC_CTX *mem_ctx,
-                                              krb5_context context,
-                                              const krb5_const_pac pac)
-{
-       krb5_error_code code;
-       uint32_t *types = NULL;
-       size_t i;
-
-       code = krb5_pac_get_types(context, pac, &pac_blobs->num_types, &types);
-       if (code != 0) {
-               DBG_ERR("krb5_pac_get_types failed\n");
-               return code;
-       }
-
-       pac_blobs->type_blobs = talloc_array(mem_ctx, struct type_data, pac_blobs->num_types);
-       if (pac_blobs->type_blobs == NULL) {
-               DBG_ERR("Out of memory\n");
-               SAFE_FREE(types);
-               return ENOMEM;
-       }
-
-       for (i = 0; i < pac_blobs->num_types; ++i) {
-               uint32_t type = types[i];
-               size_t *type_index = NULL;
-
-               pac_blobs->type_blobs[i] = (struct type_data) {
-                       .type = type,
-                       .data = NULL,
-               };
-
-               switch (type) {
-                       /* PAC buffer types that we support. */
-               case PAC_TYPE_LOGON_INFO:
-               case PAC_TYPE_CREDENTIAL_INFO:
-               case PAC_TYPE_SRV_CHECKSUM:
-               case PAC_TYPE_KDC_CHECKSUM:
-               case PAC_TYPE_LOGON_NAME:
-               case PAC_TYPE_CONSTRAINED_DELEGATION:
-               case PAC_TYPE_UPN_DNS_INFO:
-               case PAC_TYPE_CLIENT_CLAIMS_INFO:
-               case PAC_TYPE_DEVICE_INFO:
-               case PAC_TYPE_DEVICE_CLAIMS_INFO:
-               case PAC_TYPE_TICKET_CHECKSUM:
-               case PAC_TYPE_ATTRIBUTES_INFO:
-               case PAC_TYPE_REQUESTER_SID:
-               case PAC_TYPE_FULL_CHECKSUM:
-                       type_index = pac_blobs_get_index(pac_blobs, type);
-                       if (*type_index != SIZE_MAX) {
-                               DBG_WARNING("PAC buffer type[%"PRIu32"] twice\n", type);
-                               pac_blobs_destroy(pac_blobs);
-                               SAFE_FREE(types);
-                               return EINVAL;
-                       }
-                       *type_index = i;
-
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       SAFE_FREE(types);
-       return 0;
-}
-
-#define pac_blobs_ensure_exists(pac_blobs, type) \
-       _pac_blobs_ensure_exists(pac_blobs, \
-                                type, \
-                                #type, \
-                                __location__, \
-                                __func__)
-
-static inline krb5_error_code _pac_blobs_ensure_exists(struct pac_blobs *pac_blobs,
-                                                      const uint32_t type,
-                                                      const char *name,
-                                                      const char *location,
-                                                      const char *function)
-{
-       if (*pac_blobs_get_index(pac_blobs, type) == SIZE_MAX) {
-               DEBUGLF(DBGLVL_ERR, ("%s: %s missing\n", function, name), location, function);
-               return EINVAL;
-       }
-
-       return 0;
-}
-
-#define pac_blobs_replace_existing(pac_blobs, type, blob) \
-       _pac_blobs_replace_existing(pac_blobs, \
-                                   type, \
-                                   #type, \
-                                   blob, \
-                                   __location__, \
-                                   __func__)
-
-static krb5_error_code _pac_blobs_replace_existing(struct pac_blobs *pac_blobs,
-                                                  const uint32_t type,
-                                                  const char *name,
-                                                  const DATA_BLOB *blob,
-                                                  const char *location,
-                                                  const char *function)
-{
-       krb5_error_code code;
-
-       code = _pac_blobs_ensure_exists(pac_blobs,
-                                       type,
-                                       name,
-                                       location,
-                                       function);
-       if (code != 0) {
-               return code;
-       }
-
-       pac_blobs_get(pac_blobs, type)->data = blob;
-
-       return 0;
-}
-
-static krb5_error_code pac_blobs_add_blob(struct pac_blobs *pac_blobs,
-                                         TALLOC_CTX *mem_ctx,
-                                         const uint32_t type,
-                                         const DATA_BLOB *blob)
-{
-       size_t *index = NULL;
-
-       if (blob == NULL) {
-               return 0;
-       }
-
-       index = pac_blobs_get_index(pac_blobs, type);
-       if (*index == SIZE_MAX) {
-               pac_blobs->type_blobs = talloc_realloc(mem_ctx,
-                                                      pac_blobs->type_blobs,
-                                                      struct type_data,
-                                                      pac_blobs->num_types + 1);
-               if (pac_blobs->type_blobs == NULL) {
-                       DBG_ERR("Out of memory\n");
-                       return ENOMEM;
-               }
-
-               *index = pac_blobs->num_types++;
-       }
-
-       *pac_blobs_get(pac_blobs, type) = (struct type_data) {
-               .type = type,
-               .data = blob,
-       };
-
-       return 0;
-}
-
-static krb5_error_code pac_blobs_remove_blob(struct pac_blobs *pac_blobs,
-                                            TALLOC_CTX *mem_ctx,
-                                            const uint32_t type)
-{
-       size_t found_index;
-       size_t i;
-
-       /* Get the index of this PAC buffer type. */
-       found_index = *pac_blobs_get_index(pac_blobs, type);
-       if (found_index == SIZE_MAX) {
-               /* We don't have a PAC buffer of this type, so we're done. */
-               return 0;
-       }
-
-       /* Since the PAC buffer is present, there will be at least one type in the array. */
-       SMB_ASSERT(pac_blobs->num_types > 0);
-
-       /* The index should be valid. */
-       SMB_ASSERT(found_index < pac_blobs->num_types);
-
-       /*
-        * Even though a consistent ordering of PAC buffers is not to be relied
-        * upon, we must still maintain the ordering we are given.
-        */
-       for (i = found_index; i < pac_blobs->num_types - 1; ++i) {
-               size_t moved_type;
-
-               /* Shift each following element backwards by one. */
-               pac_blobs->type_blobs[i] = pac_blobs->type_blobs[i + 1];
-
-               /* Mark the new position of the moved element in the index. */
-               moved_type = pac_blobs->type_blobs[i].type;
-               if (moved_type >= PAC_TYPE_BEGIN && moved_type < PAC_TYPE_END) {
-                       *pac_blobs_get_index(pac_blobs, moved_type) = i;
-               }
-       }
-
-       /* Mark the removed element as no longer present. */
-       *pac_blobs_get_index(pac_blobs, type) = SIZE_MAX;
-
-       /* We do not free the removed data blob, as it may be statically allocated (e.g., a null blob). */
-
-       /* Remove the last element from the array. */
-       pac_blobs->type_blobs = talloc_realloc(mem_ctx,
-                                              pac_blobs->type_blobs,
-                                              struct type_data,
-                                              --pac_blobs->num_types);
-       if (pac_blobs->type_blobs == NULL) {
-               DBG_ERR("Out of memory\n");
-               return ENOMEM;
-       }
-
-       return 0;
-}
-
 static
 NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
                                       const struct auth_user_info_dc *info,
index c6c00c4c3697c50993393ae8f8bce99fd01a3ee8..807fd10791c41433be0e93e44e7295c9e58e92ec 100644 (file)
@@ -122,7 +122,7 @@ bld.SAMBA_SUBSYSTEM('sdb_kdb',
        )
 
 bld.SAMBA_SUBSYSTEM('PAC_GLUE',
-       source='pac-glue.c',
+       source='pac-glue.c pac-blobs.c',
        deps='ldb auth4_sam common_auth samba-credentials samba-hostconfig com_err ad_claims'
        )