119 lines
3.7 KiB
Diff
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;
|
|
}
|