[SCM] Samba Shared Repository - branch master updated - tevent-0-9-8-351-g30d1328

Andrew Tridgell tridge at samba.org
Tue Sep 15 21:52:51 MDT 2009


The branch, master has been updated
       via  30d13288e5bb506584a0bf012d7b2e579a6a2074 (commit)
       via  f80363c90a60a4496309a50d760ca05ac4b59e4f (commit)
      from  5d2dfd12cf779c410e041a1815e5e3edf0ea38d8 (commit)

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


- Log -----------------------------------------------------------------
commit 30d13288e5bb506584a0bf012d7b2e579a6a2074
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 20:51:10 2009 -0700

    s4-repl: take advantage of async RPC forwarding
    
    This uses async RPC forwarding for the DsReplicaSync call

commit f80363c90a60a4496309a50d760ca05ac4b59e4f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 15 20:50:30 2009 -0700

    s4-rpc: added a module for forwarding RPC requests
    
    dcesrv_irpc_forward_rpc_call() can be used to forward an arbitrary RPC
    request to another task in Samba4, with the return being handled
    asynchronously.
    
    This is useful for forwarding DRS requests to the repl or kcc tasks

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

Summary of changes:
 source4/dsdb/repl/drepl_service.c           |    8 +-
 source4/rpc_server/common/common.h          |   10 +--
 source4/rpc_server/common/forward.c         |  112 +++++++++++++++++++++++++++
 source4/rpc_server/config.mk                |    3 +-
 source4/rpc_server/drsuapi/dcesrv_drsuapi.c |   25 +-----
 5 files changed, 123 insertions(+), 35 deletions(-)
 create mode 100644 source4/rpc_server/common/forward.c


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index cb415b6..75ce42b 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -113,18 +113,16 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg,
 {
 	struct dreplsrv_service *service = talloc_get_type(msg->private_data,
 							   struct dreplsrv_service);
-	WERROR werr;
 	struct GUID *guid = &r->in.req.req1.naming_context->guid;
 
-	werr = dreplsrv_schedule_partition_pull_by_guid(service, msg, guid);
-	if (W_ERROR_IS_OK(werr)) {
+	r->out.result = dreplsrv_schedule_partition_pull_by_guid(service, msg, guid);
+	if (W_ERROR_IS_OK(r->out.result)) {
 		DEBUG(3,("drepl_replica_sync: forcing sync of partition %s\n",
 			 GUID_string(msg, guid)));
 		dreplsrv_run_pending_ops(service);
 	} else {
 		DEBUG(3,("drepl_replica_sync: failed setup of sync of partition %s - %s\n",
-			 GUID_string(msg, guid), win_errstr(werr)));
-		return NT_STATUS_INTERNAL_ERROR;
+			 GUID_string(msg, guid), win_errstr(r->out.result)));
 	}
 	return NT_STATUS_OK;
 }
diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h
index aacd460..5a1d7ab 100644
--- a/source4/rpc_server/common/common.h
+++ b/source4/rpc_server/common/common.h
@@ -25,14 +25,6 @@
 
 struct share_config;
 struct dcesrv_context;
-enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg);
-enum srvsvc_PlatformId dcesrv_common_get_platform_id(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx);
-const char *dcesrv_common_get_lan_root(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx);
-const char *dcesrv_common_get_server_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, const char *server_unc);
-uint32_t dcesrv_common_get_share_permissions(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg);
-uint32_t dcesrv_common_get_share_current_users(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg);
-const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg);
-
 struct dcesrv_context;
 
 struct dcerpc_server_info { 
@@ -42,4 +34,6 @@ struct dcerpc_server_info {
 	uint32_t version_build;
 };
 
+#include "rpc_server/common/proto.h"
+
 #endif /* _DCERPC_SERVER_COMMON_H_ */
diff --git a/source4/rpc_server/common/forward.c b/source4/rpc_server/common/forward.c
new file mode 100644
index 0000000..e0fac0e
--- /dev/null
+++ b/source4/rpc_server/common/forward.c
@@ -0,0 +1,112 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   forwarding of RPC calls to other tasks
+
+   Copyright (C) Andrew Tridgell 2009
+   
+   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_srvsvc.h"
+#include "librpc/gen_ndr/svcctl.h"
+#include "rpc_server/dcerpc_server.h"
+#include "rpc_server/common/common.h"
+#include "rpc_server/common/proto.h"
+#include "messaging/irpc.h"
+
+struct dcesrv_forward_state {
+	const char *opname;
+	struct dcesrv_call_state *dce_call;
+};
+
+/*
+  called when the forwarded rpc request is finished
+ */
+static void dcesrv_irpc_forward_callback(struct irpc_request *ireq)
+{
+	struct dcesrv_forward_state *st = talloc_get_type(ireq->async.private_data, 
+							  struct dcesrv_forward_state);
+	const char *opname = st->opname;
+	NTSTATUS status;
+	if (!NT_STATUS_IS_OK(ireq->status)) {
+		DEBUG(0,("IRPC callback failed for %s - %s\n",
+			 opname, nt_errstr(ireq->status)));
+		st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
+	}
+	talloc_free(ireq);
+	status = dcesrv_reply(st->dce_call);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0,("%s_handler: dcesrv_reply() failed - %s\n",
+			 opname, nt_errstr(status)));
+	}
+}
+
+
+
+/*
+  forward a RPC call using IRPC to another task
+ */
+void dcesrv_irpc_forward_rpc_call(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				  void *r, uint32_t callid,
+				  const struct ndr_interface_table *ndr_table,
+				  const char *dest_task, const char *opname)
+{
+	struct server_id *sid;
+	struct irpc_request *ireq;
+	struct dcesrv_forward_state *st;
+
+	st = talloc(mem_ctx, struct dcesrv_forward_state);
+	if (st == NULL) {
+		dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
+		return;
+	}
+
+	st->dce_call = dce_call;
+	st->opname   = opname;
+
+	/* if the caller has said they can't support async calls
+	   then fail the call */
+	if (!(dce_call->state_flags & DCESRV_CALL_STATE_FLAG_MAY_ASYNC)) {
+		/* we're not allowed to reply async */
+		DEBUG(0,("%s: Not available synchronously\n", dest_task));
+		dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
+		return;
+	}
+
+	/* find the server task */
+	sid = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, dest_task);
+	if (sid == NULL || sid[0].id == 0) {
+		DEBUG(0,("%s: Unable to find %s task\n", dest_task, opname));
+		dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
+		return;
+	}
+
+	/* forward the call */
+	ireq = irpc_call_send(dce_call->msg_ctx, sid[0], ndr_table, callid, r, mem_ctx);
+	if (ireq == NULL) {
+		DEBUG(0,("%s: Failed to forward request to %s task\n", 
+			 opname, dest_task));
+		dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
+		return;
+	}
+
+	/* mark the request as replied async */
+	dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
+
+	/* setup the callback */
+	ireq->async.fn = dcesrv_irpc_forward_callback;
+	ireq->async.private_data = st;
+}
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index f60f833..93617c2 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -8,7 +8,8 @@ PRIVATE_DEPENDENCIES = LIBLDB
 # End SUBSYSTEM DCERPC_COMMON
 ################################################
 
-DCERPC_COMMON_OBJ_FILES = $(addprefix $(rpc_serversrcdir)/common/, server_info.o share_info.o)
+DCERPC_COMMON_OBJ_FILES = $(addprefix $(rpc_serversrcdir)/common/, \
+	server_info.o share_info.o forward.o)
 
 $(eval $(call proto_header_template,$(rpc_serversrcdir)/common/proto.h,$(DCERPC_COMMON_OBJ_FILES:.o=.c)))
 
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index c01711d..491b962 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -28,7 +28,6 @@
 #include "lib/ldb/include/ldb_errors.h"
 #include "param/param.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
-#include "messaging/irpc.h"
 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
 #include "libcli/security/security.h"
 
@@ -232,35 +231,19 @@ static WERROR dcesrv_drsuapi_DsUnbind(struct dcesrv_call_state *dce_call, TALLOC
 static WERROR dcesrv_drsuapi_DsReplicaSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 					   struct drsuapi_DsReplicaSync *r)
 {
-	struct server_id *repld;
-	struct irpc_request *ireq;
-
 	if (security_session_user_level(dce_call->conn->auth_state.session_info) <
 	    SECURITY_DOMAIN_CONTROLLER) {
 		DEBUG(0,("DsReplicaSync refused for security token\n"));
 		return WERR_DS_DRA_ACCESS_DENIED;
 	}
 
-	repld = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "dreplsrv");
-	if (repld == NULL || repld[0].id == 0) {
-		DEBUG(0,("DsReplicaSync: Unable to find dreplsrv task\n"));
-		return WERR_DS_DRA_INTERNAL_ERROR;
-	}
-
-	ireq = IRPC_CALL_SEND(dce_call->msg_ctx, repld[0],
-			      drsuapi, DRSUAPI_DSREPLICASYNC,
-			      r, mem_ctx);
-	if (ireq == NULL) {
-		DEBUG(0,("DsReplicaSync: Failed to forward request to dreplsrv task\n"));
-		return WERR_DS_DRA_INTERNAL_ERROR;
-	}
-
-	/* we are not interested in a reply */
-	talloc_free(ireq);
-
+	dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICASYNC,
+				     &ndr_table_drsuapi,
+				     "dreplsrv", "DsReplicaSync");
 	return WERR_OK;
 }
 
+
 /* 
   drsuapi_DsReplicaAdd 
 */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list