diff options
author | Stefan Metzmacher <metze@samba.org> | 2006-07-12 14:25:50 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:10:06 -0500 |
commit | a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f (patch) | |
tree | 617c2420c90d475b05bb3b3894feb2914fbed393 /source4/libcli | |
parent | e6b29409a29bdf99c45b2c0aefecb321904f2fd3 (diff) | |
download | samba-a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f.tar.gz samba-a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f.tar.bz2 samba-a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f.zip |
r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY_SMB2
- parse SMB2 Notify reponse
metze
(This used to be commit de50e0ccddfad16ad7b254770f4c52c1abe707b9)
Diffstat (limited to 'source4/libcli')
-rw-r--r-- | source4/libcli/raw/interfaces.h | 65 | ||||
-rw-r--r-- | source4/libcli/raw/rawnotify.c | 38 | ||||
-rw-r--r-- | source4/libcli/smb2/notify.c | 31 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2_calls.h | 22 |
4 files changed, 103 insertions, 53 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 8ebdd38bee..d3e7611c75 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2128,23 +2128,60 @@ struct smb_nttrans { } out; }; +enum smb_notify_level { + RAW_NOTIFY_NTTRANS, + RAW_NOTIFY_SMB2 +}; -/* struct for nttrans change notify call */ -struct smb_notify { +union smb_notify { + /* struct for nttrans change notify call */ struct { - union smb_handle file; - uint32_t buffer_size; - uint32_t completion_filter; - BOOL recursive; - } in; + enum smb_notify_level level; - struct { - uint32_t num_changes; - struct notify_changes { - uint32_t action; - struct smb_wire_string name; - } *changes; - } out; + struct { + union smb_handle file; + uint32_t buffer_size; + uint32_t completion_filter; + BOOL recursive; + } in; + + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + struct smb_wire_string name; + } *changes; + } out; + } nttrans; + + struct smb2_notify { + enum smb_notify_level level; + + struct { + union smb_handle file; + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x32 */ + uint16_t recursive; + uint32_t buffer_size; + /*struct smb2_handle file;*/ + uint32_t completion_filter; + uint32_t unknown; + } in; + + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + /* uint16_t blob_ofs; */ + /* uint16_t blob_size; */ + + /* dynamic body */ + /*DATA_BLOB blob;*/ + + /* DATA_BLOB content */ + uint32_t num_changes; + struct notify_changes *changes; + } out; + } smb2; }; enum smb_search_level { diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index f4d4164016..2b68d96a1b 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -25,19 +25,23 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NULL; + } + nt.in.max_setup = 0; - nt.in.max_param = parms->in.buffer_size; + nt.in.max_param = parms->nttrans.in.buffer_size; nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->in.completion_filter); - SSVAL(setup, 4, parms->in.file.fnum); - SSVAL(setup, 6, parms->in.recursive); + SIVAL(setup, 0, parms->nttrans.in.completion_filter); + SSVAL(setup, 4, parms->nttrans.in.file.fnum); + SSVAL(setup, 6, parms->nttrans.in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -49,41 +53,45 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struc change notify (async recv) ****************************************************************************/ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, struct smb_notify *parms) + TALLOC_CTX *mem_ctx, union smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; uint32_t ofs, i; struct smbcli_session *session = req?req->session:NULL; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_INVALID_LEVEL; + } + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { return status; } - parms->out.changes = NULL; - parms->out.num_changes = 0; + parms->nttrans.out.changes = NULL; + parms->nttrans.out.num_changes = 0; /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { uint32_t next = IVAL(nt.out.params.data, ofs); - parms->out.num_changes++; + parms->nttrans.out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; ofs += next; } /* allocate array */ - parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); - if (!parms->out.changes) { + parms->nttrans.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->nttrans.out.num_changes); + if (!parms->nttrans.out.changes) { return NT_STATUS_NO_MEMORY; } - for (i=ofs=0; i<parms->out.num_changes; i++) { - parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + for (i=ofs=0; i<parms->nttrans.out.num_changes; i++) { + parms->nttrans.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, - &parms->out.changes[i].name, - ofs+8, ofs+12, STR_UNICODE); + &parms->nttrans.out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); } diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 0e61293495..43792267f2 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -56,19 +56,46 @@ NTSTATUS smb2_notify_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_notify *io) { NTSTATUS status; + DATA_BLOB blob; + uint32_t ofs, i; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } SMB2_CHECK_PACKET_RECV(req, 0x08, True); - status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &blob); if (!NT_STATUS_IS_OK(status)) { return status; } + io->out.changes = NULL; + io->out.num_changes = 0; + + /* count them */ + for (ofs=0; blob.length - ofs > 12; ) { + uint32_t next = IVAL(blob.data, ofs); + io->out.num_changes++; + if (next == 0 || (ofs + next) >= blob.length) break; + ofs += next; + } + + /* allocate array */ + io->out.changes = talloc_array(mem_ctx, struct notify_changes, io->out.num_changes); + if (!io->out.changes) { + return NT_STATUS_NO_MEMORY; + } + + for (i=ofs=0; i<io->out.num_changes; i++) { + io->out.changes[i].action = IVAL(blob.data, ofs+4); + smbcli_blob_pull_string(NULL, mem_ctx, &blob, + &io->out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); + ofs += IVAL(blob.data, ofs); + } + return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index c3dc629430..abb7f88ee2 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -94,28 +94,6 @@ struct smb2_setinfo { } in; }; -struct smb2_notify { - struct { - /* static body buffer 32 (0x20) bytes */ - /* uint16_t buffer_code; 0x32 */ - uint16_t recursive; - uint32_t buffer_size; - union smb_handle file; - uint32_t completion_filter; - uint32_t unknown; - } in; - - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ - /* uint16_t blob_ofs; */ - /* uint16_t blob_size; */ - - /* dynamic body */ - DATA_BLOB blob; - } out; -}; - struct cli_credentials; struct event_context; #include "libcli/smb2/smb2_proto.h" |