diff options
Diffstat (limited to 'source3/smbd/nttrans.c')
-rw-r--r-- | source3/smbd/nttrans.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 07d345aacd..6db6311a29 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1787,6 +1787,13 @@ int reply_ntrename(connection_struct *conn, don't allow a directory to be opened. ****************************************************************************/ +static void notify_callback(void *private_data, const struct notify_event *e) +{ + files_struct *fsp = (files_struct *)private_data; + DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name)); + notify_fsp(fsp, e->action, e->path); +} + static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, @@ -1801,6 +1808,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, files_struct *fsp; uint32 filter; NTSTATUS status; + BOOL recursive; if(setup_count < 6) { return ERROR_DOS(ERRDOS,ERRbadfunc); @@ -1808,6 +1816,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, fsp = file_fsp((char *)setup,4); filter = IVAL(setup, 0); + recursive = (SVAL(setup, 6) != 0) ? True : False; DEBUG(3,("call_nt_transact_notify_change\n")); @@ -1815,18 +1824,55 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, return ERROR_DOS(ERRDOS,ERRbadfid); } - DEBUG(3,("call_nt_transact_notify_change: notify change called on " - "directory name = %s\n", fsp->fsp_name )); + { + char *filter_string; + + if (!(filter_string = notify_filter_string(NULL, filter))) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + DEBUG(3,("call_nt_transact_notify_change: notify change " + "called on %s, filter = %s, recursive = %d\n", + fsp->fsp_name, filter_string, recursive)); + + TALLOC_FREE(filter_string); + } if((!fsp->is_directory) || (conn != fsp->conn)) { return ERROR_DOS(ERRDOS,ERRbadfid); } if (fsp->notify == NULL) { + char *fullpath; + struct notify_entry e; + if (!(fsp->notify = TALLOC_ZERO_P( NULL, struct notify_change_buf))) { return ERROR_NT(NT_STATUS_NO_MEMORY); } + + if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath, + fsp->fsp_name) == -1) { + DEBUG(0, ("asprintf failed\n")); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + e.path = fullpath; + e.filter = filter; + e.subdir_filter = 0; + if (recursive) { + e.subdir_filter = filter; + } + + status = notify_add(fsp->conn->notify_ctx, &e, notify_callback, + fsp); + SAFE_FREE(fullpath); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("notify_add returned %s\n", + nt_errstr(status))); + return ERROR_NT(status); + } } if (fsp->notify->num_changes != 0) { @@ -1840,8 +1886,6 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, * here. */ - SMB_ASSERT(fsp->notify->requests == NULL); - change_notify_reply(inbuf, max_param_count, fsp->notify->num_changes, fsp->notify->changes); @@ -1861,7 +1905,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, */ status = change_notify_add_request(inbuf, max_param_count, filter, - fsp); + recursive, fsp); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } |