#include "includes.h"
#include "ldb.h"
#include "../lib/util/util_ldb.h"
+#include "../lib/util/dns_cmp.h"
#include "dsdb/samdb/samdb.h"
#include "libcli/security/security.h"
#include "librpc/gen_ndr/ndr_security.h"
return NT_STATUS_OK;
}
-#define DNS_CMP_FIRST_IS_CHILD -2
-#define DNS_CMP_FIRST_IS_LESS -1
-#define DNS_CMP_MATCH 0
-#define DNS_CMP_SECOND_IS_LESS 1
-#define DNS_CMP_SECOND_IS_CHILD 2
-
-#define DNS_CMP_IS_NO_MATCH(__cmp) \
- ((__cmp == DNS_CMP_FIRST_IS_LESS) || (__cmp == DNS_CMP_SECOND_IS_LESS))
-
-/*
- * this function assumes names are well formed DNS names.
- * it doesn't validate them
- *
- * It allows strings up to a length of UINT16_MAX - 1
- * with up to UINT8_MAX components. On overflow this
- * just returns the result of strcasecmp_m().
- *
- * Trailing dots (only one) are ignored.
- *
- * The DNS names are compared per component, starting from
- * the last one.
- *
- * The function is usable in a sort, but the return value contains more
- * information than a simple comparison. There are 5 return values, defined
- * above.
- *
- * DNS_CMP_FIRST_IS_CHILD (-2) means the first argument is a sub-domain of the
- * second. e.g. dns_cmp("foo.example.org", "example.org")
- *
- * DNS_CMP_FIRST_IS_LESS (-1) means the first argument sorts before the
- * second, but is not a sub-domain. e.g. dns_cmp("eggsample.org", "example.org").
- *
- * DNS_CMP_SECOND_IS_CHILD (+2) and DNS_CMP_SECOND_IS_LESS (+1) have the
- * similar expected meanings. DNS_CMP_MATCH (0) means equality.
- *
- * NULL values are the parent of all addresses, which means comparisons
- * between a string and NULL will return +2 or -2.
- */
-static int dns_cmp(const char *s1, const char *s2)
-{
- size_t l1 = 0;
- const char *p1 = NULL;
- size_t num_comp1 = 0;
- uint16_t comp1[UINT8_MAX] = {0};
- size_t l2 = 0;
- const char *p2 = NULL;
- size_t num_comp2 = 0;
- uint16_t comp2[UINT8_MAX] = {0};
- size_t i;
-
- if (s1 == s2) {
- /* this includes the both NULL case */
- return DNS_CMP_MATCH;
- }
- if (s1 == NULL) {
- return DNS_CMP_SECOND_IS_CHILD;
- }
- if (s2 == NULL) {
- return DNS_CMP_FIRST_IS_CHILD;
- }
-
- l1 = strlen(s1);
- l2 = strlen(s2);
-
- /*
- * trailing '.' are ignored.
- */
- if (l1 > 1 && s1[l1 - 1] == '.') {
- l1--;
- }
- if (l2 > 1 && s2[l2 - 1] == '.') {
- l2--;
- }
-
- for (i = 0; i < ARRAY_SIZE(comp1); i++) {
- char *p;
-
- if (i == 0) {
- p1 = s1;
-
- if (l1 == 0 || l1 >= UINT16_MAX) {
- /* just use one single component on overflow */
- break;
- }
- }
-
- comp1[num_comp1++] = PTR_DIFF(p1, s1);
-
- p = strchr_m(p1, '.');
- if (p == NULL) {
- p1 = NULL;
- break;
- }
-
- p1 = p + 1;
- }
-
- if (p1 != NULL) {
- /* just use one single component on overflow */
- num_comp1 = 0;
- comp1[num_comp1++] = 0;
- p1 = NULL;
- }
-
- for (i = 0; i < ARRAY_SIZE(comp2); i++) {
- char *p;
-
- if (i == 0) {
- p2 = s2;
-
- if (l2 == 0 || l2 >= UINT16_MAX) {
- /* just use one single component on overflow */
- break;
- }
- }
-
- comp2[num_comp2++] = PTR_DIFF(p2, s2);
-
- p = strchr_m(p2, '.');
- if (p == NULL) {
- p2 = NULL;
- break;
- }
-
- p2 = p + 1;
- }
-
- if (p2 != NULL) {
- /* just use one single component on overflow */
- num_comp2 = 0;
- comp2[num_comp2++] = 0;
- p2 = NULL;
- }
-
- for (i = 0; i < UINT8_MAX; i++) {
- int cmp;
-
- if (i < num_comp1) {
- size_t idx = num_comp1 - (i + 1);
- p1 = s1 + comp1[idx];
- } else {
- p1 = NULL;
- }
-
- if (i < num_comp2) {
- size_t idx = num_comp2 - (i + 1);
- p2 = s2 + comp2[idx];
- } else {
- p2 = NULL;
- }
-
- if (p1 == NULL && p2 == NULL) {
- return DNS_CMP_MATCH;
- }
- if (p1 != NULL && p2 == NULL) {
- return DNS_CMP_FIRST_IS_CHILD;
- }
- if (p1 == NULL && p2 != NULL) {
- return DNS_CMP_SECOND_IS_CHILD;
- }
-
- cmp = strcasecmp_m(p1, p2);
- if (cmp < 0) {
- return DNS_CMP_FIRST_IS_LESS;
- }
- if (cmp > 0) {
- return DNS_CMP_SECOND_IS_LESS;
- }
- }
-
- smb_panic(__location__);
- return -1;
-}
-
static int dsdb_trust_find_tln_match_internal(const struct lsa_ForestTrustInformation *info,
enum lsa_ForestTrustRecordType type,
uint32_t disable_mask,