summaryrefslogtreecommitdiff
path: root/source3/smbd/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/process.c')
-rw-r--r--source3/smbd/process.c78
1 files changed, 38 insertions, 40 deletions
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index dd120f9bd2..40c85d4a62 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -40,7 +40,7 @@ extern bool global_machine_password_needs_changing;
static void construct_reply_common(struct smb_request *req, const char *inbuf,
char *outbuf);
-bool smbd_lock_socket(struct smbd_server_connection *sconn)
+static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
{
bool ok;
@@ -48,6 +48,12 @@ bool smbd_lock_socket(struct smbd_server_connection *sconn)
return true;
}
+ smbd_server_conn->smb1.echo_handler.ref_count++;
+
+ if (smbd_server_conn->smb1.echo_handler.ref_count > 1) {
+ return true;
+ }
+
DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
@@ -61,7 +67,14 @@ bool smbd_lock_socket(struct smbd_server_connection *sconn)
return true;
}
-bool smbd_unlock_socket(struct smbd_server_connection *sconn)
+void smbd_lock_socket(struct smbd_server_connection *sconn)
+{
+ if (!smbd_lock_socket_internal(sconn)) {
+ exit_server_cleanly("failed to lock socket");
+ }
+}
+
+static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
{
bool ok;
@@ -69,6 +82,12 @@ bool smbd_unlock_socket(struct smbd_server_connection *sconn)
return true;
}
+ smbd_server_conn->smb1.echo_handler.ref_count--;
+
+ if (smbd_server_conn->smb1.echo_handler.ref_count > 0) {
+ return true;
+ }
+
ok = fcntl_lock(smbd_server_conn->smb1.echo_handler.socket_lock_fd,
SMB_F_SETLKW, 0, 0, F_UNLCK);
if (!ok) {
@@ -80,6 +99,13 @@ bool smbd_unlock_socket(struct smbd_server_connection *sconn)
return true;
}
+void smbd_unlock_socket(struct smbd_server_connection *sconn)
+{
+ if (!smbd_unlock_socket_internal(sconn)) {
+ exit_server_cleanly("failed to unlock socket");
+ }
+}
+
/* Accessor function for smb_read_error for smbd functions. */
/****************************************************************************
@@ -95,12 +121,8 @@ bool srv_send_smb(int fd, char *buffer,
size_t nwritten=0;
ssize_t ret;
char *buf_out = buffer;
- bool ok;
- ok = smbd_lock_socket(smbd_server_conn);
- if (!ok) {
- exit_server_cleanly("failed to lock socket");
- }
+ smbd_lock_socket(smbd_server_conn);
if (do_signing) {
/* Sign the outgoing packet if required. */
@@ -132,11 +154,7 @@ bool srv_send_smb(int fd, char *buffer,
out:
SMB_PERFCOUNT_END(pcd);
- ok = smbd_unlock_socket(smbd_server_conn);
- if (!ok) {
- exit_server_cleanly("failed to unlock socket");
- }
-
+ smbd_unlock_socket(smbd_server_conn);
return true;
}
@@ -2174,22 +2192,14 @@ static void smbd_server_connection_read_handler(
NTSTATUS status;
uint32_t seqnum;
- bool ok;
-
bool from_client = (smbd_server_fd() == fd)?true:false;
if (from_client) {
- ok = smbd_lock_socket(conn);
- if (!ok) {
- exit_server_cleanly("failed to lock socket");
- }
+ smbd_lock_socket(conn);
if (!fd_is_readable(smbd_server_fd())) {
DEBUG(10,("the echo listener was faster\n"));
- ok = smbd_unlock_socket(conn);
- if (!ok) {
- exit_server_cleanly("failed to unlock");
- }
+ smbd_unlock_socket(conn);
return;
}
@@ -2201,10 +2211,7 @@ static void smbd_server_connection_read_handler(
&encrypted,
&inbuf_len, &seqnum,
false /* trusted channel */);
- ok = smbd_unlock_socket(conn);
- if (!ok) {
- exit_server_cleanly("failed to unlock");
- }
+ smbd_unlock_socket(conn);
} else {
/* TODO: make this completely nonblocking */
status = receive_smb_talloc(mem_ctx, fd,
@@ -2321,20 +2328,11 @@ static int client_get_tcp_info(struct sockaddr_storage *server,
*/
static bool keepalive_fn(const struct timeval *now, void *private_data)
{
- bool ok;
bool ret;
- ok = smbd_lock_socket(smbd_server_conn);
- if (!ok) {
- exit_server_cleanly("failed to lock socket");
- }
-
+ smbd_lock_socket(smbd_server_conn);
ret = send_keepalive(smbd_server_fd());
-
- ok = smbd_unlock_socket(smbd_server_conn);
- if (!ok) {
- exit_server_cleanly("failed to unlock socket");
- }
+ smbd_unlock_socket(smbd_server_conn);
if (!ret) {
DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
@@ -2574,7 +2572,7 @@ static void smbd_echo_reader(struct tevent_context *ev,
bool ok;
bool encrypted = false;
- ok = smbd_lock_socket(sconn);
+ ok = smbd_lock_socket_internal(sconn);
if (!ok) {
DEBUG(0, ("%s: failed to lock socket\n",
__location__));
@@ -2584,7 +2582,7 @@ static void smbd_echo_reader(struct tevent_context *ev,
if (!fd_is_readable(smbd_server_fd())) {
DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
(int)sys_getpid()));
- ok = smbd_unlock_socket(sconn);
+ ok = smbd_unlock_socket_internal(sconn);
if (!ok) {
DEBUG(1, ("%s: failed to unlock socket in\n",
__location__));
@@ -2618,7 +2616,7 @@ static void smbd_echo_reader(struct tevent_context *ev,
exit(1);
}
- ok = smbd_unlock_socket(sconn);
+ ok = smbd_unlock_socket_internal(sconn);
if (!ok) {
DEBUG(1, ("%s: failed to unlock socket in\n",
__location__));