コード例 #1
0
/*
   get the stamp values for the linked attribute 'linked_attr_name' of the object 'dn'
*/
static WERROR get_linked_attribute_value_stamp(TALLOC_CTX *mem_ctx, struct ldb_context *samdb,
				       struct ldb_dn *dn, const char *linked_attr_name,
				       uint32_t *attr_version, NTTIME *attr_change_time, uint32_t *attr_orig_usn)
{
	struct ldb_result *res;
	int ret;
	const char *attrs[2];
	struct ldb_dn *attr_ext_dn;
	NTSTATUS ntstatus;

	attrs[0] = linked_attr_name;
	attrs[1] = NULL;

	ret = dsdb_search_dn(samdb, mem_ctx, &res, dn, attrs,
			     DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_REVEAL_INTERNALS);
	if (ret != LDB_SUCCESS) {
		DEBUG(0, (__location__ ": Failed search for attribute %s on %s",
				linked_attr_name, ldb_dn_get_linearized(dn)));
		return WERR_INTERNAL_ERROR;
	}

	attr_ext_dn = ldb_msg_find_attr_as_dn(samdb, mem_ctx, res->msgs[0], linked_attr_name);
	if (!attr_ext_dn) {
		DEBUG(0, (__location__ ": Failed search for attribute %s on %s",
				linked_attr_name, ldb_dn_get_linearized(dn)));
		return WERR_INTERNAL_ERROR;
	}

	DEBUG(0, ("linked_attr_name = %s, attr_ext_dn = %s", linked_attr_name,
		  ldb_dn_get_extended_linearized(mem_ctx, attr_ext_dn, 1)));

	ntstatus = dsdb_get_extended_dn_uint32(attr_ext_dn, attr_version, "RMD_VERSION");
	if (!NT_STATUS_IS_OK(ntstatus)) {
		DEBUG(0, (__location__ ": Could not extract component %s from dn \"%s\"",
				"RMD_VERSION", ldb_dn_get_extended_linearized(mem_ctx, attr_ext_dn, 1)));
		return WERR_INTERNAL_ERROR;
	}

	ntstatus = dsdb_get_extended_dn_nttime(attr_ext_dn, attr_change_time, "RMD_CHANGETIME");
	if (!NT_STATUS_IS_OK(ntstatus)) {
		DEBUG(0, (__location__ ": Could not extract component %s from dn \"%s\"",
				"RMD_CHANGETIME", ldb_dn_get_extended_linearized(mem_ctx, attr_ext_dn, 1)));
		return WERR_INTERNAL_ERROR;
	}

	ntstatus = dsdb_get_extended_dn_uint32(attr_ext_dn, attr_version, "RMD_ORIGINATING_USN");
	if (!NT_STATUS_IS_OK(ntstatus)) {
		DEBUG(0, (__location__ ": Could not extract component %s from dn \"%s\"",
				"RMD_ORIGINATING_USN", ldb_dn_get_extended_linearized(mem_ctx, attr_ext_dn, 1)));
		return WERR_INTERNAL_ERROR;
	}

	return WERR_OK;
}
コード例 #2
0
ファイル: dsdb_dn.c プロジェクト: endisd/samba
char *dsdb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, 
				      struct dsdb_dn *dsdb_dn,
				      int mode)
{
	char *postfix = ldb_dn_get_extended_linearized(mem_ctx, dsdb_dn->dn, mode);
	char *ret = dsdb_dn_get_with_postfix(mem_ctx, dsdb_dn, postfix);
	talloc_free(postfix);
	return ret;
}
コード例 #3
0
ファイル: ldif_handlers.c プロジェクト: JiangWeiGitHub/Samba
static int ldif_write_dn_binary_NDR(struct ldb_context *ldb, void *mem_ctx,
				    const struct ldb_val *in, struct ldb_val *out,
				    size_t struct_size,
				    ndr_pull_flags_fn_t pull_fn,
				    ndr_print_fn_t print_fn,
				    bool mask_errors)
{
	uint8_t *p = NULL;
	enum ndr_err_code err;
	struct dsdb_dn *dsdb_dn = NULL;
	char *dn_str = NULL;
	char *str = NULL;

	if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) {
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_BINARY_DN);
	if (dsdb_dn == NULL) {
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	p = talloc_size(dsdb_dn, struct_size);
	if (p == NULL) {
		TALLOC_FREE(dsdb_dn);
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	err = ndr_pull_struct_blob(&dsdb_dn->extra_part, p, p, pull_fn);
	if (err != NDR_ERR_SUCCESS) {
		/* fail in not in mask_error mode */
		if (!mask_errors) {
			return -1;
		}
		TALLOC_FREE(dsdb_dn);
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	dn_str = ldb_dn_get_extended_linearized(dsdb_dn, dsdb_dn->dn, 1);
	if (dn_str == NULL) {
		TALLOC_FREE(dsdb_dn);
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	str = ndr_print_struct_string(mem_ctx, print_fn, dn_str, p);
	TALLOC_FREE(dsdb_dn);
	if (str == NULL) {
		return ldb_handler_copy(ldb, mem_ctx, in, out);
	}

	*out = data_blob_string_const(str);
	return 0;
}
コード例 #4
0
ファイル: schema_set.c プロジェクト: sprymak/samba
/**
 * When loading the schema from LDIF files, we don't get the extended DNs.
 *
 * We need to set these up, so that from the moment we start the provision,
 * the defaultObjectCategory links are set up correctly.
 */
int dsdb_schema_fill_extended_dn(struct ldb_context *ldb, struct dsdb_schema *schema)
{
	struct dsdb_class *cur;
	const struct dsdb_class *target_class;
	for (cur = schema->classes; cur; cur = cur->next) {
		const struct ldb_val *rdn;
		struct ldb_val guid;
		NTSTATUS status;
		struct ldb_dn *dn = ldb_dn_new(NULL, ldb, cur->defaultObjectCategory);

		if (!dn) {
			return LDB_ERR_INVALID_DN_SYNTAX;
		}
		rdn = ldb_dn_get_component_val(dn, 0);
		if (!rdn) {
			talloc_free(dn);
			return LDB_ERR_INVALID_DN_SYNTAX;
		}
		target_class = dsdb_class_by_cn_ldb_val(schema, rdn);
		if (!target_class) {
			talloc_free(dn);
			return LDB_ERR_CONSTRAINT_VIOLATION;
		}

		status = GUID_to_ndr_blob(&target_class->objectGUID, dn, &guid);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(dn);
			return ldb_operr(ldb);
		}
		ldb_dn_set_extended_component(dn, "GUID", &guid);

		cur->defaultObjectCategory = ldb_dn_get_extended_linearized(cur, dn, 1);
		talloc_free(dn);
	}
	return LDB_SUCCESS;
}
コード例 #5
0
ファイル: ldb.c プロジェクト: gojdic/samba
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;
}
コード例 #6
0
ファイル: ldb.c プロジェクト: gojdic/samba
static bool torture_ldb_dn_extended(struct torture_context *torture)
{
    TALLOC_CTX *mem_ctx = talloc_new(torture);
    struct ldb_context *ldb;
    struct ldb_dn *dn, *dn2;

    DATA_BLOB sid_blob = strhex_to_data_blob(mem_ctx, hex_sid);
    DATA_BLOB guid_blob = strhex_to_data_blob(mem_ctx, hex_guid);

    const char *dn_str = "cn=admin,cn=users,dc=samba,dc=org";

    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, dn_str),
                   "Failed to create a 'normal' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'normal' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == false,
                   "Should not find plain DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on plain DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an GUID on plain DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "WKGUID") == NULL,
                   "Should not find an WKGUID on plain DN");

    /* Now make an extended DN */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;<SID=%s>;%s",
                                       guid, sid, dn_str),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   dn2 = ldb_dn_copy(mem_ctx, dn),
                   "Failed to copy the 'extended' DN");
    talloc_free(dn);
    dn = dn2;

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on extended DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on extended DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), dn_str,
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_casefold(dn), strupper_talloc(mem_ctx, dn_str),
                             "casefolded DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_component_name(dn, 0), "cn",
                             "componet zero incorrect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_component_val(dn, 0), data_blob_string_const("admin"),
                                   "componet zero incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     guid, sid, dn_str),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     hex_guid, hex_sid, dn_str),
                             "HEX extended linearized DN incorrect");

    torture_assert(torture, ldb_dn_remove_child_components(dn, 1) == true,
                   "Failed to remove DN child");

    torture_assert(torture, ldb_dn_has_extended(dn) == false,
                   "Extended DN flag should be cleared after child element removal");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an GUID on DN");


    /* TODO:  test setting these in the other order, and ensure it still comes out 'GUID first' */
    torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "GUID", &guid_blob), 0,
                             "Failed to set a GUID on DN");

    torture_assert_int_equal(torture, ldb_dn_set_extended_component(dn, "SID", &sid_blob), 0,
                             "Failed to set a SID on DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "cn=users,dc=samba,dc=org",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     guid, sid, "cn=users,dc=samba,dc=org"),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>;<SID=%s>;%s",
                                     hex_guid, hex_sid, "cn=users,dc=samba,dc=org"),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just GUID' DN (clear format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
                                       guid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert_int_equal(torture, ldb_dn_get_comp_num(dn), 0,
                             "Should not find an 'normal' componet on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<GUID=%s>",
                                     guid),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<GUID=%s>",
                                     hex_guid),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just GUID' DN (HEX format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>",
                                       hex_guid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") != NULL,
                   "Should find an GUID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "GUID"), guid_blob,
                                   "Extended DN GUID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    /* Now check a 'just SID' DN (clear format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
                                       sid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 1),
                             talloc_asprintf(mem_ctx, "<SID=%s>",
                                     sid),
                             "Clear extended linearized DN incorrect");

    torture_assert_str_equal(torture, ldb_dn_get_extended_linearized(mem_ctx, dn, 0),
                             talloc_asprintf(mem_ctx, "<SID=%s>",
                                     hex_sid),
                             "HEX extended linearized DN incorrect");

    /* Now check a 'just SID' DN (HEX format) */
    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>",
                                       hex_sid),
                   "Failed to create an 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn),
                   "Failed to validate 'extended' DN");

    torture_assert(torture, ldb_dn_has_extended(dn) == true,
                   "Should find extended DN to be 'extended'");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "GUID") == NULL,
                   "Should not find an SID on this DN");

    torture_assert(torture, ldb_dn_get_extended_component(dn, "SID") != NULL,
                   "Should find an SID on this DN");

    torture_assert_data_blob_equal(torture, *ldb_dn_get_extended_component(dn, "SID"), sid_blob,
                                   "Extended DN SID incorect");

    torture_assert_str_equal(torture, ldb_dn_get_linearized(dn), "",
                             "linearized DN incorrect");

    talloc_free(mem_ctx);
    return true;
}
コード例 #7
0
ファイル: ldb.c プロジェクト: 0x24bin/winexe-1
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;
}
コード例 #8
0
ファイル: util_groups.c プロジェクト: Alexandr-Galko/samba
/*
 * This function generates the transitive closure of a given SAM object "dn_val"
 * (it basically expands nested memberships).
 * If the object isn't located in the "res_sids" structure yet and the
 * "only_childs" flag is false, we add it to "res_sids".
 * Then we've always to consider the "memberOf" attributes. We invoke the
 * function recursively on each of it with the "only_childs" flag set to
 * "false".
 * The "only_childs" flag is particularly useful if you have a user object and
 * want to include all it's groups (referenced with "memberOf") but not itself
 * or considering if that object matches the filter.
 *
 * At the beginning "res_sids" should reference to a NULL pointer.
 */
