summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-01-03 19:07:26 +0000
committerJeremy Allison <jra@samba.org>2003-01-03 19:07:26 +0000
commita26f2fbe2b320246dca43161245d66c6a01240d3 (patch)
tree9b0a346036a4157fecb4f1efec45c2452fbe3574 /source3/smbd
parent7476d9c6d0624a08542e11976641d086cb2eff90 (diff)
downloadsamba-a26f2fbe2b320246dca43161245d66c6a01240d3.tar.gz
samba-a26f2fbe2b320246dca43161245d66c6a01240d3.tar.bz2
samba-a26f2fbe2b320246dca43161245d66c6a01240d3.zip
Fix problem with "hide unreadable". stat file opens are baaack :-).
Jeremy. (This used to be commit 6e0cfec16594ade6e6c499f521781348fee25040)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c125
-rw-r--r--source3/smbd/dir.c857
-rw-r--r--source3/smbd/open.c144
3 files changed, 542 insertions, 584 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index dc52327cb4..b0620febef 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -21,64 +21,65 @@
#include "includes.h"
/****************************************************************************
-run a file if it is a magic script
+ Run a file if it is a magic script.
****************************************************************************/
+
static void check_magic(files_struct *fsp,connection_struct *conn)
{
- if (!*lp_magicscript(SNUM(conn)))
- return;
-
- DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
-
- {
- char *p;
- if (!(p = strrchr_m(fsp->fsp_name,'/')))
- p = fsp->fsp_name;
- else
- p++;
-
- if (!strequal(lp_magicscript(SNUM(conn)),p))
- return;
- }
-
- {
- int ret;
- pstring magic_output;
- pstring fname;
- SMB_STRUCT_STAT st;
- int tmp_fd, outfd;
-
- pstrcpy(fname,fsp->fsp_name);
- if (*lp_magicoutput(SNUM(conn)))
- pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
- else
- slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
-
- chmod(fname,0755);
- ret = smbrun(fname,&tmp_fd);
- DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
- unlink(fname);
- if (ret != 0 || tmp_fd == -1) {
- if (tmp_fd != -1)
- close(tmp_fd);
- return;
- }
- outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
- if (outfd == -1) {
- close(tmp_fd);
+ if (!*lp_magicscript(SNUM(conn)))
return;
+
+ DEBUG(5,("checking magic for %s\n",fsp->fsp_name));
+
+ {
+ char *p;
+ if (!(p = strrchr_m(fsp->fsp_name,'/')))
+ p = fsp->fsp_name;
+ else
+ p++;
+
+ if (!strequal(lp_magicscript(SNUM(conn)),p))
+ return;
}
- if (sys_fstat(tmp_fd,&st) == -1) {
+ {
+ int ret;
+ pstring magic_output;
+ pstring fname;
+ SMB_STRUCT_STAT st;
+ int tmp_fd, outfd;
+
+ pstrcpy(fname,fsp->fsp_name);
+ if (*lp_magicoutput(SNUM(conn)))
+ pstrcpy(magic_output,lp_magicoutput(SNUM(conn)));
+ else
+ slprintf(magic_output,sizeof(fname)-1, "%s.out",fname);
+
+ chmod(fname,0755);
+ ret = smbrun(fname,&tmp_fd);
+ DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
+ unlink(fname);
+ if (ret != 0 || tmp_fd == -1) {
+ if (tmp_fd != -1)
+ close(tmp_fd);
+ return;
+ }
+ outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
+ if (outfd == -1) {
+ close(tmp_fd);
+ return;
+ }
+
+ if (sys_fstat(tmp_fd,&st) == -1) {
+ close(tmp_fd);
+ close(outfd);
+ return;
+ }
+
+ transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
close(tmp_fd);
close(outfd);
- return;
}
-
- transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_size);
- close(tmp_fd);
- close(outfd);
- }
}
/****************************************************************************
@@ -97,8 +98,6 @@ static int close_filestruct(files_struct *fsp)
delete_write_cache(fsp);
}
- fsp->is_directory = False;
-
conn->num_files_open--;
SAFE_FREE(fsp->wbmpx_ptr);
@@ -258,17 +257,37 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
string_free(&fsp->fsp_name);
file_free(fsp);
+ return 0;
+}
+/****************************************************************************
+ Close a 'stat file' opened internally.
+****************************************************************************/
+
+static int close_stat(files_struct *fsp)
+{
+ /*
+ * Do the code common to files and directories.
+ */
+ close_filestruct(fsp);
+
+ if (fsp->fsp_name)
+ string_free(&fsp->fsp_name);
+
+ file_free(fsp);
return 0;
}
/****************************************************************************
- Close a directory opened by an NT SMB call.
+ Close a files_struct.
****************************************************************************/
int close_file(files_struct *fsp, BOOL normal_close)
{
if(fsp->is_directory)
return close_directory(fsp, normal_close);
- return close_normal_file(fsp, normal_close);
+ else if (fsp->is_stat)
+ return close_stat(fsp);
+ else
+ return close_normal_file(fsp, normal_close);
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index d3c71ad24e..4aa132d110 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -49,17 +49,17 @@ static int dptrs_open = 0;
void init_dptrs(void)
{
- static BOOL dptrs_init=False;
+ static BOOL dptrs_init=False;
- if (dptrs_init)
- return;
+ if (dptrs_init)
+ return;
- dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
+ dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
- if (!dptr_bmap)
- exit_server("out of memory in init_dptrs");
+ if (!dptr_bmap)
+ exit_server("out of memory in init_dptrs");
- dptrs_init = True;
+ dptrs_init = True;
}
/****************************************************************************
@@ -68,12 +68,12 @@ void init_dptrs(void)
static void dptr_idle(dptr_struct *dptr)
{
- if (dptr->ptr) {
- DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
- dptrs_open--;
- CloseDir(dptr->ptr);
- dptr->ptr = NULL;
- }
+ if (dptr->ptr) {
+ DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
+ dptrs_open--;
+ CloseDir(dptr->ptr);
+ dptr->ptr = NULL;
+ }
}
/****************************************************************************
@@ -82,29 +82,29 @@ static void dptr_idle(dptr_struct *dptr)
static void dptr_idleoldest(void)
{
- dptr_struct *dptr;
-
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
-
- if(!dptr) {
- DEBUG(0,("No dptrs available to idle ?\n"));
- return;
- }
-
- /*
- * Idle the oldest pointer.
- */
-
- for(; dptr; dptr = dptr->prev) {
- if (dptr->ptr) {
- dptr_idle(dptr);
- return;
- }
- }
+ dptr_struct *dptr;
+
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
+
+ if(!dptr) {
+ DEBUG(0,("No dptrs available to idle ?\n"));
+ return;
+ }
+
+ /*
+ * Idle the oldest pointer.
+ */
+
+ for(; dptr; dptr = dptr->prev) {
+ if (dptr->ptr) {
+ dptr_idle(dptr);
+ return;
+ }
+ }
}
/****************************************************************************
@@ -113,22 +113,22 @@ static void dptr_idleoldest(void)
static dptr_struct *dptr_get(int key, BOOL forclose)
{
- dptr_struct *dptr;
-
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if(dptr->dnum == key) {
- if (!forclose && !dptr->ptr) {
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
- DEBUG(4,("Reopening dptr key %d\n",key));
- if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
- dptrs_open++;
- }
- DLIST_PROMOTE(dirptrs,dptr);
- return dptr;
- }
- }
- return(NULL);
+ dptr_struct *dptr;
+
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if(dptr->dnum == key) {
+ if (!forclose && !dptr->ptr) {
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
+ DEBUG(4,("Reopening dptr key %d\n",key));
+ if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
+ dptrs_open++;
+ }
+ DLIST_PROMOTE(dirptrs,dptr);
+ return dptr;
+ }
+ }
+ return(NULL);
}
/****************************************************************************
@@ -137,11 +137,11 @@ static dptr_struct *dptr_get(int key, BOOL forclose)
static void *dptr_ptr(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->ptr);
- return(NULL);
+ if (dptr)
+ return(dptr->ptr);
+ return(NULL);
}
/****************************************************************************
@@ -150,11 +150,11 @@ static void *dptr_ptr(int key)
char *dptr_path(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->path);
- return(NULL);
+ if (dptr)
+ return(dptr->path);
+ return(NULL);
}
/****************************************************************************
@@ -163,11 +163,11 @@ char *dptr_path(int key)
char *dptr_wcard(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->wcard);
- return(NULL);
+ if (dptr)
+ return(dptr->wcard);
+ return(NULL);
}
/****************************************************************************
@@ -177,13 +177,13 @@ char *dptr_wcard(int key)
BOOL dptr_set_wcard(int key, char *wcard)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr) {
- dptr->wcard = wcard;
- return True;
- }
- return False;
+ if (dptr) {
+ dptr->wcard = wcard;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -193,13 +193,13 @@ BOOL dptr_set_wcard(int key, char *wcard)
BOOL dptr_set_attr(int key, uint16 attr)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr) {
- dptr->attr = attr;
- return True;
- }
- return False;
+ if (dptr) {
+ dptr->attr = attr;
+ return True;
+ }
+ return False;
}
/****************************************************************************
@@ -208,11 +208,11 @@ BOOL dptr_set_attr(int key, uint16 attr)
uint16 dptr_attr(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
+ dptr_struct *dptr = dptr_get(key, False);
- if (dptr)
- return(dptr->attr);
- return(0);
+ if (dptr)
+ return(dptr->attr);
+ return(0);
}
/****************************************************************************
@@ -221,31 +221,31 @@ uint16 dptr_attr(int key)
static void dptr_close_internal(dptr_struct *dptr)
{
- DEBUG(4,("closing dptr key %d\n",dptr->dnum));
+ DEBUG(4,("closing dptr key %d\n",dptr->dnum));
- DLIST_REMOVE(dirptrs, dptr);
+ DLIST_REMOVE(dirptrs, dptr);
- /*
- * Free the dnum in the bitmap. Remember the dnum value is always
- * biased by one with respect to the bitmap.
- */
+ /*
+ * Free the dnum in the bitmap. Remember the dnum value is always
+ * biased by one with respect to the bitmap.
+ */
- if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
- DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
+ if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
+ DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
dptr->dnum ));
- }
+ }
- bitmap_clear(dptr_bmap, dptr->dnum - 1);
+ bitmap_clear(dptr_bmap, dptr->dnum - 1);
- if (dptr->ptr) {
- CloseDir(dptr->ptr);
- dptrs_open--;
- }
+ if (dptr->ptr) {
+ CloseDir(dptr->ptr);
+ dptrs_open--;
+ }
- /* Lanman 2 specific code */
- SAFE_FREE(dptr->wcard);
- string_set(&dptr->path,"");
- SAFE_FREE(dptr);
+ /* Lanman 2 specific code */
+ SAFE_FREE(dptr->wcard);
+ string_set(&dptr->path,"");
+ SAFE_FREE(dptr);
}
/****************************************************************************
@@ -254,32 +254,32 @@ static void dptr_close_internal(dptr_struct *dptr)
void dptr_close(int *key)
{
- dptr_struct *dptr;
+ dptr_struct *dptr;
- if(*key == INVALID_DPTR_KEY)
- return;
+ if(*key == INVALID_DPTR_KEY)
+ return;
- /* OS/2 seems to use -1 to indicate "close all directories" */
- if (*key == -1) {
- dptr_struct *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- dptr_close_internal(dptr);
- }
- *key = INVALID_DPTR_KEY;
- return;
- }
+ /* OS/2 seems to use -1 to indicate "close all directories" */
+ if (*key == -1) {
+ dptr_struct *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ dptr_close_internal(dptr);
+ }
+ *key = INVALID_DPTR_KEY;
+ return;
+ }
- dptr = dptr_get(*key, True);
+ dptr = dptr_get(*key, True);
- if (!dptr) {
- DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
- return;
- }
+ if (!dptr) {
+ DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
+ return;
+ }
- dptr_close_internal(dptr);
+ dptr_close_internal(dptr);
- *key = INVALID_DPTR_KEY;
+ *key = INVALID_DPTR_KEY;
}
/****************************************************************************
@@ -288,12 +288,12 @@ void dptr_close(int *key)
void dptr_closecnum(connection_struct *conn)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (dptr->conn == conn)
- dptr_close_internal(dptr);
- }
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (dptr->conn == conn)
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
@@ -302,11 +302,11 @@ void dptr_closecnum(connection_struct *conn)
void dptr_idlecnum(connection_struct *conn)
{
- dptr_struct *dptr;
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if (dptr->conn == conn && dptr->ptr)
- dptr_idle(dptr);
- }
+ dptr_struct *dptr;
+ for(dptr = dirptrs; dptr; dptr = dptr->next) {
+ if (dptr->conn == conn && dptr->ptr)
+ dptr_idle(dptr);
+ }
}
/****************************************************************************
@@ -315,12 +315,12 @@ void dptr_idlecnum(connection_struct *conn)
void dptr_closepath(char *path,uint16 spid)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (spid == dptr->spid && strequal(dptr->path,path))
- dptr_close_internal(dptr);
- }
+ dptr_struct *dptr, *next;
+ for(dptr = dirptrs; dptr; dptr = next) {
+ next = dptr->next;
+ if (spid == dptr->spid && strequal(dptr->path,path))
+ dptr_close_internal(dptr);
+ }
}
/****************************************************************************
@@ -329,27 +329,27 @@ void dptr_closepath(char *path,uint16 spid)
static BOOL start_dir(connection_struct *conn, pstring directory)
{
- const char *dir2;
+ const char *dir2;
- DEBUG(5,("start_dir dir=%s\n",directory));
+ DEBUG(5,("start_dir dir=%s\n",directory));
- if (!check_name(directory,conn))
- return(False);
+ if (!check_name(directory,conn))
+ return(False);
- /* use a const pointer from here on */
- dir2 = directory;
+ /* use a const pointer from here on */
+ dir2 = directory;
- if (! *dir2)
- dir2 = ".";
-
- conn->dirptr = OpenDir(conn, directory, True);
- if (conn->dirptr) {
- dptrs_open++;
- string_set(&conn->dirpath,directory);
- return(True);
- }
+ if (! *dir2)
+ dir2 = ".";
+
+ conn->dirptr = OpenDir(conn, directory, True);
+ if (conn->dirptr) {
+ dptrs_open++;
+ string_set(&conn->dirpath,directory);
+ return(True);
+ }
- return(False);
+ return(False);
}
/****************************************************************************
@@ -360,32 +360,32 @@ static BOOL start_dir(connection_struct *conn, pstring directory)
static void dptr_close_oldest(BOOL old)
{
- dptr_struct *dptr;
-
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
-
- if(!dptr) {
- DEBUG(0,("No old dptrs available to close oldest ?\n"));
- return;
- }
-
- /*
- * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
- * does not have expect_close set. If 'old' is false, close
- * one of the new dnum handles.
- */
-
- for(; dptr; dptr = dptr->prev) {
- if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
- (!old && (dptr->dnum > 255))) {
- dptr_close_internal(dptr);
- return;
- }
- }
+ dptr_struct *dptr;
+
+ /*
+ * Go to the end of the list.
+ */
+ for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
+ ;
+
+ if(!dptr) {
+ DEBUG(0,("No old dptrs available to close oldest ?\n"));
+ return;
+ }
+
+ /*
+ * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
+ * does not have expect_close set. If 'old' is false, close
+ * one of the new dnum handles.
+ */
+
+ for(; dptr; dptr = dptr->prev) {
+ if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
+ (!old && (dptr->dnum > 255))) {
+ dptr_close_internal(dptr);
+ return;
+ }
+ }
}
/****************************************************************************
@@ -399,99 +399,98 @@ static void dptr_close_oldest(BOOL old)
int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid)
{
- dptr_struct *dptr;
-
- if (!start_dir(conn,path))
- return(-2); /* Code to say use a unix error return code. */
+ dptr_struct *dptr;
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
+ if (!start_dir(conn,path))
+ return(-2); /* Code to say use a unix error return code. */
- dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
- if(!dptr) {
- DEBUG(0,("malloc fail in dptr_create.\n"));
- return -1;
- }
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
- ZERO_STRUCTP(dptr);
+ dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
+ if(!dptr) {
+ DEBUG(0,("malloc fail in dptr_create.\n"));
+ return -1;
+ }
- if(old_handle) {
+ ZERO_STRUCTP(dptr);
- /*
- * This is an old-style SMBsearch request. Ensure the
- * value we return will fit in the range 1-255.
- */
+ if(old_handle) {
- dptr->dnum = bitmap_find(dptr_bmap, 0);
+ /*
+ * This is an old-style SMBsearch request. Ensure the
+ * value we return will fit in the range 1-255.
+ */
- if(dptr->dnum == -1 || dptr->dnum > 254) {
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
- /*
- * Try and close the oldest handle not marked for
- * expect close in the hope that the client has
- * finished with that one.
- */
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
- dptr_close_oldest(True);
+ /*
+ * Try and close the oldest handle not marked for
+ * expect close in the hope that the client has
+ * finished with that one.
+ */
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 0);
+ dptr_close_oldest(True);
- if(dptr->dnum == -1 || dptr->dnum > 254) {
- DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
- SAFE_FREE(dptr);
- return -1;
- }
- }
- } else {
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 0);
+ if(dptr->dnum == -1 || dptr->dnum > 254) {
+ DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr);
+ return -1;
+ }
+ }
+ } else {
- /*
- * This is a new-style trans2 request. Allocate from
- * a range that will return 256 - MAX_DIRECTORY_HANDLES.
- */
+ /*
+ * This is a new-style trans2 request. Allocate from
+ * a range that will return 256 - MAX_DIRECTORY_HANDLES.
+ */
- dptr->dnum = bitmap_find(dptr_bmap, 255);
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
- if(dptr->dnum == -1 || dptr->dnum < 255) {
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
- /*
- * Try and close the oldest handle close in the hope that
- * the client has finished with that one. This will only
- * happen in the case of the Win98 client bug where it leaks
- * directory handles.
- */
+ /*
+ * Try and close the oldest handle close in the hope that
+ * the client has finished with that one. This will only
+ * happen in the case of the Win98 client bug where it leaks
+ * directory handles.
+ */
- dptr_close_oldest(False);
+ dptr_close_oldest(False);
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 255);
+ /* Now try again... */
+ dptr->dnum = bitmap_find(dptr_bmap, 255);
- if(dptr->dnum == -1 || dptr->dnum < 255) {
- DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
- SAFE_FREE(dptr);
- return -1;
- }
- }
- }
+ if(dptr->dnum == -1 || dptr->dnum < 255) {
+ DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr);
+ return -1;
+ }
+ }
+ }
- bitmap_set(dptr_bmap, dptr->dnum);
+ bitmap_set(dptr_bmap, dptr->dnum);
- dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
+ dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
- dptr->ptr = conn->dirptr;
- string_set(&dptr->path,path);
- dptr->conn = conn;
- dptr->spid = spid;
- dptr->expect_close = expect_close;
- dptr->wcard = NULL; /* Only used in lanman2 searches */
- dptr->attr = 0; /* Only used in lanman2 searches */
+ dptr->ptr = conn->dirptr;
+ string_set(&dptr->path,path);
+ dptr->conn = conn;
+ dptr->spid = spid;
+ dptr->expect_close = expect_close;
+ dptr->wcard = NULL; /* Only used in lanman2 searches */
+ dptr->attr = 0; /* Only used in lanman2 searches */
- DLIST_ADD(dirptrs, dptr);
+ DLIST_ADD(dirptrs, dptr);
- DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- dptr->dnum,path,expect_close));
+ DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
+ dptr->dnum,path,expect_close));
- return(dptr->dnum);
+ return(dptr->dnum);
}
/****************************************************************************
@@ -500,19 +499,19 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp
BOOL dptr_fill(char *buf1,unsigned int key)
{
- unsigned char *buf = (unsigned char *)buf1;
- void *p = dptr_ptr(key);
- uint32 offset;
- if (!p) {
- DEBUG(1,("filling null dirptr %d\n",key));
- return(False);
- }
- offset = TellDir(p);
- DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
- (long)p,(int)offset));
- buf[0] = key;
- SIVAL(buf,1,offset | DPTR_MASK);
- return(True);
+ unsigned char *buf = (unsigned char *)buf1;
+ void *p = dptr_ptr(key);
+ uint32 offset;
+ if (!p) {
+ DEBUG(1,("filling null dirptr %d\n",key));
+ return(False);
+ }
+ offset = TellDir(p);
+ DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
+ (long)p,(int)offset));
+ buf[0] = key;
+ SIVAL(buf,1,offset | DPTR_MASK);
+ return(True);
}
/****************************************************************************
@@ -521,19 +520,20 @@ BOOL dptr_fill(char *buf1,unsigned int key)
void *dptr_fetch(char *buf,int *num)
{
- unsigned int key = *(unsigned char *)buf;
- void *p = dptr_ptr(key);
- uint32 offset;
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",key));
- return(NULL);
- }
- *num = key;
- offset = IVAL(buf,1)&~DPTR_MASK;
- SeekDir(p,offset);
- DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
- key,dptr_path(key),offset));
- return(p);
+ unsigned int key = *(unsigned char *)buf;
+ void *p = dptr_ptr(key);
+ uint32 offset;
+
+ if (!p) {
+ DEBUG(3,("fetched null dirptr %d\n",key));
+ return(NULL);
+ }
+ *num = key;
+ offset = IVAL(buf,1)&~DPTR_MASK;
+ SeekDir(p,offset);
+ DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
+ key,dptr_path(key),offset));
+ return(p);
}
/****************************************************************************
@@ -542,14 +542,14 @@ void *dptr_fetch(char *buf,int *num)
void *dptr_fetch_lanman2(int dptr_num)
{
- void *p = dptr_ptr(dptr_num);
-
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",dptr_num));
- return(NULL);
- }
- DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
- return(p);
+ void *p = dptr_ptr(dptr_num);
+
+ if (!p) {
+ DEBUG(3,("fetched null dirptr %d\n",dptr_num));
+ return(NULL);
+ }
+ DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
+ return(p);
}
/****************************************************************************
@@ -591,96 +591,88 @@ static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mas
BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
{
- char *dname;
- BOOL found = False;
- SMB_STRUCT_STAT sbuf;
- pstring path;
- pstring pathreal;
- BOOL isrootdir;
- pstring filename;
- BOOL needslash;
-
- *path = *pathreal = *filename = 0;
-
- isrootdir = (strequal(conn->dirpath,"./") ||
- strequal(conn->dirpath,".") ||
- strequal(conn->dirpath,"/"));
+ char *dname;
+ BOOL found = False;
+ SMB_STRUCT_STAT sbuf;
+ pstring path;
+ pstring pathreal;
+ BOOL isrootdir;
+ pstring filename;
+ BOOL needslash;
+
+ *path = *pathreal = *filename = 0;
+
+ isrootdir = (strequal(conn->dirpath,"./") ||
+ strequal(conn->dirpath,".") ||
+ strequal(conn->dirpath,"/"));
- needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+ needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
- if (!conn->dirptr)
- return(False);
+ if (!conn->dirptr)
+ return(False);
- while (!found)
- {
- dname = ReadDirName(conn->dirptr);
+ while (!found) {
+ dname = ReadDirName(conn->dirptr);
- DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
- (long)conn->dirptr,TellDir(conn->dirptr)));
+ DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+ (long)conn->dirptr,TellDir(conn->dirptr)));
- if (dname == NULL)
- return(False);
+ if (dname == NULL)
+ return(False);
- pstrcpy(filename,dname);
-
- /* notice the special *.* handling. This appears to be the only difference
- between the wildcard handling in this routine and in the trans2 routines.
- see masktest for a demo
- */
- if ((strcmp(mask,"*.*") == 0) ||
- mask_match(filename,mask,False) ||
- mangle_mask_match(conn,filename,mask))
- {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
-
- if (!mangle_is_8_3(filename, False)) {
- mangle_map(filename,True,False,SNUM(conn));
- }
-
- pstrcpy(fname,filename);
- *path = 0;
- pstrcpy(path,conn->dirpath);
- if(needslash)
- pstrcat(path,"/");
- pstrcpy(pathreal,path);
- pstrcat(path,fname);
- pstrcat(pathreal,dname);
- if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0)
- {
- DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
- continue;
- }
+ pstrcpy(filename,dname);
+
+ /* notice the special *.* handling. This appears to be the only difference
+ between the wildcard handling in this routine and in the trans2 routines.
+ see masktest for a demo
+ */
+ if ((strcmp(mask,"*.*") == 0) ||
+ mask_match(filename,mask,False) ||
+ mangle_mask_match(conn,filename,mask)) {
+ if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+ continue;
+
+ if (!mangle_is_8_3(filename, False))
+ mangle_map(filename,True,False,SNUM(conn));
+
+ pstrcpy(fname,filename);
+ *path = 0;
+ pstrcpy(path,conn->dirpath);
+ if(needslash)
+ pstrcat(path,"/");
+ pstrcpy(pathreal,path);
+ pstrcat(path,fname);
+ pstrcat(pathreal,dname);
+ if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0) {
+ DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
+ continue;
+ }
- *mode = dos_mode(conn,pathreal,&sbuf);
+ *mode = dos_mode(conn,pathreal,&sbuf);
- if (!dir_check_ftype(conn,*mode,&sbuf,dirtype))
- {
- DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
- continue;
- }
+ if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
+ DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+ continue;
+ }
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ *size = sbuf.st_size;
+ *date = sbuf.st_mtime;
- DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
-
- found = True;
- }
- }
-
- return(found);
-}
+ DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname));
+ found = True;
+ }
+ }
+ return(found);
+}
-typedef struct
-{
- int pos;
- int numentries;
- int mallocsize;
- char *data;
- char *current;
+typedef struct {
+ int pos;
+ int numentries;
+ int mallocsize;
+ char *data;
+ char *current;
} Dir;
/*******************************************************************
@@ -718,15 +710,14 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
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);
+ fsp = open_file_stat(conn, name, pst);
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);
+ close_file(fsp, True);
/* No access if SD get failed. */
if (!sd_size)
@@ -933,9 +924,10 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
void CloseDir(void *p)
{
- if (!p) return;
- SAFE_FREE(((Dir *)p)->data);
- SAFE_FREE(p);
+ if (!p)
+ return;
+ SAFE_FREE(((Dir *)p)->data);
+ SAFE_FREE(p);
}
/*******************************************************************
@@ -944,37 +936,39 @@ void CloseDir(void *p)
char *ReadDirName(void *p)
{
- char *ret;
- Dir *dirp = (Dir *)p;
+ char *ret;
+ Dir *dirp = (Dir *)p;
- if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) return(NULL);
+ if (!dirp || !dirp->current || dirp->pos >= dirp->numentries)
+ return(NULL);
- ret = dirp->current;
- dirp->current = skip_string(dirp->current,1);
- dirp->pos++;
+ ret = dirp->current;
+ dirp->current = skip_string(dirp->current,1);
+ dirp->pos++;
- return(ret);
+ return(ret);
}
-
/*******************************************************************
Seek a dir.
********************************************************************/
BOOL SeekDir(void *p,int pos)
{
- Dir *dirp = (Dir *)p;
+ Dir *dirp = (Dir *)p;
- if (!dirp) return(False);
+ if (!dirp)
+ return(False);
- if (pos < dirp->pos) {
- dirp->current = dirp->data;
- dirp->pos = 0;
- }
+ if (pos < dirp->pos) {
+ dirp->current = dirp->data;
+ dirp->pos = 0;
+ }
- while (dirp->pos < pos && ReadDirName(p)) ;
+ while (dirp->pos < pos && ReadDirName(p))
+ ;
- return(dirp->pos == pos);
+ return (dirp->pos == pos);
}
/*******************************************************************
@@ -983,11 +977,12 @@ BOOL SeekDir(void *p,int pos)
int TellDir(void *p)
{
- Dir *dirp = (Dir *)p;
+ Dir *dirp = (Dir *)p;
- if (!dirp) return(-1);
+ if (!dirp)
+ return(-1);
- return(dirp->pos);
+ return(dirp->pos);
}
/*******************************************************************************
@@ -996,11 +991,11 @@ int TellDir(void *p)
********************************************************************************/
typedef struct {
- ubi_dlNode node;
- char *path;
- char *name;
- char *dname;
- int snum;
+ ubi_dlNode node;
+ char *path;
+ char *name;
+ char *dname;
+ int snum;
} dir_cache_entry;
static ubi_dlNewList( dir_cache );
@@ -1016,36 +1011,36 @@ static ubi_dlNewList( dir_cache );
void DirCacheAdd( const char *path, char *name, char *dname, int snum )
{
- int pathlen;
- int namelen;
- dir_cache_entry *entry;
-
- /* Allocate the structure & string space in one go so that it can be freed
- * in one call to free().
- */
- pathlen = strlen( path ) +1; /* Bytes required to store path (with nul). */
- namelen = strlen( name ) +1; /* Bytes required to store name (with nul). */
- entry = (dir_cache_entry *)malloc( sizeof( dir_cache_entry )
- + pathlen
- + namelen
- + strlen( dname ) +1 );
- if( NULL == entry ) /* Not adding to the cache is not fatal, */
- return; /* so just return as if nothing happened. */
-
- /* Set pointers correctly and load values. */
- entry->path = pstrcpy( (char *)&entry[1], path);
- entry->name = pstrcpy( &(entry->path[pathlen]), name);
- entry->dname = pstrcpy( &(entry->name[namelen]), dname);
- entry->snum = snum;
-
- /* Add the new entry to the linked list. */
- (void)ubi_dlAddHead( dir_cache, entry );
- DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
-
- /* Free excess cache entries. */
- while( DIRCACHESIZE < dir_cache->count )
- safe_free( ubi_dlRemTail( dir_cache ) );
+ int pathlen;
+ int namelen;
+ dir_cache_entry *entry;
+ /*
+ * Allocate the structure & string space in one go so that it can be freed
+ * in one call to free().
+ */
+ pathlen = strlen(path) + 1; /* Bytes required to store path (with nul). */
+ namelen = strlen(name) + 1; /* Bytes required to store name (with nul). */
+ entry = (dir_cache_entry *)malloc( sizeof( dir_cache_entry )
+ + pathlen
+ + namelen
+ + strlen( dname ) +1 );
+ if( NULL == entry ) /* Not adding to the cache is not fatal, */
+ return; /* so just return as if nothing happened. */
+
+ /* Set pointers correctly and load values. */
+ entry->path = pstrcpy( (char *)&entry[1], path);
+ entry->name = pstrcpy( &(entry->path[pathlen]), name);
+ entry->dname = pstrcpy( &(entry->name[namelen]), dname);
+ entry->snum = snum;
+
+ /* Add the new entry to the linked list. */
+ (void)ubi_dlAddHead( dir_cache, entry );
+ DEBUG( 4, ("Added dir cache entry %s %s -> %s\n", path, name, dname ) );
+
+ /* Free excess cache entries. */
+ while( DIRCACHESIZE < dir_cache->count )
+ safe_free( ubi_dlRemTail( dir_cache ) );
}
/*****************************************************************************
@@ -1063,22 +1058,20 @@ void DirCacheAdd( const char *path, char *name, char *dname, int snum )
char *DirCacheCheck( const char *path, const char *name, int snum )
{
- dir_cache_entry *entry;
-
- for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
- NULL != entry;
- entry = (dir_cache_entry *)ubi_dlNext( entry ) )
- {
- if( entry->snum == snum
- && 0 == strcmp( name, entry->name )
- && 0 == strcmp( path, entry->path ) )
- {
- DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
- return( entry->dname );
- }
- }
-
- return(NULL);
+ dir_cache_entry *entry;
+
+ for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
+ NULL != entry;
+ entry = (dir_cache_entry *)ubi_dlNext( entry ) ) {
+ if( entry->snum == snum
+ && 0 == strcmp( name, entry->name )
+ && 0 == strcmp( path, entry->path ) ) {
+ DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
+ return( entry->dname );
+ }
+ }
+
+ return(NULL);
}
/*****************************************************************************
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index cee2b37184..d5521f7f47 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -228,6 +228,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = False;
+ fsp->is_stat = False;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
@@ -1255,6 +1256,7 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->oplock_type = NO_OPLOCK;
fsp->sent_oplock_break = NO_BREAK_SENT;
fsp->is_directory = True;
+ fsp->is_stat = False;
fsp->directory_delete_on_close = False;
fsp->conn = conn;
string_set(&fsp->fsp_name,fname);
@@ -1271,118 +1273,62 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return fsp;
}
-#if 0
-Old code - I have replaced with correct desired_access checking. JRA.
-
-/*******************************************************************
- Check if the share mode on a file allows it to be deleted or unlinked.
- Return True if sharing doesn't prevent the operation.
-********************************************************************/
+/****************************************************************************
+ Open a pseudo-file (no locking checks - a 'stat' open).
+****************************************************************************/
-BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
+files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_STAT *psbuf)
{
- int i;
- int ret = False;
- share_mode_entry *old_shares = 0;
- int num_share_modes;
- SMB_STRUCT_STAT sbuf;
- pid_t pid = sys_getpid();
- SMB_DEV_T dev;
- SMB_INO_T inode;
-
- if (vfs_stat(conn,fname,&sbuf) == -1)
- return(True);
-
- dev = sbuf.st_dev;
- inode = sbuf.st_ino;
-
- lock_share_entry(conn, dev, inode);
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
-
- /*
- * Check if the share modes will give us access.
- */
-
- if(num_share_modes != 0) {
- BOOL broke_oplock;
-
- do {
-
- broke_oplock = False;
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &old_shares[i];
-
- /*
- * Break oplocks before checking share modes. See comment in
- * open_file_shared for details.
- * Check if someone has an oplock on this file. If so we must
- * break it before continuing.
- */
- if(BATCH_OPLOCK_TYPE(share_entry->op_type)) {
-
- DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
-dev = %x, inode = %.0f\n", share_entry->op_type, fname, (unsigned int)dev, (double)inode));
+ extern struct current_user current_user;
+ BOOL got_stat = False;
+ files_struct *fsp = NULL;
- /* Oplock break.... */
- unlock_share_entry(conn, dev, inode);
+ if (!VALID_STAT(*psbuf))
+ return NULL;
- if(request_oplock_break(share_entry) == False) {
- DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
-dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (double)inode));
+ /* Can't 'stat' open directories. */
+ if(S_ISDIR(psbuf->st_mode))
+ return NULL;
- SAFE_FREE(old_shares);
- return False;
- }
- lock_share_entry(conn, dev, inode);
- broke_oplock = True;
- break;
- }
+ fsp = file_new(conn);
+ if(!fsp)
+ return NULL;
- /*
- * If this is a delete request and ALLOW_SHARE_DELETE is set then allow
- * this to proceed. This takes precedence over share modes.
- */
-
- if(!rename_op && GET_ALLOW_SHARE_DELETE(share_entry->share_mode))
- continue;
-
- /*
- * Someone else has a share lock on it, check to see
- * if we can too.
- */
- if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) ||
- (share_entry->pid != pid))
- goto free_and_exit;
-
- } /* end for */
+ fsp->conn = conn; /* The vfs_fXXX() macros need this. */
- if(broke_oplock) {
- SAFE_FREE(old_shares);
- num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
- }
- } while(broke_oplock);
- }
+ DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
/*
- * XXXX exactly what share mode combinations should be allowed for
- * deleting/renaming?
+ * Setup the files_struct for it.
*/
-
+
+ fsp->mode = psbuf->st_mode;
/*
- * If we got here then either there were no share modes or
- * all share modes were DENY_DOS and the pid == getpid() or
- * delete access was requested and all share modes had the
- * ALLOW_SHARE_DELETE bit set (takes precedence over other
- * share modes).
+ * Don't store dev or inode, we don't want any iterator
+ * to see this.
*/
+ fsp->inode = (SMB_INO_T)0;
+ fsp->dev = (SMB_DEV_T)0;
+ fsp->size = psbuf->st_size;
+ fsp->vuid = current_user.vuid;
+ fsp->pos = -1;
+ fsp->can_lock = False;
+ fsp->can_read = False;
+ fsp->can_write = False;
+ fsp->share_mode = 0;
+ fsp->desired_access = 0;
+ fsp->print_file = False;
+ fsp->modified = False;
+ fsp->oplock_type = NO_OPLOCK;
+ fsp->sent_oplock_break = NO_BREAK_SENT;
+ fsp->is_directory = False;
+ fsp->is_stat = True;
+ fsp->directory_delete_on_close = False;
+ fsp->conn = conn;
+ string_set(&fsp->fsp_name,fname);
- ret = True;
-
-free_and_exit:
+ conn->num_files_open++;
- unlock_share_entry(conn, dev, inode);
- SAFE_FREE(old_shares);
- return(ret);
+ return fsp;
}
-#endif