summaryrefslogtreecommitdiff
path: root/source4/librpc/ndr
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/ndr')
-rw-r--r--source4/librpc/ndr/libndr.h95
-rw-r--r--source4/librpc/ndr/ndr.c187
-rw-r--r--source4/librpc/ndr/ndr_basic.c279
-rw-r--r--source4/librpc/ndr/ndr_echo.c114
-rw-r--r--source4/librpc/ndr/ndr_echo.h76
-rw-r--r--source4/librpc/ndr/ndr_lsa.c167
-rw-r--r--source4/librpc/ndr/ndr_lsa.h82
-rw-r--r--source4/librpc/ndr/ndr_misc.c45
-rw-r--r--source4/librpc/ndr/ndr_misc.h26
-rw-r--r--source4/librpc/ndr/ndr_sec.c309
-rw-r--r--source4/librpc/ndr/ndr_sec.h90
11 files changed, 1470 insertions, 0 deletions
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
new file mode 100644
index 0000000000..0d28783a6d
--- /dev/null
+++ b/source4/librpc/ndr/libndr.h
@@ -0,0 +1,95 @@
+/*
+ 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_pull {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ char *data;
+ uint32 data_size;
+ uint32 offset;
+ TALLOC_CTX *mem_ctx;
+};
+
+struct ndr_pull_save {
+ uint32 data_size;
+ uint32 offset;
+};
+
+
+/* structure passed to functions that generate NDR formatted data */
+struct ndr_push {
+ uint32 flags; /* LIBNDR_FLAG_* */
+ char *data;
+ uint32 alloc_size;
+ uint32 offset;
+ TALLOC_CTX *mem_ctx;
+};
+
+struct ndr_push_save {
+ 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)
+
+/* these are used when generic fn pointers are needed for ndr push/pull fns */
+typedef NTSTATUS (*ndr_push_fn_t)(struct ndr_push *, void *);
+typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *);
+
+/* now pull in the individual parsers */
+#include "librpc/ndr/ndr_sec.h"
+#include "librpc/ndr/ndr_misc.h"
+#include "librpc/ndr/ndr_echo.h"
+#include "librpc/ndr/ndr_lsa.h"
diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c
new file mode 100644
index 0000000000..4e5f199835
--- /dev/null
+++ b/source4/librpc/ndr/ndr.c
@@ -0,0 +1,187 @@
+/*
+ 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 NDR parsing functions
+
+ see http://www.opengroup.org/onlinepubs/9629399/chap14.htm for details
+ of NDR encoding rules
+*/
+
+#include "includes.h"
+
+#define NDR_BASE_MARSHALL_SIZE 1024
+
+/*
+ initialise a ndr parse structure from a data blob
+*/
+struct ndr_pull *ndr_pull_init_blob(DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+{
+ struct ndr_pull *ndr;
+
+ ndr = talloc(mem_ctx, sizeof(*ndr));
+ if (!ndr) return NULL;
+
+ ndr->flags = 0;
+ 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_pull_limit_size(struct ndr_pull *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_pull_advance(struct ndr_pull *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_pull_set_offset(struct ndr_pull *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_pull_save(struct ndr_pull *ndr, struct ndr_pull_save *save)
+{
+ save->offset = ndr->offset;
+ save->data_size = ndr->data_size;
+}
+
+/* restore the size/offset of a ndr structure */
+void ndr_pull_restore(struct ndr_pull *ndr, struct ndr_pull_save *save)
+{
+ ndr->offset = save->offset;
+ ndr->data_size = save->data_size;
+}
+
+
+
+
+/* create a ndr_push structure, ready for some marshalling */
+struct ndr_push *ndr_push_init(void)
+{
+ struct ndr_push *ndr;
+ TALLOC_CTX *mem_ctx = talloc_init("ndr_push_init");
+ if (!mem_ctx) return NULL;
+
+ ndr = talloc(mem_ctx, sizeof(*ndr));
+ if (!ndr) {
+ talloc_destroy(mem_ctx);
+ return NULL;
+ }
+
+ ndr->mem_ctx = mem_ctx;
+ ndr->flags = 0;
+ ndr->alloc_size = NDR_BASE_MARSHALL_SIZE;
+ ndr->data = talloc(ndr->mem_ctx, ndr->alloc_size);
+ if (!ndr->data) {
+ ndr_push_free(ndr);
+ return NULL;
+ }
+ ndr->offset = 0;
+
+ return ndr;
+}
+
+/* free a ndr_push structure */
+void ndr_push_free(struct ndr_push *ndr)
+{
+ talloc_destroy(ndr->mem_ctx);
+}
+
+
+/* return a DATA_BLOB structure for the current ndr_push marshalled data */
+DATA_BLOB ndr_push_blob(struct ndr_push *ndr)
+{
+ DATA_BLOB blob;
+ blob.data = ndr->data;
+ blob.length = ndr->offset;
+ return blob;
+}
+
+
+/*
+ expand the available space in the buffer to 'size'
+*/
+NTSTATUS ndr_push_expand(struct ndr_push *ndr, uint32 size)
+{
+ if (ndr->alloc_size >= size) {
+ return NT_STATUS_OK;
+ }
+
+ ndr->alloc_size = size;
+ ndr->data = talloc_realloc(ndr->mem_ctx, ndr->data, ndr->alloc_size);
+ if (!ndr->data) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ set the push offset to 'ofs'
+*/
+NTSTATUS ndr_push_set_offset(struct ndr_push *ndr, uint32 ofs)
+{
+ NDR_CHECK(ndr_push_expand(ndr, ofs));
+ ndr->offset = ofs;
+ return NT_STATUS_OK;
+}
diff --git a/source4/librpc/ndr/ndr_basic.c b/source4/librpc/ndr/ndr_basic.c
new file mode 100644
index 0000000000..3bd75e7c0d
--- /dev/null
+++ b/source4/librpc/ndr/ndr_basic.c
@@ -0,0 +1,279 @@
+/*
+ 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_PULL_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_PULL_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 uint8
+*/
+NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, uint8 *v)
+{
+ NDR_PULL_NEED_BYTES(ndr, 1);
+ *v = CVAL(ndr->data, ndr->offset);
+ ndr->offset += 1;
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a uint16
+*/
+NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, uint16 *v)
+{
+ NDR_PULL_ALIGN(ndr, 2);
+ NDR_PULL_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 uint32
+*/
+NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, uint32 *v)
+{
+ NDR_PULL_ALIGN(ndr, 4);
+ NDR_PULL_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 += 4;
+ return NT_STATUS_OK;
+}
+
+/*
+ pull a NTSTATUS
+*/
+NTSTATUS ndr_pull_status(struct ndr_pull *ndr, NTSTATUS *status)
+{
+ uint32 v;
+ NDR_CHECK(ndr_pull_uint32(ndr, &v));
+ *status = NT_STATUS(v);
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a set of bytes
+*/
+NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n)
+{
+ NDR_PULL_NEED_BYTES(ndr, n);
+ memcpy(data, ndr->data + ndr->offset, n);
+ ndr->offset += n;
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a GUID
+*/
+NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid)
+{
+ int i;
+ NDR_PULL_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;
+}
+
+
+#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
+
+#define NDR_PUSH_ALIGN(ndr, n) do { \
+ uint32 _pad = (ndr->offset & (n-1)); \
+ while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, 0)); \
+} while(0)
+
+/*
+ push a uint8
+*/
+NTSTATUS ndr_push_uint8(struct ndr_push *ndr, uint8 v)
+{
+ NDR_PUSH_NEED_BYTES(ndr, 1);
+ SCVAL(ndr->data, ndr->offset, v);
+ ndr->offset += 1;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a uint16
+*/
+NTSTATUS ndr_push_uint16(struct ndr_push *ndr, uint16 v)
+{
+ NDR_PUSH_ALIGN(ndr, 2);
+ NDR_PUSH_NEED_BYTES(ndr, 2);
+ SSVAL(ndr->data, ndr->offset, v);
+ ndr->offset += 2;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a uint32
+*/
+NTSTATUS ndr_push_uint32(struct ndr_push *ndr, uint32 v)
+{
+ NDR_PUSH_ALIGN(ndr, 4);
+ NDR_PUSH_NEED_BYTES(ndr, 4);
+ SIVAL(ndr->data, ndr->offset, v);
+ ndr->offset += 4;
+ return NT_STATUS_OK;
+}
+
+/*
+ align to a uint32
+*/
+NTSTATUS ndr_push_align_uint32(struct ndr_push *ndr)
+{
+ NDR_PUSH_ALIGN(ndr, 4);
+ return NT_STATUS_OK;
+}
+
+/*
+ push some bytes
+*/
+NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n)
+{
+ NDR_PUSH_NEED_BYTES(ndr, n);
+ memcpy(ndr->data + ndr->offset, data, n);
+ ndr->offset += n;
+ return NT_STATUS_OK;
+}
+
+/*
+ save the current position
+ */
+void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ save->offset = ndr->offset;
+}
+
+/*
+ restore the position
+ */
+void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ ndr->offset = save->offset;
+}
+
+/*
+ this is used when a packet has a 4 byte length field. We remember the start position
+ and come back to it later to fill in the size
+*/
+NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ NDR_PUSH_ALIGN(ndr, 4);
+ ndr_push_save(ndr, save);
+ return ndr_push_uint32(ndr, 0);
+}
+
+NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ struct ndr_push_save save2;
+ ndr_push_save(ndr, &save2);
+ ndr_push_restore(ndr, save);
+ NDR_CHECK(ndr_push_uint32(ndr, save2.offset - ndr->offset));
+ ndr_push_restore(ndr, &save2);
+ return NT_STATUS_OK;
+}
+
+/*
+ push a 1 if a pointer is non-NULL, otherwise 0
+*/
+NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
+{
+ return ndr_push_uint32(ndr, p?1:0);
+}
+
+/*
+ push a comformant, variable ucs2 string onto the wire from a C string
+*/
+NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s)
+{
+ char *ws;
+ ssize_t len;
+ len = push_ucs2_talloc(ndr->mem_ctx, (smb_ucs2_t **)&ws, s);
+ if (len == -1) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, len/2));
+ NDR_CHECK(ndr_push_uint32(ndr, 0));
+ NDR_CHECK(ndr_push_uint32(ndr, len/2));
+ NDR_CHECK(ndr_push_bytes(ndr, ws, len));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a 4 byte offset pointer, remembering where we are so we can later fill
+ in the correct value
+*/
+NTSTATUS ndr_push_offset(struct ndr_push *ndr, struct ndr_push_save *ofs)
+{
+ NDR_PUSH_ALIGN(ndr, 4);
+ ndr_push_save(ndr, ofs);
+ return ndr_push_uint32(ndr, 0);
+}
+
+/*
+ fill in the correct offset in a saved offset pointer
+ the offset is taken relative to 'save'
+*/
+NTSTATUS ndr_push_offset_ptr(struct ndr_push *ndr,
+ struct ndr_push_save *ofs,
+ struct ndr_push_save *save)
+{
+ struct ndr_push_save save2;
+ ndr_push_save(ndr, &save2);
+ ndr_push_restore(ndr, ofs);
+ NDR_CHECK(ndr_push_uint32(ndr, save2.offset - save->offset));
+ ndr_push_restore(ndr, &save2);
+ return NT_STATUS_OK;
+}
+
+
+/*
+ push a GUID
+*/
+NTSTATUS ndr_push_guid(struct ndr_push *ndr, GUID *guid)
+{
+ return ndr_push_bytes(ndr, guid->info, GUID_SIZE);
+}
diff --git a/source4/librpc/ndr/ndr_echo.c b/source4/librpc/ndr/ndr_echo.c
new file mode 100644
index 0000000000..e2bb062d2e
--- /dev/null
+++ b/source4/librpc/ndr/ndr_echo.c
@@ -0,0 +1,114 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling rpcecho pipe
+
+ 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 addone
+*/
+NTSTATUS ndr_pull_rpcecho_addone(struct ndr_pull *ndr,
+ struct rpcecho_addone *r)
+{
+ NDR_CHECK(ndr_pull_uint32(ndr, &r->out.data));
+ return NT_STATUS_OK;
+}
+
+
+/*
+ push a addone
+*/
+NTSTATUS ndr_push_rpcecho_addone(struct ndr_push *ndr,
+ struct rpcecho_addone *r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.data));
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a echodata
+*/
+NTSTATUS ndr_pull_rpcecho_echodata(struct ndr_pull *ndr,
+ struct rpcecho_echodata *r)
+{
+ NDR_CHECK(ndr_pull_uint32(ndr, &r->out.len));
+ NDR_ALLOC_N(ndr, r->out.data, r->out.len);
+ NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a echodata
+*/
+NTSTATUS ndr_push_rpcecho_echodata(struct ndr_push *ndr,
+ struct rpcecho_echodata *r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.len));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.len));
+ NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len));
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a sinkdata
+*/
+NTSTATUS ndr_pull_rpcecho_sinkdata(struct ndr_pull *ndr,
+ struct rpcecho_sinkdata *r)
+{
+ return NT_STATUS_OK;
+}
+
+/*
+ push a sinkdata
+*/
+NTSTATUS ndr_push_rpcecho_sinkdata(struct ndr_push *ndr,
+ struct rpcecho_sinkdata *r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.len));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.len));
+ NDR_CHECK(ndr_push_bytes(ndr, r->in.data, r->in.len));
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a sourcedata
+*/
+NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr,
+ struct rpcecho_sourcedata *r)
+{
+ NDR_CHECK(ndr_pull_uint32(ndr, &r->out.len));
+ NDR_ALLOC_N(ndr, r->out.data, r->out.len);
+ NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a sourcedata
+*/
+NTSTATUS ndr_push_rpcecho_sourcedata(struct ndr_push *ndr,
+ struct rpcecho_sourcedata *r)
+{
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.len));
+ return NT_STATUS_OK;
+}
diff --git a/source4/librpc/ndr/ndr_echo.h b/source4/librpc/ndr/ndr_echo.h
new file mode 100644
index 0000000000..aecf68c4c0
--- /dev/null
+++ b/source4/librpc/ndr/ndr_echo.h
@@ -0,0 +1,76 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling the rpcecho pipe
+
+ 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.
+*/
+
+/*
+ see http://samba.org/ftp/unpacked/junkcode/rpcecho-win32/ for the
+ definition of this pipe
+*/
+
+/* AddOne interface */
+struct rpcecho_addone {
+ struct {
+ int data;
+ } in;
+ struct {
+ int data;
+ } out;
+};
+
+/* EchoData interface */
+struct rpcecho_echodata {
+ struct {
+ int len;
+ const char *data;
+ } in;
+ struct {
+ int len;
+ char *data;
+ } out;
+};
+
+/* SinkData interface */
+struct rpcecho_sinkdata {
+ struct {
+ int len;
+ char *data;
+ } in;
+};
+
+/* SourceData interface */
+struct rpcecho_sourcedata {
+ struct {
+ int len;
+ } in;
+ struct {
+ int len;
+ char *data;
+ } out;
+};
+
+/* define the command codes */
+enum {
+ RPCECHO_CALL_ADDONE=0,
+ RPCECHO_CALL_ECHODATA,
+ RPCECHO_CALL_SINKDATA,
+ RPCECHO_CALL_SOURCEDATA
+};
+
diff --git a/source4/librpc/ndr/ndr_lsa.c b/source4/librpc/ndr/ndr_lsa.c
new file mode 100644
index 0000000000..bde450687e
--- /dev/null
+++ b/source4/librpc/ndr/ndr_lsa.c
@@ -0,0 +1,167 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling lsa pipe
+
+ 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 openpolicy
+*/
+NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr,
+ struct lsa_OpenPolicy *r)
+{
+ NDR_ALLOC(ndr, r->out.handle);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, r->out.handle));
+ NDR_CHECK(ndr_pull_status(ndr, &r->out.result));
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a openpolicy2
+*/
+NTSTATUS ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr,
+ struct lsa_OpenPolicy2 *r)
+{
+ NDR_ALLOC(ndr, r->out.handle);
+ NDR_CHECK(ndr_pull_policy_handle(ndr, r->out.handle));
+ NDR_CHECK(ndr_pull_status(ndr, &r->out.result));
+ return NT_STATUS_OK;
+}
+
+
+/*
+ pull a EnumSids
+*/
+NTSTATUS ndr_pull_lsa_EnumSids(struct ndr_pull *ndr,
+ struct lsa_EnumSids *r)
+{
+ uint32 nptrs, asize, i, ptr;
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &r->out.num_entries));
+ NDR_CHECK(ndr_pull_uint32(ndr, &nptrs));
+ NDR_CHECK(ndr_pull_uint32(ndr, &ptr));
+ if (!ptr) goto done;
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &asize));
+ NDR_ALLOC_N(ndr, r->out.sids, nptrs);
+ for (i=0;i<nptrs;i++) {
+ NDR_CHECK(ndr_pull_uint32(ndr, &ptr));
+ if (ptr) {
+ NDR_ALLOC(ndr, r->out.sids[i]);
+ } else {
+ r->out.sids[i] = NULL;
+ }
+ }
+ for (i=0;i<nptrs;i++) {
+ if (r->out.sids[i]) NDR_CHECK(ndr_pull_dom_sid2(ndr, r->out.sids[i]));
+ }
+
+done:
+ NDR_CHECK(ndr_pull_status(ndr, &r->out.result));
+ return NT_STATUS_OK;
+}
+
+
+/* parser auto-generated by pidl */
+
+static NTSTATUS ndr_push_lsa_QosInfo(struct ndr_push *ndr, struct lsa_QosInfo *r)
+{
+ struct ndr_push_save len_save1, len_save2, len_save3;
+ ndr_push_save(ndr, &len_save1);
+ NDR_CHECK(ndr_push_align_uint32(ndr));
+ ndr_push_save(ndr, &len_save2);
+ NDR_CHECK(ndr_push_uint32(ndr, 0));
+ NDR_CHECK(ndr_push_uint16(ndr, r->impersonation_level));
+ NDR_CHECK(ndr_push_uint8(ndr, r->context_mode));
+ NDR_CHECK(ndr_push_uint8(ndr, r->effective_only));
+ ndr_push_save(ndr, &len_save3);
+ ndr_push_restore(ndr, &len_save2);
+ NDR_CHECK(ndr_push_uint32(ndr, len_save3.offset - len_save1.offset));
+ ndr_push_restore(ndr, &len_save3);
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS ndr_push_lsa_ObjectAttribute(struct ndr_push *ndr, struct lsa_ObjectAttribute *r)
+{
+ struct ndr_push_save len_save1, len_save2, len_save3;
+ ndr_push_save(ndr, &len_save1);
+ NDR_CHECK(ndr_push_align_uint32(ndr));
+ ndr_push_save(ndr, &len_save2);
+ NDR_CHECK(ndr_push_uint32(ndr, 0));
+ NDR_CHECK(ndr_push_ptr(ndr, r->root_dir));
+ NDR_CHECK(ndr_push_ptr(ndr, r->object_name));
+ NDR_CHECK(ndr_push_uint32(ndr, r->attributes));
+ NDR_CHECK(ndr_push_ptr(ndr, r->sec_desc));
+ NDR_CHECK(ndr_push_ptr(ndr, r->sec_qos));
+ if (r->root_dir) {
+ NDR_CHECK(ndr_push_uint8(ndr, *r->root_dir));
+ }
+ if (r->object_name) {
+ NDR_CHECK(ndr_push_unistr(ndr, r->object_name));
+ }
+ if (r->sec_desc) {
+ NDR_CHECK(ndr_push_security_descriptor(ndr, r->sec_desc));
+ }
+ if (r->sec_qos) {
+ NDR_CHECK(ndr_push_lsa_QosInfo(ndr, r->sec_qos));
+ }
+ ndr_push_save(ndr, &len_save3);
+ ndr_push_restore(ndr, &len_save2);
+ NDR_CHECK(ndr_push_uint32(ndr, len_save3.offset - len_save1.offset));
+ ndr_push_restore(ndr, &len_save3);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, struct lsa_OpenPolicy *r)
+{
+ NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name));
+ if (r->in.system_name) {
+ NDR_CHECK(ndr_push_uint16(ndr, *r->in.system_name));
+ }
+ NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.desired_access));
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, struct lsa_OpenPolicy2 *r)
+{
+ NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name));
+ if (r->in.system_name) {
+ NDR_CHECK(ndr_push_unistr(ndr, r->in.system_name));
+ }
+ NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.desired_access));
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_push_lsa_EnumSids(struct ndr_push *ndr, struct lsa_EnumSids *r)
+{
+ NDR_CHECK(ndr_push_policy_handle(ndr, r->in.handle));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.start_at));
+ NDR_CHECK(ndr_push_uint32(ndr, r->in.num_entries));
+
+ return NT_STATUS_OK;
+}
+
+
diff --git a/source4/librpc/ndr/ndr_lsa.h b/source4/librpc/ndr/ndr_lsa.h
new file mode 100644
index 0000000000..402227a8bf
--- /dev/null
+++ b/source4/librpc/ndr/ndr_lsa.h
@@ -0,0 +1,82 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling the lsa pipe
+
+ 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.
+*/
+
+/* header auto-generated by pidl */
+
+struct lsa_QosInfo {
+ uint16 impersonation_level;
+ uint8 context_mode;
+ uint8 effective_only;
+};
+
+struct lsa_ObjectAttribute {
+ uint8 *root_dir;
+ const char *object_name;
+ uint32 attributes;
+ struct security_descriptor *sec_desc;
+ struct lsa_QosInfo *sec_qos;
+};
+
+struct lsa_OpenPolicy {
+ struct {
+ uint16 *system_name;
+ struct lsa_ObjectAttribute *attr;
+ uint32 desired_access;
+ } in;
+
+ struct {
+ struct policy_handle *handle;
+ NTSTATUS result;
+ } out;
+
+};
+
+struct lsa_OpenPolicy2 {
+ struct {
+ const char *system_name;
+ struct lsa_ObjectAttribute *attr;
+ uint32 desired_access;
+ } in;
+
+ struct {
+ struct policy_handle *handle;
+ NTSTATUS result;
+ } out;
+
+};
+
+struct lsa_EnumSids {
+ struct {
+ struct policy_handle *handle;
+ uint32 start_at;
+ uint32 num_entries;
+ } in;
+
+ struct {
+ uint32 num_entries;
+ struct dom_sid **sids;
+ NTSTATUS result;
+ } out;
+
+};
+
+
diff --git a/source4/librpc/ndr/ndr_misc.c b/source4/librpc/ndr/ndr_misc.c
new file mode 100644
index 0000000000..cdd6652068
--- /dev/null
+++ b/source4/librpc/ndr/ndr_misc.c
@@ -0,0 +1,45 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling miscellaneous rpc 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 policy handle
+*/
+NTSTATUS ndr_pull_policy_handle(struct ndr_pull *ndr,
+ struct policy_handle *r)
+{
+ NDR_CHECK(ndr_pull_bytes(ndr, r->data, 20));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a policy handle
+*/
+NTSTATUS ndr_push_policy_handle(struct ndr_push *ndr,
+ struct policy_handle *r)
+{
+ NDR_CHECK(ndr_push_bytes(ndr, r->data, 20));
+ return NT_STATUS_OK;
+}
diff --git a/source4/librpc/ndr/ndr_misc.h b/source4/librpc/ndr/ndr_misc.h
new file mode 100644
index 0000000000..cc3576b3e8
--- /dev/null
+++ b/source4/librpc/ndr/ndr_misc.h
@@ -0,0 +1,26 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling miscellaneous 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.
+*/
+
+/* policy handles are used all over the place */
+struct policy_handle {
+ char data[20];
+};
diff --git a/source4/librpc/ndr/ndr_sec.c b/source4/librpc/ndr/ndr_sec.c
new file mode 100644
index 0000000000..31cf823e0d
--- /dev/null
+++ b/source4/librpc/ndr/ndr_sec.c
@@ -0,0 +1,309 @@
+/*
+ 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_pull_security_ace(struct ndr_pull *ndr, struct security_ace *ace)
+{
+ uint16 size;
+ struct ndr_pull_save save;
+
+ ndr_pull_save(ndr, &save);
+
+ NDR_CHECK(ndr_pull_uint8(ndr, &ace->type));
+ NDR_CHECK(ndr_pull_uint8(ndr, &ace->flags));
+ NDR_CHECK(ndr_pull_uint16(ndr, &size));
+ NDR_CHECK(ndr_pull_limit_size(ndr, size, 4));
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &ace->access_mask));
+
+ if (sec_ace_object(ace->type)) {
+ NDR_ALLOC(ndr, ace->obj);
+ NDR_CHECK(ndr_pull_uint32(ndr, &ace->obj->flags));
+ if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) {
+ NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->object_guid));
+ }
+ if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
+ NDR_CHECK(ndr_pull_guid(ndr, &ace->obj->inherit_guid));
+ }
+ }
+
+
+ NDR_CHECK(ndr_pull_dom_sid(ndr, &ace->trustee));
+
+ ndr_pull_restore(ndr, &save);
+ NDR_CHECK(ndr_pull_advance(ndr, size));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security_acl
+*/
+NTSTATUS ndr_pull_security_acl(struct ndr_pull *ndr, struct security_acl *acl)
+{
+ int i;
+ uint16 size;
+ struct ndr_pull_save save;
+
+ ndr_pull_save(ndr, &save);
+
+ NDR_CHECK(ndr_pull_uint16(ndr, &acl->revision));
+ NDR_CHECK(ndr_pull_uint16(ndr, &size));
+ NDR_CHECK(ndr_pull_limit_size(ndr, size, 4));
+ NDR_CHECK(ndr_pull_uint32(ndr, &acl->num_aces));
+
+ NDR_ALLOC_N(ndr, acl->aces, acl->num_aces);
+
+ for (i=0;i<acl->num_aces;i++) {
+ NDR_CHECK(ndr_pull_security_ace(ndr, &acl->aces[i]));
+ }
+
+ ndr_pull_restore(ndr, &save);
+ NDR_CHECK(ndr_pull_advance(ndr, size));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security_acl offset and structure
+*/
+NTSTATUS ndr_pull_security_acl_ofs(struct ndr_pull *ndr, struct security_acl **acl)
+{
+ uint32 ofs;
+ struct ndr_pull_save save;
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+ if (ofs == 0) {
+ /* it is valid for an acl ptr to be NULL */
+ *acl = NULL;
+ return NT_STATUS_OK;
+ }
+
+ ndr_pull_save(ndr, &save);
+ NDR_CHECK(ndr_pull_set_offset(ndr, ofs));
+ NDR_ALLOC(ndr, *acl);
+ NDR_CHECK(ndr_pull_security_acl(ndr, *acl));
+ ndr_pull_restore(ndr, &save);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a dom_sid
+*/
+NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, struct dom_sid *sid)
+{
+ int i;
+
+ NDR_CHECK(ndr_pull_uint8(ndr, &sid->sid_rev_num));
+ NDR_CHECK(ndr_pull_uint8(ndr, &sid->num_auths));
+ for (i=0;i<6;i++) {
+ NDR_CHECK(ndr_pull_uint8(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_pull_uint32(ndr, &sid->sub_auths[i]));
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
+*/
+NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, struct dom_sid *sid)
+{
+ uint32 num_auths;
+ NDR_CHECK(ndr_pull_uint32(ndr, &num_auths));
+ return ndr_pull_dom_sid(ndr, sid);
+}
+
+/*
+ parse a dom_sid offset and structure
+*/
+NTSTATUS ndr_pull_dom_sid_ofs(struct ndr_pull *ndr, struct dom_sid **sid)
+{
+ uint32 ofs;
+ struct ndr_pull_save save;
+
+ NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
+ if (ofs == 0) {
+ /* it is valid for a dom_sid ptr to be NULL */
+ *sid = NULL;
+ return NT_STATUS_OK;
+ }
+
+ ndr_pull_save(ndr, &save);
+ NDR_CHECK(ndr_pull_set_offset(ndr, ofs));
+ NDR_ALLOC(ndr, *sid);
+ NDR_CHECK(ndr_pull_dom_sid(ndr, *sid));
+ ndr_pull_restore(ndr, &save);
+
+ return NT_STATUS_OK;
+}
+
+/*
+ parse a security descriptor
+*/
+NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr,
+ struct security_descriptor **sd)
+{
+ NDR_ALLOC(ndr, *sd);
+
+ NDR_CHECK(ndr_pull_uint8(ndr, &(*sd)->revision));
+ NDR_CHECK(ndr_pull_uint16(ndr, &(*sd)->type));
+ NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->owner_sid));
+ NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &(*sd)->group_sid));
+ NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->sacl));
+ NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &(*sd)->dacl));
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a security_ace
+*/
+NTSTATUS ndr_push_security_ace(struct ndr_push *ndr, struct security_ace *ace)
+{
+ struct ndr_push_save save1, save2;
+
+ NDR_CHECK(ndr_push_uint8(ndr, ace->type));
+ NDR_CHECK(ndr_push_uint8(ndr, ace->flags));
+ ndr_push_save(ndr, &save1);
+ NDR_CHECK(ndr_push_uint16(ndr, 0));
+ NDR_CHECK(ndr_push_uint32(ndr, ace->access_mask));
+
+ if (sec_ace_object(ace->type)) {
+ NDR_CHECK(ndr_push_uint32(ndr, ace->obj->flags));
+ if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) {
+ NDR_CHECK(ndr_push_guid(ndr, &ace->obj->object_guid));
+ }
+ if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
+ NDR_CHECK(ndr_push_guid(ndr, &ace->obj->inherit_guid));
+ }
+ }
+
+ NDR_CHECK(ndr_push_dom_sid(ndr, &ace->trustee));
+
+ ndr_push_save(ndr, &save2);
+ ndr_push_restore(ndr, &save1);
+ NDR_CHECK(ndr_push_uint16(ndr, 2 + save2.offset - save1.offset));
+ ndr_push_restore(ndr, &save2);
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ push a security_acl
+*/
+NTSTATUS ndr_push_security_acl(struct ndr_push *ndr, struct security_acl *acl)
+{
+ int i;
+ struct ndr_push_save save1, save2;
+
+ NDR_CHECK(ndr_push_uint16(ndr, acl->revision));
+ ndr_push_save(ndr, &save1);
+ NDR_CHECK(ndr_push_uint16(ndr, 0));
+ NDR_CHECK(ndr_push_uint32(ndr, acl->num_aces));
+ for (i=0;i<acl->num_aces;i++) {
+ NDR_CHECK(ndr_push_security_ace(ndr, &acl->aces[i]));
+ }
+ ndr_push_save(ndr, &save2);
+ ndr_push_restore(ndr, &save1);
+ NDR_CHECK(ndr_push_uint16(ndr, 2 + save2.offset - save1.offset));
+ ndr_push_restore(ndr, &save2);
+
+ return NT_STATUS_OK;
+}
+
+/*
+ push a dom_sid
+*/
+NTSTATUS ndr_push_dom_sid(struct ndr_push *ndr, struct dom_sid *sid)
+{
+ int i;
+
+ NDR_CHECK(ndr_push_uint8(ndr, sid->sid_rev_num));
+ NDR_CHECK(ndr_push_uint8(ndr, sid->num_auths));
+ for (i=0;i<6;i++) {
+ NDR_CHECK(ndr_push_uint8(ndr, sid->id_auth[i]));
+ }
+ for (i=0;i<sid->num_auths;i++) {
+ NDR_CHECK(ndr_push_uint32(ndr, sid->sub_auths[i]));
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ generate a ndr security descriptor
+*/
+NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr,
+ struct security_descriptor *sd)
+{
+ struct ndr_push_save save;
+ struct ndr_push_save ofs1, ofs2, ofs3, ofs4;
+
+ ndr_push_save(ndr, &save);
+
+ NDR_CHECK(ndr_push_uint8(ndr, sd->revision));
+ NDR_CHECK(ndr_push_uint16(ndr, sd->type));
+
+ NDR_CHECK(ndr_push_offset(ndr, &ofs1));
+ NDR_CHECK(ndr_push_offset(ndr, &ofs2));
+ NDR_CHECK(ndr_push_offset(ndr, &ofs3));
+ NDR_CHECK(ndr_push_offset(ndr, &ofs4));
+
+ if (sd->owner_sid) {
+ NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs1, &save));
+ NDR_CHECK(ndr_push_dom_sid(ndr, sd->owner_sid));
+ }
+
+ if (sd->group_sid) {
+ NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs2, &save));
+ NDR_CHECK(ndr_push_dom_sid(ndr, sd->group_sid));
+ }
+
+ if (sd->sacl) {
+ NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs3, &save));
+ NDR_CHECK(ndr_push_security_acl(ndr, sd->sacl));
+ }
+
+ if (sd->dacl) {
+ NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs4, &save));
+ NDR_CHECK(ndr_push_security_acl(ndr, sd->dacl));
+ }
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/librpc/ndr/ndr_sec.h b/source4/librpc/ndr/ndr_sec.h
new file mode 100644
index 0000000000..0c9d542006
--- /dev/null
+++ b/source4/librpc/ndr/ndr_sec.h
@@ -0,0 +1,90 @@
+/*
+ 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;
+};
+
+/* set security descriptor */
+struct smb_set_secdesc {
+ struct {
+ uint16 fnum;
+ uint32 secinfo_flags;
+ struct security_descriptor *sd;
+ } in;
+};