Ejemplo n.º 1
0
 struct ldb_context *samba_ldb_init(TALLOC_CTX *mem_ctx,
				    struct tevent_context *ev,
				    struct loadparm_context *lp_ctx,
				    struct auth_session_info *session_info,
				    struct cli_credentials *credentials)
{
	struct ldb_context *ldb;
	int ret;

	ldb = ldb_init(mem_ctx, ev);
	if (ldb == NULL) {
		return NULL;
	}

	ldb_set_modules_dir(ldb, modules_path(ldb, "ldb"));

	ldb_set_debug(ldb, ldb_wrap_debug, NULL);

	ldb_set_utf8_fns(ldb, NULL, wrap_casefold);

	if (session_info) {
		if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
			talloc_free(ldb);
			return NULL;
		}
	}

	if (credentials) {
		if (ldb_set_opaque(ldb, "credentials", credentials)) {
			talloc_free(ldb);
			return NULL;
		}
	}

	if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) {
		talloc_free(ldb);
		return NULL;
	}

	/* This must be done before we load the schema, as these
	 * handlers for objectSid and objectGUID etc must take
	 * precedence over the 'binary attribute' declaration in the
	 * schema */
	ret = ldb_register_samba_handlers(ldb);
	if (ret != LDB_SUCCESS) {
		talloc_free(ldb);
		return NULL;
	}

	/* we usually want Samba databases to be private. If we later
	   find we need one public, we will need to add a parameter to
	   ldb_wrap_connect() */
	ldb_set_create_perms(ldb, 0600);

	return ldb;
}
Ejemplo n.º 2
0
static PyObject *py_ldb_register_samba_handlers(PyObject *self)
{
	struct ldb_context *ldb;
	int ret;

	/* XXX: Perhaps call this from PySambaLdb's init function ? */

	ldb = pyldb_Ldb_AsLdbContext(self);
	ret = ldb_register_samba_handlers(ldb);

	PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb);

	Py_RETURN_NONE;
}
Ejemplo n.º 3
0
static PyObject *py_ldb_register_samba_handlers(PyObject *self, PyObject *args)
{
	PyObject *py_ldb;
	struct ldb_context *ldb;
	int ret;

	if (!PyArg_ParseTuple(args, "O", &py_ldb))
		return NULL;

	PyErr_LDB_OR_RAISE(py_ldb, ldb);
	ret = ldb_register_samba_handlers(ldb);

	PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
	Py_RETURN_NONE;
}
Ejemplo n.º 4
0
Archivo: ldb.c Proyecto: gojdic/samba
static bool torture_ldb_dn_invalid_extended(struct torture_context *torture)
{
    TALLOC_CTX *mem_ctx = talloc_new(torture);
    struct ldb_context *ldb;
    struct ldb_dn *dn;

    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, "samba,dc=org"),
                   "Failed to create a 'normal' invalid DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'normal' invalid DN");

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

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>%s",
                                       sid, dn_str),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
                                       sid),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=%s>;",
                                       hex_sid),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
                                       hex_guid),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<SID=%s>;",
                                       guid),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    torture_assert(torture,
                   dn = ldb_dn_new_fmt(mem_ctx, ldb, "<GUID=>"),
                   "Failed to create an invalid 'extended' DN");

    torture_assert(torture,
                   ldb_dn_validate(dn) == false,
                   "should have failed to validate 'extended' DN");

    return true;
}
Ejemplo n.º 5
0
Archivo: ldb.c Proyecto: 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;
}
Ejemplo n.º 6
0
Archivo: ldb.c Proyecto: gojdic/samba
static bool torture_ldb_attrs(struct torture_context *torture)
{
    TALLOC_CTX *mem_ctx = talloc_new(torture);
    struct ldb_context *ldb;
    const struct ldb_schema_attribute *attr;
    struct ldb_val string_sid_blob, binary_sid_blob;
    struct ldb_val string_guid_blob, string_guid_blob2, binary_guid_blob;

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

    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);

    /* Test SID behaviour */
    torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectSid"),
                   "Failed to get objectSid schema attribute");

    string_sid_blob = data_blob_string_const(sid);

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_read_fn(ldb, mem_ctx,
                                     &string_sid_blob, &binary_sid_blob), 0,
                             "Failed to parse string SID");

    torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
                                   "Read SID into blob form failed");

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_read_fn(ldb, mem_ctx,
                                     &sid_blob, &binary_sid_blob), -1,
                             "Should have failed to parse binary SID");

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
                             "Failed to parse binary SID");

    torture_assert_data_blob_equal(torture,
                                   string_sid_blob, data_blob_string_const(sid),
                                   "Write SID into string form failed");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &string_sid_blob), 0,
                             "Failed to compare binary and string SID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &binary_sid_blob), 0,
                             "Failed to compare string and binary binary SID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &string_sid_blob, &string_sid_blob), 0,
                             "Failed to compare string and string SID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &binary_sid_blob, &binary_sid_blob), 0,
                             "Failed to compare binary and binary SID");

    torture_assert(torture, attr->syntax->comparison_fn(ldb, mem_ctx, &guid_blob, &binary_sid_blob) != 0,
                   "Failed to distinguish binary GUID and binary SID");


    /* Test GUID behaviour */
    torture_assert(torture, attr = ldb_schema_attribute_by_name(ldb, "objectGUID"),
                   "Failed to get objectGUID schema attribute");

    string_guid_blob = data_blob_string_const(guid);

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_read_fn(ldb, mem_ctx,
                                     &string_guid_blob, &binary_guid_blob), 0,
                             "Failed to parse string GUID");

    torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
                                   "Read GUID into blob form failed");

    string_guid_blob2 = data_blob_string_const(guid2);

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_read_fn(ldb, mem_ctx,
                                     &string_guid_blob2, &binary_guid_blob), 0,
                             "Failed to parse string GUID");

    torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
                                   "Read GUID into blob form failed");

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_read_fn(ldb, mem_ctx,
                                     &guid_blob, &binary_guid_blob), 0,
                             "Failed to parse binary GUID");

    torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
                                   "Read GUID into blob form failed");

    torture_assert_int_equal(torture,
                             attr->syntax->ldif_write_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
                             "Failed to print binary GUID as string");

    torture_assert_data_blob_equal(torture, string_sid_blob, data_blob_string_const(sid),
                                   "Write SID into string form failed");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &string_guid_blob), 0,
                             "Failed to compare binary and string GUID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &binary_guid_blob), 0,
                             "Failed to compare string and binary binary GUID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &string_guid_blob, &string_guid_blob), 0,
                             "Failed to compare string and string GUID");

    torture_assert_int_equal(torture,
                             attr->syntax->comparison_fn(ldb, mem_ctx, &binary_guid_blob, &binary_guid_blob), 0,
                             "Failed to compare binary and binary GUID");



    talloc_free(mem_ctx);
    return true;
}
Ejemplo n.º 7
0
Archivo: ldb.c Proyecto: 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;
}
Ejemplo n.º 8
0
Archivo: ldb.c Proyecto: gojdic/samba
static bool torture_ldb_dn_attrs(struct torture_context *torture)
{
    TALLOC_CTX *mem_ctx = talloc_new(torture);
    struct ldb_context *ldb;
    const struct ldb_dn_extended_syntax *attr;
    struct ldb_val string_sid_blob, binary_sid_blob;
    struct ldb_val string_guid_blob, binary_guid_blob;
    struct ldb_val hex_sid_blob, hex_guid_blob;

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

    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);

    /* Test SID behaviour */
    torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "SID"),
                   "Failed to get SID DN syntax");

    string_sid_blob = data_blob_string_const(sid);

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &string_sid_blob, &binary_sid_blob), 0,
                             "Failed to parse string SID");

    torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
                                   "Read SID into blob form failed");

    hex_sid_blob = data_blob_string_const(hex_sid);

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &hex_sid_blob, &binary_sid_blob), 0,
                             "Failed to parse HEX SID");

    torture_assert_data_blob_equal(torture, binary_sid_blob, sid_blob,
                                   "Read SID into blob form failed");

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &sid_blob, &binary_sid_blob), -1,
                             "Should have failed to parse binary SID");

    torture_assert_int_equal(torture,
                             attr->write_hex_fn(ldb, mem_ctx, &sid_blob, &hex_sid_blob), 0,
                             "Failed to parse binary SID");

    torture_assert_data_blob_equal(torture,
                                   hex_sid_blob, data_blob_string_const(hex_sid),
                                   "Write SID into HEX string form failed");

    torture_assert_int_equal(torture,
                             attr->write_clear_fn(ldb, mem_ctx, &sid_blob, &string_sid_blob), 0,
                             "Failed to parse binary SID");

    torture_assert_data_blob_equal(torture,
                                   string_sid_blob, data_blob_string_const(sid),
                                   "Write SID into clear string form failed");


    /* Test GUID behaviour */
    torture_assert(torture, attr = ldb_dn_extended_syntax_by_name(ldb, "GUID"),
                   "Failed to get GUID DN syntax");

    string_guid_blob = data_blob_string_const(guid);

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &string_guid_blob, &binary_guid_blob), 0,
                             "Failed to parse string GUID");

    torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
                                   "Read GUID into blob form failed");

    hex_guid_blob = data_blob_string_const(hex_guid);

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &hex_guid_blob, &binary_guid_blob), 0,
                             "Failed to parse HEX GUID");

    torture_assert_data_blob_equal(torture, binary_guid_blob, guid_blob,
                                   "Read GUID into blob form failed");

    torture_assert_int_equal(torture,
                             attr->read_fn(ldb, mem_ctx,
                                           &guid_blob, &binary_guid_blob), -1,
                             "Should have failed to parse binary GUID");

    torture_assert_int_equal(torture,
                             attr->write_hex_fn(ldb, mem_ctx, &guid_blob, &hex_guid_blob), 0,
                             "Failed to parse binary GUID");

    torture_assert_data_blob_equal(torture,
                                   hex_guid_blob, data_blob_string_const(hex_guid),
                                   "Write GUID into HEX string form failed");

    torture_assert_int_equal(torture,
                             attr->write_clear_fn(ldb, mem_ctx, &guid_blob, &string_guid_blob), 0,
                             "Failed to parse binary GUID");

    torture_assert_data_blob_equal(torture,
                                   string_guid_blob, data_blob_string_const(guid),
                                   "Write GUID into clear string form failed");



    talloc_free(mem_ctx);
    return true;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
