summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-04-23 04:21:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:51:33 -0500
commit493a37ba663686b7bee3f7093d6650a24250f101 (patch)
treeabcf06347f09b6468848308edce37f8ad28379b4 /source4/librpc/rpc
parent1793845e08dafa2566d8713cbf21adcda1641f0f (diff)
downloadsamba-493a37ba663686b7bee3f7093d6650a24250f101.tar.gz
samba-493a37ba663686b7bee3f7093d6650a24250f101.tar.bz2
samba-493a37ba663686b7bee3f7093d6650a24250f101.zip
r335: added much better handling of servers that die unexpectedly during a
request (a dead socket). I discovered this when testing against Sun's PC-NetLink. cleaned up the naming of some of the samr requests add IDL and test code for samr_QueryGroupMember(), samr_SetMemberAttributesOfGroup() and samr_Shutdown(). (actually, I didn't leave the samr_Shutdown() test in, as its fatal to windows servers due to doing exactly what it says it does). (This used to be commit 925bc2622c105dee4ffff809c6c35cd209a839f8)
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc_smb.c1
-rw-r--r--source4/librpc/rpc/dcerpc_tcp.c31
2 files changed, 24 insertions, 8 deletions
diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c
index 7822231b82..3d646944ac 100644
--- a/source4/librpc/rpc/dcerpc_smb.c
+++ b/source4/librpc/rpc/dcerpc_smb.c
@@ -75,6 +75,7 @@ static NTSTATUS dcerpc_raw_recv(struct dcerpc_pipe *p,
DATA_BLOB payload;
status = smb_raw_trans_recv(req, mem_ctx, &trans);
+
/* STATUS_BUFFER_OVERFLOW means that there is more data
available via SMBreadX */
if (!NT_STATUS_IS_OK(status) &&
diff --git a/source4/librpc/rpc/dcerpc_tcp.c b/source4/librpc/rpc/dcerpc_tcp.c
index 77b536b10c..1b016b8957 100644
--- a/source4/librpc/rpc/dcerpc_tcp.c
+++ b/source4/librpc/rpc/dcerpc_tcp.c
@@ -29,6 +29,18 @@ struct tcp_private {
uint32 port;
};
+
+/*
+ mark the socket dead
+*/
+static void tcp_sock_dead(struct tcp_private *tcp)
+{
+ if (tcp && tcp->fd != -1) {
+ close(tcp->fd);
+ tcp->fd = -1;
+ }
+}
+
static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
TALLOC_CTX *mem_ctx,
DATA_BLOB *blob)
@@ -45,7 +57,8 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
ret = read_data(tcp->fd, blob1.data, blob1.length);
if (ret != blob1.length) {
- return NT_STATUS_NET_WRITE_FAULT;
+ tcp_sock_dead(tcp);
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
/* this could be a ncacn_http endpoint - this doesn't work
@@ -54,7 +67,8 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
memmove(blob1.data, blob1.data+14, 2);
ret = read_data(tcp->fd, blob1.data+2, 14);
if (ret != 14) {
- return NT_STATUS_NET_WRITE_FAULT;
+ tcp_sock_dead(tcp);
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
}
@@ -74,7 +88,8 @@ static NTSTATUS tcp_raw_recv(struct dcerpc_pipe *p,
ret = read_data(tcp->fd, blob->data + blob1.length, frag_length - blob1.length);
if (ret != frag_length - blob1.length) {
- return NT_STATUS_NET_WRITE_FAULT;
+ tcp_sock_dead(tcp);
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
return NT_STATUS_OK;
@@ -90,7 +105,8 @@ static NTSTATUS tcp_full_request(struct dcerpc_pipe *p,
ret = write_data(tcp->fd, request_blob->data, request_blob->length);
if (ret != request_blob->length) {
- return NT_STATUS_NET_WRITE_FAULT;
+ tcp_sock_dead(tcp);
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
return tcp_raw_recv(p, mem_ctx, reply_blob);
@@ -120,7 +136,8 @@ static NTSTATUS tcp_initial_request(struct dcerpc_pipe *p,
ret = write_data(tcp->fd, blob->data, blob->length);
if (ret != blob->length) {
- return NT_STATUS_NET_WRITE_FAULT;
+ tcp_sock_dead(tcp);
+ return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
}
return NT_STATUS_OK;
@@ -134,9 +151,7 @@ static NTSTATUS tcp_shutdown_pipe(struct dcerpc_pipe *p)
{
struct tcp_private *tcp = p->transport.private;
- if (tcp) {
- close(tcp->fd);
- }
+ tcp_sock_dead(tcp);
return NT_STATUS_OK;
}