summaryrefslogtreecommitdiff
path: root/source3/smbd/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/dir.c')
-rw-r--r--source3/smbd/dir.c156
1 files changed, 88 insertions, 68 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index f56e0e9ef0..7dd425ef8a 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -558,6 +558,12 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
return True;
}
+static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask)
+{
+ mangle_map(filename,True,False,SNUM(conn));
+ return mask_match(filename,mask,False);
+}
+
/****************************************************************************
Get an 8.3 directory entry.
****************************************************************************/
@@ -603,8 +609,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
*/
if ((strcmp(mask,"*.*") == 0) ||
mask_match(filename,mask,False) ||
- (mangle_map(filename,True,False,SNUM(conn)) &&
- mask_match(filename,mask,False)))
+ mangle_mask_match(conn,filename,mask))
{
if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
continue;
@@ -680,7 +685,15 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
ZERO_STRUCT(ste);
- /* if we can't stat it does not show it */
+ /*
+ * If user is a member of the Admin group
+ * we never hide files from them.
+ */
+
+ if (conn->admin_user)
+ return True;
+
+ /* If we can't stat it does not show it */
if (vfs_stat(conn, name, &ste) != 0)
return False;
@@ -714,73 +727,80 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
- Dir *dirp;
- char *n;
- DIR *p = conn->vfs_ops.opendir(conn,name);
- int used=0;
-
- if (!p) return(NULL);
- dirp = (Dir *)malloc(sizeof(Dir));
- if (!dirp) {
- DEBUG(0,("Out of memory in OpenDir\n"));
- conn->vfs_ops.closedir(conn,p);
- return(NULL);
- }
- dirp->pos = dirp->numentries = dirp->mallocsize = 0;
- dirp->data = dirp->current = NULL;
-
- while (True)
- {
- int l;
-
- if (used == 0) {
- n = ".";
- } else if (used == 2) {
- n = "..";
- } else {
- n = vfs_readdirname(conn, p);
- if (n == NULL)
- break;
- if ((strcmp(".",n) == 0) ||(strcmp("..",n) == 0))
- continue;
- }
-
- l = strlen(n)+1;
-
- /* If it's a vetoed file, pretend it doesn't even exist */
- if (use_veto && conn && IS_VETO_PATH(conn, n)) continue;
-
- /* Honour _hide unreadable_ option */
- if (conn && lp_hideunreadable(SNUM(conn))) {
- char *entry;
- int ret=0;
+ Dir *dirp;
+ char *n;
+ DIR *p = conn->vfs_ops.opendir(conn,name);
+ int used=0;
+
+ if (!p)
+ return(NULL);
+ dirp = (Dir *)malloc(sizeof(Dir));
+ if (!dirp) {
+ DEBUG(0,("Out of memory in OpenDir\n"));
+ conn->vfs_ops.closedir(conn,p);
+ return(NULL);
+ }
+ dirp->pos = dirp->numentries = dirp->mallocsize = 0;
+ dirp->data = dirp->current = NULL;
+
+ while (True) {
+ int l;
+ BOOL normal_entry = True;
+
+ if (used == 0) {
+ n = ".";
+ normal_entry = False;
+ } else if (used == 2) {
+ n = "..";
+ normal_entry = False;
+ } else {
+ n = vfs_readdirname(conn, p);
+ if (n == NULL)
+ break;
+ if ((strcmp(".",n) == 0) ||(strcmp("..",n) == 0))
+ continue;
+ normal_entry = True;
+ }
+
+ l = strlen(n)+1;
+
+ /* If it's a vetoed file, pretend it doesn't even exist */
+ if (normal_entry && use_veto && conn && IS_VETO_PATH(conn, n))
+ continue;
+
+ /* Honour _hide unreadable_ option */
+ if (normal_entry && conn && lp_hideunreadable(SNUM(conn))) {
+ char *entry;
+ int ret=0;
- if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_read_file(conn, entry);
- SAFE_FREE(entry);
- }
- if (!ret) continue;
- }
-
- if (used + l > dirp->mallocsize) {
- int s = MAX(used+l,used+2000);
- char *r;
- r = (char *)Realloc(dirp->data,s);
- if (!r) {
- DEBUG(0,("Out of memory in OpenDir\n"));
- break;
- }
- dirp->data = r;
- dirp->mallocsize = s;
- dirp->current = dirp->data;
- }
- pstrcpy(dirp->data+used,n);
- used += l;
- dirp->numentries++;
- }
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_read_file(conn, entry);
+ SAFE_FREE(entry);
+ }
+ if (!ret)
+ continue;
+ }
+
+ if (used + l > dirp->mallocsize) {
+ int s = MAX(used+l,used+2000);
+ char *r;
+ r = (char *)Realloc(dirp->data,s);
+ if (!r) {
+ DEBUG(0,("Out of memory in OpenDir\n"));
+ break;
+ }
+ dirp->data = r;
+ dirp->mallocsize = s;
+ dirp->current = dirp->data;
+ }
+
+ pstrcpy(dirp->data+used,n);
+ used += l;
+ dirp->numentries++;
+ }
- conn->vfs_ops.closedir(conn,p);
- return((void *)dirp);
+ conn->vfs_ops.closedir(conn,p);
+ return((void *)dirp);
}