r5632: Fix infinite looping bug found by nasty BlueArc test :-).
[metze/samba/wip.git] / source3 / smbd / dir.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Directory handling routines
4    Copyright (C) Andrew Tridgell 1992-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /*
24    This module implements directory related functions for Samba.
25 */
26
27 /* Make directory handle internals available. */
28
29 #define NAME_CACHE_SIZE 100
30
31 struct name_cache_entry {
32         char *name;
33         long offset;
34 };
35
36 struct smb_Dir {
37         connection_struct *conn;
38         DIR *dir;
39         long offset;
40         char *dir_path;
41         struct name_cache_entry *name_cache;
42         unsigned int name_cache_index;
43 };
44
45 struct dptr_struct {
46         struct dptr_struct *next, *prev;
47         int dnum;
48         uint16 spid;
49         struct connection_struct *conn;
50         struct smb_Dir *dir_hnd;
51         BOOL expect_close;
52         char *wcard;
53         uint16 attr;
54         char *path;
55         BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */
56 };
57
58 static struct bitmap *dptr_bmap;
59 static struct dptr_struct *dirptrs;
60 static int dirhandles_open = 0;
61
62 #define INVALID_DPTR_KEY (-3)
63
64 /****************************************************************************
65  Initialise the dir bitmap.
66 ****************************************************************************/
67
68 void init_dptrs(void)
69 {
70         static BOOL dptrs_init=False;
71
72         if (dptrs_init)
73                 return;
74
75         dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
76
77         if (!dptr_bmap)
78                 exit_server("out of memory in init_dptrs");
79
80         dptrs_init = True;
81 }
82
83 /****************************************************************************
84  Idle a dptr - the directory is closed but the control info is kept.
85 ****************************************************************************/
86
87 static void dptr_idle(struct dptr_struct *dptr)
88 {
89         if (dptr->dir_hnd) {
90                 DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
91                 CloseDir(dptr->dir_hnd);
92                 dptr->dir_hnd = NULL;
93         }
94 }
95
96 /****************************************************************************
97  Idle the oldest dptr.
98 ****************************************************************************/
99
100 static void dptr_idleoldest(void)
101 {
102         struct dptr_struct *dptr;
103
104         /*
105          * Go to the end of the list.
106          */
107         for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
108                 ;
109
110         if(!dptr) {
111                 DEBUG(0,("No dptrs available to idle ?\n"));
112                 return;
113         }
114
115         /*
116          * Idle the oldest pointer.
117          */
118
119         for(; dptr; dptr = dptr->prev) {
120                 if (dptr->dir_hnd) {
121                         dptr_idle(dptr);
122                         return;
123                 }
124         }
125 }
126
127 /****************************************************************************
128  Get the struct dptr_struct for a dir index.
129 ****************************************************************************/
130
131 static struct dptr_struct *dptr_get(int key, BOOL forclose)
132 {
133         struct dptr_struct *dptr;
134
135         for(dptr = dirptrs; dptr; dptr = dptr->next) {
136                 if(dptr->dnum == key) {
137                         if (!forclose && !dptr->dir_hnd) {
138                                 if (dirhandles_open >= MAX_OPEN_DIRECTORIES)
139                                         dptr_idleoldest();
140                                 DEBUG(4,("dptr_get: Reopening dptr key %d\n",key));
141                                 if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) {
142                                         DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path,
143                                                 strerror(errno)));
144                                         return False;
145                                 }
146                         }
147                         DLIST_PROMOTE(dirptrs,dptr);
148                         return dptr;
149                 }
150         }
151         return(NULL);
152 }
153
154 /****************************************************************************
155  Get the dir path for a dir index.
156 ****************************************************************************/
157
158 char *dptr_path(int key)
159 {
160         struct dptr_struct *dptr = dptr_get(key, False);
161         if (dptr)
162                 return(dptr->path);
163         return(NULL);
164 }
165
166 /****************************************************************************
167  Get the dir wcard for a dir index.
168 ****************************************************************************/
169
170 char *dptr_wcard(int key)
171 {
172         struct dptr_struct *dptr = dptr_get(key, False);
173         if (dptr)
174                 return(dptr->wcard);
175         return(NULL);
176 }
177
178 /****************************************************************************
179  Get the dir attrib for a dir index.
180 ****************************************************************************/
181
182 uint16 dptr_attr(int key)
183 {
184         struct dptr_struct *dptr = dptr_get(key, False);
185         if (dptr)
186                 return(dptr->attr);
187         return(0);
188 }
189
190 /****************************************************************************
191  Set the dir wcard for a dir index.
192  Returns 0 on ok, 1 on fail.
193 ****************************************************************************/
194
195 BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr)
196 {
197         struct dptr_struct *dptr = dptr_get(key, False);
198
199         if (dptr) {
200                 dptr->attr = attr;
201                 dptr->wcard = SMB_STRDUP(wcard);
202                 if (!dptr->wcard)
203                         return False;
204                 if (wcard[0] == '.' && wcard[1] == 0) {
205                         dptr->has_wild = True;
206                 } else {
207                         dptr->has_wild = ms_has_wild(wcard);
208                 }
209                 return True;
210         }
211         return False;
212 }
213
214 /****************************************************************************
215  Close a dptr (internal func).
216 ****************************************************************************/
217
218 static void dptr_close_internal(struct dptr_struct *dptr)
219 {
220         DEBUG(4,("closing dptr key %d\n",dptr->dnum));
221
222         DLIST_REMOVE(dirptrs, dptr);
223
224         /* 
225          * Free the dnum in the bitmap. Remember the dnum value is always 
226          * biased by one with respect to the bitmap.
227          */
228
229         if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
230                 DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
231                         dptr->dnum ));
232         }
233
234         bitmap_clear(dptr_bmap, dptr->dnum - 1);
235
236         if (dptr->dir_hnd) {
237                 CloseDir(dptr->dir_hnd);
238         }
239
240         /* Lanman 2 specific code */
241         SAFE_FREE(dptr->wcard);
242         string_set(&dptr->path,"");
243         SAFE_FREE(dptr);
244 }
245
246 /****************************************************************************
247  Close a dptr given a key.
248 ****************************************************************************/
249
250 void dptr_close(int *key)
251 {
252         struct dptr_struct *dptr;
253
254         if(*key == INVALID_DPTR_KEY)
255                 return;
256
257         /* OS/2 seems to use -1 to indicate "close all directories" */
258         if (*key == -1) {
259                 struct dptr_struct *next;
260                 for(dptr = dirptrs; dptr; dptr = next) {
261                         next = dptr->next;
262                         dptr_close_internal(dptr);
263                 }
264                 *key = INVALID_DPTR_KEY;
265                 return;
266         }
267
268         dptr = dptr_get(*key, True);
269
270         if (!dptr) {
271                 DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
272                 return;
273         }
274
275         dptr_close_internal(dptr);
276
277         *key = INVALID_DPTR_KEY;
278 }
279
280 /****************************************************************************
281  Close all dptrs for a cnum.
282 ****************************************************************************/
283
284 void dptr_closecnum(connection_struct *conn)
285 {
286         struct dptr_struct *dptr, *next;
287         for(dptr = dirptrs; dptr; dptr = next) {
288                 next = dptr->next;
289                 if (dptr->conn == conn)
290                         dptr_close_internal(dptr);
291         }
292 }
293
294 /****************************************************************************
295  Idle all dptrs for a cnum.
296 ****************************************************************************/
297
298 void dptr_idlecnum(connection_struct *conn)
299 {
300         struct dptr_struct *dptr;
301         for(dptr = dirptrs; dptr; dptr = dptr->next) {
302                 if (dptr->conn == conn && dptr->dir_hnd)
303                         dptr_idle(dptr);
304         }
305 }
306
307 /****************************************************************************
308  Close a dptr that matches a given path, only if it matches the spid also.
309 ****************************************************************************/
310
311 void dptr_closepath(char *path,uint16 spid)
312 {
313         struct dptr_struct *dptr, *next;
314         for(dptr = dirptrs; dptr; dptr = next) {
315                 next = dptr->next;
316                 if (spid == dptr->spid && strequal(dptr->path,path))
317                         dptr_close_internal(dptr);
318         }
319 }
320
321 /****************************************************************************
322  Try and close the oldest handle not marked for
323  expect close in the hope that the client has
324  finished with that one.
325 ****************************************************************************/
326
327 static void dptr_close_oldest(BOOL old)
328 {
329         struct dptr_struct *dptr;
330
331         /*
332          * Go to the end of the list.
333          */
334         for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
335                 ;
336
337         if(!dptr) {
338                 DEBUG(0,("No old dptrs available to close oldest ?\n"));
339                 return;
340         }
341
342         /*
343          * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
344          * does not have expect_close set. If 'old' is false, close
345          * one of the new dnum handles.
346          */
347
348         for(; dptr; dptr = dptr->prev) {
349                 if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
350                         (!old && (dptr->dnum > 255))) {
351                                 dptr_close_internal(dptr);
352                                 return;
353                 }
354         }
355 }
356
357 /****************************************************************************
358  Create a new dir ptr. If the flag old_handle is true then we must allocate
359  from the bitmap range 0 - 255 as old SMBsearch directory handles are only
360  one byte long. If old_handle is false we allocate from the range
361  256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
362  a directory handle is never zero.
363 ****************************************************************************/
364
365 int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid)
366 {
367         struct dptr_struct *dptr = NULL;
368         struct smb_Dir *dir_hnd;
369         const char *dir2;
370
371         DEBUG(5,("dptr_create dir=%s\n", path));
372
373         if (!check_name(path,conn))
374                 return(-2); /* Code to say use a unix error return code. */
375
376         /* use a const pointer from here on */
377         dir2 = path;
378         if (!*dir2)
379                 dir2 = ".";
380
381         dir_hnd = OpenDir(conn, dir2);
382         if (!dir_hnd) {
383                 return (-2);
384         }
385
386         string_set(&conn->dirpath,dir2);
387
388         if (dirhandles_open >= MAX_OPEN_DIRECTORIES)
389                 dptr_idleoldest();
390
391         dptr = SMB_MALLOC_P(struct dptr_struct);
392         if(!dptr) {
393                 DEBUG(0,("malloc fail in dptr_create.\n"));
394                 CloseDir(dir_hnd);
395                 return -1;
396         }
397
398         ZERO_STRUCTP(dptr);
399
400         if(old_handle) {
401
402                 /*
403                  * This is an old-style SMBsearch request. Ensure the
404                  * value we return will fit in the range 1-255.
405                  */
406
407                 dptr->dnum = bitmap_find(dptr_bmap, 0);
408
409                 if(dptr->dnum == -1 || dptr->dnum > 254) {
410
411                         /*
412                          * Try and close the oldest handle not marked for
413                          * expect close in the hope that the client has
414                          * finished with that one.
415                          */
416
417                         dptr_close_oldest(True);
418
419                         /* Now try again... */
420                         dptr->dnum = bitmap_find(dptr_bmap, 0);
421                         if(dptr->dnum == -1 || dptr->dnum > 254) {
422                                 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
423                                 SAFE_FREE(dptr);
424                                 CloseDir(dir_hnd);
425                                 return -1;
426                         }
427                 }
428         } else {
429
430                 /*
431                  * This is a new-style trans2 request. Allocate from
432                  * a range that will return 256 - MAX_DIRECTORY_HANDLES.
433                  */
434
435                 dptr->dnum = bitmap_find(dptr_bmap, 255);
436
437                 if(dptr->dnum == -1 || dptr->dnum < 255) {
438
439                         /*
440                          * Try and close the oldest handle close in the hope that
441                          * the client has finished with that one. This will only
442                          * happen in the case of the Win98 client bug where it leaks
443                          * directory handles.
444                          */
445
446                         dptr_close_oldest(False);
447
448                         /* Now try again... */
449                         dptr->dnum = bitmap_find(dptr_bmap, 255);
450
451                         if(dptr->dnum == -1 || dptr->dnum < 255) {
452                                 DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
453                                 SAFE_FREE(dptr);
454                                 CloseDir(dir_hnd);
455                                 return -1;
456                         }
457                 }
458         }
459
460         bitmap_set(dptr_bmap, dptr->dnum);
461
462         dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
463
464         string_set(&dptr->path,dir2);
465         dptr->conn = conn;
466         dptr->dir_hnd = dir_hnd;
467         dptr->spid = spid;
468         dptr->expect_close = expect_close;
469         dptr->wcard = NULL; /* Only used in lanman2 searches */
470         dptr->attr = 0; /* Only used in lanman2 searches */
471         dptr->has_wild = True; /* Only used in lanman2 searches */
472
473         DLIST_ADD(dirptrs, dptr);
474
475         DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
476                 dptr->dnum,path,expect_close));  
477
478         conn->dirptr = dptr;
479
480         return(dptr->dnum);
481 }
482
483
484 /****************************************************************************
485  Wrapper functions to access the lower level directory handles.
486 ****************************************************************************/
487
488 int dptr_CloseDir(struct dptr_struct *dptr)
489 {
490         return CloseDir(dptr->dir_hnd);
491 }
492
493 void dptr_SeekDir(struct dptr_struct *dptr, long offset)
494 {
495         SeekDir(dptr->dir_hnd, offset);
496 }
497
498 long dptr_TellDir(struct dptr_struct *dptr)
499 {
500         return TellDir(dptr->dir_hnd);
501 }
502
503 /****************************************************************************
504  Return the next visible file name, skipping veto'd and invisible files.
505 ****************************************************************************/
506
507 static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
508 {
509         /* Normal search for the next file. */
510         const char *name;
511         while ((name = ReadDirName(dptr->dir_hnd, poffset)) != NULL) {
512                 if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
513                         return name;
514                 }
515         }
516         return NULL;
517 }
518
519 /****************************************************************************
520  Return the next visible file name, skipping veto'd and invisible files.
521 ****************************************************************************/
522
523 const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
524 {
525         pstring pathreal;
526
527         ZERO_STRUCTP(pst);
528
529         if (dptr->has_wild) {
530                 return dptr_normal_ReadDirName(dptr, poffset, pst);
531         }
532
533         /* If poffset is -1 then we know we returned this name before and we have
534            no wildcards. We're at the end of the directory. */
535         if (*poffset == -1) {
536                 return NULL;
537         }
538
539         /* We know the stored wcard contains no wildcard characters. See if we can match
540            with a stat call. If we can't, then set has_wild to true to
541            prevent us from doing this on every call. */
542
543         /* First check if it should be visible. */
544         if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
545                 dptr->has_wild = True;
546                 return dptr_normal_ReadDirName(dptr, poffset, pst);
547         }
548
549         if (VALID_STAT(*pst)) {
550                 /* We need to set the underlying dir_hdn offset to -1 also as
551                    this function is usually called with the output from TellDir. */
552                 dptr->dir_hnd->offset = *poffset = -1;
553                 return dptr->wcard;
554         }
555
556         pstrcpy(pathreal,dptr->path);
557         pstrcat(pathreal,"/");
558         pstrcat(pathreal,dptr->wcard);
559
560         if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
561                 /* We need to set the underlying dir_hdn offset to -1 also as
562                    this function is usually called with the output from TellDir. */
563                 dptr->dir_hnd->offset = *poffset = -1;
564                 return dptr->wcard;
565         } else {
566                 /* If we get any other error than ENOENT or ENOTDIR
567                    then the file exists we just can't stat it. */
568                 if (errno != ENOENT && errno != ENOTDIR) {
569                         /* We need to set the underlying dir_hdn offset to -1 also as
570                            this function is usually called with the output from TellDir. */
571                         dptr->dir_hnd->offset = *poffset = -1;
572                         return dptr->wcard;
573                 }
574         }
575
576         dptr->has_wild = True;
577
578         /* In case sensitive mode we don't search - we know if it doesn't exist 
579            with a stat we will fail. */
580
581         if (dptr->conn->case_sensitive) {
582                 /* We need to set the underlying dir_hdn offset to -1 also as
583                    this function is usually called with the output from TellDir. */
584                 dptr->dir_hnd->offset = *poffset = -1;
585                 return NULL;
586         } else {
587                 return dptr_normal_ReadDirName(dptr, poffset, pst);
588         }
589 }
590
591 /****************************************************************************
592  Search for a file by name, skipping veto'ed and not visible files.
593 ****************************************************************************/
594
595 BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst)
596 {
597         BOOL ret;
598
599         ZERO_STRUCTP(pst);
600         while ((ret = SearchDir(dptr->dir_hnd, name, poffset)) == True) {
601                 if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
602                         return True;
603                 }
604         }
605         return False;
606 }
607
608 /****************************************************************************
609  Fill the 5 byte server reserved dptr field.
610 ****************************************************************************/
611
612 BOOL dptr_fill(char *buf1,unsigned int key)
613 {
614         unsigned char *buf = (unsigned char *)buf1;
615         struct dptr_struct *dptr = dptr_get(key, False);
616         uint32 offset;
617         if (!dptr) {
618                 DEBUG(1,("filling null dirptr %d\n",key));
619                 return(False);
620         }
621         offset = TellDir(dptr->dir_hnd);
622         DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
623                 (long)dptr->dir_hnd,(int)offset));
624         buf[0] = key;
625         SIVAL(buf,1,offset | DPTR_MASK);
626         return(True);
627 }
628
629 /****************************************************************************
630  Fetch the dir ptr and seek it given the 5 byte server field.
631 ****************************************************************************/
632
633 struct dptr_struct *dptr_fetch(char *buf,int *num)
634 {
635         unsigned int key = *(unsigned char *)buf;
636         struct dptr_struct *dptr = dptr_get(key, False);
637         uint32 offset;
638
639         if (!dptr) {
640                 DEBUG(3,("fetched null dirptr %d\n",key));
641                 return(NULL);
642         }
643         *num = key;
644         offset = IVAL(buf,1)&~DPTR_MASK;
645         SeekDir(dptr->dir_hnd,(long)offset);
646         DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
647                 key,dptr_path(key),offset));
648         return(dptr);
649 }
650
651 /****************************************************************************
652  Fetch the dir ptr.
653 ****************************************************************************/
654
655 struct dptr_struct *dptr_fetch_lanman2(int dptr_num)
656 {
657         struct dptr_struct *dptr  = dptr_get(dptr_num, False);
658
659         if (!dptr) {
660                 DEBUG(3,("fetched null dirptr %d\n",dptr_num));
661                 return(NULL);
662         }
663         DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
664         return(dptr);
665 }
666
667 /****************************************************************************
668  Check a filetype for being valid.
669 ****************************************************************************/
670
671 BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype)
672 {
673         int mask;
674
675         /* Check the "may have" search bits. */
676         if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
677                 return False;
678
679         /* Check the "must have" bits, which are the may have bits shifted eight */
680         /* If must have bit is set, the file/dir can not be returned in search unless the matching
681                 file attribute is set */
682         mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */
683         if(mask) {
684                 if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask)   /* check if matching attribute present */
685                         return True;
686                 else
687                         return False;
688         }
689
690         return True;
691 }
692
693 static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
694 {
695         mangle_map(filename,True,False,SNUM(conn));
696         return mask_match(filename,mask,False);
697 }
698
699 /****************************************************************************
700  Get an 8.3 directory entry.
701 ****************************************************************************/
702
703 BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname,
704                    SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
705 {
706         const char *dname;
707         BOOL found = False;
708         SMB_STRUCT_STAT sbuf;
709         pstring path;
710         pstring pathreal;
711         BOOL isrootdir;
712         pstring filename;
713         BOOL needslash;
714
715         *path = *pathreal = *filename = 0;
716
717         isrootdir = (strequal(conn->dirpath,"./") ||
718                         strequal(conn->dirpath,".") ||
719                         strequal(conn->dirpath,"/"));
720   
721         needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
722
723         if (!conn->dirptr)
724                 return(False);
725
726         while (!found) {
727                 long curoff = dptr_TellDir(conn->dirptr);
728                 dname = dptr_ReadDirName(conn->dirptr, &curoff, &sbuf);
729
730                 DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n",
731                         (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd)));
732       
733                 if (dname == NULL) 
734                         return(False);
735       
736                 pstrcpy(filename,dname);      
737
738                 /* notice the special *.* handling. This appears to be the only difference
739                         between the wildcard handling in this routine and in the trans2 routines.
740                         see masktest for a demo
741                 */
742                 if ((strcmp(mask,"*.*") == 0) ||
743                     mask_match(filename,mask,False) ||
744                     mangle_mask_match(conn,filename,mask)) {
745                         if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
746                                 continue;
747
748                         if (!mangle_is_8_3(filename, False))
749                                 mangle_map(filename,True,False,SNUM(conn));
750
751                         pstrcpy(fname,filename);
752                         *path = 0;
753                         pstrcpy(path,conn->dirpath);
754                         if(needslash)
755                                 pstrcat(path,"/");
756                         pstrcpy(pathreal,path);
757                         pstrcat(path,fname);
758                         pstrcat(pathreal,dname);
759                         if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn, pathreal, &sbuf)) != 0) {
760                                 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
761                                 continue;
762                         }
763           
764                         *mode = dos_mode(conn,pathreal,&sbuf);
765
766                         if (!dir_check_ftype(conn,*mode,dirtype)) {
767                                 DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
768                                 continue;
769                         }
770
771                         *size = sbuf.st_size;
772                         *date = sbuf.st_mtime;
773
774                         DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
775
776                         found = True;
777                 }
778         }
779
780         return(found);
781 }
782
783 /*******************************************************************
784  Check to see if a user can read a file. This is only approximate,
785  it is used as part of the "hide unreadable" option. Don't
786  use it for anything security sensitive.
787 ********************************************************************/
788
789 static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
790 {
791         extern struct current_user current_user;
792         SEC_DESC *psd = NULL;
793         size_t sd_size;
794         files_struct *fsp;
795         int smb_action;
796         NTSTATUS status;
797         uint32 access_granted;
798
799         /*
800          * If user is a member of the Admin group
801          * we never hide files from them.
802          */
803
804         if (conn->admin_user)
805                 return True;
806
807         /* If we can't stat it does not show it */
808         if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
809                 return False;
810
811         /* Pseudo-open the file (note - no fd's created). */
812
813         if(S_ISDIR(pst->st_mode))       
814                  fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
815                         &smb_action);
816         else
817                 fsp = open_file_stat(conn, name, pst);
818
819         if (!fsp)
820                 return False;
821
822         /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
823         sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
824                         (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
825         close_file(fsp, True);
826
827         /* No access if SD get failed. */
828         if (!sd_size)
829                 return False;
830
831         return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
832                                  &access_granted, &status);
833 }
834
835 /*******************************************************************
836  Check to see if a user can write a file (and only files, we do not
837  check dirs on this one). This is only approximate,
838  it is used as part of the "hide unwriteable" option. Don't
839  use it for anything security sensitive.
840 ********************************************************************/
841
842 static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
843 {
844         extern struct current_user current_user;
845         SEC_DESC *psd = NULL;
846         size_t sd_size;
847         files_struct *fsp;
848         int smb_action;
849         int access_mode;
850         NTSTATUS status;
851         uint32 access_granted;
852
853         /*
854          * If user is a member of the Admin group
855          * we never hide files from them.
856          */
857
858         if (conn->admin_user)
859                 return True;
860
861         /* If we can't stat it does not show it */
862         if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
863                 return False;
864
865         /* Pseudo-open the file (note - no fd's created). */
866
867         if(S_ISDIR(pst->st_mode))       
868                 return True;
869         else
870                 fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
871                         (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
872                         &access_mode, &smb_action);
873
874         if (!fsp)
875                 return False;
876
877         /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
878         sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
879                         (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
880         close_file(fsp, False);
881
882         /* No access if SD get failed. */
883         if (!sd_size)
884                 return False;
885
886         return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
887                                  &access_granted, &status);
888 }
889
890 /*******************************************************************
891   Is a file a "special" type ?
892 ********************************************************************/
893
894 static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
895 {
896         /*
897          * If user is a member of the Admin group
898          * we never hide files from them.
899          */
900
901         if (conn->admin_user)
902                 return False;
903
904         /* If we can't stat it does not show it */
905         if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
906                 return True;
907
908         if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
909                 return False;
910
911         return True;
912 }
913
914 /*******************************************************************
915  Should the file be seen by the client ?
916 ********************************************************************/
917
918 BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, BOOL use_veto)
919 {
920         BOOL hide_unreadable = lp_hideunreadable(SNUM(conn));
921         BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn));
922         BOOL hide_special = lp_hide_special_files(SNUM(conn));
923
924         ZERO_STRUCTP(pst);
925
926         if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) {
927                 return True; /* . and .. are always visible. */
928         }
929
930         /* If it's a vetoed file, pretend it doesn't even exist */
931         if (use_veto && IS_VETO_PATH(conn, name)) {
932                 return False;
933         }
934
935         if (hide_unreadable || hide_unwriteable || hide_special) {
936                 char *entry = NULL;
937
938                 if (asprintf(&entry, "%s/%s", dir_path, name) == -1) {
939                         return False;
940                 }
941                 /* Honour _hide unreadable_ option */
942                 if (hide_unreadable && !user_can_read_file(conn, entry, pst)) {
943                         SAFE_FREE(entry);
944                         return False;
945                 }
946                 /* Honour _hide unwriteable_ option */
947                 if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) {
948                         SAFE_FREE(entry);
949                         return False;
950                 }
951                 /* Honour _hide_special_ option */
952                 if (hide_special && !file_is_special(conn, entry, pst)) {
953                         SAFE_FREE(entry);
954                         return False;
955                 }
956                 SAFE_FREE(entry);
957         }
958         return True;
959 }
960
961 /*******************************************************************
962  Open a directory.
963 ********************************************************************/
964
965 struct smb_Dir *OpenDir(connection_struct *conn, const char *name)
966 {
967         struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir);
968         if (!dirp) {
969                 return NULL;
970         }
971         ZERO_STRUCTP(dirp);
972
973         dirp->conn = conn;
974
975         dirp->dir_path = SMB_STRDUP(name);
976         if (!dirp->dir_path) {
977                 goto fail;
978         }
979         dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path);
980         if (!dirp->dir) {
981                 DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) ));
982                 goto fail;
983         }
984
985         dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, NAME_CACHE_SIZE);
986         if (!dirp->name_cache) {
987                 goto fail;
988         }
989
990         dirhandles_open++;
991         return dirp;
992
993   fail:
994
995         if (dirp) {
996                 if (dirp->dir) {
997                         SMB_VFS_CLOSEDIR(conn,dirp->dir);
998                 }
999                 SAFE_FREE(dirp->dir_path);
1000                 SAFE_FREE(dirp->name_cache);
1001                 SAFE_FREE(dirp);
1002         }
1003         return NULL;
1004 }
1005
1006
1007 /*******************************************************************
1008  Close a directory.
1009 ********************************************************************/
1010
1011 int CloseDir(struct smb_Dir *dirp)
1012 {
1013         int i, ret = 0;
1014
1015         if (dirp->dir) {
1016                 ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
1017         }
1018         SAFE_FREE(dirp->dir_path);
1019         if (dirp->name_cache) {
1020                 for (i = 0; i < NAME_CACHE_SIZE; i++) {
1021                         SAFE_FREE(dirp->name_cache[i].name);
1022                 }
1023         }
1024         SAFE_FREE(dirp->name_cache);
1025         SAFE_FREE(dirp);
1026         dirhandles_open--;
1027         return ret;
1028 }
1029
1030 /*******************************************************************
1031  Read from a directory. Also return current offset.
1032  Don't check for veto or invisible files.
1033 ********************************************************************/
1034
1035 const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
1036 {
1037         const char *n;
1038         connection_struct *conn = dirp->conn;
1039
1040         SeekDir(dirp, *poffset);
1041         while ((n = vfs_readdirname(conn, dirp->dir))) {
1042                 struct name_cache_entry *e;
1043                 dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
1044                 if (dirp->offset == -1) {
1045                         return NULL;
1046                 }
1047                 dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE;
1048
1049                 e = &dirp->name_cache[dirp->name_cache_index];
1050                 SAFE_FREE(e->name);
1051                 e->name = SMB_STRDUP(n);
1052                 *poffset = e->offset= dirp->offset;
1053                 return e->name;
1054         }
1055         dirp->offset = -1;
1056         return NULL;
1057 }
1058
1059 /*******************************************************************
1060  Seek a dir.
1061 ********************************************************************/
1062
1063 void SeekDir(struct smb_Dir *dirp, long offset)
1064 {
1065         if (offset != dirp->offset) {
1066                 SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset);
1067                 dirp->offset = offset;
1068         }
1069 }
1070
1071 /*******************************************************************
1072  Tell a dir position.
1073 ********************************************************************/
1074
1075 long TellDir(struct smb_Dir *dirp)
1076 {
1077         return(dirp->offset);
1078 }
1079
1080 /*******************************************************************
1081  Find an entry by name. Leave us at the offset after it.
1082  Don't check for veto or invisible files.
1083 ********************************************************************/
1084
1085 BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
1086 {
1087         int i;
1088         const char *entry;
1089         connection_struct *conn = dirp->conn;
1090
1091         /* Search back in the name cache. */
1092         for (i = dirp->name_cache_index; i >= 0; i--) {
1093                 struct name_cache_entry *e = &dirp->name_cache[i];
1094                 if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
1095                         *poffset = e->offset;
1096                         SeekDir(dirp, e->offset);
1097                         return True;
1098                 }
1099         }
1100         for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) {
1101                 struct name_cache_entry *e = &dirp->name_cache[i];
1102                 if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
1103                         *poffset = e->offset;
1104                         SeekDir(dirp, e->offset);
1105                         return True;
1106                 }
1107         }
1108
1109         /* Not found in the name cache. Rewind directory and start from scratch. */
1110         SMB_VFS_REWINDDIR(conn, dirp->dir);
1111         *poffset = 0;
1112         while ((entry = ReadDirName(dirp, poffset))) {
1113                 if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
1114                         return True;
1115                 }
1116         }
1117         return False;
1118 }