NTSTATUS dsdb_expand_nested_groups(struct ldb_context *sam_ctx,
				   struct ldb_val *dn_val, const bool only_childs, const char *filter,
				   TALLOC_CTX *res_sids_ctx, struct dom_sid **res_sids,
				   unsigned int *num_res_sids)
{
	const char * const attrs[] = { "memberOf", NULL };
	unsigned int i;
	int ret;
	bool already_there;
	struct ldb_dn *dn;
	struct dom_sid sid;
	TALLOC_CTX *tmp_ctx;
	struct ldb_result *res;
	NTSTATUS status;
	const struct ldb_message_element *el;

	if (*res_sids == NULL) {
		*num_res_sids = 0;
	}

	if (!sam_ctx) {
		DEBUG(0, ("No SAM available, cannot determine local groups\n"));
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	tmp_ctx = talloc_new(res_sids_ctx);

	dn = ldb_dn_from_ldb_val(tmp_ctx, sam_ctx, dn_val);
	if (dn == NULL) {
		talloc_free(tmp_ctx);
		DEBUG(0, (__location__ ": we failed parsing DN %.*s, so we cannot calculate the group token\n",
			  (int)dn_val->length, dn_val->data));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	status = dsdb_get_extended_dn_sid(dn, &sid, "SID");
	if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
		/* If we fail finding a SID then this is no error since it could
		 * be a non SAM object - e.g. a group with object class
		 * "groupOfNames" */
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	} else if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, (__location__ ": when parsing DN '%s' we failed to parse it's SID component, so we cannot calculate the group token: %s\n",
			  ldb_dn_get_extended_linearized(tmp_ctx, dn, 1),
			  nt_errstr(status)));
		talloc_free(tmp_ctx);
		return status;
	}

	if (!ldb_dn_minimise(dn)) {
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	if (only_childs) {
		ret = dsdb_search_dn(sam_ctx, tmp_ctx, &res, dn, attrs,
				     DSDB_SEARCH_SHOW_EXTENDED_DN);
	} else {
		/* This is an O(n^2) linear search */
		already_there = sids_contains_sid(*res_sids,
						  *num_res_sids, &sid);
		if (already_there) {
			talloc_free(tmp_ctx);
			return NT_STATUS_OK;
		}

		ret = dsdb_search(sam_ctx, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
				  attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "%s",
				  filter);
	}

	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	if (ret != LDB_SUCCESS) {
		DEBUG(1, (__location__ ": dsdb_search for %s failed: %s\n",
			  ldb_dn_get_extended_linearized(tmp_ctx, dn, 1),
			  ldb_errstring(sam_ctx)));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* We may get back 0 results, if the SID didn't match the filter - such as it wasn't a domain group, for example */
	if (res->count != 1) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	/* We only apply this test once we know the SID matches the filter */
	if (!only_childs) {
		*res_sids = talloc_realloc(res_sids_ctx, *res_sids,
			struct dom_sid, *num_res_sids + 1);
		NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*res_sids, tmp_ctx);
		(*res_sids)[*num_res_sids] = sid;
		++(*num_res_sids);
	}
コード例 #9
0
ファイル: schema_syntax.c プロジェクト: gojdic/samba
static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb, 
					    const struct dsdb_schema *schema,
					    const struct dsdb_attribute *attr,
					    const struct drsuapi_DsReplicaAttribute *in,
					    TALLOC_CTX *mem_ctx,
					    struct ldb_message_element *out)
{
	uint32_t i;
	int ret;

