diff options
-rw-r--r-- | librpc/ndr/ndr_compression.c (renamed from source4/librpc/ndr/ndr_compression.c) | 2 | ||||
-rw-r--r-- | librpc/ndr/ndr_compression.h (renamed from source3/librpc/ndr/ndr_compression.h) | 26 | ||||
-rw-r--r-- | librpc/ndr/ndr_krb5pac.c (renamed from source3/librpc/ndr/ndr_krb5pac.c) | 0 | ||||
-rw-r--r-- | source3/Makefile.in | 9 | ||||
-rw-r--r-- | source3/librpc/ndr/ndr_compression.c | 293 | ||||
-rw-r--r-- | source3/librpc/rpc/dcerpc_util.c | 1438 | ||||
-rw-r--r-- | source4/auth/ntlm/auth_server.c | 1 | ||||
-rw-r--r-- | source4/configure.ac | 2 | ||||
-rw-r--r-- | source4/lib/zlib.m4 | 1 | ||||
-rw-r--r-- | source4/librpc/config.mk | 6 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_krb5pac.c | 140 |
11 files changed, 14 insertions, 1904 deletions
diff --git a/source4/librpc/ndr/ndr_compression.c b/librpc/ndr/ndr_compression.c index 05a80e20b2..afd397e2a2 100644 --- a/source4/librpc/ndr/ndr_compression.c +++ b/librpc/ndr/ndr_compression.c @@ -23,7 +23,7 @@ #include "includes.h" #include "../lib/compression/lzxpress.h" #include "librpc/ndr/libndr.h" -#include "librpc/ndr/ndr_compression.h" +#include "../librpc/ndr/ndr_compression.h" #include <zlib.h> static voidpf ndr_zlib_alloc(voidpf opaque, uInt items, uInt size) diff --git a/source3/librpc/ndr/ndr_compression.h b/librpc/ndr/ndr_compression.h index 4cebbe190c..b939f6a42b 100644 --- a/source3/librpc/ndr/ndr_compression.h +++ b/librpc/ndr/ndr_compression.h @@ -5,25 +5,9 @@ #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) /* This file was automatically generated by mkproto.pl. DO NOT EDIT */ -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - -#ifndef _PURE_ -#define _PURE_ -#endif - -#ifndef _NORETURN_ -#define _NORETURN_ -#endif - -#ifndef _DEPRECATED_ -#define _DEPRECATED_ -#endif - -#ifndef _WARN_UNUSED_RESULT_ -#define _WARN_UNUSED_RESULT_ -#endif +/* this file contains prototypes for functions that are private + * to this subsystem or library. These functions should not be + * used outside this particular subsystem! */ /* The following definitions come from librpc/ndr/ndr_compression.c */ @@ -37,11 +21,11 @@ enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr, enum ndr_compression_alg compression_alg, ssize_t decompressed_len); enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr, - struct ndr_push **_comndr, + struct ndr_push **_uncomndr, enum ndr_compression_alg compression_alg, ssize_t decompressed_len); enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, - struct ndr_push *comndr, + struct ndr_push *uncomndr, enum ndr_compression_alg compression_alg, ssize_t decompressed_len); #undef _PRINTF_ATTRIBUTE diff --git a/source3/librpc/ndr/ndr_krb5pac.c b/librpc/ndr/ndr_krb5pac.c index 1b32df4c62..1b32df4c62 100644 --- a/source3/librpc/ndr/ndr_krb5pac.c +++ b/librpc/ndr/ndr_krb5pac.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 76fc101af3..d9ff8593f4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -151,7 +151,7 @@ CODEPAGEDIR = @codepagedir@ # the directory where pid files go PIDDIR = @piddir@ -FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) -I$(CTDBDIR)/include $(ISA) -I$(srcdir)/lib -D_SAMBA_BUILD_=3 +FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) -I$(CTDBDIR)/include $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DPRIVATE_DIR=\"$(PRIVATE_DIR)\" \ @@ -247,11 +247,12 @@ SERVER_MUTEX_OBJ = lib/server_mutex.o PASSCHANGE_OBJ = libsmb/passchange.o LIBNDR_DRSUAPI_OBJ = librpc/ndr/ndr_drsuapi.o \ - librpc/ndr/ndr_compression.o \ + ../librpc/ndr/ndr_compression.o \ librpc/gen_ndr/ndr_drsuapi.o \ librpc/gen_ndr/ndr_drsblobs.o -COMPRESSION_OBJ = ../lib/compression/mszip.o +COMPRESSION_OBJ = ../lib/compression/mszip.o \ + ../lib/compression/lzxpress.o DRSUAPI_OBJ = $(LIBNDR_DRSUAPI_OBJ) \ $(COMPRESSION_OBJ) @@ -375,7 +376,7 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o \ libads/ldap_schema.o libads/util.o libads/ndr.o LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o \ - librpc/ndr/ndr_krb5pac.o \ + ../librpc/ndr/ndr_krb5pac.o \ librpc/gen_ndr/ndr_krb5pac.o SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o diff --git a/source3/librpc/ndr/ndr_compression.c b/source3/librpc/ndr/ndr_compression.c deleted file mode 100644 index 0784204a72..0000000000 --- a/source3/librpc/ndr/ndr_compression.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - libndr compression support - - Copyright (C) Stefan Metzmacher 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../compression/mszip.h" -#include "librpc/ndr/libndr.h" -#include "librpc/ndr/ndr_compression.h" - -static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull, - struct ndr_push *ndrpush, - struct decomp_state *decomp_state, - bool *last) -{ - DATA_BLOB comp_chunk; - uint32_t comp_chunk_offset; - uint32_t comp_chunk_size; - DATA_BLOB plain_chunk; - uint32_t plain_chunk_offset; - uint32_t plain_chunk_size; - int ret; - - NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size)); - if (plain_chunk_size > 0x00008000) { - return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad MSZIP plain chunk size %08X > 0x00008000 (PULL)", - plain_chunk_size); - } - - NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size)); - - DEBUG(10,("MSZIP plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n", - plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size)); - - comp_chunk_offset = ndrpull->offset; - NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size)); - comp_chunk.length = comp_chunk_size; - comp_chunk.data = ndrpull->data + comp_chunk_offset; - - plain_chunk_offset = ndrpush->offset; - NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size)); - plain_chunk.length = plain_chunk_size; - plain_chunk.data = ndrpush->data + plain_chunk_offset; - - ret = ZIPdecompress(decomp_state, &comp_chunk, &plain_chunk); - if (ret != DECR_OK) { - return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZIPdecompress() error %d (PULL)", - ret); - } - - if ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) { - /* this is the last chunk */ - *last = true; - } - - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_compression_mszip(struct ndr_pull *subndr, - struct ndr_pull **_comndr, - ssize_t decompressed_len) -{ - struct ndr_push *ndrpush; - struct ndr_pull *comndr; - DATA_BLOB uncompressed; - uint32_t payload_header[4]; - uint32_t payload_size; - uint32_t payload_offset; - uint8_t *payload; - struct decomp_state *decomp_state; - bool last = false; - - ndrpush = ndr_push_init_ctx(subndr, NULL); - NDR_ERR_HAVE_NO_MEMORY(ndrpush); - - decomp_state = ZIPdecomp_state(subndr); - NDR_ERR_HAVE_NO_MEMORY(decomp_state); - - while (!last) { - NDR_CHECK(ndr_pull_compression_mszip_chunk(subndr, ndrpush, decomp_state, &last)); - } - - uncompressed = ndr_push_blob(ndrpush); - - if (uncompressed.length != decompressed_len) { - return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP uncompressed_len [%u] != [%d] (PULL)", - (int)uncompressed.length, (int)decompressed_len); - } - - comndr = talloc_zero(subndr, struct ndr_pull); - NDR_ERR_HAVE_NO_MEMORY(comndr); - comndr->flags = subndr->flags; - comndr->current_mem_ctx = subndr->current_mem_ctx; - - comndr->data = uncompressed.data; - comndr->data_size = uncompressed.length; - comndr->offset = 0; - - NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[0])); - NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[1])); - NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[2])); - NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[3])); - - if (payload_header[0] != 0x00081001) { - return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[0] [0x%08X] != [0x00081001] (PULL)", - payload_header[0]); - } - if (payload_header[1] != 0xCCCCCCCC) { - return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[1] [0x%08X] != [0xCCCCCCCC] (PULL)", - payload_header[1]); - } - - payload_size = payload_header[2]; - - if (payload_header[3] != 0x00000000) { - return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[3] [0x%08X] != [0x00000000] (PULL)", - payload_header[3]); - } - - payload_offset = comndr->offset; - NDR_CHECK(ndr_pull_advance(comndr, payload_size)); - payload = comndr->data + payload_offset; - - comndr->data = payload; - comndr->data_size = payload_size; - comndr->offset = 0; - - *_comndr = comndr; - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_push_compression_mszip(struct ndr_push *subndr, - struct ndr_push *comndr) -{ - return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Sorry MSZIP compression is not supported yet (PUSH)"); -} - -static enum ndr_err_code ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrpull, - struct ndr_push *ndrpush, - bool *last) -{ - DATA_BLOB comp_chunk; - uint32_t comp_chunk_offset; - uint32_t comp_chunk_size; - uint32_t plain_chunk_size; - - comp_chunk_offset = ndrpull->offset; - - NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size)); - if (plain_chunk_size > 0x00010000) { - return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad XPRESS plain chunk size %08X > 0x00010000 (PULL)", - plain_chunk_size); - } - - NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size)); - - NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size)); - comp_chunk.length = comp_chunk_size + 8; - comp_chunk.data = ndrpull->data + comp_chunk_offset; - - DEBUG(10,("XPRESS plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n", - plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size)); - - /* For now, we just copy over the compressed blob */ - NDR_CHECK(ndr_push_bytes(ndrpush, comp_chunk.data, comp_chunk.length)); - - if ((plain_chunk_size < 0x00010000) || (ndrpull->offset+4 >= ndrpull->data_size)) { - /* this is the last chunk */ - *last = true; - } - - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_compression_xpress(struct ndr_pull *subndr, - struct ndr_pull **_comndr, - ssize_t decompressed_len) -{ - struct ndr_push *ndrpush; - struct ndr_pull *comndr; - DATA_BLOB uncompressed; - bool last = false; - - ndrpush = ndr_push_init_ctx(subndr, NULL); - NDR_ERR_HAVE_NO_MEMORY(ndrpush); - - while (!last) { - NDR_CHECK(ndr_pull_compression_xpress_chunk(subndr, ndrpush, &last)); - } - - uncompressed = ndr_push_blob(ndrpush); - - comndr = talloc_zero(subndr, struct ndr_pull); - NDR_ERR_HAVE_NO_MEMORY(comndr); - comndr->flags = subndr->flags; - comndr->current_mem_ctx = subndr->current_mem_ctx; - - comndr->data = uncompressed.data; - comndr->data_size = uncompressed.length; - comndr->offset = 0; - - *_comndr = comndr; - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_push_compression_xpress(struct ndr_push *subndr, - struct ndr_push *comndr) -{ - return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "XPRESS compression is not supported yet (PUSH)"); -} - -/* - handle compressed subcontext buffers, which in midl land are user-marshalled, but - we use magic in pidl to make them easier to cope with -*/ -enum ndr_err_code ndr_pull_compression_start(struct ndr_pull *subndr, - struct ndr_pull **_comndr, - enum ndr_compression_alg compression_alg, - ssize_t decompressed_len) -{ - switch (compression_alg) { - case NDR_COMPRESSION_MSZIP: - return ndr_pull_compression_mszip(subndr, _comndr, decompressed_len); - case NDR_COMPRESSION_XPRESS: - return ndr_pull_compression_xpress(subndr, _comndr, decompressed_len); - default: - return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)", - compression_alg); - } - return NDR_ERR_SUCCESS; -} - -enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr, - struct ndr_pull *comndr, - enum ndr_compression_alg compression_alg, - ssize_t decompressed_len) -{ - return NDR_ERR_SUCCESS; -} - -/* - push a compressed subcontext -*/ -enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr, - struct ndr_push **_comndr, - enum ndr_compression_alg compression_alg, - ssize_t decompressed_len) -{ - struct ndr_push *comndr; - - comndr = ndr_push_init_ctx(subndr, NULL); - NDR_ERR_HAVE_NO_MEMORY(comndr); - comndr->flags = subndr->flags; - - *_comndr = comndr; - return NDR_ERR_SUCCESS; -} - -/* - push a compressed subcontext -*/ -enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr, - struct ndr_push *comndr, - enum ndr_compression_alg compression_alg, - ssize_t decompressed_len) -{ - switch (compression_alg) { - case NDR_COMPRESSION_MSZIP: - return ndr_push_compression_mszip(subndr, comndr); - case NDR_COMPRESSION_XPRESS: - return ndr_push_compression_xpress(subndr, comndr); - default: - return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)", - compression_alg); - } - return NDR_ERR_SUCCESS; -} diff --git a/source3/librpc/rpc/dcerpc_util.c b/source3/librpc/rpc/dcerpc_util.c deleted file mode 100644 index 3b8768ccc2..0000000000 --- a/source3/librpc/rpc/dcerpc_util.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - dcerpc utility functions - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Jelmer Vernooij 2004 - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 - Copyright (C) Rafal Szczesniak 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "lib/events/events.h" -#include "libcli/composite/composite.h" -#include "librpc/gen_ndr/ndr_epmapper_c.h" -#include "librpc/gen_ndr/ndr_dcerpc.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "librpc/rpc/dcerpc_proto.h" -#include "auth/credentials/credentials.h" -#include "param/param.h" - -/* - find a dcerpc call on an interface by name -*/ -const struct ndr_interface_call *dcerpc_iface_find_call(const struct ndr_interface_table *iface, - const char *name) -{ - int i; - for (i=0;i<iface->num_calls;i++) { - if (strcmp(iface->calls[i].name, name) == 0) { - return &iface->calls[i]; - } - } - return NULL; -} - -/* - push a ncacn_packet into a blob, potentially with auth info -*/ -NTSTATUS ncacn_push_auth(DATA_BLOB *blob, TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *iconv_convenience, - struct ncacn_packet *pkt, - struct dcerpc_auth *auth_info) -{ - struct ndr_push *ndr; - enum ndr_err_code ndr_err; - - ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience); - if (!ndr) { - return NT_STATUS_NO_MEMORY; - } - - if (!(pkt->drep[0] & DCERPC_DREP_LE)) { - ndr->flags |= LIBNDR_FLAG_BIGENDIAN; - } - - if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { - ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; - } - - if (auth_info) { - pkt->auth_length = auth_info->credentials.length; - } else { - pkt->auth_length = 0; - } - - ndr_err = ndr_push_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - - if (auth_info) { - ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth_info); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - } - - *blob = ndr_push_blob(ndr); - - /* fill in the frag length */ - dcerpc_set_frag_length(blob, blob->length); - - return NT_STATUS_OK; -} - -#define MAX_PROTSEQ 10 - -static const struct { - const char *name; - enum dcerpc_transport_t transport; - int num_protocols; - enum epm_protocol protseq[MAX_PROTSEQ]; -} transports[] = { - { "ncacn_np", NCACN_NP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_SMB, EPM_PROTOCOL_NETBIOS }}, - { "ncacn_ip_tcp", NCACN_IP_TCP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_TCP, EPM_PROTOCOL_IP } }, - { "ncacn_http", NCACN_HTTP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_HTTP, EPM_PROTOCOL_IP } }, - { "ncadg_ip_udp", NCACN_IP_UDP, 3, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UDP, EPM_PROTOCOL_IP } }, - { "ncalrpc", NCALRPC, 2, - { EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_PIPE } }, - { "ncacn_unix_stream", NCACN_UNIX_STREAM, 2, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_UNIX_DS } }, - { "ncadg_unix_dgram", NCADG_UNIX_DGRAM, 2, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_UNIX_DS } }, - { "ncacn_at_dsp", NCACN_AT_DSP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DSP } }, - { "ncadg_at_ddp", NCADG_AT_DDP, 3, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_APPLETALK, EPM_PROTOCOL_DDP } }, - { "ncacn_vns_ssp", NCACN_VNS_SPP, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_SPP } }, - { "ncacn_vns_ipc", NCACN_VNS_IPC, 3, - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_STREETTALK, EPM_PROTOCOL_VINES_IPC }, }, - { "ncadg_ipx", NCADG_IPX, 2, - { EPM_PROTOCOL_NCADG, EPM_PROTOCOL_IPX }, - }, - { "ncacn_spx", NCACN_SPX, 3, - /* I guess some MS programmer confused the identifier for - * EPM_PROTOCOL_UUID (0x0D or 13) with the one for - * EPM_PROTOCOL_SPX (0x13) here. -- jelmer*/ - { EPM_PROTOCOL_NCACN, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID }, - }, -}; - -static const struct { - const char *name; - uint32_t flag; -} ncacn_options[] = { - {"sign", DCERPC_SIGN}, - {"seal", DCERPC_SEAL}, - {"connect", DCERPC_CONNECT}, - {"spnego", DCERPC_AUTH_SPNEGO}, - {"ntlm", DCERPC_AUTH_NTLM}, - {"krb5", DCERPC_AUTH_KRB5}, - {"validate", DCERPC_DEBUG_VALIDATE_BOTH}, - {"print", DCERPC_DEBUG_PRINT_BOTH}, - {"padcheck", DCERPC_DEBUG_PAD_CHECK}, - {"bigendian", DCERPC_PUSH_BIGENDIAN}, - {"smb2", DCERPC_SMB2} -}; - -const char *epm_floor_string(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) -{ - struct ndr_syntax_id syntax; - NTSTATUS status; - - switch(epm_floor->lhs.protocol) { - case EPM_PROTOCOL_UUID: - status = dcerpc_floor_get_lhs_data(epm_floor, &syntax); - if (NT_STATUS_IS_OK(status)) { - /* lhs is used: UUID */ - char *uuidstr; - - if (GUID_equal(&syntax.uuid, &ndr_transfer_syntax.uuid)) { - return "NDR"; - } - - if (GUID_equal(&syntax.uuid, &ndr64_transfer_syntax.uuid)) { - return "NDR64"; - } - - uuidstr = GUID_string(mem_ctx, &syntax.uuid); - - return talloc_asprintf(mem_ctx, " uuid %s/0x%02x", uuidstr, syntax.if_version); - } else { /* IPX */ - return talloc_asprintf(mem_ctx, "IPX:%s", - data_blob_hex_string(mem_ctx, &epm_floor->rhs.uuid.unknown)); - } - - case EPM_PROTOCOL_NCACN: - return "RPC-C"; - - case EPM_PROTOCOL_NCADG: - return "RPC"; - - case EPM_PROTOCOL_NCALRPC: - return "NCALRPC"; - - case EPM_PROTOCOL_DNET_NSP: - return "DNET/NSP"; - - case EPM_PROTOCOL_IP: - return talloc_asprintf(mem_ctx, "IP:%s", epm_floor->rhs.ip.ipaddr); - - case EPM_PROTOCOL_PIPE: - return talloc_asprintf(mem_ctx, "PIPE:%s", epm_floor->rhs.pipe.path); - - case EPM_PROTOCOL_SMB: - return talloc_asprintf(mem_ctx, "SMB:%s", epm_floor->rhs.smb.unc); - - case EPM_PROTOCOL_UNIX_DS: - return talloc_asprintf(mem_ctx, "Unix:%s", epm_floor->rhs.unix_ds.path); - - case EPM_PROTOCOL_NETBIOS: - return talloc_asprintf(mem_ctx, "NetBIOS:%s", epm_floor->rhs.netbios.name); - - case EPM_PROTOCOL_NETBEUI: - return "NETBeui"; - - case EPM_PROTOCOL_SPX: - return "SPX"; - - case EPM_PROTOCOL_NB_IPX: - return "NB_IPX"; - - case EPM_PROTOCOL_HTTP: - return talloc_asprintf(mem_ctx, "HTTP:%d", epm_floor->rhs.http.port); - - case EPM_PROTOCOL_TCP: - return talloc_asprintf(mem_ctx, "TCP:%d", epm_floor->rhs.tcp.port); - - case EPM_PROTOCOL_UDP: - return talloc_asprintf(mem_ctx, "UDP:%d", epm_floor->rhs.udp.port); - - default: - return talloc_asprintf(mem_ctx, "UNK(%02x):", epm_floor->lhs.protocol); - } -} - - -/* - form a binding string from a binding structure -*/ -_PUBLIC_ char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_binding *b) -{ - char *s = talloc_strdup(mem_ctx, ""); - int i; - const char *t_name = NULL; - - if (b->transport != NCA_UNKNOWN) { - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].transport == b->transport) { - t_name = transports[i].name; - } - } - if (!t_name) { - return NULL; - } - } - - if (!GUID_all_zero(&b->object.uuid)) { - s = talloc_asprintf(s, "%s@", - GUID_string(mem_ctx, &b->object.uuid)); - } - - if (t_name != NULL) { - s = talloc_asprintf_append_buffer(s, "%s:", t_name); - if (s == NULL) { - return NULL; - } - } - - if (b->host) { - s = talloc_asprintf_append_buffer(s, "%s", b->host); - } - - if (!b->endpoint && !b->options && !b->flags) { - return s; - } - - s = talloc_asprintf_append_buffer(s, "["); - - if (b->endpoint) { - s = talloc_asprintf_append_buffer(s, "%s", b->endpoint); - } - - /* this is a *really* inefficent way of dealing with strings, - but this is rarely called and the strings are always short, - so I don't care */ - for (i=0;b->options && b->options[i];i++) { - s = talloc_asprintf_append_buffer(s, ",%s", b->options[i]); - if (!s) return NULL; - } - - for (i=0;i<ARRAY_SIZE(ncacn_options);i++) { - if (b->flags & ncacn_options[i].flag) { - s = talloc_asprintf_append_buffer(s, ",%s", ncacn_options[i].name); - if (!s) return NULL; - } - } - - s = talloc_asprintf_append_buffer(s, "]"); - - return s; -} - -/* - parse a binding string into a dcerpc_binding structure -*/ -_PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out) -{ - struct dcerpc_binding *b; - char *options; - char *p; - int i, j, comma_count; - - b = talloc(mem_ctx, struct dcerpc_binding); - if (!b) { - return NT_STATUS_NO_MEMORY; - } - - p = strchr(s, '@'); - - if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */ - NTSTATUS status; - - status = GUID_from_string(s, &b->object.uuid); - - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Failed parsing UUID\n")); - return status; - } - - s = p + 1; - } else { - ZERO_STRUCT(b->object); - } - - b->object.if_version = 0; - - p = strchr(s, ':'); - - if (p == NULL) { - b->transport = NCA_UNKNOWN; - } else { - char *type = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s)); - if (!type) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (strcasecmp(type, transports[i].name) == 0) { - b->transport = transports[i].transport; - break; - } - } - - if (i==ARRAY_SIZE(transports)) { - DEBUG(0,("Unknown dcerpc transport '%s'\n", type)); - return NT_STATUS_INVALID_PARAMETER; - } - - talloc_free(type); - - s = p+1; - } - - p = strchr(s, '['); - if (p) { - b->host = talloc_strndup(b, s, PTR_DIFF(p, s)); - options = talloc_strdup(mem_ctx, p+1); - if (options[strlen(options)-1] != ']') { - return NT_STATUS_INVALID_PARAMETER; - } - options[strlen(options)-1] = 0; - } else { - b->host = talloc_strdup(b, s); - options = NULL; - } - if (!b->host) { - return NT_STATUS_NO_MEMORY; - } - - b->target_hostname = b->host; - - b->options = NULL; - b->flags = 0; - b->assoc_group_id = 0; - b->endpoint = NULL; - - if (!options) { - *b_out = b; - return NT_STATUS_OK; - } - - comma_count = count_chars(options, ','); - - b->options = talloc_array(b, const char *, comma_count+2); - if (!b->options) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; (p = strchr(options, ',')); i++) { - b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options)); - if (!b->options[i]) { - return NT_STATUS_NO_MEMORY; - } - options = p+1; - } - b->options[i] = options; - b->options[i+1] = NULL; - - /* some options are pre-parsed for convenience */ - for (i=0;b->options[i];i++) { - for (j=0;j<ARRAY_SIZE(ncacn_options);j++) { - if (strcasecmp(ncacn_options[j].name, b->options[i]) == 0) { - int k; - b->flags |= ncacn_options[j].flag; - for (k=i;b->options[k];k++) { - b->options[k] = b->options[k+1]; - } - i--; - break; - } - } - } - - if (b->options[0]) { - /* Endpoint is first option */ - b->endpoint = b->options[0]; - if (strlen(b->endpoint) == 0) b->endpoint = NULL; - - for (i=0;b->options[i];i++) { - b->options[i] = b->options[i+1]; - } - } - - if (b->options[0] == NULL) - b->options = NULL; - - *b_out = b; - return NT_STATUS_OK; -} - -_PUBLIC_ NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax) -{ - TALLOC_CTX *mem_ctx = talloc_init("floor_get_lhs_data"); - struct ndr_pull *ndr = ndr_pull_init_blob(&epm_floor->lhs.lhs_data, mem_ctx, NULL); - enum ndr_err_code ndr_err; - uint16_t if_version=0; - - ndr->flags |= LIBNDR_FLAG_NOALIGN; - - ndr_err = ndr_pull_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(mem_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - ndr_err = ndr_pull_uint16(ndr, NDR_SCALARS, &if_version); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(mem_ctx); - return ndr_map_error2ntstatus(ndr_err); - } - - syntax->if_version = if_version; - - talloc_free(mem_ctx); - - return NT_STATUS_OK; -} - -static DATA_BLOB dcerpc_floor_pack_lhs_data(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax) -{ - struct ndr_push *ndr = ndr_push_init_ctx(mem_ctx, NULL); - - ndr->flags |= LIBNDR_FLAG_NOALIGN; - - ndr_push_GUID(ndr, NDR_SCALARS | NDR_BUFFERS, &syntax->uuid); - ndr_push_uint16(ndr, NDR_SCALARS, syntax->if_version); - - return ndr_push_blob(ndr); -} - -const char *dcerpc_floor_get_rhs_data(TALLOC_CTX *mem_ctx, struct epm_floor *epm_floor) -{ - switch (epm_floor->lhs.protocol) { - case EPM_PROTOCOL_TCP: - if (epm_floor->rhs.tcp.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.tcp.port); - - case EPM_PROTOCOL_UDP: - if (epm_floor->rhs.udp.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.udp.port); - - case EPM_PROTOCOL_HTTP: - if (epm_floor->rhs.http.port == 0) return NULL; - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.http.port); - - case EPM_PROTOCOL_IP: - return talloc_strdup(mem_ctx, epm_floor->rhs.ip.ipaddr); - - case EPM_PROTOCOL_NCACN: - return NULL; - - case EPM_PROTOCOL_NCADG: - return NULL; - - case EPM_PROTOCOL_SMB: - if (strlen(epm_floor->rhs.smb.unc) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.smb.unc); - - case EPM_PROTOCOL_PIPE: - if (strlen(epm_floor->rhs.pipe.path) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.pipe.path); - - case EPM_PROTOCOL_NETBIOS: - if (strlen(epm_floor->rhs.netbios.name) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.netbios.name); - - case EPM_PROTOCOL_NCALRPC: - return NULL; - - case EPM_PROTOCOL_VINES_SPP: - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_spp.port); - - case EPM_PROTOCOL_VINES_IPC: - return talloc_asprintf(mem_ctx, "%d", epm_floor->rhs.vines_ipc.port); - - case EPM_PROTOCOL_STREETTALK: - return talloc_strdup(mem_ctx, epm_floor->rhs.streettalk.streettalk); - - case EPM_PROTOCOL_UNIX_DS: - if (strlen(epm_floor->rhs.unix_ds.path) == 0) return NULL; - return talloc_strdup(mem_ctx, epm_floor->rhs.unix_ds.path); - - case EPM_PROTOCOL_NULL: - return NULL; - - default: - DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); - break; - } - - return NULL; -} - -static NTSTATUS dcerpc_floor_set_rhs_data(TALLOC_CTX *mem_ctx, - struct epm_floor *epm_floor, - const char *data) -{ - switch (epm_floor->lhs.protocol) { - case EPM_PROTOCOL_TCP: - epm_floor->rhs.tcp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_UDP: - epm_floor->rhs.udp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_HTTP: - epm_floor->rhs.http.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_IP: - epm_floor->rhs.ip.ipaddr = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.ip.ipaddr); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCACN: - epm_floor->rhs.ncacn.minor_version = 0; - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCADG: - epm_floor->rhs.ncadg.minor_version = 0; - return NT_STATUS_OK; - - case EPM_PROTOCOL_SMB: - epm_floor->rhs.smb.unc = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.smb.unc); - return NT_STATUS_OK; - - case EPM_PROTOCOL_PIPE: - epm_floor->rhs.pipe.path = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.pipe.path); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NETBIOS: - epm_floor->rhs.netbios.name = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.netbios.name); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NCALRPC: - return NT_STATUS_OK; - - case EPM_PROTOCOL_VINES_SPP: - epm_floor->rhs.vines_spp.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_VINES_IPC: - epm_floor->rhs.vines_ipc.port = atoi(data); - return NT_STATUS_OK; - - case EPM_PROTOCOL_STREETTALK: - epm_floor->rhs.streettalk.streettalk = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.streettalk.streettalk); - return NT_STATUS_OK; - - case EPM_PROTOCOL_UNIX_DS: - epm_floor->rhs.unix_ds.path = talloc_strdup(mem_ctx, data); - NT_STATUS_HAVE_NO_MEMORY(epm_floor->rhs.unix_ds.path); - return NT_STATUS_OK; - - case EPM_PROTOCOL_NULL: - return NT_STATUS_OK; - - default: - DEBUG(0,("Unsupported lhs protocol %d\n", epm_floor->lhs.protocol)); - break; - } - - return NT_STATUS_NOT_SUPPORTED; -} - -enum dcerpc_transport_t dcerpc_transport_by_endpoint_protocol(int prot) -{ - int i; - - /* Find a transport that has 'prot' as 4th protocol */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].num_protocols >= 2 && - transports[i].protseq[1] == prot) { - return transports[i].transport; - } - } - - /* Unknown transport */ - return (unsigned int)-1; -} - -_PUBLIC_ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower) -{ - int i; - - /* Find a transport that matches this tower */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - int j; - if (transports[i].num_protocols != tower->num_floors - 2) { - continue; - } - - for (j = 0; j < transports[i].num_protocols; j++) { - if (transports[i].protseq[j] != tower->floors[j+2].lhs.protocol) { - break; - } - } - - if (j == transports[i].num_protocols) { - return transports[i].transport; - } - } - - /* Unknown transport */ - return (unsigned int)-1; -} - -_PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, - struct epm_tower *tower, - struct dcerpc_binding **b_out) -{ - NTSTATUS status; - struct dcerpc_binding *binding; - - binding = talloc(mem_ctx, struct dcerpc_binding); - NT_STATUS_HAVE_NO_MEMORY(binding); - - ZERO_STRUCT(binding->object); - binding->options = NULL; - binding->host = NULL; - binding->target_hostname = NULL; - binding->flags = 0; - binding->assoc_group_id = 0; - - binding->transport = dcerpc_transport_by_tower(tower); - - if (binding->transport == (unsigned int)-1) { - return NT_STATUS_NOT_SUPPORTED; - } - - if (tower->num_floors < 1) { - return NT_STATUS_OK; - } - - /* Set object uuid */ - status = dcerpc_floor_get_lhs_data(&tower->floors[0], &binding->object); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Error pulling object uuid and version: %s", nt_errstr(status))); - return status; - } - - /* Ignore floor 1, it contains the NDR version info */ - - binding->options = NULL; - - /* Set endpoint */ - if (tower->num_floors >= 4) { - binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[3]); - } else { - binding->endpoint = NULL; - } - - /* Set network address */ - if (tower->num_floors >= 5) { - binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]); - NT_STATUS_HAVE_NO_MEMORY(binding->host); - binding->target_hostname = binding->host; - } - *b_out = binding; - return NT_STATUS_OK; -} - -_PUBLIC_ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower) -{ - const enum epm_protocol *protseq = NULL; - int num_protocols = -1, i; - NTSTATUS status; - - /* Find transport */ - for (i=0;i<ARRAY_SIZE(transports);i++) { - if (transports[i].transport == binding->transport) { - protseq = transports[i].protseq; - num_protocols = transports[i].num_protocols; - break; - } - } - - if (num_protocols == -1) { - DEBUG(0, ("Unable to find transport with id '%d'\n", binding->transport)); - return NT_STATUS_UNSUCCESSFUL; - } - - tower->num_floors = 2 + num_protocols; - tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors); - - /* Floor 0 */ - tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID; - - tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &binding->object); - - tower->floors[0].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); - - /* Floor 1 */ - tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID; - - tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, - &ndr_transfer_syntax); - - tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2); - - /* Floor 2 to num_protocols */ - for (i = 0; i < num_protocols; i++) { - tower->floors[2 + i].lhs.protocol = protseq[i]; - tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(mem_ctx, NULL, 0); - ZERO_STRUCT(tower->floors[2 + i].rhs); - dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], ""); - } - - /* The 4th floor contains the endpoint */ - if (num_protocols >= 2 && binding->endpoint) { - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[3], binding->endpoint); - if (NT_STATUS_IS_ERR(status)) { - return status; - } - } - - /* The 5th contains the network address */ - if (num_protocols >= 3 && binding->host) { - if (is_ipaddress(binding->host)) { - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], - binding->host); - } else { - /* note that we don't attempt to resolve the - name here - when we get a hostname here we - are in the client code, and want to put in - a wildcard all-zeros IP for the server to - fill in */ - status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], - "0.0.0.0"); - } - if (NT_STATUS_IS_ERR(status)) { - return status; - } - } - - return NT_STATUS_OK; -} - - -struct epm_map_binding_state { - struct dcerpc_binding *binding; - const struct ndr_interface_table *table; - struct dcerpc_pipe *pipe; - struct policy_handle handle; - struct GUID guid; - struct epm_twr_t twr; - struct epm_twr_t *twr_r; - struct epm_Map r; -}; - - -static void continue_epm_recv_binding(struct composite_context *ctx); -static void continue_epm_map(struct rpc_request *req); - - -/* - Stage 2 of epm_map_binding: Receive connected rpc pipe and send endpoint - mapping rpc request -*/ -static void continue_epm_recv_binding(struct composite_context *ctx) -{ - struct rpc_request *map_req; - - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - struct epm_map_binding_state *s = talloc_get_type(c->private_data, - struct epm_map_binding_state); - - /* receive result of rpc pipe connect request */ - c->status = dcerpc_pipe_connect_b_recv(ctx, c, &s->pipe); - if (!composite_is_ok(c)) return; - - s->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; - - /* prepare requested binding parameters */ - s->binding->object = s->table->syntax_id; - - c->status = dcerpc_binding_build_tower(s->pipe, s->binding, &s->twr.tower); - if (!composite_is_ok(c)) return; - - /* with some nice pretty paper around it of course */ - s->r.in.object = &s->guid; - s->r.in.map_tower = &s->twr; - s->r.in.entry_handle = &s->handle; - s->r.in.max_towers = 1; - s->r.out.entry_handle = &s->handle; - - /* send request for an endpoint mapping - a rpc request on connected pipe */ - map_req = dcerpc_epm_Map_send(s->pipe, c, &s->r); - if (composite_nomem(map_req, c)) return; - - composite_continue_rpc(c, map_req, continue_epm_map, c); -} - - -/* - Stage 3 of epm_map_binding: Receive endpoint mapping and provide binding details -*/ -static void continue_epm_map(struct rpc_request *req) -{ - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct epm_map_binding_state *s = talloc_get_type(c->private_data, - struct epm_map_binding_state); - - /* receive result of a rpc request */ - c->status = dcerpc_ndr_request_recv(req); - if (!composite_is_ok(c)) return; - - /* check the details */ - if (s->r.out.result != 0 || *s->r.out.num_towers != 1) { - composite_error(c, NT_STATUS_PORT_UNREACHABLE); - return; - } - - s->twr_r = s->r.out.towers[0].twr; - if (s->twr_r == NULL) { - composite_error(c, NT_STATUS_PORT_UNREACHABLE); - return; - } - - if (s->twr_r->tower.num_floors != s->twr.tower.num_floors || - s->twr_r->tower.floors[3].lhs.protocol != s->twr.tower.floors[3].lhs.protocol) { - composite_error(c, NT_STATUS_PORT_UNREACHABLE); - return; - } - - /* get received endpoint */ - s->binding->endpoint = talloc_reference(s->binding, - dcerpc_floor_get_rhs_data(c, &s->twr_r->tower.floors[3])); - if (composite_nomem(s->binding->endpoint, c)) return; - - composite_done(c); -} - - -/* - Request for endpoint mapping of dcerpc binding - try to request for endpoint - unless there is default one. -*/ -struct composite_context *dcerpc_epm_map_binding_send(TALLOC_CTX *mem_ctx, - struct dcerpc_binding *binding, - const struct ndr_interface_table *table, - struct event_context *ev, - struct loadparm_context *lp_ctx) -{ - struct composite_context *c; - struct epm_map_binding_state *s; - struct composite_context *pipe_connect_req; - struct cli_credentials *anon_creds; - struct event_context *new_ev = NULL; - - NTSTATUS status; - struct dcerpc_binding *epmapper_binding; - int i; - - /* Try to find event context in memory context in case passed - * event_context (argument) was NULL. If there's none, just - * create a new one. - */ - if (ev == NULL) { - ev = event_context_find(mem_ctx); - if (ev == NULL) { - new_ev = event_context_init(mem_ctx); - if (new_ev == NULL) return NULL; - ev = new_ev; - } - } - - /* composite context allocation and setup */ - c = composite_create(mem_ctx, ev); - if (c == NULL) { - talloc_free(new_ev); - return NULL; - } - talloc_steal(c, new_ev); - - s = talloc_zero(c, struct epm_map_binding_state); - if (composite_nomem(s, c)) return c; - c->private_data = s; - - s->binding = binding; - s->table = table; - - /* anonymous credentials for rpc connection used to get endpoint mapping */ - anon_creds = cli_credentials_init(mem_ctx); - cli_credentials_set_event_context(anon_creds, ev); - cli_credentials_set_anonymous(anon_creds); - - /* - First, check if there is a default endpoint specified in the IDL - */ - if (table != NULL) { - struct dcerpc_binding *default_binding; - - /* Find one of the default pipes for this interface */ - for (i = 0; i < table->endpoints->count; i++) { - status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding); - - if (NT_STATUS_IS_OK(status)) { - if (binding->transport == NCA_UNKNOWN) - binding->transport = default_binding->transport; - if (default_binding->transport == binding->transport && - default_binding->endpoint) { - binding->endpoint = talloc_reference(binding, default_binding->endpoint); - talloc_free(default_binding); - - composite_done(c); - return c; - - } else { - talloc_free(default_binding); - } - } - } - } - - epmapper_binding = talloc_zero(c, struct dcerpc_binding); - if (composite_nomem(epmapper_binding, c)) return c; - - /* basic endpoint mapping data */ - epmapper_binding->transport = binding->transport; - epmapper_binding->host = talloc_reference(epmapper_binding, binding->host); - epmapper_binding->target_hostname = epmapper_binding->host; - epmapper_binding->options = NULL; - epmapper_binding->flags = 0; - epmapper_binding->assoc_group_id = 0; - epmapper_binding->endpoint = NULL; - - /* initiate rpc pipe connection */ - pipe_connect_req = dcerpc_pipe_connect_b_send(c, epmapper_binding, - &ndr_table_epmapper, - anon_creds, c->event_ctx, - lp_ctx); - if (composite_nomem(pipe_connect_req, c)) return c; - - composite_continue(c, pipe_connect_req, continue_epm_recv_binding, c); - return c; -} - - -/* - Receive result of endpoint mapping request - */ -NTSTATUS dcerpc_epm_map_binding_recv(struct composite_context *c) -{ - NTSTATUS status = composite_wait(c); - - talloc_free(c); - return status; -} - - -/* - Get endpoint mapping for rpc connection -*/ -_PUBLIC_ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, - const struct ndr_interface_table *table, struct event_context *ev, - struct loadparm_context *lp_ctx) -{ - struct composite_context *c; - - c = dcerpc_epm_map_binding_send(mem_ctx, binding, table, ev, lp_ctx); - return dcerpc_epm_map_binding_recv(c); -} - - -struct pipe_auth_state { - struct dcerpc_pipe *pipe; - struct dcerpc_binding *binding; - const struct ndr_interface_table *table; - struct loadparm_context *lp_ctx; - struct cli_credentials *credentials; -}; - - -static void continue_auth_schannel(struct composite_context *ctx); -static void continue_auth(struct composite_context *ctx); -static void continue_auth_none(struct composite_context *ctx); -static void continue_ntlmssp_connection(struct composite_context *ctx); -static void continue_spnego_after_wrong_pass(struct composite_context *ctx); - - -/* - Stage 2 of pipe_auth: Receive result of schannel bind request -*/ -static void continue_auth_schannel(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - - c->status = dcerpc_bind_auth_schannel_recv(ctx); - if (!composite_is_ok(c)) return; - - composite_done(c); -} - - -/* - Stage 2 of pipe_auth: Receive result of authenticated bind request -*/ -static void continue_auth(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - - c->status = dcerpc_bind_auth_recv(ctx); - if (!composite_is_ok(c)) return; - - composite_done(c); -} -/* - Stage 2 of pipe_auth: Receive result of authenticated bind request, but handle fallbacks: - SPNEGO -> NTLMSSP -*/ -static void continue_auth_auto(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - struct pipe_auth_state *s = talloc_get_type(c->private_data, struct pipe_auth_state); - struct composite_context *sec_conn_req; - - c->status = dcerpc_bind_auth_recv(ctx); - if (NT_STATUS_EQUAL(c->status, NT_STATUS_INVALID_PARAMETER)) { - /* - * Retry with NTLMSSP auth as fallback - * send a request for secondary rpc connection - */ - sec_conn_req = dcerpc_secondary_connection_send(s->pipe, - s->binding); - composite_continue(c, sec_conn_req, continue_ntlmssp_connection, c); - return; - } else if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { - if (cli_credentials_wrong_password(s->credentials)) { - /* - * Retry SPNEGO with a better password - * send a request for secondary rpc connection - */ - sec_conn_req = dcerpc_secondary_connection_send(s->pipe, - s->binding); - composite_continue(c, sec_conn_req, continue_spnego_after_wrong_pass, c); - return; - } - } - - if (!composite_is_ok(c)) return; - - composite_done(c); -} - -/* - Stage 3 of pipe_auth (fallback to NTLMSSP case): Receive secondary - rpc connection (the first one can't be used any more, due to the - bind nak) and perform authenticated bind request -*/ -static void continue_ntlmssp_connection(struct composite_context *ctx) -{ - struct composite_context *c; - struct pipe_auth_state *s; - struct composite_context *auth_req; - struct dcerpc_pipe *p2; - - c = talloc_get_type(ctx->async.private_data, struct composite_context); - s = talloc_get_type(c->private_data, struct pipe_auth_state); - - /* receive secondary rpc connection */ - c->status = dcerpc_secondary_connection_recv(ctx, &p2); - if (!composite_is_ok(c)) return; - - talloc_steal(s, p2); - talloc_steal(p2, s->pipe); - s->pipe = p2; - - /* initiate a authenticated bind */ - auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, - DCERPC_AUTH_TYPE_NTLMSSP, - dcerpc_auth_level(s->pipe->conn), - s->table->authservices->names[0]); - composite_continue(c, auth_req, continue_auth, c); -} - -/* - Stage 3 of pipe_auth (retry on wrong password): Receive secondary - rpc connection (the first one can't be used any more, due to the - bind nak) and perform authenticated bind request -*/ -static void continue_spnego_after_wrong_pass(struct composite_context *ctx) -{ - struct composite_context *c; - struct pipe_auth_state *s; - struct composite_context *auth_req; - struct dcerpc_pipe *p2; - - c = talloc_get_type(ctx->async.private_data, struct composite_context); - s = talloc_get_type(c->private_data, struct pipe_auth_state); - - /* receive secondary rpc connection */ - c->status = dcerpc_secondary_connection_recv(ctx, &p2); - if (!composite_is_ok(c)) return; - - talloc_steal(s, p2); - talloc_steal(p2, s->pipe); - s->pipe = p2; - - /* initiate a authenticated bind */ - auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, - dcerpc_auth_level(s->pipe->conn), - s->table->authservices->names[0]); - composite_continue(c, auth_req, continue_auth, c); -} - - -/* - Stage 2 of pipe_auth: Receive result of non-authenticated bind request -*/ -static void continue_auth_none(struct composite_context *ctx) -{ - struct composite_context *c = talloc_get_type(ctx->async.private_data, - struct composite_context); - - c->status = dcerpc_bind_auth_none_recv(ctx); - if (!composite_is_ok(c)) return; - - composite_done(c); -} - - -/* - Request to perform an authenticated bind if required. Authentication - is determined using credentials passed and binding flags. -*/ -struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, - struct dcerpc_binding *binding, - const struct ndr_interface_table *table, - struct cli_credentials *credentials, - struct loadparm_context *lp_ctx) -{ - struct composite_context *c; - struct pipe_auth_state *s; - struct composite_context *auth_schannel_req; - struct composite_context *auth_req; - struct composite_context *auth_none_req; - struct dcerpc_connection *conn; - uint8_t auth_type; - - /* composite context allocation and setup */ - c = composite_create(p, p->conn->event_ctx); - if (c == NULL) return NULL; - - s = talloc_zero(c, struct pipe_auth_state); - if (composite_nomem(s, c)) return c; - c->private_data = s; - - /* store parameters in state structure */ - s->binding = binding; - s->table = table; - s->credentials = credentials; - s->pipe = p; - s->lp_ctx = lp_ctx; - - conn = s->pipe->conn; - conn->flags = binding->flags; - - /* remember the binding string for possible secondary connections */ - conn->binding_string = dcerpc_binding_string(p, binding); - - if (cli_credentials_is_anonymous(s->credentials)) { - auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table); - composite_continue(c, auth_none_req, continue_auth_none, c); - return c; - } - - if ((binding->flags & DCERPC_SCHANNEL) && - !cli_credentials_get_netlogon_creds(s->credentials)) { - /* If we don't already have netlogon credentials for - * the schannel bind, then we have to get these - * first */ - auth_schannel_req = dcerpc_bind_auth_schannel_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, - dcerpc_auth_level(conn)); - composite_continue(c, auth_schannel_req, continue_auth_schannel, c); - return c; - } - - /* - * we rely on the already authenticated CIFS connection - * if not doing sign or seal - */ - if (conn->transport.transport == NCACN_NP && - !(s->binding->flags & (DCERPC_SIGN|DCERPC_SEAL))) { - auth_none_req = dcerpc_bind_auth_none_send(c, s->pipe, s->table); - composite_continue(c, auth_none_req, continue_auth_none, c); - return c; - } - - - /* Perform an authenticated DCE-RPC bind - */ - if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) { - /* - we are doing an authenticated connection, - but not using sign or seal. We must force - the CONNECT dcerpc auth type as a NONE auth - type doesn't allow authentication - information to be passed. - */ - conn->flags |= DCERPC_CONNECT; - } - - if (s->binding->flags & DCERPC_AUTH_SPNEGO) { - auth_type = DCERPC_AUTH_TYPE_SPNEGO; - - } else if (s->binding->flags & DCERPC_AUTH_KRB5) { - auth_type = DCERPC_AUTH_TYPE_KRB5; - - } else if (s->binding->flags & DCERPC_SCHANNEL) { - auth_type = DCERPC_AUTH_TYPE_SCHANNEL; - - } else if (s->binding->flags & DCERPC_AUTH_NTLM) { - auth_type = DCERPC_AUTH_TYPE_NTLMSSP; - - } else { - /* try SPNEGO with fallback to NTLMSSP */ - auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, - dcerpc_auth_level(conn), - s->table->authservices->names[0]); - composite_continue(c, auth_req, continue_auth_auto, c); - return c; - } - - auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, auth_type, - dcerpc_auth_level(conn), - s->table->authservices->names[0]); - composite_continue(c, auth_req, continue_auth, c); - return c; -} - - -/* - Receive result of authenticated bind request on dcerpc pipe - - This returns *p, which may be different to the one originally - supllied, as it rebinds to a new pipe due to authentication fallback - -*/ -NTSTATUS dcerpc_pipe_auth_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct dcerpc_pipe **p) -{ - NTSTATUS status; - - struct pipe_auth_state *s = talloc_get_type(c->private_data, - struct pipe_auth_state); - status = composite_wait(c); - if (!NT_STATUS_IS_OK(status)) { - char *uuid_str = GUID_string(s->pipe, &s->table->syntax_id.uuid); - DEBUG(0, ("Failed to bind to uuid %s - %s\n", uuid_str, nt_errstr(status))); - talloc_free(uuid_str); - } else { - talloc_steal(mem_ctx, s->pipe); - *p = s->pipe; - } - - talloc_free(c); - return status; -} - - -/* - Perform an authenticated bind if needed - sync version - - This may change *p, as it rebinds to a new pipe due to authentication fallback -*/ -_PUBLIC_ NTSTATUS dcerpc_pipe_auth(TALLOC_CTX *mem_ctx, - struct dcerpc_pipe **p, - struct dcerpc_binding *binding, - const struct ndr_interface_table *table, - struct cli_credentials *credentials, - struct loadparm_context *lp_ctx) -{ - struct composite_context *c; - - c = dcerpc_pipe_auth_send(*p, binding, table, credentials, lp_ctx); - return dcerpc_pipe_auth_recv(c, mem_ctx, p); -} - - -NTSTATUS dcerpc_generic_session_key(struct dcerpc_connection *c, - DATA_BLOB *session_key) -{ - /* this took quite a few CPU cycles to find ... */ - session_key->data = discard_const_p(unsigned char, "SystemLibraryDTC"); - session_key->length = 16; - return NT_STATUS_OK; -} - -/* - fetch the user session key - may be default (above) or the SMB session key -*/ -_PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, - DATA_BLOB *session_key) -{ - return p->conn->security_state.session_key(p->conn, session_key); -} - - -/* - log a rpc packet in a format suitable for ndrdump. This is especially useful - for sealed packets, where ethereal cannot easily see the contents - - this triggers on a debug level of >= 10 -*/ -_PUBLIC_ void dcerpc_log_packet(const struct ndr_interface_table *ndr, - uint32_t opnum, uint32_t flags, - DATA_BLOB *pkt) -{ - const int num_examples = 20; - int i; - - if (DEBUGLEVEL < 10) return; - - for (i=0;i<num_examples;i++) { - char *name=NULL; - asprintf(&name, "%s/rpclog/%s-%u.%d.%s", - lp_lockdir(global_loadparm), ndr->name, opnum, i, - (flags&NDR_IN)?"in":"out"); - if (name == NULL) { - return; - } - if (!file_exist(name)) { - if (file_save(name, pkt->data, pkt->length)) { - DEBUG(10,("Logged rpc packet to %s\n", name)); - } - free(name); - break; - } - free(name); - } -} - - - -/* - create a secondary context from a primary connection - - this uses dcerpc_alter_context() to create a new dcerpc context_id -*/ -_PUBLIC_ NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, - struct dcerpc_pipe **pp2, - const struct ndr_interface_table *table) -{ - NTSTATUS status; - struct dcerpc_pipe *p2; - - p2 = talloc_zero(p, struct dcerpc_pipe); - if (p2 == NULL) { - return NT_STATUS_NO_MEMORY; - } - p2->conn = talloc_reference(p2, p->conn); - p2->request_timeout = p->request_timeout; - - p2->context_id = ++p->conn->next_context_id; - - p2->syntax = table->syntax_id; - - p2->transfer_syntax = ndr_transfer_syntax; - - p2->binding = talloc_reference(p2, p->binding); - - status = dcerpc_alter_context(p2, p2, &p2->syntax, &p2->transfer_syntax); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p2); - return status; - } - - *pp2 = p2; - - return NT_STATUS_OK; -} diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 539ae6aa80..fde9835cf2 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -112,7 +112,6 @@ static NTSTATUS server_check_password(struct auth_method_context *ctx, NTSTATUS nt_status; struct auth_serversupplied_info *server_info; struct cli_credentials *creds; - const char *user; struct smb_composite_sesssetup session_setup; struct smbcli_session *session = talloc_get_type(ctx->private_data, struct smbcli_session); diff --git a/source4/configure.ac b/source4/configure.ac index 5ea0e51edf..7c95f2a175 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -157,7 +157,7 @@ then builddir_headers="-I\$(builddir)/include -I\$(builddir) -I\$(builddir)/lib "; fi -CPPFLAGS="$builddir_headers-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -I\$(srcdir)/../lib/replace -I\$(srcdir)/../lib/talloc -D_SAMBA_BUILD_=4 -DHAVE_CONFIG_H $CPPFLAGS" +CPPFLAGS="$builddir_headers-I\$(srcdir)/include -I\$(srcdir) -I\$(srcdir)/lib -I\$(srcdir)/../lib/replace -I\$(srcdir)/../lib/talloc -I\$(srcdir)/.. -D_SAMBA_BUILD_=4 -DHAVE_CONFIG_H $CPPFLAGS" SMB_WRITE_PERLVARS(build/smb_build/config.pm) diff --git a/source4/lib/zlib.m4 b/source4/lib/zlib.m4 index 9ee7b8e49e..ac220ebede 100644 --- a/source4/lib/zlib.m4 +++ b/source4/lib/zlib.m4 @@ -1,4 +1,3 @@ - AC_CHECK_HEADERS(zlib.h) AC_CHECK_LIB_EXT(z, ZLIB_LIBS, zlibVersion) diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 44e05dff35..f3e9d46656 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -48,9 +48,7 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBNDR # End SUBSYSTEM NDR_COMPRESSION ################################################ -NDR_COMPRESSION_OBJ_FILES = $(ndrsrcdir)/ndr_compression.o - -$(eval $(call proto_header_template,$(ndrsrcdir)/ndr_compression.h,$(NDR_COMPRESSION_OBJ_FILES:.o=.c))) +NDR_COMPRESSION_OBJ_FILES = ../librpc/ndr/ndr_compression.o [SUBSYSTEM::NDR_SECURITY] PUBLIC_DEPENDENCIES = NDR_MISC LIBSECURITY @@ -320,7 +318,7 @@ NDR_KEYSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_keysvc.o [SUBSYSTEM::NDR_KRB5PAC] PUBLIC_DEPENDENCIES = LIBNDR NDR_NETLOGON NDR_SECURITY -NDR_KRB5PAC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_krb5pac.o $(ndrsrcdir)/ndr_krb5pac.o +NDR_KRB5PAC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_krb5pac.o ../librpc/ndr/ndr_krb5pac.o [SUBSYSTEM::NDR_XATTR] PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY diff --git a/source4/librpc/ndr/ndr_krb5pac.c b/source4/librpc/ndr/ndr_krb5pac.c deleted file mode 100644 index 1b32df4c62..0000000000 --- a/source4/librpc/ndr/ndr_krb5pac.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - routines for marshalling/unmarshalling spoolss subcontext buffer structures - - Copyright (C) Stefan Metzmacher 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -#include "includes.h" -#include "librpc/gen_ndr/ndr_krb5pac.h" - -static size_t _ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) -{ - size_t s = ndr_size_PAC_INFO(r, level, flags); - switch (level) { - case PAC_TYPE_LOGON_INFO: - return NDR_ROUND(s,8); - default: - return s; - } -} - -static size_t _subcontext_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) -{ - size_t s = ndr_size_PAC_INFO(r, level, flags); - return NDR_ROUND(s,8); -} - -enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0))); - { - uint32_t _flags_save_PAC_INFO = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info)); - ndr->flags = _flags_save_PAC_INFO; - } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); - } - if (ndr_flags & NDR_BUFFERS) { - { - uint32_t _flags_save_PAC_INFO = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); - if (r->info) { - NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info)); - { - struct ndr_push *_ndr_info; - NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); - NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type)); - NDR_CHECK(ndr_push_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); - NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); - } - } - ndr->flags = _flags_save_PAC_INFO; - } - } - return NDR_ERR_SUCCESS; -} - -enum ndr_err_code ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER *r) -{ - uint32_t _ptr_info; - TALLOC_CTX *_mem_save_info_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_PAC_TYPE(ndr, NDR_SCALARS, &r->type)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); - { - uint32_t _flags_save_PAC_INFO = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); - if (_ptr_info) { - NDR_PULL_ALLOC(ndr, r->info); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->info, _ptr_info)); - } else { - r->info = NULL; - } - ndr->flags = _flags_save_PAC_INFO; - } - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); - } - if (ndr_flags & NDR_BUFFERS) { - { - uint32_t _flags_save_PAC_INFO = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); - if (r->info) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->info)); - _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); - { - struct ndr_pull *_ndr_info; - NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, r->_ndr_size)); - NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->info, r->type)); - NDR_CHECK(ndr_pull_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); - NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 0, r->_ndr_size)); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); - ndr->offset = _relative_save_offset; - } - ndr->flags = _flags_save_PAC_INFO; - } - } - return NDR_ERR_SUCCESS; -} - -void ndr_print_PAC_BUFFER(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER *r) -{ - ndr_print_struct(ndr, name, "PAC_BUFFER"); - ndr->depth++; - ndr_print_PAC_TYPE(ndr, "type", r->type); - ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?_ndr_size_PAC_INFO(r->info,r->type,0):r->_ndr_size); - ndr_print_ptr(ndr, "info", r->info); - ndr->depth++; - if (r->info) { - ndr_print_set_switch_value(ndr, r->info, r->type); - ndr_print_PAC_INFO(ndr, "info", r->info); - } - ndr->depth--; - ndr_print_uint32(ndr, "_pad", r->_pad); - ndr->depth--; -} |