summaryrefslogtreecommitdiffstats
path: root/source/smbd/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/dir.c')
-rw-r--r--source/smbd/dir.c189
1 files changed, 38 insertions, 151 deletions
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 396ecd98c49..cce62870715 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -1,5 +1,6 @@
/*
- Unix SMB/CIFS implementation.
+ Unix SMB/Netbios implementation.
+ Version 1.9.
Directory handling routines
Copyright (C) Andrew Tridgell 1992-1998
@@ -57,7 +58,7 @@ void init_dptrs(void)
dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
if (!dptr_bmap)
- exit_server("out of memory in init_dptrs");
+ exit_server("out of memory in init_dptrs\n");
dptrs_init = True;
}
@@ -553,24 +554,9 @@ void *dptr_fetch_lanman2(int dptr_num)
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
{
- int mask;
-
- /* Check the "may have" search bits. */
- if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
- return False;
-
- /* Check the "must have" bits, which are the may have bits shifted eight */
- /* If must have bit is set, the file/dir can not be returned in search unless the matching
- file attribute is set */
- mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */
- if(mask) {
- if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */
- return True;
- else
- return False;
- }
-
- return True;
+ if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
+ return False;
+ return True;
}
static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask)
@@ -641,7 +627,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
pstrcpy(pathreal,path);
pstrcat(path,fname);
pstrcat(pathreal,dname);
- if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0)
+ if (conn->vfs_ops.stat(conn,dos_to_unix_static(pathreal), &sbuf) != 0)
{
DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
continue;
@@ -678,69 +664,18 @@ typedef struct
char *current;
} Dir;
-/*******************************************************************
- Check to see if a user can read a file. This is only approximate,
- it is used as part of the "hide unreadable" option. Don't
- use it for anything security sensitive.
-********************************************************************/
-static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
-{
- extern struct current_user current_user;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- files_struct *fsp;
- int smb_action;
- int access_mode;
- NTSTATUS status;
- uint32 access_granted;
-
- /*
- * 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 (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
- return False;
-
- /* Pseudo-open the file (note - no fd's created). */
-
- if(S_ISDIR(pst->st_mode))
- fsp = open_directory(conn, name, pst, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- unix_mode(conn,aRONLY|aDIR, name), &smb_action);
- else
- fsp = open_file_shared1(conn, name, pst, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
-
- if (!fsp)
- return False;
-
- /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
- sd_size = conn->vfs_ops.fget_nt_acl(fsp, fsp->fd, &psd);
- close_file(fsp, False);
-
- /* No access if SD get failed. */
- if (!sd_size)
- return False;
-
- return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
- &access_granted, &status);
-}
/*******************************************************************
- Check to see if a user can write a file (and only files, we do not
- check dirs on this one). This is only approximate,
- it is used as part of the "hide unwriteable" option. Don't
- use it for anything security sensitive.
+check to see if a user can read a file. This is only approximate,
+it is used as part of the "hide unreadable" option. Don't
+use it for anything security sensitive
********************************************************************/
-static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
+static BOOL user_can_read_file(connection_struct *conn, char *name)
{
extern struct current_user current_user;
+ SMB_STRUCT_STAT ste;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
@@ -749,6 +684,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
NTSTATUS status;
uint32 access_granted;
+ ZERO_STRUCT(ste);
+
/*
* If user is a member of the Admin group
* we never hide files from them.
@@ -758,16 +695,17 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
return True;
/* If we can't stat it does not show it */
- if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
+ if (vfs_stat(conn, name, &ste) != 0)
return False;
/* Pseudo-open the file (note - no fd's created). */
- if(S_ISDIR(pst->st_mode))
- return True;
+ if(S_ISDIR(ste.st_mode))
+ fsp = open_directory(conn, name, &ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ unix_mode(conn,aRONLY|aDIR, name), &smb_action);
else
- fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
+ fsp = open_file_shared1(conn, name, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
+ (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
if (!fsp)
return False;
@@ -780,35 +718,11 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
if (!sd_size)
return False;
- return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
+ return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
&access_granted, &status);
}
/*******************************************************************
- Is a file a "special" type ?
-********************************************************************/
-
-static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
-{
- /*
- * 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 (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0))
- return True;
-
- if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode))
- return False;
-
- return True;
-}
-
-/*******************************************************************
Open a directory.
********************************************************************/
@@ -816,9 +730,9 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
Dir *dirp;
char *n;
- DIR *p = conn->vfs_ops.opendir(conn,name);
+ DIR *p = conn->vfs_ops.opendir(conn,dos_to_unix_static(name));
int used=0;
-
+
if (!p)
return(NULL);
dirp = (Dir *)malloc(sizeof(Dir));
@@ -827,14 +741,13 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
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;
- SMB_STRUCT_STAT st;
- char *entry = NULL;
if (used == 0) {
n = ".";
@@ -849,69 +762,42 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
if ((strcmp(".",n) == 0) ||(strcmp("..",n) == 0))
continue;
normal_entry = True;
- }
+ }
- ZERO_STRUCT(st);
l = strlen(n)+1;
+ /* Return value of vfs_readdirname has already gone through
+ unix_to_dos() */
+
/* 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 (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_read_file(conn, entry, &st);
- }
- if (!ret) {
- SAFE_FREE(entry);
- continue;
- }
- }
-
- /* Honour _hide unwriteable_ option */
- if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
- int ret=0;
-
- if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_write_file(conn, entry, &st);
- }
- if (!ret) {
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_read_file(conn, entry);
SAFE_FREE(entry);
- continue;
}
- }
-
- /* Honour _hide_special_ option */
- if (normal_entry && conn && lp_hide_special_files(SNUM(conn))) {
- int ret=0;
-
- if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = file_is_special(conn, entry, &st);
- }
- if (ret) {
- SAFE_FREE(entry);
+ if (!ret)
continue;
- }
}
- SAFE_FREE(entry);
-
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;
- }
+ break;
+ }
dirp->data = r;
dirp->mallocsize = s;
dirp->current = dirp->data;
}
-
pstrcpy(dirp->data+used,n);
used += l;
dirp->numentries++;
@@ -928,9 +814,10 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
void CloseDir(void *p)
{
- if (!p) return;
- SAFE_FREE(((Dir *)p)->data);
- SAFE_FREE(p);
+ Dir *dirp = (Dir *)p;
+ if (!dirp) return;
+ SAFE_FREE(dirp->data);
+ SAFE_FREE(dirp);
}
/*******************************************************************