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 3 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, see <http://www.gnu.org/licenses/>.
23 This module implements directory related functions for Samba.
26 extern struct current_user current_user
;
28 /* "Special" directory offsets. */
29 #define END_OF_DIRECTORY_OFFSET ((long)-1)
30 #define START_OF_DIRECTORY_OFFSET ((long)0)
31 #define DOT_DOT_DIRECTORY_OFFSET ((long)0x80000000)
33 /* Make directory handle internals available. */
35 struct name_cache_entry
{
41 connection_struct
*conn
;
45 size_t name_cache_size
;
46 struct name_cache_entry
*name_cache
;
47 unsigned int name_cache_index
;
48 unsigned int file_number
;
52 struct dptr_struct
*next
, *prev
;
55 struct connection_struct
*conn
;
56 struct smb_Dir
*dir_hnd
;
61 BOOL has_wild
; /* Set to true if the wcard entry has MS wildcard characters in it. */
62 BOOL did_stat
; /* Optimisation for non-wcard searches. */
65 static struct bitmap
*dptr_bmap
;
66 static struct dptr_struct
*dirptrs
;
67 static int dirhandles_open
= 0;
69 #define INVALID_DPTR_KEY (-3)
71 /****************************************************************************
73 ****************************************************************************/
75 void make_dir_struct(char *buf
, const char *mask
, const char *fname
,SMB_OFF_T size
,uint32 mode
,time_t date
, BOOL uc
)
82 if ((mode
& aDIR
) != 0)
86 if ((p
= strchr_m(mask2
,'.')) != NULL
) {
88 push_ascii(buf
+1,mask2
,8, 0);
89 push_ascii(buf
+9,p
+1,3, 0);
92 push_ascii(buf
+1,mask2
,11, 0);
94 memset(buf
+21,'\0',DIR_STRUCT_SIZE
-21);
96 srv_put_dos_date(buf
,22,date
);
97 SSVAL(buf
,26,size
& 0xFFFF);
98 SSVAL(buf
,28,(size
>> 16)&0xFFFF);
99 /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf.
100 Strange, but verified on W2K3. Needed for OS/2. JRA. */
101 push_ascii(buf
+30,fname
,12, uc
? STR_UPPER
: 0);
102 DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf
+30, fname
));
105 /****************************************************************************
106 Initialise the dir bitmap.
107 ****************************************************************************/
109 void init_dptrs(void)
111 static BOOL dptrs_init
=False
;
116 dptr_bmap
= bitmap_allocate(MAX_DIRECTORY_HANDLES
);
119 exit_server("out of memory in init_dptrs");
124 /****************************************************************************
125 Idle a dptr - the directory is closed but the control info is kept.
126 ****************************************************************************/
128 static void dptr_idle(struct dptr_struct
*dptr
)
131 DEBUG(4,("Idling dptr dnum %d\n",dptr
->dnum
));
132 CloseDir(dptr
->dir_hnd
);
133 dptr
->dir_hnd
= NULL
;
137 /****************************************************************************
138 Idle the oldest dptr.
139 ****************************************************************************/
141 static void dptr_idleoldest(void)
143 struct dptr_struct
*dptr
;
146 * Go to the end of the list.
148 for(dptr
= dirptrs
; dptr
&& dptr
->next
; dptr
= dptr
->next
)
152 DEBUG(0,("No dptrs available to idle ?\n"));
157 * Idle the oldest pointer.
160 for(; dptr
; dptr
= dptr
->prev
) {
168 /****************************************************************************
169 Get the struct dptr_struct for a dir index.
170 ****************************************************************************/
172 static struct dptr_struct
*dptr_get(int key
, BOOL forclose
)
174 struct dptr_struct
*dptr
;
176 for(dptr
= dirptrs
; dptr
; dptr
= dptr
->next
) {
177 if(dptr
->dnum
== key
) {
178 if (!forclose
&& !dptr
->dir_hnd
) {
179 if (dirhandles_open
>= MAX_OPEN_DIRECTORIES
)
181 DEBUG(4,("dptr_get: Reopening dptr key %d\n",key
));
182 if (!(dptr
->dir_hnd
= OpenDir(dptr
->conn
, dptr
->path
, dptr
->wcard
, dptr
->attr
))) {
183 DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr
->path
,
188 DLIST_PROMOTE(dirptrs
,dptr
);
195 /****************************************************************************
196 Get the dir path for a dir index.
197 ****************************************************************************/
199 char *dptr_path(int key
)
201 struct dptr_struct
*dptr
= dptr_get(key
, False
);
207 /****************************************************************************
208 Get the dir wcard for a dir index.
209 ****************************************************************************/
211 char *dptr_wcard(int key
)
213 struct dptr_struct
*dptr
= dptr_get(key
, False
);
219 /****************************************************************************
220 Get the dir attrib for a dir index.
221 ****************************************************************************/
223 uint16
dptr_attr(int key
)
225 struct dptr_struct
*dptr
= dptr_get(key
, False
);
231 /****************************************************************************
232 Close a dptr (internal func).
233 ****************************************************************************/
235 static void dptr_close_internal(struct dptr_struct
*dptr
)
237 DEBUG(4,("closing dptr key %d\n",dptr
->dnum
));
239 DLIST_REMOVE(dirptrs
, dptr
);
242 * Free the dnum in the bitmap. Remember the dnum value is always
243 * biased by one with respect to the bitmap.
246 if(bitmap_query( dptr_bmap
, dptr
->dnum
- 1) != True
) {
247 DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
251 bitmap_clear(dptr_bmap
, dptr
->dnum
- 1);
254 CloseDir(dptr
->dir_hnd
);
257 /* Lanman 2 specific code */
258 SAFE_FREE(dptr
->wcard
);
259 string_set(&dptr
->path
,"");
263 /****************************************************************************
264 Close a dptr given a key.
265 ****************************************************************************/
267 void dptr_close(int *key
)
269 struct dptr_struct
*dptr
;
271 if(*key
== INVALID_DPTR_KEY
)
274 /* OS/2 seems to use -1 to indicate "close all directories" */
276 struct dptr_struct
*next
;
277 for(dptr
= dirptrs
; dptr
; dptr
= next
) {
279 dptr_close_internal(dptr
);
281 *key
= INVALID_DPTR_KEY
;
285 dptr
= dptr_get(*key
, True
);
288 DEBUG(0,("Invalid key %d given to dptr_close\n", *key
));
292 dptr_close_internal(dptr
);
294 *key
= INVALID_DPTR_KEY
;
297 /****************************************************************************
298 Close all dptrs for a cnum.
299 ****************************************************************************/
301 void dptr_closecnum(connection_struct
*conn
)
303 struct dptr_struct
*dptr
, *next
;
304 for(dptr
= dirptrs
; dptr
; dptr
= next
) {
306 if (dptr
->conn
== conn
)
307 dptr_close_internal(dptr
);
311 /****************************************************************************
312 Idle all dptrs for a cnum.
313 ****************************************************************************/
315 void dptr_idlecnum(connection_struct
*conn
)
317 struct dptr_struct
*dptr
;
318 for(dptr
= dirptrs
; dptr
; dptr
= dptr
->next
) {
319 if (dptr
->conn
== conn
&& dptr
->dir_hnd
)
324 /****************************************************************************
325 Close a dptr that matches a given path, only if it matches the spid also.
326 ****************************************************************************/
328 void dptr_closepath(char *path
,uint16 spid
)
330 struct dptr_struct
*dptr
, *next
;
331 for(dptr
= dirptrs
; dptr
; dptr
= next
) {
333 if (spid
== dptr
->spid
&& strequal(dptr
->path
,path
))
334 dptr_close_internal(dptr
);
338 /****************************************************************************
339 Try and close the oldest handle not marked for
340 expect close in the hope that the client has
341 finished with that one.
342 ****************************************************************************/
344 static void dptr_close_oldest(BOOL old
)
346 struct dptr_struct
*dptr
;
349 * Go to the end of the list.
351 for(dptr
= dirptrs
; dptr
&& dptr
->next
; dptr
= dptr
->next
)
355 DEBUG(0,("No old dptrs available to close oldest ?\n"));
360 * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
361 * does not have expect_close set. If 'old' is false, close
362 * one of the new dnum handles.
365 for(; dptr
; dptr
= dptr
->prev
) {
366 if ((old
&& (dptr
->dnum
< 256) && !dptr
->expect_close
) ||
367 (!old
&& (dptr
->dnum
> 255))) {
368 dptr_close_internal(dptr
);
374 /****************************************************************************
375 Create a new dir ptr. If the flag old_handle is true then we must allocate
376 from the bitmap range 0 - 255 as old SMBsearch directory handles are only
377 one byte long. If old_handle is false we allocate from the range
378 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
379 a directory handle is never zero.
380 wcard must not be zero.
381 ****************************************************************************/
383 NTSTATUS
dptr_create(connection_struct
*conn
, const char *path
, BOOL old_handle
, BOOL expect_close
,uint16 spid
,
384 const char *wcard
, BOOL wcard_has_wild
, uint32 attr
, struct dptr_struct
**dptr_ret
)
386 struct dptr_struct
*dptr
= NULL
;
387 struct smb_Dir
*dir_hnd
;
390 DEBUG(5,("dptr_create dir=%s\n", path
));
393 return NT_STATUS_INVALID_PARAMETER
;
396 status
= check_name(conn
,path
);
397 if (!NT_STATUS_IS_OK(status
)) {
401 dir_hnd
= OpenDir(conn
, path
, wcard
, attr
);
403 return map_nt_error_from_unix(errno
);
406 string_set(&conn
->dirpath
,path
);
408 if (dirhandles_open
>= MAX_OPEN_DIRECTORIES
) {
412 dptr
= SMB_MALLOC_P(struct dptr_struct
);
414 DEBUG(0,("malloc fail in dptr_create.\n"));
416 return NT_STATUS_NO_MEMORY
;
424 * This is an old-style SMBsearch request. Ensure the
425 * value we return will fit in the range 1-255.
428 dptr
->dnum
= bitmap_find(dptr_bmap
, 0);
430 if(dptr
->dnum
== -1 || dptr
->dnum
> 254) {
433 * Try and close the oldest handle not marked for
434 * expect close in the hope that the client has
435 * finished with that one.
438 dptr_close_oldest(True
);
440 /* Now try again... */
441 dptr
->dnum
= bitmap_find(dptr_bmap
, 0);
442 if(dptr
->dnum
== -1 || dptr
->dnum
> 254) {
443 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr
->dnum
));
446 return NT_STATUS_TOO_MANY_OPENED_FILES
;
452 * This is a new-style trans2 request. Allocate from
453 * a range that will return 256 - MAX_DIRECTORY_HANDLES.
456 dptr
->dnum
= bitmap_find(dptr_bmap
, 255);
458 if(dptr
->dnum
== -1 || dptr
->dnum
< 255) {
461 * Try and close the oldest handle close in the hope that
462 * the client has finished with that one. This will only
463 * happen in the case of the Win98 client bug where it leaks
467 dptr_close_oldest(False
);
469 /* Now try again... */
470 dptr
->dnum
= bitmap_find(dptr_bmap
, 255);
472 if(dptr
->dnum
== -1 || dptr
->dnum
< 255) {
473 DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr
->dnum
));
476 return NT_STATUS_TOO_MANY_OPENED_FILES
;
481 bitmap_set(dptr_bmap
, dptr
->dnum
);
483 dptr
->dnum
+= 1; /* Always bias the dnum by one - no zero dnums allowed. */
485 string_set(&dptr
->path
,path
);
487 dptr
->dir_hnd
= dir_hnd
;
489 dptr
->expect_close
= expect_close
;
490 dptr
->wcard
= SMB_STRDUP(wcard
);
492 bitmap_clear(dptr_bmap
, dptr
->dnum
- 1);
495 return NT_STATUS_NO_MEMORY
;
497 if (lp_posix_pathnames() || (wcard
[0] == '.' && wcard
[1] == 0)) {
498 dptr
->has_wild
= True
;
500 dptr
->has_wild
= wcard_has_wild
;
505 DLIST_ADD(dirptrs
, dptr
);
507 DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
508 dptr
->dnum
,path
,expect_close
));
516 /****************************************************************************
517 Wrapper functions to access the lower level directory handles.
518 ****************************************************************************/
520 int dptr_CloseDir(struct dptr_struct
*dptr
)
522 DLIST_REMOVE(dirptrs
, dptr
);
523 return CloseDir(dptr
->dir_hnd
);
526 void dptr_SeekDir(struct dptr_struct
*dptr
, long offset
)
528 SeekDir(dptr
->dir_hnd
, offset
);
531 long dptr_TellDir(struct dptr_struct
*dptr
)
533 return TellDir(dptr
->dir_hnd
);
536 BOOL
dptr_has_wild(struct dptr_struct
*dptr
)
538 return dptr
->has_wild
;
541 int dptr_dnum(struct dptr_struct
*dptr
)
546 /****************************************************************************
547 Return the next visible file name, skipping veto'd and invisible files.
548 ****************************************************************************/
550 static const char *dptr_normal_ReadDirName(struct dptr_struct
*dptr
, long *poffset
, SMB_STRUCT_STAT
*pst
)
552 /* Normal search for the next file. */
554 while ((name
= ReadDirName(dptr
->dir_hnd
, poffset
)) != NULL
) {
555 if (is_visible_file(dptr
->conn
, dptr
->path
, name
, pst
, True
)) {
562 /****************************************************************************
563 Return the next visible file name, skipping veto'd and invisible files.
564 ****************************************************************************/
566 const char *dptr_ReadDirName(struct dptr_struct
*dptr
, long *poffset
, SMB_STRUCT_STAT
*pst
)
568 SET_STAT_INVALID(*pst
);
570 if (dptr
->has_wild
) {
571 return dptr_normal_ReadDirName(dptr
, poffset
, pst
);
574 /* If poffset is -1 then we know we returned this name before and we have
575 no wildcards. We're at the end of the directory. */
576 if (*poffset
== END_OF_DIRECTORY_OFFSET
) {
580 if (!dptr
->did_stat
) {
583 /* We know the stored wcard contains no wildcard characters. See if we can match
584 with a stat call. If we can't, then set did_stat to true to
585 ensure we only do this once and keep searching. */
587 dptr
->did_stat
= True
;
589 /* First check if it should be visible. */
590 if (!is_visible_file(dptr
->conn
, dptr
->path
, dptr
->wcard
, pst
, True
)) {
591 /* This only returns False if the file was found, but
592 is explicitly not visible. Set us to end of directory,
593 but return NULL as we know we can't ever find it. */
594 dptr
->dir_hnd
->offset
= *poffset
= END_OF_DIRECTORY_OFFSET
;
598 if (VALID_STAT(*pst
)) {
599 /* We need to set the underlying dir_hnd offset to -1 also as
600 this function is usually called with the output from TellDir. */
601 dptr
->dir_hnd
->offset
= *poffset
= END_OF_DIRECTORY_OFFSET
;
605 pstrcpy(pathreal
,dptr
->path
);
606 pstrcat(pathreal
,"/");
607 pstrcat(pathreal
,dptr
->wcard
);
609 if (SMB_VFS_STAT(dptr
->conn
,pathreal
,pst
) == 0) {
610 /* We need to set the underlying dir_hnd offset to -1 also as
611 this function is usually called with the output from TellDir. */
612 dptr
->dir_hnd
->offset
= *poffset
= END_OF_DIRECTORY_OFFSET
;
615 /* If we get any other error than ENOENT or ENOTDIR
616 then the file exists we just can't stat it. */
617 if (errno
!= ENOENT
&& errno
!= ENOTDIR
) {
618 /* We need to set the underlying dir_hdn offset to -1 also as
619 this function is usually called with the output from TellDir. */
620 dptr
->dir_hnd
->offset
= *poffset
= END_OF_DIRECTORY_OFFSET
;
625 /* In case sensitive mode we don't search - we know if it doesn't exist
626 with a stat we will fail. */
628 if (dptr
->conn
->case_sensitive
) {
629 /* We need to set the underlying dir_hnd offset to -1 also as
630 this function is usually called with the output from TellDir. */
631 dptr
->dir_hnd
->offset
= *poffset
= END_OF_DIRECTORY_OFFSET
;
635 return dptr_normal_ReadDirName(dptr
, poffset
, pst
);
638 /****************************************************************************
639 Search for a file by name, skipping veto'ed and not visible files.
640 ****************************************************************************/
642 BOOL
dptr_SearchDir(struct dptr_struct
*dptr
, const char *name
, long *poffset
, SMB_STRUCT_STAT
*pst
)
644 SET_STAT_INVALID(*pst
);
646 if (!dptr
->has_wild
&& (dptr
->dir_hnd
->offset
== END_OF_DIRECTORY_OFFSET
)) {
647 /* This is a singleton directory and we're already at the end. */
648 *poffset
= END_OF_DIRECTORY_OFFSET
;
652 return SearchDir(dptr
->dir_hnd
, name
, poffset
);
655 /****************************************************************************
656 Add the name we're returning into the underlying cache.
657 ****************************************************************************/
659 void dptr_DirCacheAdd(struct dptr_struct
*dptr
, const char *name
, long offset
)
661 DirCacheAdd(dptr
->dir_hnd
, name
, offset
);
664 /****************************************************************************
665 Fill the 5 byte server reserved dptr field.
666 ****************************************************************************/
668 BOOL
dptr_fill(char *buf1
,unsigned int key
)
670 unsigned char *buf
= (unsigned char *)buf1
;
671 struct dptr_struct
*dptr
= dptr_get(key
, False
);
674 DEBUG(1,("filling null dirptr %d\n",key
));
677 offset
= (uint32
)TellDir(dptr
->dir_hnd
);
678 DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key
,
679 (long)dptr
->dir_hnd
,(int)offset
));
685 /****************************************************************************
686 Fetch the dir ptr and seek it given the 5 byte server field.
687 ****************************************************************************/
689 struct dptr_struct
*dptr_fetch(char *buf
,int *num
)
691 unsigned int key
= *(unsigned char *)buf
;
692 struct dptr_struct
*dptr
= dptr_get(key
, False
);
697 DEBUG(3,("fetched null dirptr %d\n",key
));
701 offset
= IVAL(buf
,1);
702 if (offset
== (uint32
)-1) {
703 seekoff
= END_OF_DIRECTORY_OFFSET
;
705 seekoff
= (long)offset
;
707 SeekDir(dptr
->dir_hnd
,seekoff
);
708 DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
709 key
,dptr_path(key
),(int)seekoff
));
713 /****************************************************************************
715 ****************************************************************************/
717 struct dptr_struct
*dptr_fetch_lanman2(int dptr_num
)
719 struct dptr_struct
*dptr
= dptr_get(dptr_num
, False
);
722 DEBUG(3,("fetched null dirptr %d\n",dptr_num
));
725 DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num
,dptr_path(dptr_num
)));
729 /****************************************************************************
730 Check that a file matches a particular file type.
731 ****************************************************************************/
733 BOOL
dir_check_ftype(connection_struct
*conn
, uint32 mode
, uint32 dirtype
)
737 /* Check the "may have" search bits. */
738 if (((mode
& ~dirtype
) & (aHIDDEN
| aSYSTEM
| aDIR
)) != 0)
741 /* Check the "must have" bits, which are the may have bits shifted eight */
742 /* If must have bit is set, the file/dir can not be returned in search unless the matching
743 file attribute is set */
744 mask
= ((dirtype
>> 8) & (aDIR
|aARCH
|aRONLY
|aHIDDEN
|aSYSTEM
)); /* & 0x37 */
746 if((mask
& (mode
& (aDIR
|aARCH
|aRONLY
|aHIDDEN
|aSYSTEM
))) == mask
) /* check if matching attribute present */
755 static BOOL
mangle_mask_match(connection_struct
*conn
,
756 const char *filename
,
761 if (!name_to_8_3(filename
,mname
,False
,conn
->params
)) {
764 return mask_match_search(mname
,mask
,False
);
767 /****************************************************************************
768 Get an 8.3 directory entry.
769 ****************************************************************************/
771 BOOL
get_dir_entry(connection_struct
*conn
,char *mask
,uint32 dirtype
, pstring fname
,
772 SMB_OFF_T
*size
,uint32
*mode
,time_t *date
,BOOL check_descend
)
776 SMB_STRUCT_STAT sbuf
;
782 *path
= *pathreal
= *filename
= 0;
784 needslash
= ( conn
->dirpath
[strlen(conn
->dirpath
) -1] != '/');
790 long curoff
= dptr_TellDir(conn
->dirptr
);
791 dname
= dptr_ReadDirName(conn
->dirptr
, &curoff
, &sbuf
);
793 DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n",
794 (long)conn
->dirptr
,TellDir(conn
->dirptr
->dir_hnd
)));
799 pstrcpy(filename
,dname
);
801 /* notice the special *.* handling. This appears to be the only difference
802 between the wildcard handling in this routine and in the trans2 routines.
803 see masktest for a demo
805 if ((strcmp(mask
,"*.*") == 0) ||
806 mask_match_search(filename
,mask
,False
) ||
807 mangle_mask_match(conn
,filename
,mask
)) {
809 if (!mangle_is_8_3(filename
, False
, conn
->params
)) {
811 if (!name_to_8_3(filename
,mname
,False
,
815 pstrcpy(filename
,mname
);
818 pstrcpy(fname
,filename
);
820 pstrcpy(path
,conn
->dirpath
);
823 pstrcpy(pathreal
,path
);
825 pstrcat(pathreal
,dname
);
826 if (!VALID_STAT(sbuf
) && (SMB_VFS_STAT(conn
, pathreal
, &sbuf
)) != 0) {
827 DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path
, strerror(errno
) ));
831 *mode
= dos_mode(conn
,pathreal
,&sbuf
);
833 if (!dir_check_ftype(conn
,*mode
,dirtype
)) {
834 DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename
,(unsigned int)*mode
,(unsigned int)dirtype
));
838 *size
= sbuf
.st_size
;
839 *date
= sbuf
.st_mtime
;
841 DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask
, pathreal
,fname
));
845 DirCacheAdd(conn
->dirptr
->dir_hnd
, dname
, curoff
);
852 /*******************************************************************
853 Check to see if a user can read a file. This is only approximate,
854 it is used as part of the "hide unreadable" option. Don't
855 use it for anything security sensitive.
856 ********************************************************************/
858 static BOOL
user_can_read_file(connection_struct
*conn
, char *name
, SMB_STRUCT_STAT
*pst
)
860 SEC_DESC
*psd
= NULL
;
864 uint32 access_granted
;
867 * If user is a member of the Admin group
868 * we never hide files from them.
871 if (conn
->admin_user
) {
875 /* If we can't stat it does not show it */
876 if (!VALID_STAT(*pst
) && (SMB_VFS_STAT(conn
, name
, pst
) != 0)) {
877 DEBUG(10,("user_can_read_file: SMB_VFS_STAT failed for file %s with error %s\n",
878 name
, strerror(errno
) ));
882 /* Pseudo-open the file (note - no fd's created). */
884 if(S_ISDIR(pst
->st_mode
)) {
885 status
= open_directory(conn
, NULL
, name
, pst
,
887 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
889 0, /* no create options. */
890 FILE_ATTRIBUTE_DIRECTORY
,
893 status
= open_file_stat(conn
, NULL
, name
, pst
, &fsp
);
896 if (!NT_STATUS_IS_OK(status
)) {
900 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
901 sd_size
= SMB_VFS_FGET_NT_ACL(fsp
, fsp
->fh
->fd
,
902 (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
|DACL_SECURITY_INFORMATION
), &psd
);
903 close_file(fsp
, NORMAL_CLOSE
);
905 /* No access if SD get failed. */
910 return se_access_check(psd
, current_user
.nt_user_token
, FILE_READ_DATA
,
911 &access_granted
, &status
);
914 /*******************************************************************
915 Check to see if a user can write a file (and only files, we do not
916 check dirs on this one). This is only approximate,
917 it is used as part of the "hide unwriteable" option. Don't
918 use it for anything security sensitive.
919 ********************************************************************/
921 static BOOL
user_can_write_file(connection_struct
*conn
, char *name
, SMB_STRUCT_STAT
*pst
)
923 SEC_DESC
*psd
= NULL
;
928 uint32 access_granted
;
931 * If user is a member of the Admin group
932 * we never hide files from them.
935 if (conn
->admin_user
) {
939 /* If we can't stat it does not show it */
940 if (!VALID_STAT(*pst
) && (SMB_VFS_STAT(conn
, name
, pst
) != 0)) {
944 /* Pseudo-open the file */
946 if(S_ISDIR(pst
->st_mode
)) {
949 status
= open_file_ntcreate(conn
, NULL
, name
, pst
,
950 FILE_WRITE_ATTRIBUTES
,
951 FILE_SHARE_READ
|FILE_SHARE_WRITE
,
954 FILE_ATTRIBUTE_NORMAL
,
959 if (!NT_STATUS_IS_OK(status
)) {
963 /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
964 sd_size
= SMB_VFS_FGET_NT_ACL(fsp
, fsp
->fh
->fd
,
965 (OWNER_SECURITY_INFORMATION
|GROUP_SECURITY_INFORMATION
|DACL_SECURITY_INFORMATION
), &psd
);
966 close_file(fsp
, NORMAL_CLOSE
);
968 /* No access if SD get failed. */
972 return se_access_check(psd
, current_user
.nt_user_token
, FILE_WRITE_DATA
,
973 &access_granted
, &status
);
976 /*******************************************************************
977 Is a file a "special" type ?
978 ********************************************************************/
980 static BOOL
file_is_special(connection_struct
*conn
, char *name
, SMB_STRUCT_STAT
*pst
)
983 * If user is a member of the Admin group
984 * we never hide files from them.
987 if (conn
->admin_user
)
990 /* If we can't stat it does not show it */
991 if (!VALID_STAT(*pst
) && (SMB_VFS_STAT(conn
, name
, pst
) != 0))
994 if (S_ISREG(pst
->st_mode
) || S_ISDIR(pst
->st_mode
) || S_ISLNK(pst
->st_mode
))
1000 /*******************************************************************
1001 Should the file be seen by the client ?
1002 ********************************************************************/
1004 BOOL
is_visible_file(connection_struct
*conn
, const char *dir_path
, const char *name
, SMB_STRUCT_STAT
*pst
, BOOL use_veto
)
1006 BOOL hide_unreadable
= lp_hideunreadable(SNUM(conn
));
1007 BOOL hide_unwriteable
= lp_hideunwriteable_files(SNUM(conn
));
1008 BOOL hide_special
= lp_hide_special_files(SNUM(conn
));
1010 SET_STAT_INVALID(*pst
);
1012 if ((strcmp(".",name
) == 0) || (strcmp("..",name
) == 0)) {
1013 return True
; /* . and .. are always visible. */
1016 /* If it's a vetoed file, pretend it doesn't even exist */
1017 if (use_veto
&& IS_VETO_PATH(conn
, name
)) {
1018 DEBUG(10,("is_visible_file: file %s is vetoed.\n", name
));
1022 if (hide_unreadable
|| hide_unwriteable
|| hide_special
) {
1025 if (asprintf(&entry
, "%s/%s", dir_path
, name
) == -1) {
1029 /* If it's a dfs symlink, ignore _hide xxxx_ options */
1030 if (lp_host_msdfs() &&
1031 lp_msdfs_root(SNUM(conn
)) &&
1032 is_msdfs_link(conn
, entry
, NULL
)) {
1037 /* Honour _hide unreadable_ option */
1038 if (hide_unreadable
&& !user_can_read_file(conn
, entry
, pst
)) {
1039 DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry
));
1043 /* Honour _hide unwriteable_ option */
1044 if (hide_unwriteable
&& !user_can_write_file(conn
, entry
, pst
)) {
1045 DEBUG(10,("is_visible_file: file %s is unwritable.\n", entry
));
1049 /* Honour _hide_special_ option */
1050 if (hide_special
&& file_is_special(conn
, entry
, pst
)) {
1051 DEBUG(10,("is_visible_file: file %s is special.\n", entry
));
1060 /*******************************************************************
1062 ********************************************************************/
1064 struct smb_Dir
*OpenDir(connection_struct
*conn
, const char *name
, const char *mask
, uint32 attr
)
1066 struct smb_Dir
*dirp
= SMB_MALLOC_P(struct smb_Dir
);
1074 dirp
->name_cache_size
= lp_directory_name_cache_size(SNUM(conn
));
1076 dirp
->dir_path
= SMB_STRDUP(name
);
1077 if (!dirp
->dir_path
) {
1080 dirp
->dir
= SMB_VFS_OPENDIR(conn
, dirp
->dir_path
, mask
, attr
);
1082 DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp
->dir_path
, strerror(errno
) ));
1086 if (dirp
->name_cache_size
) {
1087 dirp
->name_cache
= SMB_CALLOC_ARRAY(struct name_cache_entry
,
1088 dirp
->name_cache_size
);
1089 if (!dirp
->name_cache
) {
1093 dirp
->name_cache
= NULL
;
1103 SMB_VFS_CLOSEDIR(conn
,dirp
->dir
);
1105 SAFE_FREE(dirp
->dir_path
);
1106 SAFE_FREE(dirp
->name_cache
);
1113 /*******************************************************************
1115 ********************************************************************/
1117 int CloseDir(struct smb_Dir
*dirp
)
1122 ret
= SMB_VFS_CLOSEDIR(dirp
->conn
,dirp
->dir
);
1124 SAFE_FREE(dirp
->dir_path
);
1125 if (dirp
->name_cache
) {
1126 for (i
= 0; i
< dirp
->name_cache_size
; i
++) {
1127 SAFE_FREE(dirp
->name_cache
[i
].name
);
1130 SAFE_FREE(dirp
->name_cache
);
1136 /*******************************************************************
1137 Read from a directory. Also return current offset.
1138 Don't check for veto or invisible files.
1139 ********************************************************************/
1141 const char *ReadDirName(struct smb_Dir
*dirp
, long *poffset
)
1144 connection_struct
*conn
= dirp
->conn
;
1146 /* Cheat to allow . and .. to be the first entries returned. */
1147 if (((*poffset
== START_OF_DIRECTORY_OFFSET
) || (*poffset
== DOT_DOT_DIRECTORY_OFFSET
)) && (dirp
->file_number
< 2)) {
1148 if (dirp
->file_number
== 0) {
1150 *poffset
= dirp
->offset
= START_OF_DIRECTORY_OFFSET
;
1152 *poffset
= dirp
->offset
= DOT_DOT_DIRECTORY_OFFSET
;
1155 dirp
->file_number
++;
1157 } else if (*poffset
== END_OF_DIRECTORY_OFFSET
) {
1158 *poffset
= dirp
->offset
= END_OF_DIRECTORY_OFFSET
;
1161 /* A real offset, seek to it. */
1162 SeekDir(dirp
, *poffset
);
1165 while ((n
= vfs_readdirname(conn
, dirp
->dir
))) {
1166 /* Ignore . and .. - we've already returned them. */
1168 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
1172 *poffset
= dirp
->offset
= SMB_VFS_TELLDIR(conn
, dirp
->dir
);
1173 dirp
->file_number
++;
1176 *poffset
= dirp
->offset
= END_OF_DIRECTORY_OFFSET
;
1180 /*******************************************************************
1181 Rewind to the start.
1182 ********************************************************************/
1184 void RewindDir(struct smb_Dir
*dirp
, long *poffset
)
1186 SMB_VFS_REWINDDIR(dirp
->conn
, dirp
->dir
);
1187 dirp
->file_number
= 0;
1188 dirp
->offset
= START_OF_DIRECTORY_OFFSET
;
1189 *poffset
= START_OF_DIRECTORY_OFFSET
;
1192 /*******************************************************************
1194 ********************************************************************/
1196 void SeekDir(struct smb_Dir
*dirp
, long offset
)
1198 if (offset
!= dirp
->offset
) {
1199 if (offset
== START_OF_DIRECTORY_OFFSET
) {
1200 RewindDir(dirp
, &offset
);
1202 * Ok we should really set the file number here
1203 * to 1 to enable ".." to be returned next. Trouble
1204 * is I'm worried about callers using SeekDir(dirp,0)
1205 * as equivalent to RewindDir(). So leave this alone
1208 } else if (offset
== DOT_DOT_DIRECTORY_OFFSET
) {
1209 RewindDir(dirp
, &offset
);
1211 * Set the file number to 2 - we want to get the first
1212 * real file entry (the one we return after "..")
1213 * on the next ReadDir.
1215 dirp
->file_number
= 2;
1216 } else if (offset
== END_OF_DIRECTORY_OFFSET
) {
1217 ; /* Don't seek in this case. */
1219 SMB_VFS_SEEKDIR(dirp
->conn
, dirp
->dir
, offset
);
1221 dirp
->offset
= offset
;
1225 /*******************************************************************
1226 Tell a dir position.
1227 ********************************************************************/
1229 long TellDir(struct smb_Dir
*dirp
)
1231 return(dirp
->offset
);
1234 /*******************************************************************
1235 Add an entry into the dcache.
1236 ********************************************************************/
1238 void DirCacheAdd(struct smb_Dir
*dirp
, const char *name
, long offset
)
1240 struct name_cache_entry
*e
;
1242 if (!dirp
->name_cache_size
|| !dirp
->name_cache
) {
1246 dirp
->name_cache_index
= (dirp
->name_cache_index
+1) %
1247 dirp
->name_cache_size
;
1248 e
= &dirp
->name_cache
[dirp
->name_cache_index
];
1250 e
->name
= SMB_STRDUP(name
);
1254 /*******************************************************************
1255 Find an entry by name. Leave us at the offset after it.
1256 Don't check for veto or invisible files.
1257 ********************************************************************/
1259 BOOL
SearchDir(struct smb_Dir
*dirp
, const char *name
, long *poffset
)
1263 connection_struct
*conn
= dirp
->conn
;
1265 /* Search back in the name cache. */
1266 if (dirp
->name_cache_size
&& dirp
->name_cache
) {
1267 for (i
= dirp
->name_cache_index
; i
>= 0; i
--) {
1268 struct name_cache_entry
*e
= &dirp
->name_cache
[i
];
1269 if (e
->name
&& (conn
->case_sensitive
? (strcmp(e
->name
, name
) == 0) : strequal(e
->name
, name
))) {
1270 *poffset
= e
->offset
;
1271 SeekDir(dirp
, e
->offset
);
1275 for (i
= dirp
->name_cache_size
- 1; i
> dirp
->name_cache_index
; i
--) {
1276 struct name_cache_entry
*e
= &dirp
->name_cache
[i
];
1277 if (e
->name
&& (conn
->case_sensitive
? (strcmp(e
->name
, name
) == 0) : strequal(e
->name
, name
))) {
1278 *poffset
= e
->offset
;
1279 SeekDir(dirp
, e
->offset
);
1285 /* Not found in the name cache. Rewind directory and start from scratch. */
1286 SMB_VFS_REWINDDIR(conn
, dirp
->dir
);
1287 dirp
->file_number
= 0;
1288 *poffset
= START_OF_DIRECTORY_OFFSET
;
1289 while ((entry
= ReadDirName(dirp
, poffset
))) {
1290 if (conn
->case_sensitive
? (strcmp(entry
, name
) == 0) : strequal(entry
, name
)) {
1297 /*****************************************************************
1298 Is this directory empty ?
1299 *****************************************************************/
1301 NTSTATUS
can_delete_directory(struct connection_struct
*conn
,
1302 const char *dirname
)
1304 NTSTATUS status
= NT_STATUS_OK
;
1307 struct smb_Dir
*dir_hnd
= OpenDir(conn
, dirname
, NULL
, 0);
1310 return map_nt_error_from_unix(errno
);
1313 while ((dname
= ReadDirName(dir_hnd
,&dirpos
))) {
1316 /* Quick check for "." and ".." */
1317 if (dname
[0] == '.') {
1318 if (!dname
[1] || (dname
[1] == '.' && !dname
[2])) {
1323 if (!is_visible_file(conn
, dirname
, dname
, &st
, True
)) {
1327 DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname
));
1328 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;