From: Volker Lendecke Date: Tue, 30 Jul 2019 12:54:18 +0000 (+0200) Subject: smbd: Add defer_sharing_violation_smb1 X-Git-Tag: tdb-1.4.2~245 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c7e110e51afea9a36a060bff62506c53e86c8aab;p=thirdparty%2Fsamba.git smbd: Add defer_sharing_violation_smb1 This is close to what Windows SMB1 does: Instead of waiting for the share entry causing the SHARING_VIOLATION to disappear, retry every 200msec up to one second. Windows does it a little differently: Retry up to 5 times. But up to one second should be close enough. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index b8b7ed025cc..f54c8cf6313 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2567,6 +2567,36 @@ static bool setup_poll_open( return true; } +bool defer_smb1_sharing_violation(struct smb_request *req) +{ + bool ok; + int timeout_usecs; + + if (!lp_defer_sharing_violations()) { + return false; + } + + /* + * Try every 200msec up to (by default) one second. To be + * precise, according to behaviour note <247> in [MS-CIFS], + * the server tries 5 times. But up to one second should be + * close enough. + */ + + timeout_usecs = lp_parm_int( + SNUM(req->conn), + "smbd", + "sharedelay", + SHARING_VIOLATION_USEC_WAIT); + + ok = setup_poll_open( + req, + (struct file_id) {0}, + (struct timeval) { .tv_usec = timeout_usecs }, + (struct timeval) { .tv_usec = 200000 }); + return ok; +} + /**************************************************************************** On overwrite open ensure that the attributes match. ****************************************************************************/ diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 6d3a10f9d75..0fde9b78fb0 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -680,6 +680,7 @@ NTSTATUS send_break_message(struct messaging_context *msg_ctx, uint16_t break_to); struct deferred_open_record; bool is_deferred_open_async(const struct deferred_open_record *rec); +bool defer_smb1_sharing_violation(struct smb_request *req); NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, struct smb_filename *smb_dname); void msg_file_was_renamed(struct messaging_context *msg,