static int samba_dsdb_init(struct ldb_module *module)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	int ret, len, i;
	TALLOC_CTX *tmp_ctx = talloc_new(module);
	struct ldb_result *res;
	struct ldb_message *rootdse_msg = NULL, *partition_msg;
	struct ldb_dn *samba_dsdb_dn, *partition_dn;
	struct ldb_module *backend_module, *module_chain;
	const char **final_module_list, **reverse_module_list;
	/*
	  Add modules to the list to activate them by default
	  beware often order is important

	  Some Known ordering constraints:
	  - rootdse must be first, as it makes redirects from "" -> cn=rootdse
	  - extended_dn_in must be before objectclass.c, as it resolves the DN
	  - objectclass must be before password_hash and samldb since these LDB
	    modules require the expanded "objectClass" list
	  - objectclass must be before descriptor and acl, as both assume that
	    objectClass values are sorted
	  - objectclass_attrs must be behind operational in order to see all
	    attributes (the operational module protects and therefore
	    suppresses per default some important ones)
	  - partition must be last
	  - each partition has its own module list then

	  The list is presented here as a set of declarations to show the
	  stack visually - the code below then handles the creation of the list
	  based on the parameters loaded from the database.
	*/
	static const char *modules_list1[] = {"resolve_oids",
					     "rootdse",
					     "schema_load",
					     "lazy_commit",
					     "dirsync",
					     "paged_results",
					     "ranged_results",
					     "anr",
					     "server_sort",
					     "asq",
					     "extended_dn_store",
					     NULL };
	/* extended_dn_in or extended_dn_in_openldap goes here */
	static const char *modules_list1a[] = {"objectclass",
					     "descriptor",
					     "acl",
					     "aclread",
					     "samldb",
					     "password_hash",
					     "operational",
					     "instancetype",
					     "objectclass_attrs",
					     NULL };

	const char **link_modules;
	static const char *fedora_ds_modules[] = {
		"rdn_name", NULL };
	static const char *openldap_modules[] = {
		NULL };
	static const char *tdb_modules_list[] = {
		"rdn_name",
		"subtree_delete",
		"repl_meta_data",
		"subtree_rename",
		"linked_attributes",
		NULL};

	const char *extended_dn_module;
	const char *extended_dn_module_ldb = "extended_dn_out_ldb";
	const char *extended_dn_module_fds = "extended_dn_out_fds";
	const char *extended_dn_module_openldap = "extended_dn_out_openldap";
	const char *extended_dn_in_module = "extended_dn_in";

	static const char *modules_list2[] = {"show_deleted",
					      "new_partition",
					      "partition",
					      NULL };

	const char **backend_modules;
	static const char *fedora_ds_backend_modules[] = {
		"nsuniqueid", "paged_searches", "simple_dn", NULL };
	static const char *openldap_backend_modules[] = {
		"entryuuid", "simple_dn", NULL };

	static const char *samba_dsdb_attrs[] = { "backendType", NULL };
	static const char *partition_attrs[] = { "ldapBackend", NULL };
	const char *backendType, *backendUrl;
	bool use_sasl_external = false;

	if (!tmp_ctx) {
		return ldb_oom(ldb);
	}

	ret = ldb_register_samba_handlers(ldb);
	if (ret != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		return ret;
	}

	samba_dsdb_dn = ldb_dn_new(tmp_ctx, ldb, "@SAMBA_DSDB");
	if (!samba_dsdb_dn) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

	partition_dn = ldb_dn_new(tmp_ctx, ldb, DSDB_PARTITION_DN);
	if (!partition_dn) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}

