source: trunk/server/source4/libcli/raw/rawnotify.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 5.5 KB
Line 
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 "libcli/raw/libcliraw.h"
22#include "libcli/raw/raw_proto.h"
23#include "../lib/util/dlinklist.h"
24
25/****************************************************************************
26change notify (async send)
27****************************************************************************/
28_PUBLIC_ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms)
29{
30 struct smb_nttrans nt;
31 uint8_t setup[8];
32
33 if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) {
34 return NULL;
35 }
36
37 nt.in.max_setup = 0;
38 nt.in.max_param = parms->nttrans.in.buffer_size;
39 nt.in.max_data = 0;
40 nt.in.setup_count = 4;
41 nt.in.setup = setup;
42 SIVAL(setup, 0, parms->nttrans.in.completion_filter);
43 SSVAL(setup, 4, parms->nttrans.in.file.fnum);
44 SSVAL(setup, 6, parms->nttrans.in.recursive);
45 nt.in.function = NT_TRANSACT_NOTIFY_CHANGE;
46 nt.in.params = data_blob(NULL, 0);
47 nt.in.data = data_blob(NULL, 0);
48
49 return smb_raw_nttrans_send(tree, &nt);
50}
51
52/****************************************************************************
53change notify (async recv)
54****************************************************************************/
55_PUBLIC_ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req,
56 TALLOC_CTX *mem_ctx, union smb_notify *parms)
57{
58 struct smb_nttrans nt;
59 NTSTATUS status;
60 uint32_t ofs, i;
61 struct smbcli_session *session = req?req->session:NULL;
62
63 if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) {
64 return NT_STATUS_INVALID_LEVEL;
65 }
66
67 status = smb_raw_nttrans_recv(req, mem_ctx, &nt);
68 if (!NT_STATUS_IS_OK(status)) {
69 return status;
70 }
71
72 parms->nttrans.out.changes = NULL;
73 parms->nttrans.out.num_changes = 0;
74
75 /* count them */
76 for (ofs=0; nt.out.params.length - ofs > 12; ) {
77 uint32_t next = IVAL(nt.out.params.data, ofs);
78 if (next % 4 != 0)
79 return NT_STATUS_INVALID_NETWORK_RESPONSE;
80 parms->nttrans.out.num_changes++;
81 if (next == 0 ||
82 ofs + next >= nt.out.params.length) break;
83 ofs += next;
84 }
85
86 /* allocate array */
87 parms->nttrans.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->nttrans.out.num_changes);
88 if (!parms->nttrans.out.changes) {
89 return NT_STATUS_NO_MEMORY;
90 }
91
92 for (i=ofs=0; i<parms->nttrans.out.num_changes; i++) {
93 parms->nttrans.out.changes[i].action = IVAL(nt.out.params.data, ofs+4);
94 smbcli_blob_pull_string(session, mem_ctx, &nt.out.params,
95 &parms->nttrans.out.changes[i].name,
96 ofs+8, ofs+12, STR_UNICODE);
97 ofs += IVAL(nt.out.params.data, ofs);
98 }
99
100 return NT_STATUS_OK;
101}
102
103/****************************************************************************
104 handle ntcancel replies from the server,
105 as the MID of the real reply and the ntcancel reply is the same
106 we need to do find out to what request the reply belongs
107****************************************************************************/
108struct smbcli_request *smbcli_handle_ntcancel_reply(struct smbcli_request *req,
109 size_t len, const uint8_t *hdr)
110{
111 struct smbcli_request *ntcancel;
112
113 if (!req) return req;
114
115 if (!req->ntcancel) return req;
116
117 if (len >= MIN_SMB_SIZE + NBT_HDR_SIZE &&
118 (CVAL(hdr, HDR_FLG) & FLAG_REPLY) &&
119 CVAL(hdr,HDR_COM) == SMBntcancel) {
120 ntcancel = req->ntcancel;
121 DLIST_REMOVE(req->ntcancel, ntcancel);
122
123 /*
124 * TODO: untill we understand how the
125 * smb_signing works for this case we
126 * return NULL, to just ignore the packet
127 */
128 /*return ntcancel;*/
129 return NULL;
130 }
131
132 return req;
133}
134
135/****************************************************************************
136 Send a NT Cancel request - used to hurry along a pending request. Usually
137 used to cancel a pending change notify request
138 note that this request does not expect a response!
139****************************************************************************/
140NTSTATUS smb_raw_ntcancel(struct smbcli_request *oldreq)
141{
142 struct smbcli_request *req;
143
144 req = smbcli_request_setup_transport(oldreq->transport, SMBntcancel, 0, 0);
145
146 SSVAL(req->out.hdr, HDR_MID, SVAL(oldreq->out.hdr, HDR_MID));
147 SSVAL(req->out.hdr, HDR_PID, SVAL(oldreq->out.hdr, HDR_PID));
148 SSVAL(req->out.hdr, HDR_TID, SVAL(oldreq->out.hdr, HDR_TID));
149 SSVAL(req->out.hdr, HDR_UID, SVAL(oldreq->out.hdr, HDR_UID));
150
151 /* this request does not expect a reply, so tell the signing
152 subsystem not to allocate an id for a reply */
153 req->sign_single_increment = 1;
154 req->one_way_request = 1;
155
156 /*
157 * smbcli_request_send() free's oneway requests
158 * but we want to keep it under oldreq->ntcancel
159 */
160 req->do_not_free = true;
161 talloc_steal(oldreq, req);
162
163 smbcli_request_send(req);
164
165 DLIST_ADD_END(oldreq->ntcancel, req, struct smbcli_request *);
166
167 return NT_STATUS_OK;
168}
Note: See TracBrowser for help on using the repository browser.