Fix clistr_pull error with unicode and -1 src_len. Stopped smbclient -L
[Samba/ekacnet.git] / source / smbd / trans2.c
blobb12a8a81b8198275e6fc4a0b6e087edf69d1ebcd
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-2001
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 extern int Protocol;
27 extern BOOL case_sensitive;
28 extern int smb_read_error;
29 extern fstring local_machine;
30 extern int global_oplock_break;
31 extern uint32 global_client_caps;
32 extern pstring global_myname;
34 /****************************************************************************
35 Send the required number of replies back.
36 We assume all fields other than the data fields are
37 set correctly for the type of call.
38 HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the max_send
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
50 extern int max_send;
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
53 int useable_space;
54 char *pp = params;
55 char *pd = pdata;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 1; /* JRA. This used to be 3. Set to 1 to make netmon parse ok. */
58 int data_alignment_offset = 0;
60 /* Initially set the wcnt area to be 10 - this is true for all
61 trans2 replies */
62 set_message(outbuf,10,0,True);
64 /* If there genuinely are no parameters or data to send just send
65 the empty packet */
66 if(params_to_send == 0 && data_to_send == 0)
68 if (!send_smb(smbd_server_fd(),outbuf))
69 exit_server("send_trans2_replies: send_smb failed.");
70 return 0;
73 /* When sending params and data ensure that both are nicely aligned */
74 /* Only do this alignment when there is also data to send - else
75 can cause NT redirector problems. */
76 if (((params_to_send % 4) != 0) && (data_to_send != 0))
77 data_alignment_offset = 4 - (params_to_send % 4);
79 /* Space is bufsize minus Netbios over TCP header minus SMB header */
80 /* The alignment_offset is to align the param bytes on an even byte
81 boundary. NT 4.0 Beta needs this to work correctly. */
82 useable_space = bufsize - ((smb_buf(outbuf)+
83 alignment_offset+data_alignment_offset) -
84 outbuf);
86 /* useable_space can never be more than max_send minus the
87 alignment offset. */
88 useable_space = MIN(useable_space,
89 max_send - (alignment_offset+data_alignment_offset));
92 while (params_to_send || data_to_send)
94 /* Calculate whether we will totally or partially fill this packet */
95 total_sent_thistime = params_to_send + data_to_send +
96 alignment_offset + data_alignment_offset;
97 /* We can never send more than useable_space */
99 * Note that 'useable_space' does not include the alignment offsets,
100 * but we must include the alignment offsets in the calculation of
101 * the length of the data we send over the wire, as the alignment offsets
102 * are sent here. Fix from Marc_Jacobsen@hp.com.
104 total_sent_thistime = MIN(total_sent_thistime, useable_space+
105 alignment_offset + data_alignment_offset);
107 set_message(outbuf, 10, total_sent_thistime, True);
109 /* Set total params and data to be sent */
110 SSVAL(outbuf,smb_tprcnt,paramsize);
111 SSVAL(outbuf,smb_tdrcnt,datasize);
113 /* Calculate how many parameters and data we can fit into
114 this packet. Parameters get precedence */
116 params_sent_thistime = MIN(params_to_send,useable_space);
117 data_sent_thistime = useable_space - params_sent_thistime;
118 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
120 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
122 /* smb_proff is the offset from the start of the SMB header to the
123 parameter bytes, however the first 4 bytes of outbuf are
124 the Netbios over TCP header. Thus use smb_base() to subtract
125 them from the calculation */
127 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
129 if(params_sent_thistime == 0)
130 SSVAL(outbuf,smb_prdisp,0);
131 else
132 /* Absolute displacement of param bytes sent in this packet */
133 SSVAL(outbuf,smb_prdisp,pp - params);
135 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
136 if(data_sent_thistime == 0)
138 SSVAL(outbuf,smb_droff,0);
139 SSVAL(outbuf,smb_drdisp, 0);
141 else
143 /* The offset of the data bytes is the offset of the
144 parameter bytes plus the number of parameters being sent this time */
145 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
146 smb_base(outbuf)) + params_sent_thistime + data_alignment_offset);
147 SSVAL(outbuf,smb_drdisp, pd - pdata);
150 /* Copy the param bytes into the packet */
151 if(params_sent_thistime)
152 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
153 /* Copy in the data bytes */
154 if(data_sent_thistime)
155 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime+
156 data_alignment_offset,pd,data_sent_thistime);
158 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
159 params_sent_thistime, data_sent_thistime, useable_space));
160 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
161 params_to_send, data_to_send, paramsize, datasize));
163 /* Send the packet */
164 if (!send_smb(smbd_server_fd(),outbuf))
165 exit_server("send_trans2_replies: send_smb failed.");
167 pp += params_sent_thistime;
168 pd += data_sent_thistime;
170 params_to_send -= params_sent_thistime;
171 data_to_send -= data_sent_thistime;
173 /* Sanity check */
174 if(params_to_send < 0 || data_to_send < 0)
176 DEBUG(0,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
177 params_to_send, data_to_send));
178 return -1;
182 return 0;
185 /****************************************************************************
186 Reply to a TRANSACT2_OPEN.
187 ****************************************************************************/
189 static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
190 int bufsize,
191 char **pparams, char **ppdata)
193 char *params = *pparams;
194 int16 open_mode = SVAL(params, 2);
195 int16 open_attr = SVAL(params,6);
196 BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
197 #if 0
198 BOOL return_additional_info = BITSETW(params,0);
199 int16 open_sattr = SVAL(params, 4);
200 time_t open_time = make_unix_date3(params+8);
201 #endif
202 int16 open_ofun = SVAL(params,12);
203 int32 open_size = IVAL(params,14);
204 char *pname = &params[28];
205 int16 namelen = strlen(pname)+1;
207 pstring fname;
208 mode_t unixmode;
209 SMB_OFF_T size=0;
210 int fmode=0,mtime=0,rmode;
211 SMB_INO_T inode = 0;
212 SMB_STRUCT_STAT sbuf;
213 int smb_action = 0;
214 BOOL bad_path = False;
215 files_struct *fsp;
217 StrnCpy(fname,pname,namelen);
219 DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",
220 fname,open_mode, open_attr, open_ofun, open_size));
222 if (IS_IPC(conn)) {
223 return(ERROR_DOS(ERRSRV,ERRaccess));
226 /* XXXX we need to handle passed times, sattr and flags */
228 unix_convert(fname,conn,0,&bad_path,&sbuf);
230 if (!check_name(fname,conn))
232 if((errno == ENOENT) && bad_path)
234 unix_ERR_class = ERRDOS;
235 unix_ERR_code = ERRbadpath;
237 return(UNIXERROR(ERRDOS,ERRnoaccess));
240 unixmode = unix_mode(conn,open_attr | aARCH, fname);
242 fsp = open_file_shared(conn,fname,&sbuf,open_mode,open_ofun,unixmode,
243 oplock_request, &rmode,&smb_action);
245 if (!fsp)
247 if((errno == ENOENT) && bad_path)
249 unix_ERR_class = ERRDOS;
250 unix_ERR_code = ERRbadpath;
252 return(UNIXERROR(ERRDOS,ERRnoaccess));
255 size = sbuf.st_size;
256 fmode = dos_mode(conn,fname,&sbuf);
257 mtime = sbuf.st_mtime;
258 inode = sbuf.st_ino;
259 if (fmode & aDIR) {
260 close_file(fsp,False);
261 return(ERROR_DOS(ERRDOS,ERRnoaccess));
264 /* Realloc the size of parameters and data we will return */
265 params = Realloc(*pparams, 28);
266 if( params == NULL ) {
267 return(ERROR_DOS(ERRDOS,ERRnomem));
269 *pparams = params;
271 memset((char *)params,'\0',28);
272 SSVAL(params,0,fsp->fnum);
273 SSVAL(params,2,fmode);
274 put_dos_date2(params,4, mtime);
275 SIVAL(params,8, (uint32)size);
276 SSVAL(params,12,rmode);
278 if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
279 smb_action |= EXTENDED_OPLOCK_GRANTED;
282 SSVAL(params,18,smb_action);
284 * WARNING - this may need to be changed if SMB_INO_T <> 4 bytes.
286 SIVAL(params,20,inode);
288 /* Send the required number of replies */
289 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
291 return -1;
294 /*********************************************************
295 Routine to check if a given string matches exactly.
296 as a special case a mask of "." does NOT match. That
297 is required for correct wildcard semantics
298 Case can be significant or not.
299 **********************************************************/
301 static BOOL exact_match(char *str,char *mask, BOOL case_sig)
303 if (mask[0] == '.' && mask[1] == 0)
304 return False;
305 if (case_sig)
306 return strcmp(str,mask)==0;
307 return strcasecmp(str,mask) == 0;
310 /****************************************************************************
311 Get a level dependent lanman2 dir entry.
312 ****************************************************************************/
314 static BOOL get_lanman2_dir_entry(connection_struct *conn,
315 char *path_mask,int dirtype,int info_level,
316 int requires_resume_key,
317 BOOL dont_descend,char **ppdata,
318 char *base_data, int space_remaining,
319 BOOL *out_of_space, BOOL *got_exact_match,
320 int *last_name_off)
322 char *dname;
323 BOOL found = False;
324 SMB_STRUCT_STAT sbuf;
325 pstring mask;
326 pstring pathreal;
327 pstring fname;
328 char *p, *pdata = *ppdata;
329 uint32 reskey=0;
330 int prev_dirpos=0;
331 int mode=0;
332 SMB_OFF_T size = 0;
333 SMB_OFF_T allocation_size = 0;
334 uint32 len;
335 time_t mdate=0, adate=0, cdate=0;
336 char *nameptr;
337 BOOL was_8_3;
338 int nt_extmode; /* Used for NT connections instead of mode */
339 BOOL needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
341 *fname = 0;
342 *out_of_space = False;
343 *got_exact_match = False;
345 if (!conn->dirptr)
346 return(False);
348 p = strrchr(path_mask,'/');
349 if(p != NULL) {
350 if(p[1] == '\0')
351 pstrcpy(mask,"*.*");
352 else
353 pstrcpy(mask, p+1);
354 } else
355 pstrcpy(mask, path_mask);
357 while (!found) {
358 BOOL got_match;
360 /* Needed if we run out of space */
361 prev_dirpos = TellDir(conn->dirptr);
362 dname = ReadDirName(conn->dirptr);
365 * Due to bugs in NT client redirectors we are not using
366 * resume keys any more - set them to zero.
367 * Check out the related comments in findfirst/findnext.
368 * JRA.
371 reskey = 0;
373 DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%lx now at offset %d\n",
374 (long)conn->dirptr,TellDir(conn->dirptr)));
376 if (!dname)
377 return(False);
379 pstrcpy(fname,dname);
381 if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
382 got_match = mask_match(fname, mask, case_sensitive);
384 if(!got_match && !is_8_3(fname, False)) {
387 * It turns out that NT matches wildcards against
388 * both long *and* short names. This may explain some
389 * of the wildcard wierdness from old DOS clients
390 * that some people have been seeing.... JRA.
393 pstring newname;
394 pstrcpy( newname, fname);
395 name_map_mangle( newname, True, False, SNUM(conn));
396 if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
397 got_match = mask_match(newname, mask, case_sensitive);
400 if(got_match) {
401 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
402 if (dont_descend && !isdots)
403 continue;
405 pstrcpy(pathreal,conn->dirpath);
406 if(needslash)
407 pstrcat(pathreal,"/");
408 pstrcat(pathreal,dname);
410 if (vfs_stat(conn,pathreal,&sbuf) != 0) {
411 /* Needed to show the msdfs symlinks as directories */
412 if(!lp_host_msdfs() || !lp_msdfs_root(SNUM(conn))
413 || !is_msdfs_link(conn, pathreal, NULL, NULL)) {
414 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",
415 pathreal,strerror(errno)));
416 continue;
417 } else {
418 DEBUG(5,("get_lanman2_dir_entry: Masquerading msdfs link %s as a directory\n", pathreal));
419 sbuf.st_mode = (sbuf.st_mode & 0xFFF) | S_IFDIR;
423 mode = dos_mode(conn,pathreal,&sbuf);
425 if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
426 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
427 continue;
430 size = sbuf.st_size;
431 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
432 mdate = sbuf.st_mtime;
433 adate = sbuf.st_atime;
434 cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
436 if (lp_dos_filetime_resolution(SNUM(conn))) {
437 cdate &= ~1;
438 mdate &= ~1;
439 adate &= ~1;
442 if(mode & aDIR)
443 size = 0;
445 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
447 found = True;
451 name_map_mangle(fname,False,True,SNUM(conn));
453 p = pdata;
454 nameptr = p;
456 nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
458 switch (info_level) {
459 case 1:
460 if(requires_resume_key) {
461 SIVAL(p,0,reskey);
462 p += 4;
464 put_dos_date2(p,l1_fdateCreation,cdate);
465 put_dos_date2(p,l1_fdateLastAccess,adate);
466 put_dos_date2(p,l1_fdateLastWrite,mdate);
467 SIVAL(p,l1_cbFile,(uint32)size);
468 SIVAL(p,l1_cbFileAlloc,(uint32)allocation_size);
469 SSVAL(p,l1_attrFile,mode);
470 SCVAL(p,l1_cchName,strlen(fname));
471 pstrcpy(p + l1_achName, fname);
472 nameptr = p + l1_achName;
473 p += l1_achName + strlen(fname) + 1;
474 break;
476 case 2:
477 if(requires_resume_key) {
478 SIVAL(p,0,reskey);
479 p += 4;
481 put_dos_date2(p,l2_fdateCreation,cdate);
482 put_dos_date2(p,l2_fdateLastAccess,adate);
483 put_dos_date2(p,l2_fdateLastWrite,mdate);
484 SIVAL(p,l2_cbFile,(uint32)size);
485 SIVAL(p,l2_cbFileAlloc,(uint32)allocation_size);
486 SSVAL(p,l2_attrFile,mode);
487 SIVAL(p,l2_cbList,0); /* No extended attributes */
488 SCVAL(p,l2_cchName,strlen(fname));
489 pstrcpy(p + l2_achName, fname);
490 nameptr = p + l2_achName;
491 p += l2_achName + strlen(fname) + 1;
492 break;
494 case 3:
495 SIVAL(p,0,reskey);
496 put_dos_date2(p,4,cdate);
497 put_dos_date2(p,8,adate);
498 put_dos_date2(p,12,mdate);
499 SIVAL(p,16,(uint32)size);
500 SIVAL(p,20,(uint32)allocation_size);
501 SSVAL(p,24,mode);
502 SIVAL(p,26,4);
503 CVAL(p,30) = strlen(fname);
504 pstrcpy(p+31, fname);
505 nameptr = p+31;
506 p += 31 + strlen(fname) + 1;
507 break;
509 case 4:
510 if(requires_resume_key) {
511 SIVAL(p,0,reskey);
512 p += 4;
514 SIVAL(p,0,33+strlen(fname)+1);
515 put_dos_date2(p,4,cdate);
516 put_dos_date2(p,8,adate);
517 put_dos_date2(p,12,mdate);
518 SIVAL(p,16,(uint32)size);
519 SIVAL(p,20,(uint32)allocation_size);
520 SSVAL(p,24,mode);
521 CVAL(p,32) = strlen(fname);
522 pstrcpy(p + 33, fname);
523 nameptr = p+33;
524 p += 33 + strlen(fname) + 1;
525 break;
527 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
528 was_8_3 = is_8_3(fname, True);
529 len = 94+strlen(fname);
530 len = (len + 3) & ~3;
531 SIVAL(p,0,len); p += 4;
532 SIVAL(p,0,reskey); p += 4;
533 put_long_date(p,cdate); p += 8;
534 put_long_date(p,adate); p += 8;
535 put_long_date(p,mdate); p += 8;
536 put_long_date(p,mdate); p += 8;
537 SOFF_T(p,0,size);
538 SOFF_T(p,8,allocation_size);
539 p += 16;
540 SIVAL(p,0,nt_extmode); p += 4;
541 SIVAL(p,0,strlen(fname)); p += 4;
542 SIVAL(p,0,0); p += 4;
543 if (!was_8_3) {
544 fstrcpy(p+2,fname);
545 if(!name_map_mangle(p+2,True,True,SNUM(conn)))
546 (p+2)[12] = 0;
547 strupper(p+2);
548 SSVAL(p, 0, strlen(p+2));
549 } else {
550 SSVAL(p,0,0);
551 *(p+2) = 0;
553 p += 2 + 24;
554 /* nameptr = p; */
555 pstrcpy(p,fname); p += strlen(p);
556 p = pdata + len;
557 break;
559 case SMB_FIND_FILE_DIRECTORY_INFO:
560 len = 64+strlen(fname);
561 len = (len + 3) & ~3;
562 SIVAL(p,0,len); p += 4;
563 SIVAL(p,0,reskey); p += 4;
564 put_long_date(p,cdate); p += 8;
565 put_long_date(p,adate); p += 8;
566 put_long_date(p,mdate); p += 8;
567 put_long_date(p,mdate); p += 8;
568 SOFF_T(p,0,size);
569 SOFF_T(p,8,allocation_size);
570 p += 16;
571 SIVAL(p,0,nt_extmode); p += 4;
572 SIVAL(p,0,strlen(fname)); p += 4;
573 pstrcpy(p,fname);
574 p = pdata + len;
575 break;
577 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
578 len = 68+strlen(fname);
579 len = (len + 3) & ~3;
580 SIVAL(p,0,len); p += 4;
581 SIVAL(p,0,reskey); p += 4;
582 put_long_date(p,cdate); p += 8;
583 put_long_date(p,adate); p += 8;
584 put_long_date(p,mdate); p += 8;
585 put_long_date(p,mdate); p += 8;
586 SOFF_T(p,0,size);
587 SOFF_T(p,8,allocation_size);
588 p += 16;
589 SIVAL(p,0,nt_extmode); p += 4;
590 SIVAL(p,0,strlen(fname)); p += 4;
591 SIVAL(p,0,0); p += 4;
592 pstrcpy(p,fname);
593 p = pdata + len;
594 break;
596 case SMB_FIND_FILE_NAMES_INFO:
597 len = 12+strlen(fname);
598 len = (len + 3) & ~3;
599 SIVAL(p,0,len); p += 4;
600 SIVAL(p,0,reskey); p += 4;
601 SIVAL(p,0,strlen(fname)); p += 4;
602 pstrcpy(p,fname);
603 p = pdata + len;
604 break;
606 default:
607 return(False);
611 if (PTR_DIFF(p,pdata) > space_remaining) {
612 /* Move the dirptr back to prev_dirpos */
613 SeekDir(conn->dirptr, prev_dirpos);
614 *out_of_space = True;
615 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
616 return False; /* Not finished - just out of space */
619 /* Setup the last_filename pointer, as an offset from base_data */
620 *last_name_off = PTR_DIFF(nameptr,base_data);
621 /* Advance the data pointer to the next slot */
622 *ppdata = p;
624 return(found);
627 /****************************************************************************
628 Reply to a TRANS2_FINDFIRST.
629 ****************************************************************************/
631 static int call_trans2findfirst(connection_struct *conn,
632 char *inbuf, char *outbuf, int bufsize,
633 char **pparams, char **ppdata)
635 /* We must be careful here that we don't return more than the
636 allowed number of data bytes. If this means returning fewer than
637 maxentries then so be it. We assume that the redirector has
638 enough room for the fixed number of parameter bytes it has
639 requested. */
640 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
641 char *params = *pparams;
642 char *pdata = *ppdata;
643 int dirtype = SVAL(params,0);
644 int maxentries = SVAL(params,2);
645 BOOL close_after_first = BITSETW(params+4,0);
646 BOOL close_if_end = BITSETW(params+4,1);
647 BOOL requires_resume_key = BITSETW(params+4,2);
648 int info_level = SVAL(params,6);
649 pstring directory;
650 pstring mask;
651 char *p, *wcard;
652 int last_name_off=0;
653 int dptr_num = -1;
654 int numentries = 0;
655 int i;
656 BOOL finished = False;
657 BOOL dont_descend = False;
658 BOOL out_of_space = False;
659 int space_remaining;
660 BOOL bad_path = False;
661 SMB_STRUCT_STAT sbuf;
663 *directory = *mask = 0;
665 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
666 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
667 info_level, max_data_bytes));
669 switch (info_level)
671 case 1:
672 case 2:
673 case 3:
674 case 4:
675 case SMB_FIND_FILE_DIRECTORY_INFO:
676 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
677 case SMB_FIND_FILE_NAMES_INFO:
678 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
679 break;
680 default:
681 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
684 pstrcpy(directory, params + 12); /* Complete directory path with
685 wildcard mask appended */
687 RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);
689 DEBUG(5,("path=%s\n",directory));
691 unix_convert(directory,conn,0,&bad_path,&sbuf);
692 if(!check_name(directory,conn)) {
693 if((errno == ENOENT) && bad_path)
695 unix_ERR_class = ERRDOS;
696 unix_ERR_code = ERRbadpath;
699 #if 0
700 /* Ugly - NT specific hack - maybe not needed ? (JRA) */
701 if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
702 (get_remote_arch() == RA_WINNT))
704 unix_ERR_class = ERRDOS;
705 unix_ERR_code = ERRbaddirectory;
707 #endif
709 return(UNIXERROR(ERRDOS,ERRbadpath));
712 p = strrchr(directory,'/');
713 if(p == NULL) {
714 pstrcpy(mask,directory);
715 pstrcpy(directory,"./");
716 } else {
717 pstrcpy(mask,p+1);
718 *p = 0;
721 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
723 pdata = Realloc(*ppdata, max_data_bytes + 1024);
724 if( pdata == NULL ) {
725 return(ERROR_DOS(ERRDOS,ERRnomem));
727 *ppdata = pdata;
728 memset((char *)pdata,'\0',max_data_bytes + 1024);
730 /* Realloc the params space */
731 params = Realloc(*pparams, 10);
732 if( params == NULL ) {
733 return ERROR_DOS(ERRDOS,ERRnomem);
735 *pparams = params;
737 dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
738 if (dptr_num < 0)
739 return(UNIXERROR(ERRDOS,ERRbadfile));
741 /* Save the wildcard match and attribs we are using on this directory -
742 needed as lanman2 assumes these are being saved between calls */
744 if(!(wcard = strdup(mask))) {
745 dptr_close(&dptr_num);
746 return ERROR_DOS(ERRDOS,ERRnomem);
749 dptr_set_wcard(dptr_num, wcard);
750 dptr_set_attr(dptr_num, dirtype);
752 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
754 /* We don't need to check for VOL here as this is returned by
755 a different TRANS2 call. */
757 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
758 conn->dirpath,lp_dontdescend(SNUM(conn))));
759 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
760 dont_descend = True;
762 p = pdata;
763 space_remaining = max_data_bytes;
764 out_of_space = False;
766 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
768 BOOL got_exact_match = False;
770 /* this is a heuristic to avoid seeking the dirptr except when
771 absolutely necessary. It allows for a filename of about 40 chars */
772 if (space_remaining < DIRLEN_GUESS && numentries > 0)
774 out_of_space = True;
775 finished = False;
777 else
779 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
780 requires_resume_key,dont_descend,
781 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
782 &last_name_off);
785 if (finished && out_of_space)
786 finished = False;
788 if (!finished && !out_of_space)
789 numentries++;
792 * As an optimisation if we know we aren't looking
793 * for a wildcard name (ie. the name matches the wildcard exactly)
794 * then we can finish on any (first) match.
795 * This speeds up large directory searches. JRA.
798 if(got_exact_match)
799 finished = True;
801 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
804 /* Check if we can close the dirptr */
805 if(close_after_first || (finished && close_if_end))
807 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
808 dptr_close(&dptr_num);
812 * If there are no matching entries we must return ERRDOS/ERRbadfile -
813 * from observation of NT.
816 if(numentries == 0) {
817 dptr_close(&dptr_num);
818 return ERROR_DOS(ERRDOS,ERRbadfile);
821 /* At this point pdata points to numentries directory entries. */
823 /* Set up the return parameter block */
824 SSVAL(params,0,dptr_num);
825 SSVAL(params,2,numentries);
826 SSVAL(params,4,finished);
827 SSVAL(params,6,0); /* Never an EA error */
828 SSVAL(params,8,last_name_off);
830 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
832 if ((! *directory) && dptr_path(dptr_num))
833 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
835 DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
836 smb_fn_name(CVAL(inbuf,smb_com)),
837 mask, directory, dirtype, numentries ) );
840 * Force a name mangle here to ensure that the
841 * mask as an 8.3 name is top of the mangled cache.
842 * The reasons for this are subtle. Don't remove
843 * this code unless you know what you are doing
844 * (see PR#13758). JRA.
847 if(!is_8_3( mask, False))
848 name_map_mangle(mask, True, True, SNUM(conn));
850 return(-1);
853 /****************************************************************************
854 Reply to a TRANS2_FINDNEXT.
855 ****************************************************************************/
857 static int call_trans2findnext(connection_struct *conn,
858 char *inbuf, char *outbuf,
859 int length, int bufsize,
860 char **pparams, char **ppdata)
862 /* We must be careful here that we don't return more than the
863 allowed number of data bytes. If this means returning fewer than
864 maxentries then so be it. We assume that the redirector has
865 enough room for the fixed number of parameter bytes it has
866 requested. */
867 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
868 char *params = *pparams;
869 char *pdata = *ppdata;
870 int dptr_num = SVAL(params,0);
871 int maxentries = SVAL(params,2);
872 uint16 info_level = SVAL(params,4);
873 uint32 resume_key = IVAL(params,6);
874 BOOL close_after_request = BITSETW(params+10,0);
875 BOOL close_if_end = BITSETW(params+10,1);
876 BOOL requires_resume_key = BITSETW(params+10,2);
877 BOOL continue_bit = BITSETW(params+10,3);
878 pstring resume_name;
879 pstring mask;
880 pstring directory;
881 char *p;
882 uint16 dirtype;
883 int numentries = 0;
884 int i, last_name_off=0;
885 BOOL finished = False;
886 BOOL dont_descend = False;
887 BOOL out_of_space = False;
888 int space_remaining;
890 *mask = *directory = *resume_name = 0;
892 pstrcpy( resume_name, params+12);
894 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
895 close_after_request=%d, close_if_end = %d requires_resume_key = %d \
896 resume_key = %d resume name = %s continue=%d level = %d\n",
897 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
898 requires_resume_key, resume_key, resume_name, continue_bit, info_level));
900 switch (info_level)
902 case 1:
903 case 2:
904 case 3:
905 case 4:
906 case SMB_FIND_FILE_DIRECTORY_INFO:
907 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
908 case SMB_FIND_FILE_NAMES_INFO:
909 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
910 break;
911 default:
912 return ERROR_DOS(ERRDOS,ERRunknownlevel);
915 pdata = Realloc( *ppdata, max_data_bytes + 1024);
916 if(pdata == NULL) {
917 return ERROR_DOS(ERRDOS,ERRnomem);
919 *ppdata = pdata;
920 memset((char *)pdata,'\0',max_data_bytes + 1024);
922 /* Realloc the params space */
923 params = Realloc(*pparams, 6*SIZEOFWORD);
924 if( params == NULL ) {
925 return ERROR_DOS(ERRDOS,ERRnomem);
927 *pparams = params;
929 /* Check that the dptr is valid */
930 if(!(conn->dirptr = dptr_fetch_lanman2(dptr_num)))
931 return ERROR_DOS(ERRDOS,ERRnofiles);
933 string_set(&conn->dirpath,dptr_path(dptr_num));
935 /* Get the wildcard mask from the dptr */
936 if((p = dptr_wcard(dptr_num))== NULL) {
937 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
938 return ERROR_DOS(ERRDOS,ERRnofiles);
940 pstrcpy(mask, p);
941 pstrcpy(directory,conn->dirpath);
943 /* Get the attr mask from the dptr */
944 dirtype = dptr_attr(dptr_num);
946 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%lX,%d)\n",
947 dptr_num, mask, dirtype,
948 (long)conn->dirptr,
949 TellDir(conn->dirptr)));
951 /* We don't need to check for VOL here as this is returned by
952 a different TRANS2 call. */
954 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",conn->dirpath,lp_dontdescend(SNUM(conn))));
955 if (in_list(conn->dirpath,lp_dontdescend(SNUM(conn)),case_sensitive))
956 dont_descend = True;
958 p = pdata;
959 space_remaining = max_data_bytes;
960 out_of_space = False;
963 * Seek to the correct position. We no longer use the resume key but
964 * depend on the last file name instead.
966 if(requires_resume_key && *resume_name && !continue_bit)
969 * Fix for NT redirector problem triggered by resume key indexes
970 * changing between directory scans. We now return a resume key of 0
971 * and instead look for the filename to continue from (also given
972 * to us by NT/95/smbfs/smbclient). If no other scans have been done between the
973 * findfirst/findnext (as is usual) then the directory pointer
974 * should already be at the correct place. Check this by scanning
975 * backwards looking for an exact (ie. case sensitive) filename match.
976 * If we get to the beginning of the directory and haven't found it then scan
977 * forwards again looking for a match. JRA.
980 int current_pos, start_pos;
981 char *dname = NULL;
982 void *dirptr = conn->dirptr;
983 start_pos = TellDir(dirptr);
984 for(current_pos = start_pos; current_pos >= 0; current_pos--)
986 DEBUG(7,("call_trans2findnext: seeking to pos %d\n", current_pos));
988 SeekDir(dirptr, current_pos);
989 dname = ReadDirName(dirptr);
992 * Remember, name_map_mangle is called by
993 * get_lanman2_dir_entry(), so the resume name
994 * could be mangled. Ensure we do the same
995 * here.
998 if(dname != NULL)
999 name_map_mangle( dname, False, True, SNUM(conn));
1001 if(dname && strcsequal( resume_name, dname))
1003 SeekDir(dirptr, current_pos+1);
1004 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1005 break;
1010 * Scan forward from start if not found going backwards.
1013 if(current_pos < 0)
1015 DEBUG(7,("call_trans2findnext: notfound: seeking to pos %d\n", start_pos));
1016 SeekDir(dirptr, start_pos);
1017 for(current_pos = start_pos; (dname = ReadDirName(dirptr)) != NULL; SeekDir(dirptr,++current_pos))
1020 * Remember, name_map_mangle is called by
1021 * get_lanman2_dir_entry(), so the resume name
1022 * could be mangled. Ensure we do the same
1023 * here.
1026 if(dname != NULL)
1027 name_map_mangle( dname, False, True, SNUM(conn));
1029 if(dname && strcsequal( resume_name, dname))
1031 SeekDir(dirptr, current_pos+1);
1032 DEBUG(7,("call_trans2findnext: got match at pos %d\n", current_pos+1 ));
1033 break;
1035 } /* end for */
1036 } /* end if current_pos */
1037 } /* end if requires_resume_key && !continue_bit */
1039 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
1041 BOOL got_exact_match = False;
1043 /* this is a heuristic to avoid seeking the dirptr except when
1044 absolutely necessary. It allows for a filename of about 40 chars */
1045 if (space_remaining < DIRLEN_GUESS && numentries > 0)
1047 out_of_space = True;
1048 finished = False;
1050 else
1052 finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
1053 requires_resume_key,dont_descend,
1054 &p,pdata,space_remaining, &out_of_space, &got_exact_match,
1055 &last_name_off);
1058 if (finished && out_of_space)
1059 finished = False;
1061 if (!finished && !out_of_space)
1062 numentries++;
1065 * As an optimisation if we know we aren't looking
1066 * for a wildcard name (ie. the name matches the wildcard exactly)
1067 * then we can finish on any (first) match.
1068 * This speeds up large directory searches. JRA.
1071 if(got_exact_match)
1072 finished = True;
1074 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
1077 /* Check if we can close the dirptr */
1078 if(close_after_request || (finished && close_if_end))
1080 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
1081 dptr_close(&dptr_num); /* This frees up the saved mask */
1085 /* Set up the return parameter block */
1086 SSVAL(params,0,numentries);
1087 SSVAL(params,2,finished);
1088 SSVAL(params,4,0); /* Never an EA error */
1089 SSVAL(params,6,last_name_off);
1091 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
1093 if ((! *directory) && dptr_path(dptr_num))
1094 slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
1096 DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
1097 smb_fn_name(CVAL(inbuf,smb_com)),
1098 mask, directory, dirtype, numentries ) );
1100 return(-1);
1103 /****************************************************************************
1104 Reply to a TRANS2_QFSINFO (query filesystem info).
1105 ****************************************************************************/
1107 static int call_trans2qfsinfo(connection_struct *conn,
1108 char *inbuf, char *outbuf,
1109 int length, int bufsize,
1110 char **pparams, char **ppdata)
1112 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1113 char *pdata = *ppdata;
1114 char *params = *pparams;
1115 uint16 info_level = SVAL(params,0);
1116 int data_len;
1117 SMB_STRUCT_STAT st;
1118 char *vname = volume_label(SNUM(conn));
1119 int snum = SNUM(conn);
1120 char *fstype = lp_fstype(SNUM(conn));
1122 DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
1124 if(vfs_stat(conn,".",&st)!=0) {
1125 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
1126 return ERROR_DOS(ERRSRV,ERRinvdevice);
1129 pdata = Realloc(*ppdata, max_data_bytes + 1024);
1130 if ( pdata == NULL ) {
1131 return ERROR_DOS(ERRDOS,ERRnomem);
1133 *ppdata = pdata;
1134 memset((char *)pdata,'\0',max_data_bytes + 1024);
1136 switch (info_level)
1138 case 1:
1140 SMB_BIG_UINT dfree,dsize,bsize;
1141 data_len = 18;
1142 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1143 SIVAL(pdata,l1_idFileSystem,st.st_dev);
1144 SIVAL(pdata,l1_cSectorUnit,bsize/512);
1145 SIVAL(pdata,l1_cUnit,dsize);
1146 SIVAL(pdata,l1_cUnitAvail,dfree);
1147 SSVAL(pdata,l1_cbSector,512);
1148 DEBUG(5,("call_trans2qfsinfo : bsize=%u, id=%x, cSectorUnit=%u, cUnit=%u, cUnitAvail=%u, cbSector=%d\n",
1149 (unsigned int)bsize, (unsigned int)st.st_dev, ((unsigned int)bsize)/512, (unsigned int)dsize,
1150 (unsigned int)dfree, 512));
1151 break;
1154 case 2:
1156 /* Return volume name */
1157 int volname_len = MIN(strlen(vname),11);
1158 data_len = l2_vol_szVolLabel + volname_len + 1;
1160 * Add volume serial number - hash of a combination of
1161 * the called hostname and the service name.
1163 SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
1164 SCVAL(pdata,l2_vol_cch,volname_len);
1165 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
1166 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
1167 (unsigned)st.st_ctime, volname_len,
1168 pdata+l2_vol_szVolLabel));
1169 break;
1172 case SMB_QUERY_FS_ATTRIBUTE_INFO:
1174 int fstype_len;
1175 SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
1176 (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
1177 #if 0 /* Old code. JRA. */
1178 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
1179 SIVAL(pdata,0,0x700FF);
1180 #endif /* Old code. */
1182 SIVAL(pdata,4,255); /* Max filename component length */
1183 /* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
1184 and will think we can't do long filenames */
1185 fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False);
1186 SIVAL(pdata,8,fstype_len);
1187 data_len = 12 + fstype_len;
1188 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1189 break;
1192 case SMB_QUERY_FS_LABEL_INFO:
1193 data_len = 4 + strlen(vname);
1194 SIVAL(pdata,0,strlen(vname));
1195 pstrcpy(pdata+4,vname);
1196 break;
1198 case SMB_QUERY_FS_VOLUME_INFO:
1201 * Add volume serial number - hash of a combination of
1202 * the called hostname and the service name.
1204 SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
1205 (str_checksum(local_machine)<<16));
1207 /* NT4 always serves this up as unicode but expects it to be
1208 * delivered as ascii! (tridge && JRA)
1210 if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) {
1211 data_len = 18 + strlen(vname);
1212 SIVAL(pdata,12,strlen(vname));
1213 pstrcpy(pdata+18,vname);
1214 } else {
1215 int vnamelen;
1217 vnamelen = dos_PutUniCode(pdata+18, vname, sizeof(pstring), False);
1218 data_len = 18 + vnamelen;
1219 SIVAL(pdata,12,vnamelen);
1220 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1223 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
1224 (int)strlen(vname),vname));
1225 break;
1227 case SMB_QUERY_FS_SIZE_INFO:
1229 SMB_BIG_UINT dfree,dsize,bsize;
1230 data_len = 24;
1231 conn->vfs_ops.disk_free(conn,".",False,&bsize,&dfree,&dsize);
1232 SBIG_UINT(pdata,0,dsize);
1233 SBIG_UINT(pdata,8,dfree);
1234 SIVAL(pdata,16,bsize/512);
1235 SIVAL(pdata,20,512);
1236 break;
1239 case SMB_QUERY_FS_DEVICE_INFO:
1240 data_len = 8;
1241 SIVAL(pdata,0,0); /* dev type */
1242 SIVAL(pdata,4,0); /* characteristics */
1243 break;
1245 case SMB_MAC_QUERY_FS_INFO:
1247 * Thursby MAC extension... ONLY on NTFS filesystems
1248 * once we do streams then we don't need this
1250 if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
1251 data_len = 88;
1252 SIVAL(pdata,84,0x100); /* Don't support mac... */
1253 break;
1255 /* drop through */
1256 default:
1257 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1260 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
1262 DEBUG( 4, ( "%s info_level = %d\n",
1263 smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
1265 return -1;
1268 /****************************************************************************
1269 Reply to a TRANS2_SETFSINFO (set filesystem info).
1270 ****************************************************************************/
1272 static int call_trans2setfsinfo(connection_struct *conn,
1273 char *inbuf, char *outbuf, int length,
1274 int bufsize,
1275 char **pparams, char **ppdata)
1277 /* Just say yes we did it - there is nothing that
1278 can be set here so it doesn't matter. */
1279 int outsize;
1280 DEBUG(3,("call_trans2setfsinfo\n"));
1282 if (!CAN_WRITE(conn))
1283 return(ERROR_DOS(ERRSRV,ERRaccess));
1285 outsize = set_message(outbuf,10,0,True);
1287 return outsize;
1290 /****************************************************************************
1291 Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
1292 file name or file id).
1293 ****************************************************************************/
1295 static int call_trans2qfilepathinfo(connection_struct *conn,
1296 char *inbuf, char *outbuf, int length,
1297 int bufsize,
1298 char **pparams,char **ppdata,
1299 int total_data)
1301 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
1302 char *params = *pparams;
1303 char *pdata = *ppdata;
1304 uint16 tran_call = SVAL(inbuf, smb_setup0);
1305 uint16 info_level;
1306 int mode=0;
1307 SMB_OFF_T size=0;
1308 SMB_OFF_T allocation_size=0;
1309 unsigned int data_size;
1310 SMB_STRUCT_STAT sbuf;
1311 pstring fname1;
1312 char *fname;
1313 char *p;
1314 int l;
1315 SMB_OFF_T pos = 0;
1316 BOOL bad_path = False;
1317 BOOL delete_pending = False;
1318 time_t c_time;
1320 if (tran_call == TRANSACT2_QFILEINFO) {
1321 files_struct *fsp = file_fsp(params,0);
1322 info_level = SVAL(params,2);
1324 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
1326 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1328 * This is actually a QFILEINFO on a directory
1329 * handle (returned from an NT SMB). NT5.0 seems
1330 * to do this call. JRA.
1332 fname = fsp->fsp_name;
1333 unix_convert(fname,conn,0,&bad_path,&sbuf);
1334 if (!check_name(fname,conn) ||
1335 (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1336 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1338 if((errno == ENOENT) && bad_path) {
1339 unix_ERR_class = ERRDOS;
1340 unix_ERR_code = ERRbadpath;
1342 return(UNIXERROR(ERRDOS,ERRbadpath));
1345 delete_pending = fsp->directory_delete_on_close;
1347 } else {
1349 * Original code - this is an open file.
1351 CHECK_FSP(fsp,conn);
1353 fname = fsp->fsp_name;
1354 if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) {
1355 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1356 return(UNIXERROR(ERRDOS,ERRbadfid));
1359 if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1)
1360 return(UNIXERROR(ERRDOS,ERRnoaccess));
1362 delete_pending = fsp->delete_on_close;
1364 } else {
1365 /* qpathinfo */
1366 info_level = SVAL(params,0);
1368 DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
1370 fname = &fname1[0];
1371 pstrcpy(fname,&params[6]);
1373 RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
1375 unix_convert(fname,conn,0,&bad_path,&sbuf);
1376 if (!check_name(fname,conn) || (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) {
1377 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1378 if((errno == ENOENT) && bad_path) {
1379 unix_ERR_class = ERRDOS;
1380 unix_ERR_code = ERRbadpath;
1382 return(UNIXERROR(ERRDOS,ERRbadpath));
1386 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1387 fname,info_level,tran_call,total_data));
1389 p = strrchr(fname,'/');
1390 if (!p)
1391 p = fname;
1392 else
1393 p++;
1394 l = strlen(p);
1395 mode = dos_mode(conn,fname,&sbuf);
1396 size = sbuf.st_size;
1397 allocation_size = SMB_ROUNDUP_ALLOCATION(sbuf.st_size);
1398 if (mode & aDIR)
1399 size = 0;
1401 /* from now on we only want the part after the / */
1402 fname = p;
1404 params = Realloc(*pparams,2);
1405 if ( params == NULL )
1406 return ERROR_DOS(ERRDOS,ERRnomem);
1407 *pparams = params;
1408 memset((char *)params,'\0',2);
1409 data_size = max_data_bytes + 1024;
1410 pdata = Realloc(*ppdata, data_size);
1411 if ( pdata == NULL )
1412 return ERROR_DOS(ERRDOS,ERRnomem);
1413 *ppdata = pdata;
1415 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1416 /* uggh, EAs for OS2 */
1417 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1418 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1421 memset((char *)pdata,'\0',data_size);
1423 c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
1425 if (lp_dos_filetime_resolution(SNUM(conn))) {
1426 c_time &= ~1;
1427 sbuf.st_atime &= ~1;
1428 sbuf.st_mtime &= ~1;
1429 sbuf.st_mtime &= ~1;
1432 switch (info_level) {
1433 case SMB_INFO_STANDARD:
1434 case SMB_INFO_QUERY_EA_SIZE:
1435 data_size = (info_level==1?22:26);
1436 put_dos_date2(pdata,l1_fdateCreation,c_time);
1437 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1438 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1439 SIVAL(pdata,l1_cbFile,(uint32)size);
1440 SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
1441 SSVAL(pdata,l1_attrFile,mode);
1442 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1443 break;
1445 case SMB_INFO_QUERY_EAS_FROM_LIST:
1446 data_size = 24;
1447 put_dos_date2(pdata,0,c_time);
1448 put_dos_date2(pdata,4,sbuf.st_atime);
1449 put_dos_date2(pdata,8,sbuf.st_mtime);
1450 SIVAL(pdata,12,(uint32)size);
1451 SIVAL(pdata,16,(uint32)allocation_size);
1452 SIVAL(pdata,20,mode);
1453 break;
1455 case SMB_INFO_QUERY_ALL_EAS:
1456 data_size = 4;
1457 SIVAL(pdata,0,data_size);
1458 break;
1460 case 6:
1461 return ERROR_DOS(ERRDOS,ERRbadfunc); /* os/2 needs this */
1463 case SMB_FILE_BASIC_INFORMATION:
1464 case SMB_QUERY_FILE_BASIC_INFO:
1466 if (info_level == SMB_QUERY_FILE_BASIC_INFO)
1467 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1468 else {
1469 data_size = 40;
1470 SIVAL(pdata,36,0);
1472 put_long_date(pdata,c_time);
1473 put_long_date(pdata+8,sbuf.st_atime);
1474 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1475 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1476 SIVAL(pdata,32,mode);
1478 DEBUG(5,("SMB_QFBI - "));
1481 time_t create_time = c_time;
1482 DEBUG(5,("create: %s ", ctime(&create_time)));
1485 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1486 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1487 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1488 DEBUG(5,("mode: %x\n", mode));
1490 break;
1492 case SMB_FILE_STANDARD_INFORMATION:
1493 case SMB_QUERY_FILE_STANDARD_INFO:
1495 data_size = 24;
1496 /* Fake up allocation size. */
1497 SOFF_T(pdata,0,allocation_size);
1498 SOFF_T(pdata,8,size);
1499 SIVAL(pdata,16,sbuf.st_nlink);
1500 CVAL(pdata,20) = 0;
1501 CVAL(pdata,21) = (mode&aDIR)?1:0;
1502 break;
1504 case SMB_FILE_EA_INFORMATION:
1505 case SMB_QUERY_FILE_EA_INFO:
1506 data_size = 4;
1507 SIVAL(pdata,0,0);
1508 break;
1510 /* Get the 8.3 name - used if NT SMB was negotiated. */
1512 case SMB_QUERY_FILE_ALT_NAME_INFO:
1514 pstring short_name;
1515 pstrcpy(short_name,p);
1516 /* Mangle if not already 8.3 */
1517 if(!is_8_3(short_name, True)) {
1518 if(!name_map_mangle(short_name,True,True,SNUM(conn)))
1519 *short_name = '\0';
1521 strupper(short_name);
1522 l = dos_PutUniCode(pdata + 4, short_name, sizeof(pstring), False);
1523 data_size = 4 + l;
1524 SIVAL(pdata,0,l);
1525 break;
1528 case SMB_QUERY_FILE_NAME_INFO:
1530 * The first part of this code is essential
1531 * to get security descriptors to work on mapped
1532 * drives. Don't ask how I discovered this unless
1533 * you like hearing about me suffering.... :-). JRA.
1536 if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
1537 l = l*2;
1538 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
1539 dos_PutUniCode(pdata + 4, "\\",sizeof(pstring), False);
1540 } else {
1541 pstrcpy(pdata+4,fname);
1543 data_size = 4 + l;
1544 SIVAL(pdata,0,l);
1545 break;
1547 case SMB_FILE_ALLOCATION_INFORMATION:
1548 case SMB_QUERY_FILE_ALLOCATION_INFO:
1549 data_size = 8;
1550 SOFF_T(pdata,0,allocation_size);
1551 break;
1553 case SMB_QUERY_FILE_END_OF_FILEINFO:
1554 case SMB_FILE_END_OF_FILE_INFORMATION:
1555 data_size = 8;
1556 SOFF_T(pdata,0,size);
1557 break;
1559 case SMB_QUERY_FILE_ALL_INFO:
1560 put_long_date(pdata,c_time);
1561 put_long_date(pdata+8,sbuf.st_atime);
1562 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1563 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1564 SIVAL(pdata,32,mode);
1565 pdata += 40;
1566 SOFF_T(pdata,0,allocation_size);
1567 SOFF_T(pdata,8,size);
1568 SIVAL(pdata,16,sbuf.st_nlink);
1569 CVAL(pdata,20) = delete_pending;
1570 CVAL(pdata,21) = (mode&aDIR)?1:0;
1571 pdata += 24;
1572 SINO_T(pdata,0,(SMB_INO_T)sbuf.st_ino);
1573 pdata += 8; /* index number */
1574 pdata += 4; /* EA info */
1575 if (mode & aRONLY)
1576 SIVAL(pdata,0,0xA9);
1577 else
1578 SIVAL(pdata,0,0xd01BF);
1579 pdata += 4;
1580 SOFF_T(pdata,0,pos); /* current offset */
1581 pdata += 8;
1582 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1583 pdata += 4;
1584 pdata += 4; /* alignment */
1585 SIVAL(pdata,0,l);
1586 pstrcpy(pdata+4,fname);
1587 pdata += 4 + l;
1588 data_size = PTR_DIFF(pdata,(*ppdata));
1589 break;
1591 case SMB_FILE_INTERNAL_INFORMATION:
1592 /* This should be an index number - looks like dev/ino to me :-) */
1593 SIVAL(pdata,0,sbuf.st_dev);
1594 SIVAL(pdata,4,sbuf.st_ino);
1595 data_size = 8;
1596 break;
1598 case SMB_FILE_ACCESS_INFORMATION:
1599 SIVAL(pdata,0,0x12019F); /* ??? */
1600 data_size = 4;
1601 break;
1603 case SMB_FILE_NAME_INFORMATION:
1604 /* Pathname with leading '\'. */
1606 pstring new_fname;
1607 size_t byte_len;
1609 pstrcpy(new_fname, "\\");
1610 pstrcat(new_fname, fname);
1611 byte_len = dos_PutUniCode(pdata+4,new_fname,max_data_bytes,False);
1612 SIVAL(pdata,0,byte_len);
1613 data_size = 4 + byte_len;
1614 break;
1617 case SMB_FILE_DISPOSITION_INFORMATION:
1618 data_size = 1;
1619 CVAL(pdata,0) = delete_pending;
1620 break;
1622 case SMB_FILE_POSITION_INFORMATION:
1623 data_size = 8;
1624 SOFF_T(pdata,0,pos);
1625 break;
1627 case SMB_FILE_MODE_INFORMATION:
1628 SIVAL(pdata,0,mode);
1629 data_size = 4;
1630 break;
1632 case SMB_FILE_ALIGNMENT_INFORMATION:
1633 SIVAL(pdata,0,0); /* No alignment needed. */
1634 data_size = 4;
1635 break;
1637 #if 0
1638 /* Not yet finished... JRA */
1639 case 1018:
1641 pstring new_fname;
1642 size_t byte_len;
1644 put_long_date(pdata,c_time);
1645 put_long_date(pdata+8,sbuf.st_atime);
1646 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1647 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1648 SIVAL(pdata,32,mode);
1649 SIVAL(pdata,36,0); /* ??? */
1650 SIVAL(pdata,40,0x20); /* ??? */
1651 SIVAL(pdata,44,0); /* ??? */
1652 SOFF_T(pdata,48,size);
1653 SIVAL(pdata,56,0x1); /* ??? */
1654 SIVAL(pdata,60,0); /* ??? */
1655 SIVAL(pdata,64,0); /* ??? */
1656 SIVAL(pdata,68,length); /* Following string length in bytes. */
1657 dos_PutUniCode(pdata+72,,False);
1658 break;
1660 #endif
1662 case SMB_FILE_ALTERNATE_NAME_INFORMATION:
1663 /* Last component of pathname. */
1665 size_t byte_len = dos_PutUniCode(pdata+4,fname,max_data_bytes,False);
1666 SIVAL(pdata,0,byte_len);
1667 data_size = 4 + byte_len;
1668 break;
1671 case SMB_FILE_STREAM_INFORMATION:
1672 if (mode & aDIR) {
1673 data_size = 0;
1674 } else {
1675 size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
1676 SIVAL(pdata,0,0); /* ??? */
1677 SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
1678 SOFF_T(pdata,8,size);
1679 SIVAL(pdata,16,allocation_size);
1680 SIVAL(pdata,20,0); /* ??? */
1681 data_size = 24 + byte_len;
1683 break;
1685 case SMB_FILE_COMPRESSION_INFORMATION:
1686 SOFF_T(pdata,0,size);
1687 SIVAL(pdata,8,0); /* ??? */
1688 SIVAL(pdata,12,0); /* ??? */
1689 data_size = 16;
1690 break;
1692 case SMB_FILE_NETWORK_OPEN_INFORMATION:
1693 put_long_date(pdata,c_time);
1694 put_long_date(pdata+8,sbuf.st_atime);
1695 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1696 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1697 SOFF_T(pdata,32,allocation_size); /* Allocation size. */
1698 SOFF_T(pdata,40,size);
1699 SIVAL(pdata,48,mode);
1700 SIVAL(pdata,52,0); /* ??? */
1701 data_size = 56;
1702 break;
1704 case SMB_FILE_ATTRIBUTE_TAG_INFORMATION:
1705 SIVAL(pdata,0,mode);
1706 SIVAL(pdata,4,0);
1707 data_size = 8;
1708 break;
1710 #if 0
1712 * NT4 server just returns "invalid query" to this - if we try to answer
1713 * it then NTws gets a BSOD! (tridge).
1716 case SMB_QUERY_FILE_STREAM_INFO:
1717 data_size = 24 + l;
1718 SIVAL(pdata,0,pos);
1719 SIVAL(pdata,4,size);
1720 SIVAL(pdata,12,allocation_size);
1721 SIVAL(pdata,20,l);
1722 pstrcpy(pdata+24,fname);
1723 break;
1724 #endif
1726 default:
1727 return ERROR_DOS(ERRDOS,ERRunknownlevel);
1730 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1732 return(-1);
1735 /****************************************************************************
1736 Deal with the internal needs of setting the delete on close flag. Note that
1737 as the tdb locking is recursive, it is safe to call this from within
1738 open_file_shared. JRA.
1739 ****************************************************************************/
1741 NTSTATUS set_delete_on_close_internal(files_struct *fsp, BOOL delete_on_close)
1744 * Only allow delete on close for writable shares.
1747 if (delete_on_close && !CAN_WRITE(fsp->conn)) {
1748 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but write access denied on share.\n",
1749 fsp->fsp_name ));
1750 return NT_STATUS_ACCESS_DENIED;
1753 * Only allow delete on close for files/directories opened with delete intent.
1756 if (delete_on_close && !GET_DELETE_ACCESS_REQUESTED(fsp->share_mode)) {
1757 DEBUG(10,("set_delete_on_close_internal: file %s delete on close flag set but delete access denied.\n",
1758 fsp->fsp_name ));
1759 return NT_STATUS_ACCESS_DENIED;
1762 if(fsp->is_directory) {
1763 fsp->directory_delete_on_close = delete_on_close;
1764 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, directory %s\n",
1765 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1766 } else if(fsp->stat_open) {
1768 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, stat open %s\n",
1769 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1771 } else {
1773 files_struct *iterate_fsp;
1776 * Modify the share mode entry for all files open
1777 * on this device and inode to tell other smbds we have
1778 * changed the delete on close flag. This will be noticed
1779 * in the close code, the last closer will delete the file
1780 * if flag is set.
1783 DEBUG(10,("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1784 delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
1786 if (lock_share_entry_fsp(fsp) == False)
1787 return NT_STATUS_ACCESS_DENIED;
1789 if (!modify_delete_flag(fsp->dev, fsp->inode, delete_on_close)) {
1790 DEBUG(0,("set_delete_on_close_internal: failed to change delete on close flag for file %s\n",
1791 fsp->fsp_name ));
1792 unlock_share_entry_fsp(fsp);
1793 return NT_STATUS_ACCESS_DENIED;
1797 * Release the lock.
1800 unlock_share_entry_fsp(fsp);
1803 * Go through all files we have open on the same device and
1804 * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
1805 * Other smbd's that have this file open will look in the share_mode on close.
1806 * take care of this (rare) case in close_file(). See the comment there.
1807 * NB. JRA. We don't really need to do this anymore - all should be taken
1808 * care of in the share_mode changes in the tdb.
1811 for(iterate_fsp = file_find_di_first(fsp->dev, fsp->inode);
1812 iterate_fsp; iterate_fsp = file_find_di_next(iterate_fsp))
1813 fsp->delete_on_close = delete_on_close;
1816 * Set the delete on close flag in the fsp.
1818 fsp->delete_on_close = delete_on_close;
1820 DEBUG(10, ("set_delete_on_close_internal: %s delete on close flag for fnum = %d, file %s\n",
1821 delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
1825 return NT_STATUS_OK;
1828 /****************************************************************************
1829 Reply to a TRANS2_SETFILEINFO (set file info by fileid).
1830 ****************************************************************************/
1832 static int call_trans2setfilepathinfo(connection_struct *conn,
1833 char *inbuf, char *outbuf, int length,
1834 int bufsize, char **pparams,
1835 char **ppdata, int total_data)
1837 char *params = *pparams;
1838 char *pdata = *ppdata;
1839 uint16 tran_call = SVAL(inbuf, smb_setup0);
1840 uint16 info_level;
1841 int mode=0;
1842 SMB_OFF_T size=0;
1843 struct utimbuf tvs;
1844 SMB_STRUCT_STAT sbuf;
1845 pstring fname1;
1846 char *fname = NULL;
1847 int fd = -1;
1848 BOOL bad_path = False;
1849 files_struct *fsp = NULL;
1851 if (tran_call == TRANSACT2_SETFILEINFO) {
1852 fsp = file_fsp(params,0);
1853 info_level = SVAL(params,2);
1855 if(fsp && (fsp->is_directory || fsp->stat_open)) {
1857 * This is actually a SETFILEINFO on a directory
1858 * handle (returned from an NT SMB). NT5.0 seems
1859 * to do this call. JRA.
1861 fname = fsp->fsp_name;
1862 unix_convert(fname,conn,0,&bad_path,&sbuf);
1863 if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
1864 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1865 if((errno == ENOENT) && bad_path) {
1866 unix_ERR_class = ERRDOS;
1867 unix_ERR_code = ERRbadpath;
1869 return(UNIXERROR(ERRDOS,ERRbadpath));
1871 } else if (fsp && fsp->print_file) {
1873 * Doing a DELETE_ON_CLOSE should cancel a print job.
1875 if (((info_level == SMB_SET_FILE_DISPOSITION_INFO)||(info_level == SMB_FILE_DISPOSITION_INFORMATION)) &&
1876 CVAL(pdata,0)) {
1877 fsp->share_mode = FILE_DELETE_ON_CLOSE;
1879 DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n",
1880 fsp->fsp_name ));
1882 SSVAL(params,0,0);
1883 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1884 return(-1);
1886 } else {
1888 * Original code - this is an open file.
1890 CHECK_FSP(fsp,conn);
1892 fname = fsp->fsp_name;
1893 fd = fsp->fd;
1895 if (vfs_fstat(fsp,fd,&sbuf) != 0) {
1896 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
1897 return(UNIXERROR(ERRDOS,ERRbadfid));
1900 } else {
1901 /* set path info */
1902 info_level = SVAL(params,0);
1903 fname = fname1;
1904 pstrcpy(fname,&params[6]);
1905 unix_convert(fname,conn,0,&bad_path,&sbuf);
1906 if(!check_name(fname, conn)) {
1907 if((errno == ENOENT) && bad_path) {
1908 unix_ERR_class = ERRDOS;
1909 unix_ERR_code = ERRbadpath;
1911 return(UNIXERROR(ERRDOS,ERRbadpath));
1914 if(!VALID_STAT(sbuf)) {
1915 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1916 if((errno == ENOENT) && bad_path) {
1917 unix_ERR_class = ERRDOS;
1918 unix_ERR_code = ERRbadpath;
1920 return(UNIXERROR(ERRDOS,ERRbadpath));
1924 if (!CAN_WRITE(conn))
1925 return ERROR_DOS(ERRSRV,ERRaccess);
1927 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1928 tran_call,fname,info_level,total_data));
1930 /* Realloc the parameter and data sizes */
1931 params = Realloc(*pparams,2);
1932 if(params == NULL)
1933 return ERROR_DOS(ERRDOS,ERRnomem);
1934 *pparams = params;
1936 SSVAL(params,0,0);
1938 size = sbuf.st_size;
1939 tvs.modtime = sbuf.st_mtime;
1940 tvs.actime = sbuf.st_atime;
1941 mode = dos_mode(conn,fname,&sbuf);
1943 if (total_data > 4 && IVAL(pdata,0) == total_data) {
1944 /* uggh, EAs for OS2 */
1945 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1946 return ERROR_DOS(ERRDOS,ERReasnotsupported);
1949 switch (info_level) {
1950 case SMB_INFO_STANDARD:
1951 case SMB_INFO_QUERY_EA_SIZE:
1953 /* access time */
1954 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1956 /* write time */
1957 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1959 mode = SVAL(pdata,l1_attrFile);
1960 size = IVAL(pdata,l1_cbFile);
1961 break;
1964 /* XXXX um, i don't think this is right.
1965 it's also not in the cifs6.txt spec.
1967 case SMB_INFO_QUERY_EAS_FROM_LIST:
1968 tvs.actime = make_unix_date2(pdata+8);
1969 tvs.modtime = make_unix_date2(pdata+12);
1970 size = IVAL(pdata,16);
1971 mode = IVAL(pdata,24);
1972 break;
1974 /* XXXX nor this. not in cifs6.txt, either. */
1975 case SMB_INFO_QUERY_ALL_EAS:
1976 tvs.actime = make_unix_date2(pdata+8);
1977 tvs.modtime = make_unix_date2(pdata+12);
1978 size = IVAL(pdata,16);
1979 mode = IVAL(pdata,24);
1980 break;
1982 case SMB_SET_FILE_BASIC_INFO:
1983 case SMB_FILE_BASIC_INFORMATION:
1985 /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
1986 time_t write_time;
1987 time_t changed_time;
1989 /* Ignore create time at offset pdata. */
1991 /* access time */
1992 tvs.actime = interpret_long_date(pdata+8);
1994 write_time = interpret_long_date(pdata+16);
1995 changed_time = interpret_long_date(pdata+24);
1997 tvs.modtime = MIN(write_time, changed_time);
1999 /* Prefer a defined time to an undefined one. */
2000 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2001 tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
2002 ? changed_time
2003 : write_time);
2005 /* attributes */
2006 mode = IVAL(pdata,32);
2007 break;
2010 case SMB_FILE_ALLOCATION_INFORMATION:
2011 case SMB_SET_FILE_ALLOCATION_INFO:
2013 int ret = -1;
2014 SMB_OFF_T allocation_size = IVAL(pdata,0);
2015 #ifdef LARGE_SMB_OFF_T
2016 allocation_size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2017 #else /* LARGE_SMB_OFF_T */
2018 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2019 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2020 #endif /* LARGE_SMB_OFF_T */
2021 DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n",
2022 fname, (double)allocation_size ));
2024 if(allocation_size != sbuf.st_size) {
2025 SMB_STRUCT_STAT new_sbuf;
2027 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new allocation size to %.0f\n",
2028 fname, (double)allocation_size ));
2030 if (fd == -1) {
2031 files_struct *new_fsp = NULL;
2032 int access_mode = 0;
2033 int action = 0;
2035 if(global_oplock_break) {
2036 /* Queue this file modify as we are the process of an oplock break. */
2038 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2039 DEBUGADD(2,( "in oplock break state.\n"));
2041 push_oplock_pending_smb_message(inbuf, length);
2042 return -1;
2045 new_fsp = open_file_shared(conn, fname, &sbuf,
2046 SET_OPEN_MODE(DOS_OPEN_RDWR),
2047 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2048 0, 0, &access_mode, &action);
2050 if (new_fsp == NULL)
2051 return(UNIXERROR(ERRDOS,ERRbadpath));
2052 ret = vfs_allocate_file_space(new_fsp, allocation_size);
2053 if (vfs_fstat(new_fsp,new_fsp->fd,&new_sbuf) != 0) {
2054 DEBUG(3,("fstat of fnum %d failed (%s)\n",new_fsp->fnum, strerror(errno)));
2055 ret = -1;
2057 close_file(new_fsp,True);
2058 } else {
2059 ret = vfs_allocate_file_space(fsp, allocation_size);
2060 if (vfs_fstat(fsp,fd,&new_sbuf) != 0) {
2061 DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno)));
2062 ret = -1;
2065 if (ret == -1)
2066 return ERROR_NT(NT_STATUS_DISK_FULL);
2068 /* Allocate can trucate size... */
2069 size = new_sbuf.st_size;
2072 break;
2075 case SMB_FILE_END_OF_FILE_INFORMATION:
2076 case SMB_SET_FILE_END_OF_FILE_INFO:
2078 size = IVAL(pdata,0);
2079 #ifdef LARGE_SMB_OFF_T
2080 size |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
2081 #else /* LARGE_SMB_OFF_T */
2082 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
2083 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2084 #endif /* LARGE_SMB_OFF_T */
2085 DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
2086 break;
2089 case SMB_FILE_DISPOSITION_INFORMATION:
2090 case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
2092 BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
2093 NTSTATUS status;
2095 if (tran_call != TRANSACT2_SETFILEINFO)
2096 return(ERROR_DOS(ERRDOS,ERRunknownlevel));
2098 if (fsp == NULL)
2099 return(UNIXERROR(ERRDOS,ERRbadfid));
2101 status = set_delete_on_close_internal(fsp, delete_on_close);
2103 if (NT_STATUS_V(status) != NT_STATUS_V(NT_STATUS_OK))
2104 return ERROR_NT(status);
2106 break;
2109 default:
2110 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2113 /* get some defaults (no modifications) if any info is zero or -1. */
2114 if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
2115 tvs.actime = sbuf.st_atime;
2117 if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
2118 tvs.modtime = sbuf.st_mtime;
2120 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
2121 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
2122 DEBUG(6,("size: %.0f ", (double)size));
2123 DEBUG(6,("mode: %x\n" , mode));
2125 if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
2126 (info_level == SMB_SET_FILE_ALLOCATION_INFO) ||
2127 (info_level == SMB_FILE_ALLOCATION_INFORMATION) ||
2128 (info_level == SMB_FILE_END_OF_FILE_INFORMATION))) {
2130 * Only do this test if we are not explicitly
2131 * changing the size of a file.
2133 if (!size)
2134 size = sbuf.st_size;
2138 * Try and set the times, size and mode of this file -
2139 * if they are different from the current values
2142 if (sbuf.st_mtime != tvs.modtime || sbuf.st_atime != tvs.actime) {
2143 if(fsp != NULL) {
2145 * This was a setfileinfo on an open file.
2146 * NT does this a lot. It's actually pointless
2147 * setting the time here, as it will be overwritten
2148 * on the next write, so we save the request
2149 * away and will set it on file code. JRA.
2152 if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
2153 DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
2154 ctime(&tvs.modtime) ));
2155 fsp->pending_modtime = tvs.modtime;
2158 } else {
2160 DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
2162 if(file_utime(conn, fname, &tvs)!=0)
2163 return(UNIXERROR(ERRDOS,ERRnoaccess));
2167 /* check the mode isn't different, before changing it */
2168 if ((mode != 0) && (mode != dos_mode(conn, fname, &sbuf))) {
2170 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
2171 fname, mode ));
2173 if(file_chmod(conn, fname, mode, NULL)) {
2174 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
2175 return(UNIXERROR(ERRDOS,ERRnoaccess));
2179 if(size != sbuf.st_size) {
2181 DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
2182 fname, (double)size ));
2184 if (fd == -1) {
2185 files_struct *new_fsp = NULL;
2186 int access_mode = 0;
2187 int action = 0;
2189 if(global_oplock_break) {
2190 /* Queue this file modify as we are the process of an oplock break. */
2192 DEBUG(2,("call_trans2setfilepathinfo: queueing message due to being "));
2193 DEBUGADD(2,( "in oplock break state.\n"));
2195 push_oplock_pending_smb_message(inbuf, length);
2196 return -1;
2199 new_fsp = open_file_shared(conn, fname, &sbuf,
2200 SET_OPEN_MODE(DOS_OPEN_RDWR),
2201 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
2202 0, 0, &access_mode, &action);
2204 if (new_fsp == NULL)
2205 return(UNIXERROR(ERRDOS,ERRbadpath));
2206 vfs_set_filelen(new_fsp, size);
2207 close_file(new_fsp,True);
2208 } else {
2209 vfs_set_filelen(fsp, size);
2213 SSVAL(params,0,0);
2215 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2217 return(-1);
2220 /****************************************************************************
2221 Reply to a TRANS2_MKDIR (make directory with extended attributes).
2222 ****************************************************************************/
2224 static int call_trans2mkdir(connection_struct *conn,
2225 char *inbuf, char *outbuf, int length, int bufsize,
2226 char **pparams, char **ppdata)
2228 char *params = *pparams;
2229 pstring directory;
2230 int ret = -1;
2231 SMB_STRUCT_STAT sbuf;
2232 BOOL bad_path = False;
2234 if (!CAN_WRITE(conn))
2235 return ERROR_DOS(ERRSRV,ERRaccess);
2237 pstrcpy(directory, &params[4]);
2239 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
2241 unix_convert(directory,conn,0,&bad_path,&sbuf);
2242 if (check_name(directory,conn))
2243 ret = vfs_mkdir(conn,directory,unix_mode(conn,aDIR,directory));
2245 if(ret < 0)
2247 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
2248 if((errno == ENOENT) && bad_path)
2250 unix_ERR_class = ERRDOS;
2251 unix_ERR_code = ERRbadpath;
2253 return(UNIXERROR(ERRDOS,ERRnoaccess));
2256 /* Realloc the parameter and data sizes */
2257 params = Realloc(*pparams,2);
2258 if(params == NULL) {
2259 return ERROR_DOS(ERRDOS,ERRnomem);
2261 *pparams = params;
2263 SSVAL(params,0,0);
2265 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
2267 return(-1);
2270 /****************************************************************************
2271 Reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes).
2272 We don't actually do this - we just send a null response.
2273 ****************************************************************************/
2275 static int call_trans2findnotifyfirst(connection_struct *conn,
2276 char *inbuf, char *outbuf,
2277 int length, int bufsize,
2278 char **pparams, char **ppdata)
2280 static uint16 fnf_handle = 257;
2281 char *params = *pparams;
2282 uint16 info_level = SVAL(params,4);
2284 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
2286 switch (info_level)
2288 case 1:
2289 case 2:
2290 break;
2291 default:
2292 return ERROR_DOS(ERRDOS,ERRunknownlevel);
2295 /* Realloc the parameter and data sizes */
2296 params = Realloc(*pparams,6);
2297 if(params == NULL) {
2298 return ERROR_DOS(ERRDOS,ERRnomem);
2300 *pparams = params;
2302 SSVAL(params,0,fnf_handle);
2303 SSVAL(params,2,0); /* No changes */
2304 SSVAL(params,4,0); /* No EA errors */
2306 fnf_handle++;
2308 if(fnf_handle == 0)
2309 fnf_handle = 257;
2311 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
2313 return(-1);
2316 /****************************************************************************
2317 Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
2318 changes). Currently this does nothing.
2319 ****************************************************************************/
2321 static int call_trans2findnotifynext(connection_struct *conn,
2322 char *inbuf, char *outbuf,
2323 int length, int bufsize,
2324 char **pparams, char **ppdata)
2326 char *params = *pparams;
2328 DEBUG(3,("call_trans2findnotifynext\n"));
2330 /* Realloc the parameter and data sizes */
2331 params = Realloc(*pparams,4);
2332 if(params == NULL) {
2333 return ERROR_DOS(ERRDOS,ERRnomem);
2335 *pparams = params;
2337 SSVAL(params,0,0); /* No changes */
2338 SSVAL(params,2,0); /* No EA errors */
2340 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
2342 return(-1);
2345 /****************************************************************************
2346 Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
2347 ****************************************************************************/
2349 static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
2350 char* outbuf, int length, int bufsize,
2351 char** pparams, char** ppdata)
2353 char *params = *pparams;
2354 enum remote_arch_types ra_type = get_remote_arch();
2355 BOOL NT_arch = ((ra_type == RA_WINNT) || (ra_type == RA_WIN2K));
2356 pstring pathname;
2357 int reply_size = 0;
2358 int max_referral_level = SVAL(params,0);
2361 DEBUG(10,("call_trans2getdfsreferral\n"));
2363 if(!lp_host_msdfs())
2364 return ERROR_DOS(ERRDOS,ERRbadfunc);
2366 /* if pathname is in UNICODE, convert to DOS */
2367 /* NT always sends in UNICODE, may not set UNICODE flag */
2368 if(NT_arch || (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS))
2370 unistr_to_dos(pathname, &params[2], sizeof(pathname));
2371 DEBUG(10,("UNICODE referral for %s\n",pathname));
2373 else
2374 pstrcpy(pathname,&params[2]);
2376 if((reply_size = setup_dfs_referral(pathname,max_referral_level,ppdata)) < 0)
2377 return ERROR_DOS(ERRDOS,ERRbadfile);
2379 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_UNICODE_STRINGS |
2380 FLAGS2_DFS_PATHNAMES);
2381 send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
2383 return(-1);
2386 #define LMCAT_SPL 0x53
2387 #define LMFUNC_GETJOBID 0x60
2389 /****************************************************************************
2390 reply to a TRANS2_IOCTL - used for OS/2 printing.
2391 ****************************************************************************/
2393 static int call_trans2ioctl(connection_struct *conn, char* inbuf,
2394 char* outbuf, int length, int bufsize,
2395 char** pparams, char** ppdata)
2397 char *pdata = *ppdata;
2398 files_struct *fsp = file_fsp(inbuf,smb_vwv15);
2400 if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2401 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2402 pdata = Realloc(*ppdata, 32);
2403 if(pdata == NULL) {
2404 return ERROR_DOS(ERRDOS,ERRnomem);
2406 *ppdata = pdata;
2408 SSVAL(pdata,0,fsp->print_jobid); /* Job number */
2409 StrnCpy(pdata+2, global_myname, 15); /* Our NetBIOS name */
2410 StrnCpy(pdata+18, lp_servicename(SNUM(conn)), 13); /* Service name */
2411 send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
2412 return(-1);
2413 } else {
2414 DEBUG(2,("Unknown TRANS2_IOCTL\n"));
2415 return ERROR_DOS(ERRSRV,ERRerror);
2419 /****************************************************************************
2420 Reply to a SMBfindclose (stop trans2 directory search).
2421 ****************************************************************************/
2423 int reply_findclose(connection_struct *conn,
2424 char *inbuf,char *outbuf,int length,int bufsize)
2426 int outsize = 0;
2427 int dptr_num=SVALS(inbuf,smb_vwv0);
2428 START_PROFILE(SMBfindclose);
2430 DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
2432 dptr_close(&dptr_num);
2434 outsize = set_message(outbuf,0,0,True);
2436 DEBUG(3,("SMBfindclose dptr_num = %d\n", dptr_num));
2438 END_PROFILE(SMBfindclose);
2439 return(outsize);
2442 /****************************************************************************
2443 Reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search).
2444 ****************************************************************************/
2446 int reply_findnclose(connection_struct *conn,
2447 char *inbuf,char *outbuf,int length,int bufsize)
2449 int outsize = 0;
2450 int dptr_num= -1;
2451 START_PROFILE(SMBfindnclose);
2453 dptr_num = SVAL(inbuf,smb_vwv0);
2455 DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
2457 /* We never give out valid handles for a
2458 findnotifyfirst - so any dptr_num is ok here.
2459 Just ignore it. */
2461 outsize = set_message(outbuf,0,0,True);
2463 DEBUG(3,("SMB_findnclose dptr_num = %d\n", dptr_num));
2465 END_PROFILE(SMBfindnclose);
2466 return(outsize);
2469 /****************************************************************************
2470 Reply to a SMBtranss2 - just ignore it!
2471 ****************************************************************************/
2473 int reply_transs2(connection_struct *conn,
2474 char *inbuf,char *outbuf,int length,int bufsize)
2476 START_PROFILE(SMBtranss2);
2477 DEBUG(4,("Ignoring transs2 of length %d\n",length));
2478 END_PROFILE(SMBtranss2);
2479 return(-1);
2482 /****************************************************************************
2483 Reply to a SMBtrans2.
2484 ****************************************************************************/
2486 int reply_trans2(connection_struct *conn,
2487 char *inbuf,char *outbuf,int length,int bufsize)
2489 int outsize = 0;
2490 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
2491 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
2492 #if 0
2493 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
2494 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
2495 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
2496 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
2497 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
2498 int32 timeout = IVALS(inbuf,smb_timeout);
2499 #endif
2500 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
2501 unsigned int tran_call = SVAL(inbuf, smb_setup0);
2502 char *params = NULL, *data = NULL;
2503 int num_params, num_params_sofar, num_data, num_data_sofar;
2504 START_PROFILE(SMBtrans2);
2506 if(global_oplock_break && (tran_call == TRANSACT2_OPEN)) {
2507 /* Queue this open message as we are the process of an
2508 * oplock break. */
2510 DEBUG(2,("reply_trans2: queueing message trans2open due to being "));
2511 DEBUGADD(2,( "in oplock break state.\n"));
2513 push_oplock_pending_smb_message(inbuf, length);
2514 END_PROFILE(SMBtrans2);
2515 return -1;
2518 if (IS_IPC(conn) && (tran_call != TRANSACT2_OPEN)
2519 && (tran_call != TRANSACT2_GET_DFS_REFERRAL)) {
2520 END_PROFILE(SMBtrans2);
2521 return ERROR_DOS(ERRSRV,ERRaccess);
2524 outsize = set_message(outbuf,0,0,True);
2526 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
2527 is so as a sanity check */
2528 if (suwcnt != 1) {
2530 * Need to have rc=0 for ioctl to get job id for OS/2.
2531 * Network printing will fail if function is not successful.
2532 * Similar function in reply.c will be used if protocol
2533 * is LANMAN1.0 instead of LM1.2X002.
2534 * Until DosPrintSetJobInfo with PRJINFO3 is supported,
2535 * outbuf doesn't have to be set(only job id is used).
2537 if ( (suwcnt == 4) && (tran_call == TRANSACT2_IOCTL) &&
2538 (SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) &&
2539 (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) {
2540 DEBUG(2,("Got Trans2 DevIOctl jobid\n"));
2541 } else {
2542 DEBUG(2,("Invalid smb_sucnt in trans2 call(%d)\n",suwcnt));
2543 DEBUG(2,("Transaction is %d\n",tran_call));
2544 END_PROFILE(SMBtrans2);
2545 return ERROR_DOS(ERRSRV,ERRerror);
2549 /* Allocate the space for the maximum needed parameters and data */
2550 if (total_params > 0)
2551 params = (char *)malloc(total_params);
2552 if (total_data > 0)
2553 data = (char *)malloc(total_data);
2555 if ((total_params && !params) || (total_data && !data)) {
2556 DEBUG(2,("Out of memory in reply_trans2\n"));
2557 SAFE_FREE(params);
2558 SAFE_FREE(data);
2559 END_PROFILE(SMBtrans2);
2560 return ERROR_DOS(ERRDOS,ERRnomem);
2563 /* Copy the param and data bytes sent with this request into
2564 the params buffer */
2565 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
2566 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
2568 if (num_params > total_params || num_data > total_data)
2569 exit_server("invalid params in reply_trans2");
2571 if(params)
2572 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
2573 if(data)
2574 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
2576 if(num_data_sofar < total_data || num_params_sofar < total_params) {
2577 /* We need to send an interim response then receive the rest
2578 of the parameter/data bytes */
2579 outsize = set_message(outbuf,0,0,True);
2580 if (!send_smb(smbd_server_fd(),outbuf))
2581 exit_server("reply_trans2: send_smb failed.");
2583 while (num_data_sofar < total_data ||
2584 num_params_sofar < total_params) {
2585 BOOL ret;
2587 ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
2589 if ((ret &&
2590 (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
2591 outsize = set_message(outbuf,0,0,True);
2592 if(ret)
2593 DEBUG(0,("reply_trans2: Invalid secondary trans2 packet\n"));
2594 else
2595 DEBUG(0,("reply_trans2: %s in getting secondary trans2 response.\n",
2596 (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
2597 SAFE_FREE(params);
2598 SAFE_FREE(data);
2599 END_PROFILE(SMBtrans2);
2600 return ERROR_DOS(ERRSRV,ERRerror);
2603 /* Revise total_params and total_data in case
2604 they have changed downwards */
2605 total_params = SVAL(inbuf, smb_tpscnt);
2606 total_data = SVAL(inbuf, smb_tdscnt);
2607 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
2608 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
2609 if (num_params_sofar > total_params || num_data_sofar > total_data)
2610 exit_server("data overflow in trans2");
2612 memcpy( &params[ SVAL(inbuf, smb_spsdisp)],
2613 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
2614 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
2615 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
2619 if (Protocol >= PROTOCOL_NT1) {
2620 SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | 0x40); /* IS_LONG_NAME */
2623 /* Now we must call the relevant TRANS2 function */
2624 switch(tran_call) {
2625 case TRANSACT2_OPEN:
2626 START_PROFILE_NESTED(Trans2_open);
2627 outsize = call_trans2open(conn,
2628 inbuf, outbuf, bufsize,
2629 &params, &data);
2630 END_PROFILE_NESTED(Trans2_open);
2631 break;
2633 case TRANSACT2_FINDFIRST:
2634 START_PROFILE_NESTED(Trans2_findfirst);
2635 outsize = call_trans2findfirst(conn, inbuf, outbuf,
2636 bufsize, &params, &data);
2637 END_PROFILE_NESTED(Trans2_findfirst);
2638 break;
2640 case TRANSACT2_FINDNEXT:
2641 START_PROFILE_NESTED(Trans2_findnext);
2642 outsize = call_trans2findnext(conn, inbuf, outbuf,
2643 length, bufsize,
2644 &params, &data);
2645 END_PROFILE_NESTED(Trans2_findnext);
2646 break;
2648 case TRANSACT2_QFSINFO:
2649 START_PROFILE_NESTED(Trans2_qfsinfo);
2650 outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
2651 length, bufsize, &params,
2652 &data);
2653 END_PROFILE_NESTED(Trans2_qfsinfo);
2654 break;
2656 case TRANSACT2_SETFSINFO:
2657 START_PROFILE_NESTED(Trans2_setfsinfo);
2658 outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
2659 length, bufsize,
2660 &params, &data);
2661 END_PROFILE_NESTED(Trans2_setfsinfo);
2662 break;
2664 case TRANSACT2_QPATHINFO:
2665 case TRANSACT2_QFILEINFO:
2666 START_PROFILE_NESTED(Trans2_qpathinfo);
2667 outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
2668 length, bufsize,
2669 &params, &data, total_data);
2670 END_PROFILE_NESTED(Trans2_qpathinfo);
2671 break;
2672 case TRANSACT2_SETPATHINFO:
2673 case TRANSACT2_SETFILEINFO:
2674 START_PROFILE_NESTED(Trans2_setpathinfo);
2675 outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
2676 length, bufsize,
2677 &params, &data,
2678 total_data);
2679 END_PROFILE_NESTED(Trans2_setpathinfo);
2680 break;
2682 case TRANSACT2_FINDNOTIFYFIRST:
2683 START_PROFILE_NESTED(Trans2_findnotifyfirst);
2684 outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
2685 length, bufsize,
2686 &params, &data);
2687 END_PROFILE_NESTED(Trans2_findnotifyfirst);
2688 break;
2690 case TRANSACT2_FINDNOTIFYNEXT:
2691 START_PROFILE_NESTED(Trans2_findnotifynext);
2692 outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
2693 length, bufsize,
2694 &params, &data);
2695 END_PROFILE_NESTED(Trans2_findnotifynext);
2696 break;
2697 case TRANSACT2_MKDIR:
2698 START_PROFILE_NESTED(Trans2_mkdir);
2699 outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
2700 bufsize, &params, &data);
2701 END_PROFILE_NESTED(Trans2_mkdir);
2702 break;
2704 case TRANSACT2_GET_DFS_REFERRAL:
2705 START_PROFILE_NESTED(Trans2_get_dfs_referral);
2706 outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length,
2707 bufsize, &params, &data);
2708 END_PROFILE_NESTED(Trans2_get_dfs_referral);
2709 break;
2710 case TRANSACT2_IOCTL:
2711 START_PROFILE_NESTED(Trans2_ioctl);
2712 outsize = call_trans2ioctl(conn,inbuf,outbuf,length,
2713 bufsize,&params,&data);
2714 END_PROFILE_NESTED(Trans2_ioctl);
2715 break;
2716 default:
2717 /* Error in request */
2718 DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
2719 SAFE_FREE(params);
2720 SAFE_FREE(data);
2721 END_PROFILE(SMBtrans2);
2722 return ERROR_DOS(ERRSRV,ERRerror);
2725 /* As we do not know how many data packets will need to be
2726 returned here the various call_trans2xxxx calls
2727 must send their own. Thus a call_trans2xxx routine only
2728 returns a value other than -1 when it wants to send
2729 an error packet.
2732 SAFE_FREE(params);
2733 SAFE_FREE(data);
2734 END_PROFILE(SMBtrans2);
2735 return outsize; /* If a correct response was needed the
2736 call_trans2xxx calls have already sent
2737 it. If outsize != -1 then it is returning */