#define CHECK_LDB_RET(check_ret)				\
	do {							\
		if (check_ret != LDB_SUCCESS) {			\
			talloc_free(tmp_ctx);			\
			return check_ret;			\
		}						\
	} while (0)

	ret = dsdb_module_search_dn(module, tmp_ctx, &res, samba_dsdb_dn,
	                            samba_dsdb_attrs, DSDB_FLAG_NEXT_MODULE, NULL);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		backendType = "ldb";
	} else if (ret == LDB_SUCCESS) {
		backendType = ldb_msg_find_attr_as_string(res->msgs[0], "backendType", "ldb");
	} else {
		talloc_free(tmp_ctx);
		return ret;
	}

	backend_modules = NULL;
	if (strcasecmp(backendType, "ldb") == 0) {
		extended_dn_module = extended_dn_module_ldb;
		link_modules = tdb_modules_list;
	} else {
		struct cli_credentials *cred;
		bool is_ldapi = false;

		ret = dsdb_module_search_dn(module, tmp_ctx, &res, partition_dn,
					    partition_attrs, DSDB_FLAG_NEXT_MODULE, NULL);
		if (ret == LDB_SUCCESS) {
			backendUrl = ldb_msg_find_attr_as_string(res->msgs[0], "ldapBackend", "ldapi://");
			if (!strncasecmp(backendUrl, "ldapi://", sizeof("ldapi://")-1)) {
				is_ldapi = true;
			}
		} else if (ret != LDB_ERR_NO_SUCH_OBJECT) {
			talloc_free(tmp_ctx);
			return ret;
		}
		if (strcasecmp(backendType, "fedora-ds") == 0) {
			link_modules = fedora_ds_modules;
			backend_modules = fedora_ds_backend_modules;
			extended_dn_module = extended_dn_module_fds;
		} else if (strcasecmp(backendType, "openldap") == 0) {
			link_modules = openldap_modules;
			backend_modules = openldap_backend_modules;
			extended_dn_module = extended_dn_module_openldap;
			extended_dn_in_module = "extended_dn_in_openldap";
			if (is_ldapi) {
				use_sasl_external = true;
			}
		} else {
			return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "invalid backend type");
		}
		ret = ldb_set_opaque(ldb, "readOnlySchema", (void*)1);
		if (ret != LDB_SUCCESS) {
			ldb_set_errstring(ldb, "Failed to set readOnlySchema opaque");
		}

		cred = ldb_get_opaque(ldb, "credentials");
		if (!cred || !cli_credentials_authentication_requested(cred)) {
			ret = set_ldap_credentials(ldb, use_sasl_external);
			if (ret != LDB_SUCCESS) {
				return ret;
			}
		}
	}

