source: branches/samba-3.2.x/source/smbd/nttrans.c@ 204

Last change on this file since 204 was 204, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 branch to 3.2.4

File size: 75.9 KB
Line 
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
23extern int max_send;
24extern enum protocol_types Protocol;
25extern struct current_user current_user;
26
27static const char *known_nt_pipes[] = {
28 "\\LANMAN",
29 "\\srvsvc",
30 "\\samr",
31 "\\wkssvc",
32 "\\NETLOGON",
33 "\\ntlsa",
34 "\\ntsvcs",
35 "\\lsass",
36 "\\lsarpc",
37 "\\winreg",
38 "\\initshutdown",
39 "\\spoolss",
40 "\\netdfs",
41 "\\rpcecho",
42 "\\svcctl",
43 "\\eventlog",
44 "\\unixinfo",
45 NULL
46};
47
48static char *nttrans_realloc(char **ptr, size_t size)
49{
50 if (ptr==NULL) {
51 smb_panic("nttrans_realloc() called with NULL ptr");
52 }
53
54 *ptr = (char *)SMB_REALLOC(*ptr, size);
55 if(*ptr == NULL) {
56 return NULL;
57 }
58 memset(*ptr,'\0',size);
59 return *ptr;
60}
61
62/****************************************************************************
63 Send the required number of replies back.
64 We assume all fields other than the data fields are
65 set correctly for the type of call.
66 HACK ! Always assumes smb_setup field is zero.
67****************************************************************************/
68
69void send_nt_replies(connection_struct *conn,
70 struct smb_request *req, NTSTATUS nt_error,
71 char *params, int paramsize,
72 char *pdata, int datasize)
73{
74 int data_to_send = datasize;
75 int params_to_send = paramsize;
76 int useable_space;
77 char *pp = params;
78 char *pd = pdata;
79 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
80 int alignment_offset = 3;
81 int data_alignment_offset = 0;
82
83 /*
84 * If there genuinely are no parameters or data to send just send
85 * the empty packet.
86 */
87
88 if(params_to_send == 0 && data_to_send == 0) {
89 reply_outbuf(req, 18, 0);
90 show_msg((char *)req->outbuf);
91 return;
92 }
93
94 /*
95 * When sending params and data ensure that both are nicely aligned.
96 * Only do this alignment when there is also data to send - else
97 * can cause NT redirector problems.
98 */
99
100 if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
101 data_alignment_offset = 4 - (params_to_send % 4);
102 }
103
104 /*
105 * Space is bufsize minus Netbios over TCP header minus SMB header.
106 * The alignment_offset is to align the param bytes on a four byte
107 * boundary (2 bytes for data len, one byte pad).
108 * NT needs this to work correctly.
109 */
110
111 useable_space = max_send - (smb_size
112 + 2 * 18 /* wct */
113 + alignment_offset
114 + data_alignment_offset);
115
116 if (useable_space < 0) {
117 DEBUG(0, ("send_nt_replies failed sanity useable_space "
118 "= %d!!!", useable_space));
119 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
120 }
121
122 while (params_to_send || data_to_send) {
123
124 /*
125 * Calculate whether we will totally or partially fill this packet.
126 */
127
128 total_sent_thistime = params_to_send + data_to_send;
129
130 /*
131 * We can never send more than useable_space.
132 */
133
134 total_sent_thistime = MIN(total_sent_thistime, useable_space);
135
136 reply_outbuf(req, 18,
137 total_sent_thistime + alignment_offset
138 + data_alignment_offset);
139
140 /*
141 * Set total params and data to be sent.
142 */
143
144 SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
145 SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
146
147 /*
148 * Calculate how many parameters and data we can fit into
149 * this packet. Parameters get precedence.
150 */
151
152 params_sent_thistime = MIN(params_to_send,useable_space);
153 data_sent_thistime = useable_space - params_sent_thistime;
154 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
155
156 SIVAL(req->outbuf, smb_ntr_ParameterCount,
157 params_sent_thistime);
158
159 if(params_sent_thistime == 0) {
160 SIVAL(req->outbuf,smb_ntr_ParameterOffset,0);
161 SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
162 } else {
163 /*
164 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
165 * parameter bytes, however the first 4 bytes of outbuf are
166 * the Netbios over TCP header. Thus use smb_base() to subtract
167 * them from the calculation.
168 */
169
170 SIVAL(req->outbuf,smb_ntr_ParameterOffset,
171 ((smb_buf(req->outbuf)+alignment_offset)
172 - smb_base(req->outbuf)));
173 /*
174 * Absolute displacement of param bytes sent in this packet.
175 */
176
177 SIVAL(req->outbuf, smb_ntr_ParameterDisplacement,
178 pp - params);
179 }
180
181 /*
182 * Deal with the data portion.
183 */
184
185 SIVAL(req->outbuf, smb_ntr_DataCount, data_sent_thistime);
186
187 if(data_sent_thistime == 0) {
188 SIVAL(req->outbuf,smb_ntr_DataOffset,0);
189 SIVAL(req->outbuf,smb_ntr_DataDisplacement, 0);
190 } else {
191 /*
192 * The offset of the data bytes is the offset of the
193 * parameter bytes plus the number of parameters being sent this time.
194 */
195
196 SIVAL(req->outbuf, smb_ntr_DataOffset,
197 ((smb_buf(req->outbuf)+alignment_offset) -
198 smb_base(req->outbuf))
199 + params_sent_thistime + data_alignment_offset);
200 SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
201 }
202
203 /*
204 * Copy the param bytes into the packet.
205 */
206
207 if(params_sent_thistime) {
208 if (alignment_offset != 0) {
209 memset(smb_buf(req->outbuf), 0,
210 alignment_offset);
211 }
212 memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
213 params_sent_thistime);
214 }
215
216 /*
217 * Copy in the data bytes
218 */
219
220 if(data_sent_thistime) {
221 if (data_alignment_offset != 0) {
222 memset((smb_buf(req->outbuf)+alignment_offset+
223 params_sent_thistime), 0,
224 data_alignment_offset);
225 }
226 memcpy(smb_buf(req->outbuf)+alignment_offset
227 +params_sent_thistime+data_alignment_offset,
228 pd,data_sent_thistime);
229 }
230
231 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
232 params_sent_thistime, data_sent_thistime, useable_space));
233 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
234 params_to_send, data_to_send, paramsize, datasize));
235
236 if (NT_STATUS_V(nt_error)) {
237 error_packet_set((char *)req->outbuf,
238 0, 0, nt_error,
239 __LINE__,__FILE__);
240 }
241
242 /* Send the packet */
243 show_msg((char *)req->outbuf);
244 if (!srv_send_smb(smbd_server_fd(),
245 (char *)req->outbuf,
246 IS_CONN_ENCRYPTED(conn))) {
247 exit_server_cleanly("send_nt_replies: srv_send_smb failed.");
248 }
249
250 TALLOC_FREE(req->outbuf);
251
252 pp += params_sent_thistime;
253 pd += data_sent_thistime;
254
255 params_to_send -= params_sent_thistime;
256 data_to_send -= data_sent_thistime;
257
258 /*
259 * Sanity check
260 */
261
262 if(params_to_send < 0 || data_to_send < 0) {
263 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
264 params_to_send, data_to_send));
265 exit_server_cleanly("send_nt_replies: internal error");
266 }
267 }
268}
269
270/****************************************************************************
271 Is it an NTFS stream name ?
272 An NTFS file name is <path>.<extention>:<stream name>:<stream type>
273 $DATA can be used as both a stream name and a stream type. A missing stream
274 name or type implies $DATA.
275****************************************************************************/
276
277bool is_ntfs_stream_name(const char *fname)
278{
279 if (lp_posix_pathnames()) {
280 return False;
281 }
282 return (strchr_m(fname, ':') != NULL) ? True : False;
283}
284
285/****************************************************************************
286 Reply to an NT create and X call on a pipe
287****************************************************************************/
288
289static void nt_open_pipe(char *fname, connection_struct *conn,
290 struct smb_request *req, int *ppnum)
291{
292 smb_np_struct *p = NULL;
293 int i;
294
295 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
296
297 /* See if it is one we want to handle. */
298
299 if (lp_disable_spoolss() && strequal(fname, "\\spoolss")) {
300 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
301 ERRDOS, ERRbadpipe);
302 return;
303 }
304
305 for( i = 0; known_nt_pipes[i]; i++ ) {
306 if( strequal(fname,known_nt_pipes[i])) {
307 break;
308 }
309 }
310
311 if ( known_nt_pipes[i] == NULL ) {
312 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
313 ERRDOS, ERRbadpipe);
314 return;
315 }
316
317 /* Strip \\ off the name. */
318 fname++;
319
320 DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
321
322 p = open_rpc_pipe_p(fname, conn, req->vuid);
323 if (!p) {
324 reply_doserror(req, ERRSRV, ERRnofids);
325 return;
326 }
327
328 /* TODO: Add pipe to db */
329
330 if ( !store_pipe_opendb( p ) ) {
331 DEBUG(3,("nt_open_pipe: failed to store %s pipe open.\n", fname));
332 }
333
334 *ppnum = p->pnum;
335 return;
336}
337
338/****************************************************************************
339 Reply to an NT create and X call for pipes.
340****************************************************************************/
341
342static void do_ntcreate_pipe_open(connection_struct *conn,
343 struct smb_request *req)
344{
345 char *fname = NULL;
346 int pnum = -1;
347 char *p = NULL;
348 uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags);
349 TALLOC_CTX *ctx = talloc_tos();
350
351 srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname,
352 smb_buf(req->inbuf), STR_TERMINATE);
353
354 if (!fname) {
355 reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
356 ERRDOS, ERRbadpipe);
357 return;
358 }
359 nt_open_pipe(fname, conn, req, &pnum);
360
361 if (req->outbuf) {
362 /* error reply */
363 return;
364 }
365
366 /*
367 * Deal with pipe return.
368 */
369
370 if (flags & EXTENDED_RESPONSE_REQUIRED) {
371 /* This is very strange. We
372 * return 50 words, but only set
373 * the wcnt to 42 ? It's definately
374 * what happens on the wire....
375 */
376 reply_outbuf(req, 50, 0);
377 SCVAL(req->outbuf,smb_wct,42);
378 } else {
379 reply_outbuf(req, 34, 0);
380 }
381
382 p = (char *)req->outbuf + smb_vwv2;
383 p++;
384 SSVAL(p,0,pnum);
385 p += 2;
386 SIVAL(p,0,FILE_WAS_OPENED);
387 p += 4;
388 p += 32;
389 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
390 p += 20;
391 /* File type. */
392 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
393 /* Device state. */
394 SSVAL(p,2, 0x5FF); /* ? */
395 p += 4;
396
397 if (flags & EXTENDED_RESPONSE_REQUIRED) {
398 p += 25;
399 SIVAL(p,0,FILE_GENERIC_ALL);
400 /*
401 * For pipes W2K3 seems to return
402 * 0x12019B next.
403 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
404 */
405 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
406 }
407
408 DEBUG(5,("do_ntcreate_pipe_open: open pipe = %s\n", fname));
409
410 chain_reply(req);
411}
412
413/****************************************************************************
414 Reply to an NT create and X call.
415****************************************************************************/
416
417void reply_ntcreate_and_X(struct smb_request *req)
418{
419 connection_struct *conn = req->conn;
420 char *fname = NULL;
421 uint32 flags;
422 uint32 access_mask;
423 uint32 file_attributes;
424 uint32 share_access;
425 uint32 create_disposition;
426 uint32 create_options;
427 uint16 root_dir_fid;
428 SMB_BIG_UINT allocation_size;
429 /* Breakout the oplock request bits so we can set the
430 reply bits separately. */
431 uint32 fattr=0;
432 SMB_OFF_T file_len = 0;
433 SMB_STRUCT_STAT sbuf;
434 int info = 0;
435 files_struct *fsp = NULL;
436 char *p = NULL;
437 struct timespec c_timespec;
438 struct timespec a_timespec;
439 struct timespec m_timespec;
440 NTSTATUS status;
441 int oplock_request;
442 uint8_t oplock_granted = NO_OPLOCK_RETURN;
443 TALLOC_CTX *ctx = talloc_tos();
444
445 START_PROFILE(SMBntcreateX);
446
447 if (req->wct < 24) {
448 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
449 return;
450 }
451
452 flags = IVAL(req->inbuf,smb_ntcreate_Flags);
453 access_mask = IVAL(req->inbuf,smb_ntcreate_DesiredAccess);
454 file_attributes = IVAL(req->inbuf,smb_ntcreate_FileAttributes);
455 share_access = IVAL(req->inbuf,smb_ntcreate_ShareAccess);
456 create_disposition = IVAL(req->inbuf,smb_ntcreate_CreateDisposition);
457 create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions);
458 root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid);
459
460 allocation_size = (SMB_BIG_UINT)IVAL(req->inbuf,
461 smb_ntcreate_AllocationSize);
462#ifdef LARGE_SMB_OFF_T
463 allocation_size |= (((SMB_BIG_UINT)IVAL(
464 req->inbuf,
465 smb_ntcreate_AllocationSize + 4)) << 32);
466#endif
467
468 srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
469 smb_buf(req->inbuf), 0, STR_TERMINATE, &status);
470
471 if (!NT_STATUS_IS_OK(status)) {
472 reply_nterror(req, status);
473 END_PROFILE(SMBntcreateX);
474 return;
475 }
476
477 DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x "
478 "file_attributes = 0x%x, share_access = 0x%x, "
479 "create_disposition = 0x%x create_options = 0x%x "
480 "root_dir_fid = 0x%x, fname = %s\n",
481 (unsigned int)flags,
482 (unsigned int)access_mask,
483 (unsigned int)file_attributes,
484 (unsigned int)share_access,
485 (unsigned int)create_disposition,
486 (unsigned int)create_options,
487 (unsigned int)root_dir_fid,
488 fname));
489
490 /*
491 * we need to remove ignored bits when they come directly from the client
492 * because we reuse some of them for internal stuff
493 */
494 create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
495
496 /*
497 * If it's an IPC, use the pipe handler.
498 */
499
500 if (IS_IPC(conn)) {
501 if (lp_nt_pipe_support()) {
502 do_ntcreate_pipe_open(conn, req);
503 END_PROFILE(SMBntcreateX);
504 return;
505 }
506 reply_doserror(req, ERRDOS, ERRnoaccess);
507 END_PROFILE(SMBntcreateX);
508 return;
509 }
510
511 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
512 if (oplock_request) {
513 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
514 ? BATCH_OPLOCK : 0;
515 }
516
517 status = create_file(conn, req, root_dir_fid, fname,
518 access_mask, share_access, create_disposition,
519 create_options, file_attributes, oplock_request,
520 allocation_size, NULL, NULL, &fsp, &info, &sbuf);
521
522 if (!NT_STATUS_IS_OK(status)) {
523 if (open_was_deferred(req->mid)) {
524 /* We have re-scheduled this call, no error. */
525 END_PROFILE(SMBntcreateX);
526 return;
527 }
528 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
529 reply_botherror(req, status, ERRDOS, ERRfilexists);
530 }
531 else {
532 reply_nterror(req, status);
533 }
534 END_PROFILE(SMBntcreateX);
535 return;
536 }
537
538 /*
539 * If the caller set the extended oplock request bit
540 * and we granted one (by whatever means) - set the
541 * correct bit for extended oplock reply.
542 */
543
544 if (oplock_request &&
545 (lp_fake_oplocks(SNUM(conn))
546 || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
547
548 /*
549 * Exclusive oplock granted
550 */
551
552 if (flags & REQUEST_BATCH_OPLOCK) {
553 oplock_granted = BATCH_OPLOCK_RETURN;
554 } else {
555 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
556 }
557 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
558 oplock_granted = LEVEL_II_OPLOCK_RETURN;
559 } else {
560 oplock_granted = NO_OPLOCK_RETURN;
561 }
562
563 file_len = sbuf.st_size;
564 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
565 if (fattr == 0) {
566 fattr = FILE_ATTRIBUTE_NORMAL;
567 }
568
569 if (flags & EXTENDED_RESPONSE_REQUIRED) {
570 /* This is very strange. We
571 * return 50 words, but only set
572 * the wcnt to 42 ? It's definately
573 * what happens on the wire....
574 */
575 reply_outbuf(req, 50, 0);
576 SCVAL(req->outbuf,smb_wct,42);
577 } else {
578 reply_outbuf(req, 34, 0);
579 }
580
581 p = (char *)req->outbuf + smb_vwv2;
582
583 SCVAL(p, 0, oplock_granted);
584
585 p++;
586 SSVAL(p,0,fsp->fnum);
587 p += 2;
588 if ((create_disposition == FILE_SUPERSEDE)
589 && (info == FILE_WAS_OVERWRITTEN)) {
590 SIVAL(p,0,FILE_WAS_SUPERSEDED);
591 } else {
592 SIVAL(p,0,info);
593 }
594 p += 4;
595
596 /* Create time. */
597 c_timespec = get_create_timespec(
598 &sbuf,lp_fake_dir_create_times(SNUM(conn)));
599 a_timespec = get_atimespec(&sbuf);
600 m_timespec = get_mtimespec(&sbuf);
601
602 if (lp_dos_filetime_resolution(SNUM(conn))) {
603 dos_filetime_timespec(&c_timespec);
604 dos_filetime_timespec(&a_timespec);
605 dos_filetime_timespec(&m_timespec);
606 }
607
608 put_long_date_timespec(p, c_timespec); /* create time. */
609 p += 8;
610 put_long_date_timespec(p, a_timespec); /* access time */
611 p += 8;
612 put_long_date_timespec(p, m_timespec); /* write time */
613 p += 8;
614 put_long_date_timespec(p, m_timespec); /* change time */
615 p += 8;
616 SIVAL(p,0,fattr); /* File Attributes. */
617 p += 4;
618 SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
619 p += 8;
620 SOFF_T(p,0,file_len);
621 p += 8;
622 if (flags & EXTENDED_RESPONSE_REQUIRED) {
623 SSVAL(p,2,0x7);
624 }
625 p += 4;
626 SCVAL(p,0,fsp->is_directory ? 1 : 0);
627
628 if (flags & EXTENDED_RESPONSE_REQUIRED) {
629 uint32 perms = 0;
630 p += 25;
631 if (fsp->is_directory
632 || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
633 perms = FILE_GENERIC_ALL;
634 } else {
635 perms = FILE_GENERIC_READ|FILE_EXECUTE;
636 }
637 SIVAL(p,0,perms);
638 }
639
640 DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n",
641 fsp->fnum, fsp->fsp_name));
642
643 chain_reply(req);
644 END_PROFILE(SMBntcreateX);
645 return;
646}
647
648/****************************************************************************
649 Reply to a NT_TRANSACT_CREATE call to open a pipe.
650****************************************************************************/
651
652static void do_nt_transact_create_pipe(connection_struct *conn,
653 struct smb_request *req,
654 uint16 **ppsetup, uint32 setup_count,
655 char **ppparams, uint32 parameter_count,
656 char **ppdata, uint32 data_count)
657{
658 char *fname = NULL;
659 char *params = *ppparams;
660 int pnum = -1;
661 char *p = NULL;
662 NTSTATUS status;
663 size_t param_len;
664 uint32 flags;
665 TALLOC_CTX *ctx = talloc_tos();
666
667 /*
668 * Ensure minimum number of parameters sent.
669 */
670
671 if(parameter_count < 54) {
672 DEBUG(0,("do_nt_transact_create_pipe - insufficient parameters (%u)\n", (unsigned int)parameter_count));
673 reply_doserror(req, ERRDOS, ERRnoaccess);
674 return;
675 }
676
677 flags = IVAL(params,0);
678
679 srvstr_get_path(ctx, params, req->flags2, &fname, params+53,
680 parameter_count-53, STR_TERMINATE,
681 &status);
682 if (!NT_STATUS_IS_OK(status)) {
683 reply_nterror(req, status);
684 return;
685 }
686
687 nt_open_pipe(fname, conn, req, &pnum);
688
689 if (req->outbuf) {
690 /* Error return */
691 return;
692 }
693
694 /* Realloc the size of parameters and data we will return */
695 if (flags & EXTENDED_RESPONSE_REQUIRED) {
696 /* Extended response is 32 more byyes. */
697 param_len = 101;
698 } else {
699 param_len = 69;
700 }
701 params = nttrans_realloc(ppparams, param_len);
702 if(params == NULL) {
703 reply_doserror(req, ERRDOS, ERRnomem);
704 return;
705 }
706
707 p = params;
708 SCVAL(p,0,NO_OPLOCK_RETURN);
709
710 p += 2;
711 SSVAL(p,0,pnum);
712 p += 2;
713 SIVAL(p,0,FILE_WAS_OPENED);
714 p += 8;
715
716 p += 32;
717 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
718 p += 20;
719 /* File type. */
720 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
721 /* Device state. */
722 SSVAL(p,2, 0x5FF); /* ? */
723 p += 4;
724
725 if (flags & EXTENDED_RESPONSE_REQUIRED) {
726 p += 25;
727 SIVAL(p,0,FILE_GENERIC_ALL);
728 /*
729 * For pipes W2K3 seems to return
730 * 0x12019B next.
731 * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
732 */
733 SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
734 }
735
736 DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
737
738 /* Send the required number of replies */
739 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
740
741 return;
742}
743
744/****************************************************************************
745 Internal fn to set security descriptors.
746****************************************************************************/
747
748static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
749 uint32 security_info_sent)
750{
751 SEC_DESC *psd = NULL;
752 NTSTATUS status;
753
754 if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
755 return NT_STATUS_OK;
756 }
757
758 status = unmarshall_sec_desc(talloc_tos(), data, sd_len, &psd);
759
760 if (!NT_STATUS_IS_OK(status)) {
761 return status;
762 }
763
764 if (psd->owner_sid==0) {
765 security_info_sent &= ~OWNER_SECURITY_INFORMATION;
766 }
767 if (psd->group_sid==0) {
768 security_info_sent &= ~GROUP_SECURITY_INFORMATION;
769 }
770 if (psd->sacl==0) {
771 security_info_sent &= ~SACL_SECURITY_INFORMATION;
772 }
773 if (psd->dacl==0) {
774 security_info_sent &= ~DACL_SECURITY_INFORMATION;
775 }
776
777 if (fsp->fh->fd != -1) {
778 status = SMB_VFS_FSET_NT_ACL(fsp, security_info_sent, psd);
779 }
780 else {
781 status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name,
782 security_info_sent, psd);
783 }
784
785 TALLOC_FREE(psd);
786
787 return status;
788}
789
790/****************************************************************************
791 Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
792****************************************************************************/
793
794static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
795{
796 struct ea_list *ea_list_head = NULL;
797 size_t offset = 0;
798
799 if (data_size < 4) {
800 return NULL;
801 }
802
803 while (offset + 4 <= data_size) {
804 size_t next_offset = IVAL(pdata,offset);
805 struct ea_list *eal = read_ea_list_entry(ctx, pdata + offset + 4, data_size - offset - 4, NULL);
806
807 if (!eal) {
808 return NULL;
809 }
810
811 DLIST_ADD_END(ea_list_head, eal, struct ea_list *);
812 if (next_offset == 0) {
813 break;
814 }
815 offset += next_offset;
816 }
817
818 return ea_list_head;
819}
820
821/****************************************************************************
822 Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
823****************************************************************************/
824
825static void call_nt_transact_create(connection_struct *conn,
826 struct smb_request *req,
827 uint16 **ppsetup, uint32 setup_count,
828 char **ppparams, uint32 parameter_count,
829 char **ppdata, uint32 data_count,
830 uint32 max_data_count)
831{
832 char *fname = NULL;
833 char *params = *ppparams;
834 char *data = *ppdata;
835 /* Breakout the oplock request bits so we can set the reply bits separately. */
836 uint32 fattr=0;
837 SMB_OFF_T file_len = 0;
838 SMB_STRUCT_STAT sbuf;
839 int info = 0;
840 files_struct *fsp = NULL;
841 char *p = NULL;
842 uint32 flags;
843 uint32 access_mask;
844 uint32 file_attributes;
845 uint32 share_access;
846 uint32 create_disposition;
847 uint32 create_options;
848 uint32 sd_len;
849 struct security_descriptor *sd = NULL;
850 uint32 ea_len;
851 uint16 root_dir_fid;
852 struct timespec c_timespec;
853 struct timespec a_timespec;
854 struct timespec m_timespec;
855 struct ea_list *ea_list = NULL;
856 NTSTATUS status;
857 size_t param_len;
858 SMB_BIG_UINT allocation_size;
859 int oplock_request;
860 uint8_t oplock_granted;
861 TALLOC_CTX *ctx = talloc_tos();
862
863 DEBUG(5,("call_nt_transact_create\n"));
864
865 /*
866 * If it's an IPC, use the pipe handler.
867 */
868
869 if (IS_IPC(conn)) {
870 if (lp_nt_pipe_support()) {
871 do_nt_transact_create_pipe(
872 conn, req,
873 ppsetup, setup_count,
874 ppparams, parameter_count,
875 ppdata, data_count);
876 return;
877 }
878 reply_doserror(req, ERRDOS, ERRnoaccess);
879 return;
880 }
881
882 /*
883 * Ensure minimum number of parameters sent.
884 */
885
886 if(parameter_count < 54) {
887 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)parameter_count));
888 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
889 return;
890 }
891
892 flags = IVAL(params,0);
893 access_mask = IVAL(params,8);
894 file_attributes = IVAL(params,20);
895 share_access = IVAL(params,24);
896 create_disposition = IVAL(params,28);
897 create_options = IVAL(params,32);
898 sd_len = IVAL(params,36);
899 ea_len = IVAL(params,40);
900 root_dir_fid = (uint16)IVAL(params,4);
901 allocation_size = (SMB_BIG_UINT)IVAL(params,12);
902#ifdef LARGE_SMB_OFF_T
903 allocation_size |= (((SMB_BIG_UINT)IVAL(params,16)) << 32);
904#endif
905
906 /*
907 * we need to remove ignored bits when they come directly from the client
908 * because we reuse some of them for internal stuff
909 */
910 create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
911
912 /* Ensure the data_len is correct for the sd and ea values given. */
913 if ((ea_len + sd_len > data_count)
914 || (ea_len > data_count) || (sd_len > data_count)
915 || (ea_len + sd_len < ea_len) || (ea_len + sd_len < sd_len)) {
916 DEBUG(10, ("call_nt_transact_create - ea_len = %u, sd_len = "
917 "%u, data_count = %u\n", (unsigned int)ea_len,
918 (unsigned int)sd_len, (unsigned int)data_count));
919 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
920 return;
921 }
922
923 if (sd_len) {
924 DEBUG(10, ("call_nt_transact_create - sd_len = %d\n",
925 sd_len));
926
927 status = unmarshall_sec_desc(ctx, (uint8_t *)data, sd_len,
928 &sd);
929 if (!NT_STATUS_IS_OK(status)) {
930 DEBUG(10, ("call_nt_transact_create: "
931 "unmarshall_sec_desc failed: %s\n",
932 nt_errstr(status)));
933 reply_nterror(req, status);
934 return;
935 }
936 }
937
938 if (ea_len) {
939 if (!lp_ea_support(SNUM(conn))) {
940 DEBUG(10, ("call_nt_transact_create - ea_len = %u but "
941 "EA's not supported.\n",
942 (unsigned int)ea_len));
943 reply_nterror(req, NT_STATUS_EAS_NOT_SUPPORTED);
944 return;
945 }
946
947 if (ea_len < 10) {
948 DEBUG(10,("call_nt_transact_create - ea_len = %u - "
949 "too small (should be more than 10)\n",
950 (unsigned int)ea_len ));
951 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
952 return;
953 }
954
955 /* We have already checked that ea_len <= data_count here. */
956 ea_list = read_nttrans_ea_list(talloc_tos(), data + sd_len,
957 ea_len);
958 if (ea_list == NULL) {
959 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
960 return;
961 }
962 }
963
964 srvstr_get_path(ctx, params, req->flags2, &fname,
965 params+53, parameter_count-53,
966 STR_TERMINATE, &status);
967 if (!NT_STATUS_IS_OK(status)) {
968 reply_nterror(req, status);
969 return;
970 }
971
972 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
973 if (oplock_request) {
974 oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
975 ? BATCH_OPLOCK : 0;
976 }
977
978 status = create_file(conn, req, root_dir_fid, fname,
979 access_mask, share_access, create_disposition,
980 create_options, file_attributes, oplock_request,
981 allocation_size, sd, ea_list, &fsp, &info, &sbuf);
982
983 if(!NT_STATUS_IS_OK(status)) {
984 if (open_was_deferred(req->mid)) {
985 /* We have re-scheduled this call, no error. */
986 return;
987 }
988 reply_openerror(req, status);
989 return;
990 }
991
992 /*
993 * If the caller set the extended oplock request bit
994 * and we granted one (by whatever means) - set the
995 * correct bit for extended oplock reply.
996 */
997
998 if (oplock_request &&
999 (lp_fake_oplocks(SNUM(conn))
1000 || EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))) {
1001
1002 /*
1003 * Exclusive oplock granted
1004 */
1005
1006 if (flags & REQUEST_BATCH_OPLOCK) {
1007 oplock_granted = BATCH_OPLOCK_RETURN;
1008 } else {
1009 oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
1010 }
1011 } else if (fsp->oplock_type == LEVEL_II_OPLOCK) {
1012 oplock_granted = LEVEL_II_OPLOCK_RETURN;
1013 } else {
1014 oplock_granted = NO_OPLOCK_RETURN;
1015 }
1016
1017 file_len = sbuf.st_size;
1018 fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
1019 if (fattr == 0) {
1020 fattr = FILE_ATTRIBUTE_NORMAL;
1021 }
1022
1023 /* Realloc the size of parameters and data we will return */
1024 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1025 /* Extended response is 32 more byyes. */
1026 param_len = 101;
1027 } else {
1028 param_len = 69;
1029 }
1030 params = nttrans_realloc(ppparams, param_len);
1031 if(params == NULL) {
1032 reply_doserror(req, ERRDOS, ERRnomem);
1033 return;
1034 }
1035
1036 p = params;
1037 SCVAL(p, 0, oplock_granted);
1038
1039 p += 2;
1040 SSVAL(p,0,fsp->fnum);
1041 p += 2;
1042 if ((create_disposition == FILE_SUPERSEDE)
1043 && (info == FILE_WAS_OVERWRITTEN)) {
1044 SIVAL(p,0,FILE_WAS_SUPERSEDED);
1045 } else {
1046 SIVAL(p,0,info);
1047 }
1048 p += 8;
1049
1050 /* Create time. */
1051 c_timespec = get_create_timespec(
1052 &sbuf,lp_fake_dir_create_times(SNUM(conn)));
1053 a_timespec = get_atimespec(&sbuf);
1054 m_timespec = get_mtimespec(&sbuf);
1055
1056 if (lp_dos_filetime_resolution(SNUM(conn))) {
1057 dos_filetime_timespec(&c_timespec);
1058 dos_filetime_timespec(&a_timespec);
1059 dos_filetime_timespec(&m_timespec);
1060 }
1061
1062 put_long_date_timespec(p, c_timespec); /* create time. */
1063 p += 8;
1064 put_long_date_timespec(p, a_timespec); /* access time */
1065 p += 8;
1066 put_long_date_timespec(p, m_timespec); /* write time */
1067 p += 8;
1068 put_long_date_timespec(p, m_timespec); /* change time */
1069 p += 8;
1070 SIVAL(p,0,fattr); /* File Attributes. */
1071 p += 4;
1072 SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
1073 p += 8;
1074 SOFF_T(p,0,file_len);
1075 p += 8;
1076 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1077 SSVAL(p,2,0x7);
1078 }
1079 p += 4;
1080 SCVAL(p,0,fsp->is_directory ? 1 : 0);
1081
1082 if (flags & EXTENDED_RESPONSE_REQUIRED) {
1083 uint32 perms = 0;
1084 p += 25;
1085 if (fsp->is_directory
1086 || can_write_to_file(conn, fsp->fsp_name, &sbuf)) {
1087 perms = FILE_GENERIC_ALL;
1088 } else {
1089 perms = FILE_GENERIC_READ|FILE_EXECUTE;
1090 }
1091 SIVAL(p,0,perms);
1092 }
1093
1094 DEBUG(5,("call_nt_transact_create: open name = %s\n", fsp->fsp_name));
1095
1096 /* Send the required number of replies */
1097 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
1098
1099 return;
1100}
1101
1102/****************************************************************************
1103 Reply to a NT CANCEL request.
1104 conn POINTER CAN BE NULL HERE !
1105****************************************************************************/
1106
1107void reply_ntcancel(struct smb_request *req)
1108{
1109 /*
1110 * Go through and cancel any pending change notifies.
1111 */
1112
1113 START_PROFILE(SMBntcancel);
1114 remove_pending_change_notify_requests_by_mid(req->mid);
1115 remove_pending_lock_requests_by_mid(req->mid);
1116 srv_cancel_sign_response(req->mid);
1117
1118 DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
1119
1120 END_PROFILE(SMBntcancel);
1121 return;
1122}
1123
1124/****************************************************************************
1125 Copy a file.
1126****************************************************************************/
1127
1128static NTSTATUS copy_internals(TALLOC_CTX *ctx,
1129 connection_struct *conn,
1130 struct smb_request *req,
1131 const char *oldname_in,
1132 const char *newname_in,
1133 uint32 attrs)
1134{
1135 SMB_STRUCT_STAT sbuf1, sbuf2;
1136 char *oldname = NULL;
1137 char *newname = NULL;
1138 char *last_component_oldname = NULL;
1139 char *last_component_newname = NULL;
1140 files_struct *fsp1,*fsp2;
1141 uint32 fattr;
1142 int info;
1143 SMB_OFF_T ret=-1;
1144 NTSTATUS status = NT_STATUS_OK;
1145
1146 ZERO_STRUCT(sbuf1);
1147 ZERO_STRUCT(sbuf2);
1148
1149 if (!CAN_WRITE(conn)) {
1150 return NT_STATUS_MEDIA_WRITE_PROTECTED;
1151 }
1152
1153 status = unix_convert(ctx, conn, oldname_in, False, &oldname,
1154 &last_component_oldname, &sbuf1);
1155 if (!NT_STATUS_IS_OK(status)) {
1156 return status;
1157 }
1158
1159 status = check_name(conn, oldname);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 return status;
1162 }
1163
1164 /* Source must already exist. */
1165 if (!VALID_STAT(sbuf1)) {
1166 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1167 }
1168 /* Ensure attributes match. */
1169 fattr = dos_mode(conn,oldname,&sbuf1);
1170 if ((fattr & ~attrs) & (aHIDDEN | aSYSTEM)) {
1171 return NT_STATUS_NO_SUCH_FILE;
1172 }
1173
1174 status = unix_convert(ctx, conn, newname_in, False, &newname,
1175 &last_component_newname, &sbuf2);
1176 if (!NT_STATUS_IS_OK(status)) {
1177 return status;
1178 }
1179
1180 status = check_name(conn, newname);
1181 if (!NT_STATUS_IS_OK(status)) {
1182 return status;
1183 }
1184
1185 /* Disallow if newname already exists. */
1186 if (VALID_STAT(sbuf2)) {
1187 return NT_STATUS_OBJECT_NAME_COLLISION;
1188 }
1189
1190 /* No links from a directory. */
1191 if (S_ISDIR(sbuf1.st_mode)) {
1192 return NT_STATUS_FILE_IS_A_DIRECTORY;
1193 }
1194
1195 /* Ensure this is within the share. */
1196 status = check_reduced_name(conn, oldname);
1197 if (!NT_STATUS_IS_OK(status)) {
1198 return status;
1199 }
1200
1201 DEBUG(10,("copy_internals: doing file copy %s to %s\n",
1202 oldname, newname));
1203
1204 status = open_file_ntcreate(conn, req, oldname, &sbuf1,
1205 FILE_READ_DATA, /* Read-only. */
1206 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1207 FILE_OPEN,
1208 0, /* No create options. */
1209 FILE_ATTRIBUTE_NORMAL,
1210 NO_OPLOCK,
1211 &info, &fsp1);
1212
1213 if (!NT_STATUS_IS_OK(status)) {
1214 return status;
1215 }
1216
1217 status = open_file_ntcreate(conn, req, newname, &sbuf2,
1218 FILE_WRITE_DATA, /* Read-only. */
1219 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1220 FILE_CREATE,
1221 0, /* No create options. */
1222 fattr,
1223 NO_OPLOCK,
1224 &info, &fsp2);
1225
1226 if (!NT_STATUS_IS_OK(status)) {
1227 close_file(fsp1,ERROR_CLOSE);
1228 return status;
1229 }
1230
1231 if (sbuf1.st_size) {
1232 ret = vfs_transfer_file(fsp1, fsp2, sbuf1.st_size);
1233 }
1234
1235 /*
1236 * As we are opening fsp1 read-only we only expect
1237 * an error on close on fsp2 if we are out of space.
1238 * Thus we don't look at the error return from the
1239 * close of fsp1.
1240 */
1241 close_file(fsp1,NORMAL_CLOSE);
1242
1243 /* Ensure the modtime is set correctly on the destination file. */
1244 set_close_write_time(fsp2, get_mtimespec(&sbuf1));
1245
1246 status = close_file(fsp2,NORMAL_CLOSE);
1247
1248 /* Grrr. We have to do this as open_file_ntcreate adds aARCH when it
1249 creates the file. This isn't the correct thing to do in the copy
1250 case. JRA */
1251 file_set_dosmode(conn, newname, fattr, &sbuf2,
1252 parent_dirname(newname),false);
1253
1254 if (ret < (SMB_OFF_T)sbuf1.st_size) {
1255 return NT_STATUS_DISK_FULL;
1256 }
1257
1258 if (!NT_STATUS_IS_OK(status)) {
1259 DEBUG(3,("copy_internals: Error %s copy file %s to %s\n",
1260 nt_errstr(status), oldname, newname));
1261 }
1262 return status;
1263}
1264
1265/****************************************************************************
1266 Reply to a NT rename request.
1267****************************************************************************/
1268
1269void reply_ntrename(struct smb_request *req)
1270{
1271 connection_struct *conn = req->conn;
1272 char *oldname = NULL;
1273 char *newname = NULL;
1274 char *p;
1275 NTSTATUS status;
1276 bool src_has_wcard = False;
1277 bool dest_has_wcard = False;
1278 uint32 attrs;
1279 uint16 rename_type;
1280 TALLOC_CTX *ctx = talloc_tos();
1281
1282 START_PROFILE(SMBntrename);
1283
1284 if (req->wct < 4) {
1285 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1286 END_PROFILE(SMBntrename);
1287 return;
1288 }
1289
1290 attrs = SVAL(req->inbuf,smb_vwv0);
1291 rename_type = SVAL(req->inbuf,smb_vwv1);
1292
1293 p = smb_buf(req->inbuf) + 1;
1294 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p,
1295 0, STR_TERMINATE, &status,
1296 &src_has_wcard);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 reply_nterror(req, status);
1299 END_PROFILE(SMBntrename);
1300 return;
1301 }
1302
1303 if( is_ntfs_stream_name(oldname)) {
1304 /* Can't rename a stream. */
1305 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1306 END_PROFILE(SMBntrename);
1307 return;
1308 }
1309
1310 if (ms_has_wild(oldname)) {
1311 reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
1312 END_PROFILE(SMBntrename);
1313 return;
1314 }
1315
1316 p++;
1317 p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
1318 0, STR_TERMINATE, &status,
1319 &dest_has_wcard);
1320 if (!NT_STATUS_IS_OK(status)) {
1321 reply_nterror(req, status);
1322 END_PROFILE(SMBntrename);
1323 return;
1324 }
1325
1326 status = resolve_dfspath(ctx, conn,
1327 req->flags2 & FLAGS2_DFS_PATHNAMES,
1328 oldname,
1329 &oldname);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1332 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1333 ERRSRV, ERRbadpath);
1334 END_PROFILE(SMBntrename);
1335 return;
1336 }
1337 reply_nterror(req, status);
1338 END_PROFILE(SMBntrename);
1339 return;
1340 }
1341
1342 status = resolve_dfspath(ctx, conn,
1343 req->flags2 & FLAGS2_DFS_PATHNAMES,
1344 newname,
1345 &newname);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
1348 reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
1349 ERRSRV, ERRbadpath);
1350 END_PROFILE(SMBntrename);
1351 return;
1352 }
1353 reply_nterror(req, status);
1354 END_PROFILE(SMBntrename);
1355 return;
1356 }
1357
1358 DEBUG(3,("reply_ntrename : %s -> %s\n",oldname,newname));
1359
1360 switch(rename_type) {
1361 case RENAME_FLAG_RENAME:
1362 status = rename_internals(ctx, conn, req, oldname,
1363 newname, attrs, False, src_has_wcard,
1364 dest_has_wcard, DELETE_ACCESS);
1365 break;
1366 case RENAME_FLAG_HARD_LINK:
1367 if (src_has_wcard || dest_has_wcard) {
1368 /* No wildcards. */
1369 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1370 } else {
1371 status = hardlink_internals(ctx,
1372 conn,
1373 oldname,
1374 newname);
1375 }
1376 break;
1377 case RENAME_FLAG_COPY:
1378 if (src_has_wcard || dest_has_wcard) {
1379 /* No wildcards. */
1380 status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
1381 } else {
1382 status = copy_internals(ctx, conn, req, oldname,
1383 newname, attrs);
1384 }
1385 break;
1386 case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
1387 status = NT_STATUS_INVALID_PARAMETER;
1388 break;
1389 default:
1390 status = NT_STATUS_ACCESS_DENIED; /* Default error. */
1391 break;
1392 }
1393
1394 if (!NT_STATUS_IS_OK(status)) {
1395 if (open_was_deferred(req->mid)) {
1396 /* We have re-scheduled this call. */
1397 END_PROFILE(SMBntrename);
1398 return;
1399 }
1400
1401 reply_nterror(req, status);
1402 END_PROFILE(SMBntrename);
1403 return;
1404 }
1405
1406 reply_outbuf(req, 0, 0);
1407
1408 END_PROFILE(SMBntrename);
1409 return;
1410}
1411
1412/****************************************************************************
1413 Reply to a notify change - queue the request and
1414 don't allow a directory to be opened.
1415****************************************************************************/
1416
1417static void call_nt_transact_notify_change(connection_struct *conn,
1418 struct smb_request *req,
1419 uint16 **ppsetup,
1420 uint32 setup_count,
1421 char **ppparams,
1422 uint32 parameter_count,
1423 char **ppdata, uint32 data_count,
1424 uint32 max_data_count,
1425 uint32 max_param_count)
1426{
1427 uint16 *setup = *ppsetup;
1428 files_struct *fsp;
1429 uint32 filter;
1430 NTSTATUS status;
1431 bool recursive;
1432
1433 if(setup_count < 6) {
1434 reply_doserror(req, ERRDOS, ERRbadfunc);
1435 return;
1436 }
1437
1438 fsp = file_fsp(SVAL(setup,4));
1439 filter = IVAL(setup, 0);
1440 recursive = (SVAL(setup, 6) != 0) ? True : False;
1441
1442 DEBUG(3,("call_nt_transact_notify_change\n"));
1443
1444 if(!fsp) {
1445 reply_doserror(req, ERRDOS, ERRbadfid);
1446 return;
1447 }
1448
1449 {
1450 char *filter_string;
1451
1452 if (!(filter_string = notify_filter_string(NULL, filter))) {
1453 reply_nterror(req,NT_STATUS_NO_MEMORY);
1454 return;
1455 }
1456
1457 DEBUG(3,("call_nt_transact_notify_change: notify change "
1458 "called on %s, filter = %s, recursive = %d\n",
1459 fsp->fsp_name, filter_string, recursive));
1460
1461 TALLOC_FREE(filter_string);
1462 }
1463
1464 if((!fsp->is_directory) || (conn != fsp->conn)) {
1465 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1466 return;
1467 }
1468
1469 if (fsp->notify == NULL) {
1470
1471 status = change_notify_create(fsp, filter, recursive);
1472
1473 if (!NT_STATUS_IS_OK(status)) {
1474 DEBUG(10, ("change_notify_create returned %s\n",
1475 nt_errstr(status)));
1476 reply_nterror(req, status);
1477 return;
1478 }
1479 }
1480
1481 if (fsp->notify->num_changes != 0) {
1482
1483 /*
1484 * We've got changes pending, respond immediately
1485 */
1486
1487 /*
1488 * TODO: write a torture test to check the filtering behaviour
1489 * here.
1490 */
1491
1492 change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify);
1493
1494 /*
1495 * change_notify_reply() above has independently sent its
1496 * results
1497 */
1498 return;
1499 }
1500
1501 /*
1502 * No changes pending, queue the request
1503 */
1504
1505 status = change_notify_add_request(req,
1506 max_param_count,
1507 filter,
1508 recursive, fsp);
1509 if (!NT_STATUS_IS_OK(status)) {
1510 reply_nterror(req, status);
1511 }
1512 return;
1513}
1514
1515/****************************************************************************
1516 Reply to an NT transact rename command.
1517****************************************************************************/
1518
1519static void call_nt_transact_rename(connection_struct *conn,
1520 struct smb_request *req,
1521 uint16 **ppsetup, uint32 setup_count,
1522 char **ppparams, uint32 parameter_count,
1523 char **ppdata, uint32 data_count,
1524 uint32 max_data_count)
1525{
1526 char *params = *ppparams;
1527 char *new_name = NULL;
1528 files_struct *fsp = NULL;
1529 bool dest_has_wcard = False;
1530 NTSTATUS status;
1531 TALLOC_CTX *ctx = talloc_tos();
1532
1533 if(parameter_count < 5) {
1534 reply_doserror(req, ERRDOS, ERRbadfunc);
1535 return;
1536 }
1537
1538 fsp = file_fsp(SVAL(params, 0));
1539 if (!check_fsp(conn, req, fsp, &current_user)) {
1540 return;
1541 }
1542 srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4,
1543 parameter_count - 4,
1544 STR_TERMINATE, &status, &dest_has_wcard);
1545 if (!NT_STATUS_IS_OK(status)) {
1546 reply_nterror(req, status);
1547 return;
1548 }
1549
1550 /*
1551 * W2K3 ignores this request as the RAW-RENAME test
1552 * demonstrates, so we do.
1553 */
1554 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
1555
1556 DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
1557 fsp->fsp_name, new_name));
1558
1559 return;
1560}
1561
1562/******************************************************************************
1563 Fake up a completely empty SD.
1564*******************************************************************************/
1565
1566static NTSTATUS get_null_nt_acl(TALLOC_CTX *mem_ctx, SEC_DESC **ppsd)
1567{
1568 size_t sd_size;
1569
1570 *ppsd = make_standard_sec_desc( mem_ctx, &global_sid_World, &global_sid_World, NULL, &sd_size);
1571 if(!*ppsd) {
1572 DEBUG(0,("get_null_nt_acl: Unable to malloc space for security descriptor.\n"));
1573 return NT_STATUS_NO_MEMORY;
1574 }
1575
1576 return NT_STATUS_OK;
1577}
1578
1579/****************************************************************************
1580 Reply to query a security descriptor.
1581****************************************************************************/
1582
1583static void call_nt_transact_query_security_desc(connection_struct *conn,
1584 struct smb_request *req,
1585 uint16 **ppsetup,
1586 uint32 setup_count,
1587 char **ppparams,
1588 uint32 parameter_count,
1589 char **ppdata,
1590 uint32 data_count,
1591 uint32 max_data_count)
1592{
1593 char *params = *ppparams;
1594 char *data = *ppdata;
1595 SEC_DESC *psd = NULL;
1596 size_t sd_size;
1597 uint32 security_info_wanted;
1598 files_struct *fsp = NULL;
1599 NTSTATUS status;
1600 DATA_BLOB blob;
1601
1602 if(parameter_count < 8) {
1603 reply_doserror(req, ERRDOS, ERRbadfunc);
1604 return;
1605 }
1606
1607 fsp = file_fsp(SVAL(params,0));
1608 if(!fsp) {
1609 reply_doserror(req, ERRDOS, ERRbadfid);
1610 return;
1611 }
1612
1613 security_info_wanted = IVAL(params,4);
1614
1615 DEBUG(3,("call_nt_transact_query_security_desc: file = %s, info_wanted = 0x%x\n", fsp->fsp_name,
1616 (unsigned int)security_info_wanted ));
1617
1618 params = nttrans_realloc(ppparams, 4);
1619 if(params == NULL) {
1620 reply_doserror(req, ERRDOS, ERRnomem);
1621 return;
1622 }
1623
1624 /*
1625 * Get the permissions to return.
1626 */
1627
1628 if (!lp_nt_acl_support(SNUM(conn))) {
1629 status = get_null_nt_acl(talloc_tos(), &psd);
1630 } else {
1631 if (fsp->fh->fd != -1) {
1632 status = SMB_VFS_FGET_NT_ACL(
1633 fsp, security_info_wanted, &psd);
1634 }
1635 else {
1636 status = SMB_VFS_GET_NT_ACL(
1637 conn, fsp->fsp_name, security_info_wanted, &psd);
1638 }
1639 }
1640
1641 if (!NT_STATUS_IS_OK(status)) {
1642 reply_nterror(req, status);
1643 return;
1644 }
1645
1646 sd_size = ndr_size_security_descriptor(psd, 0);
1647
1648 DEBUG(3,("call_nt_transact_query_security_desc: sd_size = %lu.\n",(unsigned long)sd_size));
1649
1650 SIVAL(params,0,(uint32)sd_size);
1651
1652 if (max_data_count < sd_size) {
1653 send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
1654 params, 4, *ppdata, 0);
1655 return;
1656 }
1657
1658 /*
1659 * Allocate the data we will point this at.
1660 */
1661
1662 data = nttrans_realloc(ppdata, sd_size);
1663 if(data == NULL) {
1664 reply_doserror(req, ERRDOS, ERRnomem);
1665 return;
1666 }
1667
1668 status = marshall_sec_desc(talloc_tos(), psd,
1669 &blob.data, &blob.length);
1670
1671 if (!NT_STATUS_IS_OK(status)) {
1672 reply_nterror(req, status);
1673 return;
1674 }
1675
1676 SMB_ASSERT(sd_size == blob.length);
1677 memcpy(data, blob.data, sd_size);
1678
1679 send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
1680
1681 return;
1682}
1683
1684/****************************************************************************
1685 Reply to set a security descriptor. Map to UNIX perms or POSIX ACLs.
1686****************************************************************************/
1687
1688static void call_nt_transact_set_security_desc(connection_struct *conn,
1689 struct smb_request *req,
1690 uint16 **ppsetup,
1691 uint32 setup_count,
1692 char **ppparams,
1693 uint32 parameter_count,
1694 char **ppdata,
1695 uint32 data_count,
1696 uint32 max_data_count)
1697{
1698 char *params= *ppparams;
1699 char *data = *ppdata;
1700 files_struct *fsp = NULL;
1701 uint32 security_info_sent = 0;
1702 NTSTATUS status;
1703
1704 if(parameter_count < 8) {
1705 reply_doserror(req, ERRDOS, ERRbadfunc);
1706 return;
1707 }
1708
1709 if((fsp = file_fsp(SVAL(params,0))) == NULL) {
1710 reply_doserror(req, ERRDOS, ERRbadfid);
1711 return;
1712 }
1713
1714 if(!lp_nt_acl_support(SNUM(conn))) {
1715 goto done;
1716 }
1717
1718 security_info_sent = IVAL(params,4);
1719
1720 DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
1721 (unsigned int)security_info_sent ));
1722
1723 if (data_count == 0) {
1724 reply_doserror(req, ERRDOS, ERRnoaccess);
1725 return;
1726 }
1727
1728 status = set_sd(fsp, (uint8 *)data, data_count, security_info_sent);
1729
1730 if (!NT_STATUS_IS_OK(status)) {
1731 reply_nterror(req, status);
1732 return;
1733 }
1734
1735 done:
1736 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
1737 return;
1738}
1739
1740/****************************************************************************
1741 Reply to NT IOCTL
1742****************************************************************************/
1743
1744static void call_nt_transact_ioctl(connection_struct *conn,
1745 struct smb_request *req,
1746 uint16 **ppsetup, uint32 setup_count,
1747 char **ppparams, uint32 parameter_count,
1748 char **ppdata, uint32 data_count,
1749 uint32 max_data_count)
1750{
1751 uint32 function;
1752 uint16 fidnum;
1753 files_struct *fsp;
1754 uint8 isFSctl;
1755 uint8 compfilter;
1756 static bool logged_message;
1757 char *pdata = *ppdata;
1758
1759 if (setup_count != 8) {
1760 DEBUG(3,("call_nt_transact_ioctl: invalid setup count %d\n", setup_count));
1761 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
1762 return;
1763 }
1764
1765 function = IVAL(*ppsetup, 0);
1766 fidnum = SVAL(*ppsetup, 4);
1767 isFSctl = CVAL(*ppsetup, 6);
1768 compfilter = CVAL(*ppsetup, 7);
1769
1770 DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
1771 function, fidnum, isFSctl, compfilter));
1772
1773 fsp=file_fsp(fidnum);
1774 /* this check is done in each implemented function case for now
1775 because I don't want to break anything... --metze
1776 FSP_BELONGS_CONN(fsp,conn);*/
1777
1778 switch (function) {
1779 case FSCTL_SET_SPARSE:
1780 /* pretend this succeeded - tho strictly we should
1781 mark the file sparse (if the local fs supports it)
1782 so we can know if we need to pre-allocate or not */
1783
1784 DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
1785 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
1786 return;
1787
1788 case FSCTL_CREATE_OR_GET_OBJECT_ID:
1789 {
1790 unsigned char objid[16];
1791
1792 /* This should return the object-id on this file.
1793 * I think I'll make this be the inode+dev. JRA.
1794 */
1795
1796 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fidnum));
1797
1798 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
1799 return;
1800 }
1801
1802 data_count = 64;
1803 pdata = nttrans_realloc(ppdata, data_count);
1804 if (pdata == NULL) {
1805 reply_nterror(req, NT_STATUS_NO_MEMORY);
1806 return;
1807 }
1808 push_file_id_16(pdata, &fsp->file_id);
1809 memcpy(pdata+16,create_volume_objectid(conn,objid),16);
1810 push_file_id_16(pdata+32, &fsp->file_id);
1811 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
1812 pdata, data_count);
1813 return;
1814 }
1815
1816 case FSCTL_GET_REPARSE_POINT:
1817 /* pretend this fail - my winXP does it like this
1818 * --metze
1819 */
1820
1821 DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
1822 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
1823 return;
1824
1825 case FSCTL_SET_REPARSE_POINT:
1826 /* pretend this fail - I'm assuming this because of the FSCTL_GET_REPARSE_POINT case.
1827 * --metze
1828 */
1829
1830 DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
1831 reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
1832 return;
1833
1834 case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
1835 {
1836 /*
1837 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1838 * and return their volume names. If max_data_count is 16, then it is just
1839 * asking for the number of volumes and length of the combined names.
1840 *
1841 * pdata is the data allocated by our caller, but that uses
1842 * total_data_count (which is 0 in our case) rather than max_data_count.
1843 * Allocate the correct amount and return the pointer to let
1844 * it be deallocated when we return.
1845 */
1846 SHADOW_COPY_DATA *shadow_data = NULL;
1847 TALLOC_CTX *shadow_mem_ctx = NULL;
1848 bool labels = False;
1849 uint32 labels_data_count = 0;
1850 uint32 i;
1851 char *cur_pdata;
1852
1853 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
1854 return;
1855 }
1856
1857 if (max_data_count < 16) {
1858 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1859 max_data_count));
1860 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1861 return;
1862 }
1863
1864 if (max_data_count > 16) {
1865 labels = True;
1866 }
1867
1868 shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
1869 if (shadow_mem_ctx == NULL) {
1870 DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
1871 reply_nterror(req, NT_STATUS_NO_MEMORY);
1872 return;
1873 }
1874
1875 shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA);
1876 if (shadow_data == NULL) {
1877 DEBUG(0,("TALLOC_ZERO() failed!\n"));
1878 talloc_destroy(shadow_mem_ctx);
1879 reply_nterror(req, NT_STATUS_NO_MEMORY);
1880 return;
1881 }
1882
1883 shadow_data->mem_ctx = shadow_mem_ctx;
1884
1885 /*
1886 * Call the VFS routine to actually do the work.
1887 */
1888 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
1889 talloc_destroy(shadow_data->mem_ctx);
1890 if (errno == ENOSYS) {
1891 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
1892 conn->connectpath));
1893 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
1894 return;
1895 } else {
1896 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
1897 conn->connectpath));
1898 reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
1899 return;
1900 }
1901 }
1902
1903 labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
1904
1905 if (!labels) {
1906 data_count = 16;
1907 } else {
1908 data_count = 12+labels_data_count+4;
1909 }
1910
1911 if (max_data_count<data_count) {
1912 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1913 max_data_count,data_count));
1914 talloc_destroy(shadow_data->mem_ctx);
1915 reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1916 return;
1917 }
1918
1919 pdata = nttrans_realloc(ppdata, data_count);
1920 if (pdata == NULL) {
1921 talloc_destroy(shadow_data->mem_ctx);
1922 reply_nterror(req, NT_STATUS_NO_MEMORY);
1923 return;
1924 }
1925
1926 cur_pdata = pdata;
1927
1928 /* num_volumes 4 bytes */
1929 SIVAL(pdata,0,shadow_data->num_volumes);
1930
1931 if (labels) {
1932 /* num_labels 4 bytes */
1933 SIVAL(pdata,4,shadow_data->num_volumes);
1934 }
1935
1936 /* needed_data_count 4 bytes */
1937 SIVAL(pdata,8,labels_data_count);
1938
1939 cur_pdata+=12;
1940
1941 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1942 shadow_data->num_volumes,fsp->fsp_name));
1943 if (labels && shadow_data->labels) {
1944 for (i=0;i<shadow_data->num_volumes;i++) {
1945 srvstr_push(pdata, req->flags2,
1946 cur_pdata, shadow_data->labels[i],
1947 2*sizeof(SHADOW_COPY_LABEL),
1948 STR_UNICODE|STR_TERMINATE);
1949 cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
1950 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
1951 }
1952 }
1953
1954 talloc_destroy(shadow_data->mem_ctx);
1955
1956 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
1957 pdata, data_count);
1958
1959 return;
1960 }
1961
1962 case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
1963 {
1964 /* pretend this succeeded -
1965 *
1966 * we have to send back a list with all files owned by this SID
1967 *
1968 * but I have to check that --metze
1969 */
1970 DOM_SID sid;
1971 uid_t uid;
1972 size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
1973
1974 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
1975
1976 if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
1977 return;
1978 }
1979
1980 /* unknown 4 bytes: this is not the length of the sid :-( */
1981 /*unknown = IVAL(pdata,0);*/
1982
1983 sid_parse(pdata+4,sid_len,&sid);
1984 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
1985
1986 if (!sid_to_uid(&sid, &uid)) {
1987 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1988 sid_string_dbg(&sid),
1989 (unsigned long)sid_len));
1990 uid = (-1);
1991 }
1992
1993 /* we can take a look at the find source :-)
1994 *
1995 * find ./ -uid $uid -name '*' is what we need here
1996 *
1997 *
1998 * and send 4bytes len and then NULL terminated unicode strings
1999 * for each file
2000 *
2001 * but I don't know how to deal with the paged results
2002 * (maybe we can hang the result anywhere in the fsp struct)
2003 *
2004 * we don't send all files at once
2005 * and at the next we should *not* start from the beginning,
2006 * so we have to cache the result
2007 *
2008 * --metze
2009 */
2010
2011 /* this works for now... */
2012 send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
2013 return;
2014 }
2015 default:
2016 if (!logged_message) {
2017 logged_message = True; /* Only print this once... */
2018 DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
2019 function));
2020 }
2021 }
2022
2023 reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
2024}
2025
2026
2027#ifdef HAVE_SYS_QUOTAS
2028/****************************************************************************
2029 Reply to get user quota
2030****************************************************************************/
2031
2032static void call_nt_transact_get_user_quota(connection_struct *conn,
2033 struct smb_request *req,
2034 uint16 **ppsetup,
2035 uint32 setup_count,
2036 char **ppparams,
2037 uint32 parameter_count,
2038 char **ppdata,
2039 uint32 data_count,
2040 uint32 max_data_count)
2041{
2042 NTSTATUS nt_status = NT_STATUS_OK;
2043 char *params = *ppparams;
2044 char *pdata = *ppdata;
2045 char *entry;
2046 int data_len=0,param_len=0;
2047 int qt_len=0;
2048 int entry_len = 0;
2049 files_struct *fsp = NULL;
2050 uint16 level = 0;
2051 size_t sid_len;
2052 DOM_SID sid;
2053 bool start_enum = True;
2054 SMB_NTQUOTA_STRUCT qt;
2055 SMB_NTQUOTA_LIST *tmp_list;
2056 SMB_NTQUOTA_HANDLE *qt_handle = NULL;
2057
2058 ZERO_STRUCT(qt);
2059
2060 /* access check */
2061 if (current_user.ut.uid != 0) {
2062 DEBUG(1,("get_user_quota: access_denied service [%s] user [%s]\n",
2063 lp_servicename(SNUM(conn)),conn->user));
2064 reply_doserror(req, ERRDOS, ERRnoaccess);
2065 return;
2066 }
2067
2068 /*
2069 * Ensure minimum number of parameters sent.
2070 */
2071
2072 if (parameter_count < 4) {
2073 DEBUG(0,("TRANSACT_GET_USER_QUOTA: requires %d >= 4 bytes parameters\n",parameter_count));
2074 reply_doserror(req, ERRDOS, ERRinvalidparam);
2075 return;
2076 }
2077
2078 /* maybe we can check the quota_fnum */
2079 fsp = file_fsp(SVAL(params,0));
2080 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2081 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2082 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2083 return;
2084 }
2085
2086 /* the NULL pointer checking for fsp->fake_file_handle->pd
2087 * is done by CHECK_NTQUOTA_HANDLE_OK()
2088 */
2089 qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
2090
2091 level = SVAL(params,2);
2092
2093 /* unknown 12 bytes leading in params */
2094
2095 switch (level) {
2096 case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
2097 /* seems that we should continue with the enum here --metze */
2098
2099 if (qt_handle->quota_list!=NULL &&
2100 qt_handle->tmp_list==NULL) {
2101
2102 /* free the list */
2103 free_ntquota_list(&(qt_handle->quota_list));
2104
2105 /* Realloc the size of parameters and data we will return */
2106 param_len = 4;
2107 params = nttrans_realloc(ppparams, param_len);
2108 if(params == NULL) {
2109 reply_doserror(req, ERRDOS, ERRnomem);
2110 return;
2111 }
2112
2113 data_len = 0;
2114 SIVAL(params,0,data_len);
2115
2116 break;
2117 }
2118
2119 start_enum = False;
2120
2121 case TRANSACT_GET_USER_QUOTA_LIST_START:
2122
2123 if (qt_handle->quota_list==NULL &&
2124 qt_handle->tmp_list==NULL) {
2125 start_enum = True;
2126 }
2127
2128 if (start_enum && vfs_get_user_ntquota_list(fsp,&(qt_handle->quota_list))!=0) {
2129 reply_doserror(req, ERRSRV, ERRerror);
2130 return;
2131 }
2132
2133 /* Realloc the size of parameters and data we will return */
2134 param_len = 4;
2135 params = nttrans_realloc(ppparams, param_len);
2136 if(params == NULL) {
2137 reply_doserror(req, ERRDOS, ERRnomem);
2138 return;
2139 }
2140
2141 /* we should not trust the value in max_data_count*/
2142 max_data_count = MIN(max_data_count,2048);
2143
2144 pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
2145 if(pdata == NULL) {
2146 reply_doserror(req, ERRDOS, ERRnomem);
2147 return;
2148 }
2149
2150 entry = pdata;
2151
2152 /* set params Size of returned Quota Data 4 bytes*/
2153 /* but set it later when we know it */
2154
2155 /* for each entry push the data */
2156
2157 if (start_enum) {
2158 qt_handle->tmp_list = qt_handle->quota_list;
2159 }
2160
2161 tmp_list = qt_handle->tmp_list;
2162
2163 for (;((tmp_list!=NULL)&&((qt_len +40+SID_MAX_SIZE)<max_data_count));
2164 tmp_list=tmp_list->next,entry+=entry_len,qt_len+=entry_len) {
2165
2166 sid_len = ndr_size_dom_sid(
2167 &tmp_list->quotas->sid, 0);
2168 entry_len = 40 + sid_len;
2169
2170 /* nextoffset entry 4 bytes */
2171 SIVAL(entry,0,entry_len);
2172
2173 /* then the len of the SID 4 bytes */
2174 SIVAL(entry,4,sid_len);
2175
2176 /* unknown data 8 bytes SMB_BIG_UINT */
2177 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
2178
2179 /* the used disk space 8 bytes SMB_BIG_UINT */
2180 SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
2181
2182 /* the soft quotas 8 bytes SMB_BIG_UINT */
2183 SBIG_UINT(entry,24,tmp_list->quotas->softlim);
2184
2185 /* the hard quotas 8 bytes SMB_BIG_UINT */
2186 SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
2187
2188 /* and now the SID */
2189 sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
2190 }
2191
2192 qt_handle->tmp_list = tmp_list;
2193
2194 /* overwrite the offset of the last entry */
2195 SIVAL(entry-entry_len,0,0);
2196
2197 data_len = 4+qt_len;
2198 /* overwrite the params quota_data_len */
2199 SIVAL(params,0,data_len);
2200
2201 break;
2202
2203 case TRANSACT_GET_USER_QUOTA_FOR_SID:
2204
2205 /* unknown 4 bytes IVAL(pdata,0) */
2206
2207 if (data_count < 8) {
2208 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
2209 reply_doserror(req, ERRDOS, ERRunknownlevel);
2210 return;
2211 }
2212
2213 sid_len = IVAL(pdata,4);
2214 /* Ensure this is less than 1mb. */
2215 if (sid_len > (1024*1024)) {
2216 reply_doserror(req, ERRDOS, ERRnomem);
2217 return;
2218 }
2219
2220 if (data_count < 8+sid_len) {
2221 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %lu bytes data\n",data_count,(unsigned long)(8+sid_len)));
2222 reply_doserror(req, ERRDOS, ERRunknownlevel);
2223 return;
2224 }
2225
2226 data_len = 4+40+sid_len;
2227
2228 if (max_data_count < data_len) {
2229 DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: max_data_count(%d) < data_len(%d)\n",
2230 max_data_count, data_len));
2231 param_len = 4;
2232 SIVAL(params,0,data_len);
2233 data_len = 0;
2234 nt_status = NT_STATUS_BUFFER_TOO_SMALL;
2235 break;
2236 }
2237
2238 sid_parse(pdata+8,sid_len,&sid);
2239
2240 if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2241 ZERO_STRUCT(qt);
2242 /*
2243 * we have to return zero's in all fields
2244 * instead of returning an error here
2245 * --metze
2246 */
2247 }
2248
2249 /* Realloc the size of parameters and data we will return */
2250 param_len = 4;
2251 params = nttrans_realloc(ppparams, param_len);
2252 if(params == NULL) {
2253 reply_doserror(req, ERRDOS, ERRnomem);
2254 return;
2255 }
2256
2257 pdata = nttrans_realloc(ppdata, data_len);
2258 if(pdata == NULL) {
2259 reply_doserror(req, ERRDOS, ERRnomem);
2260 return;
2261 }
2262
2263 entry = pdata;
2264
2265 /* set params Size of returned Quota Data 4 bytes*/
2266 SIVAL(params,0,data_len);
2267
2268 /* nextoffset entry 4 bytes */
2269 SIVAL(entry,0,0);
2270
2271 /* then the len of the SID 4 bytes */
2272 SIVAL(entry,4,sid_len);
2273
2274 /* unknown data 8 bytes SMB_BIG_UINT */
2275 SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
2276
2277 /* the used disk space 8 bytes SMB_BIG_UINT */
2278 SBIG_UINT(entry,16,qt.usedspace);
2279
2280 /* the soft quotas 8 bytes SMB_BIG_UINT */
2281 SBIG_UINT(entry,24,qt.softlim);
2282
2283 /* the hard quotas 8 bytes SMB_BIG_UINT */
2284 SBIG_UINT(entry,32,qt.hardlim);
2285
2286 /* and now the SID */
2287 sid_linearize(entry+40, sid_len, &sid);
2288
2289 break;
2290
2291 default:
2292 DEBUG(0,("do_nt_transact_get_user_quota: fnum %d unknown level 0x%04hX\n",fsp->fnum,level));
2293 reply_doserror(req, ERRSRV, ERRerror);
2294 return;
2295 break;
2296 }
2297
2298 send_nt_replies(conn, req, nt_status, params, param_len,
2299 pdata, data_len);
2300}
2301
2302/****************************************************************************
2303 Reply to set user quota
2304****************************************************************************/
2305
2306static void call_nt_transact_set_user_quota(connection_struct *conn,
2307 struct smb_request *req,
2308 uint16 **ppsetup,
2309 uint32 setup_count,
2310 char **ppparams,
2311 uint32 parameter_count,
2312 char **ppdata,
2313 uint32 data_count,
2314 uint32 max_data_count)
2315{
2316 char *params = *ppparams;
2317 char *pdata = *ppdata;
2318 int data_len=0,param_len=0;
2319 SMB_NTQUOTA_STRUCT qt;
2320 size_t sid_len;
2321 DOM_SID sid;
2322 files_struct *fsp = NULL;
2323
2324 ZERO_STRUCT(qt);
2325
2326 /* access check */
2327 if (current_user.ut.uid != 0) {
2328 DEBUG(1,("set_user_quota: access_denied service [%s] user [%s]\n",
2329 lp_servicename(SNUM(conn)),conn->user));
2330 reply_doserror(req, ERRDOS, ERRnoaccess);
2331 return;
2332 }
2333
2334 /*
2335 * Ensure minimum number of parameters sent.
2336 */
2337
2338 if (parameter_count < 2) {
2339 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= 2 bytes parameters\n",parameter_count));
2340 reply_doserror(req, ERRDOS, ERRinvalidparam);
2341 return;
2342 }
2343
2344 /* maybe we can check the quota_fnum */
2345 fsp = file_fsp(SVAL(params,0));
2346 if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
2347 DEBUG(3,("TRANSACT_GET_USER_QUOTA: no valid QUOTA HANDLE\n"));
2348 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
2349 return;
2350 }
2351
2352 if (data_count < 40) {
2353 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %d bytes data\n",data_count,40));
2354 reply_doserror(req, ERRDOS, ERRunknownlevel);
2355 return;
2356 }
2357
2358 /* offset to next quota record.
2359 * 4 bytes IVAL(pdata,0)
2360 * unused here...
2361 */
2362
2363 /* sid len */
2364 sid_len = IVAL(pdata,4);
2365
2366 if (data_count < 40+sid_len) {
2367 DEBUG(0,("TRANSACT_SET_USER_QUOTA: requires %d >= %lu bytes data\n",data_count,(unsigned long)40+sid_len));
2368 reply_doserror(req, ERRDOS, ERRunknownlevel);
2369 return;
2370 }
2371
2372 /* unknown 8 bytes in pdata
2373 * maybe its the change time in NTTIME
2374 */
2375
2376 /* the used space 8 bytes (SMB_BIG_UINT)*/
2377 qt.usedspace = (SMB_BIG_UINT)IVAL(pdata,16);
2378#ifdef LARGE_SMB_OFF_T
2379 qt.usedspace |= (((SMB_BIG_UINT)IVAL(pdata,20)) << 32);
2380#else /* LARGE_SMB_OFF_T */
2381 if ((IVAL(pdata,20) != 0)&&
2382 ((qt.usedspace != 0xFFFFFFFF)||
2383 (IVAL(pdata,20)!=0xFFFFFFFF))) {
2384 /* more than 32 bits? */
2385 reply_doserror(req, ERRDOS, ERRunknownlevel);
2386 return;
2387 }
2388#endif /* LARGE_SMB_OFF_T */
2389
2390 /* the soft quotas 8 bytes (SMB_BIG_UINT)*/
2391 qt.softlim = (SMB_BIG_UINT)IVAL(pdata,24);
2392#ifdef LARGE_SMB_OFF_T
2393 qt.softlim |= (((SMB_BIG_UINT)IVAL(pdata,28)) << 32);
2394#else /* LARGE_SMB_OFF_T */
2395 if ((IVAL(pdata,28) != 0)&&
2396 ((qt.softlim != 0xFFFFFFFF)||
2397 (IVAL(pdata,28)!=0xFFFFFFFF))) {
2398 /* more than 32 bits? */
2399 reply_doserror(req, ERRDOS, ERRunknownlevel);
2400 return;
2401 }
2402#endif /* LARGE_SMB_OFF_T */
2403
2404 /* the hard quotas 8 bytes (SMB_BIG_UINT)*/
2405 qt.hardlim = (SMB_BIG_UINT)IVAL(pdata,32);
2406#ifdef LARGE_SMB_OFF_T
2407 qt.hardlim |= (((SMB_BIG_UINT)IVAL(pdata,36)) << 32);
2408#else /* LARGE_SMB_OFF_T */
2409 if ((IVAL(pdata,36) != 0)&&
2410 ((qt.hardlim != 0xFFFFFFFF)||
2411 (IVAL(pdata,36)!=0xFFFFFFFF))) {
2412 /* more than 32 bits? */
2413 reply_doserror(req, ERRDOS, ERRunknownlevel);
2414 return;
2415 }
2416#endif /* LARGE_SMB_OFF_T */
2417
2418 sid_parse(pdata+40,sid_len,&sid);
2419 DEBUGADD(8,("SID: %s\n", sid_string_dbg(&sid)));
2420
2421 /* 44 unknown bytes left... */
2422
2423 if (vfs_set_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
2424 reply_doserror(req, ERRSRV, ERRerror);
2425 return;
2426 }
2427
2428 send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
2429 pdata, data_len);
2430}
2431#endif /* HAVE_SYS_QUOTAS */
2432
2433static void handle_nttrans(connection_struct *conn,
2434 struct trans_state *state,
2435 struct smb_request *req)
2436{
2437 if (Protocol >= PROTOCOL_NT1) {
2438 req->flags2 |= 0x40; /* IS_LONG_NAME */
2439 SSVAL(req->inbuf,smb_flg2,req->flags2);
2440 }
2441
2442 /* Now we must call the relevant NT_TRANS function */
2443 switch(state->call) {
2444 case NT_TRANSACT_CREATE:
2445 {
2446 START_PROFILE(NT_transact_create);
2447 call_nt_transact_create(
2448 conn, req,
2449 &state->setup, state->setup_count,
2450 &state->param, state->total_param,
2451 &state->data, state->total_data,
2452 state->max_data_return);
2453 END_PROFILE(NT_transact_create);
2454 break;
2455 }
2456
2457 case NT_TRANSACT_IOCTL:
2458 {
2459 START_PROFILE(NT_transact_ioctl);
2460 call_nt_transact_ioctl(
2461 conn, req,
2462 &state->setup, state->setup_count,
2463 &state->param, state->total_param,
2464 &state->data, state->total_data,
2465 state->max_data_return);
2466 END_PROFILE(NT_transact_ioctl);
2467 break;
2468 }
2469
2470 case NT_TRANSACT_SET_SECURITY_DESC:
2471 {
2472 START_PROFILE(NT_transact_set_security_desc);
2473 call_nt_transact_set_security_desc(
2474 conn, req,
2475 &state->setup, state->setup_count,
2476 &state->param, state->total_param,
2477 &state->data, state->total_data,
2478 state->max_data_return);
2479 END_PROFILE(NT_transact_set_security_desc);
2480 break;
2481 }
2482
2483 case NT_TRANSACT_NOTIFY_CHANGE:
2484 {
2485 START_PROFILE(NT_transact_notify_change);
2486 call_nt_transact_notify_change(
2487 conn, req,
2488 &state->setup, state->setup_count,
2489 &state->param, state->total_param,
2490 &state->data, state->total_data,
2491 state->max_data_return,
2492 state->max_param_return);
2493 END_PROFILE(NT_transact_notify_change);
2494 break;
2495 }
2496
2497 case NT_TRANSACT_RENAME:
2498 {
2499 START_PROFILE(NT_transact_rename);
2500 call_nt_transact_rename(
2501 conn, req,
2502 &state->setup, state->setup_count,
2503 &state->param, state->total_param,
2504 &state->data, state->total_data,
2505 state->max_data_return);
2506 END_PROFILE(NT_transact_rename);
2507 break;
2508 }
2509
2510 case NT_TRANSACT_QUERY_SECURITY_DESC:
2511 {
2512 START_PROFILE(NT_transact_query_security_desc);
2513 call_nt_transact_query_security_desc(
2514 conn, req,
2515 &state->setup, state->setup_count,
2516 &state->param, state->total_param,
2517 &state->data, state->total_data,
2518 state->max_data_return);
2519 END_PROFILE(NT_transact_query_security_desc);
2520 break;
2521 }
2522
2523#ifdef HAVE_SYS_QUOTAS
2524 case NT_TRANSACT_GET_USER_QUOTA:
2525 {
2526 START_PROFILE(NT_transact_get_user_quota);
2527 call_nt_transact_get_user_quota(
2528 conn, req,
2529 &state->setup, state->setup_count,
2530 &state->param, state->total_param,
2531 &state->data, state->total_data,
2532 state->max_data_return);
2533 END_PROFILE(NT_transact_get_user_quota);
2534 break;
2535 }
2536
2537 case NT_TRANSACT_SET_USER_QUOTA:
2538 {
2539 START_PROFILE(NT_transact_set_user_quota);
2540 call_nt_transact_set_user_quota(
2541 conn, req,
2542 &state->setup, state->setup_count,
2543 &state->param, state->total_param,
2544 &state->data, state->total_data,
2545 state->max_data_return);
2546 END_PROFILE(NT_transact_set_user_quota);
2547 break;
2548 }
2549#endif /* HAVE_SYS_QUOTAS */
2550
2551 default:
2552 /* Error in request */
2553 DEBUG(0,("handle_nttrans: Unknown request %d in "
2554 "nttrans call\n", state->call));
2555 reply_doserror(req, ERRSRV, ERRerror);
2556 return;
2557 }
2558 return;
2559}
2560
2561/****************************************************************************
2562 Reply to a SMBNTtrans.
2563****************************************************************************/
2564
2565void reply_nttrans(struct smb_request *req)
2566{
2567 connection_struct *conn = req->conn;
2568 uint32_t pscnt;
2569 uint32_t psoff;
2570 uint32_t dscnt;
2571 uint32_t dsoff;
2572 uint16 function_code;
2573 NTSTATUS result;
2574 struct trans_state *state;
2575 uint32_t size;
2576 uint32_t av_size;
2577
2578 START_PROFILE(SMBnttrans);
2579
2580 if (req->wct < 19) {
2581 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2582 END_PROFILE(SMBnttrans);
2583 return;
2584 }
2585
2586 size = smb_len(req->inbuf) + 4;
2587 av_size = smb_len(req->inbuf);
2588 pscnt = IVAL(req->inbuf,smb_nt_ParameterCount);
2589 psoff = IVAL(req->inbuf,smb_nt_ParameterOffset);
2590 dscnt = IVAL(req->inbuf,smb_nt_DataCount);
2591 dsoff = IVAL(req->inbuf,smb_nt_DataOffset);
2592 function_code = SVAL(req->inbuf, smb_nt_Function);
2593
2594 if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
2595 reply_doserror(req, ERRSRV, ERRaccess);
2596 END_PROFILE(SMBnttrans);
2597 return;
2598 }
2599
2600 result = allow_new_trans(conn->pending_trans, req->mid);
2601 if (!NT_STATUS_IS_OK(result)) {
2602 DEBUG(2, ("Got invalid nttrans request: %s\n", nt_errstr(result)));
2603 reply_nterror(req, result);
2604 END_PROFILE(SMBnttrans);
2605 return;
2606 }
2607
2608 if ((state = TALLOC_P(conn->mem_ctx, struct trans_state)) == NULL) {
2609 reply_doserror(req, ERRSRV, ERRaccess);
2610 END_PROFILE(SMBnttrans);
2611 return;
2612 }
2613
2614 state->cmd = SMBnttrans;
2615
2616 state->mid = req->mid;
2617 state->vuid = req->vuid;
2618 state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount);
2619 state->data = NULL;
2620 state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount);
2621 state->param = NULL;
2622 state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount);
2623 state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount);
2624
2625 /* setup count is in *words* */
2626 state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount);
2627 state->setup = NULL;
2628 state->call = function_code;
2629
2630 /*
2631 * All nttrans messages we handle have smb_wct == 19 +
2632 * state->setup_count. Ensure this is so as a sanity check.
2633 */
2634
2635 if(req->wct != 19 + (state->setup_count/2)) {
2636 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2637 req->wct, 19 + (state->setup_count/2)));
2638 goto bad_param;
2639 }
2640
2641 /* Don't allow more than 128mb for each value. */
2642 if ((state->total_data > (1024*1024*128)) ||
2643 (state->total_param > (1024*1024*128))) {
2644 reply_doserror(req, ERRDOS, ERRnomem);
2645 END_PROFILE(SMBnttrans);
2646 return;
2647 }
2648
2649 if ((dscnt > state->total_data) || (pscnt > state->total_param))
2650 goto bad_param;
2651
2652 if (state->total_data) {
2653 /* Can't use talloc here, the core routines do realloc on the
2654 * params and data. */
2655 if ((state->data = (char *)SMB_MALLOC(state->total_data)) == NULL) {
2656 DEBUG(0,("reply_nttrans: data malloc fail for %u "
2657 "bytes !\n", (unsigned int)state->total_data));
2658 TALLOC_FREE(state);
2659 reply_doserror(req, ERRDOS, ERRnomem);
2660 END_PROFILE(SMBnttrans);
2661 return;
2662 }
2663
2664 if (dscnt > state->total_data ||
2665 dsoff+dscnt < dsoff) {
2666 goto bad_param;
2667 }
2668
2669 if (dsoff > av_size ||
2670 dscnt > av_size ||
2671 dsoff+dscnt > av_size) {
2672 goto bad_param;
2673 }
2674
2675 memcpy(state->data,smb_base(req->inbuf)+dsoff,dscnt);
2676 }
2677
2678 if (state->total_param) {
2679 /* Can't use talloc here, the core routines do realloc on the
2680 * params and data. */
2681 if ((state->param = (char *)SMB_MALLOC(state->total_param)) == NULL) {
2682 DEBUG(0,("reply_nttrans: param malloc fail for %u "
2683 "bytes !\n", (unsigned int)state->total_param));
2684 SAFE_FREE(state->data);
2685 TALLOC_FREE(state);
2686 reply_doserror(req, ERRDOS, ERRnomem);
2687 END_PROFILE(SMBnttrans);
2688 return;
2689 }
2690
2691 if (pscnt > state->total_param ||
2692 psoff+pscnt < psoff) {
2693 goto bad_param;
2694 }
2695
2696 if (psoff > av_size ||
2697 pscnt > av_size ||
2698 psoff+pscnt > av_size) {
2699 goto bad_param;
2700 }
2701
2702 memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
2703 }
2704
2705 state->received_data = dscnt;
2706 state->received_param = pscnt;
2707
2708 if(state->setup_count > 0) {
2709 DEBUG(10,("reply_nttrans: state->setup_count = %d\n",
2710 state->setup_count));
2711 state->setup = (uint16 *)TALLOC(state, state->setup_count);
2712 if (state->setup == NULL) {
2713 DEBUG(0,("reply_nttrans : Out of memory\n"));
2714 SAFE_FREE(state->data);
2715 SAFE_FREE(state->param);
2716 TALLOC_FREE(state);
2717 reply_doserror(req, ERRDOS, ERRnomem);
2718 END_PROFILE(SMBnttrans);
2719 return;
2720 }
2721
2722 if ((smb_nt_SetupStart + state->setup_count < smb_nt_SetupStart) ||
2723 (smb_nt_SetupStart + state->setup_count < state->setup_count)) {
2724 goto bad_param;
2725 }
2726 if (smb_nt_SetupStart + state->setup_count > size) {
2727 goto bad_param;
2728 }
2729
2730 memcpy( state->setup, &req->inbuf[smb_nt_SetupStart],
2731 state->setup_count);
2732 dump_data(10, (uint8 *)state->setup, state->setup_count);
2733 }
2734
2735 if ((state->received_data == state->total_data) &&
2736 (state->received_param == state->total_param)) {
2737 handle_nttrans(conn, state, req);
2738 SAFE_FREE(state->param);
2739 SAFE_FREE(state->data);
2740 TALLOC_FREE(state);
2741 END_PROFILE(SMBnttrans);
2742 return;
2743 }
2744
2745 DLIST_ADD(conn->pending_trans, state);
2746
2747 /* We need to send an interim response then receive the rest
2748 of the parameter/data bytes */
2749 reply_outbuf(req, 0, 0);
2750 show_msg((char *)req->outbuf);
2751 END_PROFILE(SMBnttrans);
2752 return;
2753
2754 bad_param:
2755
2756 DEBUG(0,("reply_nttrans: invalid trans parameters\n"));
2757 SAFE_FREE(state->data);
2758 SAFE_FREE(state->param);
2759 TALLOC_FREE(state);
2760 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2761 END_PROFILE(SMBnttrans);
2762 return;
2763}
2764
2765/****************************************************************************
2766 Reply to a SMBnttranss
2767 ****************************************************************************/
2768
2769void reply_nttranss(struct smb_request *req)
2770{
2771 connection_struct *conn = req->conn;
2772 uint32_t pcnt,poff,dcnt,doff,pdisp,ddisp;
2773 struct trans_state *state;
2774 uint32_t av_size;
2775 uint32_t size;
2776
2777 START_PROFILE(SMBnttranss);
2778
2779 show_msg((char *)req->inbuf);
2780
2781 if (req->wct < 18) {
2782 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2783 END_PROFILE(SMBnttranss);
2784 return;
2785 }
2786
2787 for (state = conn->pending_trans; state != NULL;
2788 state = state->next) {
2789 if (state->mid == req->mid) {
2790 break;
2791 }
2792 }
2793
2794 if ((state == NULL) || (state->cmd != SMBnttrans)) {
2795 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2796 END_PROFILE(SMBnttranss);
2797 return;
2798 }
2799
2800 /* Revise state->total_param and state->total_data in case they have
2801 changed downwards */
2802 if (IVAL(req->inbuf, smb_nts_TotalParameterCount)
2803 < state->total_param) {
2804 state->total_param = IVAL(req->inbuf,
2805 smb_nts_TotalParameterCount);
2806 }
2807 if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) {
2808 state->total_data = IVAL(req->inbuf, smb_nts_TotalDataCount);
2809 }
2810
2811 size = smb_len(req->inbuf) + 4;
2812 av_size = smb_len(req->inbuf);
2813
2814 pcnt = IVAL(req->inbuf,smb_nts_ParameterCount);
2815 poff = IVAL(req->inbuf, smb_nts_ParameterOffset);
2816 pdisp = IVAL(req->inbuf, smb_nts_ParameterDisplacement);
2817
2818 dcnt = IVAL(req->inbuf, smb_nts_DataCount);
2819 ddisp = IVAL(req->inbuf, smb_nts_DataDisplacement);
2820 doff = IVAL(req->inbuf, smb_nts_DataOffset);
2821
2822 state->received_param += pcnt;
2823 state->received_data += dcnt;
2824
2825 if ((state->received_data > state->total_data) ||
2826 (state->received_param > state->total_param))
2827 goto bad_param;
2828
2829 if (pcnt) {
2830 if (pdisp > state->total_param ||
2831 pcnt > state->total_param ||
2832 pdisp+pcnt > state->total_param ||
2833 pdisp+pcnt < pdisp) {
2834 goto bad_param;
2835 }
2836
2837 if (poff > av_size ||
2838 pcnt > av_size ||
2839 poff+pcnt > av_size ||
2840 poff+pcnt < poff) {
2841 goto bad_param;
2842 }
2843
2844 memcpy(state->param+pdisp, smb_base(req->inbuf)+poff,
2845 pcnt);
2846 }
2847
2848 if (dcnt) {
2849 if (ddisp > state->total_data ||
2850 dcnt > state->total_data ||
2851 ddisp+dcnt > state->total_data ||
2852 ddisp+dcnt < ddisp) {
2853 goto bad_param;
2854 }
2855
2856 if (ddisp > av_size ||
2857 dcnt > av_size ||
2858 ddisp+dcnt > av_size ||
2859 ddisp+dcnt < ddisp) {
2860 goto bad_param;
2861 }
2862
2863 memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
2864 dcnt);
2865 }
2866
2867 if ((state->received_param < state->total_param) ||
2868 (state->received_data < state->total_data)) {
2869 END_PROFILE(SMBnttranss);
2870 return;
2871 }
2872
2873 /*
2874 * construct_reply_common will copy smb_com from inbuf to
2875 * outbuf. SMBnttranss is wrong here.
2876 */
2877 SCVAL(req->inbuf,smb_com,SMBnttrans);
2878
2879 handle_nttrans(conn, state, req);
2880
2881 DLIST_REMOVE(conn->pending_trans, state);
2882 SAFE_FREE(state->data);
2883 SAFE_FREE(state->param);
2884 TALLOC_FREE(state);
2885 END_PROFILE(SMBnttranss);
2886 return;
2887
2888 bad_param:
2889
2890 DEBUG(0,("reply_nttranss: invalid trans parameters\n"));
2891 DLIST_REMOVE(conn->pending_trans, state);
2892 SAFE_FREE(state->data);
2893 SAFE_FREE(state->param);
2894 TALLOC_FREE(state);
2895 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
2896 END_PROFILE(SMBnttranss);
2897 return;
2898}
Note: See TracBrowser for help on using the repository browser.