[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Thu Jul 8 08:50:14 MDT 2010


The branch, master has been updated
       via  690ed0c... s3-rpc: when using rpc_pipe_open_internal, make sure to go through NDR.
      from  309ad2b... s4-smbtorture: skip wbcChangeUserPassword test when no oldpass is set in environment.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 690ed0c5e2c61584daa2acb5dbfb680ecee83e0f
Author: Günther Deschner <gd at samba.org>
Date:   Fri Jul 2 10:17:44 2010 +0200

    s3-rpc: when using rpc_pipe_open_internal, make sure to go through NDR.
    
    Otherwise a lot of information that is usually generated in the ndr_push remains
    in an uninitialized state.
    
    Guenther

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

Summary of changes:
 pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm    |   54 ----------
 source3/include/proto.h                    |    1 -
 source3/rpc_server/rpc_ncacn_np_internal.c |  156 +++++++++++++++++++++++++++-
 source3/rpc_server/srv_netlog_nt.c         |    6 +-
 source3/rpc_server/srv_pipe_hnd.c          |    1 -
 source3/rpc_server/srv_spoolss_util.c      |    1 -
 source3/smbd/lanman.c                      |   16 ++--
 source3/winbindd/winbindd.c                |    5 +
 source3/winbindd/winbindd_samr.c           |    2 -
 9 files changed, 167 insertions(+), 75 deletions(-)


Changeset truncated at 500 lines:

diff --git a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
index 311eb5b..a25d12b 100644
--- a/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
+++ b/pidl/lib/Parse/Pidl/Samba3/ServerNDR.pm
@@ -225,58 +225,6 @@ sub ParseFunction($$)
 	pidl "";
 }
 
-sub ParseDispatchFunction($)
-{
-	my ($if) = @_;
-
-	pidl_hdr "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r);";
-	pidl "NTSTATUS rpc_$if->{NAME}_dispatch(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *_r)";
-	pidl "{";
-	indent;
-	pidl "if (cli->pipes_struct == NULL) {";
-	pidl "\treturn NT_STATUS_INVALID_PARAMETER;";
-	pidl "}";
-	pidl "";
-	pidl "/* set opnum in fake rpc header */";
-	pidl "cli->pipes_struct->hdr_req.opnum = opnum;";
-	pidl "";
-	pidl "switch (opnum)";
-	pidl "{";
-	indent;
-	foreach my $fn (@{$if->{FUNCTIONS}}) {
-		next if ($fn->{PROPERTIES}{noopnum});
-		my $op = "NDR_".uc($fn->{NAME});
-		pidl "case $op: {";
-		indent;
-		pidl "struct $fn->{NAME} *r = (struct $fn->{NAME} *)_r;";
-
-		pidl "if (DEBUGLEVEL >= 10) {";
-		pidl "\tNDR_PRINT_IN_DEBUG($fn->{NAME}, r);";
-		pidl "}";
-
-		CallWithStruct("cli->pipes_struct", "mem_ctx", $fn, 
-			sub { pidl "\treturn NT_STATUS_NO_MEMORY;"; });
-
-		pidl "if (DEBUGLEVEL >= 10) {";
-		pidl "\tNDR_PRINT_OUT_DEBUG($fn->{NAME}, r);";
-		pidl "}";
-
-		pidl "return NT_STATUS_OK;";
-		deindent;
-		pidl "}";
-		pidl "";
-	}
-
-	pidl "default:";
-	pidl "\treturn NT_STATUS_NOT_IMPLEMENTED;";
-	deindent;
-	pidl "}";
-	deindent;
-	pidl "}";
-
-	pidl "";
-}
-
 sub ParseInterface($)
 {
 	my $if = shift;
@@ -317,8 +265,6 @@ sub ParseInterface($)
 	pidl "}";
 	pidl "";
 
-	ParseDispatchFunction($if);
-
 	if (not has_property($if, "no_srv_register")) {
 	    pidl_hdr "NTSTATUS rpc_$if->{NAME}_init(void);";
 	    pidl "NTSTATUS rpc_$if->{NAME}_init(void)";
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d08dc59..8ce2bf1 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4875,7 +4875,6 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
 					      const char *client_address,
 					      struct auth_serversupplied_info *server_info);
 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract_syntax,
-				NTSTATUS (*dispatch) (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32_t opnum, void *r),
 				struct auth_serversupplied_info *serversupplied_info,
 				struct rpc_pipe_client **presult);
 NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
diff --git a/source3/rpc_server/rpc_ncacn_np_internal.c b/source3/rpc_server/rpc_ncacn_np_internal.c
index f9317b9..d702e4b 100644
--- a/source3/rpc_server/rpc_ncacn_np_internal.c
+++ b/source3/rpc_server/rpc_ncacn_np_internal.c
@@ -20,6 +20,7 @@
  */
 
 #include "includes.h"
