From d6b158d2189bc62de530bb06ee85430161a53356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 7 Jul 2010 01:50:18 +0200 Subject: [PATCH 1/2] s3-notify: add MS-CIFS 2.2.7.4.2 FILE_NOTIFY_INFORMATION to IDL. Guenther --- source3/librpc/idl/notify.idl | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/source3/librpc/idl/notify.idl b/source3/librpc/idl/notify.idl index 0e80679..040f661 100644 --- a/source3/librpc/idl/notify.idl +++ b/source3/librpc/idl/notify.idl @@ -60,4 +60,23 @@ interface notify pointer private_data; } notify_event; + typedef [v1_enum] enum { + FILE_ACTION_ADDED = 0x00000001, + FILE_ACTION_REMOVED = 0x00000002, + FILE_ACTION_MODIFIED = 0x00000003, + FILE_ACTION_RENAMED_OLD_NAME = 0x00000004, + FILE_ACTION_RENAMED_NEW_NAME = 0x00000005, + FILE_ACTION_ADDED_STREAM = 0x00000006, + FILE_ACTION_REMOVED_STREAM = 0x00000007, + FILE_ACTION_MODIFIED_STREAM = 0x00000008 + } FILE_NOTIFY_ACTION; + + /* structure sent at the CIFS layer */ + /* Align on 4-byte boundary according to MS-CIFS 2.2.7.4.2 */ + typedef [public,gensize,flag(NDR_ALIGN4)] struct { + uint32 NextEntryOffset; + FILE_NOTIFY_ACTION Action; + [value(strlen_m(FileName1)*2)] uint32 FileNameLength; + [charset(UTF16),flag(STR_NOTERM)] uint16 FileName1[FileNameLength]; + } FILE_NOTIFY_INFORMATION; } -- 1.6.6.1 From 0bcd0c62c5de449bd2eecd00f123e68dfe3a580d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 7 Jul 2010 01:50:56 +0200 Subject: [PATCH 2/2] s3-notify: use autogenerated FILE_NOTIFY_INFORMATION marshalling in smbd. Guenther --- source3/smbd/notify.c | 82 +++++++++++++++++------------------------------- 1 files changed, 29 insertions(+), 53 deletions(-) diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index e473d99..809c5a0 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -21,7 +21,7 @@ #include "includes.h" #include "smbd/globals.h" -#include "../librpc/gen_ndr/notify.h" +#include "../librpc/gen_ndr/ndr_notify.h" struct notify_change_request { struct notify_change_request *prev, *next; @@ -63,23 +63,19 @@ static bool notify_change_record_identical(struct notify_change *c1, static bool notify_marshall_changes(int num_changes, uint32 max_offset, struct notify_change *changes, - prs_struct *ps) + DATA_BLOB *final_blob) { int i; - UNISTR uni_name; if (num_changes == -1) { return false; } - uni_name.buffer = NULL; - for (i=0; iname, strlen(c->name)+1, &uni_name.buffer, - &namelen, True) || (uni_name.buffer == NULL)) { - goto fail; - } - - namelen -= 2; /* Dump NULL termination */ + m.FileName1 = c->name; + m.FileNameLength = strlen_m(c->name)*2; + m.Action = c->action; + m.NextEntryOffset = (i == num_changes-1) ? 0 : ndr_size_FILE_NOTIFY_INFORMATION(&m, 0); /* * Offset to next entry, only if there is one */ - u32_tmp = (i == num_changes-1) ? 0 : namelen + 12; - - /* Align on 4-byte boundary according to MS-CIFS 2.2.7.4.2 */ - if ((rem = u32_tmp % 4 ) != 0) - u32_tmp += 4 - rem; - - if (!prs_uint32("offset", ps, 1, &u32_tmp)) goto fail; - - u32_tmp = c->action; - if (!prs_uint32("action", ps, 1, &u32_tmp)) goto fail; - - u32_tmp = namelen; - if (!prs_uint32("namelen", ps, 1, &u32_tmp)) goto fail; - - if (!prs_unistr("name", ps, 1, &uni_name)) goto fail; - - /* - * Not NULL terminated, decrease by the 2 UCS2 \0 chars - */ - prs_set_offset(ps, prs_offset(ps)-2); + ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &m, + (ndr_push_flags_fn_t)ndr_push_FILE_NOTIFY_INFORMATION); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } - if (rem != 0) { - if (!prs_align_custom(ps, 4)) goto fail; + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(FILE_NOTIFY_INFORMATION, &m); } - TALLOC_FREE(uni_name.buffer); + if (!data_blob_append(talloc_tos(), final_blob, + blob.data, blob.length)) { + data_blob_free(&blob); + return false; + } - if (prs_offset(ps) > max_offset) { + if (final_blob->length > max_offset) { /* Too much data for client. */ DEBUG(10, ("Client only wanted %d bytes, trying to " "marshall %d bytes\n", (int)max_offset, - (int)prs_offset(ps))); + (int)final_blob->length)); + data_blob_free(&blob); return False; } } return True; - - fail: - TALLOC_FREE(uni_name.buffer); - return False; } /**************************************************************************** @@ -157,7 +136,7 @@ void change_notify_reply(struct smb_request *req, NTSTATUS error_code, uint8_t *buf, size_t len)) { - prs_struct ps; + DATA_BLOB blob = data_blob_null; if (!NT_STATUS_IS_OK(error_code)) { reply_fn(req, error_code, NULL, 0); @@ -169,21 +148,18 @@ void change_notify_reply(struct smb_request *req, return; } - prs_init_empty(&ps, NULL, MARSHALL); - if (!notify_marshall_changes(notify_buf->num_changes, max_param, - notify_buf->changes, &ps)) { + notify_buf->changes, &blob)) { /* * We exceed what the client is willing to accept. Send * nothing. */ - prs_mem_free(&ps); - prs_init_empty(&ps, NULL, MARSHALL); + data_blob_free(&blob); } - reply_fn(req, NT_STATUS_OK, (uint8_t *)prs_data_p(&ps), prs_offset(&ps)); + reply_fn(req, NT_STATUS_OK, blob.data, blob.length); - prs_mem_free(&ps); + data_blob_free(&blob); TALLOC_FREE(notify_buf->changes); notify_buf->num_changes = 0; -- 1.6.6.1