diff options
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/ndr/libndr.h | 95 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr.c | 187 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_basic.c | 270 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_echo.c | 114 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_echo.h | 76 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_lsa.c | 155 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_lsa.h | 72 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_misc.c | 45 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_misc.h | 26 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_sec.c | 309 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_sec.h | 90 | ||||
-rw-r--r-- | source4/libcli/raw/rawdcerpc.c | 320 | ||||
-rw-r--r-- | source4/libcli/rpc/dcerpc.c | 804 | ||||
-rw-r--r-- | source4/libcli/rpc/dcerpc.h | 129 | ||||
-rw-r--r-- | source4/libcli/rpc/rpc_echo.c | 137 | ||||
-rw-r--r-- | source4/libcli/rpc/rpc_lsa.c | 142 |
16 files changed, 0 insertions, 2971 deletions
diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h deleted file mode 100644 index 7bd92b4cd1..0000000000 --- a/source4/libcli/ndr/libndr.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - 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 "libcli/ndr/ndr_sec.h" -#include "libcli/ndr/ndr_misc.h" -#include "libcli/ndr/ndr_echo.h" -#include "libcli/ndr/ndr_lsa.h" diff --git a/source4/libcli/ndr/ndr.c b/source4/libcli/ndr/ndr.c deleted file mode 100644 index 4e5f199835..0000000000 --- a/source4/libcli/ndr/ndr.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - 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/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c deleted file mode 100644 index 394d1e2eb1..0000000000 --- a/source4/libcli/ndr/ndr_basic.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - 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 u8 -*/ -NTSTATUS ndr_pull_u8(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 u16 -*/ -NTSTATUS ndr_pull_u16(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 u32 -*/ -NTSTATUS ndr_pull_u32(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_u32(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_u8(ndr, 0)); \ -} while(0) - -/* - push a u8 -*/ -NTSTATUS ndr_push_u8(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 u16 -*/ -NTSTATUS ndr_push_u16(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 u32 -*/ -NTSTATUS ndr_push_u32(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; -} - -/* - 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_u32(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_u32(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_u32(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_u32(ndr, len/2)); - NDR_CHECK(ndr_push_u32(ndr, 0)); - NDR_CHECK(ndr_push_u32(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_u32(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_u32(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/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c deleted file mode 100644 index c60569676c..0000000000 --- a/source4/libcli/ndr/ndr_echo.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - 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_u32(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_u32(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_u32(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_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_u32(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_u32(ndr, r->in.len)); - NDR_CHECK(ndr_push_u32(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_u32(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_u32(ndr, r->in.len)); - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_echo.h b/source4/libcli/ndr/ndr_echo.h deleted file mode 100644 index aecf68c4c0..0000000000 --- a/source4/libcli/ndr/ndr_echo.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - 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/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c deleted file mode 100644 index dfe978f9d4..0000000000 --- a/source4/libcli/ndr/ndr_lsa.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - 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" - -NTSTATUS ndr_push_lsa_QosInfo(struct ndr_push *ndr, - struct lsa_QosInfo *r) -{ - struct ndr_push_save length; - - NDR_CHECK(ndr_push_length4_start(ndr, &length)); - NDR_CHECK(ndr_push_u16(ndr, r->impersonation_level)); - NDR_CHECK(ndr_push_u8(ndr, r->context_mode)); - NDR_CHECK(ndr_push_u8(ndr, r->effective_only)); - NDR_CHECK(ndr_push_length4_end(ndr, &length)); - - return NT_STATUS_OK; -} - -NTSTATUS ndr_push_lsa_ObjectAttribute(struct ndr_push *ndr, - struct lsa_ObjectAttribute *r) -{ - struct ndr_push_save length; - - NDR_CHECK(ndr_push_length4_start(ndr, &length)); - NDR_CHECK(ndr_push_ptr(ndr, r->root_dir)); - NDR_CHECK(ndr_push_ptr(ndr, r->object_name)); - NDR_CHECK(ndr_push_u32(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_u8(ndr, r->root_dir[0])); - 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_CHECK(ndr_push_length4_end(ndr, &length)); - - return NT_STATUS_OK; -} - -/* - push a openpolicy -*/ -NTSTATUS ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, - struct lsa_OpenPolicy *r) -{ - NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name)); - NDR_CHECK(ndr_push_u16(ndr, r->in.system_name[0])); - NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr)); - NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access)); - return NT_STATUS_OK; -} - - -/* - parse a openpolicy -*/ -NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, - struct lsa_OpenPolicy *r) -{ - NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); - NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); - return NT_STATUS_OK; -} - -/* - push a openpolicy2 -*/ -NTSTATUS ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, - struct lsa_OpenPolicy2 *r) -{ - NDR_CHECK(ndr_push_ptr(ndr, 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_u32(ndr, r->in.desired_access)); - return NT_STATUS_OK; -} - - -/* - parse a openpolicy2 -*/ -NTSTATUS ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, - struct lsa_OpenPolicy2 *r) -{ - NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle)); - NDR_CHECK(ndr_pull_status(ndr, &r->out.status)); - return NT_STATUS_OK; -} - - -/* - push a EnumSids -*/ -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_u32(ndr, r->in.start_at)); - NDR_CHECK(ndr_push_u32(ndr, r->in.num_entries)); - 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_u32(ndr, &r->out.num_entries)); - NDR_CHECK(ndr_pull_u32(ndr, &nptrs)); - NDR_CHECK(ndr_pull_u32(ndr, &ptr)); - if (!ptr) goto done; - - NDR_CHECK(ndr_pull_u32(ndr, &asize)); - NDR_ALLOC_N(ndr, r->out.sids, nptrs); - for (i=0;i<nptrs;i++) { - NDR_CHECK(ndr_pull_u32(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.status)); - return NT_STATUS_OK; -} diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h deleted file mode 100644 index 0cc43b5f86..0000000000 --- a/source4/libcli/ndr/ndr_lsa.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - 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. -*/ - -struct lsa_QosInfo { - uint16 impersonation_level; - uint8 context_mode; - uint8 effective_only; -}; - -struct lsa_ObjectAttribute { - const char *root_dir; - const char *object_name; - uint32 attributes; - struct security_descriptor *sec_desc; - struct lsa_QosInfo *sec_qos; -}; - -struct lsa_OpenPolicy { - struct { - const char *system_name; - struct lsa_ObjectAttribute *attr; - uint32 desired_access; - } in; - struct { - struct policy_handle handle; - NTSTATUS status; - } out; -}; - -struct lsa_OpenPolicy2 { - struct { - const char *system_name; - struct lsa_ObjectAttribute *attr; - uint32 desired_access; - } in; - struct { - struct policy_handle handle; - NTSTATUS status; - } 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 status; - } out; -}; diff --git a/source4/libcli/ndr/ndr_misc.c b/source4/libcli/ndr/ndr_misc.c deleted file mode 100644 index cdd6652068..0000000000 --- a/source4/libcli/ndr/ndr_misc.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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/libcli/ndr/ndr_misc.h b/source4/libcli/ndr/ndr_misc.h deleted file mode 100644 index cc3576b3e8..0000000000 --- a/source4/libcli/ndr/ndr_misc.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - 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/libcli/ndr/ndr_sec.c b/source4/libcli/ndr/ndr_sec.c deleted file mode 100644 index 9ac5240b0f..0000000000 --- a/source4/libcli/ndr/ndr_sec.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - 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_u8(ndr, &ace->type)); - NDR_CHECK(ndr_pull_u8(ndr, &ace->flags)); - NDR_CHECK(ndr_pull_u16(ndr, &size)); - NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); - - NDR_CHECK(ndr_pull_u32(ndr, &ace->access_mask)); - - if (sec_ace_object(ace->type)) { - NDR_ALLOC(ndr, ace->obj); - NDR_CHECK(ndr_pull_u32(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_u16(ndr, &acl->revision)); - NDR_CHECK(ndr_pull_u16(ndr, &size)); - NDR_CHECK(ndr_pull_limit_size(ndr, size, 4)); - NDR_CHECK(ndr_pull_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_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_u32(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_u8(ndr, &sid->sid_rev_num)); - NDR_CHECK(ndr_pull_u8(ndr, &sid->num_auths)); - for (i=0;i<6;i++) { - NDR_CHECK(ndr_pull_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_pull_u32(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_u32(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_u32(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_u8(ndr, &(*sd)->revision)); - NDR_CHECK(ndr_pull_u16(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_u8(ndr, ace->type)); - NDR_CHECK(ndr_push_u8(ndr, ace->flags)); - ndr_push_save(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 0)); - NDR_CHECK(ndr_push_u32(ndr, ace->access_mask)); - - if (sec_ace_object(ace->type)) { - NDR_CHECK(ndr_push_u32(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_u16(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_u16(ndr, acl->revision)); - ndr_push_save(ndr, &save1); - NDR_CHECK(ndr_push_u16(ndr, 0)); - NDR_CHECK(ndr_push_u32(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_u16(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_u8(ndr, sid->sid_rev_num)); - NDR_CHECK(ndr_push_u8(ndr, sid->num_auths)); - for (i=0;i<6;i++) { - NDR_CHECK(ndr_push_u8(ndr, sid->id_auth[i])); - } - for (i=0;i<sid->num_auths;i++) { - NDR_CHECK(ndr_push_u32(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_u8(ndr, sd->revision)); - NDR_CHECK(ndr_push_u16(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/libcli/ndr/ndr_sec.h b/source4/libcli/ndr/ndr_sec.h deleted file mode 100644 index 0c9d542006..0000000000 --- a/source4/libcli/ndr/ndr_sec.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - 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; -}; diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c deleted file mode 100644 index 0541200015..0000000000 --- a/source4/libcli/raw/rawdcerpc.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - Unix SMB/CIFS implementation. - raw dcerpc operations - - Copyright (C) Tim Potter 2003 - 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" - - -/* - open a rpc connection to a named pipe -*/ -NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, const char *pipe_name) -{ - NTSTATUS status; - char *name = NULL; - union smb_open io; - TALLOC_CTX *mem_ctx; - - asprintf(&name, "\\%s", pipe_name); - if (!name) { - return NT_STATUS_NO_MEMORY; - } - - io.ntcreatex.level = RAW_OPEN_NTCREATEX; - io.ntcreatex.in.flags = 0; - io.ntcreatex.in.root_fid = 0; - io.ntcreatex.in.access_mask = - STD_RIGHT_READ_CONTROL_ACCESS | - SA_RIGHT_FILE_WRITE_ATTRIBUTES | - SA_RIGHT_FILE_WRITE_EA | - GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; - io.ntcreatex.in.file_attr = 0; - io.ntcreatex.in.alloc_size = 0; - io.ntcreatex.in.share_access = - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE; - io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; - io.ntcreatex.in.create_options = 0; - io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION; - io.ntcreatex.in.security_flags = 0; - io.ntcreatex.in.fname = name; - - mem_ctx = talloc_init("torture_rpc_connection"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - status = smb_raw_open(p->tree, mem_ctx, &io); - free(name); - talloc_destroy(mem_ctx); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - p->fnum = io.ntcreatex.out.fnum; - - /* bind to the pipe, using the pipe_name as the key */ - status = dcerpc_bind_byname(p, pipe_name); - - if (!NT_STATUS_IS_OK(status)) { - union smb_close c; - c.close.level = RAW_CLOSE_CLOSE; - c.close.in.fnum = p->fnum; - c.close.in.write_time = 0; - smb_raw_close(p->tree, &c); - } - - return status; -} - - -struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob) -{ - struct smb_trans2 trans; - uint16 setup[2]; - struct cli_request *req; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_raw_send"); - if (!mem_ctx) return NULL; - - trans.in.data = *blob; - trans.in.params = data_blob(NULL, 0); - - setup[0] = TRANSACT_DCERPCCMD; - setup[1] = p->fnum; - - trans.in.max_param = 0; - trans.in.max_data = 0x8000; - trans.in.max_setup = 0; - trans.in.setup_count = 2; - trans.in.flags = 0; - trans.in.timeout = 0; - trans.in.setup = setup; - trans.in.trans_name = "\\PIPE\\"; - - req = smb_raw_trans_send(p->tree, &trans); - - talloc_destroy(mem_ctx); - - return req; -} - - -NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p, - struct cli_request *req, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - struct smb_trans2 trans; - NTSTATUS status; - uint16 frag_length; - DATA_BLOB payload; - - status = smb_raw_trans_recv(req, mem_ctx, &trans); - /* STATUS_BUFFER_OVERFLOW means that there is more data - available via SMBreadX */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - payload = trans.out.data; - - if (trans.out.data.length < 16 || - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - goto done; - } - - /* we might have recieved a partial fragment, in which case we - need to pull the rest of it */ - frag_length = SVAL(payload.data, 8); - if (frag_length <= payload.length) { - goto done; - } - - /* make sure the payload can hold the whole fragment */ - payload.data = talloc_realloc(mem_ctx, payload.data, frag_length); - if (!payload.data) { - return NT_STATUS_NO_MEMORY; - } - - /* the rest of the data is available via SMBreadX */ - while (frag_length > payload.length) { - uint32 n; - union smb_read io; - - n = frag_length - payload.length; - if (n > 0xFF00) { - n = 0xFF00; - } - - io.generic.level = RAW_READ_READX; - io.readx.in.fnum = p->fnum; - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.in.offset = 0; - io.readx.in.remaining = 0; - io.readx.out.data = payload.data + payload.length; - status = smb_raw_read(p->tree, &io); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - break; - } - - n = io.readx.out.nread; - if (n == 0) { - status = NT_STATUS_UNSUCCESSFUL; - break; - } - - payload.length += n; - - /* if the SMBreadX returns NT_STATUS_OK then there - isn't any more data to be read */ - if (NT_STATUS_IS_OK(status)) { - break; - } - } - -done: - if (blob) { - *blob = payload; - } - - return status; -} - -NTSTATUS dcerpc_raw_packet(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *request_blob, - DATA_BLOB *reply_blob) -{ - struct cli_request *req; - req = dcerpc_raw_send(p, request_blob); - return dcerpc_raw_recv(p, req, mem_ctx, reply_blob); -} - - -/* - retrieve a secondary pdu from a pipe -*/ -NTSTATUS dcerpc_raw_packet_secondary(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - union smb_read io; - uint32 n = 0x2000; - uint32 frag_length; - NTSTATUS status; - - *blob = data_blob_talloc(mem_ctx, NULL, n); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - io.generic.level = RAW_READ_READX; - io.readx.in.fnum = p->fnum; - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.in.offset = 0; - io.readx.in.remaining = 0; - io.readx.out.data = blob->data; - - status = smb_raw_read(p->tree, &io); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - blob->length = io.readx.out.nread; - - if (blob->length < 16) { - return status; - } - - frag_length = SVAL(blob->data, 8); - if (frag_length <= blob->length) { - return status; - } - - blob->data = talloc_realloc(mem_ctx, blob->data, frag_length); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - while (frag_length > blob->length && - NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - - n = frag_length - blob->length; - if (n > 0xFF00) { - n = 0xFF00; - } - - io.readx.in.mincnt = n; - io.readx.in.maxcnt = n; - io.readx.out.data = blob->data + blob->length; - status = smb_raw_read(p->tree, &io); - - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) { - return status; - } - - n = io.readx.out.nread; - blob->length += n; - } - - return status; -} - - -/* - send an initial pdu in a multi-pdu sequence -*/ -NTSTATUS dcerpc_raw_packet_initial(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - DATA_BLOB *blob) -{ - union smb_write io; - NTSTATUS status; - - io.generic.level = RAW_WRITE_WRITEX; - io.writex.in.fnum = p->fnum; - io.writex.in.offset = 0; - io.writex.in.wmode = PIPE_START_MESSAGE; - io.writex.in.remaining = blob->length; - io.writex.in.count = blob->length; - io.writex.in.data = blob->data; - - status = smb_raw_write(p->tree, &io); - if (NT_STATUS_IS_OK(status)) { - return status; - } - - /* make sure it accepted it all */ - if (io.writex.out.nwritten != blob->length) { - return NT_STATUS_UNSUCCESSFUL; - } - - return status; -} diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c deleted file mode 100644 index 9e6c05e7ae..0000000000 --- a/source4/libcli/rpc/dcerpc.c +++ /dev/null @@ -1,804 +0,0 @@ -/* - Unix SMB/CIFS implementation. - raw dcerpc operations - - Copyright (C) Tim Potter 2003 - 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" - -/* initialise a dcerpc pipe. This currently assumes a SMB named pipe - transport */ -struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree) -{ - struct dcerpc_pipe *p; - - TALLOC_CTX *mem_ctx = talloc_init("dcerpc_tree"); - if (mem_ctx == NULL) - return NULL; - - p = talloc(mem_ctx, sizeof(*p)); - if (!p) { - talloc_destroy(mem_ctx); - return NULL; - } - - p->reference_count = 0; - p->mem_ctx = mem_ctx; - p->tree = tree; - p->tree->reference_count++; - p->call_id = 1; - p->fnum = 0; - - return p; -} - -/* close down a dcerpc over SMB pipe */ -void dcerpc_pipe_close(struct dcerpc_pipe *p) -{ - if (!p) return; - p->reference_count--; - if (p->reference_count <= 0) { - cli_tree_close(p->tree); - talloc_destroy(p->mem_ctx); - } -} - -#define BLOB_CHECK_BOUNDS(blob, offset, len) do { \ - if ((offset) > blob->length || (blob->length - (offset) < (len))) { \ - return NT_STATUS_INVALID_PARAMETER; \ - } \ -} while (0) - -#define DCERPC_ALIGN(offset, n) do { \ - (offset) = ((offset) + ((n)-1)) & ~((n)-1); \ -} while (0) - -/* - pull a wire format uuid into a string. This will consume 16 bytes -*/ -static char *dcerpc_pull_uuid(char *data, TALLOC_CTX *mem_ctx) -{ - uint32 time_low; - uint16 time_mid, time_hi_and_version; - uint8 clock_seq_hi_and_reserved; - uint8 clock_seq_low; - uint8 node[6]; - int i; - - time_low = IVAL(data, 0); - time_mid = SVAL(data, 4); - time_hi_and_version = SVAL(data, 6); - clock_seq_hi_and_reserved = CVAL(data, 8); - clock_seq_low = CVAL(data, 9); - for (i=0;i<6;i++) { - node[i] = CVAL(data, 10 + i); - } - - return talloc_asprintf(mem_ctx, - "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - time_low, time_mid, time_hi_and_version, - clock_seq_hi_and_reserved, clock_seq_low, - node[0], node[1], node[2], node[3], node[4], node[5]); -} - -/* - push a uuid_str into wire format. It will consume 16 bytes -*/ -static NTSTATUS push_uuid_str(char *data, const char *uuid_str) -{ - uint32 time_low; - uint32 time_mid, time_hi_and_version; - uint32 clock_seq_hi_and_reserved; - uint32 clock_seq_low; - uint32 node[6]; - int i; - - if (11 != sscanf(uuid_str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - &time_low, &time_mid, &time_hi_and_version, - &clock_seq_hi_and_reserved, &clock_seq_low, - &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { - return NT_STATUS_INVALID_PARAMETER; - } - - SIVAL(data, 0, time_low); - SSVAL(data, 4, time_mid); - SSVAL(data, 6, time_hi_and_version); - SCVAL(data, 8, clock_seq_hi_and_reserved); - SCVAL(data, 9, clock_seq_low); - for (i=0;i<6;i++) { - SCVAL(data, 10 + i, node[i]); - } - - return NT_STATUS_OK; -} - -/* - pull a dcerpc syntax id from a blob -*/ -static NTSTATUS dcerpc_pull_syntax_id(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_syntax_id *syntax) -{ - syntax->uuid_str = dcerpc_pull_uuid(blob->data + (*offset), mem_ctx); - if (!syntax->uuid_str) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += 16; - syntax->if_version = IVAL(blob->data, *offset); - (*offset) += 4; - return NT_STATUS_OK; -} - -/* - push a syntax id onto the wire. It will consume 20 bytes -*/ -static NTSTATUS push_syntax_id(char *data, const struct dcerpc_syntax_id *syntax) -{ - NTSTATUS status; - - status = push_uuid_str(data, syntax->uuid_str); - SIVAL(data, 16, syntax->if_version); - - return status; -} - -/* - pull an auth verifier from a packet -*/ -static NTSTATUS dcerpc_pull_auth_verifier(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - DATA_BLOB *auth) -{ - if (hdr->auth_length == 0) { - return NT_STATUS_OK; - } - - BLOB_CHECK_BOUNDS(blob, *offset, hdr->auth_length); - *auth = data_blob_talloc(mem_ctx, blob->data + (*offset), hdr->auth_length); - if (!auth->data) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += hdr->auth_length; - return NT_STATUS_OK; -} - -/* - parse a struct dcerpc_response -*/ -static NTSTATUS dcerpc_pull_response(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_response *pkt) -{ - uint32 stub_len; - - BLOB_CHECK_BOUNDS(blob, *offset, 8); - - pkt->alloc_hint = IVAL(blob->data, (*offset) + 0); - pkt->context_id = SVAL(blob->data, (*offset) + 4); - pkt->cancel_count = CVAL(blob->data, (*offset) + 6); - - (*offset) += 8; - - stub_len = blob->length - ((*offset) + hdr->auth_length); - BLOB_CHECK_BOUNDS(blob, *offset, stub_len); - pkt->stub_data = data_blob_talloc(mem_ctx, blob->data + (*offset), stub_len); - if (stub_len != 0 && !pkt->stub_data.data) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += stub_len; - - return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); -} - - -/* - parse a struct bind_ack -*/ -static NTSTATUS dcerpc_pull_bind_ack(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_bind_ack *pkt) -{ - uint16 len; - int i; - - BLOB_CHECK_BOUNDS(blob, *offset, 10); - pkt->max_xmit_frag = SVAL(blob->data, (*offset) + 0); - pkt->max_recv_frag = SVAL(blob->data, (*offset) + 2); - pkt->assoc_group_id = IVAL(blob->data, (*offset) + 4); - len = SVAL(blob->data, (*offset) + 8); - (*offset) += 10; - - if (len) { - BLOB_CHECK_BOUNDS(blob, *offset, len); - pkt->secondary_address = talloc_strndup(mem_ctx, blob->data + (*offset), len); - if (!pkt->secondary_address) { - return NT_STATUS_NO_MEMORY; - } - (*offset) += len; - } - - DCERPC_ALIGN(*offset, 4); - BLOB_CHECK_BOUNDS(blob, *offset, 4); - pkt->num_results = CVAL(blob->data, *offset); - (*offset) += 4; - - if (pkt->num_results > 0) { - pkt->ctx_list = talloc(mem_ctx, sizeof(pkt->ctx_list[0]) * pkt->num_results); - if (!pkt->ctx_list) { - return NT_STATUS_NO_MEMORY; - } - } - - for (i=0;i<pkt->num_results;i++) { - NTSTATUS status; - - BLOB_CHECK_BOUNDS(blob, *offset, 24); - pkt->ctx_list[i].result = IVAL(blob->data, *offset); - (*offset) += 4; - status = dcerpc_pull_syntax_id(blob, mem_ctx, offset, &pkt->ctx_list[i].syntax); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - - return dcerpc_pull_auth_verifier(blob, mem_ctx, offset, hdr, &pkt->auth_verifier); -} - - -/* - parse a dcerpc header -*/ -static NTSTATUS dcerpc_pull_hdr(DATA_BLOB *blob, uint32 *offset, struct dcerpc_hdr *hdr) -{ - BLOB_CHECK_BOUNDS(blob, *offset, 16); - - hdr->rpc_vers = CVAL(blob->data, (*offset) + 0); - hdr->rpc_vers_minor = CVAL(blob->data, (*offset) + 1); - hdr->ptype = CVAL(blob->data, (*offset) + 2); - hdr->pfc_flags = CVAL(blob->data, (*offset) + 3); - memcpy(hdr->drep, blob->data + (*offset) + 4, 4); - hdr->frag_length = SVAL(blob->data, (*offset) + 8); - hdr->auth_length = SVAL(blob->data, (*offset) + 10); - hdr->call_id = IVAL(blob->data, (*offset) + 12); - - (*offset) += 16; - - return NT_STATUS_OK; -} - -/* - parse a dcerpc header. It consumes 16 bytes -*/ -static void dcerpc_push_hdr(char *data, struct dcerpc_hdr *hdr) -{ - SCVAL(data, 0, hdr->rpc_vers); - SCVAL(data, 1, hdr->rpc_vers_minor); - SCVAL(data, 2, hdr->ptype); - SCVAL(data, 3, hdr->pfc_flags); - memcpy(data + 4, hdr->drep, 4); - SSVAL(data, 8, hdr->frag_length); - SSVAL(data, 12, hdr->call_id); -} - - - -/* - parse a data blob into a dcerpc_packet structure. This handles both - input and output packets -*/ -NTSTATUS dcerpc_pull(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) -{ - NTSTATUS status; - uint32 offset = 0; - - status = dcerpc_pull_hdr(blob, &offset, &pkt->hdr); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_BIND_ACK: - status = dcerpc_pull_bind_ack(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.bind_ack); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - case DCERPC_PKT_RESPONSE: - status = dcerpc_pull_response(blob, mem_ctx, &offset, &pkt->hdr, &pkt->out.response); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - break; - - default: - return NT_STATUS_INVALID_LEVEL; - } - - return status; -} - - -/* - push a dcerpc_bind into a blob -*/ -static NTSTATUS dcerpc_push_bind(DATA_BLOB *blob, uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_bind *pkt) -{ - int i, j; - - SSVAL(blob->data, (*offset) + 0, pkt->max_xmit_frag); - SSVAL(blob->data, (*offset) + 2, pkt->max_recv_frag); - SIVAL(blob->data, (*offset) + 4, pkt->assoc_group_id); - SCVAL(blob->data, (*offset) + 8, pkt->num_contexts); - (*offset) += 12; - - for (i=0;i<pkt->num_contexts;i++) { - NTSTATUS status; - - SSVAL(blob->data, (*offset) + 0, pkt->ctx_list[i].context_id); - SCVAL(blob->data, (*offset) + 2, pkt->ctx_list[i].num_transfer_syntaxes); - status = push_syntax_id(blob->data + (*offset) + 4, &pkt->ctx_list[i].abstract_syntax); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*offset) += 24; - for (j=0;j<pkt->ctx_list[i].num_transfer_syntaxes;j++) { - status = push_syntax_id(blob->data + (*offset), - &pkt->ctx_list[i].transfer_syntaxes[j]); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - (*offset) += 20; - } - } - - return NT_STATUS_OK; -} - -/* - push a dcerpc_request into a blob -*/ -static NTSTATUS dcerpc_push_request(DATA_BLOB *blob, uint32 *offset, - struct dcerpc_hdr *hdr, - struct dcerpc_request *pkt) -{ - SIVAL(blob->data, (*offset) + 0, pkt->alloc_hint); - SSVAL(blob->data, (*offset) + 4, pkt->context_id); - SSVAL(blob->data, (*offset) + 6, pkt->opnum); - - (*offset) += 8; - - memcpy(blob->data + (*offset), pkt->stub_data.data, pkt->stub_data.length); - (*offset) += pkt->stub_data.length; - - memcpy(blob->data + (*offset), pkt->auth_verifier.data, pkt->auth_verifier.length); - (*offset) += pkt->auth_verifier.length; - - return NT_STATUS_OK; -} - - -/* - work out the wire size of a dcerpc packet -*/ -static uint32 dcerpc_wire_size(struct dcerpc_packet *pkt) -{ - int i; - uint32 size = 0; - - size += 16; /* header */ - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_REQUEST: - size += 8; - size += pkt->in.request.stub_data.length; - size += pkt->in.request.auth_verifier.length; - break; - - case DCERPC_PKT_RESPONSE: - size += 8; - size += pkt->out.response.stub_data.length; - size += pkt->hdr.auth_length; - break; - - case DCERPC_PKT_BIND: - size += 12; - for (i=0;i<pkt->in.bind.num_contexts;i++) { - size += 24; - size += pkt->in.bind.ctx_list[i].num_transfer_syntaxes * 20; - } - size += pkt->hdr.auth_length; - break; - - case DCERPC_PKT_BIND_ACK: - size += 10; - if (pkt->out.bind_ack.secondary_address) { - size += strlen(pkt->out.bind_ack.secondary_address) + 1; - } - size += 4; - size += pkt->out.bind_ack.num_results * 24; - size += pkt->hdr.auth_length; - break; - } - - return size; -} - -/* - push a dcerpc_packet into a blob. This handles both input and - output packets -*/ -NTSTATUS dcerpc_push(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct dcerpc_packet *pkt) -{ - uint32 offset = 0; - uint32 wire_size; - NTSTATUS status; - - /* work out how big the packet will be on the wire */ - wire_size = dcerpc_wire_size(pkt); - - (*blob) = data_blob_talloc(mem_ctx, NULL, wire_size); - if (!blob->data) { - return NT_STATUS_NO_MEMORY; - } - - pkt->hdr.frag_length = wire_size; - - dcerpc_push_hdr(blob->data + offset, &pkt->hdr); - offset += 16; - - switch (pkt->hdr.ptype) { - case DCERPC_PKT_BIND: - status = dcerpc_push_bind(blob, &offset, &pkt->hdr, &pkt->in.bind); - break; - - case DCERPC_PKT_REQUEST: - status = dcerpc_push_request(blob, &offset, &pkt->hdr, &pkt->in.request); - break; - - default: - status = NT_STATUS_INVALID_LEVEL; - } - - return status; -} - - - - -/* - fill in the fixed values in a dcerpc header -*/ -static void init_dcerpc_hdr(struct dcerpc_hdr *hdr) -{ - hdr->rpc_vers = 5; - hdr->rpc_vers_minor = 0; - hdr->drep[0] = 0x10; /* Little endian */ - hdr->drep[1] = 0; - hdr->drep[2] = 0; - hdr->drep[3] = 0; -} - - -/* - perform a bind using the given syntax -*/ -NTSTATUS dcerpc_bind(struct dcerpc_pipe *p, - const struct dcerpc_syntax_id *syntax, - const struct dcerpc_syntax_id *transfer_syntax) -{ - TALLOC_CTX *mem_ctx; - struct dcerpc_packet pkt; - NTSTATUS status; - DATA_BLOB blob; - DATA_BLOB blob_out; - - mem_ctx = talloc_init("dcerpc_bind"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - init_dcerpc_hdr(&pkt.hdr); - - pkt.hdr.ptype = DCERPC_PKT_BIND; - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.hdr.call_id = p->call_id++; - pkt.hdr.auth_length = 0; - - pkt.in.bind.max_xmit_frag = 0x2000; - pkt.in.bind.max_recv_frag = 0x2000; - pkt.in.bind.assoc_group_id = 0; - pkt.in.bind.num_contexts = 1; - pkt.in.bind.ctx_list = talloc(mem_ctx, sizeof(pkt.in.bind.ctx_list[0])); - if (!pkt.in.bind.ctx_list) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - pkt.in.bind.ctx_list[0].context_id = 0; - pkt.in.bind.ctx_list[0].num_transfer_syntaxes = 1; - pkt.in.bind.ctx_list[0].abstract_syntax = *syntax; - pkt.in.bind.ctx_list[0].transfer_syntaxes = transfer_syntax; - - pkt.in.bind.auth_verifier = data_blob(NULL, 0); - - status = dcerpc_push(&blob, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - status = dcerpc_raw_packet(p, mem_ctx, &blob, &blob_out); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - - if (pkt.hdr.ptype != DCERPC_PKT_BIND_ACK) { - status = NT_STATUS_UNSUCCESSFUL; - } - - p->srv_max_xmit_frag = pkt.out.bind_ack.max_xmit_frag; - p->srv_max_recv_frag = pkt.out.bind_ack.max_recv_frag; - - talloc_destroy(mem_ctx); - - return status; -} - -static const struct { - const char *name; - struct dcerpc_syntax_id syntax; - const struct dcerpc_syntax_id transfer_syntax; -} known_pipes[] = { - { "lsarpc" , { "12345778-1234-abcd-ef00-0123456789ab", 0 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "samr" , { "12345778-1234-abcd-ef00-0123456789ac", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "netlogon", { "12345778-1234-abcd-ef00-01234567cffb", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "srvsvc" , { "4b324fc8-1670-01d3-1278-5a47bf6ee188", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "wkssvc" , { "6bffd098-a112-3610-9833-46c3f87e345a", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "winreg" , { "338cd001-2244-31f1-aaaa-900038001003", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "spoolss" , { "12345678-1234-abcd-ef00-0123456789ab", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "netdfs" , { "4fc742e0-4a10-11cf-8273-00aa004ae673", 3 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { "rpcecho" , { "60a15ec5-4de8-11d7-a637-005056a20182", 1 }, DCERPC_TRANSFER_SYNTAX_V2 }, - { NULL , } -}; - - -/* Perform a bind using the given well-known pipe name */ -NTSTATUS dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name) -{ - int i; - - for (i=0; known_pipes[i].name; i++) { - if (strcasecmp(known_pipes[i].name, pipe_name) == 0) - break; - } - - if (known_pipes[i].name == NULL) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - return dcerpc_bind(p, &known_pipes[i].syntax, &known_pipes[i].transfer_syntax); -} - -/* - perform a full request/response pair on a dcerpc pipe -*/ -NTSTATUS dcerpc_request(struct dcerpc_pipe *p, - uint16 opnum, - TALLOC_CTX *mem_ctx, - DATA_BLOB *stub_data_in, - DATA_BLOB *stub_data_out) -{ - - struct dcerpc_packet pkt; - NTSTATUS status; - DATA_BLOB blob_in, blob_out, payload; - uint32 remaining, chunk_size; - - init_dcerpc_hdr(&pkt.hdr); - - remaining = stub_data_in->length; - - /* we can write a full max_recv_frag size, minus the dcerpc - request header size */ - chunk_size = p->srv_max_recv_frag - 24; - - pkt.hdr.ptype = DCERPC_PKT_REQUEST; - pkt.hdr.call_id = p->call_id++; - pkt.hdr.auth_length = 0; - pkt.in.request.alloc_hint = remaining; - pkt.in.request.context_id = 0; - pkt.in.request.opnum = opnum; - pkt.in.request.auth_verifier = data_blob(NULL, 0); - - /* we send a series of pdus without waiting for a reply until - the last pdu */ - while (remaining > chunk_size) { - if (remaining == stub_data_in->length) { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST; - } else { - pkt.hdr.pfc_flags = 0; - } - - pkt.in.request.stub_data.data = stub_data_in->data + - (stub_data_in->length - remaining); - pkt.in.request.stub_data.length = chunk_size; - - status = dcerpc_push(&blob_in, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = dcerpc_raw_packet_initial(p, mem_ctx, &blob_in); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - remaining -= chunk_size; - } - - /* now we send a pdu with LAST_FRAG sent and get the first - part of the reply */ - if (remaining == stub_data_in->length) { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - } else { - pkt.hdr.pfc_flags = DCERPC_PFC_FLAG_LAST; - } - pkt.in.request.stub_data.data = stub_data_in->data + - (stub_data_in->length - remaining); - pkt.in.request.stub_data.length = remaining; - - status = dcerpc_push(&blob_in, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* send the pdu and get the initial response pdu */ - status = dcerpc_raw_packet(p, mem_ctx, &blob_in, &blob_out); - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { - return NT_STATUS_UNSUCCESSFUL; - } - - if (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { - /* something is badly wrong! */ - return NT_STATUS_UNSUCCESSFUL; - } - - payload = pkt.out.response.stub_data; - - /* continue receiving fragments */ - while (!(pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_LAST)) { - uint32 length; - - status = dcerpc_raw_packet_secondary(p, mem_ctx, &blob_out); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = dcerpc_pull(&blob_out, mem_ctx, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (pkt.hdr.pfc_flags & DCERPC_PFC_FLAG_FIRST) { - /* start of another packet!? */ - return NT_STATUS_UNSUCCESSFUL; - } - - if (pkt.hdr.ptype != DCERPC_PKT_RESPONSE) { - return NT_STATUS_UNSUCCESSFUL; - } - - length = pkt.out.response.stub_data.length; - - payload.data = talloc_realloc(mem_ctx, - payload.data, - payload.length + length); - if (!payload.data) { - return NT_STATUS_NO_MEMORY; - } - - memcpy(payload.data + payload.length, - pkt.out.response.stub_data.data, - length); - - payload.length += length; - } - - if (stub_data_out) { - *stub_data_out = payload; - } - - return status; -} - - -/* - a useful helper function for synchronous rpc requests - - this can be used when you have ndr push/pull functions in the - standard format -*/ -NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p, - uint32 opnum, - TALLOC_CTX *mem_ctx, - NTSTATUS (*ndr_push)(struct ndr_push *, void *), - NTSTATUS (*ndr_pull)(struct ndr_pull *, void *), - void *struct_ptr) -{ - struct ndr_push *push; - struct ndr_pull *pull; - NTSTATUS status; - DATA_BLOB request, response; - - /* setup for a ndr_push_* call */ - push = ndr_push_init(); - if (!push) { - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - /* push the structure into a blob */ - status = ndr_push(push, struct_ptr); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - /* retrieve the blob */ - request = ndr_push_blob(push); - - /* make the actual dcerpc request */ - status = dcerpc_request(p, opnum, mem_ctx, &request, &response); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - - /* prepare for ndr_pull_* */ - pull = ndr_pull_init_blob(&response, mem_ctx); - if (!pull) { - goto failed; - } - - /* pull the structure from the blob */ - status = ndr_pull(pull, struct_ptr); - if (!NT_STATUS_IS_OK(status)) { - goto failed; - } - -failed: - ndr_push_free(push); - return status; -} diff --git a/source4/libcli/rpc/dcerpc.h b/source4/libcli/rpc/dcerpc.h deleted file mode 100644 index 09ddc3625c..0000000000 --- a/source4/libcli/rpc/dcerpc.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - Unix SMB/CIFS implementation. - DCERPC interface structures - - Copyright (C) Tim Potter 2003 - 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://www.opengroup.org/onlinepubs/9629399/chap12.htm for details - of these structures - - note that the structure definitions here don't include some of the - fields that are wire-artifacts. Those are put on the wire by the - marshalling/unmarshalling routines in decrpc.c -*/ - -struct dcerpc_pipe { - TALLOC_CTX *mem_ctx; - uint16 fnum; - int reference_count; - uint32 call_id; - uint32 srv_max_xmit_frag; - uint32 srv_max_recv_frag; - struct cli_tree *tree; -}; - -/* dcerpc packet types */ -#define DCERPC_PKT_REQUEST 0 -#define DCERPC_PKT_RESPONSE 2 -#define DCERPC_PKT_BIND 11 -#define DCERPC_PKT_BIND_ACK 12 -#define DCERPC_PKT_BIND_NAK 13 - -/* hdr.pfc_flags */ -#define DCERPC_PFC_FLAG_FIRST 0x01 -#define DCERPC_PFC_FLAG_LAST 0x02 -#define DCERPC_PFC_FLAG_NOCALL 0x20 - -/* - all dcerpc packets use this structure. -*/ -struct dcerpc_packet { - /* all requests and responses contain a dcerpc header */ - struct dcerpc_hdr { - uint8 rpc_vers; /* RPC version */ - uint8 rpc_vers_minor; /* Minor version */ - uint8 ptype; /* Packet type */ - uint8 pfc_flags; /* Fragmentation flags */ - uint8 drep[4]; /* NDR data representation */ - uint16 frag_length; /* Total length of fragment */ - uint16 auth_length; /* authenticator length */ - uint32 call_id; /* Call identifier */ - } hdr; - - union { - struct dcerpc_bind { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - uint8 num_contexts; - struct { - uint16 context_id; - uint8 num_transfer_syntaxes; - struct dcerpc_syntax_id { - const char *uuid_str; - uint32 if_version; - } abstract_syntax; - const struct dcerpc_syntax_id *transfer_syntaxes; - } *ctx_list; - DATA_BLOB auth_verifier; - } bind; - - struct dcerpc_request { - uint32 alloc_hint; - uint16 context_id; - uint16 opnum; - DATA_BLOB stub_data; - DATA_BLOB auth_verifier; - } request; - } in; - - union { - struct dcerpc_bind_ack { - uint16 max_xmit_frag; - uint16 max_recv_frag; - uint32 assoc_group_id; - const char *secondary_address; - uint8 num_results; - struct { - uint32 result; - struct dcerpc_syntax_id syntax; - } *ctx_list; - DATA_BLOB auth_verifier; - } bind_ack; - - struct dcerpc_bind_nak { - uint16 reject_reason; - uint32 num_versions; - uint32 *versions; - } bind_nak; - - struct dcerpc_response { - uint32 alloc_hint; - uint16 context_id; - uint8 cancel_count; - DATA_BLOB stub_data; - DATA_BLOB auth_verifier; - } response; - } out; -}; - -/* this seems to be the only transfer syntax used */ -#define DCERPC_TRANSFER_SYNTAX_V2 {"8a885d04-1ceb-11c9-9fe8-08002b104860", 2} - diff --git a/source4/libcli/rpc/rpc_echo.c b/source4/libcli/rpc/rpc_echo.c deleted file mode 100644 index d73f9bda9c..0000000000 --- a/source4/libcli/rpc/rpc_echo.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - rpc echo pipe calls - - 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" - -/* - addone interface -*/ -NTSTATUS dcerpc_rpcecho_addone(struct dcerpc_pipe *p, - int in_data, int *out_data) -{ - struct rpcecho_addone r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_rpcecho_addone"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.data = in_data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_ADDONE, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_addone, - (ndr_pull_fn_t) ndr_pull_rpcecho_addone, - &r); - - /* and extract the .out parameters */ - *out_data = r.out.data; - - talloc_destroy(mem_ctx); - return status; -} - - -/* - echodata interface -*/ -NTSTATUS dcerpc_rpcecho_echodata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - const char *in_data, - int *out_len, - char **out_data) -{ - struct rpcecho_echodata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - r.in.data = in_data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_ECHODATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_echodata, - (ndr_pull_fn_t) ndr_pull_rpcecho_echodata, - &r); - - /* and extract the .out parameters */ - *out_len = r.out.len; - *out_data = r.out.data; - - return status; -} - -/* - sourcedata interface -*/ -NTSTATUS dcerpc_rpcecho_sourcedata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - int *out_len, - char **out_data) -{ - struct rpcecho_sourcedata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_SOURCEDATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_sourcedata, - (ndr_pull_fn_t) ndr_pull_rpcecho_sourcedata, - &r); - - /* and extract the .out parameters */ - *out_len = r.out.len; - *out_data = r.out.data; - - return status; -} - -/* - sinkdata interface -*/ -NTSTATUS dcerpc_rpcecho_sinkdata(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - int len, - char *data) -{ - struct rpcecho_sinkdata r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.len = len; - r.in.data = data; - - /* make the call */ - status = dcerpc_ndr_request(p, RPCECHO_CALL_SINKDATA, mem_ctx, - (ndr_push_fn_t) ndr_push_rpcecho_sinkdata, - (ndr_pull_fn_t) ndr_pull_rpcecho_sinkdata, - &r); - - return status; -} diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c deleted file mode 100644 index 65d6a81491..0000000000 --- a/source4/libcli/rpc/rpc_lsa.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - rpc lsa pipe calls - - 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" - -/* - OpenPolicy interface -*/ -NTSTATUS dcerpc_lsa_OpenPolicy(struct dcerpc_pipe *p, - const char *server, - struct lsa_ObjectAttribute *attr, - uint32 access_mask, - struct policy_handle *handle) -{ - struct lsa_OpenPolicy r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_lsa_openpolicy"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.system_name = server; - r.in.attr = attr; - r.in.desired_access = access_mask; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_OPENPOLICY, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_OpenPolicy, - (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *handle = r.out.handle; - status = r.out.status; - -done: - talloc_destroy(mem_ctx); - return status; -} - - -/* - OpenPolicy2 interface -*/ -NTSTATUS dcerpc_lsa_OpenPolicy2(struct dcerpc_pipe *p, - const char *server, - struct lsa_ObjectAttribute *attr, - uint32 access_mask, - struct policy_handle *handle) -{ - struct lsa_OpenPolicy2 r; - NTSTATUS status; - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcerpc_lsa_openpolicy2"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - /* fill the .in side of the call */ - r.in.system_name = server; - r.in.attr = attr; - r.in.desired_access = access_mask; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_OPENPOLICY2, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_OpenPolicy2, - (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy2, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *handle = r.out.handle; - status = r.out.status; - -done: - talloc_destroy(mem_ctx); - return status; -} - -/* - EnumSids interface -*/ -NTSTATUS dcerpc_lsa_EnumSids(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct policy_handle *handle, - uint32 resume_handle, - uint32 *num_entries, - struct dom_sid ***sids) -{ - struct lsa_EnumSids r; - NTSTATUS status; - - /* fill the .in side of the call */ - r.in.handle = handle; - r.in.start_at = 0; - r.in.num_entries = *num_entries; - - /* make the call */ - status = dcerpc_ndr_request(p, LSA_ENUM_ACCOUNTS, mem_ctx, - (ndr_push_fn_t) ndr_push_lsa_EnumSids, - (ndr_pull_fn_t) ndr_pull_lsa_EnumSids, - &r); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - /* and extract the .out parameters */ - *num_entries = r.out.num_entries; - *sids = r.out.sids; - status = r.out.status; - -done: - return status; -} |