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

metze at samba.org metze at samba.org
Mon Dec 6 17:48:51 GMT 2004


Author: metze
Date: 2004-12-06 17:48:51 +0000 (Mon, 06 Dec 2004)
New Revision: 4082

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

Log:
support alter_context requests

metze

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	2004-12-06 17:44:33 UTC (rev 4081)
+++ branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c	2004-12-06 17:48:51 UTC (rev 4082)
@@ -564,7 +564,66 @@
 	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;
 
+	/* 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);
+	}
+
+	/* setup a alter_ack */
+	dcesrv_init_hdr(&pkt);
+	pkt.auth_length = 0;
+	pkt.call_id = call->pkt.call_id;
+	pkt.ptype = DCERPC_PKT_ALTER_ACK;
+	pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
+	pkt.u.alter_ack.max_xmit_frag = 0x2000;
+	pkt.u.alter_ack.max_recv_frag = 0x2000;
+	pkt.u.alter_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id;
+	pkt.u.alter_ack.secondary_address = NULL;
+	pkt.u.alter_ack.num_results = 1;
+	pkt.u.alter_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx);
+	if (!pkt.u.alter_ack.ctx_list) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	pkt.u.alter_ack.ctx_list[0].result = result;
+	pkt.u.alter_ack.ctx_list[0].reason = reason;
+	GUID_from_string(NDR_GUID, &pkt.u.alter_ack.ctx_list[0].syntax.uuid);
+	pkt.u.alter_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
+	pkt.u.alter_ack.auth_info = data_blob(NULL, 0);
+
+	if (!dcesrv_auth_alter_ack(call, &pkt)) {
+		return dcesrv_bind_nak(call, 0);
+	}
+
+	rep = talloc_p(call, struct dcesrv_call_reply);
+	if (!rep) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = dcerpc_push_auth(&rep->data, call, &pkt, 
+				  call->conn->auth_state.auth_info);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	dcerpc_set_frag_length(&rep->data, rep->data.length);
+
+	DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *);
+	DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *);
+
+	return NT_STATUS_OK;
+}
+
 /*
   handle a dcerpc request packet
 */
@@ -848,6 +907,9 @@
 	case DCERPC_PKT_AUTH3:
 		status = dcesrv_auth3(call);
 		break;
+	case DCERPC_PKT_ALTER:
+		status = dcesrv_alter(call);
+		break;
 	case DCERPC_PKT_REQUEST:
 		status = dcesrv_request(call);
 		break;

Modified: branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2004-12-06 17:44:33 UTC (rev 4081)
+++ branches/SAMBA_4_0/source/rpc_server/dcesrv_auth.c	2004-12-06 17:48:51 UTC (rev 4082)
@@ -193,8 +193,79 @@
 	return True;
 }
 
+/*
+  parse any auth information from a dcerpc alter request
+  return False if we can't handle the auth request for some 
+  reason (in which case we send a bind_nak (is this true for here?))
+*/
+BOOL dcesrv_auth_alter(struct dcesrv_call_state *call)
+{
+	struct dcerpc_packet *pkt = &call->pkt;
+	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) {
+		return False;
+	}
+
+	dce_conn->auth_state.auth_info = talloc_p(dce_conn, struct dcerpc_auth);
+	if (!dce_conn->auth_state.auth_info) {
+		return False;
+	}
+
+	status = ndr_pull_struct_blob(&pkt->u.alter.auth_info,
+				      call,
+				      dce_conn->auth_state.auth_info,
+				      (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
+	if (!NT_STATUS_IS_OK(status)) {
+		return False;
+	}
+
+	return True;
+}
+
 /*
+  add any auth information needed in a alter ack, and process the authentication
+  information found in the alter.
+*/
+BOOL dcesrv_auth_alter_ack(struct dcesrv_call_state *call, struct dcerpc_packet *pkt)
+{
+	struct dcesrv_connection *dce_conn = call->conn;
+	NTSTATUS status;
+
+	if (!call->conn->auth_state.gensec_security) {
+		return False;
+	}
+
+	status = gensec_update(dce_conn->auth_state.gensec_security,
+			       call,
+			       dce_conn->auth_state.auth_info->credentials, 
+			       &dce_conn->auth_state.auth_info->credentials);
+	
+	if (NT_STATUS_IS_OK(status)) {
+		status = gensec_session_info(dce_conn->auth_state.gensec_security,
+					     &dce_conn->auth_state.session_info);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(1, ("Failed to establish session_info: %s\n", nt_errstr(status)));
+			return False;
+		}
+
+		/* Now that we are authenticated, got back to the generic session key... */
+		dce_conn->auth_state.session_key = dcesrv_generic_session_key;
+		return True;
+	} else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+		dce_conn->auth_state.auth_info->auth_pad_length = 0;
+		dce_conn->auth_state.auth_info->auth_reserved = 0;
+		return True;
+	} else {
+		DEBUG(2, ("Failed to finish dcesrv auth alter_ack: %s\n", nt_errstr(status)));
+		return True;
+	}
+}
+
+/*
   generate a CONNECT level verifier
 */
 static NTSTATUS dcesrv_connect_verifier(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)



More information about the samba-cvs mailing list