2 Unix SMB/CIFS implementation.
3 Directory handling routines
4 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
24 This module implements directory related functions for Samba.
27 /* Make directory handle internals available. */
29 #define NAME_CACHE_SIZE 100
31 struct name_cache_entry {
37 connection_struct *conn;
41 struct name_cache_entry *name_cache;
42 unsigned int name_cache_index;
44 BOOL hide_unwriteable;
50 struct dptr_struct *next, *prev;
53 struct connection_struct *conn;
54 struct smb_Dir *dir_hnd;
59 BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */
62 static struct bitmap *dptr_bmap;
63 static struct dptr_struct *dirptrs;
64 static int dptrs_open = 0;
66 #define INVALID_DPTR_KEY (-3)
68 /****************************************************************************
69 Initialise the dir bitmap.
70 ****************************************************************************/
74 static BOOL dptrs_init=False;
79 dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
82 exit_server("out of memory in init_dptrs");
87 /****************************************************************************
88 Idle a dptr - the directory is closed but the control info is kept.
89 ****************************************************************************/
91 static void dptr_idle(struct dptr_struct *dptr)
94 DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
95 CloseDir(dptr->dir_hnd);
100 /****************************************************************************
101 Idle the oldest dptr.
102 ****************************************************************************/
104 static void dptr_idleoldest(void)
106 struct dptr_struct *dptr;
109 * Go to the end of the list.
111 for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
115 DEBUG(0,("No dptrs available to idle ?\n"));
120 * Idle the oldest pointer.
123 for(; dptr; dptr = dptr->prev) {
131 /****************************************************************************
132 Get the struct dptr_struct for a dir index.
133 ****************************************************************************/
135 static struct dptr_struct *dptr_get(int key, BOOL forclose)
137 struct dptr_struct *dptr;
139 for(dptr = dirptrs; dptr; dptr = dptr->next) {
140 if(dptr->dnum == key) {
141 if (!forclose && !dptr->dir_hnd) {
142 if (dptrs_open >= MAX_OPEN_DIRECTORIES)
144 DEBUG(4,("dptr_get: Reopening dptr key %d\n",key));
145 if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, True))) {
146 DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path,
151 DLIST_PROMOTE(dirptrs,dptr);
158 /****************************************************************************
159 Get the dir path for a dir index.
160 ****************************************************************************/
162 char *dptr_path(int key)
164 struct dptr_struct *dptr = dptr_get(key, False);
170 /****************************************************************************
171 Get the dir wcard for a dir index.
172 ****************************************************************************/
174 char *dptr_wcard(int key)
176 struct dptr_struct *dptr = dptr_get(key, False);
182 /****************************************************************************
183 Get the dir attrib for a dir index.
184 ****************************************************************************/
186 uint16 dptr_attr(int key)
188 struct dptr_struct *dptr = dptr_get(key, False);
194 /****************************************************************************
195 Set the dir wcard for a dir index.
196 Returns 0 on ok, 1 on fail.
197 ****************************************************************************/
199 BOOL dptr_set_wcard_and_attributes(int key, char *wcard, uint16 attr)
201 struct dptr_struct *dptr = dptr_get(key, False);
206 dptr->has_wild = ms_has_wild(wcard);
212 /****************************************************************************
213 Close a dptr (internal func).
214 ****************************************************************************/
216 static void dptr_close_internal(struct dptr_struct *dptr)
218 DEBUG(4,("closing dptr key %d\n",dptr->dnum));
220 DLIST_REMOVE(dirptrs, dptr);
223 * Free the dnum in the bitmap. Remember the dnum value is always
224 * biased by one with respect to the bitmap.
227 if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
228 DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
232 bitmap_clear(dptr_bmap, dptr->dnum - 1);
235 CloseDir(dptr->dir_hnd);
238 /* Lanman 2 specific code */
239 SAFE_FREE(dptr->wcard);
240 string_set(&dptr->path,"");
244 /****************************************************************************
245 Close a dptr given a key.
246 ****************************************************************************/
248 void dptr_close(int *key)
250 struct dptr_struct *dptr;
252 if(*key == INVALID_DPTR_KEY)
255 /* OS/2 seems to use -1 to indicate "close all directories" */
257 struct dptr_struct *next;
258 for(dptr = dirptrs; dptr; dptr = next) {
260 dptr_close_internal(dptr);
262 *key = INVALID_DPTR_KEY;
266 dptr = dptr_get(*key, True);
269 DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
273 dptr_close_internal(dptr);
275 *key = INVALID_DPTR_KEY;
278 /****************************************************************************
279 Close all dptrs for a cnum.
280 ****************************************************************************/
282 void dptr_closecnum(connection_struct *conn)
284 struct dptr_struct *dptr, *next;
285 for(dptr = dirptrs; dptr; dptr = next) {
287 if (dptr->conn == conn)
288 dptr_close_internal(dptr);
292 /****************************************************************************
293 Idle all dptrs for a cnum.
294 ****************************************************************************/
296 void dptr_idlecnum(connection_struct *conn)
298 struct dptr_struct *dptr;
299 for(dptr = dirptrs; dptr; dptr = dptr->next) {
300 if (dptr->conn == conn && dptr->dir_hnd)
305 /****************************************************************************
306 Close a dptr that matches a given path, only if it matches the spid also.
307 ****************************************************************************/
309 void dptr_closepath(char *path,uint16 spid)
311 struct dptr_struct *dptr, *next;
312 for(dptr = dirptrs; dptr; dptr = next) {
314 if (spid == dptr->spid && strequal(dptr->path,path))
315 dptr_close_internal(dptr);
319 /****************************************************************************
320 Try and close the oldest handle not marked for
321 expect close in the hope that the client has
322 finished with that one.
323 ****************************************************************************/
325 static void dptr_close_oldest(BOOL old)
327 struct dptr_struct *dptr;
330 * Go to the end of the list.
332 for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
336 DEBUG(0,("No old dptrs available to close oldest ?\n"));
341 * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
342 * does not have expect_close set. If 'old' is false, close
343 * one of the new dnum handles.
346 for(; dptr; dptr = dptr->prev) {
347 if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
348 (!old && (dptr->dnum > 255))) {
349 dptr_close_internal(dptr);
355 /****************************************************************************
356 Create a new dir ptr. If the flag old_handle is true then we must allocate
357 from the bitmap range 0 - 255 as old SMBsearch directory handles are only
358 one byte long. If old_handle is false we allocate from the range
359 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
360 a directory handle is never zero.
361 ****************************************************************************/
363 int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid)
365 struct dptr_struct *dptr = NULL;
366 struct smb_Dir *dir_hnd;
369 DEBUG(5,("dptr_create dir=%s\n", path));
371 if (!check_name(path,conn))
372 return(-2); /* Code to say use a unix error return code. */
374 /* use a const pointer from here on */
379 dir_hnd = OpenDir(conn, dir2, True);
384 string_set(&conn->dirpath,dir2);
386 if (dptrs_open >= MAX_OPEN_DIRECTORIES)
389 dptr = SMB_MALLOC_P(struct dptr_struct);
391 DEBUG(0,("malloc fail in dptr_create.\n"));
401 * This is an old-style SMBsearch request. Ensure the
402 * value we return will fit in the range 1-255.
405 dptr->dnum = bitmap_find(dptr_bmap, 0);
407 if(dptr->dnum == -1 || dptr->dnum > 254) {
410 * Try and close the oldest handle not marked for
411 * expect close in the hope that the client has
412 * finished with that one.
415 dptr_close_oldest(True);
417 /* Now try again... */
418 dptr->dnum = bitmap_find(dptr_bmap, 0);
419 if(dptr->dnum == -1 || dptr->dnum > 254) {
420 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
429 * This is a new-style trans2 request. Allocate from
430 * a range that will return 256 - MAX_DIRECTORY_HANDLES.
433 dptr->dnum = bitmap_find(dptr_bmap, 255);
435 if(dptr->dnum == -1 || dptr->dnum < 255) {
438 * Try and close the oldest handle close in the hope that
439 * the client has finished with that one. This will only
440 * happen in the case of the Win98 client bug where it leaks
444 dptr_close_oldest(False);
446 /* Now try again... */
447 dptr->dnum = bitmap_find(dptr_bmap, 255);
449 if(dptr->dnum == -1 || dptr->dnum < 255) {
450 DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
458 bitmap_set(dptr_bmap, dptr->dnum);
460 dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
462 string_set(&dptr->path,dir2);
464 dptr->dir_hnd = dir_hnd;
466 dptr->expect_close = expect_close;
467 dptr->wcard = NULL; /* Only used in lanman2 searches */
468 dptr->attr = 0; /* Only used in lanman2 searches */
469 dptr->has_wild = True; /* Only used in lanman2 searches */
471 DLIST_ADD(dirptrs, dptr);
473 DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
474 dptr->dnum,path,expect_close));
482 /****************************************************************************
483 Wrapper functions to access the lower level directory handles.
484 ****************************************************************************/
486 int dptr_CloseDir(struct dptr_struct *dptr)
488 return CloseDir(dptr->dir_hnd);
491 const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset)
493 return ReadDirName(dptr->dir_hnd, poffset);
496 void dptr_SeekDir(struct dptr_struct *dptr, long offset)
498 SeekDir(dptr->dir_hnd, offset);
501 long dptr_TellDir(struct dptr_struct *dptr)
503 return TellDir(dptr->dir_hnd);
506 BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, BOOL case_sensitive)
508 return SearchDir(dptr->dir_hnd, name, poffset, case_sensitive);
511 /****************************************************************************
512 Fill the 5 byte server reserved dptr field.
513 ****************************************************************************/
515 BOOL dptr_fill(char *buf1,unsigned int key)
517 unsigned char *buf = (unsigned char *)buf1;
518 struct dptr_struct *dptr = dptr_get(key, False);
521 DEBUG(1,("filling null dirptr %d\n",key));
524 offset = TellDir(dptr->dir_hnd);
525 DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
526 (long)dptr->dir_hnd,(int)offset));
528 SIVAL(buf,1,offset | DPTR_MASK);
532 /****************************************************************************
533 Fetch the dir ptr and seek it given the 5 byte server field.
534 ****************************************************************************/
536 struct dptr_struct *dptr_fetch(char *buf,int *num)
538 unsigned int key = *(unsigned char *)buf;
539 struct dptr_struct *dptr = dptr_get(key, False);
543 DEBUG(3,("fetched null dirptr %d\n",key));
547 offset = IVAL(buf,1)&~DPTR_MASK;
548 SeekDir(dptr->dir_hnd,(long)offset);
549 DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
550 key,dptr_path(key),offset));
554 /****************************************************************************
556 ****************************************************************************/
558 struct dptr_struct *dptr_fetch_lanman2(int dptr_num)
560 struct dptr_struct *dptr = dptr_get(dptr_num, False);
563 DEBUG(3,("fetched null dirptr %d\n",dptr_num));
566 DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
570 /****************************************************************************
571 Check a filetype for being valid.
572 ****************************************************************************/
574 BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
578 /* Check the "may have" search bits. */
579 if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
582 /* Check the "must have" bits, which are the may have bits shifted eight */
583 /* If must have bit is set, the file/dir can not be returned in search unless the matching
584 file attribute is set */
585 mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */
587 if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */
596 static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask)
598 mangle_map(filename,True,False,SNUM(conn));
599 return mask_match(filename,mask,False);
602 /****************************************************************************
603 Get an 8.3 directory entry.
604 ****************************************************************************/
606 BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname,
607 SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
611 SMB_STRUCT_STAT sbuf;
618 *path = *pathreal = *filename = 0;
620 isrootdir = (strequal(conn->dirpath,"./") ||
621 strequal(conn->dirpath,".") ||
622 strequal(conn->dirpath,"/"));
624 needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
630 long curoff = TellDir(conn->dirptr->dir_hnd);
631 dname = ReadDirName(conn->dirptr->dir_hnd, &curoff);
633 DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n",
634 (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd)));
639 pstrcpy(filename,dname);
641 /* notice the special *.* handling. This appears to be the only difference
642 between the wildcard handling in this routine and in the trans2 routines.
643 see masktest for a demo
645 if ((strcmp(mask,"*.*") == 0) ||
646 mask_match(filename,mask,False) ||
647 mangle_mask_match(conn,filename,mask)) {
648 if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
651 if (!mangle_is_8_3(filename, False))
652 mangle_map(filename,True,False,SNUM(conn));
654 pstrcpy(fname,filename);
656 pstrcpy(path,conn->dirpath);
659 pstrcpy(pathreal,path);
661 pstrcat(pathreal,dname);
662 if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) {
663 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
667 *mode = dos_mode(conn,pathreal,&sbuf);
669 if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
670 DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
674 *size = sbuf.st_size;
675 *date = sbuf.st_mtime;
677 DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
686 /*******************************************************************
687 Check to see if a user can read a file. This is only approximate,
688 it is used as part of the "hide unreadable" option. Don't
689 use it for anything security sensitive.
690 ********************************************************************/
692 static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
694 extern struct current_user current_user;
695 SEC_DESC *psd = NULL;
700 uint32 access_granted;
703 * If user is a member of the Admin group
704 * we never hide files from them.
707 if (conn->admin_user)
710 /* If we can't stat it does not show it */
711 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
714 /* Pseudo-open the file (note - no fd's created). */
716 if(S_ISDIR(pst->st_mode))
717 fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
720 fsp = open_file_stat(conn, name, pst);
725 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
726 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
727 (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
728 close_file(fsp, True);
730 /* No access if SD get failed. */
734 return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
735 &access_granted, &status);
738 /*******************************************************************
739 Check to see if a user can write a file (and only files, we do not
740 check dirs on this one). This is only approximate,
741 it is used as part of the "hide unwriteable" option. Don't
742 use it for anything security sensitive.
743 ********************************************************************/
745 static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
747 extern struct current_user current_user;
748 SEC_DESC *psd = NULL;
754 uint32 access_granted;
757 * If user is a member of the Admin group
758 * we never hide files from them.
761 if (conn->admin_user)
764 /* If we can't stat it does not show it */
765 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
768 /* Pseudo-open the file (note - no fd's created). */
770 if(S_ISDIR(pst->st_mode))
773 fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
774 (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
775 &access_mode, &smb_action);
780 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
781 sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd,
782 (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
783 close_file(fsp, False);
785 /* No access if SD get failed. */
789 return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
790 &access_granted, &status);
793 /*******************************************************************
794 Is a file a "special" type ?
795 ********************************************************************/
797 static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
800 * If user is a member of the Admin group
801 * we never hide files from them.
804 if (conn->admin_user)
807 /* If we can't stat it does not show it */
808 if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0))
811 if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
817 /*******************************************************************
819 ********************************************************************/
821 struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
823 struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir);
830 dirp->use_veto = use_veto;
832 dirp->dir_path = SMB_STRDUP(name);
833 if (!dirp->dir_path) {
836 dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path);
838 DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) ));
842 dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, NAME_CACHE_SIZE);
843 if (!dirp->name_cache) {
847 dirp->hide_unreadable = lp_hideunreadable(SNUM(conn));
848 dirp->hide_unwriteable = lp_hideunwriteable_files(SNUM(conn));
849 dirp->hide_special = lp_hide_special_files(SNUM(conn));
858 SMB_VFS_CLOSEDIR(conn,dirp->dir);
860 SAFE_FREE(dirp->dir_path);
861 SAFE_FREE(dirp->name_cache);
868 /*******************************************************************
870 ********************************************************************/
872 int CloseDir(struct smb_Dir *dirp)
877 ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
879 SAFE_FREE(dirp->dir_path);
880 if (dirp->name_cache) {
881 for (i = 0; i < NAME_CACHE_SIZE; i++) {
882 SAFE_FREE(dirp->name_cache[i].name);
885 SAFE_FREE(dirp->name_cache);
891 /*******************************************************************
892 Read from a directory. Also return current offset.
893 ********************************************************************/
895 const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
898 connection_struct *conn = dirp->conn;
900 SeekDir(dirp, *poffset);
901 while ((n = vfs_readdirname(conn, dirp->dir))) {
902 struct name_cache_entry *e;
904 if (!((strcmp(".",n) == 0) || (strcmp("..",n) == 0))) {
905 /* If it's a vetoed file, pretend it doesn't even exist */
906 if (dirp->use_veto && IS_VETO_PATH(conn, n)) {
910 if (dirp->hide_unreadable || dirp->hide_unwriteable || dirp->hide_special) {
915 if (asprintf(&entry, "%s/%s/%s", conn->origpath, dirp->dir_path, n) == -1) {
918 /* Honour _hide unreadable_ option */
919 if (dirp->hide_unreadable && !user_can_read_file(conn, entry, &st)) {
923 /* Honour _hide unwriteable_ option */
924 if (dirp->hide_unwriteable && !user_can_write_file(conn, entry, &st)) {
928 /* Honour _hide_special_ option */
929 if (dirp->hide_special && !file_is_special(conn, entry, &st)) {
937 dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
938 if (dirp->offset == -1) {
941 dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE;
943 e = &dirp->name_cache[dirp->name_cache_index];
945 e->name = SMB_STRDUP(n);
946 *poffset = e->offset= dirp->offset;
952 /*******************************************************************
954 ********************************************************************/
956 void SeekDir(struct smb_Dir *dirp, long offset)
958 if (offset != dirp->offset) {
959 SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset);
960 dirp->offset = offset;
964 /*******************************************************************
966 ********************************************************************/
968 long TellDir(struct smb_Dir *dirp)
970 return(dirp->offset);
973 /*******************************************************************
974 Find an entry by name. Leave us at the offset after it.
975 ********************************************************************/
977 BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_sensitive)
981 connection_struct *conn = dirp->conn;
983 /* Search back in the name cache. */
984 for (i = dirp->name_cache_index; i >= 0; i--) {
985 struct name_cache_entry *e = &dirp->name_cache[i];
986 if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
987 *poffset = e->offset;
988 SeekDir(dirp, e->offset);
992 for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) {
993 struct name_cache_entry *e = &dirp->name_cache[i];
994 if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
995 *poffset = e->offset;
996 SeekDir(dirp, e->offset);
1001 /* Not found in the name cache. Rewind directory and start from scratch. */
1002 SMB_VFS_REWINDDIR(conn, dirp->dir);
1004 while ((entry = ReadDirName(dirp, poffset))) {
1005 if (case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {