[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha3-169-gb9cac46

Jelmer Vernooij jelmer at samba.org
Tue Apr 15 16:03:45 GMT 2008


The branch, v4-0-test has been updated
       via  b9cac469f3c869a26f415a6c551cf6e8fbb06ed6 (commit)
      from  19890c0d15adf4f099365f276a4bfdd3f4de52b6 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit b9cac469f3c869a26f415a6c551cf6e8fbb06ed6
Author: Jelmer Vernooij <jelmer at samba.org>
Date:   Tue Apr 15 18:03:09 2008 +0200

    Split binding structure handling out into a separate file.
    
    For easier synchronisation with Samba 3.

-----------------------------------------------------------------------

Summary of changes:
 source/librpc/config.mk         |    1 +
 source/librpc/rpc/binding.c     |  724 +++++++++++++++++++++++++++++++++++++++
 source/librpc/rpc/dcerpc_util.c |  695 -------------------------------------
 3 files changed, 725 insertions(+), 695 deletions(-)
 create mode 100644 source/librpc/rpc/binding.c


Changeset truncated at 500 lines:

diff --git a/source/librpc/config.mk b/source/librpc/config.mk
index 92409da..11a320a 100644
--- a/source/librpc/config.mk
+++ b/source/librpc/config.mk
@@ -590,6 +590,7 @@ dcerpc_VERSION = 0.0.1
 dcerpc_SOVERSION = 0
 
 dcerpc_OBJ_FILES = $(addprefix librpc/rpc/, dcerpc.o dcerpc_auth.o dcerpc_schannel.o dcerpc_util.o \
+				   binding.o \
 				  dcerpc_error.o dcerpc_smb.o dcerpc_smb2.o dcerpc_sock.o dcerpc_connect.o dcerpc_secondary.o)
 
 
diff --git a/source/librpc/rpc/binding.c b/source/librpc/rpc/binding.c
new file mode 100644
index 0000000..ae88dce
--- /dev/null
+++ b/source/librpc/rpc/binding.c
@@ -0,0 +1,724 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   dcerpc utility functions
+
+   Copyright (C) Andrew Tridgell 2003
+   Copyright (C) Jelmer Vernooij 2004
+   Copyright (C) Andrew Bartlett <abartlet at 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 "librpc/gen_ndr/ndr_epmapper_c.h"
+#include "librpc/gen_ndr/ndr_dcerpc.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+
+#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;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list