/**************************************************************************** Calculate the recommended write buffer size ****************************************************************************/ static size_t cli_write_max_bufsize(struct cli_state *cli, uint16_t write_mode) { if (write_mode == 0 && !client_is_signing_on(cli) && !cli_encryption_on(cli) && (cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) && (cli->capabilities & CAP_LARGE_FILES)) { /* Only do massive writes if we can do them direct * with no signing or encrypting - not on a pipe. */ return CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE; } if (cli->is_samba) { return CLI_SAMBA_MAX_LARGE_WRITEX_SIZE; } if (((cli->capabilities & CAP_LARGE_WRITEX) == 0) || client_is_signing_on(cli) || strequal(cli->dev, "LPT1:")) { /* * Printer devices are restricted to max_xmit writesize in * Vista and XPSP3 as are signing connections. */ return (cli->max_xmit - (smb_size+32)) & ~1023; } return CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; }
static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) { size_t len; for(;;) { NTSTATUS status; set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, cli->timeout, maxlen, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("client_receive_smb failed\n")); show_msg(cli->inbuf); if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { set_smb_read_error(&cli->smb_rw_error, SMB_READ_EOF); return -1; } if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { set_smb_read_error(&cli->smb_rw_error, SMB_READ_TIMEOUT); return -1; } set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); return -1; } /* * I don't believe len can be < 0 with NT_STATUS_OK * returned above, but this check doesn't hurt. JRA. */ if ((ssize_t)len < 0) { return len; } /* Ignore session keepalive packets. */ if(CVAL(cli->inbuf,0) != SMBkeepalive) { break; } } if (cli_encryption_on(cli)) { NTSTATUS status = cli_decrypt_message(cli); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", nt_errstr(status))); cli->smb_rw_error = SMB_READ_BAD_DECRYPT; return -1; } } show_msg(cli->inbuf); return len; }
bool cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; ssize_t ret; char *buf_out = cli->outbuf; bool enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom ([email protected]) */ if (cli->fd == -1) return false; cli_calculate_sign_mac(cli, cli->outbuf); if (enc_on) { NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error in encrypting client message. Error %s\n", nt_errstr(status) )); return false; } } len = smb_len(buf_out) + 4; while (nwritten < len) { ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { if (enc_on) { cli_free_enc_buffer(cli, buf_out); } close(cli->fd); cli->fd = -1; cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return false; } nwritten += ret; } if (enc_on) { cli_free_enc_buffer(cli, buf_out); } /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) cli->mid++; return true; }
/**************************************************************************** Calculate the recommended read buffer size ****************************************************************************/ static size_t cli_read_max_bufsize(struct cli_state *cli) { if (!client_is_signing_on(cli) && !cli_encryption_on(cli) && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; } if (cli->capabilities & CAP_LARGE_READX) { return cli->is_samba ? CLI_SAMBA_MAX_LARGE_READX_SIZE : CLI_WINDOWS_MAX_LARGE_READX_SIZE; } return (cli->max_xmit - (smb_size+32)) & ~1023; }