From: Ralph Boehme Date: Tue, 7 Mar 2017 14:33:55 +0000 (+0100) Subject: s3/smbd: fix schedule_async_open() timer X-Git-Tag: samba-4.4.11~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e94b38e14ea8090f904cc2d270ebdbb2f583e16;p=thirdparty%2Fsamba.git s3/smbd: fix schedule_async_open() timer schedule_async_open() was calling defer_open with sharemode lock = NULL, as a result there was never an active 20 s timeout. This has been broken since the commits in $ git log --reverse -p -10 8283fd0e0090ed12b0b12d5acb550642d621b026 Just roll our own deferred record instead of calling defer_open() and also set up timer that, as a last resort, catches stuck opens and just exits for now. Bug: https://bugzilla.samba.org/show_bug.cgi?id=7537 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit ad8c36125f72e0d5f9ebfc94037a4ae9e7608aad) --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 9ffae48963d..e76395d54e3 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -44,6 +44,13 @@ struct deferred_open_record { bool delayed_for_oplocks; bool async_open; struct file_id id; + + /* + * Timer for async opens, needed because they don't use a watch on + * a locking.tdb record. This is currently only used for real async + * opens and just terminates smbd if the async open times out. + */ + struct tevent_timer *te; }; /**************************************************************************** @@ -2216,19 +2223,44 @@ static void schedule_defer_open(struct share_mode_lock *lck, Reschedule an open call that went asynchronous. ****************************************************************************/ +static void schedule_async_open_timer(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + exit_server("async open timeout"); +} + static void schedule_async_open(struct timeval request_time, struct smb_request *req) { - struct timeval timeout; - - timeout = timeval_set(20, 0); + struct deferred_open_record *open_rec = NULL; + struct timeval timeout = timeval_set(20, 0); + bool ok; if (request_timed_out(request_time, timeout)) { return; } - defer_open(NULL, request_time, timeout, req, - false, true, (struct file_id){0}); + open_rec = deferred_open_record_create(false, true, (struct file_id){0}); + if (open_rec == NULL) { + exit_server("deferred_open_record_create failed"); + } + + ok = push_deferred_open_message_smb(req, request_time, timeout, + (struct file_id){0}, open_rec); + if (!ok) { + exit_server("push_deferred_open_message_smb failed"); + } + + open_rec->te = tevent_add_timer(req->sconn->ev_ctx, + req, + timeval_current_ofs(20, 0), + schedule_async_open_timer, + open_rec); + if (open_rec->te == NULL) { + exit_server("tevent_add_timer failed"); + } } /****************************************************************************