/* Check whether a DN is below the local baseDN. */ BOOL ldb_dn_check_local(struct ldb_module *module, const struct ldb_dn *dn) { const struct ldb_map_context *data = map_get_context(module); if (!data->local_base_dn) { return True; } return ldb_dn_compare_base(module->ldb, data->local_base_dn, dn) == 0; }
/* check if the scope matches in a search result */ static int ldb_match_scope(struct ldb_context *ldb, struct ldb_dn *base, struct ldb_dn *dn, enum ldb_scope scope) { int ret = 0; if (base == NULL || dn == NULL) { return 1; } switch (scope) { case LDB_SCOPE_BASE: if (ldb_dn_compare(base, dn) == 0) { ret = 1; } break; case LDB_SCOPE_ONELEVEL: if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { if (ldb_dn_compare_base(base, dn) == 0) { ret = 1; } } break; case LDB_SCOPE_SUBTREE: default: if (ldb_dn_compare_base(base, dn) == 0) { ret = 1; } break; } return ret; }
static bool torture_ldb_dn(struct torture_context *torture) { TALLOC_CTX *mem_ctx = talloc_new(torture); struct ldb_context *ldb; struct ldb_dn *dn; struct ldb_dn *child_dn; struct ldb_dn *typo_dn; torture_assert(torture, ldb = ldb_init(mem_ctx, torture->ev), "Failed to init ldb"); torture_assert_int_equal(torture, ldb_register_samba_handlers(ldb), 0, "Failed to register Samba handlers"); ldb_set_utf8_fns(ldb, NULL, wrap_casefold); /* Check behaviour of a normal DN */ torture_assert(torture, dn = ldb_dn_new(mem_ctx, ldb, NULL), "Failed to create a NULL DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate NULL DN"); torture_assert(torture, ldb_dn_add_base_fmt(dn, "dc=org"), "Failed to add base DN"); torture_assert(torture, ldb_dn_add_child_fmt(dn, "dc=samba"), "Failed to add base DN"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org", "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org", "extended linearized DN incorrect"); /* Check child DN comparisons */ torture_assert(torture, child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"), "Failed to create child DN"); torture_assert(torture, ldb_dn_compare(dn, child_dn) != 0, "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0"); torture_assert(torture, ldb_dn_compare_base(child_dn, dn) != 0, "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(dn, child_dn) == 0, "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0"); /* Check comparisons with a truncated DN */ torture_assert(torture, typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"), "Failed to create 'typo' DN"); torture_assert(torture, ldb_dn_compare(dn, typo_dn) != 0, "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(typo_dn, dn) != 0, "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(dn, typo_dn) != 0, "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0"); talloc_free(mem_ctx); return true; }
static bool torture_ldb_dn(struct torture_context *torture) { TALLOC_CTX *mem_ctx = talloc_new(torture); struct ldb_context *ldb; struct ldb_dn *dn; struct ldb_dn *child_dn; struct ldb_dn *typo_dn; struct ldb_val val; torture_assert(torture, ldb = ldb_init(mem_ctx, torture->ev), "Failed to init ldb"); torture_assert_int_equal(torture, ldb_register_samba_handlers(ldb), 0, "Failed to register Samba handlers"); ldb_set_utf8_fns(ldb, NULL, wrap_casefold); /* Check behaviour of a normal DN */ torture_assert(torture, dn = ldb_dn_new(mem_ctx, ldb, NULL), "Failed to create a NULL DN"); torture_assert(torture, ldb_dn_validate(dn), "Failed to validate NULL DN"); torture_assert(torture, ldb_dn_add_base_fmt(dn, "dc=org"), "Failed to add base DN"); torture_assert(torture, ldb_dn_add_child_fmt(dn, "dc=samba"), "Failed to add base DN"); torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "dc=samba,dc=org", "linearized DN incorrect"); torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0), "dc=samba,dc=org", "extended linearized DN incorrect"); /* Check child DN comparisons */ torture_assert(torture, child_dn = ldb_dn_new(mem_ctx, ldb, "CN=users,DC=SAMBA,DC=org"), "Failed to create child DN"); torture_assert(torture, ldb_dn_compare(dn, child_dn) != 0, "Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should != 0"); torture_assert(torture, ldb_dn_compare_base(child_dn, dn) != 0, "Base Comparison of CN=users,DC=SAMBA,DC=org and dc=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(dn, child_dn) == 0, "Base Comparison on dc=samba,dc=org and CN=users,DC=SAMBA,DC=org should == 0"); /* Check comparisons with a truncated DN */ torture_assert(torture, typo_dn = ldb_dn_new(mem_ctx, ldb, "c=samba,dc=org"), "Failed to create 'typo' DN"); torture_assert(torture, ldb_dn_compare(dn, typo_dn) != 0, "Comparison on dc=samba,dc=org and c=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(typo_dn, dn) != 0, "Base Comparison of c=samba,dc=org and dc=samba,dc=org should != 0"); torture_assert(torture, ldb_dn_compare_base(dn, typo_dn) != 0, "Base Comparison on dc=samba,dc=org and c=samba,dc=org should != 0"); /* Check DN based on MS-ADTS:3.1.1.5.1.2 Naming Constraints*/ torture_assert(torture, dn = ldb_dn_new(mem_ctx, ldb, "CN=New\nLine,DC=SAMBA,DC=org"), "Failed to create a DN with 0xA in it"); /* this is a warning until we work out how the DEL: CNs work */ if (ldb_dn_validate(dn) != false) { torture_warning(torture, "should have failed to validate a DN with 0xA in it"); } val = data_blob_const("CN=Zer\0,DC=SAMBA,DC=org", 23); torture_assert(torture, NULL == ldb_dn_from_ldb_val(mem_ctx, ldb, &val), "should fail to create a DN with 0x0 in it"); talloc_free(mem_ctx); return true; }
static bool test_referrals(struct torture_context *tctx, TALLOC_CTX *mem_ctx, const char *url, const char *basedn, const char **partitions) { struct ldb_context *ldb; struct ldb_result *res; const char * const *attrs = { NULL }; struct ldb_dn *dn1, *dn2; int ret; int i, j, k; char *tempstr; bool found, l_found; printf("Testing referrals\n"); if (partitions[0] == NULL) { printf("Partitions list empty!\n"); return false; } if (strcmp(partitions[0], basedn) != 0) { printf("The first (root) partition DN should be the base DN!\n"); return false; } ldb = ldb_wrap_connect(mem_ctx, tctx->ev, tctx->lp_ctx, url, NULL, popt_get_cmdline_credentials(), 0); /* "partitions[i]" are the partitions for which we search the parents */ for (i = 1; partitions[i] != NULL; i++) { dn1 = ldb_dn_new(mem_ctx, ldb, partitions[i]); if (dn1 == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } /* search using base scope */ /* "partitions[j]" are the parent candidates */ for (j = str_list_length(partitions) - 1; j >= 0; --j) { dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]); if (dn2 == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } ret = ldb_search(ldb, mem_ctx, &res, dn2, LDB_SCOPE_BASE, attrs, "(foo=bar)"); if (ret != LDB_SUCCESS) { printf("%s", ldb_errstring(ldb)); talloc_free(ldb); return false; } if (res->refs != NULL) { printf("There shouldn't be generated any referrals in the base scope!\n"); talloc_free(ldb); return false; } talloc_free(res); talloc_free(dn2); } /* search using onelevel scope */ found = false; /* "partitions[j]" are the parent candidates */ for (j = str_list_length(partitions) - 1; j >= 0; --j) { dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]); if (dn2 == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } ret = ldb_search(ldb, mem_ctx, &res, dn2, LDB_SCOPE_ONELEVEL, attrs, "(foo=bar)"); if (ret != LDB_SUCCESS) { printf("%s", ldb_errstring(ldb)); talloc_free(ldb); return false; } tempstr = talloc_asprintf(mem_ctx, "/%s??base", partitions[i]); if (tempstr == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } /* Try to find or find not a matching referral */ l_found = false; for (k = 0; (!l_found) && (res->refs != NULL) && (res->refs[k] != NULL); k++) { if (strstr(res->refs[k], tempstr) != NULL) { l_found = true; } } talloc_free(tempstr); if ((!found) && (ldb_dn_compare_base(dn2, dn1) == 0) && (ldb_dn_compare(dn2, dn1) != 0)) { /* This is a referral candidate */ if (!l_found) { printf("A required referral hasn't been found on onelevel scope (%s -> %s)!\n", partitions[j], partitions[i]); talloc_free(ldb); return false; } found = true; } else { /* This isn't a referral candidate */ if (l_found) { printf("A unrequired referral has been found on onelevel scope (%s -> %s)!\n", partitions[j], partitions[i]); talloc_free(ldb); return false; } } talloc_free(res); talloc_free(dn2); } /* search using subtree scope */ found = false; /* "partitions[j]" are the parent candidates */ for (j = str_list_length(partitions) - 1; j >= 0; --j) { dn2 = ldb_dn_new(mem_ctx, ldb, partitions[j]); if (dn2 == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } ret = ldb_search(ldb, mem_ctx, &res, dn2, LDB_SCOPE_SUBTREE, attrs, "(foo=bar)"); if (ret != LDB_SUCCESS) { printf("%s", ldb_errstring(ldb)); talloc_free(ldb); return false; } tempstr = talloc_asprintf(mem_ctx, "/%s", partitions[i]); if (tempstr == NULL) { printf("Out of memory\n"); talloc_free(ldb); return false; } /* Try to find or find not a matching referral */ l_found = false; for (k = 0; (!l_found) && (res->refs != NULL) && (res->refs[k] != NULL); k++) { if (strstr(res->refs[k], tempstr) != NULL) { l_found = true; } } talloc_free(tempstr); if ((!found) && (ldb_dn_compare_base(dn2, dn1) == 0) && (ldb_dn_compare(dn2, dn1) != 0)) { /* This is a referral candidate */ if (!l_found) { printf("A required referral hasn't been found on subtree scope (%s -> %s)!\n", partitions[j], partitions[i]); talloc_free(ldb); return false; } found = true; } else { /* This isn't a referral candidate */ if (l_found) { printf("A unrequired referral has been found on subtree scope (%s -> %s)!\n", partitions[j], partitions[i]); talloc_free(ldb); return false; } } talloc_free(res); talloc_free(dn2); } talloc_free(dn1); } talloc_free(ldb); return true; }
static int parse_members(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct sss_domain_info *domain, struct ldb_message_element *el, const char *parent_name, const char ***user_members, const char ***group_members, int *num_group_members) { struct ldb_dn *user_basedn = NULL, *group_basedn = NULL; struct ldb_dn *parent_dn = NULL; struct ldb_dn *dn = NULL; const char **um = NULL, **gm = NULL; unsigned int um_index = 0, gm_index = 0; TALLOC_CTX *tmp_ctx = NULL; int ret; int i; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { ret = ENOMEM; goto fail; } user_basedn = sysdb_user_base_dn(tmp_ctx, domain); group_basedn = sysdb_group_base_dn(tmp_ctx, domain); if (!user_basedn || !group_basedn) { ret = ENOMEM; goto fail; } um = talloc_array(mem_ctx, const char *, el->num_values+1); gm = talloc_array(mem_ctx, const char *, el->num_values+1); if (!um || !gm) { ret = ENOMEM; goto fail; } for (i = 0; i< el->num_values; ++i) { dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &(el->values[i])); /* user member or group member? */ parent_dn = ldb_dn_get_parent(tmp_ctx, dn); if (ldb_dn_compare_base(parent_dn, user_basedn) == 0) { um[um_index] = rdn_as_string(mem_ctx, dn); if (um[um_index] == NULL) { ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "User member %s\n", um[um_index]); um_index++; } else if (ldb_dn_compare_base(parent_dn, group_basedn) == 0) { gm[gm_index] = rdn_as_string(mem_ctx, dn); if (gm[gm_index] == NULL) { ret = ENOMEM; goto fail; } if (parent_name && strcmp(gm[gm_index], parent_name) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Skipping circular nesting for group %s\n", gm[gm_index]); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Group member %s\n", gm[gm_index]); gm_index++; } else { DEBUG(SSSDBG_OP_FAILURE, "Group member not a user nor group: %s\n", ldb_dn_get_linearized(dn)); ret = EIO; goto fail; } talloc_zfree(dn); talloc_zfree(parent_dn); } um[um_index] = NULL; gm[gm_index] = NULL; if (um_index > 0) { um = talloc_realloc(mem_ctx, um, const char *, um_index+1); if (!um) { ret = ENOMEM; goto fail; } } else {