Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : SMB NT transaction handling
4 : Copyright (C) Jeremy Allison 1994-2007
5 : Copyright (C) Stefan (metze) Metzmacher 2003
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "system/filesys.h"
23 : #include "smbd/smbd.h"
24 : #include "smbd/globals.h"
25 : #include "fake_file.h"
26 : #include "../libcli/security/security.h"
27 : #include "../librpc/gen_ndr/ndr_security.h"
28 : #include "passdb/lookup_sid.h"
29 : #include "auth.h"
30 : #include "smbprofile.h"
31 : #include "libsmb/libsmb.h"
32 : #include "lib/util_ea.h"
33 : #include "librpc/gen_ndr/ndr_quota.h"
34 : #include "librpc/gen_ndr/ndr_security.h"
35 :
36 : extern const struct generic_mapping file_generic_mapping;
37 :
38 15059 : static char *nttrans_realloc(char **ptr, size_t size)
39 : {
40 15059 : if (ptr==NULL) {
41 0 : smb_panic("nttrans_realloc() called with NULL ptr");
42 : }
43 :
44 15059 : *ptr = (char *)SMB_REALLOC(*ptr, size);
45 15059 : if(*ptr == NULL) {
46 0 : return NULL;
47 : }
48 15100 : memset(*ptr,'\0',size);
49 15059 : return *ptr;
50 : }
51 :
52 : /****************************************************************************
53 : Send the required number of replies back.
54 : We assume all fields other than the data fields are
55 : set correctly for the type of call.
56 : HACK ! Always assumes smb_setup field is zero.
57 : ****************************************************************************/
58 :
59 16648 : static void send_nt_replies(connection_struct *conn,
60 : struct smb_request *req, NTSTATUS nt_error,
61 : char *params, int paramsize,
62 : char *pdata, int datasize)
63 : {
64 16648 : int data_to_send = datasize;
65 16648 : int params_to_send = paramsize;
66 : int useable_space;
67 16648 : char *pp = params;
68 16648 : char *pd = pdata;
69 : int params_sent_thistime, data_sent_thistime, total_sent_thistime;
70 16648 : int alignment_offset = 1;
71 16648 : int data_alignment_offset = 0;
72 16648 : struct smbXsrv_connection *xconn = req->xconn;
73 16648 : int max_send = xconn->smb1.sessions.max_send;
74 :
75 : /*
76 : * If there genuinely are no parameters or data to send just send
77 : * the empty packet.
78 : */
79 :
80 16648 : if(params_to_send == 0 && data_to_send == 0) {
81 7539 : reply_outbuf(req, 18, 0);
82 7539 : if (NT_STATUS_V(nt_error)) {
83 922 : error_packet_set((char *)req->outbuf,
84 : 0, 0, nt_error,
85 : __LINE__,__FILE__);
86 : }
87 7539 : show_msg((char *)req->outbuf);
88 28548 : if (!srv_send_smb(xconn,
89 7539 : (char *)req->outbuf,
90 7539 : true, req->seqnum+1,
91 7539 : IS_CONN_ENCRYPTED(conn),
92 : &req->pcd)) {
93 0 : exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
94 : }
95 7539 : TALLOC_FREE(req->outbuf);
96 7534 : return;
97 : }
98 :
99 : /*
100 : * When sending params and data ensure that both are nicely aligned.
101 : * Only do this alignment when there is also data to send - else
102 : * can cause NT redirector problems.
103 : */
104 :
105 9109 : if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
106 0 : data_alignment_offset = 4 - (params_to_send % 4);
107 : }
108 :
109 : /*
110 : * Space is bufsize minus Netbios over TCP header minus SMB header.
111 : * The alignment_offset is to align the param bytes on a four byte
112 : * boundary (2 bytes for data len, one byte pad).
113 : * NT needs this to work correctly.
114 : */
115 :
116 9109 : useable_space = max_send - (smb_size
117 : + 2 * 18 /* wct */
118 9068 : + alignment_offset
119 9109 : + data_alignment_offset);
120 :
121 9109 : if (useable_space < 0) {
122 0 : char *msg = talloc_asprintf(
123 0 : talloc_tos(),
124 : "send_nt_replies failed sanity useable_space = %d!!!",
125 : useable_space);
126 0 : DEBUG(0, ("%s\n", msg));
127 0 : exit_server_cleanly(msg);
128 : }
129 :
130 26654 : while (params_to_send || data_to_send) {
131 :
132 : /*
133 : * Calculate whether we will totally or partially fill this packet.
134 : */
135 :
136 9109 : total_sent_thistime = params_to_send + data_to_send;
137 :
138 : /*
139 : * We can never send more than useable_space.
140 : */
141 :
142 9109 : total_sent_thistime = MIN(total_sent_thistime, useable_space);
143 :
144 9109 : reply_outbuf(req, 18,
145 9109 : total_sent_thistime + alignment_offset
146 9109 : + data_alignment_offset);
147 :
148 : /*
149 : * Set total params and data to be sent.
150 : */
151 :
152 9109 : SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
153 9109 : SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
154 :
155 : /*
156 : * Calculate how many parameters and data we can fit into
157 : * this packet. Parameters get precedence.
158 : */
159 :
160 9109 : params_sent_thistime = MIN(params_to_send,useable_space);
161 9109 : data_sent_thistime = useable_space - params_sent_thistime;
162 9109 : data_sent_thistime = MIN(data_sent_thistime,data_to_send);
163 :
164 9109 : SIVAL(req->outbuf, smb_ntr_ParameterCount,
165 : params_sent_thistime);
166 :
167 9109 : if(params_sent_thistime == 0) {
168 1244 : SIVAL(req->outbuf,smb_ntr_ParameterOffset,0);
169 1244 : SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
170 : } else {
171 : /*
172 : * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
173 : * parameter bytes, however the first 4 bytes of outbuf are
174 : * the Netbios over TCP header. Thus use smb_base() to subtract
175 : * them from the calculation.
176 : */
177 :
178 7865 : SIVAL(req->outbuf,smb_ntr_ParameterOffset,
179 : ((smb_buf(req->outbuf)+alignment_offset)
180 : - smb_base(req->outbuf)));
181 : /*
182 : * Absolute displacement of param bytes sent in this packet.
183 : */
184 :
185 7865 : SIVAL(req->outbuf, smb_ntr_ParameterDisplacement,
186 : pp - params);
187 : }
188 :
189 : /*
190 : * Deal with the data portion.
191 : */
192 :
193 9109 : SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime);
194 :
195 9109 : if(data_sent_thistime == 0) {
196 557 : SIVAL(req->outbuf,smb_ntr_DataOffset,0);
197 557 : SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0);
198 : } else {
199 : /*
200 : * The offset of the data bytes is the offset of the
201 : * parameter bytes plus the number of parameters being sent this time.
202 : */
203 :
204 8552 : SIVAL(req->outbuf, smb_ntr_DataOffset,
205 : ((smb_buf(req->outbuf)+alignment_offset) -
206 : smb_base(req->outbuf))
207 : + params_sent_thistime + data_alignment_offset);
208 8552 : SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
209 : }
210 :
211 : /*
212 : * Copy the param bytes into the packet.
213 : */
214 :
215 9109 : if(params_sent_thistime) {
216 7824 : if (alignment_offset != 0) {
217 7865 : memset(smb_buf(req->outbuf), 0,
218 : alignment_offset);
219 : }
220 7865 : memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
221 : params_sent_thistime);
222 : }
223 :
224 : /*
225 : * Copy in the data bytes
226 : */
227 :
228 9109 : if(data_sent_thistime) {
229 8552 : if (data_alignment_offset != 0) {
230 0 : memset((smb_buf(req->outbuf)+alignment_offset+
231 : params_sent_thistime), 0,
232 : data_alignment_offset);
233 : }
234 16533 : memcpy(smb_buf(req->outbuf)+alignment_offset
235 8552 : +params_sent_thistime+data_alignment_offset,
236 : pd,data_sent_thistime);
237 : }
238 :
239 9109 : DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
240 : params_sent_thistime, data_sent_thistime, useable_space));
241 9109 : DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
242 : params_to_send, data_to_send, paramsize, datasize));
243 :
244 9109 : if (NT_STATUS_V(nt_error)) {
245 5 : error_packet_set((char *)req->outbuf,
246 : 0, 0, nt_error,
247 : __LINE__,__FILE__);
248 : }
249 :
250 : /* Send the packet */
251 9109 : show_msg((char *)req->outbuf);
252 34540 : if (!srv_send_smb(xconn,
253 9109 : (char *)req->outbuf,
254 9109 : true, req->seqnum+1,
255 9109 : IS_CONN_ENCRYPTED(conn),
256 : &req->pcd)) {
257 0 : exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
258 : }
259 :
260 9109 : TALLOC_FREE(req->outbuf);
261 :
262 9109 : pp += params_sent_thistime;
263 9109 : pd += data_sent_thistime;
264 :
265 9109 : params_to_send -= params_sent_thistime;
266 9109 : data_to_send -= data_sent_thistime;
267 :
268 : /*
269 : * Sanity check
270 : */
271 :
272 9109 : if(params_to_send < 0 || data_to_send < 0) {
273 0 : DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
274 : params_to_send, data_to_send));
275 0 : exit_server_cleanly("send_nt_replies: internal error");
276 : }
277 : }
278 : }
279 :
280 : /****************************************************************************
281 : Reply to an NT create and X call on a pipe
282 : ****************************************************************************/
283 :
284 392 : static void nt_open_pipe(char *fname, connection_struct *conn,
285 : struct smb_request *req, uint16_t *ppnum)
286 : {
287 : files_struct *fsp;
288 : NTSTATUS status;
289 :
290 392 : DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
291 :
292 : /* Strip \\ off the name if present. */
293 1101 : while (fname[0] == '\\') {
294 372 : fname++;
295 : }
296 :
297 392 : status = open_np_file(req, fname, &fsp);
298 392 : if (!NT_STATUS_IS_OK(status)) {
299 24 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
300 24 : reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
301 : ERRDOS, ERRbadpipe);
302 24 : return;
303 : }
304 0 : reply_nterror(req, status);
305 0 : return;
306 : }
307 :
308 368 : *ppnum = fsp->fnum;
309 368 : return;
310 : }
311 :
312 : /****************************************************************************
313 : Reply to an NT create and X call for pipes.
314 : ****************************************************************************/
315 :
316 368 : static void do_ntcreate_pipe_open(connection_struct *conn,
317 : struct smb_request *req)
318 : {
319 368 : char *fname = NULL;
320 368 : uint16_t pnum = FNUM_FIELD_INVALID;
321 368 : char *p = NULL;
322 368 : uint32_t flags = IVAL(req->vwv+3, 1);
323 368 : TALLOC_CTX *ctx = talloc_tos();
324 :
325 368 : srvstr_pull_req_talloc(ctx, req, &fname, req->buf, STR_TERMINATE);
326 :
327 368 : if (!fname) {
328 0 : reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
329 : ERRDOS, ERRbadpipe);
330 0 : return;
331 : }
332 368 : nt_open_pipe(fname, conn, req, &pnum);
333 :
334 368 : if (req->outbuf) {
335 : /* error reply */
336 12 : return;
337 : }
338 :
339 : /*
340 : * Deal with pipe return.
341 : */
342 :
343 356 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
344 : /* This is very strange. We
345 : * return 50 words, but only set
346 : * the wcnt to 42 ? It's definitely
347 : * what happens on the wire....
348 : */
349 0 : reply_outbuf(req, 50, 0);
350 0 : SCVAL(req->outbuf,smb_wct,42);
351 : } else {
352 356 : reply_outbuf(req, 34, 0);
353 : }
354 :
355 356 : SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
356 356 : SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
357 :
358 356 : p = (char *)req->outbuf + smb_vwv2;
359 356 : p++;
360 356 : SSVAL(p,0,pnum);
361 356 : p += 2;
362 356 : SIVAL(p,0,FILE_WAS_OPENED);
363 356 : p += 4;
364 356 : p += 32;
365 356 : SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
366 356 : p += 20;
367 : /* File type. */
368 356 : SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
369 : /* Device state. */
370 356 : SSVAL(p,2, 0x5FF); /* ? */
371 356 : p += 4;
372 :
373 356 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
374 0 : p += 25;
375 0 : SIVAL(p,0,FILE_GENERIC_ALL);
376 : /*
377 : * For pipes W2K3 seems to return
378 : * 0x12019B next.
379 : * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
380 : */
381 0 : SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
382 : }
383 :
384 356 : DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
385 : }
386 :
387 : struct case_semantics_state {
388 : connection_struct *conn;
389 : bool case_sensitive;
390 : bool case_preserve;
391 : bool short_case_preserve;
392 : };
393 :
394 : /****************************************************************************
395 : Restore case semantics.
396 : ****************************************************************************/
397 :
398 4 : static int restore_case_semantics(struct case_semantics_state *state)
399 : {
400 4 : state->conn->case_sensitive = state->case_sensitive;
401 4 : state->conn->case_preserve = state->case_preserve;
402 4 : state->conn->short_case_preserve = state->short_case_preserve;
403 4 : return 0;
404 : }
405 :
406 : /****************************************************************************
407 : Save case semantics.
408 : ****************************************************************************/
409 :
410 4 : static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx,
411 : connection_struct *conn)
412 : {
413 : struct case_semantics_state *result;
414 :
415 4 : if (!(result = talloc(mem_ctx, struct case_semantics_state))) {
416 0 : return NULL;
417 : }
418 :
419 4 : result->conn = conn;
420 4 : result->case_sensitive = conn->case_sensitive;
421 4 : result->case_preserve = conn->case_preserve;
422 4 : result->short_case_preserve = conn->short_case_preserve;
423 :
424 : /* Set to POSIX. */
425 4 : conn->case_sensitive = True;
426 4 : conn->case_preserve = True;
427 4 : conn->short_case_preserve = True;
428 :
429 4 : talloc_set_destructor(result, restore_case_semantics);
430 :
431 4 : return result;
432 : }
433 :
434 : /*
435 : * Calculate the full path name given a relative fid.
436 : */
437 552 : static NTSTATUS get_relative_fid_filename(connection_struct *conn,
438 : struct smb_request *req,
439 : uint16_t root_dir_fid,
440 : char *path,
441 : char **path_out)
442 : {
443 552 : struct files_struct *dir_fsp = NULL;
444 552 : char *new_path = NULL;
445 :
446 552 : if (root_dir_fid == 0 || path == NULL) {
447 0 : return NT_STATUS_INTERNAL_ERROR;
448 : }
449 :
450 552 : dir_fsp = file_fsp(req, root_dir_fid);
451 552 : if (dir_fsp == NULL) {
452 0 : return NT_STATUS_INVALID_HANDLE;
453 : }
454 :
455 552 : if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
456 0 : return NT_STATUS_INVALID_HANDLE;
457 : }
458 :
459 552 : if (!dir_fsp->fsp_flags.is_directory) {
460 : /*
461 : * Check to see if this is a mac fork of some kind.
462 : */
463 0 : if (conn->fs_capabilities & FILE_NAMED_STREAMS) {
464 0 : char *stream = NULL;
465 :
466 0 : stream = strchr_m(path, ':');
467 0 : if (stream != NULL) {
468 0 : return NT_STATUS_OBJECT_PATH_NOT_FOUND;
469 : }
470 : }
471 :
472 : /*
473 : * We need to handle the case when we get a relative open
474 : * relative to a file and the pathname is blank - this is a
475 : * reopen! (hint from demyn plantenberg)
476 : */
477 0 : return NT_STATUS_INVALID_HANDLE;
478 : }
479 :
480 552 : if (ISDOT(dir_fsp->fsp_name->base_name)) {
481 : /*
482 : * We're at the toplevel dir, the final file name
483 : * must not contain ./, as this is filtered out
484 : * normally by srvstr_get_path and unix_convert
485 : * explicitly rejects paths containing ./.
486 : */
487 4 : new_path = talloc_strdup(talloc_tos(), path);
488 : } else {
489 : /*
490 : * Copy in the base directory name.
491 : */
492 :
493 548 : new_path = talloc_asprintf(talloc_tos(),
494 : "%s/%s",
495 548 : dir_fsp->fsp_name->base_name,
496 : path);
497 : }
498 552 : if (new_path == NULL) {
499 0 : return NT_STATUS_NO_MEMORY;
500 : }
501 :
502 552 : *path_out = new_path;
503 552 : return NT_STATUS_OK;
504 : }
505 :
506 : /****************************************************************************
507 : Reply to an NT create and X call.
508 : ****************************************************************************/
509 :
510 20287 : void reply_ntcreate_and_X(struct smb_request *req)
511 : {
512 20287 : connection_struct *conn = req->conn;
513 20287 : struct smb_filename *smb_fname = NULL;
514 20287 : char *fname = NULL;
515 : uint32_t flags;
516 : uint32_t access_mask;
517 : uint32_t file_attributes;
518 : uint32_t share_access;
519 : uint32_t create_disposition;
520 : uint32_t create_options;
521 : uint16_t root_dir_fid;
522 : uint64_t allocation_size;
523 : /* Breakout the oplock request bits so we can set the
524 : reply bits separately. */
525 20287 : uint32_t fattr=0;
526 20287 : off_t file_len = 0;
527 20287 : int info = 0;
528 20287 : files_struct *fsp = NULL;
529 20287 : char *p = NULL;
530 : struct timespec create_timespec;
531 : struct timespec c_timespec;
532 : struct timespec a_timespec;
533 : struct timespec m_timespec;
534 : NTSTATUS status;
535 : int oplock_request;
536 20287 : uint8_t oplock_granted = NO_OPLOCK_RETURN;
537 20287 : struct case_semantics_state *case_state = NULL;
538 : uint32_t ucf_flags;
539 20287 : TALLOC_CTX *ctx = talloc_tos();
540 :
541 20287 : START_PROFILE(SMBntcreateX);
542 :
543 20287 : if (req->wct < 24) {
544 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
545 0 : goto out;
546 : }
547 :
548 20287 : flags = IVAL(req->vwv+3, 1);
549 20287 : access_mask = IVAL(req->vwv+7, 1);
550 20287 : file_attributes = IVAL(req->vwv+13, 1);
551 20287 : share_access = IVAL(req->vwv+15, 1);
552 20287 : create_disposition = IVAL(req->vwv+17, 1);
553 20287 : create_options = IVAL(req->vwv+19, 1);
554 20287 : root_dir_fid = (uint16_t)IVAL(req->vwv+5, 1);
555 :
556 20287 : allocation_size = BVAL(req->vwv+9, 1);
557 :
558 20287 : srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
559 : STR_TERMINATE, &status);
560 :
561 20287 : if (!NT_STATUS_IS_OK(status)) {
562 175 : reply_nterror(req, status);
563 175 : goto out;
564 : }
565 :
566 20112 : DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
567 : "file_attributes = 0x%x, share_access = 0x%x, "
568 : "create_disposition = 0x%x create_options = 0x%x "
569 : "root_dir_fid = 0x%x, fname = %s\n",
570 : (unsigned int)flags,
571 : (unsigned int)access_mask,
572 : (unsigned int)file_attributes,
573 : (unsigned int)share_access,
574 : (unsigned int)create_disposition,
575 : (unsigned int)create_options,
576 : (unsigned int)root_dir_fid,
577 : fname));
578 :
579 : /*
580 : * we need to remove ignored bits when they come directly from the client
581 : * because we reuse some of them for internal stuff
582 : */
583 20112 : create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
584 :
585 : /*
586 : * If it's an IPC, use the pipe handler.
587 : */
588 :
589 20112 : if (IS_IPC(conn)) {
590 368 : if (lp_nt_pipe_support()) {
591 368 : do_ntcreate_pipe_open(conn, req);
592 368 : goto out;
593 : }
594 0 : reply_nterror(req, NT_STATUS_ACCESS_DENIED);
595 0 : goto out;
596 : }
597 :
598 19744 : oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
599 19744 : if (oplock_request) {
600 238 : oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
601 238 : ? BATCH_OPLOCK : 0;
602 : }
603 :
604 19744 : if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
605 4 : case_state = set_posix_case_semantics(ctx, conn);
606 4 : if (!case_state) {
607 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
608 0 : goto out;
609 : }
610 : }
611 :
612 19744 : if (root_dir_fid != 0) {
613 552 : char *new_fname = NULL;
614 :
615 552 : status = get_relative_fid_filename(conn,
616 : req,
617 : root_dir_fid,
618 : fname,
619 : &new_fname);
620 552 : if (!NT_STATUS_IS_OK(status)) {
621 0 : reply_nterror(req, status);
622 0 : goto out;
623 : }
624 552 : fname = new_fname;
625 : }
626 :
627 19744 : ucf_flags = filename_create_ucf_flags(req, create_disposition);
628 19744 : status = filename_convert(ctx,
629 : conn,
630 : fname,
631 : ucf_flags,
632 : 0,
633 : &smb_fname);
634 :
635 19744 : TALLOC_FREE(case_state);
636 :
637 19744 : if (!NT_STATUS_IS_OK(status)) {
638 178 : if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
639 0 : reply_botherror(req,
640 : NT_STATUS_PATH_NOT_COVERED,
641 : ERRSRV, ERRbadpath);
642 0 : goto out;
643 : }
644 178 : reply_nterror(req, status);
645 178 : goto out;
646 : }
647 :
648 : /*
649 : * Bug #6898 - clients using Windows opens should
650 : * never be able to set this attribute into the
651 : * VFS.
652 : */
653 19566 : file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
654 :
655 19566 : status = SMB_VFS_CREATE_FILE(
656 : conn, /* conn */
657 : req, /* req */
658 : smb_fname, /* fname */
659 : access_mask, /* access_mask */
660 : share_access, /* share_access */
661 : create_disposition, /* create_disposition*/
662 : create_options, /* create_options */
663 : file_attributes, /* file_attributes */
664 : oplock_request, /* oplock_request */
665 : NULL, /* lease */
666 : allocation_size, /* allocation_size */
667 : 0, /* private_flags */
668 : NULL, /* sd */
669 : NULL, /* ea_list */
670 : &fsp, /* result */
671 : &info, /* pinfo */
672 : NULL, NULL); /* create context */
673 :
674 19566 : if (!NT_STATUS_IS_OK(status)) {
675 6053 : if (open_was_deferred(req->xconn, req->mid)) {
676 : /* We have re-scheduled this call, no error. */
677 61 : goto out;
678 : }
679 5992 : if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
680 3177 : bool ok = defer_smb1_sharing_violation(req);
681 3177 : if (ok) {
682 1655 : goto out;
683 : }
684 : }
685 4333 : reply_openerror(req, status);
686 4333 : goto out;
687 : }
688 :
689 : /* Ensure we're pointing at the correct stat struct. */
690 13513 : TALLOC_FREE(smb_fname);
691 13513 : smb_fname = fsp->fsp_name;
692 :
693 : /*
694 : * If the caller set the extended oplock request bit
695 : * and we granted one (by whatever means) - set the
696 : * correct bit for extended oplock reply.
697 : */
698 :
699 13701 : if (oplock_request &&
700 188 : (lp_fake_oplocks(SNUM(conn))
701 188 : || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
702 :
703 : /*
704 : * Exclusive oplock granted
705 : */
706 :
707 255 : if (flags & REQUEST_BATCH_OPLOCK) {
708 92 : oplock_granted = BATCH_OPLOCK_RETURN;
709 : } else {
710 40 : oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
711 : }
712 13381 : } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
713 44 : oplock_granted = LEVEL_II_OPLOCK_RETURN;
714 : } else {
715 13337 : oplock_granted = NO_OPLOCK_RETURN;
716 : }
717 :
718 13513 : file_len = smb_fname->st.st_ex_size;
719 :
720 13513 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
721 : /* This is very strange. We
722 : * return 50 words, but only set
723 : * the wcnt to 42 ? It's definitely
724 : * what happens on the wire....
725 : */
726 1086 : reply_outbuf(req, 50, 0);
727 1086 : SCVAL(req->outbuf,smb_wct,42);
728 : } else {
729 12427 : reply_outbuf(req, 34, 0);
730 : }
731 :
732 13513 : SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
733 13513 : SSVAL(req->outbuf, smb_vwv1, 0); /* no andx offset */
734 :
735 13513 : p = (char *)req->outbuf + smb_vwv2;
736 :
737 13513 : SCVAL(p, 0, oplock_granted);
738 :
739 13513 : p++;
740 13513 : SSVAL(p,0,fsp->fnum);
741 13513 : p += 2;
742 13513 : if ((create_disposition == FILE_SUPERSEDE)
743 30 : && (info == FILE_WAS_OVERWRITTEN)) {
744 16 : SIVAL(p,0,FILE_WAS_SUPERSEDED);
745 : } else {
746 13497 : SIVAL(p,0,info);
747 : }
748 13513 : p += 4;
749 :
750 13513 : fattr = fdos_mode(fsp);
751 13513 : if (fattr == 0) {
752 0 : fattr = FILE_ATTRIBUTE_NORMAL;
753 : }
754 :
755 : /* Create time. */
756 13513 : create_timespec = get_create_timespec(conn, fsp, smb_fname);
757 13513 : a_timespec = smb_fname->st.st_ex_atime;
758 13513 : m_timespec = smb_fname->st.st_ex_mtime;
759 13513 : c_timespec = get_change_timespec(conn, fsp, smb_fname);
760 :
761 13513 : if (lp_dos_filetime_resolution(SNUM(conn))) {
762 0 : dos_filetime_timespec(&create_timespec);
763 0 : dos_filetime_timespec(&a_timespec);
764 0 : dos_filetime_timespec(&m_timespec);
765 0 : dos_filetime_timespec(&c_timespec);
766 : }
767 :
768 13513 : put_long_date_full_timespec(conn->ts_res, p, &create_timespec); /* create time. */
769 13513 : p += 8;
770 13513 : put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
771 13513 : p += 8;
772 13513 : put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
773 13513 : p += 8;
774 13513 : put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
775 13513 : p += 8;
776 13513 : SIVAL(p,0,fattr); /* File Attributes. */
777 13513 : p += 4;
778 13513 : SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn,fsp,&smb_fname->st));
779 13513 : p += 8;
780 13513 : SOFF_T(p,0,file_len);
781 13513 : p += 8;
782 13513 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
783 1086 : uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
784 1086 : unsigned int num_streams = 0;
785 1086 : struct stream_struct *streams = NULL;
786 :
787 1086 : if (lp_ea_support(SNUM(conn))) {
788 1086 : size_t num_names = 0;
789 : /* Do we have any EA's ? */
790 1086 : status = get_ea_names_from_fsp(
791 1086 : ctx, smb_fname->fsp, NULL, &num_names);
792 1086 : if (NT_STATUS_IS_OK(status) && num_names) {
793 1082 : file_status &= ~NO_EAS;
794 : }
795 : }
796 :
797 1086 : status = vfs_fstreaminfo(smb_fname->fsp, ctx,
798 : &num_streams, &streams);
799 : /* There is always one stream, ::$DATA. */
800 1086 : if (NT_STATUS_IS_OK(status) && num_streams > 1) {
801 0 : file_status &= ~NO_SUBSTREAMS;
802 : }
803 1086 : TALLOC_FREE(streams);
804 1086 : SSVAL(p,2,file_status);
805 : }
806 13513 : p += 4;
807 13513 : SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
808 :
809 13513 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
810 1086 : uint32_t perms = 0;
811 1086 : p += 25;
812 1871 : if (fsp->fsp_flags.is_directory ||
813 1360 : fsp->fsp_flags.can_write ||
814 371 : can_write_to_fsp(fsp))
815 : {
816 1047 : perms = FILE_GENERIC_ALL;
817 : } else {
818 0 : perms = FILE_GENERIC_READ|FILE_EXECUTE;
819 : }
820 1086 : SIVAL(p,0,perms);
821 : }
822 :
823 13513 : DEBUG(5,("reply_ntcreate_and_X: %s, open name = %s\n",
824 : fsp_fnum_dbg(fsp), smb_fname_str_dbg(smb_fname)));
825 :
826 20291 : out:
827 20287 : END_PROFILE(SMBntcreateX);
828 20287 : return;
829 : }
830 :
831 : /****************************************************************************
832 : Reply to a NT_TRANSACT_CREATE call to open a pipe.
833 : ****************************************************************************/
834 :
835 24 : static void do_nt_transact_create_pipe(connection_struct *conn,
836 : struct smb_request *req,
837 : uint16_t **ppsetup, uint32_t setup_count,
838 : char **ppparams, uint32_t parameter_count,
839 : char **ppdata, uint32_t data_count)
840 : {
841 24 : char *fname = NULL;
842 24 : char *params = *ppparams;
843 24 : uint16_t pnum = FNUM_FIELD_INVALID;
844 24 : char *p = NULL;
845 : NTSTATUS status;
846 : size_t param_len;
847 : uint32_t flags;
848 24 : TALLOC_CTX *ctx = talloc_tos();
849 :
850 : /*
851 : * Ensure minimum number of parameters sent.
852 : */
853 :
854 24 : if(parameter_count < 54) {
855 0 : DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
856 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
857 0 : return;
858 : }
859 :
860 24 : flags = IVAL(params,0);
861 :
862 24 : if (req->posix_pathnames) {
863 0 : srvstr_get_path_posix(ctx,
864 : params,
865 0 : req->flags2,
866 : &fname,
867 0 : params+53,
868 0 : parameter_count-53,
869 : STR_TERMINATE,
870 : &status);
871 : } else {
872 42 : srvstr_get_path(ctx,
873 : params,
874 24 : req->flags2,
875 : &fname,
876 24 : params+53,
877 24 : parameter_count-53,
878 : STR_TERMINATE,
879 : &status);
880 : }
881 24 : if (!NT_STATUS_IS_OK(status)) {
882 0 : reply_nterror(req, status);
883 0 : return;
884 : }
885 :
886 24 : nt_open_pipe(fname, conn, req, &pnum);
887 :
888 24 : if (req->outbuf) {
889 : /* Error return */
890 12 : return;
891 : }
892 :
893 : /* Realloc the size of parameters and data we will return */
894 12 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
895 : /* Extended response is 32 more byyes. */
896 0 : param_len = 101;
897 : } else {
898 12 : param_len = 69;
899 : }
900 12 : params = nttrans_realloc(ppparams, param_len);
901 12 : if(params == NULL) {
902 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
903 0 : return;
904 : }
905 :
906 12 : p = params;
907 12 : SCVAL(p,0,NO_OPLOCK_RETURN);
908 :
909 12 : p += 2;
910 12 : SSVAL(p,0,pnum);
911 12 : p += 2;
912 12 : SIVAL(p,0,FILE_WAS_OPENED);
913 12 : p += 8;
914 :
915 12 : p += 32;
916 12 : SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
917 12 : p += 20;
918 : /* File type. */
919 12 : SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
920 : /* Device state. */
921 12 : SSVAL(p,2, 0x5FF); /* ? */
922 12 : p += 4;
923 :
924 12 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
925 0 : p += 25;
926 0 : SIVAL(p,0,FILE_GENERIC_ALL);
927 : /*
928 : * For pipes W2K3 seems to return
929 : * 0x12019B next.
930 : * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
931 : */
932 0 : SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
933 : }
934 :
935 12 : DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
936 :
937 : /* Send the required number of replies */
938 12 : send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
939 :
940 12 : return;
941 : }
942 :
943 : /*********************************************************************
944 : Windows seems to do canonicalization of inheritance bits. Do the
945 : same.
946 : *********************************************************************/
947 :
948 13280 : static void canonicalize_inheritance_bits(struct files_struct *fsp,
949 : struct security_descriptor *psd)
950 : {
951 13280 : bool set_auto_inherited = false;
952 :
953 : /*
954 : * We need to filter out the
955 : * SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ
956 : * bits. If both are set we store SEC_DESC_DACL_AUTO_INHERITED
957 : * as this alters whether SEC_ACE_FLAG_INHERITED_ACE is set
958 : * when an ACE is inherited. Otherwise we zero these bits out.
959 : * See:
960 : *
961 : * http://social.msdn.microsoft.com/Forums/eu/os_fileservices/thread/11f77b68-731e-407d-b1b3-064750716531
962 : *
963 : * for details.
964 : */
965 :
966 13280 : if (!lp_acl_flag_inherited_canonicalization(SNUM(fsp->conn))) {
967 4 : psd->type &= ~SEC_DESC_DACL_AUTO_INHERIT_REQ;
968 4 : return;
969 : }
970 :
971 13276 : if ((psd->type & (SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ))
972 : == (SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ)) {
973 1370 : set_auto_inherited = true;
974 : }
975 :
976 13276 : psd->type &= ~(SEC_DESC_DACL_AUTO_INHERITED|SEC_DESC_DACL_AUTO_INHERIT_REQ);
977 13276 : if (set_auto_inherited) {
978 1370 : psd->type |= SEC_DESC_DACL_AUTO_INHERITED;
979 : }
980 : }
981 :
982 : /****************************************************************************
983 : Internal fn to set security descriptors.
984 : ****************************************************************************/
985 :
986 13282 : NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd,
987 : uint32_t security_info_sent)
988 : {
989 13282 : files_struct *sd_fsp = fsp;
990 : NTSTATUS status;
991 :
992 13282 : if (!CAN_WRITE(fsp->conn)) {
993 0 : return NT_STATUS_ACCESS_DENIED;
994 : }
995 :
996 13282 : if (!lp_nt_acl_support(SNUM(fsp->conn))) {
997 0 : return NT_STATUS_OK;
998 : }
999 :
1000 13282 : status = refuse_symlink_fsp(fsp);
1001 13282 : if (!NT_STATUS_IS_OK(status)) {
1002 0 : DBG_DEBUG("ACL set on symlink %s denied.\n",
1003 : fsp_str_dbg(fsp));
1004 0 : return status;
1005 : }
1006 :
1007 13282 : if (psd->owner_sid == NULL) {
1008 1883 : security_info_sent &= ~SECINFO_OWNER;
1009 : }
1010 13282 : if (psd->group_sid == NULL) {
1011 11121 : security_info_sent &= ~SECINFO_GROUP;
1012 : }
1013 :
1014 : /* Ensure we have at least one thing set. */
1015 13282 : if ((security_info_sent & (SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL)) == 0) {
1016 : /* Just like W2K3 */
1017 0 : return NT_STATUS_OK;
1018 : }
1019 :
1020 : /* Ensure we have the rights to do this. */
1021 13282 : if (security_info_sent & SECINFO_OWNER) {
1022 4611 : if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
1023 0 : return NT_STATUS_ACCESS_DENIED;
1024 : }
1025 : }
1026 :
1027 13282 : if (security_info_sent & SECINFO_GROUP) {
1028 2121 : if (!(fsp->access_mask & SEC_STD_WRITE_OWNER)) {
1029 0 : return NT_STATUS_ACCESS_DENIED;
1030 : }
1031 : }
1032 :
1033 13282 : if (security_info_sent & SECINFO_DACL) {
1034 11196 : if (!(fsp->access_mask & SEC_STD_WRITE_DAC)) {
1035 2 : return NT_STATUS_ACCESS_DENIED;
1036 : }
1037 : /* Convert all the generic bits. */
1038 11194 : if (psd->dacl) {
1039 11160 : security_acl_map_generic(psd->dacl, &file_generic_mapping);
1040 : }
1041 : }
1042 :
1043 13280 : if (security_info_sent & SECINFO_SACL) {
1044 2 : if (!(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
1045 0 : return NT_STATUS_ACCESS_DENIED;
1046 : }
1047 : /*
1048 : * Setting a SACL also requires WRITE_DAC.
1049 : * See the smbtorture3 SMB2-SACL test.
1050 : */
1051 2 : if (!(fsp->access_mask & SEC_STD_WRITE_DAC)) {
1052 0 : return NT_STATUS_ACCESS_DENIED;
1053 : }
1054 : /* Convert all the generic bits. */
1055 2 : if (psd->sacl) {
1056 2 : security_acl_map_generic(psd->sacl, &file_generic_mapping);
1057 : }
1058 : }
1059 :
1060 13280 : canonicalize_inheritance_bits(fsp, psd);
1061 :
1062 13280 : if (DEBUGLEVEL >= 10) {
1063 0 : DEBUG(10,("set_sd for file %s\n", fsp_str_dbg(fsp)));
1064 0 : NDR_PRINT_DEBUG(security_descriptor, psd);
1065 : }
1066 :
1067 13280 : if (fsp->base_fsp != NULL) {
1068 : /*
1069 : * This is a stream handle. Use
1070 : * the underlying pathref handle.
1071 : */
1072 2 : sd_fsp = fsp->base_fsp;
1073 : }
1074 13280 : status = SMB_VFS_FSET_NT_ACL(sd_fsp, security_info_sent, psd);
1075 :
1076 13280 : TALLOC_FREE(psd);
1077 :
1078 13280 : return status;
1079 : }
1080 :
1081 : /****************************************************************************
1082 : Internal fn to set security descriptors from a data blob.
1083 : ****************************************************************************/
1084 :
1085 13140 : NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len,
1086 : uint32_t security_info_sent)
1087 : {
1088 13140 : struct security_descriptor *psd = NULL;
1089 : NTSTATUS status;
1090 :
1091 13140 : if (sd_len == 0) {
1092 0 : return NT_STATUS_INVALID_PARAMETER;
1093 : }
1094 :
1095 13140 : status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd);
1096 :
1097 13140 : if (!NT_STATUS_IS_OK(status)) {
1098 0 : return status;
1099 : }
1100 :
1101 13140 : return set_sd(fsp, psd, security_info_sent);
1102 : }
1103 :
1104 : /****************************************************************************
1105 : Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1106 : ****************************************************************************/
1107 :
1108 561 : static void call_nt_transact_create(connection_struct *conn,
1109 : struct smb_request *req,
1110 : uint16_t **ppsetup, uint32_t setup_count,
1111 : char **ppparams, uint32_t parameter_count,
1112 : char **ppdata, uint32_t data_count,
1113 : uint32_t max_data_count)
1114 : {
1115 561 : struct smb_filename *smb_fname = NULL;
1116 561 : char *fname = NULL;
1117 561 : char *params = *ppparams;
1118 561 : char *data = *ppdata;
1119 : /* Breakout the oplock request bits so we can set the reply bits separately. */
1120 561 : uint32_t fattr=0;
1121 561 : off_t file_len = 0;
1122 561 : int info = 0;
1123 561 : files_struct *fsp = NULL;
1124 561 : char *p = NULL;
1125 : uint32_t flags;
1126 : uint32_t access_mask;
1127 : uint32_t file_attributes;
1128 : uint32_t share_access;
1129 : uint32_t create_disposition;
1130 : uint32_t create_options;
1131 : uint32_t sd_len;
1132 561 : struct security_descriptor *sd = NULL;
1133 : uint32_t ea_len;
1134 : uint16_t root_dir_fid;
1135 : struct timespec create_timespec;
1136 : struct timespec c_timespec;
1137 : struct timespec a_timespec;
1138 : struct timespec m_timespec;
1139 561 : struct ea_list *ea_list = NULL;
1140 : NTSTATUS status;
1141 : size_t param_len;
1142 : uint64_t allocation_size;
1143 : int oplock_request;
1144 : uint8_t oplock_granted;
1145 561 : struct case_semantics_state *case_state = NULL;
1146 : uint32_t ucf_flags;
1147 561 : TALLOC_CTX *ctx = talloc_tos();
1148 :
1149 561 : DEBUG(5,("call_nt_transact_create\n"));
1150 :
1151 : /*
1152 : * If it's an IPC, use the pipe handler.
1153 : */
1154 :
1155 561 : if (IS_IPC(conn)) {
1156 24 : if (lp_nt_pipe_support()) {
1157 24 : do_nt_transact_create_pipe(
1158 : conn, req,
1159 : ppsetup, setup_count,
1160 : ppparams, parameter_count,
1161 : ppdata, data_count);
1162 24 : goto out;
1163 : }
1164 0 : reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1165 0 : goto out;
1166 : }
1167 :
1168 : /*
1169 : * Ensure minimum number of parameters sent.
1170 : */
1171 :
1172 537 : if(parameter_count < 54) {
1173 0 : DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
1174 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1175 0 : goto out;
1176 : }
1177 :
1178 537 : flags = IVAL(params,0);
1179 537 : access_mask = IVAL(params,8);
1180 537 : file_attributes = IVAL(params,20);
1181 537 : share_access = IVAL(params,24);
1182 537 : create_disposition = IVAL(params,28);
1183 537 : create_options = IVAL(params,32);
1184 537 : sd_len = IVAL(params,36);
1185 537 : ea_len = IVAL(params,40);
1186 537 : root_dir_fid = (uint16_t)IVAL(params,4);
1187 537 : allocation_size = BVAL(params,12);
1188 :
1189 : /*
1190 : * we need to remove ignored bits when they come directly from the client
1191 : * because we reuse some of them for internal stuff
1192 : */
1193 537 : create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
1194 :
1195 537 : if (req->posix_pathnames) {
1196 0 : srvstr_get_path_posix(ctx,
1197 : params,
1198 0 : req->flags2,
1199 : &fname,
1200 0 : params+53,
1201 0 : parameter_count-53,
1202 : STR_TERMINATE,
1203 : &status);
1204 : } else {
1205 994 : srvstr_get_path(ctx,
1206 : params,
1207 537 : req->flags2,
1208 : &fname,
1209 537 : params+53,
1210 537 : parameter_count-53,
1211 : STR_TERMINATE,
1212 : &status);
1213 : }
1214 537 : if (!NT_STATUS_IS_OK(status)) {
1215 0 : reply_nterror(req, status);
1216 0 : goto out;
1217 : }
1218 :
1219 537 : if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1220 0 : case_state = set_posix_case_semantics(ctx, conn);
1221 0 : if (!case_state) {
1222 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1223 0 : goto out;
1224 : }
1225 : }
1226 :
1227 537 : if (root_dir_fid != 0) {
1228 0 : char *new_fname = NULL;
1229 :
1230 0 : status = get_relative_fid_filename(conn,
1231 : req,
1232 : root_dir_fid,
1233 : fname,
1234 : &new_fname);
1235 0 : if (!NT_STATUS_IS_OK(status)) {
1236 0 : reply_nterror(req, status);
1237 0 : goto out;
1238 : }
1239 0 : fname = new_fname;
1240 : }
1241 :
1242 537 : ucf_flags = filename_create_ucf_flags(req, create_disposition);
1243 537 : status = filename_convert(ctx,
1244 : conn,
1245 : fname,
1246 : ucf_flags,
1247 : 0,
1248 : &smb_fname);
1249 :
1250 537 : TALLOC_FREE(case_state);
1251 :
1252 537 : if (!NT_STATUS_IS_OK(status)) {
1253 0 : if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1254 0 : reply_botherror(req,
1255 : NT_STATUS_PATH_NOT_COVERED,
1256 : ERRSRV, ERRbadpath);
1257 0 : goto out;
1258 : }
1259 0 : reply_nterror(req, status);
1260 0 : goto out;
1261 : }
1262 :
1263 : /* Ensure the data_len is correct for the sd and ea values given. */
1264 537 : if ((ea_len + sd_len > data_count)
1265 537 : || (ea_len > data_count) || (sd_len > data_count)
1266 537 : || (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
1267 0 : DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
1268 : "%u, data_count = %u\n", (unsigned int)ea_len,
1269 : (unsigned int)sd_len, (unsigned int)data_count));
1270 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1271 0 : goto out;
1272 : }
1273 :
1274 537 : if (sd_len) {
1275 166 : DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
1276 : sd_len));
1277 :
1278 166 : status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
1279 : &sd);
1280 166 : if (!NT_STATUS_IS_OK(status)) {
1281 0 : DEBUG(10, ("call_nt_transact_create: "
1282 : "unmarshall_sec_desc failed: %s\n",
1283 : nt_errstr(status)));
1284 0 : reply_nterror(req, status);
1285 0 : goto out;
1286 : }
1287 : }
1288 :
1289 537 : if (ea_len) {
1290 15 : if (!lp_ea_support(SNUM(conn))) {
1291 0 : DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
1292 : "EA's not supported.\n",
1293 : (unsigned int)ea_len));
1294 0 : reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
1295 0 : goto out;
1296 : }
1297 :
1298 15 : if (ea_len < 10) {
1299 0 : DEBUG(10,("call_nt_transact_create - ea_len = %u - "
1300 : "too small (should be more than 10)\n",
1301 : (unsigned int)ea_len ));
1302 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1303 0 : goto out;
1304 : }
1305 :
1306 : /* We have already checked that ea_len <= data_count here. */
1307 15 : ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
1308 : ea_len);
1309 15 : if (ea_list == NULL) {
1310 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1311 0 : goto out;
1312 : }
1313 :
1314 30 : if (!req->posix_pathnames &&
1315 15 : ea_list_has_invalid_name(ea_list)) {
1316 : /* Realloc the size of parameters and data we will return */
1317 5 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
1318 : /* Extended response is 32 more byyes. */
1319 0 : param_len = 101;
1320 : } else {
1321 5 : param_len = 69;
1322 : }
1323 5 : params = nttrans_realloc(ppparams, param_len);
1324 5 : if(params == NULL) {
1325 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1326 0 : goto out;
1327 : }
1328 :
1329 5 : memset(params, '\0', param_len);
1330 5 : send_nt_replies(conn, req, STATUS_INVALID_EA_NAME,
1331 : params, param_len, NULL, 0);
1332 4 : goto out;
1333 : }
1334 : }
1335 :
1336 532 : oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1337 532 : if (oplock_request) {
1338 0 : oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
1339 0 : ? BATCH_OPLOCK : 0;
1340 : }
1341 :
1342 : /*
1343 : * Bug #6898 - clients using Windows opens should
1344 : * never be able to set this attribute into the
1345 : * VFS.
1346 : */
1347 532 : file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;
1348 :
1349 532 : status = SMB_VFS_CREATE_FILE(
1350 : conn, /* conn */
1351 : req, /* req */
1352 : smb_fname, /* fname */
1353 : access_mask, /* access_mask */
1354 : share_access, /* share_access */
1355 : create_disposition, /* create_disposition*/
1356 : create_options, /* create_options */
1357 : file_attributes, /* file_attributes */
1358 : oplock_request, /* oplock_request */
1359 : NULL, /* lease */
1360 : allocation_size, /* allocation_size */
1361 : 0, /* private_flags */
1362 : sd, /* sd */
1363 : ea_list, /* ea_list */
1364 : &fsp, /* result */
1365 : &info, /* pinfo */
1366 : NULL, NULL); /* create context */
1367 :
1368 532 : if(!NT_STATUS_IS_OK(status)) {
1369 106 : if (open_was_deferred(req->xconn, req->mid)) {
1370 : /* We have re-scheduled this call, no error. */
1371 0 : return;
1372 : }
1373 106 : if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1374 0 : bool ok = defer_smb1_sharing_violation(req);
1375 0 : if (ok) {
1376 0 : return;
1377 : }
1378 : }
1379 106 : reply_openerror(req, status);
1380 88 : goto out;
1381 : }
1382 :
1383 : /* Ensure we're pointing at the correct stat struct. */
1384 426 : TALLOC_FREE(smb_fname);
1385 426 : smb_fname = fsp->fsp_name;
1386 :
1387 : /*
1388 : * If the caller set the extended oplock request bit
1389 : * and we granted one (by whatever means) - set the
1390 : * correct bit for extended oplock reply.
1391 : */
1392 :
1393 426 : if (oplock_request &&
1394 0 : (lp_fake_oplocks(SNUM(conn))
1395 0 : || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
1396 :
1397 : /*
1398 : * Exclusive oplock granted
1399 : */
1400 :
1401 0 : if (flags & REQUEST_BATCH_OPLOCK) {
1402 0 : oplock_granted = BATCH_OPLOCK_RETURN;
1403 : } else {
1404 0 : oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
1405 : }
1406 426 : } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
1407 0 : oplock_granted = LEVEL_II_OPLOCK_RETURN;
1408 : } else {
1409 426 : oplock_granted = NO_OPLOCK_RETURN;
1410 : }
1411 :
1412 426 : file_len = smb_fname->st.st_ex_size;
1413 :
1414 : /* Realloc the size of parameters and data we will return */
1415 426 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
1416 : /* Extended response is 32 more byyes. */
1417 152 : param_len = 101;
1418 : } else {
1419 236 : param_len = 69;
1420 : }
1421 426 : params = nttrans_realloc(ppparams, param_len);
1422 426 : if(params == NULL) {
1423 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1424 0 : goto out;
1425 : }
1426 :
1427 426 : p = params;
1428 426 : SCVAL(p, 0, oplock_granted);
1429 :
1430 426 : p += 2;
1431 426 : SSVAL(p,0,fsp->fnum);
1432 426 : p += 2;
1433 426 : if ((create_disposition == FILE_SUPERSEDE)
1434 10 : && (info == FILE_WAS_OVERWRITTEN)) {
1435 5 : SIVAL(p,0,FILE_WAS_SUPERSEDED);
1436 : } else {
1437 421 : SIVAL(p,0,info);
1438 : }
1439 426 : p += 8;
1440 :
1441 426 : fattr = fdos_mode(fsp);
1442 426 : if (fattr == 0) {
1443 0 : fattr = FILE_ATTRIBUTE_NORMAL;
1444 : }
1445 :
1446 : /* Create time. */
1447 426 : create_timespec = get_create_timespec(conn, fsp, smb_fname);
1448 426 : a_timespec = smb_fname->st.st_ex_atime;
1449 426 : m_timespec = smb_fname->st.st_ex_mtime;
1450 426 : c_timespec = get_change_timespec(conn, fsp, smb_fname);
1451 :
1452 426 : if (lp_dos_filetime_resolution(SNUM(conn))) {
1453 0 : dos_filetime_timespec(&create_timespec);
1454 0 : dos_filetime_timespec(&a_timespec);
1455 0 : dos_filetime_timespec(&m_timespec);
1456 0 : dos_filetime_timespec(&c_timespec);
1457 : }
1458 :
1459 426 : put_long_date_full_timespec(conn->ts_res, p, &create_timespec); /* create time. */
1460 426 : p += 8;
1461 426 : put_long_date_full_timespec(conn->ts_res, p, &a_timespec); /* access time */
1462 426 : p += 8;
1463 426 : put_long_date_full_timespec(conn->ts_res, p, &m_timespec); /* write time */
1464 426 : p += 8;
1465 426 : put_long_date_full_timespec(conn->ts_res, p, &c_timespec); /* change time */
1466 426 : p += 8;
1467 426 : SIVAL(p,0,fattr); /* File Attributes. */
1468 426 : p += 4;
1469 426 : SOFF_T(p, 0, SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &smb_fname->st));
1470 426 : p += 8;
1471 426 : SOFF_T(p,0,file_len);
1472 426 : p += 8;
1473 426 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
1474 190 : uint16_t file_status = (NO_EAS|NO_SUBSTREAMS|NO_REPARSETAG);
1475 190 : unsigned int num_streams = 0;
1476 190 : struct stream_struct *streams = NULL;
1477 :
1478 190 : if (lp_ea_support(SNUM(conn))) {
1479 190 : size_t num_names = 0;
1480 : /* Do we have any EA's ? */
1481 190 : status = get_ea_names_from_fsp(
1482 190 : ctx, smb_fname->fsp, NULL, &num_names);
1483 190 : if (NT_STATUS_IS_OK(status) && num_names) {
1484 190 : file_status &= ~NO_EAS;
1485 : }
1486 : }
1487 :
1488 190 : status = vfs_fstreaminfo(smb_fname->fsp, ctx,
1489 : &num_streams, &streams);
1490 : /* There is always one stream, ::$DATA. */
1491 190 : if (NT_STATUS_IS_OK(status) && num_streams > 1) {
1492 0 : file_status &= ~NO_SUBSTREAMS;
1493 : }
1494 190 : TALLOC_FREE(streams);
1495 190 : SSVAL(p,2,file_status);
1496 : }
1497 426 : p += 4;
1498 426 : SCVAL(p,0,fsp->fsp_flags.is_directory ? 1 : 0);
1499 :
1500 426 : if (flags & EXTENDED_RESPONSE_REQUIRED) {
1501 190 : uint32_t perms = 0;
1502 190 : p += 25;
1503 301 : if (fsp->fsp_flags.is_directory ||
1504 148 : fsp->fsp_flags.can_write ||
1505 0 : can_write_to_fsp(fsp))
1506 : {
1507 152 : perms = FILE_GENERIC_ALL;
1508 : } else {
1509 0 : perms = FILE_GENERIC_READ|FILE_EXECUTE;
1510 : }
1511 190 : SIVAL(p,0,perms);
1512 : }
1513 :
1514 426 : DEBUG(5,("call_nt_transact_create: open name = %s\n",
1515 : smb_fname_str_dbg(smb_fname)));
1516 :
1517 : /* Send the required number of replies */
1518 426 : send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
1519 561 : out:
1520 502 : return;
1521 : }
1522 :
1523 : /****************************************************************************
1524 : Reply to a NT CANCEL request.
1525 : conn POINTER CAN BE NULL HERE !
1526 : ****************************************************************************/
1527 :
1528 986 : void reply_ntcancel(struct smb_request *req)
1529 : {
1530 986 : struct smbXsrv_connection *xconn = req->xconn;
1531 986 : struct smbd_server_connection *sconn = req->sconn;
1532 : bool found;
1533 :
1534 : /*
1535 : * Go through and cancel any pending change notifies.
1536 : */
1537 :
1538 986 : START_PROFILE(SMBntcancel);
1539 986 : srv_cancel_sign_response(xconn);
1540 986 : found = remove_pending_change_notify_requests_by_mid(sconn, req->mid);
1541 986 : if (!found) {
1542 64 : smbd_smb1_brl_finish_by_mid(sconn, req->mid);
1543 : }
1544 :
1545 986 : DEBUG(3,("reply_ntcancel: cancel called on mid = %llu.\n",
1546 : (unsigned long long)req->mid));
1547 :
1548 986 : END_PROFILE(SMBntcancel);
1549 986 : return;
1550 : }
1551 :
1552 : /****************************************************************************
1553 : Copy a file.
1554 : ****************************************************************************/
1555 :
1556 10 : NTSTATUS copy_internals(TALLOC_CTX *ctx,
1557 : connection_struct *conn,
1558 : struct smb_request *req,
1559 : struct smb_filename *smb_fname_src,
1560 : struct smb_filename *smb_fname_dst,
1561 : uint32_t attrs)
1562 : {
1563 : files_struct *fsp1,*fsp2;
1564 : uint32_t fattr;
1565 : int info;
1566 10 : off_t ret=-1;
1567 10 : NTSTATUS status = NT_STATUS_OK;
1568 10 : struct smb_filename *parent = NULL;
1569 10 : struct smb_filename *pathref = NULL;
1570 :
1571 10 : if (!CAN_WRITE(conn)) {
1572 0 : status = NT_STATUS_MEDIA_WRITE_PROTECTED;
1573 0 : goto out;
1574 : }
1575 :
1576 : /* Source must already exist. */
1577 10 : if (!VALID_STAT(smb_fname_src->st)) {
1578 0 : status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1579 0 : goto out;
1580 : }
1581 :
1582 : /* Ensure attributes match. */
1583 10 : fattr = fdos_mode(smb_fname_src->fsp);
1584 10 : if ((fattr & ~attrs) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
1585 0 : status = NT_STATUS_NO_SUCH_FILE;
1586 0 : goto out;
1587 : }
1588 :
1589 : /* Disallow if dst file already exists. */
1590 10 : if (VALID_STAT(smb_fname_dst->st)) {
1591 0 : status = NT_STATUS_OBJECT_NAME_COLLISION;
1592 0 : goto out;
1593 : }
1594 :
1595 : /* No links from a directory. */
1596 10 : if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
1597 0 : status = NT_STATUS_FILE_IS_A_DIRECTORY;
1598 0 : goto out;
1599 : }
1600 :
1601 10 : DEBUG(10,("copy_internals: doing file copy %s to %s\n",
1602 : smb_fname_str_dbg(smb_fname_src),
1603 : smb_fname_str_dbg(smb_fname_dst)));
1604 :
1605 10 : status = SMB_VFS_CREATE_FILE(
1606 : conn, /* conn */
1607 : req, /* req */
1608 : smb_fname_src, /* fname */
1609 : FILE_READ_DATA|FILE_READ_ATTRIBUTES|
1610 : FILE_READ_EA, /* access_mask */
1611 : (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
1612 : FILE_SHARE_DELETE),
1613 : FILE_OPEN, /* create_disposition*/
1614 : 0, /* create_options */
1615 : FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1616 : NO_OPLOCK, /* oplock_request */
1617 : NULL, /* lease */
1618 : 0, /* allocation_size */
1619 : 0, /* private_flags */
1620 : NULL, /* sd */
1621 : NULL, /* ea_list */
1622 : &fsp1, /* result */
1623 : &info, /* pinfo */
1624 : NULL, NULL); /* create context */
1625 :
1626 10 : if (!NT_STATUS_IS_OK(status)) {
1627 0 : goto out;
1628 : }
1629 :
1630 10 : status = SMB_VFS_CREATE_FILE(
1631 : conn, /* conn */
1632 : req, /* req */
1633 : smb_fname_dst, /* fname */
1634 : FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|
1635 : FILE_WRITE_EA, /* access_mask */
1636 : (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
1637 : FILE_SHARE_DELETE),
1638 : FILE_CREATE, /* create_disposition*/
1639 : 0, /* create_options */
1640 : fattr, /* file_attributes */
1641 : NO_OPLOCK, /* oplock_request */
1642 : NULL, /* lease */
1643 : 0, /* allocation_size */
1644 : 0, /* private_flags */
1645 : NULL, /* sd */
1646 : NULL, /* ea_list */
1647 : &fsp2, /* result */
1648 : &info, /* pinfo */
1649 : NULL, NULL); /* create context */
1650 :
1651 10 : if (!NT_STATUS_IS_OK(status)) {
1652 0 : close_file(NULL, fsp1, ERROR_CLOSE);
1653 0 : goto out;
1654 : }
1655 :
1656 10 : if (smb_fname_src->st.st_ex_size) {
1657 10 : ret = vfs_transfer_file(fsp1, fsp2, smb_fname_src->st.st_ex_size);
1658 : }
1659 :
1660 : /*
1661 : * As we are opening fsp1 read-only we only expect
1662 : * an error on close on fsp2 if we are out of space.
1663 : * Thus we don't look at the error return from the
1664 : * close of fsp1.
1665 : */
1666 10 : close_file(NULL, fsp1, NORMAL_CLOSE);
1667 :
1668 : /* Ensure the modtime is set correctly on the destination file. */
1669 10 : set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
1670 :
1671 10 : status = close_file(NULL, fsp2, NORMAL_CLOSE);
1672 :
1673 : /* Grrr. We have to do this as open_file_ntcreate adds FILE_ATTRIBUTE_ARCHIVE when it
1674 : creates the file. This isn't the correct thing to do in the copy
1675 : case. JRA */
1676 :
1677 10 : status = SMB_VFS_PARENT_PATHNAME(conn,
1678 : talloc_tos(),
1679 : smb_fname_dst,
1680 : &parent,
1681 : NULL);
1682 10 : if (!NT_STATUS_IS_OK(status)) {
1683 0 : goto out;
1684 : }
1685 10 : if (smb_fname_dst->fsp == NULL) {
1686 18 : status = synthetic_pathref(parent,
1687 : conn->cwd_fsp,
1688 10 : smb_fname_dst->base_name,
1689 10 : smb_fname_dst->stream_name,
1690 : NULL,
1691 : smb_fname_dst->twrp,
1692 : smb_fname_dst->flags,
1693 : &pathref);
1694 :
1695 : /* should we handle NT_STATUS_OBJECT_NAME_NOT_FOUND specially here ???? */
1696 10 : if (!NT_STATUS_IS_OK(status)) {
1697 0 : TALLOC_FREE(parent);
1698 0 : goto out;
1699 : }
1700 10 : file_set_dosmode(conn, pathref, fattr, parent, false);
1701 10 : smb_fname_dst->st.st_ex_mode = pathref->st.st_ex_mode;
1702 : } else {
1703 0 : file_set_dosmode(conn, smb_fname_dst, fattr, parent, false);
1704 : }
1705 10 : TALLOC_FREE(parent);
1706 :
1707 10 : if (ret < (off_t)smb_fname_src->st.st_ex_size) {
1708 0 : status = NT_STATUS_DISK_FULL;
1709 0 : goto out;
1710 : }
1711 18 : out:
1712 10 : if (!NT_STATUS_IS_OK(status)) {
1713 0 : DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1714 : nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
1715 : smb_fname_str_dbg(smb_fname_dst)));
1716 : }
1717 :
1718 10 : return status;
1719 : }
1720 :
1721 : /****************************************************************************
1722 : Reply to a NT rename request.
1723 : ****************************************************************************/
1724 :
1725 20588 : void reply_ntrename(struct smb_request *req)
1726 : {
1727 20588 : connection_struct *conn = req->conn;
1728 20588 : struct smb_filename *smb_fname_old = NULL;
1729 20588 : struct smb_filename *smb_fname_new = NULL;
1730 20588 : char *oldname = NULL;
1731 20588 : char *newname = NULL;
1732 20588 : const char *dst_original_lcomp = NULL;
1733 : const char *p;
1734 : NTSTATUS status;
1735 20588 : bool dest_has_wcard = False;
1736 : uint32_t attrs;
1737 20588 : uint32_t ucf_flags_src = ucf_flags_from_smb_request(req);
1738 20588 : uint32_t ucf_flags_dst = ucf_flags_from_smb_request(req);
1739 : uint16_t rename_type;
1740 20588 : TALLOC_CTX *ctx = talloc_tos();
1741 20588 : bool stream_rename = false;
1742 :
1743 20588 : START_PROFILE(SMBntrename);
1744 :
1745 20588 : if (req->wct < 4) {
1746 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1747 0 : goto out;
1748 : }
1749 :
1750 20588 : attrs = SVAL(req->vwv+0, 0);
1751 20588 : rename_type = SVAL(req->vwv+1, 0);
1752 :
1753 20588 : p = (const char *)req->buf + 1;
1754 20588 : p += srvstr_get_path_req(ctx, req, &oldname, p, STR_TERMINATE,
1755 : &status);
1756 20588 : if (!NT_STATUS_IS_OK(status)) {
1757 0 : reply_nterror(req, status);
1758 0 : goto out;
1759 : }
1760 :
1761 20588 : if (!req->posix_pathnames && ms_has_wild(oldname)) {
1762 5 : reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1763 5 : goto out;
1764 : }
1765 :
1766 20583 : p++;
1767 20583 : p += srvstr_get_path_req(ctx, req, &newname, p, STR_TERMINATE,
1768 : &status);
1769 20583 : if (!NT_STATUS_IS_OK(status)) {
1770 0 : reply_nterror(req, status);
1771 0 : goto out;
1772 : }
1773 :
1774 20583 : if (!req->posix_pathnames) {
1775 : /* The newname must begin with a ':' if the
1776 : oldname contains a ':'. */
1777 20583 : if (strchr_m(oldname, ':')) {
1778 16 : if (newname[0] != ':') {
1779 8 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1780 8 : goto out;
1781 : }
1782 8 : stream_rename = true;
1783 : }
1784 : }
1785 :
1786 : /*
1787 : * If this is a rename operation, allow wildcards and save the
1788 : * destination's last component.
1789 : */
1790 20575 : if (rename_type == RENAME_FLAG_RENAME) {
1791 72 : ucf_flags_dst |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
1792 : }
1793 :
1794 : /* rename_internals() calls unix_convert(), so don't call it here. */
1795 20575 : status = filename_convert(ctx, conn,
1796 : oldname,
1797 : ucf_flags_src,
1798 : 0,
1799 : &smb_fname_old);
1800 20575 : if (!NT_STATUS_IS_OK(status)) {
1801 0 : if (NT_STATUS_EQUAL(status,
1802 : NT_STATUS_PATH_NOT_COVERED)) {
1803 0 : reply_botherror(req,
1804 : NT_STATUS_PATH_NOT_COVERED,
1805 : ERRSRV, ERRbadpath);
1806 0 : goto out;
1807 : }
1808 0 : reply_nterror(req, status);
1809 0 : goto out;
1810 : }
1811 :
1812 : /* Get the last component of the destination for rename_internals(). */
1813 20575 : dst_original_lcomp = get_original_lcomp(ctx,
1814 : conn,
1815 : newname,
1816 : ucf_flags_dst);
1817 20575 : if (dst_original_lcomp == NULL) {
1818 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1819 0 : goto out;
1820 : }
1821 :
1822 20575 : if (!req->posix_pathnames) {
1823 20575 : dest_has_wcard = ms_has_wild(dst_original_lcomp);
1824 : }
1825 :
1826 20575 : status = filename_convert(ctx, conn,
1827 : newname,
1828 : ucf_flags_dst,
1829 : 0,
1830 : &smb_fname_new);
1831 20575 : if (!NT_STATUS_IS_OK(status)) {
1832 0 : if (NT_STATUS_EQUAL(status,
1833 : NT_STATUS_PATH_NOT_COVERED)) {
1834 0 : reply_botherror(req,
1835 : NT_STATUS_PATH_NOT_COVERED,
1836 : ERRSRV, ERRbadpath);
1837 0 : goto out;
1838 : }
1839 0 : reply_nterror(req, status);
1840 0 : goto out;
1841 : }
1842 :
1843 20575 : if (stream_rename) {
1844 : /* smb_fname_new must be the same as smb_fname_old. */
1845 8 : TALLOC_FREE(smb_fname_new->base_name);
1846 10 : smb_fname_new->base_name = talloc_strdup(smb_fname_new,
1847 8 : smb_fname_old->base_name);
1848 8 : if (!smb_fname_new->base_name) {
1849 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
1850 0 : goto out;
1851 : }
1852 : }
1853 :
1854 20575 : DEBUG(3,("reply_ntrename: %s -> %s\n",
1855 : smb_fname_str_dbg(smb_fname_old),
1856 : smb_fname_str_dbg(smb_fname_new)));
1857 :
1858 20575 : switch(rename_type) {
1859 72 : case RENAME_FLAG_RENAME:
1860 72 : status = rename_internals(ctx,
1861 : conn,
1862 : req,
1863 : smb_fname_old,
1864 : NULL,
1865 : smb_fname_new,
1866 : dst_original_lcomp,
1867 : attrs,
1868 : false,
1869 : DELETE_ACCESS);
1870 72 : break;
1871 13 : case RENAME_FLAG_HARD_LINK:
1872 13 : if (dest_has_wcard) {
1873 : /* No wildcards. */
1874 0 : status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1875 : } else {
1876 13 : status = hardlink_internals(ctx, conn,
1877 : req,
1878 : false,
1879 : smb_fname_old,
1880 : smb_fname_new);
1881 : }
1882 12 : break;
1883 10 : case RENAME_FLAG_COPY:
1884 10 : if (dest_has_wcard) {
1885 : /* No wildcards. */
1886 0 : status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1887 : } else {
1888 10 : status = copy_internals(ctx, conn, req,
1889 : smb_fname_old,
1890 : smb_fname_new,
1891 : attrs);
1892 : }
1893 8 : break;
1894 10 : case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1895 10 : status = NT_STATUS_INVALID_PARAMETER;
1896 10 : break;
1897 20470 : default:
1898 20470 : status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1899 20470 : break;
1900 : }
1901 :
1902 20575 : if (!NT_STATUS_IS_OK(status)) {
1903 20528 : if (open_was_deferred(req->xconn, req->mid)) {
1904 : /* We have re-scheduled this call. */
1905 4 : goto out;
1906 : }
1907 20524 : if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
1908 18 : bool ok = defer_smb1_sharing_violation(req);
1909 18 : if (ok) {
1910 8 : goto out;
1911 : }
1912 : }
1913 :
1914 20515 : reply_nterror(req, status);
1915 20515 : goto out;
1916 : }
1917 :
1918 47 : reply_outbuf(req, 0, 0);
1919 20589 : out:
1920 20588 : END_PROFILE(SMBntrename);
1921 20588 : return;
1922 : }
1923 :
1924 : /****************************************************************************
1925 : Reply to a notify change - queue the request and
1926 : don't allow a directory to be opened.
1927 : ****************************************************************************/
1928 :
1929 1048 : static void smbd_smb1_notify_reply(struct smb_request *req,
1930 : NTSTATUS error_code,
1931 : uint8_t *buf, size_t len)
1932 : {
1933 1048 : send_nt_replies(req->conn, req, error_code, (char *)buf, len, NULL, 0);
1934 1048 : }
1935 :
1936 1050 : static void call_nt_transact_notify_change(connection_struct *conn,
1937 : struct smb_request *req,
1938 : uint16_t **ppsetup,
1939 : uint32_t setup_count,
1940 : char **ppparams,
1941 : uint32_t parameter_count,
1942 : char **ppdata, uint32_t data_count,
1943 : uint32_t max_data_count,
1944 : uint32_t max_param_count)
1945 : {
1946 1050 : uint16_t *setup = *ppsetup;
1947 : files_struct *fsp;
1948 : uint32_t filter;
1949 : NTSTATUS status;
1950 : bool recursive;
1951 :
1952 1050 : if(setup_count < 6) {
1953 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1954 0 : return;
1955 : }
1956 :
1957 1050 : fsp = file_fsp(req, SVAL(setup,4));
1958 1050 : filter = IVAL(setup, 0);
1959 1050 : recursive = (SVAL(setup, 6) != 0) ? True : False;
1960 :
1961 1050 : DEBUG(3,("call_nt_transact_notify_change\n"));
1962 :
1963 1050 : if(!fsp) {
1964 0 : reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1965 0 : return;
1966 : }
1967 :
1968 : {
1969 : char *filter_string;
1970 :
1971 1050 : if (!(filter_string = notify_filter_string(NULL, filter))) {
1972 0 : reply_nterror(req,NT_STATUS_NO_MEMORY);
1973 0 : return;
1974 : }
1975 :
1976 1050 : DEBUG(3,("call_nt_transact_notify_change: notify change "
1977 : "called on %s, filter = %s, recursive = %d\n",
1978 : fsp_str_dbg(fsp), filter_string, recursive));
1979 :
1980 1050 : TALLOC_FREE(filter_string);
1981 : }
1982 :
1983 1050 : if((!fsp->fsp_flags.is_directory) || (conn != fsp->conn)) {
1984 2 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1985 2 : return;
1986 : }
1987 :
1988 1048 : if (fsp->notify == NULL) {
1989 :
1990 962 : status = change_notify_create(fsp,
1991 : max_param_count,
1992 : filter,
1993 : recursive);
1994 962 : if (!NT_STATUS_IS_OK(status)) {
1995 0 : DEBUG(10, ("change_notify_create returned %s\n",
1996 : nt_errstr(status)));
1997 0 : reply_nterror(req, status);
1998 0 : return;
1999 : }
2000 : }
2001 :
2002 1048 : if (change_notify_fsp_has_changes(fsp)) {
2003 :
2004 : /*
2005 : * We've got changes pending, respond immediately
2006 : */
2007 :
2008 : /*
2009 : * TODO: write a torture test to check the filtering behaviour
2010 : * here.
2011 : */
2012 :
2013 108 : change_notify_reply(req,
2014 54 : NT_STATUS_OK,
2015 : max_param_count,
2016 : fsp->notify,
2017 : smbd_smb1_notify_reply);
2018 :
2019 : /*
2020 : * change_notify_reply() above has independently sent its
2021 : * results
2022 : */
2023 54 : return;
2024 : }
2025 :
2026 : /*
2027 : * No changes pending, queue the request
2028 : */
2029 :
2030 994 : status = change_notify_add_request(req,
2031 : max_param_count,
2032 : filter,
2033 : recursive, fsp,
2034 : smbd_smb1_notify_reply);
2035 994 : if (!NT_STATUS_IS_OK(status)) {
2036 0 : reply_nterror(req, status);
2037 : }
2038 994 : return;
2039 : }
2040 :
2041 : /****************************************************************************
2042 : Reply to an NT transact rename command.
2043 : ****************************************************************************/
2044 :
2045 10 : static void call_nt_transact_rename(connection_struct *conn,
2046 : struct smb_request *req,
2047 : uint16_t **ppsetup, uint32_t setup_count,
2048 : char **ppparams, uint32_t parameter_count,
2049 : char **ppdata, uint32_t data_count,
2050 : uint32_t max_data_count)
2051 : {
2052 10 : char *params = *ppparams;
2053 10 : char *new_name = NULL;
2054 10 : files_struct *fsp = NULL;
2055 : NTSTATUS status;
2056 10 : TALLOC_CTX *ctx = talloc_tos();
2057 :
2058 10 : if(parameter_count < 5) {
2059 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2060 0 : return;
2061 : }
2062 :
2063 10 : fsp = file_fsp(req, SVAL(params, 0));
2064 10 : if (!check_fsp(conn, req, fsp)) {
2065 4 : return;
2066 : }
2067 5 : if (req->posix_pathnames) {
2068 0 : srvstr_get_path_posix(ctx,
2069 : params,
2070 0 : req->flags2,
2071 : &new_name,
2072 0 : params+4,
2073 0 : parameter_count - 4,
2074 : STR_TERMINATE,
2075 : &status);
2076 : } else {
2077 9 : srvstr_get_path(ctx,
2078 : params,
2079 5 : req->flags2,
2080 : &new_name,
2081 5 : params+4,
2082 5 : parameter_count - 4,
2083 : STR_TERMINATE,
2084 : &status);
2085 : }
2086 :
2087 5 : if (!NT_STATUS_IS_OK(status)) {
2088 0 : reply_nterror(req, status);
2089 0 : return;
2090 : }
2091 :
2092 : /*
2093 : * W2K3 ignores this request as the RAW-RENAME test
2094 : * demonstrates, so we do.
2095 : */
2096 5 : send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
2097 :
2098 5 : DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
2099 : fsp_str_dbg(fsp), new_name));
2100 :
2101 4 : return;
2102 : }
2103 :
2104 : /******************************************************************************
2105 : Fake up a completely empty SD.
2106 : *******************************************************************************/
2107 :
2108 12 : static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, struct security_descriptor **ppsd)
2109 : {
2110 : size_t sd_size;
2111 :
2112 12 : *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
2113 12 : if(!*ppsd) {
2114 0 : DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
2115 0 : return NT_STATUS_NO_MEMORY;
2116 : }
2117 :
2118 12 : return NT_STATUS_OK;
2119 : }
2120 :
2121 : /****************************************************************************
2122 : Reply to query a security descriptor.
2123 : Callable from SMB1 and SMB2.
2124 : If it returns NT_STATUS_BUFFER_TOO_SMALL, pdata_size is initialized with
2125 : the required size.
2126 : ****************************************************************************/
2127 :
2128 14407 : NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
2129 : TALLOC_CTX *mem_ctx,
2130 : files_struct *fsp,
2131 : uint32_t security_info_wanted,
2132 : uint32_t max_data_count,
2133 : uint8_t **ppmarshalled_sd,
2134 : size_t *psd_size)
2135 : {
2136 : NTSTATUS status;
2137 14407 : struct security_descriptor *psd = NULL;
2138 14407 : TALLOC_CTX *frame = talloc_stackframe();
2139 14407 : bool need_to_read_sd = false;
2140 :
2141 : /*
2142 : * Get the permissions to return.
2143 : */
2144 :
2145 14724 : if ((security_info_wanted & SECINFO_SACL) &&
2146 338 : !(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
2147 0 : DEBUG(10, ("Access to SACL denied.\n"));
2148 0 : TALLOC_FREE(frame);
2149 0 : return NT_STATUS_ACCESS_DENIED;
2150 : }
2151 :
2152 27228 : if ((security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|SECINFO_GROUP)) &&
2153 14393 : !(fsp->access_mask & SEC_STD_READ_CONTROL)) {
2154 14 : DEBUG(10, ("Access to DACL, OWNER, or GROUP denied.\n"));
2155 14 : TALLOC_FREE(frame);
2156 14 : return NT_STATUS_ACCESS_DENIED;
2157 : }
2158 :
2159 14393 : status = refuse_symlink_fsp(fsp);
2160 14393 : if (!NT_STATUS_IS_OK(status)) {
2161 0 : DBG_DEBUG("ACL get on symlink %s denied.\n",
2162 : fsp_str_dbg(fsp));
2163 0 : TALLOC_FREE(frame);
2164 0 : return status;
2165 : }
2166 :
2167 14393 : if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|
2168 : SECINFO_GROUP|SECINFO_SACL)) {
2169 : /* Don't return SECINFO_LABEL if anything else was
2170 : requested. See bug #8458. */
2171 14381 : security_info_wanted &= ~SECINFO_LABEL;
2172 :
2173 : /*
2174 : * Only query the file system SD if the caller asks
2175 : * for any bits. This allows a caller to open without
2176 : * READ_CONTROL but still issue a query sd. See
2177 : * smb2.sdread test.
2178 : */
2179 14381 : need_to_read_sd = true;
2180 : }
2181 :
2182 27214 : if (lp_nt_acl_support(SNUM(conn)) &&
2183 27214 : ((security_info_wanted & SECINFO_LABEL) == 0) &&
2184 : need_to_read_sd)
2185 14381 : {
2186 14381 : files_struct *sd_fsp = fsp;
2187 14381 : if (fsp->base_fsp != NULL) {
2188 : /*
2189 : * This is a stream handle. Use
2190 : * the underlying pathref handle.
2191 : */
2192 4 : sd_fsp = fsp->base_fsp;
2193 : }
2194 14381 : status = SMB_VFS_FGET_NT_ACL(
2195 : sd_fsp, security_info_wanted, frame, &psd);
2196 : } else {
2197 12 : status = get_null_nt_acl(frame, &psd);
2198 : }
2199 :
2200 14393 : if (!NT_STATUS_IS_OK(status)) {
2201 0 : TALLOC_FREE(frame);
2202 0 : return status;
2203 : }
2204 :
2205 14393 : if (!(security_info_wanted & SECINFO_OWNER)) {
2206 1270 : psd->owner_sid = NULL;
2207 : }
2208 14393 : if (!(security_info_wanted & SECINFO_GROUP)) {
2209 10680 : psd->group_sid = NULL;
2210 : }
2211 14393 : if (!(security_info_wanted & SECINFO_DACL)) {
2212 18 : psd->type &= ~SEC_DESC_DACL_PRESENT;
2213 18 : psd->dacl = NULL;
2214 : }
2215 14393 : if (!(security_info_wanted & SECINFO_SACL)) {
2216 14055 : psd->type &= ~SEC_DESC_SACL_PRESENT;
2217 14055 : psd->sacl = NULL;
2218 : }
2219 :
2220 : /* If the SACL/DACL is NULL, but was requested, we mark that it is
2221 : * present in the reply to match Windows behavior */
2222 27212 : if (psd->sacl == NULL &&
2223 14391 : security_info_wanted & SECINFO_SACL)
2224 336 : psd->type |= SEC_DESC_SACL_PRESENT;
2225 14422 : if (psd->dacl == NULL &&
2226 36 : security_info_wanted & SECINFO_DACL)
2227 18 : psd->type |= SEC_DESC_DACL_PRESENT;
2228 :
2229 14393 : if (security_info_wanted & SECINFO_LABEL) {
2230 : /* Like W2K3 return a null object. */
2231 0 : psd->owner_sid = NULL;
2232 0 : psd->group_sid = NULL;
2233 0 : psd->dacl = NULL;
2234 0 : psd->sacl = NULL;
2235 0 : psd->type &= ~(SEC_DESC_DACL_PRESENT|SEC_DESC_SACL_PRESENT);
2236 : }
2237 :
2238 14393 : *psd_size = ndr_size_security_descriptor(psd, 0);
2239 :
2240 14393 : DEBUG(3,("smbd_do_query_security_desc: sd_size = %lu.\n",
2241 : (unsigned long)*psd_size));
2242 :
2243 14393 : if (DEBUGLEVEL >= 10) {
2244 0 : DEBUG(10,("smbd_do_query_security_desc for file %s\n",
2245 : fsp_str_dbg(fsp)));
2246 0 : NDR_PRINT_DEBUG(security_descriptor, psd);
2247 : }
2248 :
2249 14393 : if (max_data_count < *psd_size) {
2250 8 : TALLOC_FREE(frame);
2251 8 : return NT_STATUS_BUFFER_TOO_SMALL;
2252 : }
2253 :
2254 14385 : status = marshall_sec_desc(mem_ctx, psd,
2255 : ppmarshalled_sd, psd_size);
2256 :
2257 14385 : if (!NT_STATUS_IS_OK(status)) {
2258 0 : TALLOC_FREE(frame);
2259 0 : return status;
2260 : }
2261 :
2262 14385 : TALLOC_FREE(frame);
2263 14385 : return NT_STATUS_OK;
2264 : }
2265 :
2266 : /****************************************************************************
2267 : SMB1 reply to query a security descriptor.
2268 : ****************************************************************************/
2269 :
2270 7306 : static void call_nt_transact_query_security_desc(connection_struct *conn,
2271 : struct smb_request *req,
2272 : uint16_t **ppsetup,
2273 : uint32_t setup_count,
2274 : char **ppparams,
2275 : uint32_t parameter_count,
2276 : char **ppdata,
2277 : uint32_t data_count,
2278 : uint32_t max_data_count)
2279 : {
2280 7306 : char *params = *ppparams;
2281 7306 : char *data = *ppdata;
2282 7306 : size_t sd_size = 0;
2283 : uint32_t security_info_wanted;
2284 7306 : files_struct *fsp = NULL;
2285 : NTSTATUS status;
2286 7306 : uint8_t *marshalled_sd = NULL;
2287 :
2288 7306 : if(parameter_count < 8) {
2289 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2290 0 : return;
2291 : }
2292 :
2293 7306 : fsp = file_fsp(req, SVAL(params,0));
2294 7306 : if(!fsp) {
2295 0 : reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2296 0 : return;
2297 : }
2298 :
2299 7306 : security_info_wanted = IVAL(params,4);
2300 :
2301 7306 : DEBUG(3,("call_nt_transact_query_security_desc: file = %s, "
2302 : "info_wanted = 0x%x\n", fsp_str_dbg(fsp),
2303 : (unsigned int)security_info_wanted));
2304 :
2305 7306 : params = nttrans_realloc(ppparams, 4);
2306 7306 : if(params == NULL) {
2307 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
2308 0 : return;
2309 : }
2310 :
2311 : /*
2312 : * Get the permissions to return.
2313 : */
2314 :
2315 7306 : status = smbd_do_query_security_desc(conn,
2316 : talloc_tos(),
2317 : fsp,
2318 : security_info_wanted &
2319 : SMB_SUPPORTED_SECINFO_FLAGS,
2320 : max_data_count,
2321 : &marshalled_sd,
2322 : &sd_size);
2323 :
2324 7306 : if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
2325 0 : SIVAL(params,0,(uint32_t)sd_size);
2326 0 : send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
2327 : params, 4, NULL, 0);
2328 0 : return;
2329 : }
2330 :
2331 7306 : if (!NT_STATUS_IS_OK(status)) {
2332 0 : reply_nterror(req, status);
2333 0 : return;
2334 : }
2335 :
2336 7306 : SMB_ASSERT(sd_size > 0);
2337 :
2338 7306 : SIVAL(params,0,(uint32_t)sd_size);
2339 :
2340 7306 : if (max_data_count < sd_size) {
2341 0 : send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
2342 : params, 4, NULL, 0);
2343 0 : return;
2344 : }
2345 :
2346 : /*
2347 : * Allocate the data we will return.
2348 : */
2349 :
2350 7306 : data = nttrans_realloc(ppdata, sd_size);
2351 7306 : if(data == NULL) {
2352 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
2353 0 : return;
2354 : }
2355 :
2356 7306 : memcpy(data, marshalled_sd, sd_size);
2357 :
2358 7306 : send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
2359 :
2360 7306 : return;
2361 : }
2362 :
2363 : /****************************************************************************
2364 : Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
2365 : ****************************************************************************/
2366 :
2367 6594 : static void call_nt_transact_set_security_desc(connection_struct *conn,
2368 : struct smb_request *req,
2369 : uint16_t **ppsetup,
2370 : uint32_t setup_count,
2371 : char **ppparams,
2372 : uint32_t parameter_count,
2373 : char **ppdata,
2374 : uint32_t data_count,
2375 : uint32_t max_data_count)
2376 : {
2377 6594 : char *params= *ppparams;
2378 6594 : char *data = *ppdata;
2379 6594 : files_struct *fsp = NULL;
2380 6594 : uint32_t security_info_sent = 0;
2381 : NTSTATUS status;
2382 :
2383 6594 : if(parameter_count < 8) {
2384 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2385 0 : return;
2386 : }
2387 :
2388 6594 : if((fsp = file_fsp(req, SVAL(params,0))) == NULL) {
2389 18 : reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2390 18 : return;
2391 : }
2392 :
2393 6576 : if (!CAN_WRITE(fsp->conn)) {
2394 0 : reply_nterror(req, NT_STATUS_ACCESS_DENIED);
2395 0 : return;
2396 : }
2397 :
2398 6576 : if(!lp_nt_acl_support(SNUM(conn))) {
2399 0 : goto done;
2400 : }
2401 :
2402 6576 : security_info_sent = IVAL(params,4);
2403 :
2404 6576 : DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n",
2405 : fsp_str_dbg(fsp), (unsigned int)security_info_sent));
2406 :
2407 6576 : if (data_count == 0) {
2408 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2409 0 : return;
2410 : }
2411 :
2412 6576 : status = set_sd_blob(fsp, (uint8_t *)data, data_count,
2413 : security_info_sent & SMB_SUPPORTED_SECINFO_FLAGS);
2414 6576 : if (!NT_STATUS_IS_OK(status)) {
2415 0 : reply_nterror(req, status);
2416 0 : return;
2417 : }
2418 :
2419 6576 : done:
2420 6576 : send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
2421 6576 : return;
2422 : }
2423 :
2424 : /****************************************************************************
2425 : Reply to NT IOCTL
2426 : ****************************************************************************/
2427 :
2428 1342 : static void call_nt_transact_ioctl(connection_struct *conn,
2429 : struct smb_request *req,
2430 : uint16_t **ppsetup, uint32_t setup_count,
2431 : char **ppparams, uint32_t parameter_count,
2432 : char **ppdata, uint32_t data_count,
2433 : uint32_t max_data_count)
2434 : {
2435 : NTSTATUS status;
2436 : uint32_t function;
2437 : uint16_t fidnum;
2438 : files_struct *fsp;
2439 : uint8_t isFSctl;
2440 : uint8_t compfilter;
2441 1342 : char *out_data = NULL;
2442 1342 : uint32_t out_data_len = 0;
2443 1342 : char *pdata = *ppdata;
2444 1342 : TALLOC_CTX *ctx = talloc_tos();
2445 :
2446 1342 : if (setup_count != 8) {
2447 0 : DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
2448 0 : reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2449 0 : return;
2450 : }
2451 :
2452 1342 : function = IVAL(*ppsetup, 0);
2453 1342 : fidnum = SVAL(*ppsetup, 4);
2454 1342 : isFSctl = CVAL(*ppsetup, 6);
2455 1342 : compfilter = CVAL(*ppsetup, 7);
2456 :
2457 1342 : DEBUG(10, ("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
2458 : function, fidnum, isFSctl, compfilter));
2459 :
2460 1342 : fsp=file_fsp(req, fidnum);
2461 :
2462 : /*
2463 : * We don't really implement IOCTLs, especially on files.
2464 : */
2465 1342 : if (!isFSctl) {
2466 0 : DEBUG(10, ("isFSctl: 0x%02X indicates IOCTL, not FSCTL!\n",
2467 : isFSctl));
2468 0 : reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2469 0 : return;
2470 : }
2471 :
2472 : /* Has to be for an open file! */
2473 1342 : if (!check_fsp_open(conn, req, fsp)) {
2474 0 : return;
2475 : }
2476 :
2477 1342 : SMB_PERFCOUNT_SET_IOCTL(&req->pcd, function);
2478 :
2479 : /*
2480 : * out_data might be allocated by the VFS module, but talloc should be
2481 : * used, and should be cleaned up when the request ends.
2482 : */
2483 1342 : status = SMB_VFS_FSCTL(fsp,
2484 : ctx,
2485 : function,
2486 : req->flags2,
2487 : (uint8_t *)pdata,
2488 : data_count,
2489 : (uint8_t **)&out_data,
2490 : max_data_count,
2491 : &out_data_len);
2492 1342 : if (!NT_STATUS_IS_OK(status)) {
2493 74 : reply_nterror(req, status);
2494 : } else {
2495 1268 : send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, out_data, out_data_len);
2496 : }
2497 : }
2498 :
2499 :
2500 : #ifdef HAVE_SYS_QUOTAS
2501 12 : static enum ndr_err_code fill_qtlist_from_sids(TALLOC_CTX *mem_ctx,
2502 : struct files_struct *fsp,
2503 : SMB_NTQUOTA_HANDLE *qt_handle,
2504 : struct dom_sid *sids,
2505 : uint32_t elems)
2506 : {
2507 : uint32_t i;
2508 12 : TALLOC_CTX *list_ctx = NULL;
2509 :
2510 12 : list_ctx = talloc_init("quota_sid_list");
2511 :
2512 12 : if (list_ctx == NULL) {
2513 0 : DBG_ERR("failed to allocate\n");
2514 0 : return NDR_ERR_ALLOC;
2515 : }
2516 :
2517 12 : if (qt_handle->quota_list!=NULL) {
2518 0 : free_ntquota_list(&(qt_handle->quota_list));
2519 : }
2520 24 : for (i = 0; i < elems; i++) {
2521 : SMB_NTQUOTA_STRUCT qt;
2522 : SMB_NTQUOTA_LIST *list_item;
2523 : bool ok;
2524 :
2525 12 : if (!NT_STATUS_IS_OK(vfs_get_ntquota(fsp,
2526 : SMB_USER_QUOTA_TYPE,
2527 : &sids[i], &qt))) {
2528 : /* non fatal error, return empty item in result */
2529 0 : ZERO_STRUCT(qt);
2530 0 : continue;
2531 : }
2532 :
2533 :
2534 12 : list_item = talloc_zero(list_ctx, SMB_NTQUOTA_LIST);
2535 12 : if (list_item == NULL) {
2536 0 : DBG_ERR("failed to allocate\n");
2537 0 : return NDR_ERR_ALLOC;
2538 : }
2539 :
2540 12 : ok = sid_to_uid(&sids[i], &list_item->uid);
2541 12 : if (!ok) {
2542 : struct dom_sid_buf buf;
2543 0 : DBG_WARNING("Could not convert SID %s to uid\n",
2544 : dom_sid_str_buf(&sids[i], &buf));
2545 : /* No idea what to return here... */
2546 0 : return NDR_ERR_INVALID_POINTER;
2547 : }
2548 :
2549 12 : list_item->quotas = talloc_zero(list_item, SMB_NTQUOTA_STRUCT);
2550 12 : if (list_item->quotas == NULL) {
2551 0 : DBG_ERR("failed to allocate\n");
2552 0 : return NDR_ERR_ALLOC;
2553 : }
2554 :
2555 12 : *list_item->quotas = qt;
2556 12 : list_item->mem_ctx = list_ctx;
2557 12 : DLIST_ADD(qt_handle->quota_list, list_item);
2558 : }
2559 12 : qt_handle->tmp_list = qt_handle->quota_list;
2560 12 : return NDR_ERR_SUCCESS;
2561 : }
2562 :
2563 12 : static enum ndr_err_code extract_sids_from_buf(TALLOC_CTX *mem_ctx,
2564 : uint32_t sidlistlength,
2565 : DATA_BLOB *sid_buf,
2566 : struct dom_sid **sids,
2567 : uint32_t *num)
2568 : {
2569 : DATA_BLOB blob;
2570 12 : uint32_t i = 0;
2571 : enum ndr_err_code err;
2572 :
2573 : struct sid_list_elem {
2574 : struct sid_list_elem *prev, *next;
2575 : struct dom_sid sid;
2576 : };
2577 :
2578 12 : struct sid_list_elem *sid_list = NULL;
2579 12 : struct sid_list_elem *iter = NULL;
2580 12 : TALLOC_CTX *list_ctx = talloc_init("sid_list");
2581 12 : if (!list_ctx) {
2582 0 : DBG_ERR("OOM\n");
2583 0 : err = NDR_ERR_ALLOC;
2584 0 : goto done;
2585 : }
2586 :
2587 12 : *num = 0;
2588 12 : *sids = NULL;
2589 :
2590 12 : if (sidlistlength) {
2591 12 : uint32_t offset = 0;
2592 12 : struct ndr_pull *ndr_pull = NULL;
2593 :
2594 12 : if (sidlistlength > sid_buf->length) {
2595 0 : DBG_ERR("sid_list_length 0x%x exceeds "
2596 : "available bytes %zx\n",
2597 : sidlistlength,
2598 : sid_buf->length);
2599 0 : err = NDR_ERR_OFFSET;
2600 0 : goto done;
2601 : }
2602 0 : while (true) {
2603 : struct file_get_quota_info info;
2604 12 : struct sid_list_elem *item = NULL;
2605 12 : uint32_t new_offset = 0;
2606 12 : blob.data = sid_buf->data + offset;
2607 12 : blob.length = sidlistlength - offset;
2608 12 : ndr_pull = ndr_pull_init_blob(&blob, list_ctx);
2609 12 : if (!ndr_pull) {
2610 0 : DBG_ERR("OOM\n");
2611 0 : err = NDR_ERR_ALLOC;
2612 0 : goto done;
2613 : }
2614 12 : err = ndr_pull_file_get_quota_info(ndr_pull,
2615 : NDR_SCALARS | NDR_BUFFERS, &info);
2616 12 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
2617 0 : DBG_ERR("Failed to pull file_get_quota_info "
2618 : "from sidlist buffer\n");
2619 0 : goto done;
2620 : }
2621 12 : item = talloc_zero(list_ctx, struct sid_list_elem);
2622 12 : if (!item) {
2623 0 : DBG_ERR("OOM\n");
2624 0 : err = NDR_ERR_ALLOC;
2625 0 : goto done;
2626 : }
2627 12 : item->sid = info.sid;
2628 12 : DLIST_ADD(sid_list, item);
2629 12 : i++;
2630 12 : if (i == UINT32_MAX) {
2631 0 : DBG_ERR("Integer overflow\n");
2632 0 : err = NDR_ERR_ARRAY_SIZE;
2633 0 : goto done;
2634 : }
2635 12 : new_offset = info.next_entry_offset;
2636 :
2637 : /* if new_offset == 0 no more sid(s) to read. */
2638 12 : if (new_offset == 0) {
2639 12 : break;
2640 : }
2641 :
2642 : /* Integer wrap? */
2643 0 : if ((offset + new_offset) < offset) {
2644 0 : DBG_ERR("Integer wrap while adding "
2645 : "new_offset 0x%x to current "
2646 : "buffer offset 0x%x\n",
2647 : new_offset, offset);
2648 0 : err = NDR_ERR_OFFSET;
2649 0 : goto done;
2650 : }
2651 :
2652 0 : offset += new_offset;
2653 :
2654 : /* check if new offset is outside buffer boundry. */
2655 0 : if (offset >= sidlistlength) {
2656 0 : DBG_ERR("bufsize 0x%x exceeded by "
2657 : "new offset 0x%x)\n",
2658 : sidlistlength,
2659 : offset);
2660 0 : err = NDR_ERR_OFFSET;
2661 0 : goto done;
2662 : }
2663 : }
2664 12 : *sids = talloc_zero_array(mem_ctx, struct dom_sid, i);
2665 12 : if (*sids == NULL) {
2666 0 : DBG_ERR("OOM\n");
2667 0 : err = NDR_ERR_ALLOC;
2668 0 : goto done;
2669 : }
2670 :
2671 12 : *num = i;
2672 :
2673 24 : for (iter = sid_list, i = 0; iter; iter = iter->next, i++) {
2674 : struct dom_sid_buf buf;
2675 12 : (*sids)[i] = iter->sid;
2676 12 : DBG_DEBUG("quota SID[%u] %s\n",
2677 : (unsigned int)i,
2678 : dom_sid_str_buf(&iter->sid, &buf));
2679 : }
2680 : }
2681 12 : err = NDR_ERR_SUCCESS;
2682 12 : done:
2683 12 : TALLOC_FREE(list_ctx);
2684 12 : return err;
2685 : }
2686 :
2687 20 : NTSTATUS smbd_do_query_getinfo_quota(TALLOC_CTX *mem_ctx,
2688 : files_struct *fsp,
2689 : bool restart_scan,
2690 : bool return_single,
2691 : uint32_t sid_list_length,
2692 : DATA_BLOB *sid_buf,
2693 : uint32_t max_data_count,
2694 : uint8_t **p_data,
2695 : uint32_t *p_data_size)
2696 : {
2697 : NTSTATUS status;
2698 20 : SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2699 20 : SMB_NTQUOTA_LIST *qt_list = NULL;
2700 20 : DATA_BLOB blob = data_blob_null;
2701 : enum ndr_err_code err;
2702 :
2703 20 : qt_handle =
2704 20 : (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->private_data;
2705 :
2706 20 : if (sid_list_length ) {
2707 : struct dom_sid *sids;
2708 12 : uint32_t elems = 0;
2709 : /*
2710 : * error check pulled offsets and lengths for wrap and
2711 : * exceeding available bytes.
2712 : */
2713 12 : if (sid_list_length > sid_buf->length) {
2714 0 : DBG_ERR("sid_list_length 0x%x exceeds "
2715 : "available bytes %zx\n",
2716 : sid_list_length,
2717 : sid_buf->length);
2718 0 : return NT_STATUS_INVALID_PARAMETER;
2719 : }
2720 :
2721 12 : err = extract_sids_from_buf(mem_ctx, sid_list_length,
2722 : sid_buf, &sids, &elems);
2723 12 : if (!NDR_ERR_CODE_IS_SUCCESS(err) || elems == 0) {
2724 0 : return NT_STATUS_INVALID_PARAMETER;
2725 : }
2726 12 : err = fill_qtlist_from_sids(mem_ctx,
2727 : fsp,
2728 : qt_handle,
2729 : sids,
2730 : elems);
2731 12 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
2732 0 : return NT_STATUS_INVALID_PARAMETER;
2733 : }
2734 8 : } else if (restart_scan) {
2735 4 : if (vfs_get_user_ntquota_list(fsp,
2736 : &(qt_handle->quota_list))!=0) {
2737 0 : return NT_STATUS_INTERNAL_ERROR;
2738 : }
2739 : } else {
2740 8 : if (qt_handle->quota_list!=NULL &&
2741 4 : qt_handle->tmp_list==NULL) {
2742 4 : free_ntquota_list(&(qt_handle->quota_list));
2743 : }
2744 : }
2745 :
2746 20 : if (restart_scan !=0 ) {
2747 4 : qt_list = qt_handle->quota_list;
2748 : } else {
2749 16 : qt_list = qt_handle->tmp_list;
2750 : }
2751 20 : status = fill_quota_buffer(mem_ctx, qt_list,
2752 : return_single != 0,
2753 : max_data_count,
2754 : &blob,
2755 : &qt_handle->tmp_list);
2756 20 : if (!NT_STATUS_IS_OK(status)) {
2757 4 : return status;
2758 : }
2759 16 : if (blob.length > max_data_count) {
2760 0 : return NT_STATUS_BUFFER_TOO_SMALL;
2761 : }
2762 :
2763 16 : *p_data = blob.data;
2764 16 : *p_data_size = blob.length;
2765 16 : return NT_STATUS_OK;
2766 : }
2767 :
2768 : /****************************************************************************
2769 : Reply to get user quota
2770 : ****************************************************************************/
2771 :
2772 2 : static void call_nt_transact_get_user_quota(connection_struct *conn,
2773 : struct smb_request *req,
2774 : uint16_t **ppsetup,
2775 : uint32_t setup_count,
2776 : char **ppparams,
2777 : uint32_t parameter_count,
2778 : char **ppdata,
2779 : uint32_t data_count,
2780 : uint32_t max_data_count)
2781 : {
2782 2 : const struct loadparm_substitution *lp_sub =
2783 0 : loadparm_s3_global_substitution();
2784 2 : NTSTATUS nt_status = NT_STATUS_OK;
2785 2 : char *params = *ppparams;
2786 2 : char *pdata = *ppdata;
2787 2 : int data_len = 0;
2788 2 : int param_len = 0;
2789 2 : files_struct *fsp = NULL;
2790 2 : DATA_BLOB blob = data_blob_null;
2791 2 : struct nttrans_query_quota_params info = {0};
2792 : enum ndr_err_code err;
2793 2 : TALLOC_CTX *tmp_ctx = NULL;
2794 2 : uint32_t resp_len = 0;
2795 2 : uint8_t *resp_data = 0;
2796 :
2797 2 : tmp_ctx = talloc_init("ntquota_list");
2798 2 : if (!tmp_ctx) {
2799 0 : nt_status = NT_STATUS_NO_MEMORY;
2800 0 : goto error;
2801 : }
2802 :
2803 : /* access check */
2804 2 : if (get_current_uid(conn) != sec_initial_uid()) {
2805 0 : DEBUG(1,("get_user_quota: access_denied service [%s] user "
2806 : "[%s]\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
2807 : conn->session_info->unix_info->unix_name));
2808 0 : nt_status = NT_STATUS_ACCESS_DENIED;
2809 0 : goto error;
2810 : }
2811 :
2812 2 : blob.data = (uint8_t*)params;
2813 2 : blob.length = parameter_count;
2814 :
2815 2 : err = ndr_pull_struct_blob(&blob, tmp_ctx, &info,
2816 : (ndr_pull_flags_fn_t)ndr_pull_nttrans_query_quota_params);
2817 :
2818 2 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
2819 0 : DEBUG(0,("TRANSACT_GET_USER_QUOTA: failed to pull "
2820 : "query_quota_params."));
2821 0 : nt_status = NT_STATUS_INVALID_PARAMETER;
2822 0 : goto error;
2823 : }
2824 2 : DBG_DEBUG("info.return_single_entry = %u, info.restart_scan = %u, "
2825 : "info.sid_list_length = %u, info.start_sid_length = %u, "
2826 : "info.start_sid_offset = %u\n",
2827 : (unsigned int)info.return_single_entry,
2828 : (unsigned int)info.restart_scan,
2829 : (unsigned int)info.sid_list_length,
2830 : (unsigned int)info.start_sid_length,
2831 : (unsigned int)info.start_sid_offset);
2832 :
2833 : /* set blob to point at data for further parsing */
2834 2 : blob.data = (uint8_t*)pdata;
2835 2 : blob.length = data_count;
2836 : /*
2837 : * Although MS-SMB ref is ambiguous here, a microsoft client will
2838 : * only ever send a start sid (as part of a list) with
2839 : * sid_list_length & start_sid_offset both set to the actual list
2840 : * length. Note: Only a single result is returned in this case
2841 : * In the case where either start_sid_offset or start_sid_length
2842 : * are set alone or if both set (but have different values) then
2843 : * it seems windows will return a number of entries from the start
2844 : * of the list of users with quotas set. This behaviour is undocumented
2845 : * and windows clients do not send messages of that type. As such we
2846 : * currently will reject these requests.
2847 : */
2848 2 : if (info.start_sid_length
2849 2 : || (info.sid_list_length != info.start_sid_offset)) {
2850 0 : DBG_ERR("TRANSACT_GET_USER_QUOTA: unsupported single or "
2851 : "compound sid format\n");
2852 0 : nt_status = NT_STATUS_INVALID_PARAMETER;
2853 0 : goto error;
2854 : }
2855 :
2856 : /* maybe we can check the quota_fnum */
2857 2 : fsp = file_fsp(req, info.fid);
2858 2 : if (!check_fsp_ntquota_handle(conn, req, fsp)) {
2859 0 : DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2860 0 : nt_status = NT_STATUS_INVALID_HANDLE;
2861 0 : goto error;
2862 : }
2863 6 : nt_status = smbd_do_query_getinfo_quota(tmp_ctx,
2864 : fsp,
2865 2 : info.restart_scan,
2866 2 : info.return_single_entry,
2867 : info.sid_list_length,
2868 : &blob,
2869 : max_data_count,
2870 : &resp_data,
2871 : &resp_len);
2872 2 : if (!NT_STATUS_IS_OK(nt_status)) {
2873 0 : if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MORE_ENTRIES)) {
2874 0 : goto error;
2875 : }
2876 0 : nt_status = NT_STATUS_OK;
2877 : }
2878 :
2879 2 : param_len = 4;
2880 2 : params = nttrans_realloc(ppparams, param_len);
2881 2 : if(params == NULL) {
2882 0 : nt_status = NT_STATUS_NO_MEMORY;
2883 0 : goto error;
2884 : }
2885 :
2886 2 : data_len = resp_len;
2887 2 : SIVAL(params, 0, data_len);
2888 2 : pdata = nttrans_realloc(ppdata, data_len);
2889 2 : memcpy(pdata, resp_data, data_len);
2890 :
2891 2 : TALLOC_FREE(tmp_ctx);
2892 2 : send_nt_replies(conn, req, nt_status, params, param_len,
2893 : pdata, data_len);
2894 2 : return;
2895 0 : error:
2896 0 : TALLOC_FREE(tmp_ctx);
2897 0 : reply_nterror(req, nt_status);
2898 : }
2899 :
2900 : /****************************************************************************
2901 : Reply to set user quota
2902 : ****************************************************************************/
2903 :
2904 0 : static void call_nt_transact_set_user_quota(connection_struct *conn,
2905 : struct smb_request *req,
2906 : uint16_t **ppsetup,
2907 : uint32_t setup_count,
2908 : char **ppparams,
2909 : uint32_t parameter_count,
2910 : char **ppdata,
2911 : uint32_t data_count,
2912 : uint32_t max_data_count)
2913 : {
2914 0 : const struct loadparm_substitution *lp_sub =
2915 0 : loadparm_s3_global_substitution();
2916 0 : char *params = *ppparams;
2917 0 : char *pdata = *ppdata;
2918 0 : int data_len=0,param_len=0;
2919 : SMB_NTQUOTA_STRUCT qt;
2920 0 : struct file_quota_information info = {0};
2921 : enum ndr_err_code err;
2922 : struct dom_sid sid;
2923 : DATA_BLOB inblob;
2924 0 : files_struct *fsp = NULL;
2925 0 : TALLOC_CTX *ctx = NULL;
2926 0 : NTSTATUS status = NT_STATUS_OK;
2927 0 : ZERO_STRUCT(qt);
2928 :
2929 : /* access check */
2930 0 : if (get_current_uid(conn) != sec_initial_uid()) {
2931 0 : DEBUG(1,("set_user_quota: access_denied service [%s] user "
2932 : "[%s]\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn)),
2933 : conn->session_info->unix_info->unix_name));
2934 0 : status = NT_STATUS_ACCESS_DENIED;
2935 0 : goto error;
2936 : }
2937 :
2938 : /*
2939 : * Ensure minimum number of parameters sent.
2940 : */
2941 :
2942 0 : if (parameter_count < 2) {
2943 0 : DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
2944 0 : status = NT_STATUS_INVALID_PARAMETER;
2945 0 : goto error;
2946 : }
2947 :
2948 : /* maybe we can check the quota_fnum */
2949 0 : fsp = file_fsp(req, SVAL(params,0));
2950 0 : if (!check_fsp_ntquota_handle(conn, req, fsp)) {
2951 0 : DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2952 0 : status = NT_STATUS_INVALID_HANDLE;
2953 0 : goto error;
2954 : }
2955 :
2956 0 : ctx = talloc_init("set_user_quota");
2957 0 : if (!ctx) {
2958 0 : status = NT_STATUS_NO_MEMORY;
2959 0 : goto error;
2960 : }
2961 0 : inblob.data = (uint8_t*)pdata;
2962 0 : inblob.length = data_count;
2963 :
2964 0 : err = ndr_pull_struct_blob(
2965 : &inblob,
2966 : ctx,
2967 : &info,
2968 : (ndr_pull_flags_fn_t)ndr_pull_file_quota_information);
2969 :
2970 0 : if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
2971 0 : DEBUG(0,("TRANSACT_SET_USER_QUOTA: failed to pull "
2972 : "file_quota_information\n"));
2973 0 : status = NT_STATUS_INVALID_PARAMETER;
2974 0 : goto error;
2975 : }
2976 0 : qt.usedspace = info.quota_used;
2977 :
2978 0 : qt.softlim = info.quota_threshold;
2979 :
2980 0 : qt.hardlim = info.quota_limit;
2981 :
2982 0 : sid = info.sid;
2983 :
2984 0 : if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2985 0 : status = NT_STATUS_INTERNAL_ERROR;
2986 0 : goto error;
2987 : }
2988 :
2989 0 : send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
2990 : pdata, data_len);
2991 0 : TALLOC_FREE(ctx);
2992 0 : return;
2993 0 : error:
2994 0 : TALLOC_FREE(ctx);
2995 0 : reply_nterror(req, status);
2996 : }
2997 : #endif /* HAVE_SYS_QUOTAS */
2998 :
2999 16865 : static void handle_nttrans(connection_struct *conn,
3000 : struct trans_state *state,
3001 : struct smb_request *req)
3002 : {
3003 16865 : if (get_Protocol() >= PROTOCOL_NT1) {
3004 16865 : req->flags2 |= 0x40; /* IS_LONG_NAME */
3005 16865 : SSVAL(discard_const_p(uint8_t, req->inbuf),smb_flg2,req->flags2);
3006 : }
3007 :
3008 :
3009 16865 : SMB_PERFCOUNT_SET_SUBOP(&req->pcd, state->call);
3010 :
3011 : /* Now we must call the relevant NT_TRANS function */
3012 16865 : switch(state->call) {
3013 561 : case NT_TRANSACT_CREATE:
3014 : {
3015 561 : START_PROFILE(NT_transact_create);
3016 1511 : call_nt_transact_create(
3017 : conn, req,
3018 : &state->setup, state->setup_count,
3019 561 : &state->param, state->total_param,
3020 561 : &state->data, state->total_data,
3021 : state->max_data_return);
3022 561 : END_PROFILE(NT_transact_create);
3023 502 : break;
3024 : }
3025 :
3026 1342 : case NT_TRANSACT_IOCTL:
3027 : {
3028 1342 : START_PROFILE(NT_transact_ioctl);
3029 4018 : call_nt_transact_ioctl(
3030 : conn, req,
3031 : &state->setup, state->setup_count,
3032 1342 : &state->param, state->total_param,
3033 1342 : &state->data, state->total_data,
3034 : state->max_data_return);
3035 1342 : END_PROFILE(NT_transact_ioctl);
3036 1338 : break;
3037 : }
3038 :
3039 6594 : case NT_TRANSACT_SET_SECURITY_DESC:
3040 : {
3041 6594 : START_PROFILE(NT_transact_set_security_desc);
3042 18718 : call_nt_transact_set_security_desc(
3043 : conn, req,
3044 : &state->setup, state->setup_count,
3045 6594 : &state->param, state->total_param,
3046 6594 : &state->data, state->total_data,
3047 : state->max_data_return);
3048 6594 : END_PROFILE(NT_transact_set_security_desc);
3049 6594 : break;
3050 : }
3051 :
3052 1050 : case NT_TRANSACT_NOTIFY_CHANGE:
3053 : {
3054 1050 : START_PROFILE(NT_transact_notify_change);
3055 3150 : call_nt_transact_notify_change(
3056 : conn, req,
3057 : &state->setup, state->setup_count,
3058 1050 : &state->param, state->total_param,
3059 1050 : &state->data, state->total_data,
3060 : state->max_data_return,
3061 : state->max_param_return);
3062 1050 : END_PROFILE(NT_transact_notify_change);
3063 1050 : break;
3064 : }
3065 :
3066 10 : case NT_TRANSACT_RENAME:
3067 : {
3068 10 : START_PROFILE(NT_transact_rename);
3069 26 : call_nt_transact_rename(
3070 : conn, req,
3071 : &state->setup, state->setup_count,
3072 10 : &state->param, state->total_param,
3073 10 : &state->data, state->total_data,
3074 : state->max_data_return);
3075 10 : END_PROFILE(NT_transact_rename);
3076 8 : break;
3077 : }
3078 :
3079 7306 : case NT_TRANSACT_QUERY_SECURITY_DESC:
3080 : {
3081 7306 : START_PROFILE(NT_transact_query_security_desc);
3082 20776 : call_nt_transact_query_security_desc(
3083 : conn, req,
3084 : &state->setup, state->setup_count,
3085 7306 : &state->param, state->total_param,
3086 7306 : &state->data, state->total_data,
3087 : state->max_data_return);
3088 7306 : END_PROFILE(NT_transact_query_security_desc);
3089 7306 : break;
3090 : }
3091 :
3092 : #ifdef HAVE_SYS_QUOTAS
3093 2 : case NT_TRANSACT_GET_USER_QUOTA:
3094 : {
3095 2 : START_PROFILE(NT_transact_get_user_quota);
3096 6 : call_nt_transact_get_user_quota(
3097 : conn, req,
3098 : &state->setup, state->setup_count,
3099 2 : &state->param, state->total_param,
3100 2 : &state->data, state->total_data,
3101 : state->max_data_return);
3102 2 : END_PROFILE(NT_transact_get_user_quota);
3103 2 : break;
3104 : }
3105 :
3106 0 : case NT_TRANSACT_SET_USER_QUOTA:
3107 : {
3108 0 : START_PROFILE(NT_transact_set_user_quota);
3109 0 : call_nt_transact_set_user_quota(
3110 : conn, req,
3111 : &state->setup, state->setup_count,
3112 0 : &state->param, state->total_param,
3113 0 : &state->data, state->total_data,
3114 : state->max_data_return);
3115 0 : END_PROFILE(NT_transact_set_user_quota);
3116 0 : break;
3117 : }
3118 : #endif /* HAVE_SYS_QUOTAS */
3119 :
3120 0 : default:
3121 : /* Error in request */
3122 0 : DEBUG(0,("handle_nttrans: Unknown request %d in "
3123 : "nttrans call\n", state->call));
3124 0 : reply_nterror(req, NT_STATUS_INVALID_LEVEL);
3125 0 : return;
3126 : }
3127 16800 : return;
3128 : }
3129 :
3130 : /****************************************************************************
3131 : Reply to a SMBNTtrans.
3132 : ****************************************************************************/
3133 :
3134 16865 : void reply_nttrans(struct smb_request *req)
3135 : {
3136 16865 : connection_struct *conn = req->conn;
3137 : uint32_t pscnt;
3138 : uint32_t psoff;
3139 : uint32_t dscnt;
3140 : uint32_t dsoff;
3141 : uint16_t function_code;
3142 : NTSTATUS result;
3143 : struct trans_state *state;
3144 :
3145 16865 : START_PROFILE(SMBnttrans);
3146 :
3147 16865 : if (req->wct < 19) {
3148 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3149 0 : END_PROFILE(SMBnttrans);
3150 0 : return;
3151 : }
3152 :
3153 16865 : pscnt = IVAL(req->vwv+9, 1);
3154 16865 : psoff = IVAL(req->vwv+11, 1);
3155 16865 : dscnt = IVAL(req->vwv+13, 1);
3156 16865 : dsoff = IVAL(req->vwv+15, 1);
3157 16865 : function_code = SVAL(req->vwv+18, 0);
3158 :
3159 16865 : if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
3160 0 : reply_nterror(req, NT_STATUS_ACCESS_DENIED);
3161 0 : END_PROFILE(SMBnttrans);
3162 0 : return;
3163 : }
3164 :
3165 16865 : result = allow_new_trans(conn->pending_trans, req->mid);
3166 16865 : if (!NT_STATUS_IS_OK(result)) {
3167 0 : DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
3168 0 : reply_nterror(req, result);
3169 0 : END_PROFILE(SMBnttrans);
3170 0 : return;
3171 : }
3172 :
3173 16865 : if ((state = talloc(conn, struct trans_state)) == NULL) {
3174 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
3175 0 : END_PROFILE(SMBnttrans);
3176 0 : return;
3177 : }
3178 :
3179 16865 : state->cmd = SMBnttrans;
3180 :
3181 16865 : state->mid = req->mid;
3182 16865 : state->vuid = req->vuid;
3183 16865 : state->total_data = IVAL(req->vwv+3, 1);
3184 16865 : state->data = NULL;
3185 16865 : state->total_param = IVAL(req->vwv+1, 1);
3186 16865 : state->param = NULL;
3187 16865 : state->max_data_return = IVAL(req->vwv+7, 1);
3188 16865 : state->max_param_return = IVAL(req->vwv+5, 1);
3189 :
3190 : /* setup count is in *words* */
3191 16865 : state->setup_count = 2*CVAL(req->vwv+17, 1);
3192 16865 : state->setup = NULL;
3193 16865 : state->call = function_code;
3194 :
3195 16865 : DEBUG(10, ("num_setup=%u, "
3196 : "param_total=%u, this_param=%u, max_param=%u, "
3197 : "data_total=%u, this_data=%u, max_data=%u, "
3198 : "param_offset=%u, data_offset=%u\n",
3199 : (unsigned)state->setup_count,
3200 : (unsigned)state->total_param, (unsigned)pscnt,
3201 : (unsigned)state->max_param_return,
3202 : (unsigned)state->total_data, (unsigned)dscnt,
3203 : (unsigned)state->max_data_return,
3204 : (unsigned)psoff, (unsigned)dsoff));
3205 :
3206 : /*
3207 : * All nttrans messages we handle have smb_wct == 19 +
3208 : * state->setup_count. Ensure this is so as a sanity check.
3209 : */
3210 :
3211 16865 : if(req->wct != 19 + (state->setup_count/2)) {
3212 0 : DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
3213 : req->wct, 19 + (state->setup_count/2)));
3214 0 : goto bad_param;
3215 : }
3216 :
3217 : /* Don't allow more than 128mb for each value. */
3218 32535 : if ((state->total_data > (1024*1024*128)) ||
3219 16865 : (state->total_param > (1024*1024*128))) {
3220 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
3221 0 : END_PROFILE(SMBnttrans);
3222 0 : return;
3223 : }
3224 :
3225 16865 : if ((dscnt > state->total_data) || (pscnt > state->total_param))
3226 0 : goto bad_param;
3227 :
3228 16865 : if (state->total_data) {
3229 :
3230 6789 : if (trans_oob(state->total_data, 0, dscnt)
3231 6789 : || trans_oob(smb_len(req->inbuf), dsoff, dscnt)) {
3232 0 : goto bad_param;
3233 : }
3234 :
3235 : /* Can't use talloc here, the core routines do realloc on the
3236 : * params and data. */
3237 6789 : if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
3238 0 : DEBUG(0,("reply_nttrans: data malloc fail for %u "
3239 : "bytes !\n", (unsigned int)state->total_data));
3240 0 : TALLOC_FREE(state);
3241 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
3242 0 : END_PROFILE(SMBnttrans);
3243 0 : return;
3244 : }
3245 :
3246 6789 : memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
3247 : }
3248 :
3249 16865 : if (state->total_param) {
3250 :
3251 14473 : if (trans_oob(state->total_param, 0, pscnt)
3252 14473 : || trans_oob(smb_len(req->inbuf), psoff, pscnt)) {
3253 0 : goto bad_param;
3254 : }
3255 :
3256 : /* Can't use talloc here, the core routines do realloc on the
3257 : * params and data. */
3258 14473 : if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
3259 0 : DEBUG(0,("reply_nttrans: param malloc fail for %u "
3260 : "bytes !\n", (unsigned int)state->total_param));
3261 0 : SAFE_FREE(state->data);
3262 0 : TALLOC_FREE(state);
3263 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
3264 0 : END_PROFILE(SMBnttrans);
3265 0 : return;
3266 : }
3267 :
3268 14473 : memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
3269 : }
3270 :
3271 16865 : state->received_data = dscnt;
3272 16865 : state->received_param = pscnt;
3273 :
3274 16865 : if(state->setup_count > 0) {
3275 2394 : DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
3276 : state->setup_count));
3277 :
3278 : /*
3279 : * No overflow possible here, state->setup_count is an
3280 : * unsigned int, being filled by a single byte from
3281 : * CVAL(req->vwv+13, 0) above. The cast in the comparison
3282 : * below is not necessary, it's here to clarify things. The
3283 : * validity of req->vwv and req->wct has been checked in
3284 : * init_smb_request already.
3285 : */
3286 2394 : if ((state->setup_count/2) + 19 > (unsigned int)req->wct) {
3287 0 : goto bad_param;
3288 : }
3289 :
3290 2394 : state->setup = (uint16_t *)TALLOC(state, state->setup_count);
3291 2394 : if (state->setup == NULL) {
3292 0 : DEBUG(0,("reply_nttrans : Out of memory\n"));
3293 0 : SAFE_FREE(state->data);
3294 0 : SAFE_FREE(state->param);
3295 0 : TALLOC_FREE(state);
3296 0 : reply_nterror(req, NT_STATUS_NO_MEMORY);
3297 0 : END_PROFILE(SMBnttrans);
3298 0 : return;
3299 : }
3300 :
3301 2398 : memcpy(state->setup, req->vwv+19, state->setup_count);
3302 2394 : dump_data(10, (uint8_t *)state->setup, state->setup_count);
3303 : }
3304 :
3305 32535 : if ((state->received_data == state->total_data) &&
3306 16865 : (state->received_param == state->total_param)) {
3307 16865 : handle_nttrans(conn, state, req);
3308 16865 : SAFE_FREE(state->param);
3309 16865 : SAFE_FREE(state->data);
3310 16865 : TALLOC_FREE(state);
3311 16865 : END_PROFILE(SMBnttrans);
3312 16800 : return;
3313 : }
3314 :
3315 0 : DLIST_ADD(conn->pending_trans, state);
3316 :
3317 : /* We need to send an interim response then receive the rest
3318 : of the parameter/data bytes */
3319 0 : reply_outbuf(req, 0, 0);
3320 0 : show_msg((char *)req->outbuf);
3321 0 : END_PROFILE(SMBnttrans);
3322 0 : return;
3323 :
3324 0 : bad_param:
3325 :
3326 0 : DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
3327 0 : SAFE_FREE(state->data);
3328 0 : SAFE_FREE(state->param);
3329 0 : TALLOC_FREE(state);
3330 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3331 0 : END_PROFILE(SMBnttrans);
3332 0 : return;
3333 : }
3334 :
3335 : /****************************************************************************
3336 : Reply to a SMBnttranss
3337 : ****************************************************************************/
3338 :
3339 0 : void reply_nttranss(struct smb_request *req)
3340 : {
3341 0 : connection_struct *conn = req->conn;
3342 : uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
3343 : struct trans_state *state;
3344 :
3345 0 : START_PROFILE(SMBnttranss);
3346 :
3347 0 : show_msg((const char *)req->inbuf);
3348 :
3349 : /* Windows clients expect all replies to
3350 : an NT transact secondary (SMBnttranss 0xA1)
3351 : to have a command code of NT transact
3352 : (SMBnttrans 0xA0). See bug #8989 for details. */
3353 0 : req->cmd = SMBnttrans;
3354 :
3355 0 : if (req->wct < 18) {
3356 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3357 0 : END_PROFILE(SMBnttranss);
3358 0 : return;
3359 : }
3360 :
3361 0 : for (state = conn->pending_trans; state != NULL;
3362 0 : state = state->next) {
3363 0 : if (state->mid == req->mid) {
3364 0 : break;
3365 : }
3366 : }
3367 :
3368 0 : if ((state == NULL) || (state->cmd != SMBnttrans)) {
3369 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3370 0 : END_PROFILE(SMBnttranss);
3371 0 : return;
3372 : }
3373 :
3374 : /* Revise state->total_param and state->total_data in case they have
3375 : changed downwards */
3376 0 : if (IVAL(req->vwv+1, 1) < state->total_param) {
3377 0 : state->total_param = IVAL(req->vwv+1, 1);
3378 : }
3379 0 : if (IVAL(req->vwv+3, 1) < state->total_data) {
3380 0 : state->total_data = IVAL(req->vwv+3, 1);
3381 : }
3382 :
3383 0 : pcnt = IVAL(req->vwv+5, 1);
3384 0 : poff = IVAL(req->vwv+7, 1);
3385 0 : pdisp = IVAL(req->vwv+9, 1);
3386 :
3387 0 : dcnt = IVAL(req->vwv+11, 1);
3388 0 : doff = IVAL(req->vwv+13, 1);
3389 0 : ddisp = IVAL(req->vwv+15, 1);
3390 :
3391 0 : state->received_param += pcnt;
3392 0 : state->received_data += dcnt;
3393 :
3394 0 : if ((state->received_data > state->total_data) ||
3395 0 : (state->received_param > state->total_param))
3396 0 : goto bad_param;
3397 :
3398 0 : if (pcnt) {
3399 0 : if (trans_oob(state->total_param, pdisp, pcnt)
3400 0 : || trans_oob(smb_len(req->inbuf), poff, pcnt)) {
3401 0 : goto bad_param;
3402 : }
3403 0 : memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,pcnt);
3404 : }
3405 :
3406 0 : if (dcnt) {
3407 0 : if (trans_oob(state->total_data, ddisp, dcnt)
3408 0 : || trans_oob(smb_len(req->inbuf), doff, dcnt)) {
3409 0 : goto bad_param;
3410 : }
3411 0 : memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,dcnt);
3412 : }
3413 :
3414 0 : if ((state->received_param < state->total_param) ||
3415 0 : (state->received_data < state->total_data)) {
3416 0 : END_PROFILE(SMBnttranss);
3417 0 : return;
3418 : }
3419 :
3420 0 : handle_nttrans(conn, state, req);
3421 :
3422 0 : DLIST_REMOVE(conn->pending_trans, state);
3423 0 : SAFE_FREE(state->data);
3424 0 : SAFE_FREE(state->param);
3425 0 : TALLOC_FREE(state);
3426 0 : END_PROFILE(SMBnttranss);
3427 0 : return;
3428 :
3429 0 : bad_param:
3430 :
3431 0 : DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
3432 0 : DLIST_REMOVE(conn->pending_trans, state);
3433 0 : SAFE_FREE(state->data);
3434 0 : SAFE_FREE(state->param);
3435 0 : TALLOC_FREE(state);
3436 0 : reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
3437 0 : END_PROFILE(SMBnttranss);
3438 0 : return;
3439 : }
|