ssize_t ret;
size_t total=0;
+ if (fd == -1) {
+ errno = EIO;
+ return -1;
+ }
+
while (total < N) {
ret = sys_read(fd,buffer + total,N - total);
if (ret == 0) {
size_t total=0;
ssize_t ret;
+ if (fd == -1) {
+ errno = EIO;
+ return -1;
+ }
+
while (total < N) {
ret = sys_write(fd, buffer + total, N - total);
if (ret == -1) {
}
+/****************************************************************************
+ mark the socket as dead
+****************************************************************************/
+void cli_sock_dead(struct cli_socket *sock)
+{
+ if (sock->fd != -1) {
+ close(sock->fd);
+ sock->fd = -1;
+ }
+}
+
/****************************************************************************
reduce socket reference count - if it becomes zero then close
****************************************************************************/
void cli_sock_close(struct cli_socket *sock)
{
sock->reference_count--;
- if (sock->reference_count <= 0 && sock->fd != -1) {
- close(sock->fd);
- sock->fd = -1;
+ if (sock->reference_count <= 0) {
+ cli_sock_dead(sock);
}
}
****************************************************************************/
ssize_t cli_sock_write(struct cli_socket *sock, const char *data, size_t len)
{
+ if (sock->fd == -1) {
+ errno = EIO;
+ return -1;
+ }
+
return write_data(sock->fd, data, len);
}
****************************************************************************/
ssize_t cli_sock_read(struct cli_socket *sock, char *data, size_t len)
{
+ if (sock->fd == -1) {
+ errno = EIO;
+ return -1;
+ }
+
return read_data(sock->fd, data, len);
}
}
}
+/*
+ mark the transport as dead
+*/
+void cli_transport_dead(struct cli_transport *transport)
+{
+ cli_sock_dead(transport->socket);
+}
+
/****************************************************************************
_send() call fails completely */
if (!req) return NT_STATUS_UNSUCCESSFUL;
- /* remove it from the list of pending requests (a null op if
- its not in the list) */
- DLIST_REMOVE(req->transport->pending_requests, req);
+ if (req->transport) {
+ /* remove it from the list of pending requests (a null op if
+ its not in the list) */
+ DLIST_REMOVE(req->transport->pending_requests, req);
+ }
/* ahh, its so nice to destroy a complex structure in such a
simple way! */
/* keep receiving packets until this one is replied to */
while (!req->in.buffer) {
if (!cli_transport_select(req->transport)) {
+ req->status = NT_STATUS_UNSUCCESSFUL;
return False;
}
if (!cli_request_receive_next(req->transport)) {
- cli_transport_close(req->transport);
+ cli_transport_dead(req->transport);
req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
return False;
}
parms->out.params.data = NULL;
if (!cli_request_receive(req)) {
- req->status = NT_STATUS_UNSUCCESSFUL;
return cli_request_destroy(req);
}
/******************/
/* Function: 0x04 */
- NTSTATUS samr_Shutdown ();
+
+ /*
+ shutdown the SAM - once you call this the SAM will be dead
+ */
+ NTSTATUS samr_Shutdown (
+ [in,ref] policy_handle *handle
+ );
/******************/
/* Function: 0x05 */
[in] uint32 rid
);
+
/************************/
/* Function 0x19 */
- NTSTATUS samr_QUERY_GROUPMEM();
+ /*
+ this isn't really valid IDL, but it does work. I suspect
+ I need to do some more pidl work to get this really right
+ */
+ typedef struct {
+ uint32 count;
+ uint32 v[count];
+ } samr_intArray;
+
+ typedef struct {
+ samr_intArray *rids;
+ samr_intArray *unknown7;
+ } samr_ridArray;
+
+ NTSTATUS samr_QueryGroupMember(
+ [in,ref] policy_handle *handle,
+ [out] uint32 *count,
+ [out] samr_ridArray rids
+ );
+
/************************/
/* Function 0x1a */
- NTSTATUS samr_SET_MEMBER_ATTRIBUTES_OF_GROUP();
+
+ /*
+ win2003 seems to accept any data at all for the two integers
+ below, and doesn't seem to do anything with them that I can
+ see. Weird. I really expected the first integer to be a rid
+ and the second to be the attributes for that rid member.
+ */
+ NTSTATUS samr_SetMemberAttributesOfGroup(
+ [in,ref] policy_handle *handle,
+ [in] uint32 unknown1,
+ [in] uint32 unknown2
+ );
/************************/
/************************/
/* Function 0x1f */
- NTSTATUS samr_AddAliasMem(
+ NTSTATUS samr_AddAliasMember(
[in,ref] policy_handle *handle,
[in,ref] dom_sid2 *sid
);
/************************/
/* Function 0x20 */
- NTSTATUS samr_DelAliasMem(
+ NTSTATUS samr_DeleteAliasMember(
[in,ref] policy_handle *handle,
[in,ref] dom_sid2 *sid
);
[out] dom_sid2 *sid
);
+
/************************/
/* Function 0x42 */
NTSTATUS samr_SET_DSRM_PASSWORD();
/************************/
/* Function 0x43 */
- NTSTATUS samr_VALIDATE_PASSWORD();
+ /*
+ I haven't been able to work out the format of this one yet.
+ Seems to start with a switch level for a union?
+ */
+ NTSTATUS samr_ValidatePassword();
}
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) &&
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)
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
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;
}
}
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;
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);
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;
{
struct tcp_private *tcp = p->transport.private;
- if (tcp) {
- close(tcp->fd);
- }
+ tcp_sock_dead(tcp);
return NT_STATUS_OK;
}
insert_ofs, insert_ofs+n, depth+1);
}
return;
+ } else {
+#if 0
+ print_depth(depth);
+ printf("expand by %d gives fault 0x%x\n", n, p->last_fault_code);
+#endif
}
if (p->last_fault_code == 5) {
reopen(&p, iface);
static void test_auto_scan(TALLOC_CTX *mem_ctx, const struct dcerpc_interface_table *iface)
{
- test_scan_call(mem_ctx, iface, 0x41);
+ test_scan_call(mem_ctx, iface, 0x26);
}
BOOL torture_rpc_autoidl(int dummy)
struct policy_handle *domain_handle,
const struct dom_sid *domain_sid)
{
- struct samr_AddAliasMem r;
- struct samr_DelAliasMem d;
+ struct samr_AddAliasMember r;
+ struct samr_DeleteAliasMember d;
NTSTATUS status;
BOOL ret = True;
struct dom_sid *sid;
sid = dom_sid_add_rid(mem_ctx, domain_sid, 512);
- printf("testing AddAliasMem\n");
+ printf("testing AddAliasMember\n");
r.in.handle = alias_handle;
r.in.sid = sid;
- status = dcerpc_samr_AddAliasMem(p, mem_ctx, &r);
+ status = dcerpc_samr_AddAliasMember(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("AddAliasMem failed - %s\n", nt_errstr(status));
+ printf("AddAliasMember failed - %s\n", nt_errstr(status));
ret = False;
}
d.in.handle = alias_handle;
d.in.sid = sid;
- status = dcerpc_samr_DelAliasMem(p, mem_ctx, &d);
+ status = dcerpc_samr_DeleteAliasMember(p, mem_ctx, &d);
if (!NT_STATUS_IS_OK(status)) {
- printf("DelAliasMem failed - %s\n", nt_errstr(status));
+ printf("DelAliasMember failed - %s\n", nt_errstr(status));
ret = False;
}
NTSTATUS status;
struct samr_AddGroupMember r;
struct samr_DeleteGroupMember d;
+ struct samr_QueryGroupMember q;
+ struct samr_SetMemberAttributesOfGroup s;
BOOL ret = True;
uint32 rid;
return False;
}
+ /* this one is quite strange. I am using random inputs in the
+ hope of triggering an error that might give us a clue */
+ s.in.handle = group_handle;
+ s.in.unknown1 = random();
+ s.in.unknown2 = random();
+
+ status = dcerpc_samr_SetMemberAttributesOfGroup(p, mem_ctx, &s);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetMemberAttributesOfGroup failed - %s\n", nt_errstr(status));
+ return False;
+ }
+
+ q.in.handle = group_handle;
+
+ status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &q);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("QueryGroupMember failed - %s\n", nt_errstr(status));
+ return False;
+ }
status = dcerpc_samr_DeleteGroupMember(p, mem_ctx, &d);
if (!NT_STATUS_IS_OK(status)) {
ZERO_STRUCT(user_handle);
ZERO_STRUCT(alias_handle);
+ ZERO_STRUCT(group_handle);
+ ZERO_STRUCT(domain_handle);
printf("Testing OpenDomain\n");