svn commit: samba r8021 - in branches/SAMBA_4_0/source: ntvfs/ipc rpc_server

metze at samba.org metze at samba.org
Thu Jun 30 17:10:04 GMT 2005


Author: metze
Date: 2005-06-30 17:10:03 +0000 (Thu, 30 Jun 2005)
New Revision: 8021

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

Log:
we only need to return STATUS_BUFFER_OVERFLOW for the ipc_trans replies
and not for the ipc_read() replies as here the client explicit says how much data it wants

the write_fn() in dcesrv_output() now returns NTSTATUS

and the ipc specific implementations are moved to the ntvfs_ipc module

metze
Modified:
   branches/SAMBA_4_0/source/ntvfs/ipc/vfs_ipc.c
   branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c
   branches/SAMBA_4_0/source/rpc_server/dcerpc_sock.c


Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/ipc/vfs_ipc.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/ipc/vfs_ipc.c	2005-06-30 17:05:02 UTC (rev 8020)
+++ branches/SAMBA_4_0/source/ntvfs/ipc/vfs_ipc.c	2005-06-30 17:10:03 UTC (rev 8021)
@@ -350,6 +350,18 @@
 	return NT_STATUS_ACCESS_DENIED;
 }
 
+static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten)
+{
+	DATA_BLOB *blob = private_data;
+
+	if (out->length < blob->length) {
+		blob->length = out->length;
+	}
+	memcpy(blob->data, out->data, blob->length);
+	*nwritten = blob->length;
+	return NT_STATUS_OK;
+}
+
 /*
   read from a file
 */
@@ -380,7 +392,7 @@
 	}
 
 	if (data.length != 0) {
-		status = dcesrv_output_blob(p->dce_conn, &data);
+		status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output);
 		if (NT_STATUS_IS_ERR(status)) {
 			return status;
 		}
@@ -604,7 +616,23 @@
 	return NT_STATUS_ACCESS_DENIED;
 }
 
+static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten)
+{
+	NTSTATUS status = NT_STATUS_OK;
+	DATA_BLOB *blob = private_data;
 
+	if (out->length > blob->length) {
+		status = STATUS_BUFFER_OVERFLOW;
+	}
+
+	if (out->length < blob->length) {
+		blob->length = out->length;
+	}
+	memcpy(blob->data, out->data, blob->length);
+	*nwritten = blob->length;
+	return status;
+}
+
 /* SMBtrans - handle a DCERPC command */
 static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs,
 			       struct smbsrv_request *req, struct smb_trans2 *trans)
@@ -638,7 +666,7 @@
 	  async calls. Again, we only expect NT_STATUS_OK. If the call fails then
 	  the error is encoded at the dcerpc level
 	*/
-	status = dcesrv_output_blob(p->dce_conn, &trans->out.data);
+	status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output);
 	if (NT_STATUS_IS_ERR(status)) {
 		return status;
 	}

Modified: branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c	2005-06-30 17:05:02 UTC (rev 8020)
+++ branches/SAMBA_4_0/source/rpc_server/dcerpc_server.c	2005-06-30 17:10:03 UTC (rev 8021)
@@ -1100,20 +1100,19 @@
 
   The first argument to write_fn() will be 'private', the second will
   be a pointer to a buffer containing the data to be sent and the 3rd
-  will be the number of bytes to be sent.
+  will be a pointer to a size_t variable that will be set to the
+  number of bytes that are consumed from the output.
 
-  write_fn() should return the number of bytes successfully written.
-
-  this will return STATUS_BUFFER_OVERFLOW if there is more to be written
   from the current fragment
 */
 NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, 
-		       void *private,
-		       ssize_t (*write_fn)(void *, DATA_BLOB *))
+		       void *private_data,
+		       NTSTATUS (*write_fn)(void *private_data, DATA_BLOB *output, size_t *nwritten))
 {
+	NTSTATUS status;
 	struct dcesrv_call_state *call;
 	struct dcesrv_call_reply *rep;
-	ssize_t nwritten;
+	size_t nwritten;
 
 	call = dce_conn->call_list;
 	if (!call || !call->replies) {
@@ -1128,12 +1127,8 @@
 	}
 	rep = call->replies;
 
-	nwritten = write_fn(private, &rep->data);
-	if (nwritten == -1) {
-		/* TODO: hmm, how do we cope with this? destroy the
-		   connection perhaps? */
-		return NT_STATUS_UNSUCCESSFUL;
-	}
+	status = write_fn(private_data, &rep->data, &nwritten);
+	NT_STATUS_IS_ERR_RETURN(status);
 
 	rep->data.length -= nwritten;
 	rep->data.data += nwritten;
@@ -1141,8 +1136,6 @@
 	if (rep->data.length == 0) {
 		/* we're done with this section of the call */
 		DLIST_REMOVE(call->replies, rep);
-	} else {
-		return STATUS_BUFFER_OVERFLOW;
 	}
 
 	if (call->replies == NULL) {
@@ -1151,33 +1144,9 @@
 		talloc_free(call);
 	}
 
-	return NT_STATUS_OK;
+	return status;
 }
 
-
-/*
-  write_fn() for dcesrv_output_blob()
-*/
-static ssize_t dcesrv_output_blob_write_fn(void *private, DATA_BLOB *out)
-{
-	DATA_BLOB *blob = private;
-	if (out->length < blob->length) {
-		blob->length = out->length;
-	}
-	memcpy(blob->data, out->data, blob->length);
-	return blob->length;
-}
-
-/*
-  a simple wrapper for dcesrv_output() for when we want to output
-  into a data blob
-*/
-NTSTATUS dcesrv_output_blob(struct dcesrv_connection *dce_conn, 
-			    DATA_BLOB *blob)
-{
-	return dcesrv_output(dce_conn, blob, dcesrv_output_blob_write_fn);
-}
-
 static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, uint32_t state_flags, struct dcesrv_context **_dce_ctx)
 {
 	NTSTATUS status;

Modified: branches/SAMBA_4_0/source/rpc_server/dcerpc_sock.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/dcerpc_sock.c	2005-06-30 17:05:02 UTC (rev 8020)
+++ branches/SAMBA_4_0/source/rpc_server/dcerpc_sock.c	2005-06-30 17:10:03 UTC (rev 8021)
@@ -38,18 +38,17 @@
 /*
   write_fn callback for dcesrv_output()
 */
-static ssize_t dcerpc_write_fn(void *private, DATA_BLOB *out)
+static NTSTATUS dcerpc_write_fn(void *private_data, DATA_BLOB *out, size_t *nwritten)
 {
 	NTSTATUS status;
-	struct socket_context *sock = private;
+	struct socket_context *sock = talloc_get_type(private_data, struct socket_context);
 	size_t sendlen;
 
 	status = socket_send(sock, out, &sendlen, 0);
-	if (NT_STATUS_IS_ERR(status)) {
-		return -1;
-	}
+	NT_STATUS_IS_ERR_RETURN(status);
 
-	return sendlen;
+	*nwritten = sendlen;
+	return status;
 }
 
 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)



More information about the samba-cvs mailing list