_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! */
*/
BOOL cli_request_send(struct cli_request *req)
{
+ uint_t ret;
+
if (IVAL(req->out.buffer, 0) == 0) {
_smb_setlen(req->out.buffer, req->out.size - NBT_HDR_SIZE);
}
cli_request_calculate_sign_mac(req);
- if (req->out.size != cli_sock_write(req->transport->socket, req->out.buffer, req->out.size)) {
+ ret = cli_sock_write(req->transport->socket, req->out.buffer, req->out.size);
+
+ if (req->out.size != ret) {
req->transport->error.etype = ETYPE_SOCKET;
req->transport->error.e.socket_error = SOCKET_WRITE_ERROR;
DEBUG(0,("Error writing %d bytes to server - %s\n",
/* 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;
}
- cli_request_receive_next(req->transport);
+ if (!cli_request_receive_next(req->transport)) {
+ cli_transport_dead(req->transport);
+ req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+ return False;
+ }
}
return True;
if (transport->oplock.handler) {
uint16 tid = SVAL(hdr, HDR_TID);
uint16 fnum = SVAL(vwv,VWV(2));
- uint8 level = CVAL(vwv,VWV(3));
+ uint8 level = CVAL(vwv,VWV(3)+1);
transport->oplock.handler(transport, tid, fnum, level, transport->oplock.private);
}
char **dest, const char *src, int byte_len, unsigned flags)
{
if (!(flags & STR_ASCII) &&
- ((flags & STR_UNICODE || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
+ (((flags & STR_UNICODE) || (req->flags2 & FLAGS2_UNICODE_STRINGS)))) {
return cli_req_pull_ucs2(req, mem_ctx, dest, src, byte_len, flags);
}
/*
put a NTTIME into a packet
*/
-
-void cli_push_nttime(void *base, uint16 offset, NTTIME *t)
+void cli_push_nttime(void *base, uint16 offset, NTTIME t)
{
- SIVAL(base, offset, t->low);
- SIVAL(base, offset+4, t->high);
+ SBVAL(base, offset, t);
}
/*
*/
NTTIME cli_pull_nttime(void *base, uint16 offset)
{
- NTTIME ret;
- ret.low = IVAL(base, offset);
- ret.high = IVAL(base, offset+4);
+ NTTIME ret = BVAL(base, offset);
return ret;
}
uint16 len_offset, uint16 str_offset,
unsigned flags)
{
+ int extra;
dest->s = NULL;
-
+
if (len_offset > blob->length-4) {
return 0;
}
} else {
dest->private_length = IVAL(blob->data, len_offset);
}
+ extra = 0;
dest->s = NULL;
if (!(flags & STR_ASCII) &&
((flags & STR_UNICODE) ||
(session->transport->negotiate.capabilities & CAP_UNICODE))) {
+ int align = 0;
+ if ((str_offset&1) && !(flags & STR_NOALIGN)) {
+ align = 1;
+ }
+ if (flags & STR_LEN_NOTERM) {
+ extra = 2;
+ }
+ return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, &dest->s,
+ blob->data+str_offset+align,
+ dest->private_length, flags);
+ }
+
+ if (flags & STR_LEN_NOTERM) {
+ extra = 1;
+ }
+
+ return extra + cli_blob_pull_ascii(mem_ctx, blob, &dest->s,
+ blob->data+str_offset, dest->private_length, flags);
+}
+
+/*
+ pull a string from a blob, returning a talloced char *
+
+ Currently only used by the UNIX search info level.
+
+ the string length is limited by 2 things:
+ - the data size in the blob
+ - the end of string (null termination)
+
+ on failure zero is returned and dest->s is set to NULL, otherwise the number
+ of bytes consumed in the blob is returned
+*/
+size_t cli_blob_pull_unix_string(struct cli_session *session,
+ TALLOC_CTX *mem_ctx,
+ DATA_BLOB *blob,
+ const char **dest,
+ uint16 str_offset,
+ unsigned flags)
+{
+ int extra = 0;
+ *dest = NULL;
+
+ if (!(flags & STR_ASCII) &&
+ ((flags & STR_UNICODE) ||
+ (session->transport->negotiate.capabilities & CAP_UNICODE))) {
+ int align = 0;
if ((str_offset&1) && !(flags & STR_NOALIGN)) {
- str_offset++;
+ align = 1;
}
- return cli_blob_pull_ucs2(mem_ctx, blob, &dest->s,
- blob->data+str_offset, dest->private_length, flags);
+ if (flags & STR_LEN_NOTERM) {
+ extra = 2;
+ }
+ return align + extra + cli_blob_pull_ucs2(mem_ctx, blob, dest,
+ blob->data+str_offset+align,
+ -1, flags);
+ }
+
+ if (flags & STR_LEN_NOTERM) {
+ extra = 1;
}
- return cli_blob_pull_ascii(mem_ctx, blob, &dest->s,
- blob->data+str_offset, dest->private_length, flags);
+ return extra + cli_blob_pull_ascii(mem_ctx, blob, dest,
+ blob->data+str_offset, -1, flags);
}
+
/*
append a string into a blob
*/