Line data Source code
1 : /* 2 : Unix SMB/CIFS implementation. 3 : client change notify operations 4 : Copyright (C) Andrew Tridgell 2003 5 : 6 : This program is free software; you can redistribute it and/or modify 7 : it under the terms of the GNU General Public License as published by 8 : the Free Software Foundation; either version 3 of the License, or 9 : (at your option) any later version. 10 : 11 : This program is distributed in the hope that it will be useful, 12 : but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : GNU General Public License for more details. 15 : 16 : You should have received a copy of the GNU General Public License 17 : along with this program. If not, see <http://www.gnu.org/licenses/>. 18 : */ 19 : 20 : #include "includes.h" 21 : #include <tevent.h> 22 : #include "libcli/raw/libcliraw.h" 23 : #include "libcli/raw/raw_proto.h" 24 : 25 : /**************************************************************************** 26 : change notify (async send) 27 : ****************************************************************************/ 28 1617 : _PUBLIC_ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) 29 : { 30 0 : struct smb_nttrans nt; 31 0 : uint8_t setup[8]; 32 : 33 1617 : if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { 34 0 : return NULL; 35 : } 36 : 37 1617 : nt.in.max_setup = 0; 38 1617 : nt.in.max_param = parms->nttrans.in.buffer_size; 39 1617 : nt.in.max_data = 0; 40 1617 : nt.in.setup_count = 4; 41 1617 : nt.in.setup = setup; 42 1617 : SIVAL(setup, 0, parms->nttrans.in.completion_filter); 43 1617 : SSVAL(setup, 4, parms->nttrans.in.file.fnum); 44 1617 : SSVAL(setup, 6, parms->nttrans.in.recursive); 45 1617 : nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; 46 1617 : nt.in.params = data_blob(NULL, 0); 47 1617 : nt.in.data = data_blob(NULL, 0); 48 : 49 1617 : return smb_raw_nttrans_send(tree, &nt); 50 : } 51 : 52 : /**************************************************************************** 53 : change notify (async recv) 54 : ****************************************************************************/ 55 1617 : _PUBLIC_ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, 56 : TALLOC_CTX *mem_ctx, union smb_notify *parms) 57 : { 58 0 : struct smb_nttrans nt; 59 0 : NTSTATUS status; 60 0 : uint32_t ofs, i; 61 1617 : struct smbcli_session *session = req?req->session:NULL; 62 : 63 1617 : if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { 64 0 : return NT_STATUS_INVALID_LEVEL; 65 : } 66 : 67 1617 : status = smb_raw_nttrans_recv(req, mem_ctx, &nt); 68 1617 : if (!NT_STATUS_IS_OK(status)) { 69 1430 : return status; 70 : } 71 : 72 187 : parms->nttrans.out.changes = NULL; 73 187 : parms->nttrans.out.num_changes = 0; 74 : 75 : /* count them */ 76 910 : for (ofs=0; nt.out.params.length - ofs > 12; ) { 77 895 : uint32_t next = IVAL(nt.out.params.data, ofs); 78 895 : if (next % 4 != 0) 79 0 : return NT_STATUS_INVALID_NETWORK_RESPONSE; 80 895 : parms->nttrans.out.num_changes++; 81 895 : if (next == 0 || 82 723 : ofs + next >= nt.out.params.length) break; 83 723 : ofs += next; 84 : } 85 : 86 : /* allocate array */ 87 187 : parms->nttrans.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->nttrans.out.num_changes); 88 187 : if (!parms->nttrans.out.changes) { 89 0 : return NT_STATUS_NO_MEMORY; 90 : } 91 : 92 1082 : for (i=ofs=0; i<parms->nttrans.out.num_changes; i++) { 93 895 : parms->nttrans.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); 94 895 : smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, 95 895 : &parms->nttrans.out.changes[i].name, 96 895 : ofs+8, ofs+12, STR_UNICODE); 97 895 : ofs += IVAL(nt.out.params.data, ofs); 98 : } 99 : 100 187 : return NT_STATUS_OK; 101 : } 102 : 103 : /**************************************************************************** 104 : Send a NT Cancel request - used to hurry along a pending request. Usually 105 : used to cancel a pending change notify request 106 : note that this request does not expect a response! 107 : ****************************************************************************/ 108 1517 : NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq) 109 : { 110 0 : bool ok; 111 : 112 1517 : if (oldreq->subreqs[0] == NULL) { 113 4 : return NT_STATUS_OK; 114 : } 115 : 116 1513 : ok = tevent_req_cancel(oldreq->subreqs[0]); 117 1513 : if (!ok) { 118 0 : return NT_STATUS_INTERNAL_ERROR; 119 : } 120 : 121 1513 : return NT_STATUS_OK; 122 : }