summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-10-30 08:32:26 +0000
committerAndrew Tridgell <tridge@samba.org>2003-10-30 08:32:26 +0000
commit7fd381376f88ae99a4bf022d89f21ae497b48c1a (patch)
tree82faf5b1e26e2676c85d17d3f34336f58f21db64 /source4/libcli
parent4e3ca10b13b03b01fda2233b88c827019a69bfee (diff)
downloadsamba-7fd381376f88ae99a4bf022d89f21ae497b48c1a.tar.gz
samba-7fd381376f88ae99a4bf022d89f21ae497b48c1a.tar.bz2
samba-7fd381376f88ae99a4bf022d89f21ae497b48c1a.zip
- a few portability fixes from Jim Myers
- added SMBD_LISTEN_BACKLOG in local.h - added the beginnings of a ndr/rpc parsing framework for Samba4. It currently correctly parses security descriptors for the nttrans QUERY_SECDESC call, but I hope it will become a reasonable framework that an idl based generator can work to (This used to be commit 9bf904fc34f88e0581f93656e73d3c01ca96f761)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/raw/rawacl.c97
-rw-r--r--source4/libcli/rpc/librpc.h71
-rw-r--r--source4/libcli/rpc/rpc_basic.c97
-rw-r--r--source4/libcli/rpc/rpc_sec.c179
-rw-r--r--source4/libcli/rpc/rpc_sec.h81
-rw-r--r--source4/libcli/rpc/rpcparse.c105
6 files changed, 630 insertions, 0 deletions
diff --git a/source4/libcli/raw/rawacl.c b/source4/libcli/raw/rawacl.c
new file mode 100644
index 0000000000..4cd3338ec5
--- /dev/null
+++ b/source4/libcli/raw/rawacl.c
@@ -0,0 +1,97 @@
+/*
+ Unix SMB/CIFS implementation.
+ ACL get/set operations
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+fetch file ACL (async send)
+****************************************************************************/
+struct cli_request *smb_raw_query_secdesc_send(struct cli_tree *tree,
+ struct smb_query_secdesc *query)
+{
+ struct smb_nttrans nt;
+ uint8 params[8];
+
+ nt.in.max_setup = 0;
+ nt.in.max_param = 4;
+ nt.in.max_data = 0x10000;
+ nt.in.setup_count = 0;
+ nt.in.function = NT_TRANSACT_QUERY_SECURITY_DESC;
+ nt.in.setup = NULL;
+
+ SSVAL(params, 0, query->in.fnum);
+ SSVAL(params, 2, 0); /* padding */
+ SIVAL(params, 4, query->in.secinfo_flags);
+
+ nt.in.params.data = params;
+ nt.in.params.length = 8;
+
+ nt.in.data = data_blob(NULL, 0);
+
+ return smb_raw_nttrans_send(tree, &nt);
+}
+
+
+/****************************************************************************
+fetch file ACL (async recv)
+****************************************************************************/
+NTSTATUS smb_raw_query_secdesc_recv(struct cli_request *req,
+ TALLOC_CTX *mem_ctx,
+ struct smb_query_secdesc *query)
+{
+ NTSTATUS status;
+ struct smb_nttrans nt;
+ struct ndr_parse *rpc;
+
+ status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* check that the basics are valid */
+ if (nt.out.params.length != 4 ||
+ IVAL(nt.out.params.data, 0) > nt.out.data.length) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ nt.out.data.length = IVAL(nt.out.params.data, 0);
+
+ rpc = ndr_parse_init_blob(&nt.out.data, mem_ctx);
+ if (!rpc) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = ndr_parse_security_descriptor(rpc, &query->out.sd);
+
+ return NT_STATUS_OK;
+}
+
+
+/****************************************************************************
+fetch file ACL (sync interface)
+****************************************************************************/
+NTSTATUS smb_raw_query_secdesc(struct cli_tree *tree,
+ TALLOC_CTX *mem_ctx,
+ struct smb_query_secdesc *query)
+{
+ struct cli_request *req = smb_raw_query_secdesc_send(tree, query);
+ return smb_raw_query_secdesc_recv(req, mem_ctx, query);
+}
+
diff --git a/source4/libcli/rpc/librpc.h b/source4/libcli/rpc/librpc.h
new file mode 100644
index 0000000000..f4f7101c90
--- /dev/null
+++ b/source4/libcli/rpc/librpc.h
@@ -0,0 +1,71 @@
+/*
+ Unix SMB/CIFS implementation.
+ rpc interface definitions
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ this provides definitions for the libcli/rpc/ MSRPC library
+*/
+
+
+/* this is the base structure passed to routines that
+ parse MSRPC formatted data
+
+ note that in Samba4 we use separate routines and structures for
+ MSRPC marshalling and unmarshalling. Also note that these routines
+ are being kept deliberately very simple, and are not tied to a
+ particular transport
+*/
+struct ndr_parse {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ char *data;
+ uint32 data_size;
+ uint32 offset;
+ TALLOC_CTX *mem_ctx;
+};
+
+struct ndr_parse_save {
+ uint32 data_size;
+ uint32 offset;
+};
+
+#define LIBNDR_FLAG_BIGENDIAN 1
+
+
+/* these are used to make the error checking on each element in libndr
+ less tedious, hopefully making the code more readable */
+#define NDR_CHECK(call) do { NTSTATUS _status; \
+ _status = call; \
+ if (!NT_STATUS_IS_OK(_status)) \
+ return _status; \
+ } while (0)
+
+
+#define NDR_ALLOC(ndr, s) do { \
+ (s) = talloc(ndr->mem_ctx, sizeof(*(s))); \
+ if (!(s)) return NT_STATUS_NO_MEMORY; \
+ } while (0)
+
+#define NDR_ALLOC_N(ndr, s, n) do { \
+ if ((n) == 0) { \
+ (s) = NULL; \
+ } else { \
+ (s) = talloc(ndr->mem_ctx, (n) * sizeof(*(s))); \
+ if (!(s)) return NT_STATUS_NO_MEMORY; \
+ } \
+ } while (0)
diff --git a/source4/libcli/rpc/rpc_basic.c b/source4/libcli/rpc/rpc_basic.c
new file mode 100644
index 0000000000..5ff17f9d99
--- /dev/null
+++ b/source4/libcli/rpc/rpc_basic.c
@@ -0,0 +1,97 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling basic types
+
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+#define NDR_NEED_BYTES(ndr, n) do { \
+ if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \
+ return NT_STATUS_BUFFER_TOO_SMALL; \
+ } \
+} while(0)
+
+#define NDR_ALIGN(ndr, n) do { \
+ ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
+ if (ndr->offset >= ndr->data_size) { \
+ return NT_STATUS_BUFFER_TOO_SMALL; \
+ } \
+} while(0)
+
+/*
+ parse a GUID
+*/
+NTSTATUS ndr_parse_guid(struct ndr_parse *ndr, GUID *guid)
+{
+ int i;
+ NDR_NEED_BYTES(ndr, GUID_SIZE);
+ for (i=0;i<GUID_SIZE;i++) {
+ guid->info[i] = CVAL(ndr->data, ndr->offset + i);
+ }
+ ndr->offset += i;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a u8
+*/
+NTSTATUS ndr_parse_u8(struct ndr_parse *ndr, uint8 *v)
+{
+ NDR_NEED_BYTES(ndr, 1);
+ *v = CVAL(ndr->data, ndr->offset);
+ ndr->offset += 1;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a u16
+*/
+NTSTATUS ndr_parse_u16(struct ndr_parse *ndr, uint16 *v)
+{
+ NDR_ALIGN(ndr, 2);
+ NDR_NEED_BYTES(ndr, 2);
+ if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
+ *v = RSVAL(ndr->data, ndr->offset);
+ } else {
+ *v = SVAL(ndr->data, ndr->offset);
+ }
+ ndr->offset += 2;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a u32
+*/
+NTSTATUS ndr_parse_u32(struct ndr_parse *ndr, uint32 *v)
+{
+ NDR_ALIGN(ndr, 4);
+ NDR_NEED_BYTES(ndr, 4);
+ if (ndr->flags & LIBNDR_FLAG_BIGENDIAN) {
+ *v = RIVAL(ndr->data, ndr->offset);
+ } else {
+ *v = IVAL(ndr->data, ndr->offset);
+ }
+ ndr->offset += 2;
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/libcli/rpc/rpc_sec.c b/source4/libcli/rpc/rpc_sec.c
new file mode 100644
index 0000000000..49b50c758c
--- /dev/null
+++ b/source4/libcli/rpc/rpc_sec.c
@@ -0,0 +1,179 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling security descriptors
+ and related structures
+
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "includes.h"
+
+/*
+ parse a security_ace
+*/
+NTSTATUS ndr_parse_security_ace(struct ndr_parse *ndr, struct security_ace *ace)
+{
+ uint16 size;
+ struct ndr_parse_save save;
+
+ ndr_parse_save(ndr, &save);
+
+ NDR_CHECK(ndr_parse_u8(ndr, &ace->type));
+ NDR_CHECK(ndr_parse_u8(ndr, &ace->flags));
+ NDR_CHECK(ndr_parse_u16(ndr, &size));
+ NDR_CHECK(ndr_parse_limit_size(ndr, size, 4));
+
+ NDR_CHECK(ndr_parse_u32(ndr, &ace->access_mask));
+
+ if (sec_ace_object(ace->type)) {
+ NDR_ALLOC(ndr, ace->obj);
+ NDR_CHECK(ndr_parse_u32(ndr, &ace->obj->flags));
+ if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) {
+ NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->object_guid));
+ }
+ if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
+ NDR_CHECK(ndr_parse_guid(ndr, &ace->obj->inherit_guid));
+ }
+ }
+
+
+ NDR_CHECK(ndr_parse_dom_sid(ndr, &ace->trustee));
+
+ ndr_parse_restore(ndr, &save);
+ NDR_CHECK(ndr_parse_advance(ndr, size));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security_acl
+*/
+NTSTATUS ndr_parse_security_acl(struct ndr_parse *ndr, struct security_acl *acl)
+{
+ int i;
+ uint16 size;
+ struct ndr_parse_save save;
+
+ ndr_parse_save(ndr, &save);
+
+ NDR_CHECK(ndr_parse_u16(ndr, &acl->revision));
+ NDR_CHECK(ndr_parse_u16(ndr, &size));
+ NDR_CHECK(ndr_parse_limit_size(ndr, size, 4));
+ NDR_CHECK(ndr_parse_u32(ndr, &acl->num_aces));
+
+ NDR_ALLOC_N(ndr, acl->aces, acl->num_aces);
+
+ for (i=0;i<acl->num_aces;i++) {
+ NDR_CHECK(ndr_parse_security_ace(ndr, &acl->aces[i]));
+ }
+
+ ndr_parse_restore(ndr, &save);
+ NDR_CHECK(ndr_parse_advance(ndr, size));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security_acl offset and structure
+*/
+NTSTATUS ndr_parse_security_acl_ofs(struct ndr_parse *ndr, struct security_acl **acl)
+{
+ uint32 ofs;
+ struct ndr_parse_save save;
+
+ NDR_CHECK(ndr_parse_u32(ndr, &ofs));
+ if (ofs == 0) {
+ /* it is valid for an acl ptr to be NULL */
+ *acl = NULL;
+ return NT_STATUS_OK;
+ }
+
+ ndr_parse_save(ndr, &save);
+ NDR_CHECK(ndr_parse_set_offset(ndr, ofs));
+ NDR_ALLOC(ndr, *acl);
+ NDR_CHECK(ndr_parse_security_acl(ndr, *acl));
+ ndr_parse_restore(ndr, &save);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a dom_sid
+*/
+NTSTATUS ndr_parse_dom_sid(struct ndr_parse *ndr, struct dom_sid *sid)
+{
+ int i;
+
+ NDR_CHECK(ndr_parse_u8(ndr, &sid->sid_rev_num));
+ NDR_CHECK(ndr_parse_u8(ndr, &sid->num_auths));
+ for (i=0;i<6;i++) {
+ NDR_CHECK(ndr_parse_u8(ndr, &sid->id_auth[i]));
+ }
+
+ NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths);
+
+ for (i=0;i<sid->num_auths;i++) {
+ NDR_CHECK(ndr_parse_u32(ndr, &sid->sub_auths[i]));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a dom_sid offset and structure
+*/
+NTSTATUS ndr_parse_dom_sid_ofs(struct ndr_parse *ndr, struct dom_sid **sid)
+{
+ uint32 ofs;
+ struct ndr_parse_save save;
+
+ NDR_CHECK(ndr_parse_u32(ndr, &ofs));
+ if (ofs == 0) {
+ /* it is valid for a dom_sid ptr to be NULL */
+ *sid = NULL;
+ return NT_STATUS_OK;
+ }
+
+ ndr_parse_save(ndr, &save);
+ NDR_CHECK(ndr_parse_set_offset(ndr, ofs));
+ NDR_ALLOC(ndr, *sid);
+ NDR_CHECK(ndr_parse_dom_sid(ndr, *sid));
+ ndr_parse_restore(ndr, &save);
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security descriptor
+*/
+NTSTATUS ndr_parse_security_descriptor(struct ndr_parse *ndr,
+ struct security_descriptor **sd)
+{
+ NDR_ALLOC(ndr, *sd);
+
+ NDR_CHECK(ndr_parse_u8(ndr, &(*sd)->revision));
+ NDR_CHECK(ndr_parse_u16(ndr, &(*sd)->type));
+ NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->owner_sid));
+ NDR_CHECK(ndr_parse_dom_sid_ofs(ndr, &(*sd)->group_sid));
+ NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->sacl));
+ NDR_CHECK(ndr_parse_security_acl_ofs(ndr, &(*sd)->dacl));
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/libcli/rpc/rpc_sec.h b/source4/libcli/rpc/rpc_sec.h
new file mode 100644
index 0000000000..3cda400eb2
--- /dev/null
+++ b/source4/libcli/rpc/rpc_sec.h
@@ -0,0 +1,81 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling security descriptors
+ and related structures
+
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* a domain SID. Note that unlike Samba3 this contains a pointer,
+ so you can't copy them using assignment */
+struct dom_sid {
+ uint8 sid_rev_num; /**< SID revision number */
+ uint8 num_auths; /**< Number of sub-authorities */
+ uint8 id_auth[6]; /**< Identifier Authority */
+ uint32 *sub_auths;
+};
+
+/* an access control element */
+struct security_ace {
+ uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */
+ uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */
+
+ uint32 access_mask;
+
+ /* the 'obj' part is present when type is XXXX_TYPE_XXXX_OBJECT */
+ struct {
+ uint32 flags;
+ GUID object_guid;
+ GUID inherit_guid;
+ } *obj;
+
+ struct dom_sid trustee;
+};
+
+
+/* a security ACL */
+struct security_acl {
+ uint16 revision;
+ uint32 num_aces;
+
+ struct security_ace *aces;
+};
+
+
+/* a security descriptor */
+struct security_descriptor {
+ uint8 revision;
+ uint16 type; /* SEC_DESC_xxxx flags */
+
+ struct dom_sid *owner_sid;
+ struct dom_sid *group_sid;
+ struct security_acl *sacl; /* system ACL */
+ struct security_acl *dacl; /* user (discretionary) ACL */
+};
+
+/* query security descriptor */
+struct smb_query_secdesc {
+ struct {
+ uint16 fnum;
+ uint32 secinfo_flags;
+ } in;
+ struct {
+ struct security_descriptor *sd;
+ } out;
+};
diff --git a/source4/libcli/rpc/rpcparse.c b/source4/libcli/rpc/rpcparse.c
new file mode 100644
index 0000000000..41e6919b72
--- /dev/null
+++ b/source4/libcli/rpc/rpcparse.c
@@ -0,0 +1,105 @@
+/*
+ Unix SMB/CIFS implementation.
+ libndr interface
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ this provides the core routines for MSNDR parsing functions
+*/
+
+#include "includes.h"
+
+/*
+ initialise a ndr parse structure from a data blob
+*/
+struct ndr_parse *ndr_parse_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+{
+ struct ndr_parse *ndr;
+
+ ndr = talloc(mem_ctx, sizeof(*ndr));
+ if (!ndr) return NULL;
+
+ ndr->data = blob->data;
+ ndr->data_size = blob->length;
+ ndr->offset = 0;
+ ndr->mem_ctx = mem_ctx;
+
+ return ndr;
+}
+
+
+/* limit the remaining size of the current ndr parse structure to the
+ given size, starting at the given offset
+
+ this is used when a ndr packet has an explicit size on the wire, and we
+ need to make sure that we don't use more data than is indicated
+
+ the 'ofs' parameter indicates how many bytes back from the current
+ offset in the buffer the 'size' number of bytes starts
+*/
+NTSTATUS ndr_parse_limit_size(struct ndr_parse *ndr, uint32 size, uint32 ofs)
+{
+ uint32 new_size;
+ new_size = ndr->offset + size - ofs;
+
+ if (new_size > ndr->data_size) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ ndr->data_size = new_size;
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ advance by 'size' bytes
+*/
+NTSTATUS ndr_parse_advance(struct ndr_parse *ndr, uint32 size)
+{
+ ndr->offset += size;
+ if (ndr->offset > ndr->data_size) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ return NT_STATUS_OK;
+}
+
+/*
+ set the parse offset to 'ofs'
+*/
+NTSTATUS ndr_parse_set_offset(struct ndr_parse *ndr, uint32 ofs)
+{
+ ndr->offset = ofs;
+ if (ndr->offset > ndr->data_size) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+ return NT_STATUS_OK;
+}
+
+/* save the offset/size of the current ndr state */
+void ndr_parse_save(struct ndr_parse *ndr, struct ndr_parse_save *save)
+{
+ save->offset = ndr->offset;
+ save->data_size = ndr->data_size;
+}
+
+/* restore the size/offset of a ndr structure */
+void ndr_parse_restore(struct ndr_parse *ndr, struct ndr_parse_save *save)
+{
+ ndr->offset = save->offset;
+ ndr->data_size = save->data_size;
+}