	out->flags	= 0;
	out->name	= talloc_strdup(mem_ctx, attr->lDAPDisplayName);
	W_ERROR_HAVE_NO_MEMORY(out->name);

	out->num_values	= in->value_ctr.num_values;
	out->values	= talloc_array(mem_ctx, struct ldb_val, out->num_values);
	W_ERROR_HAVE_NO_MEMORY(out->values);

	for (i=0; i < out->num_values; i++) {
		struct drsuapi_DsReplicaObjectIdentifier3 id3;
		enum ndr_err_code ndr_err;
		DATA_BLOB guid_blob;
		struct ldb_dn *dn;
		TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
		if (!tmp_ctx) {
			W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
		}

		if (in->value_ctr.values[i].blob == NULL) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		if (in->value_ctr.values[i].blob->length == 0) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		

		ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
						   tmp_ctx, schema->iconv_convenience, &id3,
						   (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}

		dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
		if (!dn) {
			talloc_free(tmp_ctx);
			/* If this fails, it must be out of memory, as it does not do much parsing */
			W_ERROR_HAVE_NO_MEMORY(dn);
		}

		ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
					       (ndr_push_flags_fn_t)ndr_push_GUID);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
			talloc_free(tmp_ctx);
			return ntstatus_to_werror(status);
		}

		ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
		if (ret != LDB_SUCCESS) {
			talloc_free(tmp_ctx);
			return WERR_FOOBAR;
		}

		talloc_free(guid_blob.data);

		if (id3.__ndr_size_sid) {
			DATA_BLOB sid_blob;
			ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
						       (ndr_push_flags_fn_t)ndr_push_dom_sid);
			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
				NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
				talloc_free(tmp_ctx);
				return ntstatus_to_werror(status);
			}

			ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
			if (ret != LDB_SUCCESS) {
				talloc_free(tmp_ctx);
				return WERR_FOOBAR;
			}
		}

		out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
		talloc_free(tmp_ctx);
	}

	return WERR_OK;
}
コード例 #10
0
ファイル: util_samr.c プロジェクト: Arkhont/samba
/* Return the members of this group (which may be a domain group or an alias) */
NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
			     TALLOC_CTX *mem_ctx,
			     struct ldb_dn *dn,
			     struct dom_sid **members_out,
			     unsigned int *pnum_members)
{
	struct ldb_message *msg;
	unsigned int i, j;
	int ret;
	struct dom_sid *members;
	struct ldb_message_element *member_el;
	const char *attrs[] = { "member", NULL };
	NTSTATUS status;
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
			      DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}
	if (ret != LDB_SUCCESS) {
		DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n",
			  ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	member_el = ldb_msg_find_element(msg, "member");
	if (!member_el) {
		*members_out = NULL;
		*pnum_members = 0;
		talloc_free(tmp_ctx);
		return NT_STATUS_OK;
	}

	members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values);
	if (members == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	j = 0;
	for (i=0; i <member_el->num_values; i++) {
		struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb,
							       &member_el->values[i]);
		if (!member_dn || !ldb_dn_validate(member_dn)) {
			DEBUG(1, ("Could not parse %*.*s as a DN\n",
				  (int)member_el->values[i].length,
				  (int)member_el->values[i].length,
				  (const char *)member_el->values[i].data));
			talloc_free(tmp_ctx);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}

		status = dsdb_get_extended_dn_sid(member_dn, &members[j],
						  "SID");
		if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
			/* If we fail finding a SID then this is no error since
			 * it could be a non SAM object - e.g. a contact */
			continue;
		} else if (!NT_STATUS_IS_OK(status)) {
			DEBUG(1, ("When parsing DN '%s' we failed to parse it's SID component, so we cannot fetch the membership: %s\n",
				  ldb_dn_get_extended_linearized(tmp_ctx, member_dn, 1),
				  nt_errstr(status)));
			talloc_free(tmp_ctx);
			return status;
		}

		++j;
	}

	*members_out = talloc_steal(mem_ctx, members);
	*pnum_members = j;
	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