+#include "rpc_server/srv_pipe_internal.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -186,6 +187,155 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
 	return p;
 }
 
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS internal_ndr_push(TALLOC_CTX *mem_ctx,
+				  struct rpc_pipe_client *cli,
+				  const struct ndr_interface_table *table,
+				  uint32_t opnum,
+				  void *r)
+{
+	const struct ndr_interface_call *call;
+	struct ndr_push *push;
+	enum ndr_err_code ndr_err;
+	DATA_BLOB blob;
+	bool ret;
+
+	if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax) ||
+	    (opnum >= table->num_calls)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	call = &table->calls[opnum];
+
+	if (DEBUGLEVEL >= 10) {
+		ndr_print_function_debug(call->ndr_print,
+					 call->name, NDR_IN, r);
+	}
+
+	push = ndr_push_init_ctx(mem_ctx);
+	if (push == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ndr_err = call->ndr_push(push, NDR_IN, r);
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		TALLOC_FREE(push);
+		return ndr_map_error2ntstatus(ndr_err);
+	}
+
+	blob = ndr_push_blob(push);
+	ret = prs_init_data_blob(&cli->pipes_struct->in_data.data, &blob, mem_ctx);
+	TALLOC_FREE(push);
+	if (!ret) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS internal_ndr_pull(TALLOC_CTX *mem_ctx,
+				  struct rpc_pipe_client *cli,
+				  const struct ndr_interface_table *table,
+				  uint32_t opnum,
+				  void *r)
+{
+	const struct ndr_interface_call *call;
+	struct ndr_pull *pull;
+	enum ndr_err_code ndr_err;
+	DATA_BLOB blob;
+	bool ret;
+
+	if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax) ||
+	    (opnum >= table->num_calls)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	call = &table->calls[opnum];
+
+	ret = prs_data_blob(&cli->pipes_struct->out_data.rdata, &blob, mem_ctx);
+	if (!ret) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	pull = ndr_pull_init_blob(&blob, mem_ctx);
+	if (pull == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* have the ndr parser alloc memory for us */
+	pull->flags |= LIBNDR_FLAG_REF_ALLOC;
+	ndr_err = call->ndr_pull(pull, NDR_OUT, r);
+	TALLOC_FREE(pull);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		return ndr_map_error2ntstatus(ndr_err);
+	}
+
+	if (DEBUGLEVEL >= 10) {
+		ndr_print_function_debug(call->ndr_print,
+					 call->name, NDR_OUT, r);
+	}
+
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+static NTSTATUS rpc_pipe_internal_dispatch(struct rpc_pipe_client *cli,
+					   TALLOC_CTX *mem_ctx,
+					   const struct ndr_interface_table *table,
+					   uint32_t opnum, void *r)
+{
+	NTSTATUS status;
+	int num_cmds = rpc_srv_get_pipe_num_cmds(&table->syntax_id);
+	const struct api_struct *cmds = rpc_srv_get_pipe_cmds(&table->syntax_id);
+	int i;
+
+	if (cli->pipes_struct == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* set opnum in fake rpc header */
+	cli->pipes_struct->hdr_req.opnum = opnum;
+
+	for (i = 0; i < num_cmds; i++) {
+		if (cmds[i].opnum == opnum && cmds[i].fn != NULL) {
+			break;
+		}
+	}
+
+	if (i == num_cmds) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	prs_init_empty(&cli->pipes_struct->out_data.rdata, cli->pipes_struct->mem_ctx, MARSHALL);
+
+	status = internal_ndr_push(mem_ctx, cli, table, opnum, r);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (!cmds[i].fn(cli->pipes_struct)) {
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	status = internal_ndr_pull(mem_ctx, cli, table, opnum, r);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	prs_mem_free(&cli->pipes_struct->in_data.data);
+	prs_mem_free(&cli->pipes_struct->out_data.rdata);
+
+	return NT_STATUS_OK;
+}
+
 /**
  * @brief Create a new RPC client context which uses a local dispatch function.
  *
@@ -217,10 +367,6 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx,
  */
 NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
 				const struct ndr_syntax_id *abstract_syntax,
-				NTSTATUS (*dispatch) (struct rpc_pipe_client *cli,
-						      TALLOC_CTX *mem_ctx,
-						      const struct ndr_interface_table *table,
-						      uint32_t opnum, void *r),
 				struct auth_serversupplied_info *serversupplied_info,
 				struct rpc_pipe_client **presult)
 {
@@ -233,7 +379,7 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx,
 
 	result->abstract_syntax = *abstract_syntax;
 	result->transfer_syntax = ndr_transfer_syntax;
-	result->dispatch = dispatch;
+	result->dispatch = rpc_pipe_internal_dispatch;
 
 	result->pipes_struct = make_internal_rpc_pipe_p(
 		result, abstract_syntax, "", serversupplied_info);
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index cccd0d5..c7ff3dd 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -406,7 +406,7 @@ NTSTATUS _netr_NetrEnumerateTrustedDomains(pipes_struct *p,
 	DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
 
 	status = rpc_pipe_open_internal(p->mem_ctx, &ndr_table_lsarpc.syntax_id,
-					rpc_lsarpc_dispatch, p->server_info,
+					p->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
@@ -629,7 +629,7 @@ static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
 	ZERO_STRUCT(user_handle);
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-					rpc_samr_dispatch, server_info,
+					server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto out;
@@ -1032,7 +1032,7 @@ static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
 	ZERO_STRUCT(user_handle);
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-					rpc_samr_dispatch, server_info,
+					server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto out;
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index e933992..9ed54a4 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -1411,7 +1411,6 @@ NTSTATUS rpc_connect_spoolss_pipe(connection_struct *conn,
 	if (!conn->spoolss_pipe) {
 		status = rpc_pipe_open_internal(conn,
 						&ndr_table_spoolss.syntax_id,
-						rpc_spoolss_dispatch,
 						conn->server_info,
 						&conn->spoolss_pipe);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c
index 4c70ce4..49f6a71 100644
--- a/source3/rpc_server/srv_spoolss_util.c
+++ b/source3/rpc_server/srv_spoolss_util.c
@@ -250,7 +250,6 @@ static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
 	/* create winreg connection */
 	status = rpc_pipe_open_internal(mem_ctx,
 					&ndr_table_winreg.syntax_id,
-					rpc_winreg_dispatch,
 					server_info,
 					&pipe_handle);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index ba51c61..ce7ad0e 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -2235,7 +2235,7 @@ static bool api_RNetShareAdd(struct smbd_server_connection *sconn,
 	}
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
-					rpc_srvsvc_dispatch, conn->server_info,
+					conn->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("api_RNetShareAdd: could not connect to srvsvc: %s\n",
@@ -2341,7 +2341,7 @@ static bool api_RNetGroupEnum(struct smbd_server_connection *sconn,
 	}
 
 	status = rpc_pipe_open_internal(
-		talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+		talloc_tos(), &ndr_table_samr.syntax_id,
 		conn->server_info, &samr_pipe);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
@@ -2523,7 +2523,7 @@ static bool api_NetUserGetGroups(struct smbd_server_connection *sconn,
 	endp = *rdata + *rdata_len;
 
 	status = rpc_pipe_open_internal(
-		talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+		talloc_tos(), &ndr_table_samr.syntax_id,
 		conn->server_info, &samr_pipe);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
@@ -2679,7 +2679,7 @@ static bool api_RNetUserEnum(struct smbd_server_connection *sconn,
 	endp = *rdata + *rdata_len;
 
 	status = rpc_pipe_open_internal(
-		talloc_tos(), &ndr_table_samr.syntax_id, rpc_samr_dispatch,
+		talloc_tos(), &ndr_table_samr.syntax_id,
 		conn->server_info, &samr_pipe);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("api_RNetUserEnum: Could not connect to samr: %s\n",
@@ -2922,7 +2922,7 @@ static bool api_SetUserPassword(struct smbd_server_connection *sconn,
 	ZERO_STRUCT(user_handle);
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-					rpc_samr_dispatch, conn->server_info,
+					conn->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n",
@@ -3138,7 +3138,7 @@ static bool api_SamOEMChangePassword(struct smbd_server_connection *sconn,
 	memcpy(hash.hash, data+516, 16);
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-					rpc_samr_dispatch, conn->server_info,
+					conn->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("api_SamOEMChangePassword: could not connect to samr: %s\n",
@@ -3691,7 +3691,7 @@ static bool api_RNetServerGetInfo(struct smbd_server_connection *sconn,
 	p2 = p + struct_len;
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_srvsvc.syntax_id,
-					rpc_srvsvc_dispatch, conn->server_info,
+					conn->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("api_RNetServerGetInfo: could not connect to srvsvc: %s\n",
@@ -4113,7 +4113,7 @@ static bool api_RNetUserGetInfo(struct smbd_server_connection *sconn,
 	ZERO_STRUCT(user_handle);
 
 	status = rpc_pipe_open_internal(mem_ctx, &ndr_table_samr.syntax_id,
-					rpc_samr_dispatch, conn->server_info,
+					conn->server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0,("api_RNetUserGetInfo: could not connect to samr: %s\n",
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 25d4e1d..7e1eb3e 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -26,6 +26,8 @@
 #include "winbindd.h"
 #include "../../nsswitch/libwbclient/wbc_async.h"
 #include "librpc/gen_ndr/messaging.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/srv_samr.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -1289,6 +1291,9 @@ int main(int argc, char **argv, char **envp)
 
 	winbindd_register_handlers();
 
+	rpc_lsarpc_init();
+	rpc_samr_init();
+
 	if (!init_system_info()) {
 		DEBUG(0,("ERROR: failed to setup system user info.\n"));
 		exit(1);
diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c
index a2865a0..e9e3e6f 100644
--- a/source3/winbindd/winbindd_samr.c
+++ b/source3/winbindd/winbindd_samr.c
@@ -60,7 +60,6 @@ static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,
 	/* create a samr connection */
 	status = rpc_pipe_open_internal(mem_ctx,
 					&ndr_table_samr.syntax_id,
-					rpc_samr_dispatch,
 					server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -132,7 +131,6 @@ static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx,
 	/* create a samr connection */
 	status = rpc_pipe_open_internal(mem_ctx,
 					&ndr_table_lsarpc.syntax_id,
-					rpc_lsarpc_dispatch,
 					server_info,
 					&cli);
 	if (!NT_STATUS_IS_OK(status)) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list