source: branches/samba-3.5.x/source3/smbd/nttrans.c@ 732

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

Samba Server 3.5: update branche to 3.5.12

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