summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2009-02-24 11:40:18 +0100
committerStefan Metzmacher <metze@samba.org>2009-02-24 17:55:37 +0100
commit12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2 (patch)
tree5085b6257d2ca2608533501ee1060d10f634c4da /source4
parentd1922725c66c9f4de25c1d664ae03c90e6c098fb (diff)
downloadsamba-12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2.tar.gz
samba-12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2.tar.bz2
samba-12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2.zip
s4:libcli: split out LIBCLI_LDAP_MESSAGE subsystem
metze
Diffstat (limited to 'source4')
-rw-r--r--source4/headermap.txt1
-rw-r--r--source4/libcli/ldap/config.mk21
-rw-r--r--source4/libcli/ldap/ldap.h191
-rw-r--r--source4/libcli/ldap/ldap_message.c (renamed from source4/libcli/ldap/ldap.c)63
-rw-r--r--source4/libcli/ldap/ldap_message.h225
-rw-r--r--source4/libcli/ldap/ldap_msg.c87
6 files changed, 301 insertions, 287 deletions
diff --git a/source4/headermap.txt b/source4/headermap.txt
index 8f3749a3b5..8a968315bf 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -49,6 +49,7 @@ param/share.h: share.h
../lib/util/util_tdb.h: util_tdb.h
../lib/util/util_ldb.h: util_ldb.h
../lib/util/wrap_xattr.h: wrap_xattr.h
+libcli/ldap/ldap_message.h: ldap_message.h
libcli/ldap/ldap_ndr.h: ldap_ndr.h
../lib/tevent/tevent.h: tevent.h
../lib/tevent/tevent_internal.h: tevent_internal.h
diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk
index 2708c66b68..a0e178ac40 100644
--- a/source4/libcli/ldap/config.mk
+++ b/source4/libcli/ldap/config.mk
@@ -1,14 +1,20 @@
+[SUBSYSTEM::LIBCLI_LDAP_MESSAGE]
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB
+PRIVATE_DEPENDENCIES = ASN1_UTIL
+
+LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \
+ ldap_message.o)
+PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h
+
[SUBSYSTEM::LIBCLI_LDAP]
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET
-PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \
- LDAP_ENCODE LIBNDR LP_RESOLVE gensec
+PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \
+ LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE
LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \
- ldap.o ldap_client.o ldap_bind.o \
- ldap_msg.o ldap_ildap.o ldap_controls.o)
-
-
-PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h
+ ldap_client.o ldap_bind.o \
+ ldap_ildap.o ldap_controls.o)
+PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h
$(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c)))
@@ -16,3 +22,4 @@ $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_L
PRIVATE_DEPENDENCIES = LIBLDB
LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o
+PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h
diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h
index 3d99d6f47d..a642e671e6 100644
--- a/source4/libcli/ldap/ldap.h
+++ b/source4/libcli/ldap/ldap.h
@@ -21,200 +21,11 @@
#ifndef _SMB_LDAP_H_
#define _SMB_LDAP_H_
-#include "libcli/ldap/ldap_errors.h"
-#include "lib/ldb/include/ldb.h"
+#include "libcli/ldap/ldap_message.h"
#include "librpc/gen_ndr/misc.h"
-enum ldap_request_tag {
- LDAP_TAG_BindRequest = 0,
- LDAP_TAG_BindResponse = 1,
- LDAP_TAG_UnbindRequest = 2,
- LDAP_TAG_SearchRequest = 3,
- LDAP_TAG_SearchResultEntry = 4,
- LDAP_TAG_SearchResultDone = 5,
- LDAP_TAG_ModifyRequest = 6,
- LDAP_TAG_ModifyResponse = 7,
- LDAP_TAG_AddRequest = 8,
- LDAP_TAG_AddResponse = 9,
- LDAP_TAG_DelRequest = 10,
- LDAP_TAG_DelResponse = 11,
- LDAP_TAG_ModifyDNRequest = 12,
- LDAP_TAG_ModifyDNResponse = 13,
- LDAP_TAG_CompareRequest = 14,
- LDAP_TAG_CompareResponse = 15,
- LDAP_TAG_AbandonRequest = 16,
- LDAP_TAG_SearchResultReference = 19,
- LDAP_TAG_ExtendedRequest = 23,
- LDAP_TAG_ExtendedResponse = 24
-};
-
-enum ldap_auth_mechanism {
- LDAP_AUTH_MECH_SIMPLE = 0,
- LDAP_AUTH_MECH_SASL = 3
-};
-
-struct ldap_Result {
- int resultcode;
- const char *dn;
- const char *errormessage;
- const char *referral;
-};
-
-struct ldap_BindRequest {
- int version;
- const char *dn;
- enum ldap_auth_mechanism mechanism;
- union {
- const char *password;
- struct {
- const char *mechanism;
- DATA_BLOB *secblob;/* optional */
- } SASL;
- } creds;
-};
-
-struct ldap_BindResponse {
- struct ldap_Result response;
- union {
- DATA_BLOB *secblob;/* optional */
- } SASL;
-};
-
-struct ldap_UnbindRequest {
- uint8_t __dummy;
-};
-
-enum ldap_scope {
- LDAP_SEARCH_SCOPE_BASE = 0,
- LDAP_SEARCH_SCOPE_SINGLE = 1,
- LDAP_SEARCH_SCOPE_SUB = 2
-};
-
-enum ldap_deref {
- LDAP_DEREFERENCE_NEVER = 0,
- LDAP_DEREFERENCE_IN_SEARCHING = 1,
- LDAP_DEREFERENCE_FINDING_BASE = 2,
- LDAP_DEREFERENCE_ALWAYS
-};
-
-struct ldap_SearchRequest {
- const char *basedn;
- enum ldap_scope scope;
- enum ldap_deref deref;
- uint32_t timelimit;
- uint32_t sizelimit;
- bool attributesonly;
- struct ldb_parse_tree *tree;
- int num_attributes;
- const char * const *attributes;
-};
-
-struct ldap_SearchResEntry {
- const char *dn;
- int num_attributes;
- struct ldb_message_element *attributes;
-};
-
-struct ldap_SearchResRef {
- const char *referral;
-};
-
-enum ldap_modify_type {
- LDAP_MODIFY_NONE = -1,
- LDAP_MODIFY_ADD = 0,
- LDAP_MODIFY_DELETE = 1,
- LDAP_MODIFY_REPLACE = 2
-};
-
-struct ldap_mod {
- enum ldap_modify_type type;
- struct ldb_message_element attrib;
-};
-
-struct ldap_ModifyRequest {
- const char *dn;
- int num_mods;
- struct ldap_mod *mods;
-};
-
-struct ldap_AddRequest {
- const char *dn;
- int num_attributes;
- struct ldb_message_element *attributes;
-};
-
-struct ldap_DelRequest {
- const char *dn;
-};
-
-struct ldap_ModifyDNRequest {
- const char *dn;
- const char *newrdn;
- bool deleteolddn;
- const char *newsuperior;/* optional */
-};
-
-struct ldap_CompareRequest {
- const char *dn;
- const char *attribute;
- DATA_BLOB value;
-};
-
-struct ldap_AbandonRequest {
- uint32_t messageid;
-};
-
-struct ldap_ExtendedRequest {
- const char *oid;
- DATA_BLOB *value;/* optional */
-};
-
-struct ldap_ExtendedResponse {
- struct ldap_Result response;
- const char *oid;/* optional */
- DATA_BLOB *value;/* optional */
-};
-
-union ldap_Request {
- struct ldap_Result GeneralResult;
- struct ldap_BindRequest BindRequest;
- struct ldap_BindResponse BindResponse;
- struct ldap_UnbindRequest UnbindRequest;
- struct ldap_SearchRequest SearchRequest;
- struct ldap_SearchResEntry SearchResultEntry;
- struct ldap_Result SearchResultDone;
- struct ldap_SearchResRef SearchResultReference;
- struct ldap_ModifyRequest ModifyRequest;
- struct ldap_Result ModifyResponse;
- struct ldap_AddRequest AddRequest;
- struct ldap_Result AddResponse;
- struct ldap_DelRequest DelRequest;
- struct ldap_Result DelResponse;
- struct ldap_ModifyDNRequest ModifyDNRequest;
- struct ldap_Result ModifyDNResponse;
- struct ldap_CompareRequest CompareRequest;
- struct ldap_Result CompareResponse;
- struct ldap_AbandonRequest AbandonRequest;
- struct ldap_ExtendedRequest ExtendedRequest;
- struct ldap_ExtendedResponse ExtendedResponse;
-};
-
-
-struct ldap_message {
- int messageid;
- enum ldap_request_tag type;
- union ldap_Request r;
- struct ldb_control **controls;
- bool *controls_decoded;
-};
-
struct tevent_context;
struct cli_credentials;
struct dom_sid;
-struct asn1_data;
-
-struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx);
-NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg);
-bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx);
#endif
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap_message.c
index 7a65cc5c27..07362fa685 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap_message.c
@@ -27,6 +27,63 @@
#include "libcli/ldap/ldap.h"
#include "libcli/ldap/ldap_proto.h"
+_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
+{
+ return talloc_zero(mem_ctx, struct ldap_message);
+}
+
+
+static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
+ struct ldb_message_element *attrib)
+{
+ attrib->values = talloc_realloc(mem_ctx,
+ attrib->values,
+ DATA_BLOB,
+ attrib->num_values+1);
+ if (attrib->values == NULL)
+ return false;
+
+ attrib->values[attrib->num_values].data = talloc_steal(attrib->values,
+ value->data);
+ attrib->values[attrib->num_values].length = value->length;
+ attrib->num_values += 1;
+ return true;
+}
+
+static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx,
+ const struct ldb_message_element *attrib,
+ struct ldb_message_element **attribs,
+ int *num_attribs)
+{
+ *attribs = talloc_realloc(mem_ctx,
+ *attribs,
+ struct ldb_message_element,
+ *num_attribs+1);
+
+ if (*attribs == NULL)
+ return false;
+
+ (*attribs)[*num_attribs] = *attrib;
+ talloc_steal(*attribs, attrib->values);
+ talloc_steal(*attribs, attrib->name);
+ *num_attribs += 1;
+ return true;
+}
+
+static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx,
+ struct ldap_mod *mod,
+ struct ldap_mod **mods,
+ int *num_mods)
+{
+ *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1);
+
+ if (*mods == NULL)
+ return false;
+
+ (*mods)[*num_mods] = *mod;
+ *num_mods += 1;
+ return true;
+}
static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree)
{
@@ -926,9 +983,9 @@ void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
}
/* Decode a set of LDAP attributes, as found in a search entry */
-void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
- struct ldb_message_element **attributes,
- int *num_attributes)
+static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes)
{
asn1_start_tag(data, ASN1_SEQUENCE(0));
ldap_decode_attribs_bare(mem_ctx, data,
diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h
new file mode 100644
index 0000000000..47ee724e97
--- /dev/null
+++ b/source4/libcli/ldap/ldap_message.h
@@ -0,0 +1,225 @@
+/*
+ Unix SMB/CIFS Implementation.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Volker Lendecke 2004
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef _LIBCLI_LDAP_MESSAGE_H_
+#define _LIBCLI_LDAP_MESSAGE_H_
+
+#include "libcli/ldap/ldap_errors.h"
+#include "lib/ldb/include/ldb.h"
+
+enum ldap_request_tag {
+ LDAP_TAG_BindRequest = 0,
+ LDAP_TAG_BindResponse = 1,
+ LDAP_TAG_UnbindRequest = 2,
+ LDAP_TAG_SearchRequest = 3,
+ LDAP_TAG_SearchResultEntry = 4,
+ LDAP_TAG_SearchResultDone = 5,
+ LDAP_TAG_ModifyRequest = 6,
+ LDAP_TAG_ModifyResponse = 7,
+ LDAP_TAG_AddRequest = 8,
+ LDAP_TAG_AddResponse = 9,
+ LDAP_TAG_DelRequest = 10,
+ LDAP_TAG_DelResponse = 11,
+ LDAP_TAG_ModifyDNRequest = 12,
+ LDAP_TAG_ModifyDNResponse = 13,
+ LDAP_TAG_CompareRequest = 14,
+ LDAP_TAG_CompareResponse = 15,
+ LDAP_TAG_AbandonRequest = 16,
+ LDAP_TAG_SearchResultReference = 19,
+ LDAP_TAG_ExtendedRequest = 23,
+ LDAP_TAG_ExtendedResponse = 24
+};
+
+enum ldap_auth_mechanism {
+ LDAP_AUTH_MECH_SIMPLE = 0,
+ LDAP_AUTH_MECH_SASL = 3
+};
+
+struct ldap_Result {
+ int resultcode;
+ const char *dn;
+ const char *errormessage;
+ const char *referral;
+};
+
+struct ldap_BindRequest {
+ int version;
+ const char *dn;
+ enum ldap_auth_mechanism mechanism;
+ union {
+ const char *password;
+ struct {
+ const char *mechanism;
+ DATA_BLOB *secblob;/* optional */
+ } SASL;
+ } creds;
+};
+
+struct ldap_BindResponse {
+ struct ldap_Result response;
+ union {
+ DATA_BLOB *secblob;/* optional */
+ } SASL;
+};
+
+struct ldap_UnbindRequest {
+ uint8_t __dummy;
+};
+
+enum ldap_scope {
+ LDAP_SEARCH_SCOPE_BASE = 0,
+ LDAP_SEARCH_SCOPE_SINGLE = 1,
+ LDAP_SEARCH_SCOPE_SUB = 2
+};
+
+enum ldap_deref {
+ LDAP_DEREFERENCE_NEVER = 0,
+ LDAP_DEREFERENCE_IN_SEARCHING = 1,
+ LDAP_DEREFERENCE_FINDING_BASE = 2,
+ LDAP_DEREFERENCE_ALWAYS
+};
+
+struct ldap_SearchRequest {
+ const char *basedn;
+ enum ldap_scope scope;
+ enum ldap_deref deref;
+ uint32_t timelimit;
+ uint32_t sizelimit;
+ bool attributesonly;
+ struct ldb_parse_tree *tree;
+ int num_attributes;
+ const char * const *attributes;
+};
+
+struct ldap_SearchResEntry {
+ const char *dn;
+ int num_attributes;
+ struct ldb_message_element *attributes;
+};
+
+struct ldap_SearchResRef {
+ const char *referral;
+};
+
+enum ldap_modify_type {
+ LDAP_MODIFY_NONE = -1,
+ LDAP_MODIFY_ADD = 0,
+ LDAP_MODIFY_DELETE = 1,
+ LDAP_MODIFY_REPLACE = 2
+};
+
+struct ldap_mod {
+ enum ldap_modify_type type;
+ struct ldb_message_element attrib;
+};
+
+struct ldap_ModifyRequest {
+ const char *dn;
+ int num_mods;
+ struct ldap_mod *mods;
+};
+
+struct ldap_AddRequest {
+ const char *dn;
+ int num_attributes;
+ struct ldb_message_element *attributes;
+};
+
+struct ldap_DelRequest {
+ const char *dn;
+};
+
+struct ldap_ModifyDNRequest {
+ const char *dn;
+ const char *newrdn;
+ bool deleteolddn;
+ const char *newsuperior;/* optional */
+};
+
+struct ldap_CompareRequest {
+ const char *dn;
+ const char *attribute;
+ DATA_BLOB value;
+};
+
+struct ldap_AbandonRequest {
+ uint32_t messageid;
+};
+
+struct ldap_ExtendedRequest {
+ const char *oid;
+ DATA_BLOB *value;/* optional */
+};
+
+struct ldap_ExtendedResponse {
+ struct ldap_Result response;
+ const char *oid;/* optional */
+ DATA_BLOB *value;/* optional */
+};
+
+union ldap_Request {
+ struct ldap_Result GeneralResult;
+ struct ldap_BindRequest BindRequest;
+ struct ldap_BindResponse BindResponse;
+ struct ldap_UnbindRequest UnbindRequest;
+ struct ldap_SearchRequest SearchRequest;
+ struct ldap_SearchResEntry SearchResultEntry;
+ struct ldap_Result SearchResultDone;
+ struct ldap_SearchResRef SearchResultReference;
+ struct ldap_ModifyRequest ModifyRequest;
+ struct ldap_Result ModifyResponse;
+ struct ldap_AddRequest AddRequest;
+ struct ldap_Result AddResponse;
+ struct ldap_DelRequest DelRequest;
+ struct ldap_Result DelResponse;
+ struct ldap_ModifyDNRequest ModifyDNRequest;
+ struct ldap_Result ModifyDNResponse;
+ struct ldap_CompareRequest CompareRequest;
+ struct ldap_Result CompareResponse;
+ struct ldap_AbandonRequest AbandonRequest;
+ struct ldap_ExtendedRequest ExtendedRequest;
+ struct ldap_ExtendedResponse ExtendedResponse;
+};
+
+
+struct ldap_message {
+ int messageid;
+ enum ldap_request_tag type;
+ union ldap_Request r;
+ struct ldb_control **controls;
+ bool *controls_decoded;
+};
+
+struct asn1_data;
+
+struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx);
+NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg);
+bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx);
+NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size);
+
+bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
+ struct asn1_data *data,
+ const char **result);
+
+void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
+ struct ldb_message_element **attributes,
+ int *num_attributes);
+
+#endif
diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c
deleted file mode 100644
index e45213c004..0000000000
--- a/source4/libcli/ldap/ldap_msg.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Unix SMB/CIFS mplementation.
-
- LDAP protocol helper functions for SAMBA
-
- Copyright (C) Andrew Tridgell 2005
- Copyright (C) Volker Lendecke 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "includes.h"
-#include "libcli/ldap/ldap.h"
-#include "libcli/ldap/ldap_client.h"
-#include "libcli/ldap/ldap_proto.h"
-
-
-_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
-{
- return talloc_zero(mem_ctx, struct ldap_message);
-}
-
-
-bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
- struct ldb_message_element *attrib)
-{
- attrib->values = talloc_realloc(mem_ctx,
- attrib->values,
- DATA_BLOB,
- attrib->num_values+1);
- if (attrib->values == NULL)
- return false;
-
- attrib->values[attrib->num_values].data = talloc_steal(attrib->values,
- value->data);
- attrib->values[attrib->num_values].length = value->length;
- attrib->num_values += 1;
- return true;
-}
-
-bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx,
- const struct ldb_message_element *attrib,
- struct ldb_message_element **attribs,
- int *num_attribs)
-{
- *attribs = talloc_realloc(mem_ctx,
- *attribs,
- struct ldb_message_element,
- *num_attribs+1);
-
- if (*attribs == NULL)
- return false;
-
- (*attribs)[*num_attribs] = *attrib;
- talloc_steal(*attribs, attrib->values);
- talloc_steal(*attribs, attrib->name);
- *num_attribs += 1;
- return true;
-}
-
-bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx,
- struct ldap_mod *mod,
- struct ldap_mod **mods,
- int *num_mods)
-{
- *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1);
-
- if (*mods == NULL)
- return false;
-
- (*mods)[*num_mods] = *mod;
- *num_mods += 1;
- return true;
-}
-