コード例 #11
0
ファイル: ridalloc.c プロジェクト: samba-team/samba
/*
  create a RID Set object for the specified DC
 */
static int ridalloc_create_rid_set_ntds(struct ldb_module *module, TALLOC_CTX *mem_ctx,
					struct ldb_dn *rid_manager_dn,
					struct ldb_dn *ntds_dn, struct ldb_dn **dn,
					struct ldb_request *parent)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct ldb_dn *server_dn, *machine_dn, *rid_set_dn;
	int ret;
	struct ldb_message *msg;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	static const struct ridalloc_ridset_values o = {
		.alloc_pool	= UINT64_MAX,
		.prev_pool	= UINT64_MAX,
		.next_rid	= UINT32_MAX,
		.used_pool	= UINT32_MAX,
	};
	struct ridalloc_ridset_values n = {
		.alloc_pool	= 0,
		.prev_pool	= 0,
		.next_rid	= 0,
		.used_pool	= 0,
	};
	const char *no_attrs[] = { NULL };
	struct ldb_result *res;

	/*
	  steps:

	  find the machine object for the DC
	  construct the RID Set DN
	  load rIDAvailablePool to find next available set
	  modify RID Manager object to update rIDAvailablePool
	  add the RID Set object
	  link to the RID Set object in machine object
	 */

	server_dn = ldb_dn_get_parent(tmp_ctx, ntds_dn);
	if (!server_dn) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	ret = dsdb_module_reference_dn(module, tmp_ctx, server_dn, "serverReference", &machine_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find serverReference in %s - %s",
				       ldb_dn_get_linearized(server_dn), ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	rid_set_dn = ldb_dn_copy(tmp_ctx, machine_dn);
	if (rid_set_dn == NULL) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	if (! ldb_dn_add_child_fmt(rid_set_dn, "CN=RID Set")) {
		talloc_free(tmp_ctx);
		return ldb_module_oom(module);
	}

	/* grab a pool from the RID Manager object */
	ret = ridalloc_rid_manager_allocate(module, rid_manager_dn, &n.alloc_pool, parent);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* create the RID Set object */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = rid_set_dn;

	ret = ldb_msg_add_string(msg, "objectClass", "rIDSet");
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	ret = ridalloc_set_ridset_values(module, msg, &o, &n);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	/* we need this to go all the way to the top of the module
	 * stack, as we need all the extra attributes added (including
	 * complex ones like ntsecuritydescriptor).  We must do this
	 * as system, otherwise a user might end up owning the RID
	 * set, and that would be bad... */
	ret = dsdb_module_add(module, msg,
			      DSDB_FLAG_TOP_MODULE | DSDB_FLAG_AS_SYSTEM
			      | DSDB_MODIFY_RELAX, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add RID Set %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	/* add the rIDSetReferences link */
	msg = ldb_msg_new(tmp_ctx);
	msg->dn = machine_dn;

	/* we need the extended DN of the RID Set object for
	 * rIDSetReferences */
	ret = dsdb_module_search_dn(module, msg, &res, rid_set_dn, no_attrs,
				    DSDB_FLAG_NEXT_MODULE | DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find extended DN of RID Set %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}
	rid_set_dn = res->msgs[0]->dn;


	ret = ldb_msg_add_string(msg, "rIDSetReferences", ldb_dn_get_extended_linearized(msg, rid_set_dn, 1));
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}
	msg->elements[0].flags = LDB_FLAG_MOD_ADD;

	ret = dsdb_module_modify(module, msg, DSDB_FLAG_NEXT_MODULE, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to add rIDSetReferences to %s - %s",
				       ldb_dn_get_linearized(msg->dn),
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	(*dn) = talloc_steal(mem_ctx, rid_set_dn);

	talloc_free(tmp_ctx);
	return LDB_SUCCESS;
}


/*
  create a RID Set object for this DC
 */
int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *mem_ctx,
				struct ldb_dn **dn, struct ldb_request *parent)
{
	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	struct ldb_dn *rid_manager_dn, *fsmo_role_dn;
	int ret;
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct GUID fsmo_role_guid;
	const struct GUID *our_ntds_guid;
	NTSTATUS status;

