summaryrefslogtreecommitdiff
path: root/source3/smbd/nttrans.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/nttrans.c')
-rw-r--r--source3/smbd/nttrans.c54
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);
}