java-topology/defects/samba-0001/patch/samba-0001.patch

119 lines
3.7 KiB
Diff

# UNDF: UNDF-2026-000001030
# UNDF: UNDF-2026-XXXXXXXXX
--- a/libcli/security/security_token.c
+++ b/libcli/security/security_token.c
@@ -23,6 +23,7 @@
#include "replace.h"
#include <talloc.h>
#include "lib/util/talloc_stack.h"
+#include <stdlib.h>
#include "lib/util/debug.h"
#include "lib/util/fault.h"
#include "libcli/security/security_token.h"
@@ -138,11 +138,63 @@ bool security_token_is_anonymous(const struct security_token *token)
return security_token_is_sid(token, &global_sid_Anonymous);
}
+/*
+ * Comparator for qsort/bsearch of struct dom_sid arrays.
+ */
+static int dom_sid_qsort_cmp(const void *a, const void *b)
+{
+ const struct dom_sid *sa = (const struct dom_sid *)a;
+ const struct dom_sid *sb = (const struct dom_sid *)b;
+ return dom_sid_compare(sa, sb);
+}
+
+/**
+ * security_token_sort_sids - sort the extra SIDs in a token for O(log N) lookup.
+ *
+ * Indices 0 (user SID) and 1 (primary group SID) are left in place; they carry
+ * semantic meaning that must be preserved. All remaining SIDs
+ * (indices REMAINING_SIDS_INDEX..) are sorted in-place with qsort so that
+ * security_token_has_sid() can use bsearch instead of a linear scan.
+ *
+ * Call this once, after the token is fully assembled and before it is used
+ * for any access check (e.g. at the end of finalize_local_nt_token /
+ * security_token_create).
+ */
+void security_token_sort_sids(struct security_token *token)
+{
+ if (token == NULL || token->num_sids <= REMAINING_SIDS_INDEX) {
+ return;
+ }
+ qsort(&token->sids[REMAINING_SIDS_INDEX],
+ token->num_sids - REMAINING_SIDS_INDEX,
+ sizeof(struct dom_sid),
+ dom_sid_qsort_cmp);
+}
+
bool security_token_has_sid(const struct security_token *token, const struct dom_sid *sid)
{
- uint32_t i;
- for (i = 0; i < token->num_sids; i++) {
+ uint32_t i;
+
+ if (token->sids == NULL) {
+ return false;
+ }
+
+ /*
+ * Indices 0 (user) and 1 (primary group) are not sorted into the
+ * sorted tail, so check them with direct equality first.
+ */
+ for (i = 0; i < REMAINING_SIDS_INDEX && i < token->num_sids; i++) {
if (dom_sid_equal(&token->sids[i], sid)) {
return true;
}
}
- return false;
+
+ if (token->num_sids > REMAINING_SIDS_INDEX) {
+ /*
+ * Binary search over the sorted tail
+ * sids[REMAINING_SIDS_INDEX .. num_sids-1].
+ * Requires security_token_sort_sids() to have been called.
+ */
+ const struct dom_sid *found = (const struct dom_sid *)bsearch(
+ sid,
+ &token->sids[REMAINING_SIDS_INDEX],
+ token->num_sids - REMAINING_SIDS_INDEX,
+ sizeof(struct dom_sid),
+ dom_sid_qsort_cmp);
+ return found != NULL;
+ }
+
+ return false;
}
--- a/libcli/security/security_token.h
+++ b/libcli/security/security_token.h
@@ -55,6 +55,16 @@ bool security_token_has_sid(const struct security_token *token, const struct dom
/*
+ * Sort token->sids[REMAINING_SIDS_INDEX..] in-place so that
+ * security_token_has_sid() can use binary search. Call once after
+ * the token is fully built (before the first access check).
+ * Indices 0 and 1 (user and primary group) are left in place.
+ */
+void security_token_sort_sids(struct security_token *token);
+
+/*
* Return any of the domain sids found in the token matching "domain"
* in _domain_sid, makes most sense if you just found one.
*/
--- a/source3/auth/token_util.c
+++ b/source3/auth/token_util.c
@@ -875,6 +875,12 @@ NTSTATUS finalize_local_nt_token(struct security_token *result,
get_privileges_for_sids(&result->privilege_mask, result->sids,
result->num_sids);
}
+
+ /*
+ * Sort sids[REMAINING_SIDS_INDEX..] so security_token_has_sid()
+ * can use binary search instead of O(N) linear scan.
+ */
+ security_token_sort_sids(result);
return NT_STATUS_OK;
}