struct cli_state {
int port;
int fd;
- int smb_rw_error; /* Copy of last read or write error. */
+ /* Copy of last read or write error. */
+ enum smb_read_errors smb_rw_error;
uint16 cnum;
uint16 pid;
uint16 mid;
#include "debug.h"
/* this defines the error codes that receive_smb can put in smb_read_error */
-#define READ_TIMEOUT 1
-#define READ_EOF 2
-#define READ_ERROR 3
-#define WRITE_ERROR 4 /* This error code can go into the client smb_rw_error. */
-#define READ_BAD_SIG 5
-#define DO_NOT_DO_TDIS 6 /* cli_close_connection() check for this when smbfs wants to keep tree connected */
+enum smb_read_errors {
+ SMB_READ_OK = 0,
+ SMB_READ_TIMEOUT,
+ SMB_READ_EOF,
+ SMB_READ_ERROR,
+ SMB_WRITE_ERROR, /* This error code can go into the client smb_rw_error. */
+ SMB_READ_BAD_SIG,
+ SMB_DO_NOT_DO_TDIS /* cli_close_connection() check for this when smbfs wants to keep tree connected */
+};
#define DIR_STRUCT_SIZE 43
return get_socket_port(client_fd);
}
-int smb_read_error = 0;
+/****************************************************************************
+ Accessor functions to make thread-safe code easier later...
+****************************************************************************/
+
+static enum smb_read_errors smb_read_error = SMB_READ_OK;
+
+enum smb_read_errors get_smb_read_error(void)
+{
+ return smb_read_error;
+}
+
+void set_smb_read_error(enum smb_read_errors newerr)
+{
+ smb_read_error = newerr;
+}
+
+void cond_set_smb_read_error(enum smb_read_errors newerr)
+{
+ if (smb_read_error == SMB_READ_OK) {
+ smb_read_error = newerr;
+ }
+}
/****************************************************************************
Determine if a file descriptor is in fact a socket.
if (maxcnt <= 0)
return(0);
- smb_read_error = 0;
+ set_smb_read_error(SMB_READ_OK);
/* Blocking read */
if (time_out == 0) {
if (readret == 0) {
DEBUG(5,("read_socket_with_timeout: "
"blocking read. EOF from client.\n"));
- smb_read_error = READ_EOF;
+ set_smb_read_error(SMB_READ_EOF);
return -1;
}
"read error = %s.\n",
strerror(errno) ));
}
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return -1;
}
nread += readret;
"read. select error = %s.\n",
strerror(errno) ));
}
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (selrtn == 0) {
DEBUG(10,("read_socket_with_timeout: timeout read. "
"select timed out.\n"));
- smb_read_error = READ_TIMEOUT;
+ set_smb_read_error(SMB_READ_TIMEOUT);
return -1;
}
/* we got EOF on the file descriptor */
DEBUG(5,("read_socket_with_timeout: timeout read. "
"EOF from client.\n"));
- smb_read_error = READ_EOF;
+ set_smb_read_error(SMB_READ_EOF);
return -1;
}
"read. read error = %s.\n",
strerror(errno) ));
}
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return -1;
}
ssize_t ret;
size_t total=0;
- smb_read_error = 0;
+ set_smb_read_error(SMB_READ_OK);
while (total < N) {
ret = sys_read(fd,buffer + total,N - total);
DEBUG(10,("read_data: read of %d returned 0. "
"Error = %s\n",
(int)(N - total), strerror(errno) ));
- smb_read_error = READ_EOF;
+ set_smb_read_error(SMB_READ_EOF);
return 0;
}
(int)(N - total),
strerror(errno) ));
}
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return -1;
}
total += ret;
{
ssize_t len,ret;
- smb_read_error = 0;
+ set_smb_read_error(SMB_READ_OK);
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0) {
* variables still suck :-). JRA.
*/
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
* variables still suck :-). JRA.
*/
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
}
}
if (ret != len) {
- if (smb_read_error == 0) {
- smb_read_error = READ_ERROR;
- }
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (!srv_check_sign_mac(buffer, true)) {
DEBUG(0, ("receive_smb: SMB Signature verification "
"failed on incoming packet!\n"));
- if (smb_read_error == 0) {
- smb_read_error = READ_BAD_SIG;
+ if (get_smb_read_error() == 0) {
+ smb_read_error = SMB_READ_BAD_SIG;
}
return false;
}
nt_status = cli_nt_error(cli);
if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
- if (cli->smb_rw_error == READ_BAD_SIG) {
+ if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
nt_status = NT_STATUS_ACCESS_DENIED;
} else {
nt_status = NT_STATUS_UNSUCCESSFUL;
#include "includes.h"
-extern int smb_read_error;
-
/****************************************************************************
Change the timeout (in milliseconds).
****************************************************************************/
/* If the server is not responding, note that now */
if (len < 0) {
DEBUG(0, ("Receiving SMB: Server stopped responding\n"));
- cli->smb_rw_error = smb_read_error;
+ cli->smb_rw_error = get_smb_read_error();
close(cli->fd);
cli->fd = -1;
return False;
* Reflected signature on login error.
* Set bad sig but don't close fd.
*/
- cli->smb_rw_error = READ_BAD_SIG;
+ cli->smb_rw_error = SMB_READ_BAD_SIG;
return True;
}
DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
- cli->smb_rw_error = READ_BAD_SIG;
+ cli->smb_rw_error = SMB_READ_BAD_SIG;
close(cli->fd);
cli->fd = -1;
return False;
read_err:
- cli->smb_rw_error = smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
+ cli->smb_rw_error = SMB_READ_ERROR;
close(cli->fd);
cli->fd = -1;
return False;
if (ret <= 0) {
close(cli->fd);
cli->fd = -1;
- cli->smb_rw_error = WRITE_ERROR;
+ 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;
if (ret <= 0) {
close(cli->fd);
cli->fd = -1;
- cli->smb_rw_error = WRITE_ERROR;
+ 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;
if (ret <= 0) {
close(cli->fd);
cli->fd = -1;
- cli->smb_rw_error = WRITE_ERROR;
+ cli->smb_rw_error = SMB_WRITE_ERROR;
DEBUG(0,("Error writing %d extradata "
"bytes to client. %d (%s)\n",
(int)extradata,(int)ret, strerror(errno) ));
* later. This tree disconnect forces the peer to clean up, since the
* connection will be going away.
*
- * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS
+ * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS
* the only user for this so far is smbmount which passes opened connection
* down to kernel's smbfs module.
*/
- if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) {
+ if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) {
cli_tdis(cli);
}
static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli)
{
switch(cli->smb_rw_error) {
- case READ_TIMEOUT:
+ case SMB_READ_TIMEOUT:
return NT_STATUS_IO_TIMEOUT;
- case READ_EOF:
+ case SMB_READ_EOF:
return NT_STATUS_END_OF_FILE;
/* What we shoud really do for read/write errors is convert from errno. */
/* FIXME. JRA. */
- case READ_ERROR:
+ case SMB_READ_ERROR:
return NT_STATUS_INVALID_NETWORK_RESPONSE;
- case WRITE_ERROR:
+ case SMB_WRITE_ERROR:
return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- case READ_BAD_SIG:
+ case SMB_READ_BAD_SIG:
return NT_STATUS_INVALID_PARAMETER;
default:
break;
/* Was it server socket error ? */
if (cli->fd == -1 && cli->smb_rw_error) {
switch(cli->smb_rw_error) {
- case READ_TIMEOUT:
+ case SMB_READ_TIMEOUT:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Call timed out: server did not respond after %d milliseconds",
cli->timeout);
break;
- case READ_EOF:
+ case SMB_READ_EOF:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Call returned zero bytes (EOF)" );
break;
- case READ_ERROR:
+ case SMB_READ_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Read error: %s", strerror(errno) );
break;
- case WRITE_ERROR:
+ case SMB_WRITE_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Write error: %s", strerror(errno) );
break;
- case READ_BAD_SIG:
+ case SMB_READ_BAD_SIG:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Server packet had invalid SMB signature!");
break;
extern int max_send;
extern enum protocol_types Protocol;
-extern int smb_read_error;
extern struct current_user current_user;
static const char *known_nt_pipes[] = {
bool global_client_failed_oplock_break = False;
extern uint32 global_client_caps;
-extern int smb_read_error;
static struct kernel_oplocks *koplocks;
static files_struct *irix_oplock_receive_message(fd_set *fds)
{
- extern int smb_read_error;
oplock_stat_t os;
char dummy;
struct file_id fileid;
DEBUG(0,("irix_oplock_receive_message: read of kernel "
"notification failed. Error was %s.\n",
strerror(errno) ));
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return NULL;
}
*/
return NULL;
}
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return NULL;
}
extern struct auth_context *negprot_global_auth_context;
extern int smb_echo_count;
-extern int smb_read_error;
const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
int max_recv = BUFFER_SIZE;
extern int last_message;
-extern int smb_read_error;
SIG_ATOMIC_T reload_after_sighup = 0;
SIG_ATOMIC_T got_sig_term = 0;
extern bool global_machine_password_needs_changing;
* variables still suck :-). JRA.
*/
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return false;
}
}
}
if (ret != len) {
- if (smb_read_error == 0) {
- smb_read_error = READ_ERROR;
- }
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
}
if (ret != STANDARD_WRITE_AND_X_HEADER_SIZE) {
- if (smb_read_error == 0) {
- smb_read_error = READ_ERROR;
- }
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (*buffer == NULL) {
DEBUG(0, ("Could not allocate inbuf of length %d\n",
(int)sizeof(writeX_header)));
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (*buffer == NULL) {
DEBUG(0, ("Could not allocate inbuf of length %d\n",
(int)len+4));
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
ssize_t len,ret;
int min_recv_size = lp_min_receive_file_size();
- smb_read_error = 0;
+ set_smb_read_error(SMB_READ_OK);
*p_unread = 0;
len = read_smb_length_return_keepalive(fd, lenbuf, timeout);
* variables still suck :-). JRA.
*/
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (*buffer == NULL) {
DEBUG(0, ("Could not allocate inbuf of length %d\n",
(int)len+4));
- if (smb_read_error == 0)
- smb_read_error = READ_ERROR;
+ cond_set_smb_read_error(SMB_READ_ERROR);
return -1;
}
if (!srv_check_sign_mac(*buffer, true)) {
DEBUG(0, ("receive_smb: SMB Signature verification failed on "
"incoming packet!\n"));
- if (smb_read_error == 0) {
- smb_read_error = READ_BAD_SIG;
- }
+ cond_set_smb_read_error(SMB_READ_BAD_SIG);
return -1;
}
ssize_t len;
*p_unread = 0;
- smb_read_error = 0;
+ set_smb_read_error(SMB_READ_OK);
again:
msg->buf.length);
if (*buffer == NULL) {
DEBUG(0, ("talloc failed\n"));
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return False;
}
*buffer_len = msg->buf.length;
/* Check if error */
if (selrtn == -1) {
/* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
+ set_smb_read_error(SMB_READ_ERROR);
return False;
}
/* Did we timeout ? */
if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
+ set_smb_read_error(SMB_READ_TIMEOUT);
return False;
}
{
time_t t;
- if (smb_read_error == READ_EOF) {
+ if (get_smb_read_error() == SMB_READ_EOF) {
DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
- return False;
+ return false;
}
- if (smb_read_error == READ_ERROR) {
+ if (get_smb_read_error() == SMB_READ_ERROR) {
DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
strerror(errno)));
- return False;
+ return false;
}
- if (smb_read_error == READ_BAD_SIG) {
+ if (get_smb_read_error() == SMB_READ_BAD_SIG) {
DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
- return False;
+ return false;
}
*last_timeout_processing_time = t = time(NULL);
extern int max_send;
extern enum protocol_types Protocol;
-extern int smb_read_error;
extern uint32 global_client_caps;
extern struct current_user current_user;