summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2008-05-20 18:08:41 +0200
committerMichael Adam <obnox@samba.org>2008-05-22 11:29:57 +0200
commitb398a96b09af5268e71bd3108f6c1e97568736f8 (patch)
tree5f00890e3310cc3baa062294d71394c30df5de3a
parent59a6b2df747796dadebf92001a32cba0e6a80252 (diff)
downloadsamba-b398a96b09af5268e71bd3108f6c1e97568736f8.tar.gz
samba-b398a96b09af5268e71bd3108f6c1e97568736f8.tar.bz2
samba-b398a96b09af5268e71bd3108f6c1e97568736f8.zip
rpc_client: use endpoint mapper to get the port for rpc_pipe_open_tcp().
Michael (This used to be commit f7db445c828c0eef2c08b538bd07d485dc248689)
-rw-r--r--source3/Makefile.in7
-rw-r--r--source3/client/client_proto.h1
-rw-r--r--source3/include/proto.h8
-rw-r--r--source3/rpc_client/cli_pipe.c167
4 files changed, 171 insertions, 12 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 6899faf91e..faf4ccf4f6 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -750,7 +750,7 @@ SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
- rpc_client/cli_pipe.o $(RPC_PARSE_OBJ2) \
+ rpc_client/cli_pipe.o librpc/rpc/binding.o $(RPC_PARSE_OBJ2) \
$(RPC_CLIENT_OBJ1) \
$(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ $(SMBLDAP_OBJ) $(LDB_OBJ) $(GROUPDB_OBJ) \
$(LIBMSRPC_GEN_OBJ)
@@ -829,6 +829,7 @@ LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ)
CLIENT_OBJ1 = client/client.o client/clitar.o rpc_client/cli_pipe.o \
+ librpc/rpc/binding.o \
client/dnsbrowse.o \
$(RPC_CLIENT_OBJ1) \
$(RPC_PARSE_OBJ2)
@@ -837,7 +838,7 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(LIBMSRPC_GEN_OBJ) \
$(READLINE_OBJ) $(POPT_LIB_OBJ) \
$(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ) \
- $(DISPLAY_SEC_OBJ)
+ $(DISPLAY_SEC_OBJ)
LIBNETAPI_OBJ1 = lib/netapi/netapi.o \
lib/netapi/cm.o \
@@ -1144,7 +1145,7 @@ NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
librpc/gen_ndr/ndr_netlogon.o
-VLP_OBJ1 = ../testsuite/printing/vlp.o $(RPC_CLIENT_OBJ1) $(RPC_PARSE_OBJ2) $(RPC_CLIENT_OBJ)
+VLP_OBJ1 = ../testsuite/printing/vlp.o $(RPC_CLIENT_OBJ1) $(RPC_PARSE_OBJ2) $(RPC_CLIENT_OBJ) librpc/rpc/binding.o
VLP_OBJ = $(VLP_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(LIBMSRPC_GEN_OBJ) \
diff --git a/source3/client/client_proto.h b/source3/client/client_proto.h
index d88805a097..7adc086186 100644
--- a/source3/client/client_proto.h
+++ b/source3/client/client_proto.h
@@ -123,7 +123,6 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
const char *password,
struct cli_pipe_auth_data **presult);
NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
- uint16_t port,
const struct ndr_syntax_id *abstract_syntax,
struct rpc_pipe_client **presult);
struct rpc_pipe_client *cli_rpc_pipe_open_noauth(struct cli_state *cli, int pipe_idx, NTSTATUS *perr);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f76e43ac64..03a7f918c0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -7061,8 +7061,14 @@ NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
const char *username,
const char *password,
struct cli_pipe_auth_data **presult);
+NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
+ uint16_t port,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_pipe_client **presult);
+NTSTATUS rpc_pipe_get_tcp_port(const char *host,
+ const struct ndr_syntax_id *abstract_syntax,
+ uint16_t *pport);
NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
- uint16_t port,
const struct ndr_syntax_id *abstract_syntax,
struct rpc_pipe_client **presult);
NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 9908c69674..7a5a62f2d9 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -18,6 +18,7 @@
*/
#include "includes.h"
+#include "librpc/gen_ndr/cli_epmapper.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_CLI
@@ -2509,13 +2510,13 @@ static int rpc_pipe_sock_destructor(struct rpc_pipe_client *p)
return 0;
}
-/********************************************************************
- Create a rpc pipe client struct, connecting to a tcp port
- ********************************************************************/
-NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
- uint16_t port,
- const struct ndr_syntax_id *abstract_syntax,
- struct rpc_pipe_client **presult)
+/**
+ * Create an rpc pipe client struct, connecting to a tcp port.
+ */
+NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
+ uint16_t port,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_pipe_client **presult)
{
struct rpc_pipe_client *result;
struct sockaddr_storage addr;
@@ -2563,6 +2564,158 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
return status;
}
+/**
+ * Determine the tcp port on which a dcerpc interface is listening
+ * for the ncacn_ip_tcp transport via the endpoint mapper of the
+ * target host.
+ */
+NTSTATUS rpc_pipe_get_tcp_port(const char *host,
+ const struct ndr_syntax_id *abstract_syntax,
+ uint16_t *pport)
+{
+ NTSTATUS status;
+ struct rpc_pipe_client *epm_pipe = NULL;
+ struct cli_pipe_auth_data *auth = NULL;
+ struct dcerpc_binding *map_binding = NULL;
+ struct dcerpc_binding *res_binding = NULL;
+ struct epm_twr_t *map_tower = NULL;
+ struct epm_twr_t *res_towers = NULL;
+ struct policy_handle *entry_handle = NULL;
+ uint32_t num_towers = 0;
+ uint32_t max_towers = 1;
+ struct epm_twr_p_t towers;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+ if (pport == NULL) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ /* open the connection to the endpoint mapper */
+ status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
+ &ndr_table_epmapper.syntax_id,
+ &epm_pipe);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_anon_bind_data(tmp_ctx, &auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpc_pipe_bind(epm_pipe, auth);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ /* create tower for asking the epmapper */
+
+ map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
+ if (map_binding == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ map_binding->transport = NCACN_IP_TCP;
+ map_binding->object = *abstract_syntax;
+ map_binding->host = host; /* needed? */
+ map_binding->endpoint = "0"; /* correct? needed? */
+
+ map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
+ if (map_tower == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
+ &(map_tower->tower));
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ /* allocate further parameters for the epm_Map call */
+
+ res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
+ if (res_towers == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ towers.twr = res_towers;
+
+ entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
+ if (entry_handle == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* ask the endpoint mapper for the port */
+
+ status = rpccli_epm_Map(epm_pipe,
+ tmp_ctx,
+ &(abstract_syntax->uuid),
+ map_tower,
+ entry_handle,
+ max_towers,
+ &num_towers,
+ &towers);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ if (num_towers != 1) {
+ status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* extract the port from the answer */
+
+ status = dcerpc_binding_from_tower(tmp_ctx,
+ &(towers.twr->tower),
+ &res_binding);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ /* are further checks here necessary? */
+ if (res_binding->transport != NCACN_IP_TCP) {
+ status = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ *pport = (uint16_t)atoi(res_binding->endpoint);
+
+done:
+ TALLOC_FREE(tmp_ctx);
+ return status;
+}
+
+/**
+ * Create a rpc pipe client struct, connecting to a host via tcp.
+ * The port is determined by asking the endpoint mapper on the given
+ * host.
+ */
+NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_pipe_client **presult)
+{
+ NTSTATUS status;
+ uint16_t port;
+
+ status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpc_pipe_open_tcp_port(mem_ctx, host, port,
+ abstract_syntax, presult);
+
+done:
+ return status;
+}
+
/********************************************************************
Create a rpc pipe client struct, connecting to a unix domain socket
********************************************************************/