Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Core SMB2 server
4 :
5 : Copyright (C) Stefan Metzmacher 2009
6 : Copyright (C) Jeremy Allison 2010
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "locking/share_mode_lock.h"
24 : #include "smbd/smbd.h"
25 : #include "smbd/globals.h"
26 : #include "../libcli/smb/smb_common.h"
27 : #include "trans2.h"
28 : #include "../lib/util/tevent_ntstatus.h"
29 : #include "../librpc/gen_ndr/open_files.h"
30 : #include "source3/lib/dbwrap/dbwrap_watch.h"
31 : #include "messages.h"
32 : #include "librpc/gen_ndr/ndr_quota.h"
33 :
34 : #undef DBGC_CLASS
35 : #define DBGC_CLASS DBGC_SMB2
36 :
37 : static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
38 : struct tevent_context *ev,
39 : struct smbd_smb2_request *smb2req,
40 : struct files_struct *in_fsp,
41 : uint8_t in_info_type,
42 : uint8_t in_file_info_class,
43 : DATA_BLOB in_input_buffer,
44 : uint32_t in_additional_information);
45 : static NTSTATUS smbd_smb2_setinfo_recv(struct tevent_req *req);
46 :
47 : static void smbd_smb2_request_setinfo_done(struct tevent_req *subreq);
48 13250 : NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
49 : {
50 13250 : struct smbXsrv_connection *xconn = req->xconn;
51 2 : NTSTATUS status;
52 2 : const uint8_t *inbody;
53 2 : uint8_t in_info_type;
54 2 : uint8_t in_file_info_class;
55 2 : uint16_t in_input_buffer_offset;
56 2 : uint32_t in_input_buffer_length;
57 2 : DATA_BLOB in_input_buffer;
58 2 : uint32_t in_additional_information;
59 2 : uint64_t in_file_id_persistent;
60 2 : uint64_t in_file_id_volatile;
61 2 : struct files_struct *in_fsp;
62 2 : struct tevent_req *subreq;
63 :
64 13250 : status = smbd_smb2_request_verify_sizes(req, 0x21);
65 13250 : if (!NT_STATUS_IS_OK(status)) {
66 0 : return smbd_smb2_request_error(req, status);
67 : }
68 13250 : inbody = SMBD_SMB2_IN_BODY_PTR(req);
69 :
70 13250 : in_info_type = CVAL(inbody, 0x02);
71 13250 : in_file_info_class = CVAL(inbody, 0x03);
72 13250 : in_input_buffer_length = IVAL(inbody, 0x04);
73 13250 : in_input_buffer_offset = SVAL(inbody, 0x08);
74 : /* 0x0A 2 bytes reserved */
75 13250 : in_additional_information = IVAL(inbody, 0x0C);
76 13250 : in_file_id_persistent = BVAL(inbody, 0x10);
77 13250 : in_file_id_volatile = BVAL(inbody, 0x18);
78 :
79 13250 : if (in_input_buffer_offset == 0 && in_input_buffer_length == 0) {
80 : /* This is ok */
81 13250 : } else if (in_input_buffer_offset !=
82 13250 : (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(req))) {
83 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
84 : }
85 :
86 13250 : if (in_input_buffer_length > SMBD_SMB2_IN_DYN_LEN(req)) {
87 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
88 : }
89 :
90 13250 : in_input_buffer.data = SMBD_SMB2_IN_DYN_PTR(req);
91 13250 : in_input_buffer.length = in_input_buffer_length;
92 :
93 13250 : if (in_input_buffer.length > xconn->smb2.server.max_trans) {
94 0 : DEBUG(2,("smbd_smb2_request_process_setinfo: "
95 : "client ignored max trans: %s: 0x%08X: 0x%08X\n",
96 : __location__, (unsigned)in_input_buffer.length,
97 : (unsigned)xconn->smb2.server.max_trans));
98 0 : return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
99 : }
100 :
101 13250 : status = smbd_smb2_request_verify_creditcharge(req,
102 13248 : in_input_buffer.length);
103 13250 : if (!NT_STATUS_IS_OK(status)) {
104 0 : return smbd_smb2_request_error(req, status);
105 : }
106 :
107 13250 : in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile);
108 13250 : if (in_fsp == NULL) {
109 0 : return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
110 : }
111 :
112 13250 : subreq = smbd_smb2_setinfo_send(req, req->sconn->ev_ctx,
113 : req, in_fsp,
114 : in_info_type,
115 : in_file_info_class,
116 : in_input_buffer,
117 : in_additional_information);
118 13250 : if (subreq == NULL) {
119 0 : return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
120 : }
121 13250 : tevent_req_set_callback(subreq, smbd_smb2_request_setinfo_done, req);
122 :
123 13250 : return smbd_smb2_request_pending_queue(req, subreq, 500);
124 : }
125 :
126 13250 : static void smbd_smb2_request_setinfo_done(struct tevent_req *subreq)
127 : {
128 13250 : struct smbd_smb2_request *req = tevent_req_callback_data(subreq,
129 : struct smbd_smb2_request);
130 2 : DATA_BLOB outbody;
131 2 : NTSTATUS status;
132 2 : NTSTATUS error; /* transport error */
133 :
134 13250 : status = smbd_smb2_setinfo_recv(subreq);
135 13250 : TALLOC_FREE(subreq);
136 13250 : if (!NT_STATUS_IS_OK(status)) {
137 276 : error = smbd_smb2_request_error(req, status);
138 276 : if (!NT_STATUS_IS_OK(error)) {
139 0 : smbd_server_connection_terminate(req->xconn,
140 : nt_errstr(error));
141 276 : return;
142 : }
143 276 : return;
144 : }
145 :
146 12974 : outbody = smbd_smb2_generate_outbody(req, 0x02);
147 12974 : if (outbody.data == NULL) {
148 0 : error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
149 0 : if (!NT_STATUS_IS_OK(error)) {
150 0 : smbd_server_connection_terminate(req->xconn,
151 : nt_errstr(error));
152 0 : return;
153 : }
154 0 : return;
155 : }
156 :
157 12974 : SSVAL(outbody.data, 0x00, 0x02); /* struct size */
158 :
159 12974 : error = smbd_smb2_request_done(req, outbody, NULL);
160 12974 : if (!NT_STATUS_IS_OK(error)) {
161 0 : smbd_server_connection_terminate(req->xconn,
162 : nt_errstr(error));
163 0 : return;
164 : }
165 : }
166 :
167 : struct defer_rename_state {
168 : struct tevent_req *req;
169 : struct smbd_smb2_request *smb2req;
170 : struct tevent_context *ev;
171 : struct files_struct *fsp;
172 : char *data;
173 : int data_size;
174 : };
175 :
176 4 : static int defer_rename_state_destructor(struct defer_rename_state *rename_state)
177 : {
178 4 : SAFE_FREE(rename_state->data);
179 4 : return 0;
180 : }
181 :
182 : static void defer_rename_done(struct tevent_req *subreq);
183 :
184 : struct delay_rename_lease_break_state {
185 : struct files_struct *fsp;
186 : bool delay;
187 : };
188 :
189 18 : static bool delay_rename_lease_break_fn(
190 : struct share_mode_entry *e,
191 : void *private_data)
192 : {
193 18 : struct delay_rename_lease_break_state *state = private_data;
194 18 : struct files_struct *fsp = state->fsp;
195 0 : uint32_t e_lease_type, break_to;
196 0 : bool ours, stale;
197 :
198 18 : ours = smb2_lease_equal(fsp_client_guid(fsp),
199 18 : &fsp->lease->lease.lease_key,
200 18 : &e->client_guid,
201 18 : &e->lease_key);
202 18 : if (ours) {
203 10 : return false;
204 : }
205 :
206 8 : e_lease_type = get_lease_type(e, fsp->file_id);
207 :
208 8 : if ((e_lease_type & SMB2_LEASE_HANDLE) == 0) {
209 4 : return false;
210 : }
211 :
212 4 : stale = share_entry_stale_pid(e);
213 4 : if (stale) {
214 0 : return false;
215 : }
216 :
217 4 : state->delay = true;
218 4 : break_to = (e_lease_type & ~SMB2_LEASE_HANDLE);
219 :
220 4 : send_break_message(
221 4 : fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
222 :
223 4 : return false;
224 : }
225 :
226 796 : static struct tevent_req *delay_rename_for_lease_break(struct tevent_req *req,
227 : struct smbd_smb2_request *smb2req,
228 : struct tevent_context *ev,
229 : struct files_struct *fsp,
230 : struct share_mode_lock *lck,
231 : char *data,
232 : int data_size)
233 :
234 : {
235 0 : struct tevent_req *subreq;
236 0 : struct defer_rename_state *rename_state;
237 796 : struct delay_rename_lease_break_state state = { .fsp = fsp };
238 0 : struct timeval timeout;
239 0 : bool ok;
240 :
241 796 : if (fsp->oplock_type != LEASE_OPLOCK) {
242 786 : return NULL;
243 : }
244 :
245 10 : ok = share_mode_forall_leases(
246 : lck, delay_rename_lease_break_fn, &state);
247 10 : if (!ok) {
248 0 : return NULL;
249 : }
250 :
251 10 : if (!state.delay) {
252 6 : return NULL;
253 : }
254 :
255 : /* Setup a watch on this record. */
256 4 : rename_state = talloc_zero(req, struct defer_rename_state);
257 4 : if (rename_state == NULL) {
258 0 : return NULL;
259 : }
260 :
261 4 : rename_state->req = req;
262 4 : rename_state->smb2req = smb2req;
263 4 : rename_state->ev = ev;
264 4 : rename_state->fsp = fsp;
265 4 : rename_state->data = data;
266 4 : rename_state->data_size = data_size;
267 :
268 4 : talloc_set_destructor(rename_state, defer_rename_state_destructor);
269 :
270 4 : subreq = share_mode_watch_send(
271 : rename_state,
272 : ev,
273 : lck,
274 4 : (struct server_id){0});
275 :
276 4 : if (subreq == NULL) {
277 0 : exit_server("Could not watch share mode record for rename\n");
278 : }
279 :
280 4 : tevent_req_set_callback(subreq, defer_rename_done, rename_state);
281 :
282 4 : timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
283 4 : if (!tevent_req_set_endtime(subreq,
284 : ev,
285 4 : timeval_sum(&smb2req->request_time, &timeout))) {
286 0 : exit_server("Could not set rename timeout\n");
287 : }
288 :
289 4 : return subreq;
290 : }
291 :
292 4 : static void defer_rename_done(struct tevent_req *subreq)
293 : {
294 4 : struct defer_rename_state *state = tevent_req_callback_data(
295 : subreq, struct defer_rename_state);
296 0 : NTSTATUS status;
297 0 : struct share_mode_lock *lck;
298 4 : int ret_size = 0;
299 0 : bool ok;
300 :
301 4 : status = share_mode_watch_recv(subreq, NULL, NULL);
302 4 : TALLOC_FREE(subreq);
303 4 : if (!NT_STATUS_IS_OK(status)) {
304 0 : DEBUG(5, ("dbwrap_record_watch_recv returned %s\n",
305 : nt_errstr(status)));
306 0 : tevent_req_nterror(state->req, status);
307 0 : return;
308 : }
309 :
310 : /*
311 : * Make sure we run as the user again
312 : */
313 4 : ok = change_to_user_and_service(
314 4 : state->smb2req->tcon->compat,
315 4 : state->smb2req->session->global->session_wire_id);
316 4 : if (!ok) {
317 0 : tevent_req_nterror(state->req, NT_STATUS_ACCESS_DENIED);
318 0 : return;
319 : }
320 :
321 : /* Do we still need to wait ? */
322 4 : lck = get_existing_share_mode_lock(state->req, state->fsp->file_id);
323 4 : if (lck == NULL) {
324 0 : tevent_req_nterror(state->req, NT_STATUS_UNSUCCESSFUL);
325 0 : return;
326 : }
327 4 : subreq = delay_rename_for_lease_break(state->req,
328 : state->smb2req,
329 : state->ev,
330 : state->fsp,
331 : lck,
332 : state->data,
333 : state->data_size);
334 4 : if (subreq) {
335 : /* Yep - keep waiting. */
336 0 : state->data = NULL;
337 0 : TALLOC_FREE(state);
338 0 : TALLOC_FREE(lck);
339 0 : return;
340 : }
341 :
342 : /* Do the rename under the lock. */
343 4 : status = smbd_do_setfilepathinfo(state->fsp->conn,
344 4 : state->smb2req->smb1req,
345 : state,
346 : SMB2_FILE_RENAME_INFORMATION_INTERNAL,
347 4 : state->fsp,
348 4 : state->fsp->fsp_name,
349 : &state->data,
350 : state->data_size,
351 : &ret_size);
352 :
353 4 : TALLOC_FREE(lck);
354 4 : SAFE_FREE(state->data);
355 :
356 4 : if (!NT_STATUS_IS_OK(status)) {
357 0 : tevent_req_nterror(state->req, status);
358 0 : return;
359 : }
360 :
361 4 : tevent_req_done(state->req);
362 : }
363 :
364 : struct smbd_smb2_setinfo_state {
365 : struct smbd_smb2_request *smb2req;
366 : };
367 :
368 13250 : static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
369 : struct tevent_context *ev,
370 : struct smbd_smb2_request *smb2req,
371 : struct files_struct *fsp,
372 : uint8_t in_info_type,
373 : uint8_t in_file_info_class,
374 : DATA_BLOB in_input_buffer,
375 : uint32_t in_additional_information)
376 : {
377 13250 : struct tevent_req *req = NULL;
378 13250 : struct smbd_smb2_setinfo_state *state = NULL;
379 13250 : struct smb_request *smbreq = NULL;
380 13250 : connection_struct *conn = smb2req->tcon->compat;
381 13250 : struct share_mode_lock *lck = NULL;
382 2 : NTSTATUS status;
383 2 : int ret;
384 :
385 13250 : req = tevent_req_create(mem_ctx, &state,
386 : struct smbd_smb2_setinfo_state);
387 13250 : if (req == NULL) {
388 0 : return NULL;
389 : }
390 13250 : state->smb2req = smb2req;
391 :
392 13250 : DEBUG(10,("smbd_smb2_setinfo_send: %s - %s\n",
393 : fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
394 :
395 13250 : smbreq = smbd_smb2_fake_smb_request(smb2req, fsp);
396 13250 : if (tevent_req_nomem(smbreq, req)) {
397 0 : return tevent_req_post(req, ev);
398 : }
399 :
400 13250 : if (IS_IPC(conn)) {
401 0 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
402 0 : return tevent_req_post(req, ev);
403 : }
404 :
405 13250 : switch (in_info_type) {
406 6296 : case SMB2_0_INFO_FILE:
407 : {
408 0 : uint16_t file_info_level;
409 0 : char *data;
410 0 : int data_size;
411 6296 : int ret_size = 0;
412 :
413 :
414 6296 : file_info_level = in_file_info_class + 1000;
415 6296 : if (file_info_level == SMB_FILE_RENAME_INFORMATION) {
416 : /* SMB2_FILE_RENAME_INFORMATION_INTERNAL == 0xFF00 + in_file_info_class */
417 792 : file_info_level = SMB2_FILE_RENAME_INFORMATION_INTERNAL;
418 : }
419 :
420 6296 : if (fsp_get_pathref_fd(fsp) == -1) {
421 : /*
422 : * This is actually a SETFILEINFO on a directory
423 : * handle (returned from an NT SMB). NT5.0 seems
424 : * to do this call. JRA.
425 : */
426 0 : ret = vfs_stat(fsp->conn, fsp->fsp_name);
427 0 : if (ret != 0) {
428 0 : DBG_WARNING("vfs_stat() of %s failed (%s)\n",
429 : fsp_str_dbg(fsp),
430 : strerror(errno));
431 0 : status = map_nt_error_from_unix(errno);
432 0 : tevent_req_nterror(req, status);
433 275 : return tevent_req_post(req, ev);
434 : }
435 6296 : } else if (fsp->print_file) {
436 : /*
437 : * Doing a DELETE_ON_CLOSE should cancel a print job.
438 : */
439 0 : if ((file_info_level == SMB_SET_FILE_DISPOSITION_INFO)
440 0 : && in_input_buffer.length >= 1
441 0 : && CVAL(in_input_buffer.data,0)) {
442 0 : fsp->fsp_flags.delete_on_close = true;
443 :
444 0 : DEBUG(3,("smbd_smb2_setinfo_send: "
445 : "Cancelling print job (%s)\n",
446 : fsp_str_dbg(fsp)));
447 :
448 0 : tevent_req_done(req);
449 0 : return tevent_req_post(req, ev);
450 : }
451 0 : tevent_req_nterror(req, NT_STATUS_OBJECT_PATH_INVALID);
452 0 : return tevent_req_post(req, ev);
453 : } else {
454 : /*
455 : * Original code - this is an open file.
456 : */
457 :
458 6296 : status = vfs_stat_fsp(fsp);
459 6296 : if (!NT_STATUS_IS_OK(status)) {
460 0 : DEBUG(3,("smbd_smb2_setinfo_send: fstat "
461 : "of %s failed (%s)\n",
462 : fsp_fnum_dbg(fsp),
463 : nt_errstr(status)));
464 0 : tevent_req_nterror(req, status);
465 0 : return tevent_req_post(req, ev);
466 : }
467 : }
468 :
469 6296 : data = NULL;
470 6296 : data_size = in_input_buffer.length;
471 6296 : if (data_size > 0) {
472 6296 : data = (char *)SMB_MALLOC_ARRAY(char, data_size);
473 6296 : if (tevent_req_nomem(data, req)) {
474 0 : return tevent_req_post(req, ev);
475 : }
476 6296 : memcpy(data, in_input_buffer.data, data_size);
477 : }
478 :
479 6296 : if (file_info_level == SMB2_FILE_RENAME_INFORMATION_INTERNAL) {
480 0 : struct tevent_req *subreq;
481 :
482 792 : lck = get_existing_share_mode_lock(mem_ctx,
483 : fsp->file_id);
484 792 : if (lck == NULL) {
485 0 : SAFE_FREE(data);
486 0 : tevent_req_nterror(req,
487 : NT_STATUS_UNSUCCESSFUL);
488 0 : return tevent_req_post(req, ev);
489 : }
490 :
491 792 : subreq = delay_rename_for_lease_break(req,
492 : smb2req,
493 : ev,
494 : fsp,
495 : lck,
496 : data,
497 : data_size);
498 792 : if (subreq) {
499 : /* Wait for lease break response. */
500 :
501 : /* Ensure we can't be closed in flight. */
502 4 : if (!aio_add_req_to_fsp(fsp, req)) {
503 0 : TALLOC_FREE(lck);
504 0 : tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
505 0 : return tevent_req_post(req, ev);
506 : }
507 :
508 4 : TALLOC_FREE(lck);
509 4 : return req;
510 : }
511 : }
512 :
513 6292 : status = smbd_do_setfilepathinfo(conn, smbreq, state,
514 : file_info_level,
515 : fsp,
516 : fsp->fsp_name,
517 : &data,
518 : data_size,
519 : &ret_size);
520 6292 : TALLOC_FREE(lck);
521 6292 : SAFE_FREE(data);
522 6292 : if (!NT_STATUS_IS_OK(status)) {
523 271 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
524 0 : status = NT_STATUS_INVALID_INFO_CLASS;
525 : }
526 271 : tevent_req_nterror(req, status);
527 271 : return tevent_req_post(req, ev);
528 : }
529 6021 : break;
530 : }
531 :
532 0 : case SMB2_0_INFO_FILESYSTEM:
533 : {
534 0 : uint16_t file_info_level = in_file_info_class + 1000;
535 :
536 0 : status = smbd_do_setfsinfo(conn, smbreq, state,
537 : file_info_level,
538 : fsp,
539 : &in_input_buffer);
540 0 : if (!NT_STATUS_IS_OK(status)) {
541 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
542 0 : status = NT_STATUS_INVALID_INFO_CLASS;
543 : }
544 0 : tevent_req_nterror(req, status);
545 0 : return tevent_req_post(req, ev);
546 : }
547 0 : break;
548 : }
549 :
550 6950 : case SMB2_0_INFO_SECURITY:
551 : {
552 6950 : if (!CAN_WRITE(conn)) {
553 0 : tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
554 0 : return tevent_req_post(req, ev);
555 : }
556 :
557 6952 : status = set_sd_blob(fsp,
558 : in_input_buffer.data,
559 6950 : in_input_buffer.length,
560 : in_additional_information &
561 : SMB_SUPPORTED_SECINFO_FLAGS);
562 6950 : if (!NT_STATUS_IS_OK(status)) {
563 5 : tevent_req_nterror(req, status);
564 5 : return tevent_req_post(req, ev);
565 : }
566 6943 : break;
567 : }
568 :
569 4 : case SMB2_0_INFO_QUOTA:
570 : {
571 : #ifdef HAVE_SYS_QUOTAS
572 4 : struct file_quota_information info = {0};
573 4 : SMB_NTQUOTA_STRUCT qt = {0};
574 0 : enum ndr_err_code err;
575 :
576 4 : if (!fsp->fake_file_handle) {
577 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
578 0 : return tevent_req_post(req, ev);
579 : }
580 4 : err = ndr_pull_struct_blob(
581 : &in_input_buffer, state, &info,
582 : (ndr_pull_flags_fn_t)ndr_pull_file_quota_information);
583 4 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
584 0 : tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
585 0 : return tevent_req_post(req, ev);
586 : }
587 :
588 4 : qt.usedspace = info.quota_used;
589 :
590 4 : qt.softlim = info.quota_threshold;
591 :
592 4 : qt.hardlim = info.quota_limit;
593 :
594 4 : qt.sid = info.sid;
595 4 : ret = vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &qt.sid, &qt);
596 4 : if (ret !=0 ) {
597 0 : status = map_nt_error_from_unix(errno);
598 0 : tevent_req_nterror(req, status);
599 0 : return tevent_req_post(req, ev);
600 : }
601 4 : status = NT_STATUS_OK;
602 4 : break;
603 : #else
604 : tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
605 : return tevent_req_post(req, ev);
606 : #endif
607 : }
608 0 : default:
609 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
610 0 : return tevent_req_post(req, ev);
611 : }
612 :
613 12970 : tevent_req_done(req);
614 12970 : return tevent_req_post(req, ev);
615 : }
616 :
617 13250 : static NTSTATUS smbd_smb2_setinfo_recv(struct tevent_req *req)
618 : {
619 2 : NTSTATUS status;
620 :
621 13250 : if (tevent_req_is_nterror(req, &status)) {
622 276 : tevent_req_received(req);
623 276 : return status;
624 : }
625 :
626 12974 : tevent_req_received(req);
627 12974 : return NT_STATUS_OK;
628 : }
|