	/* work out who is the RID Manager */
	ret = dsdb_module_rid_manager_dn(module, tmp_ctx, &rid_manager_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find RID Manager object - %s",
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	/* find the DN of the RID Manager */
	ret = dsdb_module_reference_dn(module, tmp_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn, parent);
	if (ret != LDB_SUCCESS) {
		ldb_asprintf_errstring(ldb, "Failed to find fSMORoleOwner in RID Manager object - %s",
				       ldb_errstring(ldb));
		talloc_free(tmp_ctx);
		return ret;
	}

	status = dsdb_get_extended_dn_guid(fsmo_role_dn, &fsmo_role_guid, "GUID");
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(tmp_ctx);
		return ldb_operr(ldb_module_get_ctx(module));
	}

	our_ntds_guid = samdb_ntds_objectGUID(ldb_module_get_ctx(module));
	if (!our_ntds_guid) {
		talloc_free(tmp_ctx);
		return ldb_operr(ldb_module_get_ctx(module));
	}

	if (!GUID_equal(&fsmo_role_guid, our_ntds_guid)) {
		ret = ridalloc_poke_rid_manager(module);
		if (ret != LDB_SUCCESS) {
			ldb_asprintf_errstring(ldb,
					"Request for remote creation of "
					"RID Set for this DC failed: %s",
					ldb_errstring(ldb));
		} else {
			ldb_asprintf_errstring(ldb,
					"Remote RID Set creation needed");
		}
		talloc_free(tmp_ctx);
		return LDB_ERR_UNWILLING_TO_PERFORM;
	}

	ret = ridalloc_create_rid_set_ntds(module, mem_ctx, rid_manager_dn, fsmo_role_dn, dn, parent);
	talloc_free(tmp_ctx);
	return ret;
}