#define CHECK_MODULE_LIST \
	do {							\
		if (!final_module_list) {			\
			talloc_free(tmp_ctx);			\
			return ldb_oom(ldb);			\
		}						\
	} while (0)

	final_module_list = str_list_copy_const(tmp_ctx, modules_list1);
	CHECK_MODULE_LIST;

	final_module_list = str_list_add_const(final_module_list, extended_dn_in_module);
	CHECK_MODULE_LIST;

	final_module_list = str_list_append_const(final_module_list, modules_list1a);
	CHECK_MODULE_LIST;

	final_module_list = str_list_append_const(final_module_list, link_modules);
	CHECK_MODULE_LIST;

	final_module_list = str_list_add_const(final_module_list, extended_dn_module);
	CHECK_MODULE_LIST;

	final_module_list = str_list_append_const(final_module_list, modules_list2);
	CHECK_MODULE_LIST;


	ret = read_at_rootdse_record(ldb, module, tmp_ctx, &rootdse_msg, NULL);
	CHECK_LDB_RET(ret);

	partition_msg = ldb_msg_new(tmp_ctx);
	partition_msg->dn = ldb_dn_new(partition_msg, ldb, "@" DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME);

	ret = prepare_modules_line(ldb, tmp_ctx,
				   rootdse_msg,
				   partition_msg, "schemaNamingContext",
				   "schema_data", backend_modules);
	CHECK_LDB_RET(ret);

	ret = prepare_modules_line(ldb, tmp_ctx,
				   rootdse_msg,
				   partition_msg, NULL,
				   NULL, backend_modules);
	CHECK_LDB_RET(ret);

	ret = ldb_set_opaque(ldb, DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME, partition_msg);
	CHECK_LDB_RET(ret);

	talloc_steal(ldb, partition_msg);

	/* Now prepare the module chain.  Oddly, we must give it to ldb_load_modules_list in REVERSE */
	for (len = 0; final_module_list[len]; len++) { /* noop */};

	reverse_module_list = talloc_array(tmp_ctx, const char *, len+1);
	if (!reverse_module_list) {
		talloc_free(tmp_ctx);
		return ldb_oom(ldb);
	}
	for (i=0; i < len; i++) {
		reverse_module_list[i] = final_module_list[(len - 1) - i];
	}
	reverse_module_list[i] = NULL;

	/* The backend (at least until the partitions module
	 * reconfigures things) is the next module in the currently
	 * loaded chain */
	backend_module = ldb_module_next(module);
	ret = ldb_module_load_list(ldb, reverse_module_list, backend_module, &module_chain);
	CHECK_LDB_RET(ret);

	talloc_free(tmp_ctx);
	/* Set this as the 'next' module, so that we effectivly append it to module chain */
	ldb_module_set_next(module, module_chain);

	return ldb_next_init(module);
}
Ejemplo n.º 11
0
/*
  wrapped connection to a ldb database
  to close just talloc_free() the returned ldb_context

  TODO:  We need an error_string parameter
 */
struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
				     struct tevent_context *ev,
				     struct loadparm_context *lp_ctx,
				     const char *url,
				     struct auth_session_info *session_info,
				     struct cli_credentials *credentials,
				     unsigned int flags)
{
	struct ldb_context *ldb;
	int ret;
	char *real_url = NULL;
	struct ldb_wrap *w;
	struct ldb_wrap_context c;

	c.url          = url;
	c.ev           = ev;
	c.lp_ctx       = lp_ctx;
	c.session_info = session_info;
	c.credentials  = credentials;
	c.flags        = flags;

	/* see if we can re-use an existing ldb */
	for (w=ldb_wrap_list; w; w=w->next) {
		if (ldb_wrap_same_context(&c, &w->context)) {
			return talloc_reference(mem_ctx, w->ldb);
		}
	}

	/* we want to use the existing event context if possible. This
	   relies on the fact that in smbd, everything is a child of
	   the main event_context */
	if (ev == NULL) {
		return NULL;
	}

	ldb = ldb_init(mem_ctx, ev);
	if (ldb == NULL) {
		return NULL;
	}

	ldb_set_modules_dir(ldb,
			    talloc_asprintf(ldb,
					    "%s/ldb",
					    lp_modulesdir(lp_ctx)));

	if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
		talloc_free(ldb);
		return NULL;
	}

	if (ldb_set_opaque(ldb, "credentials", credentials)) {
		talloc_free(ldb);
		return NULL;
	}

	if (ldb_set_opaque(ldb, "loadparm", lp_ctx)) {
		talloc_free(ldb);
		return NULL;
	}

	/* This must be done before we load the schema, as these
	 * handlers for objectSid and objectGUID etc must take
	 * precedence over the 'binary attribute' declaration in the
	 * schema */
	ret = ldb_register_samba_handlers(ldb);
	if (ret == -1) {
		talloc_free(ldb);
		return NULL;
	}

	if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) {
		dsdb_set_global_schema(ldb);
	}

	ldb_set_debug(ldb, ldb_wrap_debug, NULL);

	ldb_set_utf8_fns(ldb, NULL, wrap_casefold);

	real_url = private_path(ldb, lp_ctx, url);
	if (real_url == NULL) {
		talloc_free(ldb);
		return NULL;
	}

	/* allow admins to force non-sync ldb for all databases */
	if (lp_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) {
		flags |= LDB_FLG_NOSYNC;
	}

	if (DEBUGLVL(10)) {
		flags |= LDB_FLG_ENABLE_TRACING;
	}

	/* we usually want Samba databases to be private. If we later
	   find we need one public, we will need to add a parameter to
	   ldb_wrap_connect() */
	ldb_set_create_perms(ldb, 0600);
	
	ret = ldb_connect(ldb, real_url, flags, NULL);
	if (ret != LDB_SUCCESS) {
		talloc_free(ldb);
		return NULL;
	}

	/* setup for leak detection */
	ldb_set_opaque(ldb, "wrap_url", real_url);
	
	/* add to the list of open ldb contexts */
	w = talloc(ldb, struct ldb_wrap);
	if (w == NULL) {
		talloc_free(ldb);
		return NULL;
	}

	w->context = c;
	w->context.url = talloc_strdup(w, url);
	if (w->context.url == NULL) {
		talloc_free(ldb);
		return NULL;
	}

	w->ldb = ldb;

	DLIST_ADD(ldb_wrap_list, w);

	/* make the resulting schema global */
	if (lp_ctx != NULL && strcmp(lp_sam_url(lp_ctx), url) == 0) {
		dsdb_make_schema_global(ldb);
	}

	DEBUG(3,("ldb_wrap open of %s\n", url));

	talloc_set_destructor(w, ldb_wrap_destructor);

	return ldb;
}
Ejemplo n.º 12
0
/**
  process command line options
*/
struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, 
					int argc, const char **argv,
					void (*usage)(void))
{
	struct ldb_cmdline *ret=NULL;
	poptContext pc;
#if (_SAMBA_BUILD_ >= 4)
	int r;
#endif
	int num_options = 0;
	int opt;
	int flags = 0;

#if (_SAMBA_BUILD_ >= 4)
	r = ldb_register_samba_handlers(ldb);
	if (r != 0) {
		goto failed;
	}

#endif

	/* make the ldb utilities line buffered */
	setlinebuf(stdout);

	ret = talloc_zero(ldb, struct ldb_cmdline);
	if (ret == NULL) {
		fprintf(stderr, "Out of memory!\n");
		goto failed;
	}

	options = *ret;
	
	/* pull in URL */
	options.url = getenv("LDB_URL");

	/* and editor (used by ldbedit) */
	options.editor = getenv("VISUAL");
	if (!options.editor) {
		options.editor = getenv("EDITOR");
	}
	if (!options.editor) {
		options.editor = "vi";
	}

	options.scope = LDB_SCOPE_DEFAULT;

	pc = poptGetContext(argv[0], argc, argv, popt_options, 
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case 's': {
			const char *arg = poptGetOptArg(pc);
			if (strcmp(arg, "base") == 0) {
				options.scope = LDB_SCOPE_BASE;
			} else if (strcmp(arg, "sub") == 0) {
				options.scope = LDB_SCOPE_SUBTREE;
			} else if (strcmp(arg, "one") == 0) {
				options.scope = LDB_SCOPE_ONELEVEL;
			} else {
				fprintf(stderr, "Invalid scope '%s'\n", arg);
				goto failed;
			}
			break;
		}

		case 'v':
			options.verbose++;
			break;

		case 'o':
			options.options = talloc_realloc(ret, options.options, 
							 const char *, num_options+3);
			if (options.options == NULL) {
				fprintf(stderr, "Out of memory!\n");
				goto failed;
			}
			options.options[num_options] = poptGetOptArg(pc);
			options.options[num_options+1] = NULL;
			num_options++;
			break;

		case 'c': {
			const char *cs = poptGetOptArg(pc);
			const char *p;

			for (p = cs; p != NULL; ) {
				const char *t, *c;

				t = strchr(p, ',');
				if (t == NULL) {
					c = talloc_strdup(options.controls, p);
					p = NULL;
				} else {
					c = talloc_strndup(options.controls, p, t-p);
			        	p = t + 1;
				}
				if (c == NULL || !add_control(ret, c)) {
					fprintf(stderr, __location__ ": out of memory\n");
					goto failed;
				}
			}

			break;	  
		}
		case 'P':
			if (!add_control(ret, "paged_results:1:1024")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'D':
			if (!add_control(ret, "show_deleted:1")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'R':
			if (!add_control(ret, "show_recycled:0")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'd':
			if (!add_control(ret, "show_deactivated_link:0")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'r':
			if (!add_control(ret, "reveal_internals:0")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'N':
			if (!add_control(ret, "search_options:1:2")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		case 'E':
			if (!add_control(ret, "extended_dn:1:1")) {
				fprintf(stderr, __location__ ": out of memory\n");
				goto failed;
			}
			break;
		default:
			fprintf(stderr, "Invalid option %s: %s\n", 
				poptBadOption(pc, 0), poptStrerror(opt));
			if (usage) usage();
			goto failed;
		}
	}

	/* setup the remaining options for the main program to use */
	options.argv = poptGetArgs(pc);
	if (options.argv) {
		options.argv++;
		while (options.argv[options.argc]) options.argc++;
	}

	*ret = options;

	/* all utils need some option */
	if (ret->url == NULL) {
		fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n");
		if (usage) usage();
		goto failed;
	}

	if (strcmp(ret->url, "NONE") == 0) {
		return ret;
	}

	if (options.nosync) {
		flags |= LDB_FLG_NOSYNC;
	}

	if (options.show_binary) {
		flags |= LDB_FLG_SHOW_BINARY;
	}

	if (options.tracing) {
		flags |= LDB_FLG_ENABLE_TRACING;
	}

#if (_SAMBA_BUILD_ >= 4)
	/* Must be after we have processed command line options */
	gensec_init(cmdline_lp_ctx); 
	
	if (ldb_set_opaque(ldb, "sessionInfo", system_session(cmdline_lp_ctx))) {
		goto failed;
	}
	if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {
		goto failed;
	}
	if (ldb_set_opaque(ldb, "loadparm", cmdline_lp_ctx)) {
		goto failed;
	}

	ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
#endif

	if (options.modules_path != NULL) {
		ldb_set_modules_dir(ldb, options.modules_path);
	} else if (getenv("LDB_MODULES_PATH") != NULL) {
		ldb_set_modules_dir(ldb, getenv("LDB_MODULES_PATH"));
	}

	/* now connect to the ldb */
	if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) {
		fprintf(stderr, "Failed to connect to %s - %s\n", 
			ret->url, ldb_errstring(ldb));
		goto failed;
	}

	return ret;

failed:
	talloc_free(ret);
	exit(1);
	return NULL;
}