svn commit: samba r4642 - in branches/SAMBA_4_0/source/rpc_server: .

tridge at samba.org tridge at samba.org
Mon Jan 10 12:39:42 GMT 2005


Author: tridge
Date: 2005-01-10 12:39:42 +0000 (Mon, 10 Jan 2005)
New Revision: 4642

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4642

Log:
added support for alter_context in the server for adding new interfaces to an existing pipe





Modified:
   branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c
   branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c


Changeset:
Modified: branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c	2005-01-10 12:30:13 UTC (rev 4641)
+++ branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c	2005-01-10 12:39:42 UTC (rev 4642)
@@ -599,23 +599,87 @@
 	return NT_STATUS_OK;
 }
 
+
 /*
   handle a bind request
 */
+static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32 context_id)
+{
+	uint32_t if_version, transfer_syntax_version;
+	const char *uuid, *transfer_syntax;
+	struct dcesrv_connection_context *context;
+	const struct dcesrv_interface *iface;
+
+	if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version;
+	uuid = GUID_string(call, &call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid);
+	if (!uuid) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
+	transfer_syntax = GUID_string(call, 
+				      &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid);
+	if (!transfer_syntax ||
+	    strcasecmp(NDR_GUID, transfer_syntax) != 0 ||
+	    NDR_GUID_VERSION != transfer_syntax_version) {
+		/* we only do NDR encoded dcerpc */
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version);
+	if (iface == NULL) {
+		DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version));
+		return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
+	}
+
+	/* add this context to the list of available context_ids */
+	context = talloc(call->conn, struct dcesrv_connection_context);
+	if (context == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	context->conn = call->conn;
+	context->iface = iface;
+	context->context_id = context_id;
+	context->private = NULL;
+	context->handles = NULL;
+	DLIST_ADD(call->conn->contexts, context);
+	call->context = context;
+
+	return NT_STATUS_OK;
+}
+
+
+/*
+  handle a bind request
+*/
 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
 {
 	struct dcerpc_packet pkt;
 	struct dcesrv_call_reply *rep;
 	NTSTATUS status;
 	uint32_t result=0, reason=0;
+	uint32_t context_id;
 
 	/* handle any authentication that is being requested */
 	if (!dcesrv_auth_alter(call)) {
 		/* TODO: work out the right reject code */
-		return dcesrv_bind_nak(call, 0);
+		result = DCERPC_BIND_PROVIDER_REJECT;
+		reason = DCERPC_BIND_REASON_ASYNTAX;		
 	}
 
-	/* setup a alter_ack */
+	context_id = call->pkt.u.alter.ctx_list[0].context_id;
+
+	/* see if they are asking for a new interface */
+	if (result == 0 &&
+	    dcesrv_find_context(call->conn, context_id) == NULL) {
+		status = dcesrv_alter_new_context(call, context_id);
+		if (!NT_STATUS_IS_OK(status)) {
+			result = DCERPC_BIND_PROVIDER_REJECT;
+			reason = DCERPC_BIND_REASON_ASYNTAX;		
+		}
+	}
+
+	/* setup a alter_resp */
 	dcesrv_init_hdr(&pkt);
 	pkt.auth_length = 0;
 	pkt.call_id = call->pkt.call_id;
@@ -623,7 +687,7 @@
 	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
 	pkt.u.alter_resp.max_xmit_frag = 0x2000;
 	pkt.u.alter_resp.max_recv_frag = 0x2000;
-	pkt.u.alter_resp.assoc_group_id = call->pkt.u.bind.assoc_group_id;
+	pkt.u.alter_resp.assoc_group_id = call->pkt.u.alter.assoc_group_id;
 	pkt.u.alter_resp.secondary_address = NULL;
 	pkt.u.alter_resp.num_results = 1;
 	pkt.u.alter_resp.ctx_list = talloc_p(call, struct dcerpc_ack_ctx);
@@ -635,6 +699,7 @@
 	GUID_from_string(NDR_GUID, &pkt.u.alter_resp.ctx_list[0].syntax.uuid);
 	pkt.u.alter_resp.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
 	pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
+	pkt.u.alter_resp.secondary_address = "";
 
 	if (!dcesrv_auth_alter_ack(call, &pkt)) {
 		return dcesrv_bind_nak(call, 0);

Modified: branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2005-01-10 12:30:13 UTC (rev 4641)
+++ branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2005-01-10 12:39:42 UTC (rev 4642)
@@ -204,9 +204,13 @@
 	struct dcesrv_connection *dce_conn = call->conn;
 	NTSTATUS status;
 
-	/* We can't work without an existing gensec state, and an new blob to feed it */
-	if (!dce_conn->auth_state.gensec_security ||
-	    pkt->u.alter.auth_info.length == 0) {
+	/* on a pure interface change there is no auth blob */
+	if (pkt->u.alter.auth_info.length == 0) {
+		return True;
+	}
+
+	/* We can't work without an existing gensec state */
+	if (!dce_conn->auth_state.gensec_security) {
 		return False;
 	}
 
@@ -235,6 +239,11 @@
 	struct dcesrv_connection *dce_conn = call->conn;
 	NTSTATUS status;
 
+	/* on a pure interface change there is no auth blob */
+	if (pkt->u.alter.auth_info.length == 0) {
+		return True;
+	}
+
 	if (!call->conn->auth_state.gensec_security) {
 		return False;
 	}



More information about the samba-cvs mailing list