Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / smbd / nttrans.c
blob5604c1272d8e2d3a19abc578add7f8fe1dbd23dc
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB NT transaction handling
5 Copyright (C) Jeremy Allison 1994-1998
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 2 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
23 #include "nterr.h"
25 extern int DEBUGLEVEL;
26 extern int Protocol;
27 extern int Client;
28 extern int smb_read_error;
29 extern int global_oplock_break;
30 extern BOOL case_sensitive;
31 extern BOOL case_preserve;
32 extern BOOL short_case_preserve;
34 static void remove_pending_change_notify_requests_by_mid(int mid);
36 static char *known_nt_pipes[] = {
37 "\\LANMAN",
38 "\\srvsvc",
39 "\\samr",
40 "\\wkssvc",
41 "\\NETLOGON",
42 "\\ntlsa",
43 "\\ntsvcs",
44 "\\lsass",
45 "\\lsarpc",
46 "\\winreg",
47 NULL
50 /* Combinations of standard masks. */
51 #define STANDARD_RIGHTS_ALL_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS) /* 0x001f0000 */
52 #define STANDARD_RIGHTS_EXECUTE_ACCESS (READ_CONTROL_ACCESS) /* 0x00020000 */
53 #define STANDARD_RIGHTS_READ_ACCESS (READ_CONTROL_ACCESS) /* 0x00200000 */
54 #define STANDARD_RIGHTS_REQUIRED_ACCESS (DELETE_ACCESS|READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS) /* 0x000f0000 */
55 #define STANDARD_RIGHTS_WRITE_ACCESS (READ_CONTROL_ACCESS) /* 0x00020000 */
57 /* Mapping of generic access rights for files to specific rights. */
59 #define FILE_GENERIC_ALL (STANDARD_RIGHTS_REQUIRED_ACCESS| SYNCHRONIZE_ACCESS|FILE_ALL_ATTRIBUTES)
61 #define FILE_GENERIC_READ (STANDARD_RIGHTS_READ_ACCESS|FILE_READ_DATA|FILE_READ_ATTRIBUTES|\
62 FILE_READ_EA|SYNCHRONIZE_ACCESS)
64 #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\
65 FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE_ACCESS)
67 #define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\
68 FILE_EXECUTE|SYNCHRONIZE_ACCESS)
70 /* A type to describe the mapping of generic access rights to object
71 specific access rights. */
73 typedef struct generic_mapping {
74 uint32 generic_read;
75 uint32 generic_write;
76 uint32 generic_execute;
77 uint32 generic_all;
78 } GENERIC_MAPPING;
80 /* Map generic permissions to file object specific permissions */
82 struct generic_mapping file_generic_mapping = {
83 FILE_GENERIC_READ,
84 FILE_GENERIC_WRITE,
85 FILE_GENERIC_EXECUTE,
86 FILE_GENERIC_ALL
89 /* Map generic access rights to object specific rights. This technique is
90 used to give meaning to assigning read, write, execute and all access to
91 objects. Each type of object has its own mapping of generic to object
92 specific access rights. */
94 void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
96 uint32 old_mask = *access_mask;
98 if (*access_mask & GENERIC_READ_ACCESS) {
99 *access_mask &= ~GENERIC_READ_ACCESS;
100 *access_mask |= mapping->generic_read;
103 if (*access_mask & GENERIC_WRITE_ACCESS) {
104 *access_mask &= ~GENERIC_WRITE_ACCESS;
105 *access_mask |= mapping->generic_write;
108 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
109 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
110 *access_mask |= mapping->generic_execute;
113 if (*access_mask & GENERIC_ALL_ACCESS) {
114 *access_mask &= ~GENERIC_ALL_ACCESS;
115 *access_mask |= mapping->generic_all;
118 if (old_mask != *access_mask) {
119 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
120 old_mask, *access_mask));
124 /****************************************************************************
125 Send the required number of replies back.
126 We assume all fields other than the data fields are
127 set correctly for the type of call.
128 HACK ! Always assumes smb_setup field is zero.
129 ****************************************************************************/
131 static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
132 int paramsize, char *pdata, int datasize)
134 extern int max_send;
135 int data_to_send = datasize;
136 int params_to_send = paramsize;
137 int useable_space;
138 char *pp = params;
139 char *pd = pdata;
140 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
141 int alignment_offset = 3;
142 int data_alignment_offset = 0;
145 * Initially set the wcnt area to be 18 - this is true for all
146 * transNT replies.
149 set_message(outbuf,18,0,True);
151 if(nt_error != 0) {
152 /* NT Error. */
153 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
155 ERROR(0,nt_error);
159 * If there genuinely are no parameters or data to send just send
160 * the empty packet.
163 if(params_to_send == 0 && data_to_send == 0) {
164 send_smb(Client,outbuf);
165 return 0;
169 * When sending params and data ensure that both are nicely aligned.
170 * Only do this alignment when there is also data to send - else
171 * can cause NT redirector problems.
174 if (((params_to_send % 4) != 0) && (data_to_send != 0))
175 data_alignment_offset = 4 - (params_to_send % 4);
178 * Space is bufsize minus Netbios over TCP header minus SMB header.
179 * The alignment_offset is to align the param bytes on a four byte
180 * boundary (2 bytes for data len, one byte pad).
181 * NT needs this to work correctly.
184 useable_space = bufsize - ((smb_buf(outbuf)+
185 alignment_offset+data_alignment_offset) -
186 outbuf);
189 * useable_space can never be more than max_send minus the
190 * alignment offset.
193 useable_space = MIN(useable_space,
194 max_send - (alignment_offset+data_alignment_offset));
197 while (params_to_send || data_to_send) {
200 * Calculate whether we will totally or partially fill this packet.
203 total_sent_thistime = params_to_send + data_to_send +
204 alignment_offset + data_alignment_offset;
207 * We can never send more than useable_space.
210 total_sent_thistime = MIN(total_sent_thistime, useable_space);
212 set_message(outbuf, 18, total_sent_thistime, True);
215 * Set total params and data to be sent.
218 SIVAL(outbuf,smb_ntr_TotalParameterCount,paramsize);
219 SIVAL(outbuf,smb_ntr_TotalDataCount,datasize);
222 * Calculate how many parameters and data we can fit into
223 * this packet. Parameters get precedence.
226 params_sent_thistime = MIN(params_to_send,useable_space);
227 data_sent_thistime = useable_space - params_sent_thistime;
228 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
230 SIVAL(outbuf,smb_ntr_ParameterCount,params_sent_thistime);
232 if(params_sent_thistime == 0) {
233 SIVAL(outbuf,smb_ntr_ParameterOffset,0);
234 SIVAL(outbuf,smb_ntr_ParameterDisplacement,0);
235 } else {
237 * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
238 * parameter bytes, however the first 4 bytes of outbuf are
239 * the Netbios over TCP header. Thus use smb_base() to subtract
240 * them from the calculation.
243 SIVAL(outbuf,smb_ntr_ParameterOffset,
244 ((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
246 * Absolute displacement of param bytes sent in this packet.
249 SIVAL(outbuf,smb_ntr_ParameterDisplacement,pp - params);
253 * Deal with the data portion.
256 SIVAL(outbuf,smb_ntr_DataCount, data_sent_thistime);
258 if(data_sent_thistime == 0) {
259 SIVAL(outbuf,smb_ntr_DataOffset,0);
260 SIVAL(outbuf,smb_ntr_DataDisplacement, 0);
261 } else {
263 * The offset of the data bytes is the offset of the
264 * parameter bytes plus the number of parameters being sent this time.
267 SIVAL(outbuf,smb_ntr_DataOffset,((smb_buf(outbuf)+alignment_offset) -
268 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
269 SIVAL(outbuf,smb_ntr_DataDisplacement, pd - pdata);
273 * Copy the param bytes into the packet.
276 if(params_sent_thistime)
277 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
280 * Copy in the data bytes
283 if(data_sent_thistime)
284 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
285 data_alignment_offset,pd,data_sent_thistime);
287 DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
288 params_sent_thistime, data_sent_thistime, useable_space));
289 DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
290 params_to_send, data_to_send, paramsize, datasize));
292 /* Send the packet */
293 send_smb(Client,outbuf);
295 pp += params_sent_thistime;
296 pd += data_sent_thistime;
298 params_to_send -= params_sent_thistime;
299 data_to_send -= data_sent_thistime;
302 * Sanity check
305 if(params_to_send < 0 || data_to_send < 0) {
306 DEBUG(0,("send_nt_replies failed sanity check pts = %d, dts = %d\n!!!",
307 params_to_send, data_to_send));
308 return -1;
312 return 0;
315 /****************************************************************************
316 (Hopefully) temporary call to fix bugs in NT5.0beta2. This OS sends unicode
317 strings in NT calls AND DOESN'T SET THE UNICODE BIT !!!!!!!
318 ****************************************************************************/
320 static void get_filename( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
323 * We need various heuristics here to detect a unicode string... JRA.
326 DEBUG(10,("get_filename: data_offset = %d, data_len = %d, fname_len = %d\n",
327 data_offset, data_len, fname_len ));
329 if(data_len - fname_len > 1) {
331 * NT 5.0 Beta 2 has kindly sent us a UNICODE string
332 * without bothering to set the unicode bit. How kind.
334 * Firstly - ensure that the data offset is aligned
335 * on a 2 byte boundary - add one if not.
337 fname_len = fname_len/2;
338 if(data_offset & 1)
339 data_offset++;
340 pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
341 } else {
342 StrnCpy(fname,inbuf+data_offset,fname_len);
343 fname[fname_len] = '\0';
347 /****************************************************************************
348 Fix bugs in Win2000 final release. In trans calls this OS sends unicode
349 strings AND DOESN'T SET THE UNICODE BIT !!!!!!!
350 ****************************************************************************/
352 static void get_filename_transact( char *fname, char *inbuf, int data_offset, int data_len, int fname_len)
355 * We need various heuristics here to detect a unicode string... JRA.
358 DEBUG(10,("get_filename_transact: data_offset = %d, data_len = %d, fname_len = %d\n",
359 data_offset, data_len, fname_len ));
362 * Win2K sends a unicode filename plus one extra alingment byte.
363 * WinNT4.x send an ascii string with multiple garbage bytes on
364 * the end here.
367 if((data_len - fname_len == 1) || (inbuf[data_offset] == '\0')) {
369 * Ensure that the data offset is aligned
370 * on a 2 byte boundary - add one if not.
372 fname_len = fname_len/2;
373 if(data_offset & 1)
374 data_offset++;
375 pstrcpy(fname, dos_unistrn2((uint16 *)(inbuf+data_offset), fname_len));
376 } else {
377 StrnCpy(fname,inbuf+data_offset,fname_len);
378 fname[fname_len] = '\0';
382 /****************************************************************************
383 Save case statics.
384 ****************************************************************************/
386 static BOOL saved_case_sensitive;
387 static BOOL saved_case_preserve;
388 static BOOL saved_short_case_preserve;
390 /****************************************************************************
391 Save case semantics.
392 ****************************************************************************/
394 static void set_posix_case_semantics(uint32 file_attributes)
396 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
397 return;
399 saved_case_sensitive = case_sensitive;
400 saved_case_preserve = case_preserve;
401 saved_short_case_preserve = short_case_preserve;
403 /* Set to POSIX. */
404 case_sensitive = True;
405 case_preserve = True;
406 short_case_preserve = True;
409 /****************************************************************************
410 Restore case semantics.
411 ****************************************************************************/
413 static void restore_case_semantics(uint32 file_attributes)
415 if(!(file_attributes & FILE_FLAG_POSIX_SEMANTICS))
416 return;
418 case_sensitive = saved_case_sensitive;
419 case_preserve = saved_case_preserve;
420 short_case_preserve = saved_short_case_preserve;
423 /****************************************************************************
424 Utility function to map create disposition.
425 ****************************************************************************/
427 static int map_create_disposition( uint32 create_disposition)
429 int ret;
431 switch( create_disposition ) {
432 case FILE_CREATE:
433 /* create if not exist, fail if exist */
434 ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL);
435 break;
436 case FILE_SUPERSEDE:
437 case FILE_OVERWRITE_IF:
438 /* create if not exist, trunc if exist */
439 ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
440 break;
441 case FILE_OPEN:
442 /* fail if not exist, open if exists */
443 ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN);
444 break;
445 case FILE_OPEN_IF:
446 /* create if not exist, open if exists */
447 ret = (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_OPEN);
448 break;
449 case FILE_OVERWRITE:
450 /* fail if not exist, truncate if exists */
451 ret = (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE);
452 break;
453 default:
454 DEBUG(0,("map_create_disposition: Incorrect value for create_disposition = %d\n",
455 create_disposition ));
456 return -1;
459 DEBUG(10,("map_create_disposition: Mapped create_disposition %lx to %x\n",
460 (unsigned long)create_disposition, ret ));
462 return ret;
465 /****************************************************************************
466 Utility function to map share modes.
467 ****************************************************************************/
469 static int map_share_mode( BOOL *pstat_open_only, char *fname, uint32 create_options,
470 uint32 desired_access, uint32 share_access, uint32 file_attributes)
472 int smb_open_mode = -1;
474 DEBUG(6, ("map_share_mode(%s, create_options=0x%x, "
475 "desired_access=0x%x, share_access=0x%x, "
476 "file_attributes=0x%x\n",
477 fname, create_options, desired_access,
478 share_access, file_attributes));
481 * Convert GENERIC bits to specific bits.
484 se_map_generic(&desired_access, &file_generic_mapping);
486 *pstat_open_only = False;
488 /* this is just so the next switch works sane */
489 if (desired_access & FILE_EXECUTE)
490 desired_access |= FILE_READ_DATA;
492 switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
493 case FILE_READ_DATA:
494 smb_open_mode = DOS_OPEN_RDONLY;
495 break;
496 case FILE_WRITE_DATA:
497 case FILE_APPEND_DATA:
498 case FILE_WRITE_DATA|FILE_APPEND_DATA:
499 smb_open_mode = DOS_OPEN_WRONLY;
500 break;
501 case FILE_READ_DATA|FILE_WRITE_DATA:
502 case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
503 case FILE_READ_DATA|FILE_APPEND_DATA:
504 smb_open_mode = DOS_OPEN_RDWR;
505 break;
509 * NB. For DELETE_ACCESS we should really check the
510 * directory permissions, as that is what controls
511 * delete, and for WRITE_DAC_ACCESS we should really
512 * check the ownership, as that is what controls the
513 * chmod. Note that this is *NOT* a security hole (this
514 * note is for you, Andrew) as we are not *allowing*
515 * the access at this point, the actual unlink or
516 * chown or chmod call would do this. We are just helping
517 * clients out by telling them if they have a hope
518 * of any of this succeeding. POSIX acls may still
519 * deny the real call. JRA.
522 if (smb_open_mode == -1) {
523 if(desired_access == WRITE_DAC_ACCESS || desired_access == READ_CONTROL_ACCESS)
524 *pstat_open_only = True;
526 if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS|
527 FILE_EXECUTE|FILE_READ_ATTRIBUTES|
528 FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
529 FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS)) {
530 smb_open_mode = DOS_OPEN_RDONLY;
531 } else if (desired_access == 0) {
533 * JRA - NT seems to sometimes send desired_access as zero. play it safe
534 * and map to a stat open.
536 smb_open_mode = DOS_OPEN_RDONLY;
537 } else {
538 DEBUG(0,("map_share_mode: Incorrect value 0x%lx for desired_access to file %s\n",
539 (unsigned long)desired_access, fname));
540 return -1;
545 * Set the special bit that means allow share delete.
546 * This is held outside the normal share mode bits at 1<<15.
547 * JRA.
550 if(share_access & FILE_SHARE_DELETE) {
551 smb_open_mode |= ALLOW_SHARE_DELETE;
552 DEBUG(10,("map_share_mode: FILE_SHARE_DELETE requested. open_mode = 0x%x\n", smb_open_mode));
556 * We need to store the intent to open for Delete. This
557 * is what determines if a delete on close flag can be set.
558 * This is the wrong way (and place) to store this, but for 2.x this
559 * is the only practical way. JRA.
562 if(desired_access & DELETE_ACCESS) {
563 DEBUG(10,("map_share_mode: DELETE_ACCESS requested. open_mode = 0x%x\n", smb_open_mode));
566 if (create_options & FILE_DELETE_ON_CLOSE) {
567 /* Implicit delete access is *NOT* requested... */
568 smb_open_mode |= DELETE_ON_CLOSE_FLAG;
569 DEBUG(10,("map_share_mode: FILE_DELETE_ON_CLOSE requested. open_mode = 0x%x\n", smb_open_mode));
572 /* Add in the requested share mode. */
573 switch( share_access & (FILE_SHARE_READ|FILE_SHARE_WRITE)) {
574 case FILE_SHARE_READ:
575 smb_open_mode |= SET_DENY_MODE(DENY_WRITE);
576 break;
577 case FILE_SHARE_WRITE:
578 smb_open_mode |= SET_DENY_MODE(DENY_READ);
579 break;
580 case (FILE_SHARE_READ|FILE_SHARE_WRITE):
581 smb_open_mode |= SET_DENY_MODE(DENY_NONE);
582 break;
583 case FILE_SHARE_NONE:
584 smb_open_mode |= SET_DENY_MODE(DENY_ALL);
585 break;
589 * Handle an O_SYNC request.
592 if(file_attributes & FILE_FLAG_WRITE_THROUGH)
593 smb_open_mode |= FILE_SYNC_OPENMODE;
595 DEBUG(10,("map_share_mode: Mapped desired access 0x%lx, share access 0x%lx, file attributes 0x%lx \
596 to open_mode 0x%x\n", (unsigned long)desired_access, (unsigned long)share_access,
597 (unsigned long)file_attributes, smb_open_mode ));
599 return smb_open_mode;
603 * This is a *disgusting* hack.
604 * This is *so* bad that even I'm embarrassed (and I
605 * have no shame). Here's the deal :
606 * Until we get the correct SPOOLSS code into smbd
607 * then when we're running with NT SMB support then
608 * NT makes this call with a level of zero, and then
609 * immediately follows it with an open request to
610 * the \\SRVSVC pipe. If we allow that open to
611 * succeed then NT barfs when it cannot open the
612 * \\SPOOLSS pipe immediately after and continually
613 * whines saying "Printer name is invalid" forever
614 * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
615 * to fail, then NT downgrades to using the downlevel code
616 * and everything works as well as before. I hate
617 * myself for adding this code.... JRA.
619 * The HACK_FAIL_TIME define allows only a 2
620 * second window for this to occur, just in
621 * case...
624 static BOOL fail_next_srvsvc = False;
625 static time_t fail_time;
626 #define HACK_FAIL_TIME 2 /* In seconds. */
628 void fail_next_srvsvc_open(void)
630 /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
631 if (get_remote_arch() != RA_WINNT)
632 return;
634 fail_next_srvsvc = True;
635 fail_time = time(NULL);
636 DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
640 * HACK alert.... see above - JRA.
643 BOOL should_fail_next_srvsvc_open(const char *pipename)
646 DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
647 (int)fail_next_srvsvc, pipename));
649 if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
650 fail_next_srvsvc = False;
651 fail_time = (time_t)0;
652 DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
655 if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
656 fail_next_srvsvc = False;
657 DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
658 return True;
660 return False;
664 /****************************************************************************
665 Reply to an NT create and X call on a pipe.
666 ****************************************************************************/
667 static int nt_open_pipe(char *fname, connection_struct *conn,
668 char *inbuf, char *outbuf, int *ppnum)
670 pipes_struct *p = NULL;
672 uint16 vuid = SVAL(inbuf, smb_uid);
673 int i;
675 DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
677 /* See if it is one we want to handle. */
678 for( i = 0; known_nt_pipes[i]; i++ )
679 if( strequal(fname,known_nt_pipes[i]))
680 break;
682 if ( known_nt_pipes[i] == NULL )
683 return(ERROR(ERRSRV,ERRaccess));
685 /* Strip \\ off the name. */
686 fname++;
688 if(should_fail_next_srvsvc_open(fname))
689 return (ERROR(ERRSRV,ERRaccess));
691 DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
693 p = open_rpc_pipe_p(fname, conn, vuid);
694 if (!p)
695 return(ERROR(ERRSRV,ERRnofids));
697 *ppnum = p->pnum;
699 return 0;
702 /****************************************************************************
703 Reply to an NT create and X call.
704 ****************************************************************************/
706 int reply_ntcreate_and_X(connection_struct *conn,
707 char *inbuf,char *outbuf,int length,int bufsize)
709 pstring fname;
710 uint32 flags = IVAL(inbuf,smb_ntcreate_Flags);
711 uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
712 uint32 file_attributes = IVAL(inbuf,smb_ntcreate_FileAttributes);
713 uint32 share_access = IVAL(inbuf,smb_ntcreate_ShareAccess);
714 uint32 create_disposition = IVAL(inbuf,smb_ntcreate_CreateDisposition);
715 uint32 create_options = IVAL(inbuf,smb_ntcreate_CreateOptions);
716 uint32 fname_len = MIN(((uint32)SVAL(inbuf,smb_ntcreate_NameLength)),
717 ((uint32)sizeof(fname)-1));
718 uint16 root_dir_fid = (uint16)IVAL(inbuf,smb_ntcreate_RootDirectoryFid);
719 int smb_ofun;
720 int smb_open_mode;
721 int smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
722 /* Breakout the oplock request bits so we can set the
723 reply bits separately. */
724 int oplock_request = 0;
725 mode_t unixmode;
726 int pnum = -1;
727 int fmode=0,rmode=0;
728 SMB_OFF_T file_len = 0;
729 SMB_STRUCT_STAT sbuf;
730 int smb_action = 0;
731 BOOL bad_path = False;
732 files_struct *fsp=NULL;
733 char *p = NULL;
734 BOOL stat_open_only = False;
737 * We need to construct the open_and_X ofun value from the
738 * NT values, as that's what our code is structured to accept.
741 if((smb_ofun = map_create_disposition( create_disposition )) == -1)
742 return(ERROR(ERRDOS,ERRbadaccess));
745 * Get the file name.
748 if(root_dir_fid != 0) {
750 * This filename is relative to a directory fid.
752 files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
753 size_t dir_name_len;
755 if(!dir_fsp)
756 return(ERROR(ERRDOS,ERRbadfid));
758 if(!dir_fsp->is_directory) {
760 * Check to see if this is a mac fork of some kind.
763 get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
764 smb_buflen(inbuf),fname_len);
766 if( fname[0] == ':') {
767 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
768 return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
770 return(ERROR(ERRDOS,ERRbadfid));
774 * Copy in the base directory name.
777 pstrcpy( fname, dir_fsp->fsp_name );
778 dir_name_len = strlen(fname);
781 * Ensure it ends in a '\'.
784 if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
785 pstrcat(fname, "\\");
786 dir_name_len++;
790 * This next calculation can refuse a correct filename if we're dealing
791 * with the Win2k unicode bug, but that would be rare. JRA.
794 if(fname_len + dir_name_len >= sizeof(pstring))
795 return(ERROR(ERRSRV,ERRfilespecs));
797 get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
798 smb_buflen(inbuf),fname_len);
800 } else {
802 get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
803 smb_buflen(inbuf),fname_len);
806 /* If it's an IPC, use the pipe handler. */
808 if (IS_IPC(conn) && lp_nt_pipe_support()) {
810 int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
811 if(ret != 0)
812 return ret;
815 * Deal with pipe return.
818 set_message(outbuf,34,0,True);
820 p = outbuf + smb_vwv2;
821 p++;
822 SSVAL(p,0,pnum);
823 p += 2;
824 SIVAL(p,0,FILE_WAS_OPENED);
825 p += 4;
826 p += 32;
827 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
828 p += 20;
829 /* File type. */
830 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
831 /* Device state. */
832 SSVAL(p,2, 0x5FF); /* ? */
834 DEBUG(5,("reply_ntcreate_and_X: open pipe = %s\n", fname));
836 return chain_reply(inbuf,outbuf,length,bufsize);
840 * Now contruct the smb_open_mode value from the filename,
841 * desired access and the share access.
844 if((smb_open_mode = map_share_mode(&stat_open_only, fname, create_options, desired_access,
845 share_access,
846 file_attributes)) == -1)
847 return(ERROR(ERRDOS,ERRbadaccess));
849 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
850 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
853 * Ordinary file or directory.
857 * Check if POSIX semantics are wanted.
860 set_posix_case_semantics(file_attributes);
862 unix_convert(fname,conn,0,&bad_path,NULL);
864 fsp = file_new();
865 if (!fsp) {
866 restore_case_semantics(file_attributes);
867 return(ERROR(ERRSRV,ERRnofids));
870 if (!check_name(fname,conn)) {
871 if((errno == ENOENT) && bad_path) {
872 unix_ERR_class = ERRDOS;
873 unix_ERR_code = ERRbadpath;
875 file_free(fsp);
877 restore_case_semantics(file_attributes);
879 return(UNIXERROR(ERRDOS,ERRnoaccess));
882 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
885 * If it's a request for a directory open, deal with it separately.
888 if(create_options & FILE_DIRECTORY_FILE) {
889 oplock_request = 0;
891 open_directory(fsp, conn, fname, smb_ofun,
892 unixmode, &smb_action);
894 restore_case_semantics(file_attributes);
896 if(!fsp->open) {
897 file_free(fsp);
898 return(UNIXERROR(ERRDOS,ERRnoaccess));
900 } else {
902 * Ordinary file case.
905 /* NB. We have a potential bug here. If we
906 * cause an oplock break to ourselves, then we
907 * could end up processing filename related
908 * SMB requests whilst we await the oplock
909 * break response. As we may have changed the
910 * filename case semantics to be POSIX-like,
911 * this could mean a filename request could
912 * fail when it should succeed. This is a rare
913 * condition, but eventually we must arrange
914 * to restore the correct case semantics
915 * before issuing an oplock break request to
916 * our client. JRA. */
918 open_file_shared(fsp,conn,fname,smb_open_mode,
919 smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
921 if (!fsp->open) {
922 /* We cheat here. There are two cases we
923 * care about. One is a directory rename,
924 * where the NT client will attempt to
925 * open the source directory for
926 * DELETE access. Note that when the
927 * NT client does this it does *not*
928 * set the directory bit in the
929 * request packet. This is translated
930 * into a read/write open
931 * request. POSIX states that any open
932 * for write request on a directory
933 * will generate an EISDIR error, so
934 * we can catch this here and open a
935 * pseudo handle that is flagged as a
936 * directory. The second is an open
937 * for a permissions read only, which
938 * we handle in the open_file_stat case. JRA.
941 if(errno == EISDIR) {
944 * Fail the open if it was explicitly a non-directory file.
947 if (create_options & FILE_NON_DIRECTORY_FILE) {
948 file_free(fsp);
949 restore_case_semantics(file_attributes);
950 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
951 return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
954 oplock_request = 0;
955 open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
957 if(!fsp->open) {
958 file_free(fsp);
959 restore_case_semantics(file_attributes);
960 return(UNIXERROR(ERRDOS,ERRnoaccess));
962 #ifdef EROFS
963 } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
964 #else /* !EROFS */
965 } else if (errno == EACCES && stat_open_only) {
966 #endif
968 * We couldn't open normally and all we want
969 * are the permissions. Try and do a stat open.
972 oplock_request = 0;
974 open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
976 if(!fsp->open) {
977 file_free(fsp);
978 restore_case_semantics(file_attributes);
979 return(UNIXERROR(ERRDOS,ERRnoaccess));
982 } else {
984 if((errno == ENOENT) && bad_path) {
985 unix_ERR_class = ERRDOS;
986 unix_ERR_code = ERRbadpath;
989 file_free(fsp);
991 restore_case_semantics(file_attributes);
993 return(UNIXERROR(ERRDOS,ERRnoaccess));
998 if(fsp->is_directory) {
999 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
1000 close_file(fsp,True);
1001 restore_case_semantics(file_attributes);
1002 return(ERROR(ERRDOS,ERRnoaccess));
1004 } else {
1005 if (!fsp->stat_open && sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1006 close_file(fsp,False);
1007 restore_case_semantics(file_attributes);
1008 return(ERROR(ERRDOS,ERRnoaccess));
1012 restore_case_semantics(file_attributes);
1014 file_len = sbuf.st_size;
1015 fmode = dos_mode(conn,fname,&sbuf);
1016 if(fmode == 0)
1017 fmode = FILE_ATTRIBUTE_NORMAL;
1018 if (!fsp->is_directory && (fmode & aDIR)) {
1019 close_file(fsp,False);
1020 return(ERROR(ERRDOS,ERRnoaccess));
1024 * If the caller set the extended oplock request bit
1025 * and we granted one (by whatever means) - set the
1026 * correct bit for extended oplock reply.
1029 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1030 smb_action |= EXTENDED_OPLOCK_GRANTED;
1032 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1033 smb_action |= EXTENDED_OPLOCK_GRANTED;
1035 set_message(outbuf,34,0,True);
1037 p = outbuf + smb_vwv2;
1040 * Currently as we don't support level II oplocks we just report
1041 * exclusive & batch here.
1044 if (smb_action & EXTENDED_OPLOCK_GRANTED)
1045 SCVAL(p,0, BATCH_OPLOCK_RETURN);
1046 else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
1047 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
1048 else
1049 SCVAL(p,0,NO_OPLOCK_RETURN);
1051 p++;
1052 SSVAL(p,0,fsp->fnum);
1053 p += 2;
1054 SIVAL(p,0,smb_action);
1055 p += 4;
1057 /* Create time. */
1058 put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1059 p += 8;
1060 put_long_date(p,sbuf.st_atime); /* access time */
1061 p += 8;
1062 put_long_date(p,sbuf.st_mtime); /* write time */
1063 p += 8;
1064 put_long_date(p,sbuf.st_mtime); /* change time */
1065 p += 8;
1066 SIVAL(p,0,fmode); /* File Attributes. */
1067 p += 4;
1068 SOFF_T(p, 0, file_len);
1069 p += 8;
1070 SOFF_T(p,0,file_len);
1071 p += 12;
1072 SCVAL(p,0,fsp->is_directory ? 1 : 0);
1074 DEBUG(5,("reply_ntcreate_and_X: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
1076 return chain_reply(inbuf,outbuf,length,bufsize);
1079 /****************************************************************************
1080 Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
1081 ****************************************************************************/
1083 static int call_nt_transact_create(connection_struct *conn,
1084 char *inbuf, char *outbuf, int length,
1085 int bufsize, char **ppsetup, char **ppparams,
1086 char **ppdata)
1088 pstring fname;
1089 char *params = *ppparams;
1090 int total_parameter_count = (int)IVAL(inbuf, smb_nt_TotalParameterCount);
1091 /* Breakout the oplock request bits so we can set the
1092 reply bits separately. */
1093 int oplock_request = 0;
1094 mode_t unixmode;
1095 int pnum = -1;
1096 int fmode=0,rmode=0;
1097 SMB_OFF_T file_len = 0;
1098 SMB_STRUCT_STAT sbuf;
1099 int smb_action = 0;
1100 BOOL bad_path = False;
1101 files_struct *fsp = NULL;
1102 char *p = NULL;
1103 BOOL stat_open_only = False;
1104 uint32 flags;
1105 uint32 desired_access;
1106 uint32 file_attributes;
1107 uint32 share_access;
1108 uint32 create_disposition;
1109 uint32 create_options;
1110 uint32 fname_len;
1111 uint16 root_dir_fid;
1112 int smb_ofun;
1113 int smb_open_mode;
1114 int smb_attr;
1116 DEBUG(5,("call_nt_transact_create\n"));
1119 * Ensure minimum number of parameters sent.
1122 if(total_parameter_count < 54) {
1123 DEBUG(0,("call_nt_transact_create - insufficient parameters (%u)\n", (unsigned int)total_parameter_count));
1124 return(ERROR(ERRDOS,ERRbadaccess));
1127 flags = IVAL(params,0);
1128 desired_access = IVAL(params,8);
1129 file_attributes = IVAL(params,20);
1130 share_access = IVAL(params,24);
1131 create_disposition = IVAL(params,28);
1132 create_options = IVAL(params,32);
1133 fname_len = MIN(((uint32)IVAL(params,44)),((uint32)sizeof(fname)-1));
1134 root_dir_fid = (uint16)IVAL(params,4);
1135 smb_attr = (file_attributes & SAMBA_ATTRIBUTES_MASK);
1138 * We need to construct the open_and_X ofun value from the
1139 * NT values, as that's what our code is structured to accept.
1142 if((smb_ofun = map_create_disposition( create_disposition )) == -1)
1143 return(ERROR(ERRDOS,ERRbadmem));
1146 * Get the file name.
1149 if(root_dir_fid != 0) {
1151 * This filename is relative to a directory fid.
1154 files_struct *dir_fsp = file_fsp(params,4);
1155 size_t dir_name_len;
1157 if(!dir_fsp)
1158 return(ERROR(ERRDOS,ERRbadfid));
1160 if(!dir_fsp->is_directory) {
1162 * Check to see if this is a mac fork of some kind.
1165 get_filename_transact(&fname[0], params, 53,
1166 total_parameter_count - 53 - fname_len, fname_len);
1168 if( fname[0] == ':') {
1169 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1170 return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
1173 return(ERROR(ERRDOS,ERRbadfid));
1177 * Copy in the base directory name.
1180 pstrcpy( fname, dir_fsp->fsp_name );
1181 dir_name_len = strlen(fname);
1184 * Ensure it ends in a '\'.
1187 if((fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
1188 pstrcat(fname, "\\");
1189 dir_name_len++;
1193 * This next calculation can refuse a correct filename if we're dealing
1194 * with the Win2k unicode bug, but that would be rare. JRA.
1197 if(fname_len + dir_name_len >= sizeof(pstring))
1198 return(ERROR(ERRSRV,ERRfilespecs));
1200 get_filename_transact(&fname[dir_name_len], params, 53,
1201 total_parameter_count - 53 - fname_len, fname_len);
1203 } else {
1204 get_filename_transact(&fname[0], params, 53,
1205 total_parameter_count - 53 - fname_len, fname_len);
1208 /* If it's an IPC, use the pipe handler. */
1209 if (IS_IPC(conn)) {
1210 int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
1211 if(ret != 0)
1212 return ret;
1213 smb_action = FILE_WAS_OPENED;
1214 } else {
1217 * Now contruct the smb_open_mode value from the desired access
1218 * and the share access.
1221 if((smb_open_mode = map_share_mode( &stat_open_only, fname, create_options, desired_access,
1222 share_access, file_attributes)) == -1)
1223 return(ERROR(ERRDOS,ERRbadaccess));
1225 oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
1226 oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
1229 * Check if POSIX semantics are wanted.
1232 set_posix_case_semantics(file_attributes);
1234 unix_convert(fname,conn,0,&bad_path,NULL);
1236 fsp = file_new();
1237 if (!fsp) {
1238 restore_case_semantics(file_attributes);
1239 return(ERROR(ERRSRV,ERRnofids));
1242 if (!check_name(fname,conn)) {
1243 if((errno == ENOENT) && bad_path) {
1244 unix_ERR_class = ERRDOS;
1245 unix_ERR_code = ERRbadpath;
1247 file_free(fsp);
1249 restore_case_semantics(file_attributes);
1251 return(UNIXERROR(ERRDOS,ERRnoaccess));
1254 unixmode = unix_mode(conn,smb_attr | aARCH, fname);
1257 * If it's a request for a directory open, deal with it separately.
1260 if(create_options & FILE_DIRECTORY_FILE) {
1262 oplock_request = 0;
1265 * We will get a create directory here if the Win32
1266 * app specified a security descriptor in the
1267 * CreateDirectory() call.
1270 open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
1272 if(!fsp->open) {
1273 file_free(fsp);
1274 restore_case_semantics(file_attributes);
1275 return(UNIXERROR(ERRDOS,ERRnoaccess));
1278 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
1279 close_file(fsp,True);
1280 restore_case_semantics(file_attributes);
1281 return(ERROR(ERRDOS,ERRnoaccess));
1284 } else {
1287 * Ordinary file case.
1290 open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode,
1291 oplock_request,&rmode,&smb_action);
1293 if (!fsp->open) {
1295 if(errno == EISDIR) {
1298 * Fail the open if it was explicitly a non-directory file.
1301 if (create_options & FILE_NON_DIRECTORY_FILE) {
1302 file_free(fsp);
1303 restore_case_semantics(file_attributes);
1304 SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
1305 return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
1308 oplock_request = 0;
1309 open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
1311 if(!fsp->open) {
1312 file_free(fsp);
1313 restore_case_semantics(file_attributes);
1314 return(UNIXERROR(ERRDOS,ERRnoaccess));
1316 #ifdef EROFS
1317 } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
1318 #else /* !EROFS */
1319 } else if (errno == EACCES && stat_open_only) {
1320 #endif
1323 * We couldn't open normally and all we want
1324 * are the permissions. Try and do a stat open.
1327 oplock_request = 0;
1329 open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
1331 if(!fsp->open) {
1332 file_free(fsp);
1333 restore_case_semantics(file_attributes);
1334 return(UNIXERROR(ERRDOS,ERRnoaccess));
1336 } else {
1338 if((errno == ENOENT) && bad_path) {
1339 unix_ERR_class = ERRDOS;
1340 unix_ERR_code = ERRbadpath;
1342 file_free(fsp);
1344 restore_case_semantics(file_attributes);
1346 return(UNIXERROR(ERRDOS,ERRnoaccess));
1350 if(fsp->is_directory) {
1351 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
1352 close_file(fsp,True);
1353 restore_case_semantics(file_attributes);
1354 return(ERROR(ERRDOS,ERRnoaccess));
1356 } else {
1357 if (!fsp->stat_open && sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1358 close_file(fsp,False);
1359 restore_case_semantics(file_attributes);
1360 return(ERROR(ERRDOS,ERRnoaccess));
1364 file_len = sbuf.st_size;
1365 fmode = dos_mode(conn,fname,&sbuf);
1366 if(fmode == 0)
1367 fmode = FILE_ATTRIBUTE_NORMAL;
1369 if (fmode & aDIR) {
1370 close_file(fsp,False);
1371 restore_case_semantics(file_attributes);
1372 return(ERROR(ERRDOS,ERRnoaccess));
1376 * If the caller set the extended oplock request bit
1377 * and we granted one (by whatever means) - set the
1378 * correct bit for extended oplock reply.
1381 if (oplock_request && lp_fake_oplocks(SNUM(conn)))
1382 smb_action |= EXTENDED_OPLOCK_GRANTED;
1384 if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
1385 smb_action |= EXTENDED_OPLOCK_GRANTED;
1389 restore_case_semantics(file_attributes);
1391 /* Realloc the size of parameters and data we will return */
1392 params = *ppparams = Realloc(*ppparams, 69);
1393 if(params == NULL)
1394 return(ERROR(ERRDOS,ERRnomem));
1396 memset((char *)params,'\0',69);
1398 p = params;
1399 if (smb_action & EXTENDED_OPLOCK_GRANTED)
1400 SCVAL(p,0, BATCH_OPLOCK_RETURN);
1401 else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
1402 SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
1403 else
1404 SCVAL(p,0,NO_OPLOCK_RETURN);
1406 p += 2;
1407 if (IS_IPC(conn)) {
1408 SSVAL(p,0,pnum);
1409 } else {
1410 SSVAL(p,0,fsp->fnum);
1412 p += 2;
1413 SIVAL(p,0,smb_action);
1414 p += 8;
1416 if (IS_IPC(conn)) {
1418 * Deal with pipe return.
1420 p += 32;
1421 SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
1422 p += 20;
1423 /* File type. */
1424 SSVAL(p,0,FILE_TYPE_MESSAGE_MODE_PIPE);
1425 /* Device state. */
1426 SSVAL(p,2, 0x5FF); /* ? */
1427 } else {
1429 * Deal with file return.
1431 /* Create time. */
1432 put_long_date(p,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn))));
1433 p += 8;
1434 put_long_date(p,sbuf.st_atime); /* access time */
1435 p += 8;
1436 put_long_date(p,sbuf.st_mtime); /* write time */
1437 p += 8;
1438 put_long_date(p,sbuf.st_mtime); /* change time */
1439 p += 8;
1440 SIVAL(p,0,fmode); /* File Attributes. */
1441 p += 4;
1442 SOFF_T(p,0,file_len);
1443 p += 8;
1444 SOFF_T(p,0,file_len);
1447 DEBUG(5,("call_nt_transact_create: open name = %s\n", fname));
1449 /* Send the required number of replies */
1450 send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
1452 return -1;
1455 /****************************************************************************
1456 Reply to a NT CANCEL request.
1457 ****************************************************************************/
1458 int reply_ntcancel(connection_struct *conn,
1459 char *inbuf,char *outbuf,int length,int bufsize)
1462 * Go through and cancel any pending change notifies.
1465 int mid = SVAL(inbuf,smb_mid);
1466 remove_pending_change_notify_requests_by_mid(mid);
1467 remove_pending_lock_requests_by_mid(mid);
1469 DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
1471 return(-1);
1474 /****************************************************************************
1475 Reply to an unsolicited SMBNTtranss - just ignore it!
1476 ****************************************************************************/
1477 int reply_nttranss(connection_struct *conn,
1478 char *inbuf,char *outbuf,int length,int bufsize)
1480 DEBUG(4,("Ignoring nttranss of length %d\n",length));
1481 return(-1);
1484 /****************************************************************************
1485 Reply to an NT transact rename command.
1486 ****************************************************************************/
1488 static int call_nt_transact_rename(connection_struct *conn,
1489 char *inbuf, char *outbuf, int length,
1490 int bufsize,
1491 char **ppsetup, char **ppparams, char **ppdata)
1493 char *params = *ppparams;
1494 pstring new_name;
1495 files_struct *fsp = file_fsp(params, 0);
1496 BOOL replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
1497 uint32 fname_len = MIN((((uint32)IVAL(inbuf,smb_nt_TotalParameterCount)-4)),
1498 ((uint32)sizeof(new_name)-1));
1499 int outsize = 0;
1501 CHECK_FSP(fsp, conn);
1502 StrnCpy(new_name,params+4,fname_len);
1503 new_name[fname_len] = '\0';
1505 outsize = rename_internals(conn, inbuf, outbuf, fsp->fsp_name,
1506 new_name, replace_if_exists);
1507 if(outsize == 0) {
1509 * Rename was successful.
1511 send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
1513 DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
1514 fsp->fsp_name, new_name));
1516 outsize = -1;
1519 return(outsize);
1522 /****************************************************************************
1523 This is the structure to keep the information needed to
1524 determine if a directory has changed.
1525 *****************************************************************************/
1527 typedef struct {
1528 time_t modify_time; /* Info from the directory we're monitoring. */
1529 time_t status_time; /* Info from the directory we're monitoring. */
1530 time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
1531 unsigned int num_entries; /* Zero or the number of files in the directory. */
1532 } change_hash_data;
1534 /****************************************************************************
1535 This is the structure to queue to implement NT change
1536 notify. It consists of smb_size bytes stored from the
1537 transact command (to keep the mid, tid etc around).
1538 Plus the fid to examine and the time to check next.
1539 *****************************************************************************/
1541 typedef struct {
1542 ubi_slNode msg_next;
1543 files_struct *fsp;
1544 connection_struct *conn;
1545 uint32 flags;
1546 time_t next_check_time;
1547 change_hash_data change_data;
1548 char request_buf[smb_size];
1549 } change_notify_buf;
1551 static ubi_slList change_notify_queue = { NULL, (ubi_slNodePtr)&change_notify_queue, 0};
1553 /****************************************************************************
1554 Setup the common parts of the return packet and send it.
1555 *****************************************************************************/
1557 static void change_notify_reply_packet(char *inbuf, int error_class, uint32 error_code)
1559 extern int Client;
1560 char outbuf[smb_size+38];
1562 memset(outbuf, '\0', sizeof(outbuf));
1563 construct_reply_common(inbuf, outbuf);
1566 * If we're returning a 'too much in the directory changed' we need to
1567 * set this is an NT error status flags. If we don't then the (probably
1568 * untested) code in the NT redirector has a bug in that it doesn't re-issue
1569 * the change notify.... Ah - I *love* it when I get so deeply into this I
1570 * can even determine how MS failed to test stuff and why.... :-). JRA.
1573 if(error_class == 0) /* NT Error. */
1574 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
1576 ERROR(error_class,error_code);
1579 * Seems NT needs a transact command with an error code
1580 * in it. This is a longer packet than a simple error.
1582 set_message(outbuf,18,0,False);
1584 send_smb(Client,outbuf);
1587 /****************************************************************************
1588 Create the hash we will use to determine if the contents changed.
1589 *****************************************************************************/
1591 static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
1593 SMB_STRUCT_STAT st;
1594 files_struct *fsp = cnbp->fsp;
1596 memset((char *)change_data, '\0', sizeof(change_data));
1599 * Store the current timestamp on the directory we are monitoring.
1602 if(dos_stat(fsp->fsp_name, &st) < 0) {
1603 DEBUG(0,("create_directory_notify_hash: Unable to stat name = %s. \
1604 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1605 return False;
1608 change_data->modify_time = st.st_mtime;
1609 change_data->status_time = st.st_ctime;
1612 * If we are to watch for changes that are only stored
1613 * in inodes of files, not in the directory inode, we must
1614 * scan the directory and produce a unique identifier with
1615 * which we can determine if anything changed. We use the
1616 * modify and change times from all the files in the
1617 * directory, added together (ignoring wrapping if it's
1618 * larger than the max time_t value).
1621 if(cnbp->flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE)) {
1622 pstring full_name;
1623 char *p;
1624 char *fname;
1625 size_t remaining_len;
1626 size_t fullname_len;
1627 void *dp = OpenDir(cnbp->conn, fsp->fsp_name, True);
1629 if(dp == NULL) {
1630 DEBUG(0,("create_directory_notify_hash: Unable to open directory = %s. \
1631 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1632 return False;
1635 change_data->num_entries = 0;
1637 pstrcpy(full_name, fsp->fsp_name);
1638 pstrcat(full_name, "/");
1640 fullname_len = strlen(full_name);
1641 remaining_len = sizeof(full_name) - fullname_len - 1;
1642 p = &full_name[fullname_len];
1644 while ((fname = ReadDirName(dp))) {
1645 if(strequal(fname, ".") || strequal(fname, ".."))
1646 continue;
1648 change_data->num_entries++;
1649 safe_strcpy( p, fname, remaining_len);
1651 memset(&st, '\0', sizeof(st));
1654 * Do the stat - but ignore errors.
1657 if(dos_stat(full_name, &st) < 0) {
1658 DEBUG(5,("create_directory_notify_hash: Unable to stat content file = %s. \
1659 Error was %s\n", fsp->fsp_name, strerror(errno) ));
1661 change_data->total_time += (st.st_mtime + st.st_ctime);
1664 CloseDir(dp);
1667 return True;
1670 /****************************************************************************
1671 Delete entries by fnum from the change notify pending queue.
1672 *****************************************************************************/
1674 void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
1676 change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1677 change_notify_buf *prev = NULL;
1679 while(cnbp != NULL) {
1680 if(cnbp->fsp->fnum == fsp->fnum) {
1681 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1682 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1683 continue;
1686 prev = cnbp;
1687 cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1691 /****************************************************************************
1692 Delete entries by mid from the change notify pending queue. Always send reply.
1693 *****************************************************************************/
1695 static void remove_pending_change_notify_requests_by_mid(int mid)
1697 change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1698 change_notify_buf *prev = NULL;
1700 while(cnbp != NULL) {
1701 if(SVAL(cnbp->request_buf,smb_mid) == mid) {
1702 change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
1703 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1704 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1705 continue;
1708 prev = cnbp;
1709 cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1713 /****************************************************************************
1714 Delete entries by filename and cnum from the change notify pending queue.
1715 Always send reply.
1716 *****************************************************************************/
1718 void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
1720 change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1721 change_notify_buf *prev = NULL;
1723 while(cnbp != NULL) {
1725 * We know it refers to the same directory if the connection number and
1726 * the filename are identical.
1728 if((cnbp->fsp->conn == fsp->conn) && strequal(cnbp->fsp->fsp_name,fsp->fsp_name)) {
1729 change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
1730 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1731 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1732 continue;
1735 prev = cnbp;
1736 cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1740 /****************************************************************************
1741 Process the change notify queue. Note that this is only called as root.
1742 Returns True if there are still outstanding change notify requests on the
1743 queue.
1744 *****************************************************************************/
1746 BOOL process_pending_change_notify_queue(time_t t)
1748 change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1749 change_notify_buf *prev = NULL;
1751 if(cnbp == NULL)
1752 return False;
1754 if(cnbp->next_check_time >= t)
1755 return True;
1758 * It's time to check. Go through the queue and see if
1759 * the timestamps changed.
1762 while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
1763 change_hash_data change_data;
1764 connection_struct *conn = cnbp->conn;
1765 uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
1766 SVAL(cnbp->request_buf,smb_uid);
1768 ZERO_STRUCT(change_data);
1771 * Ensure we don't have any old chain_fsp values
1772 * sitting around....
1774 chain_size = 0;
1775 file_chain_reset();
1777 if(!become_user(conn,vuid)) {
1778 DEBUG(0,("process_pending_change_notify_queue: Unable to become user vuid=%d.\n",
1779 vuid ));
1781 * Remove the entry and return an error to the client.
1783 change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1784 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1785 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1786 continue;
1789 if(!become_service(conn,True)) {
1790 DEBUG(0,("process_pending_change_notify_queue: Unable to become service Error was %s.\n", strerror(errno) ));
1792 * Remove the entry and return an error to the client.
1794 change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1795 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1796 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1797 unbecome_user();
1798 continue;
1801 if(!create_directory_notify_hash( cnbp, &change_data)) {
1802 DEBUG(0,("process_pending_change_notify_queue: Unable to create change data for \
1803 directory %s\n", cnbp->fsp->fsp_name ));
1805 * Remove the entry and return an error to the client.
1807 change_notify_reply_packet(cnbp->request_buf,ERRSRV,ERRaccess);
1808 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1809 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1810 unbecome_user();
1811 continue;
1814 if(memcmp( (char *)&cnbp->change_data, (char *)&change_data, sizeof(change_data))) {
1816 * Remove the entry and return a change notify to the client.
1818 DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed.\n",
1819 cnbp->fsp->fsp_name ));
1820 change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
1821 free((char *)ubi_slRemNext( &change_notify_queue, prev));
1822 cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
1823 unbecome_user();
1824 continue;
1827 unbecome_user();
1830 * Move to the next in the list.
1832 prev = cnbp;
1833 cnbp = (change_notify_buf *)ubi_slNext(cnbp);
1836 return (cnbp != NULL);
1839 /****************************************************************************
1840 Return true if there are pending change notifies.
1841 ****************************************************************************/
1843 BOOL change_notifies_pending(void)
1845 change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
1846 return (cnbp != NULL);
1849 /****************************************************************************
1850 Reply to a notify change - queue the request and
1851 don't allow a directory to be opened.
1852 ****************************************************************************/
1854 static int call_nt_transact_notify_change(connection_struct *conn,
1855 char *inbuf, char *outbuf, int length,
1856 int bufsize,
1857 char **ppsetup,
1858 char **ppparams, char **ppdata)
1860 char *setup = *ppsetup;
1861 files_struct *fsp;
1862 change_notify_buf *cnbp;
1864 fsp = file_fsp(setup,4);
1866 DEBUG(3,("call_nt_transact_notify_change\n"));
1868 if(!fsp)
1869 return(ERROR(ERRDOS,ERRbadfid));
1871 if((!fsp->open) || (!fsp->is_directory) || (conn != fsp->conn))
1872 return(ERROR(ERRDOS,ERRbadfid));
1875 * Now queue an entry on the notify change stack. We timestamp
1876 * the entry we are adding so that we know when to scan next.
1877 * We only need to save smb_size bytes from this incoming packet
1878 * as we will always by returning a 'read the directory yourself'
1879 * error.
1882 if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
1883 DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
1884 return -1;
1887 memset((char *)cnbp, '\0', sizeof(change_notify_buf));
1889 memcpy(cnbp->request_buf, inbuf, smb_size);
1890 cnbp->fsp = fsp;
1891 cnbp->conn = conn;
1892 cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
1893 cnbp->flags = IVAL(setup, 0);
1895 if(!create_directory_notify_hash( cnbp, &cnbp->change_data )) {
1896 free((char *)cnbp);
1897 return(UNIXERROR(ERRDOS,ERRbadfid));
1901 * Adding to the tail enables us to check only
1902 * the head when scanning for change, as this entry
1903 * is forced to have the first timeout expiration.
1906 ubi_slAddTail(&change_notify_queue, cnbp);
1908 DEBUG(3,("call_nt_transact_notify_change: notify change called on directory \
1909 name = %s\n", fsp->fsp_name ));
1911 return -1;
1914 /****************************************************************************
1915 Map unix perms to NT.
1916 ****************************************************************************/
1918 static SEC_ACCESS map_unix_perms( int *pacl_type, mode_t perm, int r_mask, int w_mask, int x_mask, BOOL is_directory)
1920 SEC_ACCESS sa;
1921 uint32 nt_mask = 0;
1923 *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
1925 if((perm & (r_mask|w_mask|x_mask)) == (r_mask|w_mask|x_mask)) {
1926 nt_mask = UNIX_ACCESS_RWX;
1927 } else if((perm & (r_mask|w_mask|x_mask)) == 0) {
1928 nt_mask = UNIX_ACCESS_NONE;
1929 } else {
1930 nt_mask |= (perm & r_mask) ? UNIX_ACCESS_R : 0;
1931 if(is_directory)
1932 nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
1933 else
1934 nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
1935 nt_mask |= (perm & x_mask) ? UNIX_ACCESS_X : 0;
1937 init_sec_access(&sa,nt_mask);
1938 return sa;
1941 /****************************************************************************
1942 Function to create owner and group SIDs from a SMB_STRUCT_STAT.
1943 ****************************************************************************/
1945 static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
1947 extern DOM_SID global_sam_sid;
1949 sid_copy(powner_sid, &global_sam_sid);
1950 sid_copy(pgroup_sid, &global_sam_sid);
1951 sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid));
1952 sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid));
1955 /****************************************************************************
1956 Reply to query a security descriptor from an fsp. If it succeeds it allocates
1957 the space for the return elements and returns True.
1958 ****************************************************************************/
1960 static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
1962 extern DOM_SID global_sid_World;
1963 SMB_STRUCT_STAT sbuf;
1964 SEC_ACE ace_list[6];
1965 DOM_SID owner_sid;
1966 DOM_SID group_sid;
1967 size_t sec_desc_size;
1968 SEC_ACL *psa = NULL;
1969 SEC_ACCESS owner_access;
1970 int owner_acl_type;
1971 SEC_ACCESS group_access;
1972 int grp_acl_type;
1973 SEC_ACCESS other_access;
1974 int other_acl_type;
1975 int num_acls = 0;
1977 *ppdesc = NULL;
1979 if(!lp_nt_acl_support()) {
1980 sid_copy( &owner_sid, &global_sid_World);
1981 sid_copy( &group_sid, &global_sid_World);
1982 } else {
1984 if(fsp->is_directory || fsp->fd_ptr == NULL) {
1985 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
1986 return 0;
1988 } else {
1989 if(sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
1990 return 0;
1995 * Get the owner, group and world SIDs.
1998 create_file_sids(&sbuf, &owner_sid, &group_sid);
2001 * Create the generic 3 element UNIX acl.
2004 owner_access = map_unix_perms(&owner_acl_type, sbuf.st_mode,
2005 S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
2006 group_access = map_unix_perms(&grp_acl_type, sbuf.st_mode,
2007 S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
2008 other_access = map_unix_perms(&other_acl_type, sbuf.st_mode,
2009 S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
2011 if(owner_access.mask)
2012 init_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
2013 owner_access, 0);
2015 if(group_access.mask)
2016 init_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
2017 group_access, 0);
2019 if(other_access.mask)
2020 init_sec_ace(&ace_list[num_acls++], &global_sid_World, other_acl_type,
2021 other_access, 0);
2023 if(fsp->is_directory) {
2025 * For directory ACLs we also add in the inherited permissions
2026 * ACE entries. These are the permissions a file would get when
2027 * being created in the directory.
2029 mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
2031 owner_access = map_unix_perms(&owner_acl_type, mode,
2032 S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
2033 group_access = map_unix_perms(&grp_acl_type, mode,
2034 S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
2035 other_access = map_unix_perms(&other_acl_type, mode,
2036 S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
2038 if(owner_access.mask)
2039 init_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
2040 owner_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
2042 if(group_access.mask)
2043 init_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
2044 group_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
2046 if(other_access.mask)
2047 init_sec_ace(&ace_list[num_acls++], &global_sid_World, other_acl_type,
2048 other_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
2051 if(num_acls)
2052 if((psa = make_sec_acl( 3, num_acls, ace_list)) == NULL) {
2053 DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
2054 return 0;
2058 *ppdesc = make_standard_sec_desc( &owner_sid, &group_sid, psa, &sec_desc_size);
2060 if(!*ppdesc) {
2061 DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
2062 sec_desc_size = 0;
2065 free_sec_acl(&psa);
2067 return sec_desc_size;
2070 /****************************************************************************
2071 Reply to query a security descriptor - currently this is not implemented (it
2072 is planned to be though). Right now it just returns the same thing NT would
2073 when queried on a FAT filesystem. JRA.
2074 ****************************************************************************/
2076 static int call_nt_transact_query_security_desc(connection_struct *conn,
2077 char *inbuf, char *outbuf,
2078 int length, int bufsize,
2079 char **ppsetup, char **ppparams, char **ppdata)
2081 uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
2082 char *params = *ppparams;
2083 char *data = *ppdata;
2084 prs_struct pd;
2085 SEC_DESC *psd;
2086 size_t sec_desc_size;
2088 files_struct *fsp = file_fsp(params,0);
2090 if(!fsp)
2091 return(ERROR(ERRDOS,ERRbadfid));
2093 DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
2095 params = *ppparams = Realloc(*ppparams, 4);
2096 if(params == NULL)
2097 return(ERROR(ERRDOS,ERRnomem));
2100 * Get the permissions to return.
2103 if((sec_desc_size = get_nt_acl(fsp, &psd)) == 0)
2104 return(UNIXERROR(ERRDOS,ERRnoaccess));
2106 DEBUG(3,("call_nt_transact_query_security_desc: sec_desc_size = %d.\n",(int)sec_desc_size));
2108 SIVAL(params,0,(uint32)sec_desc_size);
2110 if(max_data_count < sec_desc_size) {
2112 free_sec_desc(&psd);
2114 send_nt_replies(inbuf, outbuf, bufsize, 0xC0000000|NT_STATUS_BUFFER_TOO_SMALL,
2115 params, 4, *ppdata, 0);
2116 return -1;
2120 * Allocate the data we will point this at.
2123 data = *ppdata = Realloc(*ppdata, sec_desc_size);
2124 if(data == NULL) {
2125 free_sec_desc(&psd);
2126 return(ERROR(ERRDOS,ERRnomem));
2129 memset(data, '\0', sec_desc_size);
2132 * Init the parse struct we will marshall into.
2135 prs_init(&pd, 0, 4, MARSHALL);
2138 * Setup the prs_struct to point at the memory we just
2139 * allocated.
2142 prs_give_memory( &pd, data, (uint32)sec_desc_size, False);
2145 * Finally, linearize into the outgoing buffer.
2148 if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
2149 free_sec_desc(&psd);
2150 DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
2151 security descriptor.\n"));
2153 * Return access denied for want of a better error message..
2155 return(UNIXERROR(ERRDOS,ERRnoaccess));
2159 * Now we can delete the security descriptor.
2162 free_sec_desc(&psd);
2164 send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
2165 return -1;
2168 /****************************************************************************
2169 Validate a SID.
2170 ****************************************************************************/
2172 static BOOL validate_unix_sid( DOM_SID *psid, uint32 *prid, DOM_SID *sd_sid)
2174 extern DOM_SID global_sam_sid;
2175 DOM_SID sid;
2177 if(!sd_sid) {
2178 DEBUG(5,("validate_unix_sid: sid missing.\n"));
2179 return False;
2182 sid_copy(psid, sd_sid);
2183 sid_copy(&sid, sd_sid);
2185 if(!sid_split_rid(&sid, prid)) {
2186 DEBUG(5,("validate_unix_sid: cannot get RID from sid.\n"));
2187 return False;
2190 if(!sid_equal( &sid, &global_sam_sid)) {
2191 DEBUG(5,("validate_unix_sid: sid is not ours.\n"));
2192 return False;
2195 return True;
2198 /****************************************************************************
2199 Map NT perms to UNIX.
2200 ****************************************************************************/
2202 #define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES)
2203 #define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
2204 #define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
2206 static mode_t map_nt_perms( SEC_ACCESS sec_access, int type)
2208 mode_t mode = 0;
2210 switch(type) {
2211 case S_IRUSR:
2212 if(sec_access.mask & GENERIC_ALL_ACCESS)
2213 mode = S_IRUSR|S_IWUSR|S_IXUSR;
2214 else {
2215 mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
2216 mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
2217 mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
2219 break;
2220 case S_IRGRP:
2221 if(sec_access.mask & GENERIC_ALL_ACCESS)
2222 mode = S_IRGRP|S_IWGRP|S_IXGRP;
2223 else {
2224 mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
2225 mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
2226 mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
2228 break;
2229 case S_IROTH:
2230 if(sec_access.mask & GENERIC_ALL_ACCESS)
2231 mode = S_IROTH|S_IWOTH|S_IXOTH;
2232 else {
2233 mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
2234 mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
2235 mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
2237 break;
2240 return mode;
2243 /****************************************************************************
2244 Unpack a SEC_DESC into a owner, group and set of UNIX permissions.
2245 ****************************************************************************/
2247 static BOOL unpack_nt_permissions(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp, mode_t *pmode,
2248 uint32 security_info_sent, SEC_DESC *psd, BOOL is_directory)
2250 extern DOM_SID global_sid_World;
2251 DOM_SID owner_sid;
2252 DOM_SID grp_sid;
2253 DOM_SID file_owner_sid;
2254 DOM_SID file_grp_sid;
2255 uint32 owner_rid;
2256 uint32 grp_rid;
2257 SEC_ACL *dacl = psd->dacl;
2258 BOOL all_aces_are_inherit_only = (is_directory ? True : False);
2259 int i;
2261 *pmode = 0;
2262 *puser = (uid_t)-1;
2263 *pgrp = (gid_t)-1;
2265 if(security_info_sent == 0) {
2266 DEBUG(0,("unpack_nt_permissions: no security info sent !\n"));
2267 return False;
2271 * Windows 2000 sends the owner and group SIDs as the logged in
2272 * user, not the connected user. But it still sends the file
2273 * owner SIDs on an ACL set. So we need to check for the file
2274 * owner and group SIDs as well as the owner SIDs. JRA.
2277 create_file_sids(psbuf, &file_owner_sid, &file_grp_sid);
2280 * Validate the owner and group SID's.
2283 memset(&owner_sid, '\0', sizeof(owner_sid));
2284 memset(&grp_sid, '\0', sizeof(grp_sid));
2286 DEBUG(5,("unpack_nt_permissions: validating owner_sid.\n"));
2289 * Don't immediately fail if the owner sid cannot be validated.
2290 * This may be a group chown only set.
2293 if(!validate_unix_sid( &owner_sid, &owner_rid, psd->owner_sid))
2294 DEBUG(3,("unpack_nt_permissions: unable to validate owner sid.\n"));
2295 else if(security_info_sent & OWNER_SECURITY_INFORMATION)
2296 *puser = pdb_user_rid_to_uid(owner_rid);
2299 * Don't immediately fail if the group sid cannot be validated.
2300 * This may be an owner chown only set.
2303 if(!validate_unix_sid( &grp_sid, &grp_rid, psd->grp_sid))
2304 DEBUG(3,("unpack_nt_permissions: unable to validate group sid.\n"));
2305 else if(security_info_sent & GROUP_SECURITY_INFORMATION)
2306 *pgrp = pdb_user_rid_to_gid(grp_rid);
2309 * If no DACL then this is a chown only security descriptor.
2312 if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !dacl) {
2313 *pmode = 0;
2314 return True;
2318 * Now go through the DACL and ensure that
2319 * any owner/group sids match.
2322 for(i = 0; i < dacl->num_aces; i++) {
2323 DOM_SID ace_sid;
2324 SEC_ACE *psa = &dacl->ace_list[i];
2326 if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) &&
2327 (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
2328 DEBUG(3,("unpack_nt_permissions: unable to set anything but an ALLOW or DENY ACE.\n"));
2329 return False;
2333 * Ignore or remove bits we don't care about on a directory ACE.
2336 if(is_directory) {
2337 if(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
2338 DEBUG(3,("unpack_nt_permissions: ignoring inherit only ACE.\n"));
2339 continue;
2343 * At least one of the ACE entries wasn't inherit only.
2344 * Flag this so we know the returned mode is valid.
2347 all_aces_are_inherit_only = False;
2351 * Windows 2000 sets these flags even on *file* ACE's. This is wrong
2352 * but we can ignore them for now. Revisit this when we go to POSIX
2353 * ACLs on directories.
2356 psa->flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT);
2358 if(psa->flags != 0) {
2359 DEBUG(1,("unpack_nt_permissions: unable to set ACE flags (%x).\n",
2360 (unsigned int)psa->flags));
2361 return False;
2365 * The security mask may be UNIX_ACCESS_NONE which should map into
2366 * no permissions (we overload the WRITE_OWNER bit for this) or it
2367 * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
2368 * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
2371 psa->info.mask &= (GENERIC_ALL_ACCESS|GENERIC_EXECUTE_ACCESS|GENERIC_WRITE_ACCESS|
2372 GENERIC_READ_ACCESS|UNIX_ACCESS_NONE|FILE_ALL_ATTRIBUTES);
2374 if(psa->info.mask != UNIX_ACCESS_NONE)
2375 psa->info.mask &= ~UNIX_ACCESS_NONE;
2377 sid_copy(&ace_sid, &psa->sid);
2379 if(sid_equal(&ace_sid, &file_owner_sid)) {
2381 * Map the desired permissions into owner perms.
2384 if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
2385 *pmode |= map_nt_perms( psa->info, S_IRUSR);
2386 else
2387 *pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
2389 } else if( sid_equal(&ace_sid, &file_grp_sid)) {
2391 * Map the desired permissions into group perms.
2394 if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
2395 *pmode |= map_nt_perms( psa->info, S_IRGRP);
2396 else
2397 *pmode &= ~(map_nt_perms( psa->info, S_IRGRP));
2399 } else if( sid_equal(&ace_sid, &global_sid_World)) {
2401 * Map the desired permissions into other perms.
2404 if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
2405 *pmode |= map_nt_perms( psa->info, S_IROTH);
2406 else
2407 *pmode &= ~(map_nt_perms( psa->info, S_IROTH));
2409 } else {
2410 DEBUG(0,("unpack_nt_permissions: unknown SID used in ACL.\n"));
2411 return False;
2415 if (is_directory && all_aces_are_inherit_only) {
2417 * Windows 2000 is doing one of these weird 'inherit acl'
2418 * traverses to conserve NTFS ACL resources. Just pretend
2419 * there was no DACL sent. JRA.
2422 DEBUG(10,("unpack_nt_permissions: Win2k inherit acl traverse. Ignoring DACL.\n"));
2423 free_sec_acl(&psd->dacl);
2426 return True;
2429 /****************************************************************************
2430 Reply to set a security descriptor. Map to UNIX perms.
2431 ****************************************************************************/
2433 static int call_nt_transact_set_security_desc(connection_struct *conn,
2434 char *inbuf, char *outbuf, int length,
2435 int bufsize, char **ppsetup,
2436 char **ppparams, char **ppdata)
2438 uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
2439 char *params= *ppparams;
2440 char *data = *ppdata;
2441 prs_struct pd;
2442 SEC_DESC *psd = NULL;
2443 uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
2444 uid_t user = (uid_t)-1;
2445 gid_t grp = (gid_t)-1;
2446 mode_t perms = 0;
2447 SMB_STRUCT_STAT sbuf;
2448 files_struct *fsp = NULL;
2449 uint32 security_info_sent = 0;
2450 BOOL got_dacl = False;
2452 if(!lp_nt_acl_support())
2453 return(UNIXERROR(ERRDOS,ERRnoaccess));
2455 if(total_parameter_count < 8)
2456 return(ERROR(ERRDOS,ERRbadfunc));
2458 if((fsp = file_fsp(params,0)) == NULL)
2459 return(ERROR(ERRDOS,ERRbadfid));
2461 security_info_sent = IVAL(params,4);
2463 DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
2464 (unsigned int)security_info_sent ));
2467 * Init the parse struct we will unmarshall from.
2470 prs_init(&pd, 0, 4, UNMARSHALL);
2473 * Setup the prs_struct to point at the memory we just
2474 * allocated.
2477 prs_give_memory( &pd, data, total_data_count, False);
2480 * Finally, unmarshall from the data buffer.
2483 if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
2484 free_sec_desc(&psd);
2485 DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
2486 security descriptor.\n"));
2488 * Return access denied for want of a better error message..
2490 return(UNIXERROR(ERRDOS,ERRnoaccess));
2494 * Get the current state of the file.
2497 if(fsp->is_directory) {
2498 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
2499 free_sec_desc(&psd);
2500 return(UNIXERROR(ERRDOS,ERRnoaccess));
2502 } else {
2504 int ret;
2506 if(fsp->fd_ptr == NULL)
2507 ret = dos_stat(fsp->fsp_name, &sbuf);
2508 else
2509 ret = sys_fstat(fsp->fd_ptr->fd,&sbuf);
2511 if(ret != 0) {
2512 free_sec_desc(&psd);
2513 return(UNIXERROR(ERRDOS,ERRnoaccess));
2518 * Unpack the user/group/world id's and permissions.
2521 if(!unpack_nt_permissions( &sbuf, &user, &grp, &perms, security_info_sent, psd, fsp->is_directory)) {
2522 free_sec_desc(&psd);
2523 return(UNIXERROR(ERRDOS,ERRnoaccess));
2526 if (psd->dacl != NULL)
2527 got_dacl = True;
2529 free_sec_desc(&psd);
2532 * Do we need to chown ?
2535 if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) {
2537 DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
2538 fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
2540 if(dos_chown( fsp->fsp_name, user, grp) == -1) {
2541 DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
2542 fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
2543 return(UNIXERROR(ERRDOS,ERRnoaccess));
2547 * Recheck the current state of the file, which may have changed.
2548 * (suid/sgid bits, for instance)
2551 if(fsp->is_directory) {
2552 if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
2553 return(UNIXERROR(ERRDOS,ERRnoaccess));
2555 } else {
2557 int ret;
2559 if(fsp->fd_ptr == NULL)
2560 ret = dos_stat(fsp->fsp_name, &sbuf);
2561 else
2562 ret = sys_fstat(fsp->fd_ptr->fd,&sbuf);
2564 if(ret != 0)
2565 return(UNIXERROR(ERRDOS,ERRnoaccess));
2570 * Only change security if we got a DACL.
2573 if((security_info_sent & DACL_SECURITY_INFORMATION) && got_dacl) {
2576 * Check to see if we need to change anything.
2577 * Enforce limits on modified bits *only*. Don't enforce masks
2578 * on bits not changed by the user.
2581 if(fsp->is_directory) {
2583 perms &= (lp_dir_security_mask(SNUM(conn)) | sbuf.st_mode);
2584 perms |= (lp_force_dir_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
2586 } else {
2588 perms &= (lp_security_mask(SNUM(conn)) | sbuf.st_mode);
2589 perms |= (lp_force_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
2594 * Preserve special bits.
2597 perms |= (sbuf.st_mode & ~0777);
2600 * Do we need to chmod ?
2603 if(sbuf.st_mode != perms) {
2605 DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
2606 fsp->fsp_name, (unsigned int)perms ));
2608 if(dos_chmod( fsp->fsp_name, perms) == -1) {
2609 DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
2610 fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
2611 return(UNIXERROR(ERRDOS,ERRnoaccess));
2616 send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
2617 return -1;
2620 /****************************************************************************
2621 Reply to IOCTL - not implemented - no plans.
2622 ****************************************************************************/
2623 static int call_nt_transact_ioctl(connection_struct *conn,
2624 char *inbuf, char *outbuf, int length,
2625 int bufsize,
2626 char **ppsetup, char **ppparams, char **ppdata)
2628 static BOOL logged_message = False;
2630 if(!logged_message) {
2631 DEBUG(3,("call_nt_transact_ioctl: Currently not implemented.\n"));
2632 logged_message = True; /* Only print this once... */
2634 return(ERROR(ERRSRV,ERRnosupport));
2637 /****************************************************************************
2638 Reply to a SMBNTtrans.
2639 ****************************************************************************/
2640 int reply_nttrans(connection_struct *conn,
2641 char *inbuf,char *outbuf,int length,int bufsize)
2643 int outsize = 0;
2644 #if 0 /* Not used. */
2645 uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
2646 uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
2647 uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
2648 #endif /* Not used. */
2649 uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
2650 uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
2651 uint32 parameter_count = IVAL(inbuf,smb_nt_ParameterCount);
2652 uint32 parameter_offset = IVAL(inbuf,smb_nt_ParameterOffset);
2653 uint32 data_count = IVAL(inbuf,smb_nt_DataCount);
2654 uint32 data_offset = IVAL(inbuf,smb_nt_DataOffset);
2655 uint16 setup_count = 2*CVAL(inbuf,smb_nt_SetupCount); /* setup count is in *words* */
2656 uint16 function_code = SVAL( inbuf, smb_nt_Function);
2657 char *params = NULL, *data = NULL, *setup = NULL;
2658 uint32 num_params_sofar, num_data_sofar;
2660 if(global_oplock_break && (function_code == NT_TRANSACT_CREATE)) {
2662 * Queue this open message as we are the process of an oplock break.
2665 DEBUG(2,("reply_nttrans: queueing message NT_TRANSACT_CREATE \
2666 due to being in oplock break state.\n" ));
2668 push_oplock_pending_smb_message( inbuf, length);
2669 return -1;
2672 outsize = set_message(outbuf,0,0,True);
2675 * All nttrans messages we handle have smb_wct == 19 + setup_count.
2676 * Ensure this is so as a sanity check.
2679 if(CVAL(inbuf, smb_wct) != 19 + (setup_count/2)) {
2680 DEBUG(2,("Invalid smb_wct %d in nttrans call (should be %d)\n",
2681 CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
2682 return(ERROR(ERRSRV,ERRerror));
2685 /* Allocate the space for the setup, the maximum needed parameters and data */
2687 if(setup_count > 0)
2688 setup = (char *)malloc(setup_count);
2689 if (total_parameter_count > 0)
2690 params = (char *)malloc(total_parameter_count);
2691 if (total_data_count > 0)
2692 data = (char *)malloc(total_data_count);
2694 if ((total_parameter_count && !params) || (total_data_count && !data) ||
2695 (setup_count && !setup)) {
2696 SAFE_FREE(setup);
2697 SAFE_FREE(params);
2698 SAFE_FREE(data);
2699 DEBUG(0,("reply_nttrans : Out of memory\n"));
2700 return ERROR(ERRDOS,ERRnomem);
2703 /* Copy the param and data bytes sent with this request into
2704 the params buffer */
2705 num_params_sofar = parameter_count;
2706 num_data_sofar = data_count;
2708 if (parameter_count > total_parameter_count || data_count > total_data_count)
2709 goto bad_param;
2711 if(setup) {
2712 DEBUG(10,("reply_nttrans: setup_count = %d\n", setup_count));
2713 if ((smb_nt_SetupStart + setup_count < smb_nt_SetupStart) ||
2714 (smb_nt_SetupStart + setup_count < setup_count))
2715 goto bad_param;
2716 if (smb_nt_SetupStart + setup_count > length)
2717 goto bad_param;
2719 memcpy( setup, &inbuf[smb_nt_SetupStart], setup_count);
2721 if(params) {
2722 DEBUG(10,("reply_nttrans: parameter_count = %d\n", parameter_count));
2723 if ((parameter_offset + parameter_count < parameter_offset) ||
2724 (parameter_offset + parameter_count < parameter_count))
2725 goto bad_param;
2726 if (smb_base(inbuf) + parameter_offset + parameter_count > inbuf + length)
2727 goto bad_param;
2729 memcpy( params, smb_base(inbuf) + parameter_offset, parameter_count);
2731 if(data) {
2732 DEBUG(10,("reply_nttrans: data_count = %d\n",data_count));
2733 if ((data_offset + data_count < data_offset) || (data_offset + data_count < data_count))
2734 goto bad_param;
2735 if (smb_base(inbuf) + data_offset + data_count > inbuf + length)
2736 goto bad_param;
2738 memcpy( data, smb_base(inbuf) + data_offset, data_count);
2742 if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2743 /* We need to send an interim response then receive the rest
2744 of the parameter/data bytes */
2745 outsize = set_message(outbuf,0,0,True);
2746 if (!send_smb(Client,outbuf))
2747 exit_server("reply_nttrans: send_smb failed.");
2749 while( num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
2750 BOOL ret;
2751 uint32 parameter_displacement;
2752 uint32 data_displacement;
2754 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2756 if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
2757 outsize = set_message(outbuf,0,0,True);
2758 if(ret) {
2759 DEBUG(0,("reply_nttrans: Invalid secondary nttrans packet\n"));
2760 } else {
2761 DEBUG(0,("reply_nttrans: %s in getting secondary nttrans response.\n",
2762 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2764 goto bad_param;
2767 /* Revise total_params and total_data in case they have changed downwards */
2768 if (IVAL(inbuf, smb_nts_TotalParameterCount) < total_parameter_count)
2769 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
2770 if (IVAL(inbuf, smb_nts_TotalDataCount) < total_data_count)
2771 total_data_count = IVAL(inbuf, smb_nts_TotalDataCount);
2773 parameter_count = IVAL(inbuf,smb_nts_ParameterCount);
2774 parameter_offset = IVAL(inbuf, smb_nts_ParameterOffset);
2775 parameter_displacement = IVAL(inbuf, smb_nts_ParameterDisplacement);
2776 num_params_sofar += parameter_count;
2778 data_count = IVAL(inbuf, smb_nts_DataCount);
2779 data_displacement = IVAL(inbuf, smb_nts_DataDisplacement);
2780 data_offset = IVAL(inbuf, smb_nts_DataOffset);
2781 num_data_sofar += data_count;
2783 if (num_params_sofar > total_parameter_count || num_data_sofar > total_data_count) {
2784 DEBUG(0,("reply_nttrans2: data overflow in secondary nttrans packet"));
2785 goto bad_param;
2788 if (parameter_count) {
2789 if (parameter_displacement + parameter_count >= total_parameter_count)
2790 goto bad_param;
2791 if ((parameter_displacement + parameter_count < parameter_displacement) ||
2792 (parameter_displacement + parameter_count < parameter_count))
2793 goto bad_param;
2794 if (smb_base(inbuf) + parameter_offset + parameter_count >= inbuf + bufsize)
2795 goto bad_param;
2796 if (params + parameter_displacement < params)
2797 goto bad_param;
2799 memcpy( &params[parameter_displacement], smb_base(inbuf) + parameter_offset, parameter_count);
2802 if (data_count) {
2803 if (data_displacement + data_count >= total_data_count)
2804 goto bad_param;
2805 if ((data_displacement + data_count < data_displacement) ||
2806 (data_displacement + data_count < data_count))
2807 goto bad_param;
2808 if (smb_base(inbuf) + data_offset + data_count >= inbuf + bufsize)
2809 goto bad_param;
2810 if (data + data_displacement < data)
2811 goto bad_param;
2813 memcpy( &data[data_displacement], smb_base(inbuf)+ data_offset, data_count);
2818 if (Protocol >= PROTOCOL_NT1) {
2819 uint16 flg2 = SVAL(outbuf,smb_flg2);
2820 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
2823 /* Now we must call the relevant NT_TRANS function */
2824 switch(function_code) {
2825 case NT_TRANSACT_CREATE:
2826 outsize = call_nt_transact_create(conn, inbuf, outbuf, length, bufsize,
2827 &setup, &params, &data);
2828 break;
2829 case NT_TRANSACT_IOCTL:
2830 outsize = call_nt_transact_ioctl(conn,
2831 inbuf, outbuf, length, bufsize,
2832 &setup, &params, &data);
2833 break;
2834 case NT_TRANSACT_SET_SECURITY_DESC:
2835 outsize = call_nt_transact_set_security_desc(conn, inbuf, outbuf,
2836 length, bufsize,
2837 &setup, &params, &data);
2838 break;
2839 case NT_TRANSACT_NOTIFY_CHANGE:
2840 outsize = call_nt_transact_notify_change(conn, inbuf, outbuf,
2841 length, bufsize,
2842 &setup, &params, &data);
2843 break;
2844 case NT_TRANSACT_RENAME:
2845 outsize = call_nt_transact_rename(conn, inbuf, outbuf, length,
2846 bufsize,
2847 &setup, &params, &data);
2848 break;
2850 case NT_TRANSACT_QUERY_SECURITY_DESC:
2851 outsize = call_nt_transact_query_security_desc(conn, inbuf, outbuf,
2852 length, bufsize,
2853 &setup, &params, &data);
2854 break;
2855 default:
2856 /* Error in request */
2857 DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
2858 if(setup)
2859 free(setup);
2860 if(params)
2861 free(params);
2862 if(data)
2863 free(data);
2864 return (ERROR(ERRSRV,ERRerror));
2867 /* As we do not know how many data packets will need to be
2868 returned here the various call_nt_transact_xxxx calls
2869 must send their own. Thus a call_nt_transact_xxxx routine only
2870 returns a value other than -1 when it wants to send
2871 an error packet.
2874 if(setup)
2875 free(setup);
2876 if(params)
2877 free(params);
2878 if(data)
2879 free(data);
2880 return outsize; /* If a correct response was needed the call_nt_transact_xxxx
2881 calls have already sent it. If outsize != -1 then it is
2882 returning an error packet. */
2883 bad_param:
2885 SAFE_FREE(params);
2886 SAFE_FREE(data);
2887 SAFE_FREE(setup);
2888 return ERROR(ERRDOS,ERRinvalidparam);