static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
				    const char *exp_fmt, ...)
{
	struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
		m->private_data, struct pdb_samba_dsdb_state);
	const char *attrs[] = { "objectClass", "objectSid", "description", "samAccountName", "groupType",
				NULL };
	struct ldb_message *msg;
	va_list ap;
	char *expression = NULL;
	struct dom_sid *sid;
	const char *str;
	int rc;
	struct id_map id_map;
	struct id_map *id_maps[2];
	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	va_start(ap, exp_fmt);
	expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
	va_end(ap);

	if (!expression) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
	if (rc == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_SUCH_GROUP;
	} else if (rc != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("dsdb_search_one failed %s\n",
			   ldb_errstring(state->ldb)));
		return NT_STATUS_LDAP(rc);
	}

	sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
	if (!sid) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("Could not pull SID\n"));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	map->sid = *sid;

	if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
		NTSTATUS status;
		uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
		switch (grouptype) {
		case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
		case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
			map->sid_name_use = SID_NAME_ALIAS;
			break;
		case GTYPE_SECURITY_GLOBAL_GROUP:
			map->sid_name_use = SID_NAME_DOM_GRP;
			break;
		default:
			talloc_free(tmp_ctx);
			DEBUG(10, ("Could not pull groupType\n"));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}

		ZERO_STRUCT(id_map);
		id_map.sid = sid;
		id_maps[0] = &id_map;
		id_maps[1] = NULL;

		status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);

		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(tmp_ctx);
			return status;
		}
		if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
			map->gid = id_map.xid.id;
		} else {
			DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
			talloc_free(tmp_ctx);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	} else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
		DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	str = ldb_msg_find_attr_as_string(msg, "samAccountName",
					  NULL);
	if (str == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}
	map->nt_name = talloc_strdup(map, str);
	if (!map->nt_name) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	str = ldb_msg_find_attr_as_string(msg, "description",
					    NULL);
	if (str != NULL) {
		map->comment = talloc_strdup(map, str);
	} else {
		map->comment = talloc_strdup(map, "");
	}
	if (!map->comment) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}
static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
				    const char *exp_fmt, ...)
{
	struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
		m->private_data, struct pdb_samba_dsdb_state);
	const char *attrs[] = { "objectClass", "objectSid", "description", "samAccountName", "groupType",
				NULL };
	struct ldb_message *msg;
	va_list ap;
	char *expression = NULL;
	struct dom_sid *sid;
	const char *str;
	int rc;
	struct id_map id_map;
	struct id_map *id_maps[2];
	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	va_start(ap, exp_fmt);
	expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
	va_end(ap);

	if (!expression) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
	if (rc == LDB_ERR_NO_SUCH_OBJECT) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_SUCH_GROUP;
	} else if (rc != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("dsdb_search_one failed %s\n",
			   ldb_errstring(state->ldb)));
		return NT_STATUS_LDAP(rc);
	}

	sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
	if (!sid) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("Could not pull SID\n"));
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	map->sid = *sid;

	if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
		NTSTATUS status;
		uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
		switch (grouptype) {
		case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
		case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
			map->sid_name_use = SID_NAME_ALIAS;
			break;
		case GTYPE_SECURITY_GLOBAL_GROUP:
			map->sid_name_use = SID_NAME_DOM_GRP;
			break;
		default:
			talloc_free(tmp_ctx);
			DEBUG(10, ("Could not pull groupType\n"));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}

		ZERO_STRUCT(id_map);
		id_map.sid = sid;
		id_maps[0] = &id_map;
		id_maps[1] = NULL;

		status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);

		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(tmp_ctx);
			return status;
		}
		if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
			map->gid = id_map.xid.id;
		} else {
			DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
			talloc_free(tmp_ctx);
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	} else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
		DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	str = ldb_msg_find_attr_as_string(msg, "samAccountName",
					  NULL);
	if (str == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}
	map->nt_name = talloc_strdup(map, str);
	if (!map->nt_name) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	str = ldb_msg_find_attr_as_string(msg, "description",
					    NULL);
	if (str != NULL) {
		map->comment = talloc_strdup(map, str);
	} else {
		map->comment = talloc_strdup(map, "");
	}
	if (!map->comment) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	talloc_free(tmp_ctx);
	return NT_STATUS_OK;
}