From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/smbd/dir.c | 955 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 955 insertions(+) create mode 100644 source3/smbd/dir.c (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c new file mode 100644 index 0000000000..ac6f918b9d --- /dev/null +++ b/source3/smbd/dir.c @@ -0,0 +1,955 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Directory handling routines + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" + +extern int DEBUGLEVEL; +extern connection_struct Connections[]; + +/* + This module implements directory related functions for Samba. +*/ + + + +uint32 dircounter = 0; + + +#define NUMDIRPTRS 256 + + +static struct dptr_struct +{ + int pid; + int cnum; + uint32 lastused; + void *ptr; + BOOL valid; + BOOL finished; + BOOL expect_close; + char *wcard; /* Field only used for lanman2 trans2_findfirst/next searches */ + uint16 attr; /* Field only used for lanman2 trans2_findfirst/next searches */ + char *path; +} +dirptrs[NUMDIRPTRS]; + + +static int dptrs_open = 0; + +/**************************************************************************** +initialise the dir array +****************************************************************************/ +void init_dptrs(void) +{ + static BOOL dptrs_init=False; + int i; + + if (dptrs_init) return; + for (i=0;i= MAXDIR) + dptr_idleoldest(); + DEBUG(4,("Reopening dptr key %d\n",key)); + if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path))) + dptrs_open++; + } + return(dirptrs[key].ptr); + } + return(NULL); +} + +/**************************************************************************** +get the dir path for a dir index +****************************************************************************/ +char *dptr_path(int key) +{ + if (dirptrs[key].valid) + return(dirptrs[key].path); + return(NULL); +} + +/**************************************************************************** +get the dir wcard for a dir index (lanman2 specific) +****************************************************************************/ +char *dptr_wcard(int key) +{ + if (dirptrs[key].valid) + return(dirptrs[key].wcard); + return(NULL); +} + +/**************************************************************************** +set the dir wcard for a dir index (lanman2 specific) +Returns 0 on ok, 1 on fail. +****************************************************************************/ +BOOL dptr_set_wcard(int key, char *wcard) +{ + if (dirptrs[key].valid) { + dirptrs[key].wcard = wcard; + return True; + } + return False; +} + +/**************************************************************************** +set the dir attrib for a dir index (lanman2 specific) +Returns 0 on ok, 1 on fail. +****************************************************************************/ +BOOL dptr_set_attr(int key, uint16 attr) +{ + if (dirptrs[key].valid) { + dirptrs[key].attr = attr; + return True; + } + return False; +} + +/**************************************************************************** +get the dir attrib for a dir index (lanman2 specific) +****************************************************************************/ +uint16 dptr_attr(int key) +{ + if (dirptrs[key].valid) + return(dirptrs[key].attr); + return(0); +} + +/**************************************************************************** +close a dptr +****************************************************************************/ +void dptr_close(int key) +{ + if (dirptrs[key].valid) { + DEBUG(4,("closing dptr key %d\n",key)); + if (dirptrs[key].ptr) { + CloseDir(dirptrs[key].ptr); + dptrs_open--; + } + /* Lanman 2 specific code */ + if (dirptrs[key].wcard) + free(dirptrs[key].wcard); + dirptrs[key].valid = False; + string_set(&dirptrs[key].path,""); + } +} + +/**************************************************************************** +close all dptrs for a cnum +****************************************************************************/ +void dptr_closecnum(int cnum) +{ + int i; + for (i=0;i= MAXDIR) + dptr_idleoldest(); + + for (i=0;ipos = dirp->numentries = dirp->mallocsize = 0; + dirp->data = dirp->current = NULL; + + while ((n = readdirname(p))) { + int l = strlen(n)+1; + 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; + } + strcpy(dirp->data+used,n); + used += l; + dirp->numentries++; + } + + closedir(p); + return((void *)dirp); +} + + +/******************************************************************* +close a directory +********************************************************************/ +void CloseDir(void *p) +{ + Dir *dirp = (Dir *)p; + if (!dirp) return; + if (dirp->data) free(dirp->data); + free(dirp); +} + +/******************************************************************* +read from a directory +********************************************************************/ +char *ReadDirName(void *p) +{ + char *ret; + Dir *dirp = (Dir *)p; + + if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) return(NULL); + + ret = dirp->current; + dirp->current = skip_string(dirp->current,1); + dirp->pos++; + + return(ret); +} + + +/******************************************************************* +seek a dir +********************************************************************/ +BOOL SeekDir(void *p,int pos) +{ + Dir *dirp = (Dir *)p; + + if (!dirp) return(False); + + if (pos < dirp->pos) { + dirp->current = dirp->data; + dirp->pos = 0; + } + + while (dirp->pos < pos && ReadDirName(p)) ; + + return(dirp->pos == pos); +} + +/******************************************************************* +tell a dir position +********************************************************************/ +int TellDir(void *p) +{ + Dir *dirp = (Dir *)p; + + if (!dirp) return(-1); + + return(dirp->pos); +} + + +static int dir_cache_size = 0; +static struct dir_cache { + struct dir_cache *next; + struct dir_cache *prev; + char *path; + char *name; + char *dname; + int snum; +} *dir_cache = NULL; + +/******************************************************************* +add an entry to the directory cache +********************************************************************/ +void DirCacheAdd(char *path,char *name,char *dname,int snum) +{ + struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry)); + if (!entry) return; + entry->path = strdup(path); + entry->name = strdup(name); + entry->dname = strdup(dname); + entry->snum = snum; + if (!entry->path || !entry->name || !entry->dname) return; + + entry->next = dir_cache; + entry->prev = NULL; + if (entry->next) entry->next->prev = entry; + dir_cache = entry; + + DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname)); + + if (dir_cache_size == DIRCACHESIZE) { + for (entry=dir_cache; entry->next; entry=entry->next) ; + free(entry->path); + free(entry->name); + free(entry->dname); + if (entry->prev) entry->prev->next = entry->next; + free(entry); + } else { + dir_cache_size++; + } +} + + +/******************************************************************* +check for an entry in the directory cache +********************************************************************/ +char *DirCacheCheck(char *path,char *name,int snum) +{ + struct dir_cache *entry; + + for (entry=dir_cache; entry; entry=entry->next) { + if (entry->snum == snum && + strcmp(path,entry->path) == 0 && + strcmp(name,entry->name) == 0) { + DEBUG(4,("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname)); + return(entry->dname); + } + } + + return(NULL); +} + +/******************************************************************* +flush entries in the dir_cache +********************************************************************/ +void DirCacheFlush(int snum) +{ + struct dir_cache *entry,*next; + + for (entry=dir_cache; entry; entry=next) { + if (entry->snum == snum) { + free(entry->path); + free(entry->dname); + free(entry->name); + next = entry->next; + if (entry->prev) entry->prev->next = entry->next; + if (entry->next) entry->next->prev = entry->prev; + if (dir_cache == entry) dir_cache = entry->next; + free(entry); + } else { + next = entry->next; + } + } +} + + +#ifdef REPLACE_GETWD +/* This is getcwd.c from bash. It is needed in Interactive UNIX. To + * add support for another OS you need to determine which of the + * conditional compilation macros you need to define. All the options + * are defined for Interactive UNIX. + */ +#ifdef ISC +#define HAVE_UNISTD_H +#define USGr3 +#define USG +#endif + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (__STDC__) +# define CONST const +# define PTR void * +#else /* !__STDC__ */ +# define CONST +# define PTR char * +#endif /* !__STDC__ */ + +#if !defined (PATH_MAX) +# if defined (MAXPATHLEN) +# define PATH_MAX MAXPATHLEN +# else /* !MAXPATHLEN */ +# define PATH_MAX 1024 +# endif /* !MAXPATHLEN */ +#endif /* !PATH_MAX */ + +#if defined (_POSIX_VERSION) || defined (USGr3) || defined (HAVE_DIRENT_H) +# if !defined (HAVE_DIRENT) +# define HAVE_DIRENT +# endif /* !HAVE_DIRENT */ +#endif /* _POSIX_VERSION || USGr3 || HAVE_DIRENT_H */ + +#if defined (HAVE_DIRENT) +# define D_NAMLEN(d) (strlen ((d)->d_name)) +#else +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* ! (_POSIX_VERSION || USGr3) */ + +#if defined (USG) || defined (USGr3) +# define d_fileno d_ino +#endif + +#if !defined (alloca) +extern char *alloca (); +#endif /* alloca */ + +/* Get the pathname of the current working directory, + and put it in SIZE bytes of BUF. Returns NULL if the + directory couldn't be determined or SIZE was too small. + If successful, returns BUF. In GNU, if BUF is NULL, + an array is allocated with `malloc'; the array is SIZE + bytes long, unless SIZE <= 0, in which case it is as + big as necessary. */ +#if defined (__STDC__) +char * +getcwd (char *buf, size_t size) +#else /* !__STDC__ */ +char * +getcwd (buf, size) + char *buf; + int size; +#endif /* !__STDC__ */ +{ + static CONST char dots[] + = "../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../../\ +../../../../../../../../../../../../../../../../../../../../../../../../../.."; + CONST char *dotp, *dotlist; + size_t dotsize; + dev_t rootdev, thisdev; + ino_t rootino, thisino; + char path[PATH_MAX + 1]; + register char *pathp; + char *pathbuf; + size_t pathsize; + struct stat st; + + if (buf != NULL && size == 0) + { + errno = EINVAL; + return ((char *)NULL); + } + + pathsize = sizeof (path); + pathp = &path[pathsize]; + *--pathp = '\0'; + pathbuf = path; + + if (stat (".", &st) < 0) + return ((char *)NULL); + thisdev = st.st_dev; + thisino = st.st_ino; + + if (stat ("/", &st) < 0) + return ((char *)NULL); + rootdev = st.st_dev; + rootino = st.st_ino; + + dotsize = sizeof (dots) - 1; + dotp = &dots[sizeof (dots)]; + dotlist = dots; + while (!(thisdev == rootdev && thisino == rootino)) + { + register DIR *dirstream; + register struct dirent *d; + dev_t dotdev; + ino_t dotino; + char mount_point; + int namlen; + + /* Look at the parent directory. */ + if (dotp == dotlist) + { + /* My, what a deep directory tree you have, Grandma. */ + char *new; + if (dotlist == dots) + { + new = malloc (dotsize * 2 + 1); + if (new == NULL) + goto lose; + memcpy (new, dots, dotsize); + } + else + { + new = realloc ((PTR) dotlist, dotsize * 2 + 1); + if (new == NULL) + goto lose; + } + memcpy (&new[dotsize], new, dotsize); + dotp = &new[dotsize]; + dotsize *= 2; + new[dotsize] = '\0'; + dotlist = new; + } + + dotp -= 3; + + /* Figure out if this directory is a mount point. */ + if (stat (dotp, &st) < 0) + goto lose; + dotdev = st.st_dev; + dotino = st.st_ino; + mount_point = dotdev != thisdev; + + /* Search for the last directory. */ + dirstream = opendir(dotp); + if (dirstream == NULL) + goto lose; + while ((d = (struct dirent *)readdir(dirstream)) != NULL) + { + if (d->d_name[0] == '.' && + (d->d_name[1] == '\0' || + (d->d_name[1] == '.' && d->d_name[2] == '\0'))) + continue; + if (mount_point || d->d_fileno == thisino) + { + char *name; + + namlen = D_NAMLEN(d); + name = (char *) + alloca (dotlist + dotsize - dotp + 1 + namlen + 1); + memcpy (name, dotp, dotlist + dotsize - dotp); + name[dotlist + dotsize - dotp] = '/'; + memcpy (&name[dotlist + dotsize - dotp + 1], + d->d_name, namlen + 1); + if (lstat (name, &st) < 0) + { + int save = errno; + closedir(dirstream); + errno = save; + goto lose; + } + if (st.st_dev == thisdev && st.st_ino == thisino) + break; + } + } + if (d == NULL) + { + int save = errno; + closedir(dirstream); + errno = save; + goto lose; + } + else + { + size_t space; + + while ((space = pathp - pathbuf) <= namlen) + { + char *new; + + if (pathbuf == path) + { + new = malloc (pathsize * 2); + if (!new) + goto lose; + } + else + { + new = realloc ((PTR) pathbuf, (pathsize * 2)); + if (!new) + goto lose; + pathp = new + space; + } + (void) memcpy (new + pathsize + space, pathp, pathsize - space); + pathp = new + pathsize + space; + pathbuf = new; + pathsize *= 2; + } + + pathp -= namlen; + (void) memcpy (pathp, d->d_name, namlen); + *--pathp = '/'; + closedir(dirstream); + } + + thisdev = dotdev; + thisino = dotino; + } + + if (pathp == &path[sizeof(path) - 1]) + *--pathp = '/'; + + if (dotlist != dots) + free ((PTR) dotlist); + + { + size_t len = pathbuf + pathsize - pathp; + if (buf == NULL) + { + if (len < (size_t) size) + len = size; + buf = (char *) malloc (len); + if (buf == NULL) + goto lose2; + } + else if ((size_t) size < len) + { + errno = ERANGE; + goto lose2; + } + (void) memcpy((PTR) buf, (PTR) pathp, len); + } + + if (pathbuf != path) + free (pathbuf); + + return (buf); + + lose: + if ((dotlist != dots) && dotlist) + { + int e = errno; + free ((PTR) dotlist); + errno = e; + } + + lose2: + if ((pathbuf != path) && pathbuf) + { + int e = errno; + free ((PTR) pathbuf); + errno = e; + } + return ((char *)NULL); +} +#endif -- cgit From 341a401b4802b2759092819ab5e50fe237a406d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 May 1996 11:23:23 +0000 Subject: handle being passed a dptr of -1 to mean "close all open dir handles". Looks like OS/2 does this. It caused a core dump. (This used to be commit 4b2579daae0a9d78780476694fd395d97445e197) --- source3/smbd/dir.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ac6f918b9d..214b28dad0 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -186,6 +186,19 @@ close a dptr ****************************************************************************/ void dptr_close(int key) { + /* OS/2 seems to use -1 to indicate "close all directories" */ + if (key == -1) { + int i; + for (i=0;i= NUMDIRPTRS) { + DEBUG(3,("Invalid key %d given to dptr_close\n",key)); + return; + } + if (dirptrs[key].valid) { DEBUG(4,("closing dptr key %d\n",key)); if (dirptrs[key].ptr) { -- cgit From e38afbf38210b8cf30c5b13dc5ea96a6dda433f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Jun 1996 15:16:09 +0000 Subject: - changed some debug levels in clientutil.c - added dir_check_ftype() to clean up the file type checking a bit - added check for libc version >= 5 for setfsuid() for Linux - moved the AM_MASTER() and related macros to nameserv.h - added proper defines for the various netbios announce types - don't call the announce_backup() code, as I'm pretty sure its wrong it sent ANN_GetBackupListReq packets as broadcasts, they are supposed to be used only by clients to the master browser to find a list of available backup servers to remote a netserverenum to, I don't think nmbd should ever send one. - fixed a bug in the browse list writing - minor debug cleanups - put in the code to discard our own broadcasts (it won't work for multi-homed hosts though) - changed ELECTION_VERSION to 1 so we can be beaten by a NT 3.51 server by lowering the os level. - only do sync_browse_lists() if we are the master browser, otherwise we'll cause network overload - don't call tell_become_backup() as it appears to be badly broken, it should only be used when the machine being told has its MAINTAIN_LIST to to auto. Not calling it does no great harm anyway - fix a nasty bug where becomebackup was confused with reset browser! - make setbuffer() not get caught by the auto protototypes (This used to be commit cfbad9b08242962f41595273de08a7293fe432b1) --- source3/smbd/dir.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 214b28dad0..32f2eb5e7d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -411,6 +411,16 @@ void *dptr_fetch_lanman2(char *params,int dptr_num) return(p); } +/**************************************************************************** +check a filetype for being valid +****************************************************************************/ +BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype) +{ + if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) + return False; + return True; +} + /**************************************************************************** get a directory entry ****************************************************************************/ @@ -474,11 +484,11 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo *mode = dos_mode(cnum,pathreal,&sbuf); - if (((*mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) - { - DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); - continue; - } + if (!dir_check_ftype(cnum,*mode,&sbuf,dirtype)) { + DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); + continue; + } + *size = sbuf.st_size; *date = sbuf.st_mtime; -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/smbd/dir.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 32f2eb5e7d..55a5983468 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; extern connection_struct Connections[]; -- cgit From 28177ca73bdbe3f8fb17a608db3df1a39e0e37a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 17 Aug 1996 11:37:44 +0000 Subject: - added support for Amiga-unix (based on BSD I think) - changed the order of PROGS and SPROGS in Makefile (SPROGS first) - another 64 bit cleanup (for INADDR_NONE) - added paranoia code in DirCacheAdd() to detect looping - fixed important DirCache flush bug - rewrote the NetServerEnum code after I found it could return servers from multiple workgroups at once, and this could cause browsing havoc. Now a null workgroup query is equivalent to a query for the servers primary workgroup - got rid of my_workgroup() - got rid of "workgroup = *" comment in Makefile. We no longer support a workgroup of *, users must set the workgroup explicitly - the wins.dat file was being stored in a different format to what it was being loaded in - this could cause havoc. fixed. - uppercase our netbios name and the workgroup name at startup - if accept fails in main loop when running as a daemon then continue, don't just exit! - don't use ./ on smbclient in smbtar - better code to detect if a process exists (This used to be commit ec3d53963064b50ff33e8eff47812aac82f164ba) --- source3/smbd/dir.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 55a5983468..42bd54c270 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -631,6 +631,7 @@ add an entry to the directory cache ********************************************************************/ void DirCacheAdd(char *path,char *name,char *dname,int snum) { + int count; struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry)); if (!entry) return; entry->path = strdup(path); @@ -647,7 +648,12 @@ void DirCacheAdd(char *path,char *name,char *dname,int snum) DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname)); if (dir_cache_size == DIRCACHESIZE) { - for (entry=dir_cache; entry->next; entry=entry->next) ; + for (entry=dir_cache, count=1; + entry->next && count < dir_cache_size; + entry=entry->next, count++) ; + if (entry->next || count != dir_cache_size) { + DEBUG(0,("DirCache bug - please report\n")); + } free(entry->path); free(entry->name); free(entry->dname); @@ -695,6 +701,7 @@ void DirCacheFlush(int snum) if (entry->next) entry->next->prev = entry->prev; if (dir_cache == entry) dir_cache = entry->next; free(entry); + dir_cache_size--; } else { next = entry->next; } -- cgit From 8c41ad5614f4b3e6218cc7a3a21526122b202709 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 24 Aug 1996 01:32:51 +0000 Subject: fixed dircahe bug (This used to be commit 050f941e21aeb57ab47ac9d29fb4acfceab45087) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 42bd54c270..f2e672987e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -649,9 +649,9 @@ void DirCacheAdd(char *path,char *name,char *dname,int snum) if (dir_cache_size == DIRCACHESIZE) { for (entry=dir_cache, count=1; - entry->next && count < dir_cache_size; + entry->next && count < dir_cache_size + 1; entry=entry->next, count++) ; - if (entry->next || count != dir_cache_size) { + if (entry->next || count != dir_cache_size + 1) { DEBUG(0,("DirCache bug - please report\n")); } free(entry->path); -- cgit From 908771bb0f0fdc7c3a523e3f28a741778c1ec227 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Aug 1996 01:46:47 +0000 Subject: added debug info (This used to be commit 4a988021a2aceaa5fc0d4e5ba2802392a7141ad8) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f2e672987e..73c4afd77e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -652,7 +652,7 @@ void DirCacheAdd(char *path,char *name,char *dname,int snum) entry->next && count < dir_cache_size + 1; entry=entry->next, count++) ; if (entry->next || count != dir_cache_size + 1) { - DEBUG(0,("DirCache bug - please report\n")); + DEBUG(0,("DirCache bug - please report %d %d\n",dir_cache_size,count)); } free(entry->path); free(entry->name); -- cgit From b719173ecb7eeff518d27952c523a64bcbcf0fb2 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 10 Dec 1996 17:49:11 +0000 Subject: Added in veto files parameter create by Whistle. jra@cygnus.com (This used to be commit d5659df9c23822766501397b8fbbffbce6842ea7) --- source3/smbd/dir.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 73c4afd77e..f3c1ae020e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -533,6 +533,9 @@ void *OpenDir(char *name) while ((n = readdirname(p))) { int l = strlen(n)+1; + /* If it's a vetoed file, pretend it doesn't even exist */ + if(is_vetoed_name(n)) + continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f3c1ae020e..2437b8b17e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Directory handling routines - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From aa864415c5183c948fe9ae221023d40265c38013 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 20 May 1997 00:32:51 +0000 Subject: dir.c: Fixed double slash issue. includes.h: Changed to ifdef FAST_SHARE_MODES. ipc.c: Changed lp_workgroup() to myworkgroup. loadparm.c: Added new shared mem parameters. Added Luke's fix. locking.c: Rewrite to do share modes better (both fast and slow modes). nameannounce.c: Changed lp_workgroup() to myworkgroup. Added Luke's fix. nameconf.c: Changed lp_workgroup() to myworkgroup. namedbname.c: Improved debug. namedbserver.c: Changed lp_workgroup() to myworkgroup. namedbsubnet.c: Added Luke's fix - rewritten somewhat. namedbwork.c: Changed lp_workgroup() to myworkgroup. nameelect.c: Added Luke's fix - rewritten somewhat. nameresp.c: Stoped shadowing global. nameserv.c: Added Luke's fix - Improved debug. nameservreply.c: Improved debug. namework.c: Changed lp_workgroup() to myworkgroup. nmbd.c: Added Luke's fix - Changed lp_workgroup() to myworkgroup. pipes.c: Changed lp_workgroup() to myworkgroup. proto.h: Added Luke's fix, added smb_shm_ proto's. reply.c: Changed lp_workgroup() to myworkgroup. server.c: Rewrite to do share modes better (both fast and slow modes). shmem.c: Rewrite to do share modes better (both fast and slow modes). smb.h: Rewrite to do share modes better (both fast and slow modes). status.c: Rewrite to do share modes better (both fast and slow modes). trans2.c: Fixed double slash issue. util.c: Tidied up, created myworkgroup. Jeremy Allison (jallison@whistle.com). (This used to be commit 2a1711eaaf08bb6776770cd3c96b3010f431a677) --- source3/smbd/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2437b8b17e..bc099dd1e8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -433,6 +433,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo BOOL isrootdir; pstring filename; BOOL matched; + BOOL needslash; *path = *pathreal = *filename = 0; @@ -440,6 +441,9 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo strequal(Connections[cnum].dirpath,".") || strequal(Connections[cnum].dirpath,"/")); + needslash = + ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/'); + if (!Connections[cnum].dirptr) return(False); @@ -467,7 +471,8 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo strcpy(fname,filename); *path = 0; strcpy(path,Connections[cnum].dirpath); - strcat(path,"/"); + if(needslash) + strcat(path,"/"); strcpy(pathreal,path); strcat(path,fname); strcat(pathreal,dname); -- cgit From ce9baa3bac6eba5f7a468557572f342d3ba918ec Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 1 Jul 1997 19:42:42 +0000 Subject: made "hide files" and "veto files" into per-service parameter sections, instead of just [global]. this makes it easier to decide whether to remove the "hide dot files" per-service parameter, and supercede it with a default "hide files" value of ".*". lkcl (This used to be commit f3ee4620ea7b93e4a00e77f9d787a118fd11ccaa) --- source3/smbd/dir.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index bc099dd1e8..f674c92804 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -108,7 +108,7 @@ static void dptr_idleoldest(void) /**************************************************************************** get the dir ptr for a dir index ****************************************************************************/ -static void *dptr_get(int key,uint32 lastused) +static void *dptr_get(int cnum, int key,uint32 lastused) { if (dirptrs[key].valid) { if (lastused) dirptrs[key].lastused = lastused; @@ -116,7 +116,7 @@ static void *dptr_get(int key,uint32 lastused) if (dptrs_open >= MAXDIR) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path))) + if ((dirptrs[key].ptr = OpenDir(cnum, dirptrs[key].path))) dptrs_open++; } return(dirptrs[key].ptr); @@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory) if (! *directory) directory = "."; - Connections[cnum].dirptr = OpenDir(directory); + Connections[cnum].dirptr = OpenDir(cnum, directory); if (Connections[cnum].dirptr) { dptrs_open++; string_set(&Connections[cnum].dirpath,directory); @@ -345,10 +345,10 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) /**************************************************************************** fill the 5 byte server reserved dptr field ****************************************************************************/ -BOOL dptr_fill(char *buf1,unsigned int key) +BOOL dptr_fill(int cnum, char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; - void *p = dptr_get(key,0); + void *p = dptr_get(cnum, key,0); uint32 offset; if (!p) { DEBUG(1,("filling null dirptr %d\n",key)); @@ -373,10 +373,10 @@ BOOL dptr_zero(char *buf) /**************************************************************************** fetch the dir ptr and seek it given the 5 byte server field ****************************************************************************/ -void *dptr_fetch(char *buf,int *num) +void *dptr_fetch(int cnum, char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_get(key,dircounter++); + void *p = dptr_get(cnum, key,dircounter++); uint32 offset; if (!p) { DEBUG(3,("fetched null dirptr %d\n",key)); @@ -393,9 +393,9 @@ void *dptr_fetch(char *buf,int *num) /**************************************************************************** fetch the dir ptr and seek it given the lanman2 parameter block ****************************************************************************/ -void *dptr_fetch_lanman2(char *params,int dptr_num) +void *dptr_fetch_lanman2(int cnum, char *params,int dptr_num) { - void *p = dptr_get(dptr_num,dircounter++); + void *p = dptr_get(cnum, dptr_num,dircounter++); uint32 resume_key = SVAL(params,6); BOOL uses_resume_key = BITSETW(params+10,2); BOOL continue_bit = BITSETW(params+10,3); @@ -520,7 +520,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(char *name) +void *OpenDir(int cnum, char *name) { Dir *dirp; char *n; @@ -539,7 +539,7 @@ void *OpenDir(char *name) while ((n = readdirname(p))) { int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if(is_vetoed_name(n)) + if(is_vetoed_name(cnum, n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); -- cgit From 1599e41ec42998fdf05a3b22c3f3a93f8b4832ed Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 1 Jul 1997 20:50:57 +0000 Subject: Rolled back Lukes changes. Not quite ready for prime time. Jeremy (jallison@whistle.com) (This used to be commit ed04ec7ab8b8e73b5442bdef03d5a3c994247b4e) --- source3/smbd/dir.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f674c92804..bc099dd1e8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -108,7 +108,7 @@ static void dptr_idleoldest(void) /**************************************************************************** get the dir ptr for a dir index ****************************************************************************/ -static void *dptr_get(int cnum, int key,uint32 lastused) +static void *dptr_get(int key,uint32 lastused) { if (dirptrs[key].valid) { if (lastused) dirptrs[key].lastused = lastused; @@ -116,7 +116,7 @@ static void *dptr_get(int cnum, int key,uint32 lastused) if (dptrs_open >= MAXDIR) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dirptrs[key].ptr = OpenDir(cnum, dirptrs[key].path))) + if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path))) dptrs_open++; } return(dirptrs[key].ptr); @@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory) if (! *directory) directory = "."; - Connections[cnum].dirptr = OpenDir(cnum, directory); + Connections[cnum].dirptr = OpenDir(directory); if (Connections[cnum].dirptr) { dptrs_open++; string_set(&Connections[cnum].dirpath,directory); @@ -345,10 +345,10 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) /**************************************************************************** fill the 5 byte server reserved dptr field ****************************************************************************/ -BOOL dptr_fill(int cnum, char *buf1,unsigned int key) +BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; - void *p = dptr_get(cnum, key,0); + void *p = dptr_get(key,0); uint32 offset; if (!p) { DEBUG(1,("filling null dirptr %d\n",key)); @@ -373,10 +373,10 @@ BOOL dptr_zero(char *buf) /**************************************************************************** fetch the dir ptr and seek it given the 5 byte server field ****************************************************************************/ -void *dptr_fetch(int cnum, char *buf,int *num) +void *dptr_fetch(char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_get(cnum, key,dircounter++); + void *p = dptr_get(key,dircounter++); uint32 offset; if (!p) { DEBUG(3,("fetched null dirptr %d\n",key)); @@ -393,9 +393,9 @@ void *dptr_fetch(int cnum, char *buf,int *num) /**************************************************************************** fetch the dir ptr and seek it given the lanman2 parameter block ****************************************************************************/ -void *dptr_fetch_lanman2(int cnum, char *params,int dptr_num) +void *dptr_fetch_lanman2(char *params,int dptr_num) { - void *p = dptr_get(cnum, dptr_num,dircounter++); + void *p = dptr_get(dptr_num,dircounter++); uint32 resume_key = SVAL(params,6); BOOL uses_resume_key = BITSETW(params+10,2); BOOL continue_bit = BITSETW(params+10,3); @@ -520,7 +520,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(int cnum, char *name) +void *OpenDir(char *name) { Dir *dirp; char *n; @@ -539,7 +539,7 @@ void *OpenDir(int cnum, char *name) while ((n = readdirname(p))) { int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if(is_vetoed_name(cnum, n)) + if(is_vetoed_name(n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); -- cgit From f6384eca672565bf820f86721de5cf25a5e5e9fe Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 3 Jul 1997 19:44:06 +0000 Subject: Fix for deleting directories that contain only veto files. Needed for interoperability with netatalk volumes. Jeremy (jallison@whistle.com) (This used to be commit e72a8513bccf77177f6fb6002057fee608947a32) --- source3/smbd/dir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index bc099dd1e8..1d0228864c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -116,7 +116,7 @@ static void *dptr_get(int key,uint32 lastused) if (dptrs_open >= MAXDIR) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path))) + if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path, True))) dptrs_open++; } return(dirptrs[key].ptr); @@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory) if (! *directory) directory = "."; - Connections[cnum].dirptr = OpenDir(directory); + Connections[cnum].dirptr = OpenDir(directory, True); if (Connections[cnum].dirptr) { dptrs_open++; string_set(&Connections[cnum].dirpath,directory); @@ -520,7 +520,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(char *name) +void *OpenDir(char *name, BOOL use_veto) { Dir *dirp; char *n; @@ -539,7 +539,7 @@ void *OpenDir(char *name) while ((n = readdirname(p))) { int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if(is_vetoed_name(n)) + if(use_veto && is_vetoed_name(n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); -- cgit From 1fe89d0b716ccd9fca4abe4daf89df063b38f4b3 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sun, 6 Jul 1997 13:48:10 +0000 Subject: added, tested and debugged new "hide files" option. lkcl (This used to be commit 60af320a436c3a26230fd7ac71856e67ef64e819) --- source3/smbd/dir.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1d0228864c..2a219e0281 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -108,7 +108,7 @@ static void dptr_idleoldest(void) /**************************************************************************** get the dir ptr for a dir index ****************************************************************************/ -static void *dptr_get(int key,uint32 lastused) +static void *dptr_get(int snum, int key,uint32 lastused) { if (dirptrs[key].valid) { if (lastused) dirptrs[key].lastused = lastused; @@ -116,7 +116,7 @@ static void *dptr_get(int key,uint32 lastused) if (dptrs_open >= MAXDIR) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path, True))) + if ((dirptrs[key].ptr = OpenDir(snum, dirptrs[key].path, True))) dptrs_open++; } return(dirptrs[key].ptr); @@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory) if (! *directory) directory = "."; - Connections[cnum].dirptr = OpenDir(directory, True); + Connections[cnum].dirptr = OpenDir(SNUM(cnum), directory, True); if (Connections[cnum].dirptr) { dptrs_open++; string_set(&Connections[cnum].dirpath,directory); @@ -345,10 +345,10 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) /**************************************************************************** fill the 5 byte server reserved dptr field ****************************************************************************/ -BOOL dptr_fill(char *buf1,unsigned int key) +BOOL dptr_fill(int snum, char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; - void *p = dptr_get(key,0); + void *p = dptr_get(snum, key,0); uint32 offset; if (!p) { DEBUG(1,("filling null dirptr %d\n",key)); @@ -373,10 +373,10 @@ BOOL dptr_zero(char *buf) /**************************************************************************** fetch the dir ptr and seek it given the 5 byte server field ****************************************************************************/ -void *dptr_fetch(char *buf,int *num) +void *dptr_fetch(int snum, char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_get(key,dircounter++); + void *p = dptr_get(snum, key,dircounter++); uint32 offset; if (!p) { DEBUG(3,("fetched null dirptr %d\n",key)); @@ -393,9 +393,9 @@ void *dptr_fetch(char *buf,int *num) /**************************************************************************** fetch the dir ptr and seek it given the lanman2 parameter block ****************************************************************************/ -void *dptr_fetch_lanman2(char *params,int dptr_num) +void *dptr_fetch_lanman2(int snum, char *params,int dptr_num) { - void *p = dptr_get(dptr_num,dircounter++); + void *p = dptr_get(snum, dptr_num,dircounter++); uint32 resume_key = SVAL(params,6); BOOL uses_resume_key = BITSETW(params+10,2); BOOL continue_bit = BITSETW(params+10,3); @@ -520,7 +520,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(char *name, BOOL use_veto) +void *OpenDir(int snum, char *name, BOOL use_veto) { Dir *dirp; char *n; @@ -536,11 +536,13 @@ void *OpenDir(char *name, BOOL use_veto) dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = readdirname(p))) { + while ((n = readdirname(p))) + { int l = strlen(n)+1; + /* If it's a vetoed file, pretend it doesn't even exist */ - if(use_veto && is_vetoed_name(n)) - continue; + if (use_veto && is_vetoed_name(snum, n)) continue; + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; -- cgit From 15ae50ca5203bc4c04567e400ba041a4d1757b2b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 24 Jul 1997 17:25:11 +0000 Subject: Makefile: Added UNIXWARE 2.x with shadow passwords from fja@extratech.com client.c: Made prompt appear at debug level 0. Fixed strcasecmp redefinition. Caused client to use set_blocking rather than making fcntl calls itself. dir.c: Removed redundent snum parameters. includes.h: Added SCO fixes. loadparm.c: Made default 'files to hide' a null string. nmbd.c: Removed O_NONBLOCK from pid file open for platforms that dont have it. proto.h: Changed snum to cnum where needed. Changed is_xx_path to is_in_path (now called via MACRO). quotas.c: Swapped setuid/seteuid calls when restoring uid. reply.c: Removed redundent snum parameters. server.c: Changed snum to cnum where needed. Setup new veto_list, hide_list namelists. Added standard_sub changes from Stefaan A Eeckels and Paul Rippin shmem.c: Changed cast for sizeof to be int before negating. smb.h: Added new veto_list, hide_list entries to connections. Added IS_PRINT, IS_HIDDEN_PATH, IS_VETO_PATH macros. trans2.c: Removed redundent snum parameters. util.c: Added standard_sub_basic changes from Stefaan A Eeckels and Paul Rippin Fixed up veto/hidden path processing so the paths are pres-parsed and checked for wildcards (for speed). Jeremy (jallison@whistle.com) (This used to be commit 9afa36f7874cfd527aa6ef1e7965c1d35d46ab1f) --- source3/smbd/dir.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2a219e0281..5bd5b1d573 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -108,18 +108,20 @@ static void dptr_idleoldest(void) /**************************************************************************** get the dir ptr for a dir index ****************************************************************************/ -static void *dptr_get(int snum, int key,uint32 lastused) +static void *dptr_get(int key,uint32 lastused) { - if (dirptrs[key].valid) { - if (lastused) dirptrs[key].lastused = lastused; - if (!dirptrs[key].ptr) { + struct dptr_struct *dp = &dirptrs[key]; + + if (dp->valid) { + if (lastused) dp->lastused = lastused; + if (!dp->ptr) { if (dptrs_open >= MAXDIR) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dirptrs[key].ptr = OpenDir(snum, dirptrs[key].path, True))) + if ((dp->ptr = OpenDir(dp->cnum, dp->path, True))) dptrs_open++; } - return(dirptrs[key].ptr); + return(dp->ptr); } return(NULL); } @@ -259,7 +261,7 @@ static BOOL start_dir(int cnum,char *directory) if (! *directory) directory = "."; - Connections[cnum].dirptr = OpenDir(SNUM(cnum), directory, True); + Connections[cnum].dirptr = OpenDir(cnum, directory, True); if (Connections[cnum].dirptr) { dptrs_open++; string_set(&Connections[cnum].dirpath,directory); @@ -345,10 +347,10 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) /**************************************************************************** fill the 5 byte server reserved dptr field ****************************************************************************/ -BOOL dptr_fill(int snum, char *buf1,unsigned int key) +BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; - void *p = dptr_get(snum, key,0); + void *p = dptr_get(key,0); uint32 offset; if (!p) { DEBUG(1,("filling null dirptr %d\n",key)); @@ -373,10 +375,10 @@ BOOL dptr_zero(char *buf) /**************************************************************************** fetch the dir ptr and seek it given the 5 byte server field ****************************************************************************/ -void *dptr_fetch(int snum, char *buf,int *num) +void *dptr_fetch(char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_get(snum, key,dircounter++); + void *p = dptr_get(key,dircounter++); uint32 offset; if (!p) { DEBUG(3,("fetched null dirptr %d\n",key)); @@ -393,9 +395,9 @@ void *dptr_fetch(int snum, char *buf,int *num) /**************************************************************************** fetch the dir ptr and seek it given the lanman2 parameter block ****************************************************************************/ -void *dptr_fetch_lanman2(int snum, char *params,int dptr_num) +void *dptr_fetch_lanman2(char *params,int dptr_num) { - void *p = dptr_get(snum, dptr_num,dircounter++); + void *p = dptr_get(dptr_num,dircounter++); uint32 resume_key = SVAL(params,6); BOOL uses_resume_key = BITSETW(params+10,2); BOOL continue_bit = BITSETW(params+10,3); @@ -520,7 +522,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(int snum, char *name, BOOL use_veto) +void *OpenDir(int cnum, char *name, BOOL use_veto) { Dir *dirp; char *n; @@ -541,7 +543,7 @@ void *OpenDir(int snum, char *name, BOOL use_veto) int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if (use_veto && is_vetoed_name(snum, n)) continue; + if (use_veto && IS_VETO_PATH(cnum, n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); -- cgit From c76dc7c2963d1205cf46849df6b6f0edbf63692d Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 20 Aug 1997 01:22:05 +0000 Subject: Fix suggested by "Christian Groessler" dir.c: Cause dptr_create to return -2 when failing on unix error. reply.c: Use UNIXERROR in more cases. server.c: Add ENOTDIR mapping to error table. trans2.c: Correctly determine UNIX error on dptr_create. Jeremy (jallison@whistle.com) (This used to be commit de38a0b34fcd65fa3024300f978aa30eb86d854f) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5bd5b1d573..06ee6ae8ed 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -282,7 +282,7 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) int oldi; if (!start_dir(cnum,path)) - return(-1); + return(-2); /* Code to say use a unix error return code. */ if (dptrs_open >= MAXDIR) dptr_idleoldest(); -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 06ee6ae8ed..567bc14424 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -461,7 +461,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo matched = False; - strcpy(filename,dname); + pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || (name_map_mangle(filename,True,SNUM(cnum)) && -- cgit From a0cd12e221af54e00aa7dd971c080881da8b32ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 1997 02:38:19 +0000 Subject: dir.c: more pstrcpys. local.h: Add OPLOCK_BREAK_TIMEOUT. password.c: Fix for paranoia password server security bug. proto.h: Updated. reply.c: Oplock changes. server.c: Massive oplock changes - nearly there.... smb.h: oplock definitions. util.c: Add local message processing queues for oplocks. Jeremy (jallison@whistle.com) (This used to be commit 92f1553db2cdf6f32881eb984a87050cf3e4760b) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 567bc14424..316b58818f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -470,12 +470,12 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; - strcpy(fname,filename); + pstrcpy(fname,filename); *path = 0; - strcpy(path,Connections[cnum].dirpath); + pstrcpy(path,Connections[cnum].dirpath); if(needslash) strcat(path,"/"); - strcpy(pathreal,path); + pstrcpy(pathreal,path); strcat(path,fname); strcat(pathreal,dname); if (sys_stat(pathreal,&sbuf) != 0) -- cgit From 50147ca41c12694b9658c15ddf4b2d8b4e1d4746 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Thu, 16 Oct 1997 01:03:18 +0000 Subject: Made changes to the dir cache functions: - They now use the ubi_dLinkList linked list code. This is not a big gain, I suppose. It would be significant if there were lots of doubly-linked lists in the code and I replaced them all. The only other advantage is that the code is more modular, which appeals to my own sense of order, if no one elses. :-} - I allocate space for the entry structure and the strings in one go, instead of using malloc() and separate strdup() calls. This should be more efficient, and allows for a single call to free() to free the whole thing. These are very minor changes, but they do serve to make me more familiar with the code overall. (This used to be commit 1dafef88871338f06dbcbbb67ce3bbbb460d7bb6) --- source3/smbd/dir.c | 204 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 83 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 316b58818f..d69ccfe1c1 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -628,97 +628,135 @@ int TellDir(void *p) } -static int dir_cache_size = 0; -static struct dir_cache { - struct dir_cache *next; - struct dir_cache *prev; - char *path; - char *name; - char *dname; - int snum; -} *dir_cache = NULL; +/* -------------------------------------------------------------------------- ** + * This section manages a global directory cache. + * (It should probably be split into a separate module. crh) + * -------------------------------------------------------------------------- ** + */ -/******************************************************************* -add an entry to the directory cache -********************************************************************/ -void DirCacheAdd(char *path,char *name,char *dname,int snum) -{ - int count; - struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry)); - if (!entry) return; - entry->path = strdup(path); - entry->name = strdup(name); - entry->dname = strdup(dname); - entry->snum = snum; - if (!entry->path || !entry->name || !entry->dname) return; - - entry->next = dir_cache; - entry->prev = NULL; - if (entry->next) entry->next->prev = entry; - dir_cache = entry; - - DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname)); - - if (dir_cache_size == DIRCACHESIZE) { - for (entry=dir_cache, count=1; - entry->next && count < dir_cache_size + 1; - entry=entry->next, count++) ; - if (entry->next || count != dir_cache_size + 1) { - DEBUG(0,("DirCache bug - please report %d %d\n",dir_cache_size,count)); - } - free(entry->path); - free(entry->name); - free(entry->dname); - if (entry->prev) entry->prev->next = entry->next; - free(entry); - } else { - dir_cache_size++; - } -} +#include "ubi_dLinkList.h" +typedef struct + { + ubi_dlNode node; + char *path; + char *name; + char *dname; + int snum; + } dir_cache_entry; + +static ubi_dlList dir_cache[1] = { { NULL, NULL, 0 } }; + +void DirCacheAdd( char *path, char *name, char *dname, int snum ) + /* ------------------------------------------------------------------------ ** + * Add an entry to the directory cache. + * + * Input: path - + * name - + * dname - + * snum - + * + * Output: None. + * + * ------------------------------------------------------------------------ ** + */ + { + 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 = strcpy( (char *)&entry[1], path); + entry->name = strcpy( &(entry->path[pathlen]), name); + entry->dname = strcpy( &(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 ) + free( ubi_dlRemTail( dir_cache ) ); + + } /* DirCacheAdd */ + + +char *DirCacheCheck( char *path, char *name, int snum ) + /* ------------------------------------------------------------------------ ** + * Search for an entry to the directory cache. + * + * Input: path - + * name - + * snum - + * + * Output: The dname string of the located entry, or NULL if the entry was + * not found. + * + * Notes: This uses a linear search, which is is okay because of + * the small size of the cache. Use a splay tree or hash + * for large caches. + * + * ------------------------------------------------------------------------ ** + */ + { + dir_cache_entry *entry; -/******************************************************************* -check for an entry in the directory cache -********************************************************************/ -char *DirCacheCheck(char *path,char *name,int snum) -{ - struct dir_cache *entry; - - for (entry=dir_cache; entry; entry=entry->next) { - if (entry->snum == snum && - strcmp(path,entry->path) == 0 && - strcmp(name,entry->name) == 0) { - DEBUG(4,("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname)); - return(entry->dname); + 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); -} + } /* DirCacheCheck */ + +void DirCacheFlush( int snum ) + /* ------------------------------------------------------------------------ ** + * Remove all cache entries which have an snum that matches the input. + * + * Input: snum - + * + * Output: None. + * + * ------------------------------------------------------------------------ ** + */ + { + dir_cache_entry *entry; + ubi_dlNodePtr next; -/******************************************************************* -flush entries in the dir_cache -********************************************************************/ -void DirCacheFlush(int snum) -{ - struct dir_cache *entry,*next; - - for (entry=dir_cache; entry; entry=next) { - if (entry->snum == snum) { - free(entry->path); - free(entry->dname); - free(entry->name); - next = entry->next; - if (entry->prev) entry->prev->next = entry->next; - if (entry->next) entry->next->prev = entry->prev; - if (dir_cache == entry) dir_cache = entry->next; - free(entry); - dir_cache_size--; - } else { - next = entry->next; + for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); NULL != entry; ) + { + next = ubi_dlNext( entry ); + if( entry->snum == snum ) + free( ubi_dlRemThis( dir_cache, entry ) ); + entry = (dir_cache_entry *)next; } - } -} + } /* DirCacheFlush */ + +/* -------------------------------------------------------------------------- ** + * End of the section that manages the global directory cache. + * -------------------------------------------------------------------------- ** + */ #ifdef REPLACE_GETWD -- cgit From 10087a663bfda233d3e18137f469f0cc7e769a0a Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 17 Oct 1997 21:06:20 +0000 Subject: Simply moved the #include for ubi_dLinkList.h from within dir.c to includes.h. More consistent with current practice. (This used to be commit cb51c860b352fb9d07fb3298d0317274ba6c9925) --- source3/smbd/dir.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index d69ccfe1c1..c12305499a 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -634,8 +634,6 @@ int TellDir(void *p) * -------------------------------------------------------------------------- ** */ -#include "ubi_dLinkList.h" - typedef struct { ubi_dlNode node; -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index c12305499a..d751653263 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Directory handling routines - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From de3badf479eb08c19d4abc0625488effc79dc1fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 1998 19:53:55 +0000 Subject: Fix for NT redirector bug where deltree fails if the resume key indexes are changed between directory scans. This fix does what NT4.x SP3 does in that it stops using resume keys and returns zero instead. We now use the filename in findnext to continue the search in the correct place (as NT does). Jeremy. (This used to be commit b813fb22c4c1b0ee48667e99e82434d20266bbf2) --- source3/smbd/dir.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index d751653263..a34406cc65 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -393,21 +393,16 @@ void *dptr_fetch(char *buf,int *num) } /**************************************************************************** -fetch the dir ptr and seek it given the lanman2 parameter block +fetch the dir ptr. ****************************************************************************/ -void *dptr_fetch_lanman2(char *params,int dptr_num) +void *dptr_fetch_lanman2(int dptr_num) { void *p = dptr_get(dptr_num,dircounter++); - uint32 resume_key = SVAL(params,6); - BOOL uses_resume_key = BITSETW(params+10,2); - BOOL continue_bit = BITSETW(params+10,3); if (!p) { DEBUG(3,("fetched null dirptr %d\n",dptr_num)); return(NULL); } - if(uses_resume_key && !continue_bit) - SeekDir(p,resume_key); DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num))); return(p); } -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/smbd/dir.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index a34406cc65..37fcd05743 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -469,10 +469,10 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo *path = 0; pstrcpy(path,Connections[cnum].dirpath); if(needslash) - strcat(path,"/"); + pstrcat(path,"/"); pstrcpy(pathreal,path); - strcat(path,fname); - strcat(pathreal,dname); + pstrcat(path,fname); + pstrcat(pathreal,dname); if (sys_stat(pathreal,&sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]\n",path)); @@ -552,7 +552,7 @@ void *OpenDir(int cnum, char *name, BOOL use_veto) dirp->mallocsize = s; dirp->current = dirp->data; } - strcpy(dirp->data+used,n); + pstrcpy(dirp->data+used,n); used += l; dirp->numentries++; } @@ -671,9 +671,9 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum ) return; /* so just return as if nothing happened. */ /* Set pointers correctly and load values. */ - entry->path = strcpy( (char *)&entry[1], path); - entry->name = strcpy( &(entry->path[pathlen]), name); - entry->dname = strcpy( &(entry->name[namelen]), dname); + 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. */ -- cgit From 6580fa6b5ce023a6bb7ce8aa9b8ab4b5c524f08b Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 22 May 1998 05:16:27 +0000 Subject: Removed all ubiqx includes from includes.h. So far, this was only a problem for dir.h, which I've fixed. Andrew did not add includes.h to the ubiqx headers, which is good because it would cause internal conflicts within the ubiqx tree modules. It's also bad because the definitions and includes that are part of includes.h are now in the ubiqx C files, but not in the header files. So, if includes.h were to redefine int, for example, the new definition would be in the ubiqx C files, but not in the headers. So, until Andrew and I can work something out that we both agree upon, there are three basic rules: 1) Don't include includes.h in the ubiqx headers. Problems may arise. 2) The ubiqx headers must follow includes.h in any Samba module that uses them. This can and should all be worked out. We just have to talk about it. Chris -)----- (This used to be commit 2b6be7084df4ddfca3a1ab7b73304007c5f9d0aa) --- source3/smbd/dir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 37fcd05743..59ee23bbe8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "ubiqx/ubi_dLinkList.h" extern int DEBUGLEVEL; extern connection_struct Connections[]; -- cgit From cfc43a5a2fe65cccd9902bc28441da6c8d29f6a0 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 22 May 1998 07:46:39 +0000 Subject: I've put the ubiqx headers back into includes.h, and removed them from dir.c & mangle.c. This was possible after I checked the tree code to make sure that the tree code did not reference functions by macro name. Also, note that the AVL module has been removed to prevent conflict with the SplayTree macro defines. Chris -)----- (This used to be commit a1f4c8567c3c5264cbfa99867fa894cafab7da81) --- source3/smbd/dir.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 59ee23bbe8..37fcd05743 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "ubiqx/ubi_dLinkList.h" extern int DEBUGLEVEL; extern connection_struct Connections[]; -- cgit From 471087c9d28a4058efc16f98784cb179ffc1e4c4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Jul 1998 22:21:24 +0000 Subject: Code added to fix the renaming of a directory under NT SMB calls. local.h: Changed MAXDIR to MAX_OPEN_DIRECTORIES - shmem size also tuned by this. dir.c: Use MAX_OPEN_DIRECTORIES. nttrans.c: Allow opening of a directory to succeed. Doesn't actually open a file descriptor but takes a files_struct slot marked as an fd. reply.c: Changed to close any outstanding is_directory files. reply_close changed to understand directory files. server.c: Added open_directory(), close_directory() calls. smb.h: Added is_directory to files_struct. Changed OPEN_FNUM to check that target is !is_directory (this prevents the normal file calls from processing a directory files_struct. Jeremy. (This used to be commit e01ce693f47e75e277f3440d46e32b0bd866b550) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 37fcd05743..8296a90fa1 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -115,7 +115,7 @@ static void *dptr_get(int key,uint32 lastused) if (dp->valid) { if (lastused) dp->lastused = lastused; if (!dp->ptr) { - if (dptrs_open >= MAXDIR) + if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("Reopening dptr key %d\n",key)); if ((dp->ptr = OpenDir(dp->cnum, dp->path, True))) @@ -284,7 +284,7 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) if (!start_dir(cnum,path)) return(-2); /* Code to say use a unix error return code. */ - if (dptrs_open >= MAXDIR) + if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); for (i=0;i Date: Fri, 24 Jul 1998 07:43:13 +0000 Subject: Changed the definition of the linked list header used in the directory cache so that it uses the new ubi_dlNewList() macro in ubi_dLinkList.h. (This used to be commit 16f0ad0c913e2d5b0198409485c56ad4809ca077) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 8296a90fa1..ceb9ae7633 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -638,7 +638,7 @@ typedef struct int snum; } dir_cache_entry; -static ubi_dlList dir_cache[1] = { { NULL, NULL, 0 } }; +static ubi_dlNewList( dir_cache ); void DirCacheAdd( char *path, char *name, char *dname, int snum ) /* ------------------------------------------------------------------------ ** -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/smbd/dir.c | 301 +++-------------------------------------------------- 1 file changed, 14 insertions(+), 287 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ceb9ae7633..44e0556f20 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -30,7 +30,7 @@ extern connection_struct Connections[]; -uint32 dircounter = 0; +static uint32 dircounter = 0; #define NUMDIRPTRS 256 @@ -723,7 +723,7 @@ char *DirCacheCheck( char *path, char *name, int snum ) return(NULL); } /* DirCacheCheck */ -void DirCacheFlush( int snum ) +void DirCacheFlush(int snum) /* ------------------------------------------------------------------------ ** * Remove all cache entries which have an snum that matches the input. * @@ -733,18 +733,18 @@ void DirCacheFlush( int snum ) * * ------------------------------------------------------------------------ ** */ - { - dir_cache_entry *entry; - ubi_dlNodePtr next; - - for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); NULL != entry; ) - { - next = ubi_dlNext( entry ); - if( entry->snum == snum ) - free( ubi_dlRemThis( dir_cache, entry ) ); - entry = (dir_cache_entry *)next; - } - } /* DirCacheFlush */ +{ + dir_cache_entry *entry; + ubi_dlNodePtr next; + + for(entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); + NULL != entry; ) { + next = ubi_dlNext( entry ); + if( entry->snum == snum ) + free( ubi_dlRemThis( dir_cache, entry ) ); + entry = (dir_cache_entry *)next; + } +} /* DirCacheFlush */ /* -------------------------------------------------------------------------- ** * End of the section that manages the global directory cache. @@ -752,276 +752,3 @@ void DirCacheFlush( int snum ) */ -#ifdef REPLACE_GETWD -/* This is getcwd.c from bash. It is needed in Interactive UNIX. To - * add support for another OS you need to determine which of the - * conditional compilation macros you need to define. All the options - * are defined for Interactive UNIX. - */ -#ifdef ISC -#define HAVE_UNISTD_H -#define USGr3 -#define USG -#endif - -#if defined (HAVE_UNISTD_H) -# include -#endif - -#if defined (__STDC__) -# define CONST const -# define PTR void * -#else /* !__STDC__ */ -# define CONST -# define PTR char * -#endif /* !__STDC__ */ - -#if !defined (PATH_MAX) -# if defined (MAXPATHLEN) -# define PATH_MAX MAXPATHLEN -# else /* !MAXPATHLEN */ -# define PATH_MAX 1024 -# endif /* !MAXPATHLEN */ -#endif /* !PATH_MAX */ - -#if defined (_POSIX_VERSION) || defined (USGr3) || defined (HAVE_DIRENT_H) -# if !defined (HAVE_DIRENT) -# define HAVE_DIRENT -# endif /* !HAVE_DIRENT */ -#endif /* _POSIX_VERSION || USGr3 || HAVE_DIRENT_H */ - -#if defined (HAVE_DIRENT) -# define D_NAMLEN(d) (strlen ((d)->d_name)) -#else -# define D_NAMLEN(d) ((d)->d_namlen) -#endif /* ! (_POSIX_VERSION || USGr3) */ - -#if defined (USG) || defined (USGr3) -# define d_fileno d_ino -#endif - -#if !defined (alloca) -extern char *alloca (); -#endif /* alloca */ - -/* Get the pathname of the current working directory, - and put it in SIZE bytes of BUF. Returns NULL if the - directory couldn't be determined or SIZE was too small. - If successful, returns BUF. In GNU, if BUF is NULL, - an array is allocated with `malloc'; the array is SIZE - bytes long, unless SIZE <= 0, in which case it is as - big as necessary. */ -#if defined (__STDC__) -char * -getcwd (char *buf, size_t size) -#else /* !__STDC__ */ -char * -getcwd (buf, size) - char *buf; - int size; -#endif /* !__STDC__ */ -{ - static CONST char dots[] - = "../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../../\ -../../../../../../../../../../../../../../../../../../../../../../../../../.."; - CONST char *dotp, *dotlist; - size_t dotsize; - dev_t rootdev, thisdev; - ino_t rootino, thisino; - char path[PATH_MAX + 1]; - register char *pathp; - char *pathbuf; - size_t pathsize; - struct stat st; - - if (buf != NULL && size == 0) - { - errno = EINVAL; - return ((char *)NULL); - } - - pathsize = sizeof (path); - pathp = &path[pathsize]; - *--pathp = '\0'; - pathbuf = path; - - if (stat (".", &st) < 0) - return ((char *)NULL); - thisdev = st.st_dev; - thisino = st.st_ino; - - if (stat ("/", &st) < 0) - return ((char *)NULL); - rootdev = st.st_dev; - rootino = st.st_ino; - - dotsize = sizeof (dots) - 1; - dotp = &dots[sizeof (dots)]; - dotlist = dots; - while (!(thisdev == rootdev && thisino == rootino)) - { - register DIR *dirstream; - register struct dirent *d; - dev_t dotdev; - ino_t dotino; - char mount_point; - int namlen; - - /* Look at the parent directory. */ - if (dotp == dotlist) - { - /* My, what a deep directory tree you have, Grandma. */ - char *new; - if (dotlist == dots) - { - new = malloc (dotsize * 2 + 1); - if (new == NULL) - goto lose; - memcpy (new, dots, dotsize); - } - else - { - new = realloc ((PTR) dotlist, dotsize * 2 + 1); - if (new == NULL) - goto lose; - } - memcpy (&new[dotsize], new, dotsize); - dotp = &new[dotsize]; - dotsize *= 2; - new[dotsize] = '\0'; - dotlist = new; - } - - dotp -= 3; - - /* Figure out if this directory is a mount point. */ - if (stat (dotp, &st) < 0) - goto lose; - dotdev = st.st_dev; - dotino = st.st_ino; - mount_point = dotdev != thisdev; - - /* Search for the last directory. */ - dirstream = opendir(dotp); - if (dirstream == NULL) - goto lose; - while ((d = (struct dirent *)readdir(dirstream)) != NULL) - { - if (d->d_name[0] == '.' && - (d->d_name[1] == '\0' || - (d->d_name[1] == '.' && d->d_name[2] == '\0'))) - continue; - if (mount_point || d->d_fileno == thisino) - { - char *name; - - namlen = D_NAMLEN(d); - name = (char *) - alloca (dotlist + dotsize - dotp + 1 + namlen + 1); - memcpy (name, dotp, dotlist + dotsize - dotp); - name[dotlist + dotsize - dotp] = '/'; - memcpy (&name[dotlist + dotsize - dotp + 1], - d->d_name, namlen + 1); - if (lstat (name, &st) < 0) - { - int save = errno; - closedir(dirstream); - errno = save; - goto lose; - } - if (st.st_dev == thisdev && st.st_ino == thisino) - break; - } - } - if (d == NULL) - { - int save = errno; - closedir(dirstream); - errno = save; - goto lose; - } - else - { - size_t space; - - while ((space = pathp - pathbuf) <= namlen) - { - char *new; - - if (pathbuf == path) - { - new = malloc (pathsize * 2); - if (!new) - goto lose; - } - else - { - new = realloc ((PTR) pathbuf, (pathsize * 2)); - if (!new) - goto lose; - pathp = new + space; - } - (void) memcpy (new + pathsize + space, pathp, pathsize - space); - pathp = new + pathsize + space; - pathbuf = new; - pathsize *= 2; - } - - pathp -= namlen; - (void) memcpy (pathp, d->d_name, namlen); - *--pathp = '/'; - closedir(dirstream); - } - - thisdev = dotdev; - thisino = dotino; - } - - if (pathp == &path[sizeof(path) - 1]) - *--pathp = '/'; - - if (dotlist != dots) - free ((PTR) dotlist); - - { - size_t len = pathbuf + pathsize - pathp; - if (buf == NULL) - { - if (len < (size_t) size) - len = size; - buf = (char *) malloc (len); - if (buf == NULL) - goto lose2; - } - else if ((size_t) size < len) - { - errno = ERANGE; - goto lose2; - } - (void) memcpy((PTR) buf, (PTR) pathp, len); - } - - if (pathbuf != path) - free (pathbuf); - - return (buf); - - lose: - if ((dotlist != dots) && dotlist) - { - int e = errno; - free ((PTR) dotlist); - errno = e; - } - - lose2: - if ((pathbuf != path) && pathbuf) - { - int e = errno; - free ((PTR) pathbuf); - errno = e; - } - return ((char *)NULL); -} -#endif -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/smbd/dir.c | 128 ++++++++++++++++++++++++++--------------------------- 1 file changed, 63 insertions(+), 65 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 44e0556f20..42ed68f713 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -22,7 +22,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern connection_struct Connections[]; /* This module implements directory related functions for Samba. @@ -36,18 +35,17 @@ static uint32 dircounter = 0; #define NUMDIRPTRS 256 -static struct dptr_struct -{ - int pid; - int cnum; - uint32 lastused; - void *ptr; - BOOL valid; - BOOL finished; - BOOL expect_close; - char *wcard; /* Field only used for lanman2 trans2_findfirst/next searches */ - uint16 attr; /* Field only used for lanman2 trans2_findfirst/next searches */ - char *path; +static struct dptr_struct { + int pid; + connection_struct *conn; + uint32 lastused; + void *ptr; + BOOL valid; + BOOL finished; + BOOL expect_close; + char *wcard; /* Field only used for trans2_ searches */ + uint16 attr; /* Field only used for trans2_ searches */ + char *path; } dirptrs[NUMDIRPTRS]; @@ -110,20 +108,20 @@ get the dir ptr for a dir index ****************************************************************************/ static void *dptr_get(int key,uint32 lastused) { - struct dptr_struct *dp = &dirptrs[key]; - - if (dp->valid) { - if (lastused) dp->lastused = lastused; - if (!dp->ptr) { - if (dptrs_open >= MAX_OPEN_DIRECTORIES) - dptr_idleoldest(); - DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dp->ptr = OpenDir(dp->cnum, dp->path, True))) - dptrs_open++; - } - return(dp->ptr); - } - return(NULL); + struct dptr_struct *dp = &dirptrs[key]; + + if (dp->valid) { + if (lastused) dp->lastused = lastused; + if (!dp->ptr) { + if (dptrs_open >= MAX_OPEN_DIRECTORIES) + dptr_idleoldest(); + DEBUG(4,("Reopening dptr key %d\n",key)); + if ((dp->ptr = OpenDir(dp->conn, dp->path, True))) + dptrs_open++; + } + return(dp->ptr); + } + return(NULL); } /**************************************************************************** @@ -217,22 +215,22 @@ void dptr_close(int key) /**************************************************************************** close all dptrs for a cnum ****************************************************************************/ -void dptr_closecnum(int cnum) +void dptr_closecnum(connection_struct *conn) { int i; for (i=0;idirptr = OpenDir(conn, directory, True); + if (conn->dirptr) { + dptrs_open++; + string_set(&conn->dirpath,directory); + return(True); + } - return(False); + return(False); } /**************************************************************************** create a new dir ptr ****************************************************************************/ -int dptr_create(int cnum,char *path, BOOL expect_close,int pid) +int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid) { int i; uint32 old; int oldi; - if (!start_dir(cnum,path)) + if (!start_dir(conn,path)) return(-2); /* Code to say use a unix error return code. */ if (dptrs_open >= MAX_OPEN_DIRECTORIES) @@ -325,11 +323,11 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid) if (dirptrs[i].valid) dptr_close(i); - dirptrs[i].ptr = Connections[cnum].dirptr; + dirptrs[i].ptr = conn->dirptr; string_set(&dirptrs[i].path,path); dirptrs[i].lastused = dircounter++; dirptrs[i].finished = False; - dirptrs[i].cnum = cnum; + dirptrs[i].conn = conn; dirptrs[i].pid = pid; dirptrs[i].expect_close = expect_close; dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */ @@ -357,7 +355,7 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(False); } offset = TellDir(p); - DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,p,offset)); + DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,(unsigned)p,offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); return(True); @@ -410,7 +408,7 @@ void *dptr_fetch_lanman2(int dptr_num) /**************************************************************************** check a filetype for being valid ****************************************************************************/ -BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype) +BOOL dir_check_ftype(connection_struct *conn,int mode,struct stat *st,int dirtype) { if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) return False; @@ -420,7 +418,7 @@ BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype) /**************************************************************************** get a directory entry ****************************************************************************/ -BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend) +BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend) { char *dname; BOOL found = False; @@ -434,22 +432,22 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo *path = *pathreal = *filename = 0; - isrootdir = (strequal(Connections[cnum].dirpath,"./") || - strequal(Connections[cnum].dirpath,".") || - strequal(Connections[cnum].dirpath,"/")); + isrootdir = (strequal(conn->dirpath,"./") || + strequal(conn->dirpath,".") || + strequal(conn->dirpath,"/")); needslash = - ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/'); + ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); - if (!Connections[cnum].dirptr) + if (!conn->dirptr) return(False); while (!found) { - dname = ReadDirName(Connections[cnum].dirptr); + dname = ReadDirName(conn->dirptr); DEBUG(6,("readdir on dirptr 0x%x now at offset %d\n", - Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr))); + (unsigned)conn->dirptr,TellDir(conn->dirptr))); if (dname == NULL) return(False); @@ -459,7 +457,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || - (name_map_mangle(filename,True,SNUM(cnum)) && + (name_map_mangle(filename,True,SNUM(conn)) && mask_match(filename,mask,False,False))) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) @@ -467,7 +465,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo pstrcpy(fname,filename); *path = 0; - pstrcpy(path,Connections[cnum].dirpath); + pstrcpy(path,conn->dirpath); if(needslash) pstrcat(path,"/"); pstrcpy(pathreal,path); @@ -483,9 +481,9 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo !strequal(fname,".") && !strequal(fname,"..")) continue; - *mode = dos_mode(cnum,pathreal,&sbuf); + *mode = dos_mode(conn,pathreal,&sbuf); - if (!dir_check_ftype(cnum,*mode,&sbuf,dirtype)) { + if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) { DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); continue; } @@ -517,7 +515,7 @@ typedef struct /******************************************************************* open a directory ********************************************************************/ -void *OpenDir(int cnum, char *name, BOOL use_veto) +void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; @@ -538,7 +536,7 @@ void *OpenDir(int cnum, char *name, BOOL use_veto) int l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if (use_veto && IS_VETO_PATH(cnum, n)) continue; + if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); -- cgit From 18556274139cc5a00593471bd745354d98a35303 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Sep 1998 20:11:54 +0000 Subject: More abstraction of file system data types, to move to a 64 bit file interface for the NT SMB's. Created a new define, SMB_STRUCT_STAT that currently is defined to be struct stat - this wil change to a user defined type containing 64 bit info when the correct wrappers are written for 64 bit stat(), fstat() and lstat() calls. Also changed all sys_xxxx() calls that were previously just wrappers to the same call prefixed by a dos_to_unix() call into dos_xxxx() calls. This makes it explicit when a pathname translation is being done, and when it is not. Now, all sys_xxx() calls are meant to be wrappers to mask OS differences, and not silently converting filenames on the fly. Jeremy. (This used to be commit 28aa182dbffaa4ffd86047e608400de4b26e80eb) --- source3/smbd/dir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 42ed68f713..7c81b826d1 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -408,7 +408,7 @@ void *dptr_fetch_lanman2(int dptr_num) /**************************************************************************** check a filetype for being valid ****************************************************************************/ -BOOL dir_check_ftype(connection_struct *conn,int mode,struct stat *st,int dirtype) +BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype) { if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) return False; @@ -422,7 +422,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,in { char *dname; BOOL found = False; - struct stat sbuf; + SMB_STRUCT_STAT sbuf; pstring path; pstring pathreal; BOOL isrootdir; @@ -471,7 +471,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,in pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (sys_stat(pathreal,&sbuf) != 0) + if (dos_stat(pathreal,&sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]\n",path)); continue; @@ -519,7 +519,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - void *p = sys_opendir(name); + void *p = dos_opendir(name); int used=0; if (!p) return(NULL); -- cgit From 7bb86c1b132bce31a006ea9768a54db7a45fe1a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Sep 1998 18:40:31 +0000 Subject: Ok - this is the 64 bit widening check in. It changes the configure to check for stat64 and friends, and then changes much of Samba to use the data type SMB_OFF_T for file size information. stat/fstat/lstat/lseek/ftruncate have now become sys_stat etc. to hide the 64 bit calls if needed. Note that this still does not expose 64 bit functionality to the client, as the changes to the reply_xxx smb's are not yet done. This code change should make these changes possible. Still to do before full 64 bit-ness to the client: fcntl lock code. statfs code widening of dev_t and ino_t (now possible due to SMB_DEV_T and SMB_OFF_T types being in place). Let me know if wierd things happen after this check-in and I'll fix them :-). Jeremy. (This used to be commit 14500936c321d15995c963766aac67bf1f4e3824) --- source3/smbd/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7c81b826d1..73db295548 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -418,7 +418,8 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di /**************************************************************************** get a directory entry ****************************************************************************/ -BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend) +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; -- cgit From cf3a9741dc7427efb97eff09a3c197a906ce6767 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Sep 1998 21:43:48 +0000 Subject: Changes to test in configure if capabilities are enabled on a system. Changes to get Samba to compile cleanly with the IRIX compiler with the options : -fullwarn -woff 1209,1174 (the -woff options are to turn off warnings about unused function parameters and controlling loop expressions being constants). Split prototype generation as we hit a limit in IRIX nawk. Removed "." code in smbd/filename.c (yet again :-). Jeremy. (This used to be commit e0567433bd72aec17bf5a54cc292701095d25f09) --- source3/smbd/dir.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 73db295548..03864334eb 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -428,7 +428,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, pstring pathreal; BOOL isrootdir; pstring filename; - BOOL matched; BOOL needslash; *path = *pathreal = *filename = 0; @@ -453,8 +452,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, if (dname == NULL) return(False); - matched = False; - pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || -- cgit From a2297c720388bd098394552590dd9120622f97c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 12:36:23 +0000 Subject: fixed some cast warnings from "cc -64" on IRIX (This used to be commit 624097e8f4a104393865ee100e884f000ca3f6df) --- source3/smbd/dir.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 03864334eb..da907b27a2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -355,7 +355,8 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(False); } offset = TellDir(p); - DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,(unsigned)p,offset)); + DEBUG(6,("fill on key %ld dirptr 0x%x now at %d\n",key, + (long)p,offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); return(True); @@ -446,8 +447,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, { dname = ReadDirName(conn->dirptr); - DEBUG(6,("readdir on dirptr 0x%x now at offset %d\n", - (unsigned)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); -- cgit From 788263ba2f749c5bb1546ca6c9363fd508e94280 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:21:33 +0000 Subject: - fixed a bunch of warnings and minor errors - got smbtorture to compile - removed %D from some of lukes code - Luke, what is %D? it ain't portable anyway (This used to be commit 91597c12fb593f49b23c7cea5b64dbb89a0428b3) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index da907b27a2..4b1a58016c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -356,7 +356,7 @@ BOOL dptr_fill(char *buf1,unsigned int key) } offset = TellDir(p); DEBUG(6,("fill on key %ld dirptr 0x%x now at %d\n",key, - (long)p,offset)); + (long)p,(int)offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); return(True); -- cgit From 3a4a2d56befe66e16003a46432ae77f6b6d62c8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 21:54:26 +0000 Subject: fixed a warning (This used to be commit d4291d353b293bbc65fb0bf76c2d943733297726) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 4b1a58016c..5b7b08b476 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -355,7 +355,7 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(False); } offset = TellDir(p); - DEBUG(6,("fill on key %ld dirptr 0x%x now at %d\n",key, + DEBUG(6,("fill on key %ld dirptr 0x%lx now at %d\n",key, (long)p,(int)offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); -- cgit From eaac4014f08f62ba3e64cc179650fe0fe93ea8ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 21:58:24 +0000 Subject: really fixed the warning this time :) (This used to be commit 64692f292fc610b90de97a85101203946ce65bfa) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5b7b08b476..db2de23f6d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -355,7 +355,7 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(False); } offset = TellDir(p); - DEBUG(6,("fill on key %ld dirptr 0x%lx now at %d\n",key, + 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); -- cgit From bfc38ff872446e0ad365c22327c779e72a81bef9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Nov 1998 21:17:20 +0000 Subject: Makefile.in: Added maintainer mode fixes. aclocal.m4: Added AC_LIBTESTFUNC. configure.in: Fixed -lsecurity -lsec problems. client.c: dos_ fixes. groupdb/aliasunix.c: Dead code removal. include/includes.h: Added default PRINTCAP_NAME. lib/genrand.c: dos_ fixes. lib/replace.c: Added strtoul. lib/system.c: dos_ fixes. lib/util.c: dos_ fixes. lib/util_sid.c: Signed/unsigned fixes. lib/util_str.c: removed bad const. locking/locking_slow.c: dos_ fixes. printing/printing.c: dos_ fixes. rpc_server/srv_samr.c: Dead code removal. rpc_server/srv_sid.c: global_myworkgroup defined with wrong size AGAIN ! smbd/dir.c: dos_ fixes. smbd/open.c: dos_ fixes. smbd/oplock.c: dos_ fixes. smbd/reply.c smbd/server.c smbd/service.c smbd/uid.c: dos_ fixes. Jeremy. (This used to be commit 6acb4b68f68d516e2ac3c47e500f5600d653435e) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index db2de23f6d..dcf1d158b4 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -518,7 +518,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - void *p = dos_opendir(name); + DIR *p = dos_opendir(name); int used=0; if (!p) return(NULL); @@ -530,7 +530,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = readdirname(p))) + while ((n = dos_readdirname(p))) { int l = strlen(n)+1; -- cgit From d4ba8a3fb31698603cb2da740a0e434dd43eb48e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 4 Apr 1999 05:40:28 +0000 Subject: Use VFS operations for file I/O. Changed calls to dos_{opendir,readdir} to vfs_{opendir,readdir} equivalents. (This used to be commit 5051a210619374639121124e32d24217255e992e) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index dcf1d158b4..52d271e284 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -470,7 +470,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (dos_stat(pathreal,&sbuf) != 0) + if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]\n",path)); continue; @@ -518,7 +518,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = dos_opendir(name); + DIR *p = conn->vfs_ops.opendir(name); int used=0; if (!p) return(NULL); @@ -530,7 +530,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = dos_readdirname(p))) + while ((n = vfs_readdirname(conn, p))) { int l = strlen(n)+1; -- cgit From 06c7ec8485c449dbcff7ea4f24ecce068fdab44c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 8 Apr 1999 03:01:18 +0000 Subject: Forgot about closedir() function for VFS. Hoo embarassing. (This used to be commit c1cbe07c0391c36066b068fdd42bf1aa40259a5c) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 52d271e284..b7ae2af47c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -524,7 +524,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { - closedir(p); + conn->vfs_ops.closedir(p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; @@ -554,7 +554,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->numentries++; } - closedir(p); + conn->vfs_ops.closedir(p); return((void *)dirp); } -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/dir.c | 643 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 407 insertions(+), 236 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b7ae2af47c..28faa9a06b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -27,257 +27,378 @@ extern int DEBUGLEVEL; This module implements directory related functions for Samba. */ - - -static uint32 dircounter = 0; - - -#define NUMDIRPTRS 256 - - -static struct dptr_struct { - int pid; +typedef struct _dptr_struct { + struct _dptr_struct *next, *prev; + int dnum; + uint16 spid; connection_struct *conn; - uint32 lastused; void *ptr; - BOOL valid; - BOOL finished; BOOL expect_close; char *wcard; /* Field only used for trans2_ searches */ uint16 attr; /* Field only used for trans2_ searches */ char *path; -} -dirptrs[NUMDIRPTRS]; +} dptr_struct; +static struct bitmap *dptr_bmap; +static dptr_struct *dirptrs; static int dptrs_open = 0; +#define INVALID_DPTR_KEY (-3) + /**************************************************************************** -initialise the dir array + Initialise the dir bitmap. ****************************************************************************/ + void init_dptrs(void) { static BOOL dptrs_init=False; - int i; - if (dptrs_init) return; - for (i=0;iptr) { + DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum)); dptrs_open--; - CloseDir(dirptrs[key].ptr); - dirptrs[key].ptr = NULL; - } + CloseDir(dptr->ptr); + dptr->ptr = NULL; + } } /**************************************************************************** -idle the oldest dptr + Idle the oldest dptr. ****************************************************************************/ + static void dptr_idleoldest(void) { - int i; - uint32 old=dircounter+1; - int oldi= -1; - for (i=0;inext; 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; } - if (oldi != -1) - dptr_idle(oldi); - else - DEBUG(0,("No dptrs available to idle??\n")); + } } /**************************************************************************** -get the dir ptr for a dir index + Get the dptr_struct for a dir index. ****************************************************************************/ -static void *dptr_get(int key,uint32 lastused) + +static dptr_struct *dptr_get(int key, BOOL forclose) { - struct dptr_struct *dp = &dirptrs[key]; - - if (dp->valid) { - if (lastused) dp->lastused = lastused; - if (!dp->ptr) { - if (dptrs_open >= MAX_OPEN_DIRECTORIES) - dptr_idleoldest(); - DEBUG(4,("Reopening dptr key %d\n",key)); - if ((dp->ptr = OpenDir(dp->conn, dp->path, True))) - dptrs_open++; - } - return(dp->ptr); - } - 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); } /**************************************************************************** -get the dir path for a dir index + Get the dptr ptr for a dir index. ****************************************************************************/ + +static void *dptr_ptr(int key) +{ + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) + return(dptr->ptr); + return(NULL); +} + +/**************************************************************************** + Get the dir path for a dir index. +****************************************************************************/ + char *dptr_path(int key) { - if (dirptrs[key].valid) - return(dirptrs[key].path); + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) + return(dptr->path); return(NULL); } /**************************************************************************** -get the dir wcard for a dir index (lanman2 specific) + Get the dir wcard for a dir index (lanman2 specific). ****************************************************************************/ + char *dptr_wcard(int key) { - if (dirptrs[key].valid) - return(dirptrs[key].wcard); + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) + return(dptr->wcard); return(NULL); } /**************************************************************************** -set the dir wcard for a dir index (lanman2 specific) -Returns 0 on ok, 1 on fail. + Set the dir wcard for a dir index (lanman2 specific). + Returns 0 on ok, 1 on fail. ****************************************************************************/ + BOOL dptr_set_wcard(int key, char *wcard) { - if (dirptrs[key].valid) { - dirptrs[key].wcard = wcard; + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) { + dptr->wcard = wcard; return True; } return False; } /**************************************************************************** -set the dir attrib for a dir index (lanman2 specific) -Returns 0 on ok, 1 on fail. + Set the dir attrib for a dir index (lanman2 specific). + Returns 0 on ok, 1 on fail. ****************************************************************************/ + BOOL dptr_set_attr(int key, uint16 attr) { - if (dirptrs[key].valid) { - dirptrs[key].attr = attr; + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) { + dptr->attr = attr; return True; } return False; } /**************************************************************************** -get the dir attrib for a dir index (lanman2 specific) + Get the dir attrib for a dir index (lanman2 specific) ****************************************************************************/ + uint16 dptr_attr(int key) { - if (dirptrs[key].valid) - return(dirptrs[key].attr); + dptr_struct *dptr = dptr_get(key, False); + + if (dptr) + return(dptr->attr); return(0); } /**************************************************************************** -close a dptr + Close a dptr (internal func). +****************************************************************************/ + +static void dptr_close_internal(dptr_struct *dptr) +{ + DEBUG(4,("closing dptr key %d\n",dptr->dnum)); + + DLIST_REMOVE(dirptrs, dptr); + + /* + * 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", + dptr->dnum )); + } + + bitmap_clear(dptr_bmap, dptr->dnum - 1); + + if (dptr->ptr) { + CloseDir(dptr->ptr); + dptrs_open--; + } + + /* Lanman 2 specific code */ + if (dptr->wcard) + free(dptr->wcard); + string_set(&dptr->path,""); + free((char *)dptr); +} + +/**************************************************************************** + Close a dptr given a key. ****************************************************************************/ -void dptr_close(int key) + +void dptr_close(int *key) { + dptr_struct *dptr; + + if(*key == INVALID_DPTR_KEY) + return; + /* OS/2 seems to use -1 to indicate "close all directories" */ - if (key == -1) { - int i; - for (i=0;inext; + dptr_close_internal(dptr); + } + *key = INVALID_DPTR_KEY; return; } - if (key < 0 || key >= NUMDIRPTRS) { - DEBUG(3,("Invalid key %d given to dptr_close\n",key)); + dptr = dptr_get(*key, True); + + if (!dptr) { + DEBUG(0,("Invalid key %d given to dptr_close\n", *key)); return; } - if (dirptrs[key].valid) { - DEBUG(4,("closing dptr key %d\n",key)); - if (dirptrs[key].ptr) { - CloseDir(dirptrs[key].ptr); - dptrs_open--; - } - /* Lanman 2 specific code */ - if (dirptrs[key].wcard) - free(dirptrs[key].wcard); - dirptrs[key].valid = False; - string_set(&dirptrs[key].path,""); - } + dptr_close_internal(dptr); + + *key = INVALID_DPTR_KEY; } /**************************************************************************** -close all dptrs for a cnum + Close all dptrs for a cnum. ****************************************************************************/ + void dptr_closecnum(connection_struct *conn) { - int i; - for (i=0;inext; + if (dptr->conn == conn) + dptr_close_internal(dptr); + } } /**************************************************************************** -idle all dptrs for a cnum + Idle all dptrs for a cnum. ****************************************************************************/ + void dptr_idlecnum(connection_struct *conn) { - int i; - for (i=0;inext) { + if (dptr->conn == conn && dptr->ptr) + dptr_idle(dptr); + } } /**************************************************************************** -close a dptr that matches a given path, only if it matches the pid also + Close a dptr that matches a given path, only if it matches the spid also. ****************************************************************************/ -void dptr_closepath(char *path,int pid) + +void dptr_closepath(char *path,uint16 spid) { - int i; - for (i=0;inext; + if (spid == dptr->spid && strequal(dptr->path,path)) + dptr_close_internal(dptr); + } } /**************************************************************************** - start a directory listing + Start a directory listing. ****************************************************************************/ + static BOOL start_dir(connection_struct *conn,char *directory) { - 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); - if (! *directory) - directory = "."; - - conn->dirptr = OpenDir(conn, directory, True); - if (conn->dirptr) { - dptrs_open++; - string_set(&conn->dirpath,directory); - return(True); - } + if (! *directory) + directory = "."; + + conn->dirptr = OpenDir(conn, directory, True); + if (conn->dirptr) { + dptrs_open++; + string_set(&conn->dirpath,directory); + return(True); + } - return(False); + return(False); } +/**************************************************************************** + Try and close the oldest handle not marked for + expect close in the hope that the client has + finished with that one. +****************************************************************************/ + +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; + } + } +} /**************************************************************************** -create a new dir ptr + Create a new dir ptr. If the flag old_handle is true then we must allocate + from the bitmap range 0 - 255 as old SMBsearch directory handles are only + one byte long. If old_handle is false we allocate from the range + 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure + a directory handle is never zero. All the above is folklore taught to + me at Andrew's knee.... :-) :-). JRA. ****************************************************************************/ -int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid) + +int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid) { - int i; - uint32 old; - int oldi; + dptr_struct *dptr; if (!start_dir(conn,path)) return(-2); /* Code to say use a unix error return code. */ @@ -285,70 +406,103 @@ int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid) if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); - for (i=0;idnum = bitmap_find(dptr_bmap, 0); + + if(dptr->dnum == -1 || dptr->dnum > 254) { + + /* + * Try and close the oldest handle not marked for + * expect close in the hope that the client has + * finished with that one. + */ + + dptr_close_oldest(True); + /* Now try again... */ + dptr->dnum = bitmap_find(dptr_bmap, 0); - /* as a 2nd option, grab the oldest not marked for expect_close */ - if (i == -1) { - old=dircounter+1; - oldi= -1; - for (i=0;idnum == -1 || dptr->dnum > 254) { + DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); + free((char *)dptr); + return -1; } - i = oldi; - } + } + } else { + + /* + * 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); + + if(dptr->dnum == -1 || dptr->dnum < 255) { - /* a 3rd option - grab the oldest one */ - if (i == -1) { - old=dircounter+1; - oldi= -1; - for (i=0;idnum = 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)); + free((char *)dptr); + return -1; } - i = oldi; + } } - if (i == -1) { - DEBUG(0,("Error - all dirptrs in use??\n")); - return(-1); - } + bitmap_set(dptr_bmap, dptr->dnum); + + dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ - if (dirptrs[i].valid) - dptr_close(i); + 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 */ - dirptrs[i].ptr = conn->dirptr; - string_set(&dirptrs[i].path,path); - dirptrs[i].lastused = dircounter++; - dirptrs[i].finished = False; - dirptrs[i].conn = conn; - dirptrs[i].pid = pid; - dirptrs[i].expect_close = expect_close; - dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */ - dirptrs[i].attr = 0; /* Only used in lanman2 searches */ - dirptrs[i].valid = True; + DLIST_ADD(dirptrs, dptr); DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", - i,path,expect_close)); + dptr->dnum,path,expect_close)); - return(i); + return(dptr->dnum); } #define DPTR_MASK ((uint32)(((uint32)1)<<31)) /**************************************************************************** -fill the 5 byte server reserved dptr field + Fill the 5 byte server reserved dptr field. ****************************************************************************/ + BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; - void *p = dptr_get(key,0); + void *p = dptr_ptr(key); uint32 offset; if (!p) { DEBUG(1,("filling null dirptr %d\n",key)); @@ -364,20 +518,22 @@ BOOL dptr_fill(char *buf1,unsigned int key) /**************************************************************************** -return True is the offset is at zero + Return True if the offset is at zero. ****************************************************************************/ + BOOL dptr_zero(char *buf) { return((IVAL(buf,1)&~DPTR_MASK) == 0); } /**************************************************************************** -fetch the dir ptr and seek it given the 5 byte server field + Fetch the dir ptr and seek it given the 5 byte server field. ****************************************************************************/ + void *dptr_fetch(char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_get(key,dircounter++); + void *p = dptr_ptr(key); uint32 offset; if (!p) { DEBUG(3,("fetched null dirptr %d\n",key)); @@ -392,11 +548,12 @@ void *dptr_fetch(char *buf,int *num) } /**************************************************************************** -fetch the dir ptr. + Fetch the dir ptr. ****************************************************************************/ + void *dptr_fetch_lanman2(int dptr_num) { - void *p = dptr_get(dptr_num,dircounter++); + void *p = dptr_ptr(dptr_num); if (!p) { DEBUG(3,("fetched null dirptr %d\n",dptr_num)); @@ -407,8 +564,9 @@ void *dptr_fetch_lanman2(int dptr_num) } /**************************************************************************** -check a filetype for being valid + Check a filetype for being valid. ****************************************************************************/ + BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype) { if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) @@ -417,8 +575,9 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di } /**************************************************************************** - get a directory entry + Get an 8.3 directory entry. ****************************************************************************/ + 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) { @@ -437,64 +596,71 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, 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); while (!found) - { - dname = ReadDirName(conn->dirptr); + { + BOOL filename_is_mask = False; + 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); - - if ((strcmp(filename,mask) == 0) || - (name_map_mangle(filename,True,SNUM(conn)) && - mask_match(filename,mask,False,False))) - { - if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) - continue; - - 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(dos_to_unix(pathreal, False), &sbuf) != 0) - { - DEBUG(5,("Couldn't stat 1 [%s]\n",path)); - continue; - } - - if (check_descend && - !strequal(fname,".") && !strequal(fname,"..")) - continue; + pstrcpy(filename,dname); + + if ((filename_is_mask = (strcmp(filename,mask) == 0)) || + (name_map_mangle(filename,True,False,SNUM(conn)) && + mask_match(filename,mask,False,False))) + { + if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) + continue; + + pstrcpy(fname,filename); + *path = 0; + pstrcpy(path,conn->dirpath); + if(needslash) + pstrcat(path,"/"); + pstrcpy(pathreal,path); + pstrcat(path,fname); + pstrcat(pathreal,dname); + if (dos_stat(pathreal,&sbuf) != 0) + { + DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); + continue; + } + + if (check_descend && !strequal(fname,".") && !strequal(fname,"..")) + 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; - } + if (!filename_is_mask) + { + /* Now we can allow the mangled cache to be updated */ + pstrcpy(filename,dname); + name_map_mangle(filename,True,True,SNUM(conn)); + } - *size = sbuf.st_size; - *date = sbuf.st_mtime; + *size = sbuf.st_size; + *date = sbuf.st_mtime; - DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname)); + DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname)); - found = True; - } + found = True; } + } return(found); } @@ -512,25 +678,26 @@ typedef struct /******************************************************************* -open a directory + Open a directory. ********************************************************************/ + void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = conn->vfs_ops.opendir(name); + DIR *p = dos_opendir(name); int used=0; if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { - conn->vfs_ops.closedir(p); + closedir(p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = vfs_readdirname(conn, p))) + while ((n = dos_readdirname(p))) { int l = strlen(n)+1; @@ -554,14 +721,15 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->numentries++; } - conn->vfs_ops.closedir(p); + closedir(p); return((void *)dirp); } /******************************************************************* -close a directory + Close a directory. ********************************************************************/ + void CloseDir(void *p) { Dir *dirp = (Dir *)p; @@ -571,8 +739,9 @@ void CloseDir(void *p) } /******************************************************************* -read from a directory + Read from a directory. ********************************************************************/ + char *ReadDirName(void *p) { char *ret; @@ -589,8 +758,9 @@ char *ReadDirName(void *p) /******************************************************************* -seek a dir + Seek a dir. ********************************************************************/ + BOOL SeekDir(void *p,int pos) { Dir *dirp = (Dir *)p; @@ -608,8 +778,9 @@ BOOL SeekDir(void *p,int pos) } /******************************************************************* -tell a dir position + Tell a dir position. ********************************************************************/ + int TellDir(void *p) { Dir *dirp = (Dir *)p; -- cgit From c4914e2202c17dd37b88c63446c14f7eb5f94d56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Jan 2000 19:59:42 +0000 Subject: client/client.c: I18N fixes. smbd/dir.c: Reformatting comments. smbd/ipc.c: New password change code for Win98. Jeremy. (This used to be commit 9e90122afd1b6a7cf38660fc3bc3aa8e526bf08b) --- source3/smbd/dir.c | 96 +++++++++++++++++++++--------------------------------- 1 file changed, 38 insertions(+), 58 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 28faa9a06b..cae6281e91 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -790,38 +790,32 @@ int TellDir(void *p) return(dirp->pos); } +/******************************************************************************* + This section manages a global directory cache. + (It should probably be split into a separate module. crh) +********************************************************************************/ -/* -------------------------------------------------------------------------- ** - * This section manages a global directory cache. - * (It should probably be split into a separate module. crh) - * -------------------------------------------------------------------------- ** - */ - -typedef struct - { +typedef struct { ubi_dlNode node; char *path; char *name; char *dname; int snum; - } dir_cache_entry; +} dir_cache_entry; static ubi_dlNewList( dir_cache ); +/***************************************************************************** + Add an entry to the directory cache. + Input: path - + name - + dname - + snum - + Output: None. +*****************************************************************************/ + void DirCacheAdd( char *path, char *name, char *dname, int snum ) - /* ------------------------------------------------------------------------ ** - * Add an entry to the directory cache. - * - * Input: path - - * name - - * dname - - * snum - - * - * Output: None. - * - * ------------------------------------------------------------------------ ** - */ - { +{ int pathlen; int namelen; dir_cache_entry *entry; @@ -852,27 +846,23 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum ) while( DIRCACHESIZE < dir_cache->count ) free( ubi_dlRemTail( dir_cache ) ); - } /* DirCacheAdd */ +} +/***************************************************************************** + Search for an entry to the directory cache. + Input: path - + name - + snum - + Output: The dname string of the located entry, or NULL if the entry was + not found. + + Notes: This uses a linear search, which is is okay because of + the small size of the cache. Use a splay tree or hash + for large caches. +*****************************************************************************/ char *DirCacheCheck( char *path, char *name, int snum ) - /* ------------------------------------------------------------------------ ** - * Search for an entry to the directory cache. - * - * Input: path - - * name - - * snum - - * - * Output: The dname string of the located entry, or NULL if the entry was - * not found. - * - * Notes: This uses a linear search, which is is okay because of - * the small size of the cache. Use a splay tree or hash - * for large caches. - * - * ------------------------------------------------------------------------ ** - */ - { +{ dir_cache_entry *entry; for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); @@ -889,18 +879,15 @@ char *DirCacheCheck( char *path, char *name, int snum ) } return(NULL); - } /* DirCacheCheck */ +} + +/***************************************************************************** + Remove all cache entries which have an snum that matches the input. + Input: snum - + Output: None. +*****************************************************************************/ void DirCacheFlush(int snum) - /* ------------------------------------------------------------------------ ** - * Remove all cache entries which have an snum that matches the input. - * - * Input: snum - - * - * Output: None. - * - * ------------------------------------------------------------------------ ** - */ { dir_cache_entry *entry; ubi_dlNodePtr next; @@ -912,11 +899,4 @@ void DirCacheFlush(int snum) free( ubi_dlRemThis( dir_cache, entry ) ); entry = (dir_cache_entry *)next; } -} /* DirCacheFlush */ - -/* -------------------------------------------------------------------------- ** - * End of the section that manages the global directory cache. - * -------------------------------------------------------------------------- ** - */ - - +} -- cgit From b5e7e4277d87c9eaa663f92c081a869b34170380 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Jan 2000 22:57:51 +0000 Subject: First set of speed improvements from Ying Chen . Inline several commonly used functions as macros. Jeremy. (This used to be commit fc0219c7cc4b83e6db17d5b3be70d74fd7971089) --- source3/smbd/dir.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index cae6281e91..f3f261f0b2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -493,8 +493,6 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect return(dptr->dnum); } -#define DPTR_MASK ((uint32)(((uint32)1)<<31)) - /**************************************************************************** Fill the 5 byte server reserved dptr field. ****************************************************************************/ @@ -516,16 +514,6 @@ BOOL dptr_fill(char *buf1,unsigned int key) return(True); } - -/**************************************************************************** - Return True if the offset is at zero. -****************************************************************************/ - -BOOL dptr_zero(char *buf) -{ - return((IVAL(buf,1)&~DPTR_MASK) == 0); -} - /**************************************************************************** Fetch the dir ptr and seek it given the 5 byte server field. ****************************************************************************/ -- cgit From 16bb009dbbe6302febf3848cee61e9927eeb0fb5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 05:17:25 +0000 Subject: Mega-VFS merge. Yeah baby! Synopsis: change every disk access function to work through a vfs_ops structure contained in the connection_struct. (This used to be commit 3aad500c0fb61232ed3431ff4b743b5d18ec852f) --- source3/smbd/dir.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f3f261f0b2..32fc523541 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -617,14 +617,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (dos_stat(pathreal,&sbuf) != 0) + if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; } - - if (check_descend && !strequal(fname,".") && !strequal(fname,"..")) - continue; *mode = dos_mode(conn,pathreal,&sbuf); @@ -673,19 +670,19 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = dos_opendir(name); + DIR *p = conn->vfs_ops.opendir(name); int used=0; if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { - closedir(p); + conn->vfs_ops.closedir(p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = dos_readdirname(p))) + while ((n = vfs_readdirname(conn, p))) { int l = strlen(n)+1; @@ -709,7 +706,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->numentries++; } - closedir(p); + conn->vfs_ops.closedir(p); return((void *)dirp); } -- cgit From ae7696117e81bb469fa71f9bc880f6b5aac0724e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Feb 2000 23:08:24 +0000 Subject: Put back lots of missing calls to dos_to_unix(). Thanks to aono@cc.osaka-kyoiku.ac.jp (Tomoki AONO) (This used to be commit 176c405d2702a4245561ff56c8eac3c754a0dea3) --- source3/smbd/dir.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 32fc523541..58b0061e19 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -670,7 +670,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = conn->vfs_ops.opendir(name); + DIR *p = conn->vfs_ops.opendir(dos_to_unix(name,False)); int used=0; if (!p) return(NULL); @@ -684,10 +684,14 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) while ((n = vfs_readdirname(conn, p))) { - int l = strlen(n)+1; + int l; + pstring zn; + + pstrcpy(zn, unix_to_dos(n,True)); + l = strlen(zn)+1; /* If it's a vetoed file, pretend it doesn't even exist */ - if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; + if (use_veto && conn && IS_VETO_PATH(conn, zn)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); @@ -701,7 +705,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->mallocsize = s; dirp->current = dirp->data; } - pstrcpy(dirp->data+used,n); + pstrcpy(dirp->data+used,zn); used += l; dirp->numentries++; } -- cgit From 84b16407bf8bdf2f318eba75a483c5b2a367d6ae Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 Mar 2000 07:44:23 +0000 Subject: More Japanese filename fixes wrt VFS code from Tomoki AONO (This used to be commit a9b628ebaa90e464366d0284226753f31439af9f) --- source3/smbd/dir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 58b0061e19..55d5bf132c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -685,13 +685,14 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) while ((n = vfs_readdirname(conn, p))) { int l; - pstring zn; - - pstrcpy(zn, unix_to_dos(n,True)); - l = strlen(zn)+1; + + 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 (use_veto && conn && IS_VETO_PATH(conn, zn)) continue; + if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); @@ -705,7 +706,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->mallocsize = s; dirp->current = dirp->data; } - pstrcpy(dirp->data+used,zn); + pstrcpy(dirp->data+used,n); used += l; dirp->numentries++; } -- cgit From 700f72453ed8dfd356a5591b9447127b5066ac4b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 11:04:28 +0000 Subject: - removed all our old wildcard matching code and replaced it with a call to ms_fnmatch(). This also removes all the Win9X semantics stuff and a bunch of other associated cruft. - moved the stat cache code into statcache.c - fixed the uint16 alignment requirements of ascii_to_unistr() and unistr_to_ascii() - trans2 SMB_FIND_FILE_BOTH_DIRECTORY_INFO returns the short name as unicode always (at least thats what NT4 does) - fixed some errors in the in-memory tdb code. Still ugly, but doesn't crash as much (This used to be commit 03e9cea004bbba72161a5323cf3b4556c94aed8e) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 55d5bf132c..bd4e2a44f9 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -604,7 +604,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, if ((filename_is_mask = (strcmp(filename,mask) == 0)) || (name_map_mangle(filename,True,False,SNUM(conn)) && - mask_match(filename,mask,False,False))) + mask_match(filename,mask,False))) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; -- cgit From 34cd425c1ded2afe5adc4d898843c31f66f26b5a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 14:29:45 +0000 Subject: fixed our smbsearch code. We now store the mask with the dptr, this turns out to be essential for a correct implementation (there ins't enough room to store all possible masks in the status return structure!) (This used to be commit 38f5e133670ada6e5799a16cf1a0e2e3ee1d9afd) --- source3/smbd/dir.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index bd4e2a44f9..ee383ea72a 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -591,7 +591,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, while (!found) { - BOOL filename_is_mask = False; dname = ReadDirName(conn->dirptr); DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n", @@ -602,13 +601,22 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, pstrcpy(filename,dname); - if ((filename_is_mask = (strcmp(filename,mask) == 0)) || + /* 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) || (name_map_mangle(filename,True,False,SNUM(conn)) && mask_match(filename,mask,False))) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; + if (!is_8_3(filename, False)) { + name_map_mangle(filename,True,False,SNUM(conn)); + } + pstrcpy(fname,filename); *path = 0; pstrcpy(path,conn->dirpath); @@ -631,17 +639,10 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, continue; } - if (!filename_is_mask) - { - /* Now we can allow the mangled cache to be updated */ - pstrcpy(filename,dname); - name_map_mangle(filename,True,True,SNUM(conn)); - } - *size = sbuf.st_size; *date = sbuf.st_mtime; - DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname)); + DEBUG(0,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); found = True; } -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/dir.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ee383ea72a..aaab206a26 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1,3 +1,5 @@ +#define OLD_NTDOMAIN 1 + /* Unix SMB/Netbios implementation. Version 1.9. @@ -891,3 +893,5 @@ void DirCacheFlush(int snum) entry = (dir_cache_entry *)next; } } + +#undef OLD_NTDOMAIN -- cgit From 636f146abf0a75cd3b21a57b50627ee149a635ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 03:21:49 +0000 Subject: Restructuring of vfs layer to include a "this" pointer - can be an fsp or a conn struct depending on the call. We need this to have a clean NT ACL call interface. This will break any existing VFS libraries (that's why this is pre-release code). Andrew gets credit for this one :-) :-). In addition - added Herb's WITH_PROFILE changes - Herb - please examine the changes I've made to the smbd/reply.c code you added. The original code was very ugly and I have replaced it with a START_PROFILE(x)/END_PROFILE(x) pair using the preprocessor. Please check this compiles ok with the --with-profile switch. Jeremy. (This used to be commit b07611f8159b0b3f42e7e02611be9f4d56de96f5) --- source3/smbd/dir.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index aaab206a26..bf15be2f1c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -627,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(dos_to_unix(pathreal, False), &sbuf) != 0) + if (conn->vfs_ops.stat(conn,dos_to_unix(pathreal, False), &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; @@ -673,13 +673,13 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = conn->vfs_ops.opendir(dos_to_unix(name,False)); + DIR *p = conn->vfs_ops.opendir(conn,dos_to_unix(name,False)); int used=0; if (!p) return(NULL); dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { - conn->vfs_ops.closedir(p); + conn->vfs_ops.closedir(conn,p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; @@ -714,7 +714,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->numentries++; } - conn->vfs_ops.closedir(p); + conn->vfs_ops.closedir(conn,p); return((void *)dirp); } -- cgit From 66f6ad97297fe09b3cbd91aab6099fd3c98b078b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Jan 2001 17:08:44 +0000 Subject: Turned down noisy debug statement. From "Richard Bollinger" (This used to be commit 1ec44d62eed67d88f59417d20680a073918626bd) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index bf15be2f1c..b9b3b88269 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -644,7 +644,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, *size = sbuf.st_size; *date = sbuf.st_mtime; - DEBUG(0,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); + DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); found = True; } -- cgit From 01634eaf129e90877c054664703d100be9f41ce0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Feb 2001 20:47:09 +0000 Subject: merge from SAMBA_2_2 (This used to be commit 9347121ce6888afeae3cdf256b5f0c5b9c58b0bc) --- source3/smbd/dir.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b9b3b88269..6a8cde1883 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -590,6 +590,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, if (!conn->dirptr) return(False); + + if (strequal(mask, "????????.???")) + pstrcpy(mask, "*"); + + while (!found) { -- cgit From 53a2d8ce88d152b7d5571bbb74f8dbb171cfec1f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 23 Feb 2001 16:06:18 +0000 Subject: removed wrong patch to get_dir_entry(). This was left over from the wildcard stuff.... (This used to be commit f77fa6a0e510fe5ad54d20eaabd345e6ee0526dc) --- source3/smbd/dir.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 6a8cde1883..a7e05c5682 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -591,11 +591,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, if (!conn->dirptr) return(False); - if (strequal(mask, "????????.???")) - pstrcpy(mask, "*"); - - - while (!found) { dname = ReadDirName(conn->dirptr); -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/dir.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index a7e05c5682..5bf0dec944 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1,5 +1,3 @@ -#define OLD_NTDOMAIN 1 - /* Unix SMB/Netbios implementation. Version 1.9. @@ -893,5 +891,3 @@ void DirCacheFlush(int snum) entry = (dir_cache_entry *)next; } } - -#undef OLD_NTDOMAIN -- cgit From 4355098a757885462dd44b94b616014c30eea2bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 Apr 2001 15:16:31 +0000 Subject: hide unreadable patch from idra (This used to be commit 7b6cfe243002a92f5dfb52413e9b3550c61cecfb) --- source3/smbd/dir.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5bf0dec944..46078b8d06 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -663,6 +663,36 @@ typedef struct } 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, const char *name) +{ + struct stat ste; + + /* if we can't stat it does not show it */ + if (stat(name, &ste) != 0) return False; + + if (ste.st_uid == conn->uid) { + return (ste.st_mode & S_IRUSR) == S_IRUSR; + } else { + int i; + if (ste.st_gid == conn->gid) { + return (ste.st_mode & S_IRGRP) == S_IRGRP; + } + for (i=0; ingroups; i++) { + if (conn->groups[i] == ste.st_gid) { + return (ste.st_mode & S_IRGRP) == S_IRGRP; + } + } + } + + return (ste.st_mode & S_IROTH) == S_IROTH; +} + /******************************************************************* Open a directory. ********************************************************************/ @@ -677,6 +707,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) 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); } @@ -695,6 +726,24 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) /* 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; + + entry = (char *)malloc(PATH_MAX); + if (!entry) { + DEBUG(0,("Out of memory in OpenDir\n")); + conn->vfs_ops.closedir(conn,p); + return(NULL); + } + slprintf(entry, PATH_MAX, "%s/%s/%s", conn->origpath, name, n); + ret = user_can_read_file(conn, entry); + free(entry); + if (!ret) continue; + } + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; -- cgit From a5bd9ef712786a51089f15e034a32111bc416344 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2001 02:27:23 +0000 Subject: Rememver to use VFS at all times... even in new user_can_read_file code :-). Jeremy. (This used to be commit 0d10113d01d6d15f470359259a76e4f107a06c73) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 46078b8d06..1d497574a6 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -669,12 +669,12 @@ 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, const char *name) +static BOOL user_can_read_file(connection_struct *conn, char *name) { - struct stat ste; + SMB_STRUCT_STAT ste; /* if we can't stat it does not show it */ - if (stat(name, &ste) != 0) return False; + if (vfs_stat(conn, name, &ste) != 0) return False; if (ste.st_uid == conn->uid) { return (ste.st_mode & S_IRUSR) == S_IRUSR; -- cgit From 944aeb7de472e0654561f7d8f37a5703487a973e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 28 Apr 2001 12:43:15 +0000 Subject: use asprintf for hideunreadable option (This used to be commit 338d5ca8addb3079e0ab4a68338596d6e3b17ddb) --- source3/smbd/dir.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1d497574a6..fa9cbdc4a2 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -727,21 +727,15 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) if (use_veto && conn && IS_VETO_PATH(conn, n)) continue; /* Honour _hide unreadable_ option */ - if (conn && lp_hideunreadable(SNUM(conn))) - { - char *entry; - int ret; + if (conn && lp_hideunreadable(SNUM(conn))) { + char *entry; + int ret=0; - entry = (char *)malloc(PATH_MAX); - if (!entry) { - DEBUG(0,("Out of memory in OpenDir\n")); - conn->vfs_ops.closedir(conn,p); - return(NULL); - } - slprintf(entry, PATH_MAX, "%s/%s/%s", conn->origpath, name, n); - ret = user_can_read_file(conn, entry); - free(entry); - if (!ret) continue; + if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_read_file(conn, entry); + free(entry); + } + if (!ret) continue; } if (used + l > dirp->mallocsize) { -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/smbd/dir.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index fa9cbdc4a2..9a9c745944 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -625,7 +625,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,dos_to_unix(pathreal, False), &sbuf) != 0) + if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; @@ -701,7 +701,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) { Dir *dirp; char *n; - DIR *p = conn->vfs_ops.opendir(conn,dos_to_unix(name,False)); + DIR *p = conn->vfs_ops.opendir(conn,name); int used=0; if (!p) return(NULL); @@ -720,9 +720,6 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) 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 (use_veto && conn && IS_VETO_PATH(conn, n)) continue; -- cgit From 61b2794968faa35dc91edce17e9b91e5366c3514 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 11:25:41 +0000 Subject: move to SAFE_FREE() (This used to be commit a95943fde0ad89ae3f2deca2f7ba9cb5ab612b74) --- source3/smbd/dir.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 9a9c745944..c0c728fe8f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -246,10 +246,9 @@ static void dptr_close_internal(dptr_struct *dptr) } /* Lanman 2 specific code */ - if (dptr->wcard) - free(dptr->wcard); + SAFE_FREE(dptr->wcard); string_set(&dptr->path,""); - free((char *)dptr); + SAFE_FREE(dptr); } /**************************************************************************** @@ -438,7 +437,7 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect if(dptr->dnum == -1 || dptr->dnum > 254) { DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); - free((char *)dptr); + SAFE_FREE(dptr); return -1; } } @@ -467,7 +466,7 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect if(dptr->dnum == -1 || dptr->dnum < 255) { DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum)); - free((char *)dptr); + SAFE_FREE(dptr); return -1; } } @@ -730,7 +729,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { ret = user_can_read_file(conn, entry); - free(entry); + SAFE_FREE(entry); } if (!ret) continue; } @@ -763,10 +762,9 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) void CloseDir(void *p) { - Dir *dirp = (Dir *)p; - if (!dirp) return; - if (dirp->data) free(dirp->data); - free(dirp); + if (!p) return; + SAFE_FREE(((Dir *)p)->data); + SAFE_FREE(p); } /******************************************************************* @@ -875,7 +873,7 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum ) /* Free excess cache entries. */ while( DIRCACHESIZE < dir_cache->count ) - free( ubi_dlRemTail( dir_cache ) ); + safe_free( ubi_dlRemTail( dir_cache ) ); } @@ -927,7 +925,7 @@ void DirCacheFlush(int snum) NULL != entry; ) { next = ubi_dlNext( entry ); if( entry->snum == snum ) - free( ubi_dlRemThis( dir_cache, entry ) ); + safe_free( ubi_dlRemThis( dir_cache, entry ) ); entry = (dir_cache_entry *)next; } } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/dir.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index c0c728fe8f..59c8f1e97b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -21,8 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /* This module implements directory related functions for Samba. */ -- cgit From d876260d885ad991526544756609ea38e4867028 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 5 Nov 2001 00:02:38 +0000 Subject: Don't put a \n on the end of the arg to exit_server() (This used to be commit dfb8566220c3e90ca2b757ea124f53aed103269e) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 59c8f1e97b..1e2858ae26 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -58,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\n"); + exit_server("out of memory in init_dptrs"); dptrs_init = True; } -- cgit From 02c3dcd8ee6f4007ea6db9fbcd75b16129a657eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Dec 2001 19:16:22 +0000 Subject: Made "hide unreadable" work much more reliably (just for Volker :-). Jeremy. (This used to be commit f6d6825bc86662d54ff3920d7d5390d151f34b0f) --- source3/smbd/dir.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1e2858ae26..faf5bca52d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -666,12 +666,47 @@ 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) { + extern struct current_user current_user; SMB_STRUCT_STAT ste; + SEC_DESC *psd = NULL; + size_t sd_size; + files_struct *fsp; + int smb_action; + NTSTATUS status; + uint32 access_granted; + + ZERO_STRUCT(ste); /* if we can't stat it does not show it */ - if (vfs_stat(conn, name, &ste) != 0) return False; + if (vfs_stat(conn, name, &ste) != 0) + return False; + + /* Pseudo-open the file (note - no fd's created). */ + + if(S_ISDIR(ste.st_mode)) + fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), FILE_OPEN, + unix_mode(conn,aRONLY|aDIR, name), &smb_action); + else + fsp = open_file_stat(conn,name,&ste,DOS_OPEN_RDONLY,&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, True); + + /* 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); + +#if 0 + /* Old - crappy check :-). JRA */ if (ste.st_uid == conn->uid) { return (ste.st_mode & S_IRUSR) == S_IRUSR; @@ -688,6 +723,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) } return (ste.st_mode & S_IROTH) == S_IROTH; +#endif } /******************************************************************* -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index faf5bca52d..2b2683caa5 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Directory handling routines Copyright (C) Andrew Tridgell 1992-1998 -- cgit From b9e91d2a8e41a43d7ebb7d7eed807a7d8de9b329 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 00:46:53 +0000 Subject: Remove the "stat open" code - make it inline. This should fix the bugs with opening and renaming mp3 files, also the word rename problems that people have had for a while. Needs a make clean :-) make. Also added JohnR's printing fix. Jeremy. (This used to be commit 504e5ef0494c54efbd0357e334cb2aa5a9eb9c14) --- source3/smbd/dir.c | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2b2683caa5..3a7b697d75 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -674,6 +674,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) size_t sd_size; files_struct *fsp; int smb_action; + int access_mode; NTSTATUS status; uint32 access_granted; @@ -686,10 +687,12 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(ste.st_mode)) - fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), FILE_OPEN, + fsp = open_directory(conn, name, &ste, 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_stat(conn,name,&ste,DOS_OPEN_RDONLY,&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; @@ -703,26 +706,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA, &access_granted, &status); - -#if 0 - /* Old - crappy check :-). JRA */ - - if (ste.st_uid == conn->uid) { - return (ste.st_mode & S_IRUSR) == S_IRUSR; - } else { - int i; - if (ste.st_gid == conn->gid) { - return (ste.st_mode & S_IRGRP) == S_IRGRP; - } - for (i=0; ingroups; i++) { - if (conn->groups[i] == ste.st_gid) { - return (ste.st_mode & S_IRGRP) == S_IRGRP; - } - } - } - - return (ste.st_mode & S_IROTH) == S_IROTH; -#endif } /******************************************************************* -- cgit From 1783dcd2f189d64514733e759bdecc68e86a95ea Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 21 Mar 2002 14:00:13 +0000 Subject: return . and .. first in readdir - this fixes masktest on IRIX which returns . then single letter files then .. then all other files. (This used to be commit d4d9361eec11f50c780ed4c79bc9775ac24d8c0e) --- source3/smbd/dir.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 3a7b697d75..40b198ed72 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -729,10 +729,22 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) dirp->pos = dirp->numentries = dirp->mallocsize = 0; dirp->data = dirp->current = NULL; - while ((n = vfs_readdirname(conn, p))) + 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 */ -- cgit From c90cd26e9430b2fc065f620bdb6aaf4be0372fcc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Mar 2002 02:57:44 +0000 Subject: Fix the mp3 rename bug - also tidy up our open code and remove the special cases for rename and unlink. Had to add desired_access into the share mode record. Jeremy. (This used to be commit 3b1b8ac43535fb0839c5474fa55bf7150f6cde31) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 40b198ed72..0bf234dd3e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -687,7 +687,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(ste.st_mode)) - fsp = open_directory(conn, name, &ste, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), + 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, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), @@ -698,7 +698,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) /* 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, True); + close_file(fsp, False); /* No access if SD get failed. */ if (!sd_size) -- cgit From 9cd0306baa1b3a78b40ab97b5d199b90a4c34aa6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Apr 2002 02:20:56 +0000 Subject: This split the mangling code up to allow for the possibility of multiple mangling implementation, selectable using "mangling method = " in smb.conf It also tidies the interface a little, although it is still nasty. (This used to be commit be23d87a178e7d0691e7d942adf89bb3d2d533c2) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 0bf234dd3e..f56e0e9ef0 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -603,14 +603,14 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, */ if ((strcmp(mask,"*.*") == 0) || mask_match(filename,mask,False) || - (name_map_mangle(filename,True,False,SNUM(conn)) && + (mangle_map(filename,True,False,SNUM(conn)) && mask_match(filename,mask,False))) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; - if (!is_8_3(filename, False)) { - name_map_mangle(filename,True,False,SNUM(conn)); + if (!mangle_is_8_3(filename, False)) { + mangle_map(filename,True,False,SNUM(conn)); } pstrcpy(fname,filename); -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/dir.c | 156 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 88 insertions(+), 68 deletions(-) (limited to 'source3/smbd/dir.c') 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); } -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/dir.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7dd425ef8a..1a18476b75 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -721,6 +721,62 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) &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 +********************************************************************/ + +static BOOL user_can_write_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; + int smb_action; + int access_mode; + NTSTATUS status; + uint32 access_granted; + + ZERO_STRUCT(ste); + + /* + * 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; + + /* Pseudo-open the file (note - no fd's created). */ + + if(S_ISDIR(ste.st_mode)) + return True; + else + fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_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_WRITE_DATA, + &access_granted, &status); +} + /******************************************************************* Open a directory. ********************************************************************/ @@ -781,6 +837,19 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) continue; } + /* Honour _hide unwriteable_ option */ + if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) { + char *entry; + int ret=0; + + if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_write_file(conn, entry); + SAFE_FREE(entry); + } + if (!ret) + continue; + } + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/dir.c | 121 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 85 insertions(+), 36 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1a18476b75..396ecd98c4 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -553,9 +553,24 @@ void *dptr_fetch_lanman2(int dptr_num) BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype) { - if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) - return False; - return True; + 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; } static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mask) @@ -663,18 +678,15 @@ 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 + 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) +static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { extern struct current_user current_user; - SMB_STRUCT_STAT ste; SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; @@ -683,8 +695,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) NTSTATUS status; uint32 access_granted; - ZERO_STRUCT(ste); - /* * If user is a member of the Admin group * we never hide files from them. @@ -694,16 +704,16 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) return True; /* If we can't stat it does not show it */ - if (vfs_stat(conn, name, &ste) != 0) + if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ - 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), + 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, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), + 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) @@ -722,16 +732,15 @@ static BOOL user_can_read_file(connection_struct *conn, char *name) } /******************************************************************* -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 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. ********************************************************************/ -static BOOL user_can_write_file(connection_struct *conn, char *name) +static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { extern struct current_user current_user; - SMB_STRUCT_STAT ste; SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; @@ -740,8 +749,6 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) NTSTATUS status; uint32 access_granted; - ZERO_STRUCT(ste); - /* * If user is a member of the Admin group * we never hide files from them. @@ -751,15 +758,15 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) return True; /* If we can't stat it does not show it */ - if (vfs_stat(conn, name, &ste) != 0) + if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ - if(S_ISDIR(ste.st_mode)) + if(S_ISDIR(pst->st_mode)) return True; else - fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), + 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); if (!fsp) @@ -777,6 +784,30 @@ static BOOL user_can_write_file(connection_struct *conn, char *name) &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. ********************************************************************/ @@ -802,6 +833,8 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) while (True) { int l; BOOL normal_entry = True; + SMB_STRUCT_STAT st; + char *entry = NULL; if (used == 0) { n = "."; @@ -818,6 +851,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) normal_entry = True; } + ZERO_STRUCT(st); l = strlen(n)+1; /* If it's a vetoed file, pretend it doesn't even exist */ @@ -826,30 +860,45 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) /* 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 (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_read_file(conn, entry, &st); } - if (!ret) + if (!ret) { + SAFE_FREE(entry); continue; + } } /* Honour _hide unwriteable_ option */ if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) { - char *entry; int ret=0; - if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { - ret = user_can_write_file(conn, entry); + if (entry || asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) { + ret = user_can_write_file(conn, entry, &st); + } + if (!ret) { 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) + if (ret) { + SAFE_FREE(entry); continue; + } } + SAFE_FREE(entry); + if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/smbd/dir.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 396ecd98c4..d3c71ad24e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -327,15 +327,20 @@ void dptr_closepath(char *path,uint16 spid) Start a directory listing. ****************************************************************************/ -static BOOL start_dir(connection_struct *conn,char *directory) +static BOOL start_dir(connection_struct *conn, pstring directory) { + const char *dir2; + DEBUG(5,("start_dir dir=%s\n",directory)); if (!check_name(directory,conn)) return(False); + + /* use a const pointer from here on */ + dir2 = directory; - if (! *directory) - directory = "."; + if (! *dir2) + dir2 = "."; conn->dirptr = OpenDir(conn, directory, True); if (conn->dirptr) { @@ -392,7 +397,7 @@ static void dptr_close_oldest(BOOL old) me at Andrew's knee.... :-) :-). JRA. ****************************************************************************/ -int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid) +int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid) { dptr_struct *dptr; @@ -812,10 +817,10 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT Open a directory. ********************************************************************/ -void *OpenDir(connection_struct *conn, char *name, BOOL use_veto) +void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { Dir *dirp; - char *n; + const char *n; DIR *p = conn->vfs_ops.opendir(conn,name); int used=0; @@ -1009,7 +1014,7 @@ static ubi_dlNewList( dir_cache ); Output: None. *****************************************************************************/ -void DirCacheAdd( char *path, char *name, char *dname, int snum ) +void DirCacheAdd( const char *path, char *name, char *dname, int snum ) { int pathlen; int namelen; @@ -1056,7 +1061,7 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum ) for large caches. *****************************************************************************/ -char *DirCacheCheck( char *path, char *name, int snum ) +char *DirCacheCheck( const char *path, const char *name, int snum ) { dir_cache_entry *entry; -- cgit From 20f1cf6cdcf9fc74d18fb9401e627a3455183ef3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Jan 2003 18:50:13 +0000 Subject: Fix problem with "hide unreadable". stat file opens are baaack :-). Jeremy. (This used to be commit 62038a0abf193d4dc4f37c31ac77216a10f6f326) --- source3/smbd/dir.c | 857 ++++++++++++++++++++++++++--------------------------- 1 file changed, 425 insertions(+), 432 deletions(-) (limited to 'source3/smbd/dir.c') 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); } /***************************************************************************** -- cgit From 55b8c949aa4220c266b55a9fa07797d0abf917e7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 14 Jan 2003 23:52:42 +0000 Subject: removing unused variable and unused file (This used to be commit c8266011b7afc2d6bcb8638c2a5ed3f9116cd88a) --- source3/smbd/dir.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 4aa132d110..9e8de2979b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -688,7 +688,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S size_t sd_size; files_struct *fsp; int smb_action; - int access_mode; NTSTATUS status; uint32 access_granted; -- cgit From 8a20407442efa0f9fe43e1b1c61140a0771c6ff8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Feb 2003 11:47:21 +0000 Subject: Cleanups: (merge from HEAD) - use safe_strcpy() instead of pstrcpy() for malloc()ed strings - CUPS: a failure in an attempt to automaticly add a printer is not level 0 stuff. - Fix up a possible Realloc() failure segfault Andrew Bartlett (This used to be commit c1cfc296c2efdb2b5972202146e80f0e3b6a3da4) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 9e8de2979b..e022d26ea3 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -907,7 +907,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->current = dirp->data; } - pstrcpy(dirp->data+used,n); + safe_strcpy(dirp->data+used,n, dirp->mallocsize - used - 1); used += l; dirp->numentries++; } -- cgit From 1738f7c2b7b0d2bdfa6414267d20b2c08e204f78 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Feb 2003 21:37:30 +0000 Subject: don't pass NULL pointers to strcmp() (This used to be commit 9b0a49a0bc177f9637f197b3ab4613f25db1b43d) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index e022d26ea3..2a5f7ffd71 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1063,8 +1063,8 @@ char *DirCacheCheck( const char *path, const char *name, int snum ) NULL != entry; entry = (dir_cache_entry *)ubi_dlNext( entry ) ) { if( entry->snum == snum - && 0 == strcmp( name, entry->name ) - && 0 == strcmp( path, entry->path ) ) { + && entry->name && 0 == strcmp( name, entry->name ) + && entry->path && 0 == strcmp( path, entry->path ) ) { DEBUG(4, ("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname)); return( entry->dname ); } -- cgit From e4c8e7ad8a154d9806a7b1214adb9982dc28f4b1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Feb 2003 23:21:37 +0000 Subject: and the winner of "i should have just written it in assembly is..." don't use pstrcpy() when you are not dealing with pstrings. (This used to be commit e1b21381f3b5cf6f97c101642e9286df9987998e) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2a5f7ffd71..10241e88d9 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1028,9 +1028,9 @@ void DirCacheAdd( const char *path, char *name, char *dname, int snum ) 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->path = memcpy( (char *)&entry[1], path, strlen(path) ); + entry->name = memcpy( &(entry->path[pathlen]), name, strlen(name) ); + entry->dname = memcpy( &(entry->name[namelen]), dname, strlen(dname) ); entry->snum = snum; /* Add the new entry to the linked list. */ -- cgit From 19995a40c15b33fe82a3d2399de00f8972325d1e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Feb 2003 23:54:58 +0000 Subject: don't forget the NULL (This used to be commit 4aa611958ebedfafbb9bfc1070b7d632272e1aaf) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 10241e88d9..95acf4a262 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1028,9 +1028,9 @@ void DirCacheAdd( const char *path, char *name, char *dname, int snum ) return; /* so just return as if nothing happened. */ /* Set pointers correctly and load values. */ - entry->path = memcpy( (char *)&entry[1], path, strlen(path) ); - entry->name = memcpy( &(entry->path[pathlen]), name, strlen(name) ); - entry->dname = memcpy( &(entry->name[namelen]), dname, strlen(dname) ); + entry->path = memcpy( (char *)&entry[1], path, strlen(path)+1 ); + entry->name = memcpy( &(entry->path[pathlen]), name, strlen(name)+1 ); + entry->dname = memcpy( &(entry->name[namelen]), dname, strlen(dname)+1 ); entry->snum = snum; /* Add the new entry to the linked list. */ -- cgit From ad0d6509a761154c113e040a82ad78e72a3ccf30 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:56:13 +0000 Subject: Merge from HEAD: - Make ReadDirName return a const char*. - Consequential changes from that - mark our fstring/pstring assumptions in function prototypes Andrew Bartlett (This used to be commit 10b53d7c6fd77f23433dd2ef12bb14b227147a48) --- source3/smbd/dir.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 95acf4a262..3f29ac892c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -578,7 +578,7 @@ 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) +static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) { mangle_map(filename,True,False,SNUM(conn)); return mask_match(filename,mask,False); @@ -588,10 +588,10 @@ static BOOL mangle_mask_match(connection_struct *conn, char *filename, char *mas Get an 8.3 directory entry. ****************************************************************************/ -BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname, +BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname, SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend) { - char *dname; + const char *dname; BOOL found = False; SMB_STRUCT_STAT sbuf; pstring path; @@ -907,7 +907,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->current = dirp->data; } - safe_strcpy(dirp->data+used,n, dirp->mallocsize - used - 1); + safe_strcpy_base(dirp->data+used,n, dirp->data, dirp->mallocsize); used += l; dirp->numentries++; } @@ -933,7 +933,7 @@ void CloseDir(void *p) Read from a directory. ********************************************************************/ -char *ReadDirName(void *p) +const char *ReadDirName(void *p) { char *ret; Dir *dirp = (Dir *)p; @@ -1008,7 +1008,7 @@ static ubi_dlNewList( dir_cache ); Output: None. *****************************************************************************/ -void DirCacheAdd( const char *path, char *name, char *dname, int snum ) +void DirCacheAdd( const char *path, const char *name, const char *dname, int snum ) { int pathlen; int namelen; -- cgit From bdb7a74419356f4b6064d928636c8f295e8b7230 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Apr 2003 03:48:26 +0000 Subject: Whitespace syncup. (This used to be commit 8fe5bab565cdcf498e4d0f5cca31f799d249e3b3) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 3f29ac892c..6cf56fd373 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -627,8 +627,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname see masktest for a demo */ if ((strcmp(mask,"*.*") == 0) || - mask_match(filename,mask,False) || - mangle_mask_match(conn,filename,mask)) { + mask_match(filename,mask,False) || + mangle_mask_match(conn,filename,mask)) { if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; -- cgit From e7c8c15888454043c73967635deb4d3419a489e9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sun, 11 May 2003 23:34:18 +0000 Subject: Fix VFS layer: 1. Finally work with cascaded modules with private data storage per module 2. Convert VFS API to macro calls to simplify cascading 3. Add quota support to VFS layer (prepare to NT quota support) Patch by Stefan (metze) Metzemacher, with review of Jelmer and me Tested in past few weeks. Documentation to new VFS API for third-party developers to follow (This used to be commit 91984ef5caa2d13c5d52e1f535bd3bbbae1ec978) --- source3/smbd/dir.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 6cf56fd373..48ddf86837 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -643,7 +643,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (conn->vfs_ops.stat(conn, pathreal, &sbuf) != 0) { + if (VFS_STAT(conn, pathreal, &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; } @@ -700,7 +700,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -715,7 +715,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S 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); + sd_size = VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); close_file(fsp, True); /* No access if SD get failed. */ @@ -753,7 +753,7 @@ 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 (!VALID_STAT(*pst) && (VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -768,7 +768,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ 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); + sd_size = VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); close_file(fsp, False); /* No access if SD get failed. */ @@ -794,7 +794,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (vfs_stat(conn, name, pst) != 0)) + 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)) @@ -811,7 +811,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { Dir *dirp; const char *n; - DIR *p = conn->vfs_ops.opendir(conn,name); + DIR *p = VFS_OPENDIR(conn,name); int used=0; if (!p) @@ -819,7 +819,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { DEBUG(0,("Out of memory in OpenDir\n")); - conn->vfs_ops.closedir(conn,p); + VFS_CLOSEDIR(conn,p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; @@ -912,7 +912,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->numentries++; } - conn->vfs_ops.closedir(conn,p); + VFS_CLOSEDIR(conn,p); return((void *)dirp); } -- cgit From bc2a3748e9caa8f60f7c2387e7eecd7fb3fae899 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 14 May 2003 10:59:01 +0000 Subject: Prefix VFS API macros with SMB_ for consistency and to avoid problems with VFS_ macros at system side. We currently have one clash with AIX and its VFS_LOCK. Compiled and tested -- no new functionality or code, just plain rename of macros for yet-unreleased VFS API version. Needs to be done before a24 is out (This used to be commit c2689ed118b490e49497a76ed6a2251262018769) --- source3/smbd/dir.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 48ddf86837..910ab35de8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -643,7 +643,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (VFS_STAT(conn, pathreal, &sbuf) != 0) { + if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) { DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); continue; } @@ -700,7 +700,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -715,7 +715,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); close_file(fsp, True); /* No access if SD get failed. */ @@ -753,7 +753,7 @@ 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 (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return False; /* Pseudo-open the file (note - no fd's created). */ @@ -768,7 +768,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); close_file(fsp, False); /* No access if SD get failed. */ @@ -794,7 +794,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) return True; if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) @@ -811,7 +811,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { Dir *dirp; const char *n; - DIR *p = VFS_OPENDIR(conn,name); + DIR *p = SMB_VFS_OPENDIR(conn,name); int used=0; if (!p) @@ -819,7 +819,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp = (Dir *)malloc(sizeof(Dir)); if (!dirp) { DEBUG(0,("Out of memory in OpenDir\n")); - VFS_CLOSEDIR(conn,p); + SMB_VFS_CLOSEDIR(conn,p); return(NULL); } dirp->pos = dirp->numentries = dirp->mallocsize = 0; @@ -912,7 +912,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->numentries++; } - VFS_CLOSEDIR(conn,p); + SMB_VFS_CLOSEDIR(conn,p); return((void *)dirp); } -- cgit From 545e8d499947fec55832352d741e8a904122d564 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 May 2003 23:49:31 +0000 Subject: Change get_nt_acl() to include security_info wanted. Only return this. This gets us closer to W2k+ in what we return for file ACLs. Fix horribly broken make_sec_desc() that screwed up the size when given a SD with no owner or group (how did it get this bad... ?). Jeremy. (This used to be commit 183c9ed4052ab14e269ed1234ca557053f77e77a) --- source3/smbd/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 910ab35de8..94b605ee8f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -715,7 +715,8 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, True); /* No access if SD get failed. */ @@ -768,7 +769,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return False; /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, &psd); + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, False); /* No access if SD get failed. */ -- cgit From 033fc98a6e340c3a87c20cc117384caa4ed36a30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 23 Dec 2003 07:33:42 +0000 Subject: Fix for special files being hidden from admins by Dmitry Butskoj Jeremy. (This used to be commit bee4b3348e5052cc927c837c2a21b4c90db980fc) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 94b605ee8f..bbd79e1659 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -793,7 +793,7 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT */ if (conn->admin_user) - return True; + return False; /* If we can't stat it does not show it */ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) -- cgit From 722aa118c66b020c2b9f2b595e1af50429f13986 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Apr 2004 18:46:19 +0000 Subject: Added per-share parameter "store dos attributes". When set, will store dos attributes in an EA. Based on an original patch from tridge, but modified somewhat to cover all cases. Jeremy. (This used to be commit ed653cd468213e0be901bc654aa3748ce5837947) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index bbd79e1659..06ef23ab8c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -707,7 +707,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S 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); + &smb_action); else fsp = open_file_stat(conn, name, pst); @@ -763,7 +763,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return True; 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); + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action); if (!fsp) return False; -- cgit From 2fc57c9a2ce3a266534dd20e6fed4883e052c557 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Jun 2004 16:14:31 +0000 Subject: r1085: Now it's had some proper user testing, merge in the deferred open fix. I'm still doing more testing, but it fixes a behaviour that we've been wrong on ever since the start of Samba. Jeremy. (This used to be commit 894cc6d16296b934c112786eec896846156aee5d) --- source3/smbd/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 06ef23ab8c..b88f687766 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -763,7 +763,8 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ return True; else fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, 0, &access_mode, &smb_action); + (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, + &access_mode, &smb_action); if (!fsp) return False; -- cgit From db2ffe10f9283c86f95ae76d38c21916065a4b87 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Aug 2004 23:20:47 +0000 Subject: r2076: Removed old dir caching code - not being used now we have the statcache anyway. New dir caching will be done on nanosecond timestamps. Jeremy. (This used to be commit ba473a580245430009245a4c8b8dcaf9fc4b6406) --- source3/smbd/dir.c | 109 ----------------------------------------------------- 1 file changed, 109 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b88f687766..2bda42f76d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -986,112 +986,3 @@ int TellDir(void *p) return(dirp->pos); } - -/******************************************************************************* - This section manages a global directory cache. - (It should probably be split into a separate module. crh) -********************************************************************************/ - -typedef struct { - ubi_dlNode node; - char *path; - char *name; - char *dname; - int snum; -} dir_cache_entry; - -static ubi_dlNewList( dir_cache ); - -/***************************************************************************** - Add an entry to the directory cache. - Input: path - - name - - dname - - snum - - Output: None. -*****************************************************************************/ - -void DirCacheAdd( const char *path, const char *name, const 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 = memcpy( (char *)&entry[1], path, strlen(path)+1 ); - entry->name = memcpy( &(entry->path[pathlen]), name, strlen(name)+1 ); - entry->dname = memcpy( &(entry->name[namelen]), dname, strlen(dname)+1 ); - 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 ) ); -} - -/***************************************************************************** - Search for an entry to the directory cache. - Input: path - - name - - snum - - Output: The dname string of the located entry, or NULL if the entry was - not found. - - Notes: This uses a linear search, which is is okay because of - the small size of the cache. Use a splay tree or hash - for large caches. -*****************************************************************************/ - -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 - && entry->name && 0 == strcmp( name, entry->name ) - && entry->path && 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); -} - -/***************************************************************************** - Remove all cache entries which have an snum that matches the input. - Input: snum - - Output: None. -*****************************************************************************/ - -void DirCacheFlush(int snum) -{ - dir_cache_entry *entry; - ubi_dlNodePtr next; - - for(entry = (dir_cache_entry *)ubi_dlFirst( dir_cache ); - NULL != entry; ) { - next = ubi_dlNext( entry ); - if( entry->snum == snum ) - safe_free( ubi_dlRemThis( dir_cache, entry ) ); - entry = (dir_cache_entry *)next; - } -} -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2bda42f76d..f721bf3ba8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -407,7 +407,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); - dptr = (dptr_struct *)malloc(sizeof(dptr_struct)); + dptr = SMB_MALLOC_P(dptr_struct); if(!dptr) { DEBUG(0,("malloc fail in dptr_create.\n")); return -1; @@ -819,7 +819,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) if (!p) return(NULL); - dirp = (Dir *)malloc(sizeof(Dir)); + dirp = SMB_MALLOC_P(Dir); if (!dirp) { DEBUG(0,("Out of memory in OpenDir\n")); SMB_VFS_CLOSEDIR(conn,p); @@ -900,7 +900,7 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) if (used + l > dirp->mallocsize) { int s = MAX(used+l,used+2000); char *r; - r = (char *)Realloc(dirp->data,s); + r = (char *)SMB_REALLOC(dirp->data,s); if (!r) { DEBUG(0,("Out of memory in OpenDir\n")); break; -- cgit From de728fa81ae549b496f2ff26ebb082092aae2204 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jan 2005 21:01:58 +0000 Subject: r5063: Shamelessly steal the Samba4 logic (and some code :-) for directory evaluation. This stops us from reading the entire directory into memory at one go, and allows partial reads. It also keeps almost the same interface to the OpenDir/ReadDir etc. code (sorry James :-). Next I will optimise the findfirst with exact match code. This speeds up our interactive response for large directories, but not when a missing (ie. negative) findfirst is done. Jeremy (This used to be commit 0af1d2f6f24f238cb05e10d7d53dcd5b5e0f5f5d) --- source3/smbd/dir.c | 350 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 215 insertions(+), 135 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f721bf3ba8..ff240b7e5a 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -612,9 +612,10 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname return(False); while (!found) { - dname = ReadDirName(conn->dirptr); + long curoff = TellDir(conn->dirptr); + dname = ReadDirName(conn->dirptr, &curoff); - DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n", + DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", (long)conn->dirptr,TellDir(conn->dirptr))); if (dname == NULL) @@ -667,14 +668,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname return(found); } -typedef struct { - int pos; - int numentries; - int mallocsize; - char *data; - 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 @@ -806,117 +799,74 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; } +#define NAME_CACHE_SIZE 100 + +struct name_cache_entry { + char *name; + long offset; +}; + +typedef struct { + connection_struct *conn; + DIR *dir; + long offset; + char *dir_path; + struct name_cache_entry *name_cache; + unsigned int name_cache_index; + BOOL hide_unreadable; + BOOL hide_unwriteable; + BOOL hide_special; + BOOL use_veto; + BOOL finished; +} Dir; + /******************************************************************* Open a directory. ********************************************************************/ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { - Dir *dirp; - const char *n; - DIR *p = SMB_VFS_OPENDIR(conn,name); - int used=0; - - if (!p) - return(NULL); - dirp = SMB_MALLOC_P(Dir); + Dir *dirp = SMB_MALLOC_P(Dir); if (!dirp) { - DEBUG(0,("Out of memory in OpenDir\n")); - SMB_VFS_CLOSEDIR(conn,p); - return(NULL); + 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 = "."; - 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; - } + ZERO_STRUCTP(dirp); - ZERO_STRUCT(st); - l = strlen(n)+1; + dirp->conn = conn; + dirp->use_veto = use_veto; - /* If it's a vetoed file, pretend it doesn't even exist */ - if (normal_entry && use_veto && conn && IS_VETO_PATH(conn, n)) - continue; + dirp->dir_path = SMB_STRDUP(name); + if (!dirp->dir_path) { + goto fail; + } + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path); + if (!dirp->dir) { + DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); + goto fail; + } - /* Honour _hide unreadable_ option */ - if (normal_entry && conn && lp_hideunreadable(SNUM(conn))) { - 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; - } - } + dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, NAME_CACHE_SIZE); + if (!dirp->name_cache) { + goto fail; + } - /* 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) { - SAFE_FREE(entry); - continue; - } - } + dirp->hide_unreadable = lp_hideunreadable(SNUM(conn)); + dirp->hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); + dirp->hide_special = lp_hide_special_files(SNUM(conn)); - /* 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); - continue; - } - } + return((void *)dirp); - SAFE_FREE(entry); + fail: - if (used + l > dirp->mallocsize) { - int s = MAX(used+l,used+2000); - char *r; - r = (char *)SMB_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; + if (dirp) { + if (dirp->dir) { + SMB_VFS_CLOSEDIR(conn,dirp->dir); } - - safe_strcpy_base(dirp->data+used,n, dirp->data, dirp->mallocsize); - used += l; - dirp->numentries++; + SAFE_FREE(dirp->dir_path); + SAFE_FREE(dirp->name_cache); + SAFE_FREE(dirp); } - - SMB_VFS_CLOSEDIR(conn,p); - return((void *)dirp); + return NULL; } @@ -924,65 +874,195 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) Close a directory. ********************************************************************/ -void CloseDir(void *p) +int CloseDir(void *p) { - if (!p) - return; - SAFE_FREE(((Dir *)p)->data); - SAFE_FREE(p); + int i, ret = 0; + Dir *dirp = (Dir *)p; + + if (dirp->dir) { + ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); + } + SAFE_FREE(dirp->dir_path); + if (dirp->name_cache) { + for (i = 0; i < NAME_CACHE_SIZE; i++) { + SAFE_FREE(dirp->name_cache[i].name); + } + } + SAFE_FREE(dirp->name_cache); + SAFE_FREE(dirp); + return ret; } /******************************************************************* - Read from a directory. + Set a directory into an inactive state. ********************************************************************/ -const char *ReadDirName(void *p) +static void SleepDir(Dir *dirp) { - char *ret; - Dir *dirp = (Dir *)p; - - if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) - return(NULL); + if (dirp->dir) { + SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); + dirp->dir = 0; + } + dirp->offset = 0; +} - ret = dirp->current; - dirp->current = skip_string(dirp->current,1); - dirp->pos++; +/******************************************************************* + Wake a directory into a known state. +********************************************************************/ - return(ret); +static int WakeDir(Dir *dirp, long offset) +{ + if (!dirp->dir) { + dirp->dir = SMB_VFS_OPENDIR(dirp->conn, dirp->dir_path); + if (!dirp->dir) { + DEBUG(0,("WakeDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); + dirp->finished = True; + return -1; + } + } + if (offset != dirp->offset) { + SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); + dirp->offset = SMB_VFS_TELLDIR(dirp->conn, dirp->dir); + if (dirp->offset != offset) { + DEBUG(0,("WakeDir: in path %s. offset changed %ld -> %ld\n", + dirp->dir_path, offset, dirp->offset )); + return -1; + } + } + return 0; } /******************************************************************* - Seek a dir. + Read from a directory. Also return current offset. ********************************************************************/ -BOOL SeekDir(void *p,int pos) +const char *ReadDirName(void *p, long *poffset) { + const char *n; Dir *dirp = (Dir *)p; + connection_struct *conn = dirp->conn; - if (!dirp) - return(False); + if (WakeDir(dirp, *poffset) == -1) { + return NULL; + } + + while ((n = vfs_readdirname(conn, dirp->dir))) { + struct name_cache_entry *e; + + if (!((strcmp(".",n) == 0) || (strcmp("..",n) == 0))) { + /* If it's a vetoed file, pretend it doesn't even exist */ + if (dirp->use_veto && IS_VETO_PATH(conn, n)) { + continue; + } + + if (dirp->hide_unreadable || dirp->hide_unwriteable || dirp->hide_special) { + SMB_STRUCT_STAT st; + ZERO_STRUCT(st); + char *entry = NULL; + + if (asprintf(&entry, "%s/%s/%s", conn->origpath, dirp->dir_path, n) == -1) { + return NULL; + } + /* Honour _hide unreadable_ option */ + if (dirp->hide_unreadable && !user_can_read_file(conn, entry, &st)) { + SAFE_FREE(entry); + continue; + } + /* Honour _hide unwriteable_ option */ + if (dirp->hide_unwriteable && !user_can_write_file(conn, entry, &st)) { + SAFE_FREE(entry); + continue; + } + /* Honour _hide_special_ option */ + if (dirp->hide_special && !file_is_special(conn, entry, &st)) { + SAFE_FREE(entry); + continue; + } + SAFE_FREE(entry); + } + } + + dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); + if (dirp->offset == -1) { + return NULL; + } + dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; - if (pos < dirp->pos) { - dirp->current = dirp->data; - dirp->pos = 0; + e = &dirp->name_cache[dirp->name_cache_index]; + SAFE_FREE(e->name); + e->name = SMB_STRDUP(n); + *poffset = e->offset= dirp->offset; + return e->name; } - while (dirp->pos < pos && ReadDirName(p)) - ; + dirp->finished = True; + SleepDir(dirp); + return NULL; +} + +/******************************************************************* + Seek a dir. +********************************************************************/ - return (dirp->pos == pos); +BOOL SeekDir(void *p,long offset) +{ + Dir *dirp = (Dir *)p; + return (WakeDir(dirp, offset) != -1); } /******************************************************************* Tell a dir position. ********************************************************************/ -int TellDir(void *p) +long TellDir(void *p) { Dir *dirp = (Dir *)p; + return(dirp->offset); +} - if (!dirp) - return(-1); - - return(dirp->pos); +/******************************************************************* + Find an entry by name. Leave us at the offset after it. +********************************************************************/ + +BOOL SearchDir(void *p, const char *name, long *poffset, BOOL case_sensitive) +{ + int i; + Dir *dirp = (Dir *)p; + const char *entry; + connection_struct *conn = dirp->conn; + + /* Re-create dir but don't seek. */ + if (WakeDir(dirp, dirp->offset) == -1) { + return False; + } + + /* Search back in the name cache. */ + for (i = dirp->name_cache_index; i >= 0; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + WakeDir(dirp, e->offset); + return True; + } + } + for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + WakeDir(dirp, e->offset); + return True; + } + } + + /* Not found in the name cache. Rewind directory and start from scratch. */ + SMB_VFS_REWINDDIR(conn, dirp->dir); + *poffset = 0; + while ((entry = ReadDirName(dirp, poffset))) { + if (case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { + return True; + } + } + + SleepDir(dirp); + return False; } -- cgit From 0dc388a8370c5d7852f09327fa76fe16fd0a496c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Jan 2005 09:38:15 +0000 Subject: r5096: Attempt to fix the build (This used to be commit 5f34139b68460f6fb1046e2b97f16dbeff3fb136) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ff240b7e5a..4d41f88f35 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -957,8 +957,8 @@ const char *ReadDirName(void *p, long *poffset) if (dirp->hide_unreadable || dirp->hide_unwriteable || dirp->hide_special) { SMB_STRUCT_STAT st; - ZERO_STRUCT(st); char *entry = NULL; + ZERO_STRUCT(st); if (asprintf(&entry, "%s/%s/%s", conn->origpath, dirp->dir_path, n) == -1) { return NULL; -- cgit From 784adfbcbb7f3e85b81b3df5a5c8823663bac8d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Feb 2005 00:28:20 +0000 Subject: r5152: Restructure the directory handling code, stop using void * pointers that just allow the wrong pointer to be assigned :-) and make the interface more consistent. Fix the FreeBSD directory problem. Last thing to do is to add the "singleton" directory concept from James Peach's code. Jeremy. (This used to be commit cfa8150fd9932470cb8f3b5e14c0156dda67125d) --- source3/smbd/dir.c | 382 +++++++++++++++++++++++------------------------------ 1 file changed, 162 insertions(+), 220 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 4d41f88f35..7f1237cb29 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -24,21 +24,43 @@ This module implements directory related functions for Samba. */ -typedef struct _dptr_struct { - struct _dptr_struct *next, *prev; +/* Make directory handle internals available. */ + +#define NAME_CACHE_SIZE 100 + +struct name_cache_entry { + char *name; + long offset; +}; + +struct smb_Dir { + connection_struct *conn; + DIR *dir; + long offset; + char *dir_path; + struct name_cache_entry *name_cache; + unsigned int name_cache_index; + BOOL hide_unreadable; + BOOL hide_unwriteable; + BOOL hide_special; + BOOL use_veto; +}; + +struct dptr_struct { + struct dptr_struct *next, *prev; int dnum; uint16 spid; - connection_struct *conn; - void *ptr; + struct connection_struct *conn; + struct smb_Dir *dir_hnd; BOOL expect_close; - char *wcard; /* Field only used for trans2_ searches */ - uint16 attr; /* Field only used for trans2_ searches */ + char *wcard; + uint16 attr; char *path; -} dptr_struct; + BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ +}; static struct bitmap *dptr_bmap; -static dptr_struct *dirptrs; - +static struct dptr_struct *dirptrs; static int dptrs_open = 0; #define INVALID_DPTR_KEY (-3) @@ -66,13 +88,12 @@ void init_dptrs(void) Idle a dptr - the directory is closed but the control info is kept. ****************************************************************************/ -static void dptr_idle(dptr_struct *dptr) +static void dptr_idle(struct dptr_struct *dptr) { - if (dptr->ptr) { + if (dptr->dir_hnd) { DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum)); - dptrs_open--; - CloseDir(dptr->ptr); - dptr->ptr = NULL; + CloseDir(dptr->dir_hnd); + dptr->dir_hnd = NULL; } } @@ -82,7 +103,7 @@ static void dptr_idle(dptr_struct *dptr) static void dptr_idleoldest(void) { - dptr_struct *dptr; + struct dptr_struct *dptr; /* * Go to the end of the list. @@ -100,7 +121,7 @@ static void dptr_idleoldest(void) */ for(; dptr; dptr = dptr->prev) { - if (dptr->ptr) { + if (dptr->dir_hnd) { dptr_idle(dptr); return; } @@ -108,21 +129,24 @@ static void dptr_idleoldest(void) } /**************************************************************************** - Get the dptr_struct for a dir index. + Get the struct dptr_struct for a dir index. ****************************************************************************/ -static dptr_struct *dptr_get(int key, BOOL forclose) +static struct dptr_struct *dptr_get(int key, BOOL forclose) { - dptr_struct *dptr; + struct dptr_struct *dptr; for(dptr = dirptrs; dptr; dptr = dptr->next) { if(dptr->dnum == key) { - if (!forclose && !dptr->ptr) { + if (!forclose && !dptr->dir_hnd) { 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++; + DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); + if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, True))) { + DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, + strerror(errno))); + return False; + } } DLIST_PROMOTE(dirptrs,dptr); return dptr; @@ -131,95 +155,65 @@ static dptr_struct *dptr_get(int key, BOOL forclose) return(NULL); } -/**************************************************************************** - Get the dptr ptr for a dir index. -****************************************************************************/ - -static void *dptr_ptr(int key) -{ - dptr_struct *dptr = dptr_get(key, False); - - if (dptr) - return(dptr->ptr); - return(NULL); -} - /**************************************************************************** Get the dir path for a dir index. ****************************************************************************/ char *dptr_path(int key) { - dptr_struct *dptr = dptr_get(key, False); - + struct dptr_struct *dptr = dptr_get(key, False); if (dptr) return(dptr->path); return(NULL); } /**************************************************************************** - Get the dir wcard for a dir index (lanman2 specific). + Get the dir wcard for a dir index. ****************************************************************************/ char *dptr_wcard(int key) { - dptr_struct *dptr = dptr_get(key, False); - + struct dptr_struct *dptr = dptr_get(key, False); if (dptr) return(dptr->wcard); return(NULL); } /**************************************************************************** - Set the dir wcard for a dir index (lanman2 specific). - Returns 0 on ok, 1 on fail. + Get the dir attrib for a dir index. ****************************************************************************/ -BOOL dptr_set_wcard(int key, char *wcard) +uint16 dptr_attr(int key) { - dptr_struct *dptr = dptr_get(key, False); - - if (dptr) { - dptr->wcard = wcard; - return True; - } - return False; + struct dptr_struct *dptr = dptr_get(key, False); + if (dptr) + return(dptr->attr); + return(0); } /**************************************************************************** - Set the dir attrib for a dir index (lanman2 specific). + Set the dir wcard for a dir index. Returns 0 on ok, 1 on fail. ****************************************************************************/ -BOOL dptr_set_attr(int key, uint16 attr) +BOOL dptr_set_wcard_and_attributes(int key, char *wcard, uint16 attr) { - dptr_struct *dptr = dptr_get(key, False); + struct dptr_struct *dptr = dptr_get(key, False); if (dptr) { dptr->attr = attr; + dptr->wcard = wcard; + dptr->has_wild = ms_has_wild(wcard); return True; } return False; } -/**************************************************************************** - Get the dir attrib for a dir index (lanman2 specific) -****************************************************************************/ - -uint16 dptr_attr(int key) -{ - dptr_struct *dptr = dptr_get(key, False); - - if (dptr) - return(dptr->attr); - return(0); -} - /**************************************************************************** Close a dptr (internal func). ****************************************************************************/ -static void dptr_close_internal(dptr_struct *dptr) +static void dptr_close_internal(struct dptr_struct *dptr) { DEBUG(4,("closing dptr key %d\n",dptr->dnum)); @@ -237,9 +231,8 @@ static void dptr_close_internal(dptr_struct *dptr) bitmap_clear(dptr_bmap, dptr->dnum - 1); - if (dptr->ptr) { - CloseDir(dptr->ptr); - dptrs_open--; + if (dptr->dir_hnd) { + CloseDir(dptr->dir_hnd); } /* Lanman 2 specific code */ @@ -254,14 +247,14 @@ static void dptr_close_internal(dptr_struct *dptr) void dptr_close(int *key) { - dptr_struct *dptr; + struct dptr_struct *dptr; if(*key == INVALID_DPTR_KEY) return; /* OS/2 seems to use -1 to indicate "close all directories" */ if (*key == -1) { - dptr_struct *next; + struct dptr_struct *next; for(dptr = dirptrs; dptr; dptr = next) { next = dptr->next; dptr_close_internal(dptr); @@ -288,7 +281,7 @@ void dptr_close(int *key) void dptr_closecnum(connection_struct *conn) { - dptr_struct *dptr, *next; + struct dptr_struct *dptr, *next; for(dptr = dirptrs; dptr; dptr = next) { next = dptr->next; if (dptr->conn == conn) @@ -302,9 +295,9 @@ void dptr_closecnum(connection_struct *conn) void dptr_idlecnum(connection_struct *conn) { - dptr_struct *dptr; + struct dptr_struct *dptr; for(dptr = dirptrs; dptr; dptr = dptr->next) { - if (dptr->conn == conn && dptr->ptr) + if (dptr->conn == conn && dptr->dir_hnd) dptr_idle(dptr); } } @@ -315,7 +308,7 @@ void dptr_idlecnum(connection_struct *conn) void dptr_closepath(char *path,uint16 spid) { - dptr_struct *dptr, *next; + struct dptr_struct *dptr, *next; for(dptr = dirptrs; dptr; dptr = next) { next = dptr->next; if (spid == dptr->spid && strequal(dptr->path,path)) @@ -323,35 +316,6 @@ void dptr_closepath(char *path,uint16 spid) } } -/**************************************************************************** - Start a directory listing. -****************************************************************************/ - -static BOOL start_dir(connection_struct *conn, pstring directory) -{ - const char *dir2; - - DEBUG(5,("start_dir dir=%s\n",directory)); - - if (!check_name(directory,conn)) - return(False); - - /* 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); - } - - return(False); -} - /**************************************************************************** Try and close the oldest handle not marked for expect close in the hope that the client has @@ -360,7 +324,7 @@ static BOOL start_dir(connection_struct *conn, pstring directory) static void dptr_close_oldest(BOOL old) { - dptr_struct *dptr; + struct dptr_struct *dptr; /* * Go to the end of the list. @@ -393,23 +357,39 @@ static void dptr_close_oldest(BOOL old) from the bitmap range 0 - 255 as old SMBsearch directory handles are only one byte long. If old_handle is false we allocate from the range 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure - a directory handle is never zero. All the above is folklore taught to - me at Andrew's knee.... :-) :-). JRA. + a directory handle is never zero. ****************************************************************************/ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid) { - dptr_struct *dptr; + struct dptr_struct *dptr = NULL; + struct smb_Dir *dir_hnd; + const char *dir2; + + DEBUG(5,("dptr_create dir=%s\n", path)); - if (!start_dir(conn,path)) + if (!check_name(path,conn)) return(-2); /* Code to say use a unix error return code. */ + /* use a const pointer from here on */ + dir2 = path; + if (!*dir2) + dir2 = "."; + + dir_hnd = OpenDir(conn, dir2, True); + if (!dir_hnd) { + return (-2); + } + + string_set(&conn->dirpath,dir2); + if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); - dptr = SMB_MALLOC_P(dptr_struct); + dptr = SMB_MALLOC_P(struct dptr_struct); if(!dptr) { DEBUG(0,("malloc fail in dptr_create.\n")); + CloseDir(dir_hnd); return -1; } @@ -439,6 +419,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp 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); + CloseDir(dir_hnd); return -1; } } @@ -468,6 +449,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp 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); + CloseDir(dir_hnd); return -1; } } @@ -477,22 +459,55 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ - dptr->ptr = conn->dirptr; - string_set(&dptr->path,path); + string_set(&dptr->path,dir2); dptr->conn = conn; + dptr->dir_hnd = dir_hnd; 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->has_wild = True; /* Only used in lanman2 searches */ DLIST_ADD(dirptrs, dptr); DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", dptr->dnum,path,expect_close)); + conn->dirptr = dptr; + return(dptr->dnum); } + +/**************************************************************************** + Wrapper functions to access the lower level directory handles. +****************************************************************************/ + +int dptr_CloseDir(struct dptr_struct *dptr) +{ + return CloseDir(dptr->dir_hnd); +} + +const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset) +{ + return ReadDirName(dptr->dir_hnd, poffset); +} + +void dptr_SeekDir(struct dptr_struct *dptr, long offset) +{ + SeekDir(dptr->dir_hnd, offset); +} + +long dptr_TellDir(struct dptr_struct *dptr) +{ + return TellDir(dptr->dir_hnd); +} + +BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, BOOL case_sensitive) +{ + return SearchDir(dptr->dir_hnd, name, poffset, case_sensitive); +} + /**************************************************************************** Fill the 5 byte server reserved dptr field. ****************************************************************************/ @@ -500,15 +515,15 @@ 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); + struct dptr_struct *dptr = dptr_get(key, False); uint32 offset; - if (!p) { + if (!dptr) { DEBUG(1,("filling null dirptr %d\n",key)); return(False); } - offset = TellDir(p); + offset = TellDir(dptr->dir_hnd); DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, - (long)p,(int)offset)); + (long)dptr->dir_hnd,(int)offset)); buf[0] = key; SIVAL(buf,1,offset | DPTR_MASK); return(True); @@ -518,38 +533,38 @@ BOOL dptr_fill(char *buf1,unsigned int key) Fetch the dir ptr and seek it given the 5 byte server field. ****************************************************************************/ -void *dptr_fetch(char *buf,int *num) +struct dptr_struct *dptr_fetch(char *buf,int *num) { unsigned int key = *(unsigned char *)buf; - void *p = dptr_ptr(key); + struct dptr_struct *dptr = dptr_get(key, False); uint32 offset; - if (!p) { + if (!dptr) { DEBUG(3,("fetched null dirptr %d\n",key)); return(NULL); } *num = key; offset = IVAL(buf,1)&~DPTR_MASK; - SeekDir(p,offset); + SeekDir(dptr->dir_hnd,(long)offset); DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", key,dptr_path(key),offset)); - return(p); + return(dptr); } /**************************************************************************** Fetch the dir ptr. ****************************************************************************/ -void *dptr_fetch_lanman2(int dptr_num) +struct dptr_struct *dptr_fetch_lanman2(int dptr_num) { - void *p = dptr_ptr(dptr_num); + struct dptr_struct *dptr = dptr_get(dptr_num, False); - if (!p) { + if (!dptr) { 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); + return(dptr); } /**************************************************************************** @@ -612,11 +627,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname return(False); while (!found) { - long curoff = TellDir(conn->dirptr); - dname = ReadDirName(conn->dirptr, &curoff); + long curoff = TellDir(conn->dirptr->dir_hnd); + dname = ReadDirName(conn->dirptr->dir_hnd, &curoff); DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", - (long)conn->dirptr,TellDir(conn->dirptr))); + (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); if (dname == NULL) return(False); @@ -799,34 +814,13 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; } -#define NAME_CACHE_SIZE 100 - -struct name_cache_entry { - char *name; - long offset; -}; - -typedef struct { - connection_struct *conn; - DIR *dir; - long offset; - char *dir_path; - struct name_cache_entry *name_cache; - unsigned int name_cache_index; - BOOL hide_unreadable; - BOOL hide_unwriteable; - BOOL hide_special; - BOOL use_veto; - BOOL finished; -} Dir; - /******************************************************************* Open a directory. ********************************************************************/ -void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) +struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) { - Dir *dirp = SMB_MALLOC_P(Dir); + struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); if (!dirp) { return NULL; } @@ -854,7 +848,8 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) dirp->hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); dirp->hide_special = lp_hide_special_files(SNUM(conn)); - return((void *)dirp); + dptrs_open++; + return dirp; fail: @@ -874,10 +869,9 @@ void *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) Close a directory. ********************************************************************/ -int CloseDir(void *p) +int CloseDir(struct smb_Dir *dirp) { int i, ret = 0; - Dir *dirp = (Dir *)p; if (dirp->dir) { ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); @@ -890,62 +884,20 @@ int CloseDir(void *p) } SAFE_FREE(dirp->name_cache); SAFE_FREE(dirp); + dptrs_open--; return ret; } -/******************************************************************* - Set a directory into an inactive state. -********************************************************************/ - -static void SleepDir(Dir *dirp) -{ - if (dirp->dir) { - SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); - dirp->dir = 0; - } - dirp->offset = 0; -} - -/******************************************************************* - Wake a directory into a known state. -********************************************************************/ - -static int WakeDir(Dir *dirp, long offset) -{ - if (!dirp->dir) { - dirp->dir = SMB_VFS_OPENDIR(dirp->conn, dirp->dir_path); - if (!dirp->dir) { - DEBUG(0,("WakeDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); - dirp->finished = True; - return -1; - } - } - if (offset != dirp->offset) { - SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); - dirp->offset = SMB_VFS_TELLDIR(dirp->conn, dirp->dir); - if (dirp->offset != offset) { - DEBUG(0,("WakeDir: in path %s. offset changed %ld -> %ld\n", - dirp->dir_path, offset, dirp->offset )); - return -1; - } - } - return 0; -} - /******************************************************************* Read from a directory. Also return current offset. ********************************************************************/ -const char *ReadDirName(void *p, long *poffset) +const char *ReadDirName(struct smb_Dir *dirp, long *poffset) { const char *n; - Dir *dirp = (Dir *)p; connection_struct *conn = dirp->conn; - if (WakeDir(dirp, *poffset) == -1) { - return NULL; - } - + SeekDir(dirp, *poffset); while ((n = vfs_readdirname(conn, dirp->dir))) { struct name_cache_entry *e; @@ -994,9 +946,6 @@ const char *ReadDirName(void *p, long *poffset) *poffset = e->offset= dirp->offset; return e->name; } - - dirp->finished = True; - SleepDir(dirp); return NULL; } @@ -1004,19 +953,20 @@ const char *ReadDirName(void *p, long *poffset) Seek a dir. ********************************************************************/ -BOOL SeekDir(void *p,long offset) +void SeekDir(struct smb_Dir *dirp, long offset) { - Dir *dirp = (Dir *)p; - return (WakeDir(dirp, offset) != -1); + if (offset != dirp->offset) { + SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); + dirp->offset = offset; + } } /******************************************************************* Tell a dir position. ********************************************************************/ -long TellDir(void *p) +long TellDir(struct smb_Dir *dirp) { - Dir *dirp = (Dir *)p; return(dirp->offset); } @@ -1024,24 +974,18 @@ long TellDir(void *p) Find an entry by name. Leave us at the offset after it. ********************************************************************/ -BOOL SearchDir(void *p, const char *name, long *poffset, BOOL case_sensitive) +BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_sensitive) { int i; - Dir *dirp = (Dir *)p; const char *entry; connection_struct *conn = dirp->conn; - /* Re-create dir but don't seek. */ - if (WakeDir(dirp, dirp->offset) == -1) { - return False; - } - /* Search back in the name cache. */ for (i = dirp->name_cache_index; i >= 0; i--) { struct name_cache_entry *e = &dirp->name_cache[i]; if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { *poffset = e->offset; - WakeDir(dirp, e->offset); + SeekDir(dirp, e->offset); return True; } } @@ -1049,7 +993,7 @@ BOOL SearchDir(void *p, const char *name, long *poffset, BOOL case_sensitive) struct name_cache_entry *e = &dirp->name_cache[i]; if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { *poffset = e->offset; - WakeDir(dirp, e->offset); + SeekDir(dirp, e->offset); return True; } } @@ -1062,7 +1006,5 @@ BOOL SearchDir(void *p, const char *name, long *poffset, BOOL case_sensitive) return True; } } - - SleepDir(dirp); return False; } -- cgit From c1d7588c74ecfb8cf613256629e272b81f154aa6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Feb 2005 02:06:00 +0000 Subject: r5154: Tidy up interface a little. Jeremy. (This used to be commit a38eeb765f4c744ca7bf0aca86bb448240ad295d) --- source3/smbd/dir.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7f1237cb29..29ef4cbe61 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -196,13 +196,15 @@ uint16 dptr_attr(int key) Returns 0 on ok, 1 on fail. ****************************************************************************/ -BOOL dptr_set_wcard_and_attributes(int key, char *wcard, uint16 attr) +BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr) { struct dptr_struct *dptr = dptr_get(key, False); if (dptr) { dptr->attr = attr; - dptr->wcard = wcard; + dptr->wcard = SMB_STRDUP(wcard); + if (!dptr->wcard) + return False; dptr->has_wild = ms_has_wild(wcard); return True; } -- cgit From 021011f90030f6f4c39c9ef27db17eec5d4536ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Feb 2005 18:33:50 +0000 Subject: r5160: First cut at refactoring of directory code to handle non-wildcard directory match more efficiently. Passes RAW-SEARCH under valgrind but needs more testing (which I'll do later today :-). Jeremy. (This used to be commit 0b04dd9d0c6d1fe02d1b5e43f203577bf5466f33) --- source3/smbd/dir.c | 212 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 149 insertions(+), 63 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 29ef4cbe61..e9934ff49c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -40,10 +40,6 @@ struct smb_Dir { char *dir_path; struct name_cache_entry *name_cache; unsigned int name_cache_index; - BOOL hide_unreadable; - BOOL hide_unwriteable; - BOOL hide_special; - BOOL use_veto; }; struct dptr_struct { @@ -142,7 +138,7 @@ static struct dptr_struct *dptr_get(int key, BOOL forclose) if (dptrs_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); - if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, True))) { + if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); return False; @@ -205,7 +201,11 @@ BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr) dptr->wcard = SMB_STRDUP(wcard); if (!dptr->wcard) return False; - dptr->has_wild = ms_has_wild(wcard); + if (wcard[0] == '.' && wcard[1] == 0) { + dptr->has_wild = True; + } else { + dptr->has_wild = ms_has_wild(wcard); + } return True; } return False; @@ -378,7 +378,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp if (!*dir2) dir2 = "."; - dir_hnd = OpenDir(conn, dir2, True); + dir_hnd = OpenDir(conn, dir2); if (!dir_hnd) { return (-2); } @@ -490,11 +490,6 @@ int dptr_CloseDir(struct dptr_struct *dptr) return CloseDir(dptr->dir_hnd); } -const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset) -{ - return ReadDirName(dptr->dir_hnd, poffset); -} - void dptr_SeekDir(struct dptr_struct *dptr, long offset) { SeekDir(dptr->dir_hnd, offset); @@ -505,9 +500,90 @@ long dptr_TellDir(struct dptr_struct *dptr) return TellDir(dptr->dir_hnd); } -BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, BOOL case_sensitive) +/**************************************************************************** + Return the next visible file name, skipping veto'd and invisible files. +****************************************************************************/ + +static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) { - return SearchDir(dptr->dir_hnd, name, poffset, case_sensitive); + /* Normal search for the next file. */ + const char *name; + while ((name = ReadDirName(dptr->dir_hnd, poffset)) != NULL) { + if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { + return name; + } + } + return NULL; +} + +/**************************************************************************** + Return the next visible file name, skipping veto'd and invisible files. +****************************************************************************/ + +const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) +{ + pstring pathreal; + + ZERO_STRUCTP(pst); + if (dptr->has_wild) { + return dptr_normal_ReadDirName(dptr, poffset, pst); + } + + /* We know the stored wcard contains no wildcard characters. See if we can match + with a stat call. If we can't, then set has_wild to true to + prevent us from doing this on every call. */ + + /* First check if it should be visible. */ + if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) { + dptr->has_wild = True; + return dptr_normal_ReadDirName(dptr, poffset, pst); + } + + if (VALID_STAT(*pst)) { + return dptr->wcard; + } + + pstrcpy(pathreal,dptr->path); + pstrcat(pathreal,"/"); + pstrcat(pathreal,dptr->wcard); + + if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { + return dptr->wcard; + } else { + /* If we get any other error than ENOENT or ENOTDIR + then the file exists we just can't stat it. */ + if (errno != ENOENT && errno != ENOTDIR) { + return dptr->wcard; + } + } + + dptr->has_wild = True; + + /* In case sensitive mode we don't search - we know if it doesn't exist + with a stat we will fail. */ + + if (dptr->conn->case_sensitive) { + return NULL; + } else { + return dptr_normal_ReadDirName(dptr, poffset, pst); + } +} + +/**************************************************************************** + Search for a file by name, skipping veto'ed and not visible files. +****************************************************************************/ + +BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) +{ + BOOL ret; + + ZERO_STRUCTP(pst); + while ((ret = SearchDir(dptr->dir_hnd, name, poffset)) == True) { + if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { + return True; + } + } + return False; } /**************************************************************************** @@ -573,7 +649,7 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) Check a filetype for being valid. ****************************************************************************/ -BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype) +BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype) { int mask; @@ -629,8 +705,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname return(False); while (!found) { - long curoff = TellDir(conn->dirptr->dir_hnd); - dname = ReadDirName(conn->dirptr->dir_hnd, &curoff); + long curoff = dptr_TellDir(conn->dirptr); + dname = dptr_ReadDirName(conn->dirptr, &curoff, &sbuf); DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); @@ -661,14 +737,14 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname pstrcpy(pathreal,path); pstrcat(path,fname); pstrcat(pathreal,dname); - if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) { + if (!VALID_STAT(sbuf) && (SMB_VFS_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); - if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) { + if (!dir_check_ftype(conn,*mode,dirtype)) { DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); continue; } @@ -816,11 +892,58 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT return True; } +/******************************************************************* + Should the file be seen by the client ? +********************************************************************/ + +BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, BOOL use_veto) +{ + BOOL hide_unreadable = lp_hideunreadable(SNUM(conn)); + BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); + BOOL hide_special = lp_hide_special_files(SNUM(conn)); + + ZERO_STRUCT(pst); + + if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) { + return True; /* . and .. are always visible. */ + } + + /* If it's a vetoed file, pretend it doesn't even exist */ + if (use_veto && IS_VETO_PATH(conn, name)) { + return False; + } + + if (hide_unreadable || hide_unwriteable || hide_special) { + char *entry = NULL; + + if (asprintf(&entry, "%s/%s", dir_path, name) == -1) { + return False; + } + /* Honour _hide unreadable_ option */ + if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { + SAFE_FREE(entry); + return False; + } + /* Honour _hide unwriteable_ option */ + if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) { + SAFE_FREE(entry); + return False; + } + /* Honour _hide_special_ option */ + if (hide_special && !file_is_special(conn, entry, pst)) { + SAFE_FREE(entry); + return False; + } + SAFE_FREE(entry); + } + return True; +} + /******************************************************************* Open a directory. ********************************************************************/ -struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto) +struct smb_Dir *OpenDir(connection_struct *conn, const char *name) { struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); if (!dirp) { @@ -829,7 +952,6 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto ZERO_STRUCTP(dirp); dirp->conn = conn; - dirp->use_veto = use_veto; dirp->dir_path = SMB_STRDUP(name); if (!dirp->dir_path) { @@ -846,10 +968,6 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto goto fail; } - dirp->hide_unreadable = lp_hideunreadable(SNUM(conn)); - dirp->hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); - dirp->hide_special = lp_hide_special_files(SNUM(conn)); - dptrs_open++; return dirp; @@ -892,6 +1010,7 @@ int CloseDir(struct smb_Dir *dirp) /******************************************************************* Read from a directory. Also return current offset. + Don't check for veto or invisible files. ********************************************************************/ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) @@ -902,40 +1021,6 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) SeekDir(dirp, *poffset); while ((n = vfs_readdirname(conn, dirp->dir))) { struct name_cache_entry *e; - - if (!((strcmp(".",n) == 0) || (strcmp("..",n) == 0))) { - /* If it's a vetoed file, pretend it doesn't even exist */ - if (dirp->use_veto && IS_VETO_PATH(conn, n)) { - continue; - } - - if (dirp->hide_unreadable || dirp->hide_unwriteable || dirp->hide_special) { - SMB_STRUCT_STAT st; - char *entry = NULL; - ZERO_STRUCT(st); - - if (asprintf(&entry, "%s/%s/%s", conn->origpath, dirp->dir_path, n) == -1) { - return NULL; - } - /* Honour _hide unreadable_ option */ - if (dirp->hide_unreadable && !user_can_read_file(conn, entry, &st)) { - SAFE_FREE(entry); - continue; - } - /* Honour _hide unwriteable_ option */ - if (dirp->hide_unwriteable && !user_can_write_file(conn, entry, &st)) { - SAFE_FREE(entry); - continue; - } - /* Honour _hide_special_ option */ - if (dirp->hide_special && !file_is_special(conn, entry, &st)) { - SAFE_FREE(entry); - continue; - } - SAFE_FREE(entry); - } - } - dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); if (dirp->offset == -1) { return NULL; @@ -974,9 +1059,10 @@ long TellDir(struct smb_Dir *dirp) /******************************************************************* Find an entry by name. Leave us at the offset after it. + Don't check for veto or invisible files. ********************************************************************/ -BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_sensitive) +BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) { int i; const char *entry; @@ -985,7 +1071,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_ /* Search back in the name cache. */ for (i = dirp->name_cache_index; i >= 0; i--) { struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { *poffset = e->offset; SeekDir(dirp, e->offset); return True; @@ -993,7 +1079,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_ } for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) { struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { *poffset = e->offset; SeekDir(dirp, e->offset); return True; @@ -1004,7 +1090,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_ SMB_VFS_REWINDDIR(conn, dirp->dir); *poffset = 0; while ((entry = ReadDirName(dirp, poffset))) { - if (case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { + if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { return True; } } -- cgit From 91ef89daa03551fa17ff78adb9f36420057948da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Feb 2005 02:02:54 +0000 Subject: r5183: Ensure we correctly set the per-connection "case_sensitive" setting. Rename dptrs_open to the more correct dirhandles_open. Remove old #if 1. Jeremy. (This used to be commit c43bae306a18f5716acbe8571f4f414873400cb1) --- source3/smbd/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index e9934ff49c..fb1a700074 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -57,7 +57,7 @@ struct dptr_struct { static struct bitmap *dptr_bmap; static struct dptr_struct *dirptrs; -static int dptrs_open = 0; +static int dirhandles_open = 0; #define INVALID_DPTR_KEY (-3) @@ -135,7 +135,7 @@ static struct dptr_struct *dptr_get(int key, BOOL forclose) for(dptr = dirptrs; dptr; dptr = dptr->next) { if(dptr->dnum == key) { if (!forclose && !dptr->dir_hnd) { - if (dptrs_open >= MAX_OPEN_DIRECTORIES) + if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) { @@ -385,7 +385,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp string_set(&conn->dirpath,dir2); - if (dptrs_open >= MAX_OPEN_DIRECTORIES) + if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); dptr = SMB_MALLOC_P(struct dptr_struct); @@ -968,7 +968,7 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name) goto fail; } - dptrs_open++; + dirhandles_open++; return dirp; fail: @@ -1004,7 +1004,7 @@ int CloseDir(struct smb_Dir *dirp) } SAFE_FREE(dirp->name_cache); SAFE_FREE(dirp); - dptrs_open--; + dirhandles_open--; return ret; } -- cgit From fcbb7b0e25ae22bd8fb04918cf1c5af44a06ca19 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Feb 2005 20:54:06 +0000 Subject: r5508: Typo - ZERO_STRUCT -> ZERO_STRUCTP. Jeremy. (This used to be commit 76e1d90aef45ccc089492d962e0f284e2e4d8e7a) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index fb1a700074..7dde18f430 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -902,7 +902,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); BOOL hide_special = lp_hide_special_files(SNUM(conn)); - ZERO_STRUCT(pst); + ZERO_STRUCTP(pst); if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) { return True; /* . and .. are always visible. */ -- cgit From 5713c65a82564b5fdb9ecbbd650ade7f302492c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Mar 2005 02:04:36 +0000 Subject: r5632: Fix infinite looping bug found by nasty BlueArc test :-). When finding a singleton directory remember that we're at the end and don't continuously return the same name. Jeremy. (This used to be commit 3da50060279609f534aeffe6338b0a2b07d0e8f1) --- source3/smbd/dir.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7dde18f430..d9fd382d52 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -525,10 +525,17 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT pstring pathreal; ZERO_STRUCTP(pst); + if (dptr->has_wild) { return dptr_normal_ReadDirName(dptr, poffset, pst); } + /* If poffset is -1 then we know we returned this name before and we have + no wildcards. We're at the end of the directory. */ + if (*poffset == -1) { + return NULL; + } + /* We know the stored wcard contains no wildcard characters. See if we can match with a stat call. If we can't, then set has_wild to true to prevent us from doing this on every call. */ @@ -540,6 +547,9 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT } if (VALID_STAT(*pst)) { + /* We need to set the underlying dir_hdn offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = -1; return dptr->wcard; } @@ -548,11 +558,17 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT pstrcat(pathreal,dptr->wcard); if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { + /* We need to set the underlying dir_hdn offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = -1; return dptr->wcard; } else { /* If we get any other error than ENOENT or ENOTDIR then the file exists we just can't stat it. */ if (errno != ENOENT && errno != ENOTDIR) { + /* We need to set the underlying dir_hdn offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = -1; return dptr->wcard; } } @@ -563,6 +579,9 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT with a stat we will fail. */ if (dptr->conn->case_sensitive) { + /* We need to set the underlying dir_hdn offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = -1; return NULL; } else { return dptr_normal_ReadDirName(dptr, poffset, pst); @@ -1033,6 +1052,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) *poffset = e->offset= dirp->offset; return e->name; } + dirp->offset = -1; return NULL; } -- cgit From ee804161aae672a1e46d46bcbbc49fd453616bb7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Mar 2005 01:02:30 +0000 Subject: r5843: Removed unused variable - pointed out by jason@ncac.gwu.edu in bugid #2460. Jeremy. (This used to be commit 1f988333ecaedfb21a8deee6eebb9bd4de91bfd6) --- source3/smbd/dir.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index d9fd382d52..db16b8a6e0 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -594,10 +594,8 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { - BOOL ret; - ZERO_STRUCTP(pst); - while ((ret = SearchDir(dptr->dir_hnd, name, poffset)) == True) { + while (SearchDir(dptr->dir_hnd, name, poffset) == True) { if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { return True; } -- cgit From ff107a93cdf4ab75be44097897ecc42ea46580e2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 21 Mar 2005 18:10:21 +0000 Subject: r5922: Fix for NASTY NASTY bug #2501. All my fault :-(. Brown paper bag time. Stops Win98 from looping doing findnext on a singleton directory. More testing very welcome. Jeremy. (This used to be commit e32a58742e618a49934e19b72cd5222c9666cf95) --- source3/smbd/dir.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index db16b8a6e0..1ec35d839c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -595,6 +595,13 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { ZERO_STRUCTP(pst); + + if (!dptr->has_wild && (dptr->dir_hnd->offset == -1)) { + /* This is a singleton directory and we're already at the end. */ + *poffset = -1; + return False; + } + while (SearchDir(dptr->dir_hnd, name, poffset) == True) { if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { return True; -- cgit From 143bf1202c924f53db811d1d076580eea4acdb7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Mar 2005 02:23:32 +0000 Subject: r6022: Fix for bug #2533. Incorrect dir listings from OS/2 clients. Jeremy. (This used to be commit cf8949f684ee9adcd35d56d923b2f5733efc05ac) --- source3/smbd/dir.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1ec35d839c..6ecdcec461 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -713,16 +713,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname 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] != '/'); if (!conn->dirptr) @@ -747,8 +742,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname 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)); -- cgit From 445a9729f03117afdaa141a6d074d8af064b4399 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Mar 2005 19:33:02 +0000 Subject: r6044: Ensure the old search calls always ask mask_match to translate patterns like ????????.??? - even if using an NT1 protocol. Matches W2K3 behavior. Jeremy. (This used to be commit 67f6473f50f3284b9ccbe6f983f23cd42b3b7c9f) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 6ecdcec461..55f1523865 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -698,7 +698,7 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype) static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) { mangle_map(filename,True,False,SNUM(conn)); - return mask_match(filename,mask,False); + return mask_match_search(filename,mask,False); } /**************************************************************************** @@ -740,7 +740,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname see masktest for a demo */ if ((strcmp(mask,"*.*") == 0) || - mask_match(filename,mask,False) || + mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { if (!mangle_is_8_3(filename, False)) -- cgit From 8d2e18ac539455055b23bcbd72434e76ec46a1ce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 1 Apr 2005 19:57:22 +0000 Subject: r6169: Fix bug #2563. Infinite loop on non-existant file with findnext. Jeremy (This used to be commit 065ab9182dc39557b8c26d3d110abe9963ad9568) --- source3/smbd/dir.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 55f1523865..27ec003fb8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -573,8 +573,6 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT } } - dptr->has_wild = True; - /* In case sensitive mode we don't search - we know if it doesn't exist with a stat we will fail. */ @@ -584,6 +582,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT dptr->dir_hnd->offset = *poffset = -1; return NULL; } else { + dptr->has_wild = True; return dptr_normal_ReadDirName(dptr, poffset, pst); } } @@ -602,7 +601,7 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S return False; } - while (SearchDir(dptr->dir_hnd, name, poffset) == True) { + if (SearchDir(dptr->dir_hnd, name, poffset)) { if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { return True; } -- cgit From 978ca8486031e43754a3c23757f361bf3a85f335 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 27ec003fb8..0f32dddd2d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -24,6 +24,8 @@ This module implements directory related functions for Samba. */ +extern struct current_user current_user; + /* Make directory handle internals available. */ #define NAME_CACHE_SIZE 100 @@ -785,7 +787,6 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname 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; @@ -838,7 +839,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S static BOOL user_can_write_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; -- cgit From d0a0930485508da9d3bd2ee2e37c3cc15896940e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 Apr 2005 07:57:52 +0000 Subject: r6417: Strange old IRIX systems return -1 for telldir() when end of directory reached. Don't check for that and bail when reading directory entries as it's a valid value. Excellent work from Cale Fairchild tracked this down. Jeremy. (This used to be commit a60fe9aba16eac4f195a2359d8b7672d8c8aa240) --- source3/smbd/dir.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 0f32dddd2d..054588b25e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1038,11 +1038,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) while ((n = vfs_readdirname(conn, dirp->dir))) { struct name_cache_entry *e; dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); - if (dirp->offset == -1) { - return NULL; - } dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; - e = &dirp->name_cache[dirp->name_cache_index]; SAFE_FREE(e->name); e->name = SMB_STRDUP(n); -- cgit From e0c105ece672502aae19f0e17fde3021207dd47a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Apr 2005 23:15:48 +0000 Subject: r6473: Fix for bug #2644 - test for special files to be ignored was reversed. Jeremy. (This used to be commit 7c173dec2efcbe3fe42ffb9a2e85f3fbc8710ec4) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 054588b25e..5ebbfe478f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -946,7 +946,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * return False; } /* Honour _hide_special_ option */ - if (hide_special && !file_is_special(conn, entry, pst)) { + if (hide_special && file_is_special(conn, entry, pst)) { SAFE_FREE(entry); return False; } -- cgit From 431a28a3151f6cb8f9e1de769da11a22c379d9d8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 1 May 2005 09:30:18 +0000 Subject: r6548: Fix bug #2622 - remove DPTR_MASK as it makes no sense. Jeremy. (This used to be commit 927681c8c4458c77de2622557f1465fd5ca1c28b) --- source3/smbd/dir.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5ebbfe478f..3c93c188ff 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -624,11 +624,11 @@ BOOL dptr_fill(char *buf1,unsigned int key) DEBUG(1,("filling null dirptr %d\n",key)); return(False); } - offset = TellDir(dptr->dir_hnd); + offset = (uint32)TellDir(dptr->dir_hnd); DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, (long)dptr->dir_hnd,(int)offset)); buf[0] = key; - SIVAL(buf,1,offset | DPTR_MASK); + SIVAL(buf,1,offset); return(True); } @@ -641,16 +641,22 @@ struct dptr_struct *dptr_fetch(char *buf,int *num) unsigned int key = *(unsigned char *)buf; struct dptr_struct *dptr = dptr_get(key, False); uint32 offset; + long seekoff; if (!dptr) { DEBUG(3,("fetched null dirptr %d\n",key)); return(NULL); } *num = key; - offset = IVAL(buf,1)&~DPTR_MASK; - SeekDir(dptr->dir_hnd,(long)offset); + offset = IVAL(buf,1); + if (offset == (uint32)-1) { + seekoff = -1; + } else { + seekoff = (long)offset; + } + SeekDir(dptr->dir_hnd,seekoff); DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", - key,dptr_path(key),offset)); + key,dptr_path(key),(int)seekoff)); return(dptr); } -- cgit From 0483dd60ded1239d8a3ab46598e164416f7668b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 1 May 2005 10:00:14 +0000 Subject: r6550: Move function make_dir_struct from util to dir.c Jeremy. (This used to be commit 5b86e3dcdf31dec61449d2faede61d24c3a8d79f) --- source3/smbd/dir.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 3c93c188ff..95a5903c14 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -63,6 +63,40 @@ static int dirhandles_open = 0; #define INVALID_DPTR_KEY (-3) +/**************************************************************************** + Make a dir struct. +****************************************************************************/ + +void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL uc) +{ + char *p; + pstring mask2; + + pstrcpy(mask2,mask); + + if ((mode & aDIR) != 0) + size = 0; + + memset(buf+1,' ',11); + if ((p = strchr_m(mask2,'.')) != NULL) { + *p = 0; + push_ascii(buf+1,mask2,8, 0); + push_ascii(buf+9,p+1,3, 0); + *p = '.'; + } else + push_ascii(buf+1,mask2,11, 0); + + memset(buf+21,'\0',DIR_STRUCT_SIZE-21); + SCVAL(buf,21,mode); + put_dos_date(buf,22,date); + SSVAL(buf,26,size & 0xFFFF); + SSVAL(buf,28,(size >> 16)&0xFFFF); + /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf. + Strange, but verified on W2K3. Needed for OS/2. JRA. */ + push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0); + DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname)); +} + /**************************************************************************** Initialise the dir bitmap. ****************************************************************************/ -- cgit From 02e3717ee9e045d197d845489e84ac40083ca868 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 May 2005 08:07:39 +0000 Subject: r6625: Remove another global variable left over from a long time ago (magic char). Jeremy. (This used to be commit b1bfa9cb37deb22d1d08bc60ba44d61334f6446e) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 95a5903c14..d66d1601fb 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -784,7 +784,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { - if (!mangle_is_8_3(filename, False)) + if (!mangle_is_8_3(filename, False, SNUM(conn))) mangle_map(filename,True,False,SNUM(conn)); pstrcpy(fname,filename); -- cgit From ed5e7ff9f184fd36b4344c958f145cc4a4987c71 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Jun 2005 23:18:52 +0000 Subject: r7200: Don't use memset, use SET_STAT_INVALID (has the same effect). Jeremy. (This used to be commit 0b6f87d5e14da461bd2b1c3a4e6f47a69d2cd1c4) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index d66d1601fb..935ca20195 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -560,7 +560,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT { pstring pathreal; - ZERO_STRUCTP(pst); + SET_STAT_INVALID(pst); if (dptr->has_wild) { return dptr_normal_ReadDirName(dptr, poffset, pst); @@ -629,7 +629,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { - ZERO_STRUCTP(pst); + SET_STAT_INVALID(pst); if (!dptr->has_wild && (dptr->dir_hnd->offset == -1)) { /* This is a singleton directory and we're already at the end. */ @@ -958,7 +958,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); BOOL hide_special = lp_hide_special_files(SNUM(conn)); - ZERO_STRUCTP(pst); + SET_STAT_INVALID(pst); if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) { return True; /* . and .. are always visible. */ -- cgit From 0deab47cc6f17e597430130df66f7acf8842ff30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Jun 2005 05:35:04 +0000 Subject: r7210: Fix my own mistakes up, sorry. Jeremy. (This used to be commit 53c3a954ee0e1c9dc61950f1a9d0a654de9382c6) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 935ca20195..f335c60897 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -560,7 +560,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT { pstring pathreal; - SET_STAT_INVALID(pst); + SET_STAT_INVALID(*pst); if (dptr->has_wild) { return dptr_normal_ReadDirName(dptr, poffset, pst); @@ -629,7 +629,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { - SET_STAT_INVALID(pst); + SET_STAT_INVALID(*pst); if (!dptr->has_wild && (dptr->dir_hnd->offset == -1)) { /* This is a singleton directory and we're already at the end. */ @@ -958,7 +958,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); BOOL hide_special = lp_hide_special_files(SNUM(conn)); - SET_STAT_INVALID(pst); + SET_STAT_INVALID(*pst); if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) { return True; /* . and .. are always visible. */ -- cgit From c3fedee2a67966e4640b26dd084e75125e58f55c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Jun 2005 23:13:25 +0000 Subject: r7474: A *foul* and *disgusting* hack to ensure that, at the very lowest level, . and .. are the first two entries returned when reading a directory. This also means we can't seek to these offsets, but we will never be doing that anyway (as far as I can think). The reason we have to do this is that the NT4 explorer will happily display a folder marked ".." as a clickable folder (and probably would display "." as a clickable folder too) if these are not in positions zero and one of the returned file list. W2K seems to have fixed this but there are too many older systems out there... Never mind, more for the "Undocumented CIFS talk", coming to a CIFS2005 conference near you soon.... :-). Jeremy. (This used to be commit 7b6e907922b7d98abe4430ea73712a9c6419ea08) --- source3/smbd/dir.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f335c60897..b9c6cf8797 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -42,6 +42,7 @@ struct smb_Dir { char *dir_path; struct name_cache_entry *name_cache; unsigned int name_cache_index; + unsigned int file_number; }; struct dptr_struct { @@ -1074,15 +1075,35 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) const char *n; connection_struct *conn = dirp->conn; - SeekDir(dirp, *poffset); + /* Cheat to allow . and .. to be the first entries returned. */ + if ((*poffset == 0) && (dirp->file_number < 2)) { + if (dirp->file_number == 0) { + n = "."; + } else { + n = ".."; + } + dirp->file_number++; + return n; + } else { + /* A real offset, seek to it. */ + SeekDir(dirp, *poffset); + } + while ((n = vfs_readdirname(conn, dirp->dir))) { struct name_cache_entry *e; + /* Ignore . and .. - we've already returned them. */ + if (*n == '.') { + if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) { + continue; + } + } dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; e = &dirp->name_cache[dirp->name_cache_index]; SAFE_FREE(e->name); e->name = SMB_STRDUP(n); *poffset = e->offset= dirp->offset; + dirp->file_number++; return e->name; } dirp->offset = -1; @@ -1141,6 +1162,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) /* Not found in the name cache. Rewind directory and start from scratch. */ SMB_VFS_REWINDDIR(conn, dirp->dir); + dirp->file_number = 0; *poffset = 0; while ((entry = ReadDirName(dirp, poffset))) { if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { -- cgit From 741b0a97bbf3e2f7ed3292b9508b39edb00d97c1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jun 2005 18:37:34 +0000 Subject: r7617: Fix for bug #2801 - delete veto files was broken with the new large directory code. Jeremy. (This used to be commit f397cc08b5628913af4d7f9c2c6d20c778e5d8ca) --- source3/smbd/dir.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b9c6cf8797..072f396b8c 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1110,6 +1110,18 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) return NULL; } +/******************************************************************* + Rewind to the start. +********************************************************************/ + +void RewindDir(struct smb_Dir *dirp, long *poffset) +{ + SMB_VFS_REWINDDIR(dirp->conn, dirp->dir); + dirp->file_number = 0; + dirp->offset = 0; + *poffset = 0; +} + /******************************************************************* Seek a dir. ********************************************************************/ @@ -1117,7 +1129,11 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) void SeekDir(struct smb_Dir *dirp, long offset) { if (offset != dirp->offset) { - SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); + if (offset == 0) { + RewindDir(dirp, &offset); + } else { + SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); + } dirp->offset = offset; } } -- cgit From 7e509e9b99a18495bde01a990e37de70bae35aac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Jun 2005 21:20:41 +0000 Subject: r7842: With the patch I sent Steve yesterday this gives us complete POSIX pathnames. ie. files containing : and \ can be accessed from Linux. Jeremy. (This used to be commit e9b8d23d6138d909a65ea70b2e801881e8333b38) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 072f396b8c..ae21e16e31 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -238,7 +238,7 @@ BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr) dptr->wcard = SMB_STRDUP(wcard); if (!dptr->wcard) return False; - if (wcard[0] == '.' && wcard[1] == 0) { + if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { dptr->has_wild = True; } else { dptr->has_wild = ms_has_wild(wcard); -- cgit From ff7e5c26733c933d0ed71616c39e2d931ad1e597 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Jun 2005 03:03:44 +0000 Subject: r7893: Add in the extra parameters to opendir() to fix the large directory/insane app problem. Rev vfs version. Doesn't change the normal codepath. Jeremy. (This used to be commit 0f03a6bdcdbdf60da81e0aeffa84ac6e48fc6a04) --- source3/smbd/dir.c | 69 ++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 39 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ae21e16e31..fd0a303504 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -53,7 +53,7 @@ struct dptr_struct { struct smb_Dir *dir_hnd; BOOL expect_close; char *wcard; - uint16 attr; + uint32 attr; char *path; BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ }; @@ -68,7 +68,7 @@ static int dirhandles_open = 0; Make a dir struct. ****************************************************************************/ -void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,int mode,time_t date, BOOL uc) +void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,uint32 mode,time_t date, BOOL uc) { char *p; pstring mask2; @@ -175,7 +175,7 @@ static struct dptr_struct *dptr_get(int key, BOOL forclose) if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); - if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) { + if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); return False; @@ -224,30 +224,6 @@ uint16 dptr_attr(int key) return(0); } -/**************************************************************************** - Set the dir wcard for a dir index. - Returns 0 on ok, 1 on fail. -****************************************************************************/ - -BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr) -{ - struct dptr_struct *dptr = dptr_get(key, False); - - if (dptr) { - dptr->attr = attr; - dptr->wcard = SMB_STRDUP(wcard); - if (!dptr->wcard) - return False; - if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { - dptr->has_wild = True; - } else { - dptr->has_wild = ms_has_wild(wcard); - } - return True; - } - return False; -} - /**************************************************************************** Close a dptr (internal func). ****************************************************************************/ @@ -399,7 +375,8 @@ static void dptr_close_oldest(BOOL old) a directory handle is never zero. ****************************************************************************/ -int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid) +int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, + const char *wcard, uint32 attr) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; @@ -415,7 +392,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp if (!*dir2) dir2 = "."; - dir_hnd = OpenDir(conn, dir2); + dir_hnd = OpenDir(conn, dir2, wcard, attr); if (!dir_hnd) { return (-2); } @@ -503,9 +480,23 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dptr->dir_hnd = dir_hnd; 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->has_wild = True; /* Only used in lanman2 searches */ + if (wcard) { + dptr->wcard = SMB_STRDUP(wcard); + if (!dptr->wcard) { + bitmap_clear(dptr_bmap, dptr->dnum - 1); + SAFE_FREE(dptr); + CloseDir(dir_hnd); + return -1; + } + } else { + dptr->wcard = NULL; + } + dptr->attr = attr; + if (lp_posix_pathnames() || (wcard && (wcard[0] == '.' && wcard[1] == 0))) { + dptr->has_wild = True; + } else { + dptr->has_wild = ms_has_wild(wcard); + } DLIST_ADD(dirptrs, dptr); @@ -715,9 +706,9 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) Check a filetype for being valid. ****************************************************************************/ -BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype) +BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) { - int mask; + uint32 mask; /* Check the "may have" search bits. */ if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0) @@ -747,8 +738,8 @@ static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *m Get an 8.3 directory entry. ****************************************************************************/ -BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname, - SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend) +BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fname, + SMB_OFF_T *size,uint32 *mode,time_t *date,BOOL check_descend) { const char *dname; BOOL found = False; @@ -804,7 +795,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname *mode = dos_mode(conn,pathreal,&sbuf); if (!dir_check_ftype(conn,*mode,dirtype)) { - DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype)); + DEBUG(5,("[%s] attribs didn't match %x\n",filename,(unsigned int)dirtype)); continue; } @@ -1000,7 +991,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * Open a directory. ********************************************************************/ -struct smb_Dir *OpenDir(connection_struct *conn, const char *name) +struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) { struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); if (!dirp) { @@ -1014,7 +1005,7 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name) if (!dirp->dir_path) { goto fail; } - dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path); + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); if (!dirp->dir) { DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); goto fail; -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/smbd/dir.c | 60 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 22 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index fd0a303504..949e31210f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -822,7 +822,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; - int smb_action; NTSTATUS status; uint32 access_granted; @@ -831,32 +830,41 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S * we never hide files from them. */ - if (conn->admin_user) + if (conn->admin_user) { return True; + } /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_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), - &smb_action); - else + if(S_ISDIR(pst->st_mode)) { + fsp = open_directory(conn, name, pst, + READ_CONTROL_ACCESS, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, /* no create options. */ + NULL); + } else { fsp = open_file_stat(conn, name, pst); + } - if (!fsp) + if (!fsp) { return False; + } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, True); /* No access if SD get failed. */ - if (!sd_size) + if (!sd_size) { return False; + } return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA, &access_granted, &status); @@ -874,8 +882,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ SEC_DESC *psd = NULL; size_t sd_size; files_struct *fsp; - int smb_action; - int access_mode; + int info; NTSTATUS status; uint32 access_granted; @@ -884,27 +891,36 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ * we never hide files from them. */ - if (conn->admin_user) + if (conn->admin_user) { return True; + } /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) + if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { return False; + } - /* Pseudo-open the file (note - no fd's created). */ + /* Pseudo-open the file */ - if(S_ISDIR(pst->st_mode)) + if(S_ISDIR(pst->st_mode)) { return True; - else - fsp = open_file_shared1(conn, name, pst, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE), - (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &access_mode, &smb_action); + } else { + fsp = open_file_ntcreate(conn, name, pst, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, + 0, + FILE_ATTRIBUTE_NORMAL, + INTERNAL_OPEN_ONLY, + &info); + } - if (!fsp) + if (!fsp) { return False; + } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fd, + sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, False); -- cgit From 87801bc387e60d8cac74a6fb59af30bfdcc7850d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Jul 2005 17:38:38 +0000 Subject: r8609: Fix for bugid #2889. I think the problem is that the top 16 bits of the "server state" field must be non-zero. As we're using the 32 bit field as an offset then normally this field will be zero. W2K3 fills this field with a counter enumerating the number of SMBsearch calls on this directory - starting at 1. Add back the 1<<31 bit flag DPTR_MASK to ensure this is non-zero - with better checks on use. Jeremy. (This used to be commit 6415657942c49ea51d4e4f4ee2189c7d70b9c5fa) --- source3/smbd/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 949e31210f..aeada5968f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -641,6 +641,8 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S Fill the 5 byte server reserved dptr field. ****************************************************************************/ +#define DPTR_MASK ((uint32)(((uint32)1)<<31)) + BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; @@ -653,8 +655,12 @@ BOOL dptr_fill(char *buf1,unsigned int key) offset = (uint32)TellDir(dptr->dir_hnd); DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, (long)dptr->dir_hnd,(int)offset)); + if (offset != (uint32)-1 && (offset & DPTR_MASK)) { + DEBUG(0,("dptr_fill: Error - offset has bit 32 set. Can't use in server state.\n")); + return False; + } buf[0] = key; - SIVAL(buf,1,offset); + SIVAL(buf,1,offset | DPTR_MASK); return(True); } @@ -678,7 +684,7 @@ struct dptr_struct *dptr_fetch(char *buf,int *num) if (offset == (uint32)-1) { seekoff = -1; } else { - seekoff = (long)offset; + seekoff = (long)(offset & ~DPTR_MASK); } SeekDir(dptr->dir_hnd,seekoff); DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", -- cgit From 78e3b4f04b424fce1e2a908dac214d00bec493cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Jul 2005 17:44:44 +0000 Subject: r8610: If I'm going to do a debug level zero, at least make it useful. Jeremy. (This used to be commit 99dae22dcf4050b5aacbb2cd4d2a08a183611402) --- source3/smbd/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index aeada5968f..4f59205feb 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -656,7 +656,8 @@ BOOL dptr_fill(char *buf1,unsigned int key) DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, (long)dptr->dir_hnd,(int)offset)); if (offset != (uint32)-1 && (offset & DPTR_MASK)) { - DEBUG(0,("dptr_fill: Error - offset has bit 32 set. Can't use in server state.\n")); + DEBUG(0,("dptr_fill: Error - offset 0x%x has bit 32 set. Can't use in server state.\n", + (unsigned int)offset )); return False; } buf[0] = key; -- cgit From aa63997c2341e565c8a81716ed44bca3d6c27798 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Jul 2005 18:21:38 +0000 Subject: r8655: Still trying to fix #2889. We don't need the DPTR_MASK after all, now thinking it might be to do with flags2... Jeremy. (This used to be commit a3ceabf7c678b5e7f77cc073cf535498ffc67eb6) --- source3/smbd/dir.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 4f59205feb..949e31210f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -641,8 +641,6 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S Fill the 5 byte server reserved dptr field. ****************************************************************************/ -#define DPTR_MASK ((uint32)(((uint32)1)<<31)) - BOOL dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; @@ -655,13 +653,8 @@ BOOL dptr_fill(char *buf1,unsigned int key) offset = (uint32)TellDir(dptr->dir_hnd); DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key, (long)dptr->dir_hnd,(int)offset)); - if (offset != (uint32)-1 && (offset & DPTR_MASK)) { - DEBUG(0,("dptr_fill: Error - offset 0x%x has bit 32 set. Can't use in server state.\n", - (unsigned int)offset )); - return False; - } buf[0] = key; - SIVAL(buf,1,offset | DPTR_MASK); + SIVAL(buf,1,offset); return(True); } @@ -685,7 +678,7 @@ struct dptr_struct *dptr_fetch(char *buf,int *num) if (offset == (uint32)-1) { seekoff = -1; } else { - seekoff = (long)(offset & ~DPTR_MASK); + seekoff = (long)offset; } SeekDir(dptr->dir_hnd,seekoff); DEBUG(3,("fetching dirptr %d for path %s at offset %d\n", -- cgit From 58a3749e9c4393330c1c795b689ffb98c0aae381 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 Jul 2005 20:24:21 +0000 Subject: r8689: Fixes bugid #2889 for sure. Turns out the OS/2 dos box doesn't like two offsets to be identical. Make offsets for . and .. different (and explicit). Jeremy. (This used to be commit 217cc66e46b3df35a66fed4055bd5032aab4d73f) --- source3/smbd/dir.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 949e31210f..a0df924dc7 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -26,6 +26,11 @@ extern struct current_user current_user; +/* "Special" directory offsets. */ +#define END_OF_DIRECTORY_OFFSET ((long)-1) +#define START_OF_DIRECTORY_OFFSET ((long)0) +#define DOT_DOT_DIRECTORY_OFFSET ((long)0x80000000) + /* Make directory handle internals available. */ #define NAME_CACHE_SIZE 100 @@ -560,7 +565,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT /* If poffset is -1 then we know we returned this name before and we have no wildcards. We're at the end of the directory. */ - if (*poffset == -1) { + if (*poffset == END_OF_DIRECTORY_OFFSET) { return NULL; } @@ -577,7 +582,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT if (VALID_STAT(*pst)) { /* We need to set the underlying dir_hdn offset to -1 also as this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = -1; + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; return dptr->wcard; } @@ -588,7 +593,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { /* We need to set the underlying dir_hdn offset to -1 also as this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = -1; + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; return dptr->wcard; } else { /* If we get any other error than ENOENT or ENOTDIR @@ -596,7 +601,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT if (errno != ENOENT && errno != ENOTDIR) { /* We need to set the underlying dir_hdn offset to -1 also as this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = -1; + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; return dptr->wcard; } } @@ -607,7 +612,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT if (dptr->conn->case_sensitive) { /* We need to set the underlying dir_hdn offset to -1 also as this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = -1; + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; return NULL; } else { dptr->has_wild = True; @@ -623,9 +628,9 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S { SET_STAT_INVALID(*pst); - if (!dptr->has_wild && (dptr->dir_hnd->offset == -1)) { + if (!dptr->has_wild && (dptr->dir_hnd->offset == END_OF_DIRECTORY_OFFSET)) { /* This is a singleton directory and we're already at the end. */ - *poffset = -1; + *poffset = END_OF_DIRECTORY_OFFSET; return False; } @@ -676,7 +681,7 @@ struct dptr_struct *dptr_fetch(char *buf,int *num) *num = key; offset = IVAL(buf,1); if (offset == (uint32)-1) { - seekoff = -1; + seekoff = END_OF_DIRECTORY_OFFSET; } else { seekoff = (long)offset; } @@ -1083,10 +1088,12 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) connection_struct *conn = dirp->conn; /* Cheat to allow . and .. to be the first entries returned. */ - if ((*poffset == 0) && (dirp->file_number < 2)) { + if (((*poffset == START_OF_DIRECTORY_OFFSET) || (*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2)) { if (dirp->file_number == 0) { n = "."; + *poffset = dirp->offset = START_OF_DIRECTORY_OFFSET; } else { + *poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET; n = ".."; } dirp->file_number++; @@ -1113,7 +1120,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) dirp->file_number++; return e->name; } - dirp->offset = -1; + dirp->offset = END_OF_DIRECTORY_OFFSET; return NULL; } @@ -1125,8 +1132,8 @@ void RewindDir(struct smb_Dir *dirp, long *poffset) { SMB_VFS_REWINDDIR(dirp->conn, dirp->dir); dirp->file_number = 0; - dirp->offset = 0; - *poffset = 0; + dirp->offset = START_OF_DIRECTORY_OFFSET; + *poffset = START_OF_DIRECTORY_OFFSET; } /******************************************************************* @@ -1136,7 +1143,7 @@ void RewindDir(struct smb_Dir *dirp, long *poffset) void SeekDir(struct smb_Dir *dirp, long offset) { if (offset != dirp->offset) { - if (offset == 0) { + if (offset == START_OF_DIRECTORY_OFFSET || offset == DOT_DOT_DIRECTORY_OFFSET) { RewindDir(dirp, &offset); } else { SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); @@ -1186,7 +1193,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) /* Not found in the name cache. Rewind directory and start from scratch. */ SMB_VFS_REWINDDIR(conn, dirp->dir); dirp->file_number = 0; - *poffset = 0; + *poffset = START_OF_DIRECTORY_OFFSET; while ((entry = ReadDirName(dirp, poffset))) { if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) { return True; -- cgit From 15b842d401beebc304c98e855c33421782c51a85 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Aug 2005 23:45:16 +0000 Subject: r9286: Fix false positive found by Coverity - wcard must not be null. Jeremy. (This used to be commit 31104e5bcfffdd48071b2062809313679f29961f) --- source3/smbd/dir.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index a0df924dc7..159ce37236 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -378,6 +378,7 @@ static void dptr_close_oldest(BOOL old) one byte long. If old_handle is false we allocate from the range 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure a directory handle is never zero. + wcard must not be zero. ****************************************************************************/ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, @@ -389,6 +390,10 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp DEBUG(5,("dptr_create dir=%s\n", path)); + if (!wcard) { + return -1; + } + if (!check_name(path,conn)) return(-2); /* Code to say use a unix error return code. */ @@ -485,24 +490,21 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dptr->dir_hnd = dir_hnd; dptr->spid = spid; dptr->expect_close = expect_close; - if (wcard) { - dptr->wcard = SMB_STRDUP(wcard); - if (!dptr->wcard) { - bitmap_clear(dptr_bmap, dptr->dnum - 1); - SAFE_FREE(dptr); - CloseDir(dir_hnd); - return -1; - } - } else { - dptr->wcard = NULL; + dptr->wcard = SMB_STRDUP(wcard); + if (!dptr->wcard) { + bitmap_clear(dptr_bmap, dptr->dnum - 1); + SAFE_FREE(dptr); + CloseDir(dir_hnd); + return -1; } - dptr->attr = attr; - if (lp_posix_pathnames() || (wcard && (wcard[0] == '.' && wcard[1] == 0))) { + if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { dptr->has_wild = True; } else { dptr->has_wild = ms_has_wild(wcard); } + dptr->attr = attr; + DLIST_ADD(dirptrs, dptr); DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", -- cgit From f069f96a1fd96f760597bdfd04968bd6ab2ff5b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 21 Aug 2005 21:12:27 +0000 Subject: r9457: Attempt to fix bug #3010 by handling END_OF_DIRECTORY_OFFSET consistently. Jeremy. (This used to be commit ac8f22a328d878f064277638d63446bf68b68dfd) --- source3/smbd/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 159ce37236..f722bedecb 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1100,6 +1100,9 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) } dirp->file_number++; return n; + } else if (*poffset == END_OF_DIRECTORY_OFFSET) { + *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET; + return NULL; } else { /* A real offset, seek to it. */ SeekDir(dirp, *poffset); @@ -1122,7 +1125,7 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) dirp->file_number++; return e->name; } - dirp->offset = END_OF_DIRECTORY_OFFSET; + *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET; return NULL; } @@ -1147,6 +1150,8 @@ void SeekDir(struct smb_Dir *dirp, long offset) if (offset != dirp->offset) { if (offset == START_OF_DIRECTORY_OFFSET || offset == DOT_DOT_DIRECTORY_OFFSET) { RewindDir(dirp, &offset); + } else if (offset == END_OF_DIRECTORY_OFFSET) { + ; /* Don't seek in this case. */ } else { SMB_VFS_SEEKDIR(dirp->conn, dirp->dir, offset); } -- cgit From f98f86394a654722fa13ef1dc3c4dea82d452442 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 22 Aug 2005 18:03:08 +0000 Subject: r9483: Changed DIR to SMB_STRUCT_DIR because of the amazing stupidity of a UNIX vendor not understanding abstract data types :-(. Jeremy. (This used to be commit be5b4e2fa3ed30b0ff01b47d2354e5f782a12e25) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f722bedecb..02e15d222a 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -42,7 +42,7 @@ struct name_cache_entry { struct smb_Dir { connection_struct *conn; - DIR *dir; + SMB_STRUCT_DIR *dir; long offset; char *dir_path; struct name_cache_entry *name_cache; -- cgit From 22f603ac567f369b544267c5e891d282dd3e2dfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Sep 2005 20:41:22 +0000 Subject: r10558: Fix bug #3010 yet again. Die monster, die ! Jeremy. (This used to be commit dba56e8d23dc10a31f0f700b02c8776bdc8f57c1) --- source3/smbd/dir.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 02e15d222a..70a3b81ad6 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1148,8 +1148,23 @@ void RewindDir(struct smb_Dir *dirp, long *poffset) void SeekDir(struct smb_Dir *dirp, long offset) { if (offset != dirp->offset) { - if (offset == START_OF_DIRECTORY_OFFSET || offset == DOT_DOT_DIRECTORY_OFFSET) { + if (offset == START_OF_DIRECTORY_OFFSET) { RewindDir(dirp, &offset); + /* + * Ok we should really set the file number here + * to 1 to enable ".." to be returned next. Trouble + * is I'm worried about callers using SeekDir(dirp,0) + * as equivalent to RewindDir(). So leave this alone + * for now. + */ + } else if (offset == DOT_DOT_DIRECTORY_OFFSET) { + RewindDir(dirp, &offset); + /* + * Set the file number to 2 - we want to get the first + * real file entry (the one we return after "..") + * on the next ReadDir. + */ + dirp->file_number = 2; } else if (offset == END_OF_DIRECTORY_OFFSET) { ; /* Don't seek in this case. */ } else { -- cgit From 6baec64a7370ff1871f0b806a623b1fc1a898acb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Oct 2005 20:11:58 +0000 Subject: r11420: Fix issue pointed out by Dina Fine . We can only tell at parse time from the wire if an incoming name has wildcards or not. If it's a mangled name and we demangle the demangled name may contain wildcard characters. Ensure these are ignored. Jeremy. (This used to be commit 4cd8e2a96b98ff711905e8c6f416b22440c16062) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 70a3b81ad6..7ea97e69b0 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -382,7 +382,7 @@ static void dptr_close_oldest(BOOL old) ****************************************************************************/ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, - const char *wcard, uint32 attr) + const char *wcard, BOOL wcard_has_wild, uint32 attr) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; @@ -500,7 +500,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { dptr->has_wild = True; } else { - dptr->has_wild = ms_has_wild(wcard); + dptr->has_wild = wcard_has_wild; } dptr->attr = attr; -- cgit From 6d5757395a0e54245543794d0d6d6d6a32cd857a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Nov 2005 04:21:55 +0000 Subject: r11511: A classic "friday night check-in" :-). This moves much of the Samba4 timezone handling code back into Samba3. Gets rid of "kludge-gmt" and removes the effectiveness of the parameter "time offset" (I can add this back in very easily if needed) - it's no longer being looked at. I'm hoping this will fix the problems people have been having with DST transitions. I'll start comprehensive testing tomorrow, but for now all modifications are done. Splits time get/set functions into srv_XXX and cli_XXX as they need to look at different timezone offsets. Get rid of much of the "efficiency" cruft that was added to Samba back in the day when the C library timezone handling functions were slow. Jeremy. (This used to be commit 414303bc0272f207046b471a0364fa296b67c1f8) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7ea97e69b0..c993012a25 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -94,7 +94,7 @@ void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T si memset(buf+21,'\0',DIR_STRUCT_SIZE-21); SCVAL(buf,21,mode); - put_dos_date(buf,22,date); + srv_put_dos_date(buf,22,date); SSVAL(buf,26,size & 0xFFFF); SSVAL(buf,28,(size >> 16)&0xFFFF); /* We only uppercase if FLAGS2_LONG_PATH_COMPONENTS is zero in the input buf. -- cgit From 5a06869da700261b97c62b20802f17cf5277cba8 Mon Sep 17 00:00:00 2001 From: Paul Green Date: Thu, 10 Nov 2005 21:34:25 +0000 Subject: r11657: Tiny improvement to debug error message in dir_check_ftype. (This used to be commit 46674ca21d9c257bc48af97e313b49118c7b478d) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index c993012a25..0635db22db 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -802,7 +802,7 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn *mode = dos_mode(conn,pathreal,&sbuf); if (!dir_check_ftype(conn,*mode,dirtype)) { - DEBUG(5,("[%s] attribs didn't match %x\n",filename,(unsigned int)dirtype)); + DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype)); continue; } -- cgit From d14af63e6ab600eb3ac705f2f425c860e927553a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 20:44:50 +0000 Subject: r13293: Rather a big patch I'm afraid, but this should fix bug #3347 by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 0635db22db..81fe7c4021 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -866,7 +866,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, True); + close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ if (!sd_size) { @@ -929,7 +929,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, False); + close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ if (!sd_size) -- cgit From 876f2deb3a6029b4e02ec25bc3099bfa07840a14 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 8 Apr 2006 05:00:04 +0000 Subject: r14986: Fix OS/2 directory delete bug found by kukks. (Thanks a lot for all your hard work on this). We were caching the results of *all* directory scans, not just the results that match the client wildcard. This actually made no sense, as only matches on the client wildcard can be returned to the client and so might need to be searched for in the cache. This fixes the directory cache to only cache entries that we return to the client. Jeremy. (This used to be commit c88af597d042390ff11b26fe802b0b10d0faa6ce) --- source3/smbd/dir.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 81fe7c4021..cd6c1b0bda 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -644,6 +644,15 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S return False; } +/**************************************************************************** + Add the name we're returning into the underlying cache. +****************************************************************************/ + +void dptr_DirCacheAdd(struct dptr_struct *dptr, const char *name, long offset) +{ + DirCacheAdd(dptr->dir_hnd, name, offset); +} + /**************************************************************************** Fill the 5 byte server reserved dptr field. ****************************************************************************/ @@ -812,6 +821,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); found = True; + + DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff); } } @@ -1109,21 +1120,15 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset) } while ((n = vfs_readdirname(conn, dirp->dir))) { - struct name_cache_entry *e; /* Ignore . and .. - we've already returned them. */ if (*n == '.') { if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) { continue; } } - dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); - dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; - e = &dirp->name_cache[dirp->name_cache_index]; - SAFE_FREE(e->name); - e->name = SMB_STRDUP(n); - *poffset = e->offset= dirp->offset; + *poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir); dirp->file_number++; - return e->name; + return n; } *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET; return NULL; @@ -1183,6 +1188,21 @@ long TellDir(struct smb_Dir *dirp) return(dirp->offset); } +/******************************************************************* + Add an entry into the dcache. +********************************************************************/ + +void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) +{ + struct name_cache_entry *e; + + dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; + e = &dirp->name_cache[dirp->name_cache_index]; + SAFE_FREE(e->name); + e->name = SMB_STRDUP(name); + e->offset = offset; +} + /******************************************************************* Find an entry by name. Leave us at the offset after it. Don't check for veto or invisible files. -- cgit From e18c9a926f43853594a00db89167f698466b10ee Mon Sep 17 00:00:00 2001 From: Paul Green Date: Mon, 24 Apr 2006 10:45:06 +0000 Subject: r15196: Update a comment that I found confusing (I confuse easily). (This used to be commit eb53f01863f8f9d2980d9c2c8d27899dd39e5fa2) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index cd6c1b0bda..27a4182c22 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -719,7 +719,7 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) } /**************************************************************************** - Check a filetype for being valid. + Check that a file matches a particular file type. ****************************************************************************/ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) -- cgit From a24c4049670e6837705ac7013c7d2da596a95f6a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 26 Jun 2006 23:36:03 +0000 Subject: r16537: Fix for bug #3858, all files in a directory not being deleted when hide unreadable set to true. Here's the scoop. This one is really interesting. The pattern of deleting a directory is to do a findfirst to get the first part of the list, then for each name returned it does a open/set delete on close/close -> thus deleting the file. Then it does a findnext with the last file name THAT IT JUST DELETED ! Now we can handle this in the findnext in the case where hide unreadable is set to false as we look back in our cache of names and just seek to the right point. The bug is actually fixed in the first hunk of this patch - the one that removes the is_visible_file() check after SearchDir returns false. We don't actually need it and in this case it's causing the delete to be aborted because it can't find the name (doh ! it was just deleted). We don't need it as SearchDir is only ever called from findnext, and findnext should only ever be returning names we gave it. The rest of the patch are the debugs I used to find the problem but they're generically useful. Phew - that one took a while to track down..... Jerry, please merge for 3.0.23 final. Jeremy. (This used to be commit cd048cb775f0a8525fc19aa463db07c477521f5b) --- source3/smbd/dir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 27a4182c22..5ba9e1ed57 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -636,12 +636,7 @@ BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, S return False; } - if (SearchDir(dptr->dir_hnd, name, poffset)) { - if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) { - return True; - } - } - return False; + return SearchDir(dptr->dir_hnd, name, poffset); } /**************************************************************************** @@ -854,6 +849,8 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* If we can't stat it does not show it */ if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { + DEBUG(10,("user_can_read_file: SMB_VFS_STAT failed for file %s with error %s\n", + name, strerror(errno) )); return False; } @@ -992,6 +989,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * /* If it's a vetoed file, pretend it doesn't even exist */ if (use_veto && IS_VETO_PATH(conn, name)) { + DEBUG(10,("is_visible_file: file %s is vetoed.\n", name )); return False; } @@ -1003,16 +1001,19 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * } /* Honour _hide unreadable_ option */ if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { + DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); SAFE_FREE(entry); return False; } /* Honour _hide unwriteable_ option */ if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) { + DEBUG(10,("is_visible_file: file %s is unwritable.\n", entry )); SAFE_FREE(entry); return False; } /* Honour _hide_special_ option */ if (hide_special && file_is_special(conn, entry, pst)) { + DEBUG(10,("is_visible_file: file %s is special.\n", entry )); SAFE_FREE(entry); return False; } -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/dir.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5ba9e1ed57..96e0923dbd 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -741,7 +741,7 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) { - mangle_map(filename,True,False,SNUM(conn)); + mangle_map(filename,True,False,conn->params); return mask_match_search(filename,mask,False); } @@ -787,8 +787,9 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { - if (!mangle_is_8_3(filename, False, SNUM(conn))) - mangle_map(filename,True,False,SNUM(conn)); + if (!mangle_is_8_3(filename, False, conn->params)) + mangle_map(filename,True,False, + conn->params); pstrcpy(fname,filename); *path = 0; @@ -857,17 +858,17 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(pst->st_mode)) { - fsp = open_directory(conn, name, pst, + status = open_directory(conn, name, pst, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, /* no create options. */ - NULL); + NULL, &fsp); } else { - fsp = open_file_stat(conn, name, pst); + status = open_file_stat(conn, name, pst, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } @@ -920,17 +921,17 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ if(S_ISDIR(pst->st_mode)) { return True; } else { - fsp = open_file_ntcreate(conn, name, pst, + status = open_file_ntcreate(conn, name, pst, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, - &info); + &info, &fsp); } - if (!fsp) { + if (!NT_STATUS_IS_OK(status)) { return False; } -- cgit From 315ad641c381b0630976eff711f251d1831ffc7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Sep 2006 09:06:36 +0000 Subject: r18547: Add in fixes to mangling dir code - ensure don't look in the paths for wcard - always read directly from incoming packet. Jeremy. (This used to be commit 3745a1af4ea9262fcda28931539fa6ab4c9060d1) --- source3/smbd/dir.c | 91 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 40 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 96e0923dbd..1c77630ee7 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -61,6 +61,7 @@ struct dptr_struct { uint32 attr; char *path; BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ + BOOL did_stat; /* Optimisation for non-wcard searches. */ }; static struct bitmap *dptr_bmap; @@ -535,6 +536,11 @@ long dptr_TellDir(struct dptr_struct *dptr) return TellDir(dptr->dir_hnd); } +BOOL dptr_has_wild(struct dptr_struct *dptr) +{ + return dptr->has_wild; +} + /**************************************************************************** Return the next visible file name, skipping veto'd and invisible files. ****************************************************************************/ @@ -557,8 +563,6 @@ static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffs const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) { - pstring pathreal; - SET_STAT_INVALID(*pst); if (dptr->has_wild) { @@ -571,55 +575,62 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT return NULL; } - /* We know the stored wcard contains no wildcard characters. See if we can match - with a stat call. If we can't, then set has_wild to true to - prevent us from doing this on every call. */ + if (!dptr->did_stat) { + pstring pathreal; - /* First check if it should be visible. */ - if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) { - dptr->has_wild = True; - return dptr_normal_ReadDirName(dptr, poffset, pst); - } + /* We know the stored wcard contains no wildcard characters. See if we can match + with a stat call. If we can't, then set did_stat to true to + ensure we only do this once and keep searching. */ - if (VALID_STAT(*pst)) { - /* We need to set the underlying dir_hdn offset to -1 also as - this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; - return dptr->wcard; - } + dptr->did_stat = True; - pstrcpy(pathreal,dptr->path); - pstrcat(pathreal,"/"); - pstrcat(pathreal,dptr->wcard); + /* First check if it should be visible. */ + if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) { + /* This only returns False if the file was found, but + is explicitly not visible. Set us to end of directory, + but return NULL as we know we can't ever find it. */ + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + return NULL; + } - if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { - /* We need to set the underlying dir_hdn offset to -1 also as - this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; - return dptr->wcard; - } else { - /* If we get any other error than ENOENT or ENOTDIR - then the file exists we just can't stat it. */ - if (errno != ENOENT && errno != ENOTDIR) { - /* We need to set the underlying dir_hdn offset to -1 also as + if (VALID_STAT(*pst)) { + /* We need to set the underlying dir_hnd offset to -1 also as this function is usually called with the output from TellDir. */ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; return dptr->wcard; } - } - /* In case sensitive mode we don't search - we know if it doesn't exist - with a stat we will fail. */ + pstrcpy(pathreal,dptr->path); + pstrcat(pathreal,"/"); + pstrcat(pathreal,dptr->wcard); - if (dptr->conn->case_sensitive) { - /* We need to set the underlying dir_hdn offset to -1 also as - this function is usually called with the output from TellDir. */ - dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; - return NULL; - } else { - dptr->has_wild = True; - return dptr_normal_ReadDirName(dptr, poffset, pst); + if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { + /* We need to set the underlying dir_hnd offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + return dptr->wcard; + } else { + /* If we get any other error than ENOENT or ENOTDIR + then the file exists we just can't stat it. */ + if (errno != ENOENT && errno != ENOTDIR) { + /* We need to set the underlying dir_hdn offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + return dptr->wcard; + } + } + + /* In case sensitive mode we don't search - we know if it doesn't exist + with a stat we will fail. */ + + if (dptr->conn->case_sensitive) { + /* We need to set the underlying dir_hnd offset to -1 also as + this function is usually called with the output from TellDir. */ + dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + return NULL; + } } + return dptr_normal_ReadDirName(dptr, poffset, pst); } /**************************************************************************** -- cgit From 8e6390a1604da9e34f1f6823399687bf38cd7380 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Dec 2006 20:39:53 +0000 Subject: r20411: Fix originally from SATOH Fumiyasu (slightly modified). Ensure "hide unXXX" parameters don't hide MSDFS links. Bug #3319. Jeremy. (This used to be commit e5466fffc286a99fafe0fcfbf70e903e33baa7f9) --- source3/smbd/dir.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 1c77630ee7..5a6b9713e5 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1011,6 +1011,18 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * if (asprintf(&entry, "%s/%s", dir_path, name) == -1) { return False; } + + /* If it's a dfs symlink, ignore _hide xxxx_ options */ + if (lp_host_msdfs() && + lp_msdfs_root(SNUM(conn)) && + /* We get away with NULL talloc ctx here as + we're not interested in the link contents + so we have nothing to free. */ + is_msdfs_link(NULL, conn, entry, NULL, NULL, NULL)) { + SAFE_FREE(entry); + return True; + } + /* Honour _hide unreadable_ option */ if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); -- cgit From 83eb0d1d6d90d182e8eee8496695113c89f8dba1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 02:09:37 +0000 Subject: r20844: Somewhat radical change - this may break the build (I will watch carefully - so I'm doing it in one transaction so I can roll back). Change check_name(), reduce_name() and dptr_create() to return NTSTATUS. This helps a lot in error path processing and especially in reduce_name() allows us to ditch the flaky and error-prone saving of errno and return errors directly. Jeremy. (This used to be commit 6133a694aa429d638320e39ffe1c49d172583ccf) --- source3/smbd/dir.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5a6b9713e5..7be5c03f1b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -382,21 +382,26 @@ static void dptr_close_oldest(BOOL old) wcard must not be zero. ****************************************************************************/ -int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, - const char *wcard, BOOL wcard_has_wild, uint32 attr) +NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, + const char *wcard, BOOL wcard_has_wild, uint32 attr, int *dptr_hnd_ret) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; const char *dir2; + NTSTATUS status; DEBUG(5,("dptr_create dir=%s\n", path)); + *dptr_hnd_ret = -1; + if (!wcard) { - return -1; + return NT_STATUS_INVALID_PARAMETER; } - if (!check_name(path,conn)) - return(-2); /* Code to say use a unix error return code. */ + status = check_name(conn,path); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* use a const pointer from here on */ dir2 = path; @@ -405,19 +410,20 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dir_hnd = OpenDir(conn, dir2, wcard, attr); if (!dir_hnd) { - return (-2); + return map_nt_error_from_unix(errno); } string_set(&conn->dirpath,dir2); - if (dirhandles_open >= MAX_OPEN_DIRECTORIES) + if (dirhandles_open >= MAX_OPEN_DIRECTORIES) { dptr_idleoldest(); + } dptr = SMB_MALLOC_P(struct dptr_struct); if(!dptr) { DEBUG(0,("malloc fail in dptr_create.\n")); CloseDir(dir_hnd); - return -1; + return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(dptr); @@ -447,7 +453,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); SAFE_FREE(dptr); CloseDir(dir_hnd); - return -1; + return NT_STATUS_TOO_MANY_OPENED_FILES; } } } else { @@ -477,7 +483,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum)); SAFE_FREE(dptr); CloseDir(dir_hnd); - return -1; + return NT_STATUS_TOO_MANY_OPENED_FILES; } } } @@ -496,7 +502,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp bitmap_clear(dptr_bmap, dptr->dnum - 1); SAFE_FREE(dptr); CloseDir(dir_hnd); - return -1; + return NT_STATUS_NO_MEMORY; } if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { dptr->has_wild = True; @@ -513,7 +519,8 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp conn->dirptr = dptr; - return(dptr->dnum); + *dptr_hnd_ret = dptr->dnum; + return NT_STATUS_OK; } -- cgit From fd37f98158161406229b728a7c767121a30e254f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jan 2007 06:19:24 +0000 Subject: r20873: Some correctness fixes w.r.t. Samba4 torture BASE-DELETE. Allow us to correctly refuse to set delete on close on a non-empty directory. There are still some delete-on-close wrinkles to be fixed, but I understand how to do that better now. I'll fix this tomorrow. Jeremy. (This used to be commit 029635885825a5562e7974a6f5675cce3bf1b5dc) --- source3/smbd/dir.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7be5c03f1b..98356882aa 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -383,7 +383,7 @@ static void dptr_close_oldest(BOOL old) ****************************************************************************/ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, - const char *wcard, BOOL wcard_has_wild, uint32 attr, int *dptr_hnd_ret) + const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; @@ -392,8 +392,6 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO DEBUG(5,("dptr_create dir=%s\n", path)); - *dptr_hnd_ret = -1; - if (!wcard) { return NT_STATUS_INVALID_PARAMETER; } @@ -517,9 +515,8 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", dptr->dnum,path,expect_close)); - conn->dirptr = dptr; + *dptr_ret = dptr; - *dptr_hnd_ret = dptr->dnum; return NT_STATUS_OK; } @@ -530,6 +527,7 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO int dptr_CloseDir(struct dptr_struct *dptr) { + DLIST_REMOVE(dirptrs, dptr); return CloseDir(dptr->dir_hnd); } @@ -548,6 +546,11 @@ BOOL dptr_has_wild(struct dptr_struct *dptr) return dptr->has_wild; } +int dptr_dnum(struct dptr_struct *dptr) +{ + return dptr->dnum; +} + /**************************************************************************** Return the next visible file name, skipping veto'd and invisible files. ****************************************************************************/ -- cgit From 7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Feb 2007 21:05:34 +0000 Subject: r21191: Add in the POSIX open/mkdir/unlink calls. Move more error code returns to NTSTATUS. Client test code to follow... See if this passes the build-farm before I add it into 3.0.25. Jeremy. (This used to be commit 83dbbdff345fa9e427c9579183f4380004bf3dd7) --- source3/smbd/dir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 98356882aa..9f0350fe6d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -884,6 +884,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, /* no create options. */ + FILE_ATTRIBUTE_DIRECTORY, NULL, &fsp); } else { status = open_file_stat(conn, name, pst, &fsp); -- cgit From 86e5659abac9938e7ac0cea989ca33e807b3e181 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Feb 2007 02:03:39 +0000 Subject: r21257: Better fix for bug #4188 : Windows Vista RC1 and RC2 can't delete directory on Samba share based on work by Joe Meadows . Jeremy. (This used to be commit 2dab8928769938ab79da7b7ce2d165fc388f9b00) --- source3/smbd/dir.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 9f0350fe6d..2795b2a24b 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1279,3 +1279,42 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) } return False; } + +/***************************************************************** + Is this directory empty ? +*****************************************************************/ + +NTSTATUS can_delete_directory(struct connection_struct *conn, + const char *dirname) +{ + NTSTATUS status = NT_STATUS_OK; + long dirpos = 0; + const char *dname; + struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0); + + if (!dir_hnd) { + return map_nt_error_from_unix(errno); + } + + while ((dname = ReadDirName(dir_hnd,&dirpos))) { + SMB_STRUCT_STAT st; + + /* Quick check for "." and ".." */ + if (dname[0] == '.') { + if (!dname[1] || (dname[1] == '.' && !dname[2])) { + continue; + } + } + + if (!is_visible_file(conn, dirname, dname, &st, True)) { + continue; + } + + DEBUG(10,("can_delete_directory: got name %s - can't delete\n", dname )); + status = NT_STATUS_DIRECTORY_NOT_EMPTY; + break; + } + CloseDir(dir_hnd); + + return status; +} -- cgit From 24cdd7c73389c9eed981313973df2c3595222781 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Mar 2007 17:55:24 +0000 Subject: r21800: Check-in the DFS rewrite. I am still testing this but it works from smbclient and Windows, and I am promising to support and fix both client and server code moving forward. Still need to test the RPC admin support but I haven't changed that code. Jeremy. (This used to be commit 7a7862c01d07796ef206b255c676ad7dc2cc42fc) --- source3/smbd/dir.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2795b2a24b..db3e155ae4 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1017,6 +1017,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * } if (hide_unreadable || hide_unwriteable || hide_special) { + pstring link_target; char *entry = NULL; if (asprintf(&entry, "%s/%s", dir_path, name) == -1) { @@ -1026,10 +1027,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * /* If it's a dfs symlink, ignore _hide xxxx_ options */ if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && - /* We get away with NULL talloc ctx here as - we're not interested in the link contents - so we have nothing to free. */ - is_msdfs_link(NULL, conn, entry, NULL, NULL, NULL)) { + is_msdfs_link(conn, entry, link_target, NULL)) { SAFE_FREE(entry); return True; } -- cgit From 0bc56a2e5ffd0e65e4770e10c80d9fec02950b36 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jul 2007 16:26:27 +0000 Subject: r23724: Reduce access to the global inbuf a tiny bit. Add a struct smb_request that contains some of the fields from the SMB header, removing the need to access inbuf directly. This right now is used only in the open file code & friends, and creating that header is only done when needed. This needs more work, but it is a start. Jeremy, I'm only checking this into 3_0, please review before I merge it to _26. Volker (This used to be commit ca988f4e79e977160d82e86486972afd15d4acf5) --- source3/smbd/dir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index db3e155ae4..e7baf2b759 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -879,7 +879,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S /* Pseudo-open the file (note - no fd's created). */ if(S_ISDIR(pst->st_mode)) { - status = open_directory(conn, name, pst, + status = open_directory(conn, NULL, name, pst, READ_CONTROL_ACCESS, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, @@ -887,7 +887,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S FILE_ATTRIBUTE_DIRECTORY, NULL, &fsp); } else { - status = open_file_stat(conn, name, pst, &fsp); + status = open_file_stat(conn, NULL, name, pst, &fsp); } if (!NT_STATUS_IS_OK(status)) { @@ -943,7 +943,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ if(S_ISDIR(pst->st_mode)) { return True; } else { - status = open_file_ntcreate(conn, name, pst, + status = open_file_ntcreate(conn, NULL, name, pst, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index e7baf2b759..074fe6aed6 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 074fe6aed6..30c1d77a84 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From f1041f98ced8ef50373ca37d541d7ca8b1d46638 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Aug 2007 21:53:00 +0000 Subject: r24639: Add parameter "directory name cache size" - parameterize use of directory name cache, 100 by default. Will be needed to turn this off for *BSD systems. Jeremy. (This used to be commit bea8e9840fd65268e649f813eba10502b0c4d721) --- source3/smbd/dir.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 30c1d77a84..eec8fa12ef 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -32,8 +32,6 @@ extern struct current_user current_user; /* Make directory handle internals available. */ -#define NAME_CACHE_SIZE 100 - struct name_cache_entry { char *name; long offset; @@ -44,6 +42,7 @@ struct smb_Dir { SMB_STRUCT_DIR *dir; long offset; char *dir_path; + size_t name_cache_size; struct name_cache_entry *name_cache; unsigned int name_cache_index; unsigned int file_number; @@ -1061,12 +1060,14 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) { struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); + if (!dirp) { return NULL; } ZERO_STRUCTP(dirp); dirp->conn = conn; + dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); dirp->dir_path = SMB_STRDUP(name); if (!dirp->dir_path) { @@ -1078,9 +1079,14 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *m goto fail; } - dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, NAME_CACHE_SIZE); - if (!dirp->name_cache) { - goto fail; + if (dirp->name_cache_size) { + dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, + dirp->name_cache_size); + if (!dirp->name_cache) { + goto fail; + } + } else { + dirp->name_cache = NULL; } dirhandles_open++; @@ -1113,7 +1119,7 @@ int CloseDir(struct smb_Dir *dirp) } SAFE_FREE(dirp->dir_path); if (dirp->name_cache) { - for (i = 0; i < NAME_CACHE_SIZE; i++) { + for (i = 0; i < dirp->name_cache_size; i++) { SAFE_FREE(dirp->name_cache[i].name); } } @@ -1229,7 +1235,12 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) { struct name_cache_entry *e; - dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; + if (!dirp->name_cache_size || !dirp->name_cache) { + return; + } + + dirp->name_cache_index = (dirp->name_cache_index+1) % + dirp->name_cache_size; e = &dirp->name_cache[dirp->name_cache_index]; SAFE_FREE(e->name); e->name = SMB_STRDUP(name); @@ -1248,20 +1259,22 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) connection_struct *conn = dirp->conn; /* Search back in the name cache. */ - for (i = dirp->name_cache_index; i >= 0; i--) { - struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { - *poffset = e->offset; - SeekDir(dirp, e->offset); - return True; + if (dirp->name_cache_size && dirp->name_cache) { + for (i = dirp->name_cache_index; i >= 0; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + SeekDir(dirp, e->offset); + return True; + } } - } - for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) { - struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { - *poffset = e->offset; - SeekDir(dirp, e->offset); - return True; + for (i = dirp->name_cache_size - 1; i > dirp->name_cache_index; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + SeekDir(dirp, e->offset); + return True; + } } } -- cgit From 132ee3990af5d31573978f5a3abf43db2303880b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Sep 2007 20:57:01 +0000 Subject: r25009: Large patch discussed with Volker. Move unix_convert to a talloc-based interface. More development will come on top of this. Remove the "mangled map" parameter. Jeremy. (This used to be commit dee8beba7a92b8a3f68bbcc59fd0a827f68c7736) --- source3/smbd/dir.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index eec8fa12ef..e602008b8f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -380,12 +380,11 @@ static void dptr_close_oldest(BOOL old) wcard must not be zero. ****************************************************************************/ -NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, +NTSTATUS dptr_create(connection_struct *conn, const char *path, BOOL old_handle, BOOL expect_close,uint16 spid, const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; - const char *dir2; NTSTATUS status; DEBUG(5,("dptr_create dir=%s\n", path)); @@ -399,17 +398,12 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO return status; } - /* use a const pointer from here on */ - dir2 = path; - if (!*dir2) - dir2 = "."; - - dir_hnd = OpenDir(conn, dir2, wcard, attr); + dir_hnd = OpenDir(conn, path, wcard, attr); if (!dir_hnd) { return map_nt_error_from_unix(errno); } - string_set(&conn->dirpath,dir2); + string_set(&conn->dirpath,path); if (dirhandles_open >= MAX_OPEN_DIRECTORIES) { dptr_idleoldest(); @@ -488,7 +482,7 @@ NTSTATUS dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOO dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ - string_set(&dptr->path,dir2); + string_set(&dptr->path,path); dptr->conn = conn; dptr->dir_hnd = dir_hnd; dptr->spid = spid; @@ -758,10 +752,15 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) return True; } -static BOOL mangle_mask_match(connection_struct *conn, fstring filename, char *mask) +static BOOL mangle_mask_match(connection_struct *conn, const char *filename, + char *mask) { - mangle_map(filename,True,False,conn->params); - return mask_match_search(filename,mask,False); + char mname[13]; + + if (!name_to_8_3(filename,mname,False,conn->params)) { + return False; + } + return mask_match_search(mname,mask,False); } /**************************************************************************** @@ -806,9 +805,14 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { - if (!mangle_is_8_3(filename, False, conn->params)) - mangle_map(filename,True,False, - conn->params); + if (!mangle_is_8_3(filename, False, conn->params)) { + char mname[13]; + if (!name_to_8_3(filename,mname,False, + conn->params)) { + continue; + } + pstrcpy(filename,mname); + } pstrcpy(fname,filename); *path = 0; -- cgit From 351eb37a2555ce474ee02758f2f2cfee33d4d434 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Sep 2007 18:31:29 +0000 Subject: r25102: Rewrite msdfs code to use talloced filenames. Passes make test and make valgrindtest. Final step will be to change srvstr_get_path() to return talloced memory in the major codepaths. Jeremy. (This used to be commit cf6b6f9c3a38b68d2671c753f412772344506742) --- source3/smbd/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index e602008b8f..b21e6501d6 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1019,7 +1019,6 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * } if (hide_unreadable || hide_unwriteable || hide_special) { - pstring link_target; char *entry = NULL; if (asprintf(&entry, "%s/%s", dir_path, name) == -1) { @@ -1029,7 +1028,7 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * /* If it's a dfs symlink, ignore _hide xxxx_ options */ if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) && - is_msdfs_link(conn, entry, link_target, NULL)) { + is_msdfs_link(conn, entry, NULL)) { SAFE_FREE(entry); return True; } -- cgit From 3a9d3821649c9ea88a6cd424f0838a453165a00a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Sep 2007 23:57:59 +0000 Subject: r25111: Move to talloced pathnames on most code paths. There are now ony 17 pstrings left in reply.c, and these will be easy to remove (and I'll be doing that shortly). Had to fix an interesting bug in pull_ucs2_base_talloc() when a source string is not null terminated :-). Jeremy. (This used to be commit 0c9a8c4dff10974dbffd2a302ae982896122fcc0) --- source3/smbd/dir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index b21e6501d6..7a6815b680 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -752,8 +752,9 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) return True; } -static BOOL mangle_mask_match(connection_struct *conn, const char *filename, - char *mask) +static BOOL mangle_mask_match(connection_struct *conn, + const char *filename, + const char *mask) { char mname[13]; @@ -791,11 +792,11 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); - - if (dname == NULL) + + if (dname == NULL) return(False); - - pstrcpy(filename,dname); + + 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. -- cgit From 12f61e09d943ea7fc4149166077507b5b0b3b4e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Sep 2007 21:48:20 +0000 Subject: r25117: The mega-patch Jerry was waiting for. Remove all pstrings from the main server code paths. We should now be able to cope with paths up to PATH_MAX length now. Final job will be to add the TALLOC_CTX * parameter to unix_convert to make it explicit (for Volker). Jeremy. (This used to be commit 7f0db75fb0f24873577dcb758a2ecee74fdc4297) --- source3/smbd/dir.c | 135 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 41 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7a6815b680..a7b1b020b8 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1,18 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Directory handling routines Copyright (C) Andrew Tridgell 1992-1998 - + Copyright (C) Jeremy Allison 2007 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -72,15 +73,25 @@ static int dirhandles_open = 0; Make a dir struct. ****************************************************************************/ -void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T size,uint32 mode,time_t date, BOOL uc) -{ +BOOL make_dir_struct(TALLOC_CTX *ctx, + char *buf, + const char *mask, + const char *fname, + SMB_OFF_T size, + uint32 mode, + time_t date, + BOOL uc) +{ char *p; - pstring mask2; + char *mask2 = talloc_strdup(ctx, mask); - pstrcpy(mask2,mask); + if (!mask2) { + return False; + } - if ((mode & aDIR) != 0) + if ((mode & aDIR) != 0) { size = 0; + } memset(buf+1,' ',11); if ((p = strchr_m(mask2,'.')) != NULL) { @@ -88,8 +99,9 @@ void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T si push_ascii(buf+1,mask2,8, 0); push_ascii(buf+9,p+1,3, 0); *p = '.'; - } else + } else { push_ascii(buf+1,mask2,11, 0); + } memset(buf+21,'\0',DIR_STRUCT_SIZE-21); SCVAL(buf,21,mode); @@ -100,6 +112,7 @@ void make_dir_struct(char *buf, const char *mask, const char *fname,SMB_OFF_T si Strange, but verified on W2K3. Needed for OS/2. JRA. */ push_ascii(buf+30,fname,12, uc ? STR_UPPER : 0); DEBUG(8,("put name [%s] from [%s] into dir struct\n",buf+30, fname)); + return True; } /**************************************************************************** @@ -238,7 +251,7 @@ static void dptr_close_internal(struct dptr_struct *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. */ @@ -563,7 +576,10 @@ static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffs Return the next visible file name, skipping veto'd and invisible files. ****************************************************************************/ -const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) +const char *dptr_ReadDirName(TALLOC_CTX *ctx, + struct dptr_struct *dptr, + long *poffset, + SMB_STRUCT_STAT *pst) { SET_STAT_INVALID(*pst); @@ -578,7 +594,7 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT } if (!dptr->did_stat) { - pstring pathreal; + char *pathreal = NULL; /* We know the stored wcard contains no wildcard characters. See if we can match with a stat call. If we can't, then set did_stat to true to @@ -602,14 +618,19 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT return dptr->wcard; } - pstrcpy(pathreal,dptr->path); - pstrcat(pathreal,"/"); - pstrcat(pathreal,dptr->wcard); + pathreal = talloc_asprintf(ctx, + "%s/%s", + dptr->path, + dptr->wcard); + if (!pathreal) { + return NULL; + } if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) { /* We need to set the underlying dir_hnd offset to -1 also as this function is usually called with the output from TellDir. */ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + TALLOC_FREE(pathreal); return dptr->wcard; } else { /* If we get any other error than ENOENT or ENOTDIR @@ -618,10 +639,13 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT /* We need to set the underlying dir_hdn offset to -1 also as this function is usually called with the output from TellDir. */ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; + TALLOC_FREE(pathreal); return dptr->wcard; } } + TALLOC_FREE(pathreal); + /* In case sensitive mode we don't search - we know if it doesn't exist with a stat we will fail. */ @@ -768,35 +792,43 @@ static BOOL mangle_mask_match(connection_struct *conn, Get an 8.3 directory entry. ****************************************************************************/ -BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fname, - SMB_OFF_T *size,uint32 *mode,time_t *date,BOOL check_descend) +BOOL get_dir_entry(TALLOC_CTX *ctx, + connection_struct *conn, + const char *mask, + uint32 dirtype, + char **pp_fname_out, + SMB_OFF_T *size, + uint32 *mode, + time_t *date, + BOOL check_descend) { - const char *dname; + const char *dname = NULL; BOOL found = False; SMB_STRUCT_STAT sbuf; - pstring path; - pstring pathreal; - pstring filename; + char *pathreal = NULL; + const char *filename = NULL; BOOL needslash; - *path = *pathreal = *filename = 0; + *pp_fname_out = NULL; needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/'); - if (!conn->dirptr) + if (!conn->dirptr) { return(False); + } while (!found) { long curoff = dptr_TellDir(conn->dirptr); - dname = dptr_ReadDirName(conn->dirptr, &curoff, &sbuf); + dname = dptr_ReadDirName(ctx, conn->dirptr, &curoff, &sbuf); DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n", (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd))); - if (dname == NULL) + if (dname == NULL) { return(False); + } - pstrcpy(filename,dname); + 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. @@ -805,44 +837,65 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,uint32 dirtype, pstring fn if ((strcmp(mask,"*.*") == 0) || mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { + char mname[13]; if (!mangle_is_8_3(filename, False, conn->params)) { - char mname[13]; if (!name_to_8_3(filename,mname,False, conn->params)) { continue; } - pstrcpy(filename,mname); + filename = mname; + } + + if (needslash) { + pathreal = talloc_asprintf(ctx, + "%s/%s", + conn->dirpath, + dname); + } else { + pathreal = talloc_asprintf(ctx, + "%s%s", + conn->dirpath, + dname); + } + if (!pathreal) { + return False; } - pstrcpy(fname,filename); - *path = 0; - pstrcpy(path,conn->dirpath); - if(needslash) - pstrcat(path,"/"); - pstrcpy(pathreal,path); - pstrcat(path,fname); - pstrcat(pathreal,dname); if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn, pathreal, &sbuf)) != 0) { - DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) )); + DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n", + pathreal, strerror(errno) )); + TALLOC_FREE(pathreal); continue; } - + *mode = dos_mode(conn,pathreal,&sbuf); if (!dir_check_ftype(conn,*mode,dirtype)) { DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype)); + TALLOC_FREE(pathreal); continue; } *size = sbuf.st_size; *date = sbuf.st_mtime; - DEBUG(3,("get_dir_entry mask=[%s] found %s fname=%s\n",mask, pathreal,fname)); + DEBUG(3,("get_dir_entry mask=[%s] found %s " + "fname=%s (%s)\n", + mask, + pathreal, + dname, + filename)); found = True; + *pp_fname_out = talloc_strdup(ctx, filename); + if (!*pp_fname_out) { + return False; + } + DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff); + TALLOC_FREE(pathreal); } } @@ -1198,7 +1251,7 @@ void SeekDir(struct smb_Dir *dirp, long offset) if (offset != dirp->offset) { if (offset == START_OF_DIRECTORY_OFFSET) { RewindDir(dirp, &offset); - /* + /* * Ok we should really set the file number here * to 1 to enable ".." to be returned next. Trouble * is I'm worried about callers using SeekDir(dirp,0) -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/dir.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index a7b1b020b8..f6a8b27ab4 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -55,12 +55,12 @@ struct dptr_struct { uint16 spid; struct connection_struct *conn; struct smb_Dir *dir_hnd; - BOOL expect_close; + bool expect_close; char *wcard; uint32 attr; char *path; - BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ - BOOL did_stat; /* Optimisation for non-wcard searches. */ + bool has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */ + bool did_stat; /* Optimisation for non-wcard searches. */ }; static struct bitmap *dptr_bmap; @@ -73,14 +73,14 @@ static int dirhandles_open = 0; Make a dir struct. ****************************************************************************/ -BOOL make_dir_struct(TALLOC_CTX *ctx, +bool make_dir_struct(TALLOC_CTX *ctx, char *buf, const char *mask, const char *fname, SMB_OFF_T size, uint32 mode, time_t date, - BOOL uc) + bool uc) { char *p; char *mask2 = talloc_strdup(ctx, mask); @@ -121,7 +121,7 @@ BOOL make_dir_struct(TALLOC_CTX *ctx, void init_dptrs(void) { - static BOOL dptrs_init=False; + static bool dptrs_init=False; if (dptrs_init) return; @@ -182,7 +182,7 @@ static void dptr_idleoldest(void) Get the struct dptr_struct for a dir index. ****************************************************************************/ -static struct dptr_struct *dptr_get(int key, BOOL forclose) +static struct dptr_struct *dptr_get(int key, bool forclose) { struct dptr_struct *dptr; @@ -354,7 +354,7 @@ void dptr_closepath(char *path,uint16 spid) finished with that one. ****************************************************************************/ -static void dptr_close_oldest(BOOL old) +static void dptr_close_oldest(bool old) { struct dptr_struct *dptr; @@ -393,8 +393,8 @@ static void dptr_close_oldest(BOOL old) wcard must not be zero. ****************************************************************************/ -NTSTATUS dptr_create(connection_struct *conn, const char *path, BOOL old_handle, BOOL expect_close,uint16 spid, - const char *wcard, BOOL wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) +NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, bool expect_close,uint16 spid, + const char *wcard, bool wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) { struct dptr_struct *dptr = NULL; struct smb_Dir *dir_hnd; @@ -546,7 +546,7 @@ long dptr_TellDir(struct dptr_struct *dptr) return TellDir(dptr->dir_hnd); } -BOOL dptr_has_wild(struct dptr_struct *dptr) +bool dptr_has_wild(struct dptr_struct *dptr) { return dptr->has_wild; } @@ -663,7 +663,7 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, Search for a file by name, skipping veto'ed and not visible files. ****************************************************************************/ -BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) +bool dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst) { SET_STAT_INVALID(*pst); @@ -689,7 +689,7 @@ void dptr_DirCacheAdd(struct dptr_struct *dptr, const char *name, long offset) Fill the 5 byte server reserved dptr field. ****************************************************************************/ -BOOL dptr_fill(char *buf1,unsigned int key) +bool dptr_fill(char *buf1,unsigned int key) { unsigned char *buf = (unsigned char *)buf1; struct dptr_struct *dptr = dptr_get(key, False); @@ -754,7 +754,7 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num) Check that a file matches a particular file type. ****************************************************************************/ -BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) +bool dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) { uint32 mask; @@ -776,7 +776,7 @@ BOOL dir_check_ftype(connection_struct *conn, uint32 mode, uint32 dirtype) return True; } -static BOOL mangle_mask_match(connection_struct *conn, +static bool mangle_mask_match(connection_struct *conn, const char *filename, const char *mask) { @@ -792,7 +792,7 @@ static BOOL mangle_mask_match(connection_struct *conn, Get an 8.3 directory entry. ****************************************************************************/ -BOOL get_dir_entry(TALLOC_CTX *ctx, +bool get_dir_entry(TALLOC_CTX *ctx, connection_struct *conn, const char *mask, uint32 dirtype, @@ -800,14 +800,14 @@ BOOL get_dir_entry(TALLOC_CTX *ctx, SMB_OFF_T *size, uint32 *mode, time_t *date, - BOOL check_descend) + bool check_descend) { const char *dname = NULL; - BOOL found = False; + bool found = False; SMB_STRUCT_STAT sbuf; char *pathreal = NULL; const char *filename = NULL; - BOOL needslash; + bool needslash; *pp_fname_out = NULL; @@ -908,7 +908,7 @@ BOOL get_dir_entry(TALLOC_CTX *ctx, use it for anything security sensitive. ********************************************************************/ -static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { SEC_DESC *psd = NULL; size_t sd_size; @@ -971,7 +971,7 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S 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_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { SEC_DESC *psd = NULL; size_t sd_size; @@ -1030,7 +1030,7 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ Is a file a "special" type ? ********************************************************************/ -static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { /* * If user is a member of the Admin group @@ -1054,11 +1054,11 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT Should the file be seen by the client ? ********************************************************************/ -BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, BOOL use_veto) +bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto) { - BOOL hide_unreadable = lp_hideunreadable(SNUM(conn)); - BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); - BOOL hide_special = lp_hide_special_files(SNUM(conn)); + bool hide_unreadable = lp_hideunreadable(SNUM(conn)); + bool hide_unwriteable = lp_hideunwriteable_files(SNUM(conn)); + bool hide_special = lp_hide_special_files(SNUM(conn)); SET_STAT_INVALID(*pst); @@ -1309,7 +1309,7 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) Don't check for veto or invisible files. ********************************************************************/ -BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) +bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) { int i; const char *entry; -- cgit From 15953b82eb3b49d736b4b835b1d0d3cf0da0bff8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Oct 2007 21:06:49 +0200 Subject: Make [f]get_nt_acl return NTSTATUS (This used to be commit dcbe1bf942d017a3cd5084c6ef605a13912f795b) --- source3/smbd/dir.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index f6a8b27ab4..05679ee0ee 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -911,7 +911,6 @@ bool get_dir_entry(TALLOC_CTX *ctx, static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { SEC_DESC *psd = NULL; - size_t sd_size; files_struct *fsp; NTSTATUS status; uint32 access_granted; @@ -951,12 +950,12 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, + status = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ - if (!sd_size) { + if (!NT_STATUS_IS_OK(status)) { return False; } @@ -974,7 +973,6 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { SEC_DESC *psd = NULL; - size_t sd_size; files_struct *fsp; int info; NTSTATUS status; @@ -1014,13 +1012,14 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - sd_size = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, + status = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, NORMAL_CLOSE); /* No access if SD get failed. */ - if (!sd_size) + if (!NT_STATUS_IS_OK(status)) { return False; + } return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA, &access_granted, &status); -- cgit From 596018455af0d80add90215689a80d336157429c Mon Sep 17 00:00:00 2001 From: James Peach Date: Sat, 22 Dec 2007 14:55:37 -0800 Subject: Use filesystem capabilities to support case-insensitive filesystems. If we know the underlying filesystem is case-insensitive, then we know that it won't help to search for case variations of the requested name. Jeremy, please review (and revert if you disagree). (This used to be commit 9e8b8f8c16612d8a08b55802f4fd9afca5498a7c) --- source3/smbd/dir.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 05679ee0ee..ccf91fe57d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -646,10 +646,13 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, TALLOC_FREE(pathreal); - /* In case sensitive mode we don't search - we know if it doesn't exist - with a stat we will fail. */ + /* Stat failed. We know this is authoratiative if we are + * providing case sensitive semantics or the underlying + * filesystem is case sensitive. + */ - if (dptr->conn->case_sensitive) { + if (dptr->conn->case_sensitive || + !(dptr->conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { /* We need to set the underlying dir_hnd offset to -1 also as this function is usually called with the output from TellDir. */ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET; @@ -924,12 +927,7 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; } - /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) { - DEBUG(10,("user_can_read_file: SMB_VFS_STAT failed for file %s with error %s\n", - name, strerror(errno) )); - return False; - } + SMB_ASSERT(VALID_STAT(*pst)); /* Pseudo-open the file (note - no fd's created). */ @@ -987,10 +985,7 @@ 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) && (SMB_VFS_STAT(conn, name, pst) != 0)) { - return False; - } + SMB_ASSERT(VALID_STAT(*pst)); /* Pseudo-open the file */ @@ -1039,9 +1034,7 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT if (conn->admin_user) return False; - /* If we can't stat it does not show it */ - if (!VALID_STAT(*pst) && (SMB_VFS_STAT(conn, name, pst) != 0)) - return True; + SMB_ASSERT(VALID_STAT(*pst)); if (S_ISREG(pst->st_mode) || S_ISDIR(pst->st_mode) || S_ISLNK(pst->st_mode)) return False; @@ -1050,7 +1043,9 @@ static bool file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT } /******************************************************************* - Should the file be seen by the client ? + Should the file be seen by the client ? NOTE: A successful return + is no guarantee of the file's existence ... you also have to check + whether pst is valid. ********************************************************************/ bool is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, bool use_veto) @@ -1086,6 +1081,15 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char * return True; } + /* If the file name does not exist, there's no point checking + * the configuration options. We succeed, on the basis that the + * checks *might* have passed if the file was present. + */ + if (SMB_VFS_STAT(conn, entry, pst) != 0) { + SAFE_FREE(entry); + return True; + } + /* Honour _hide unreadable_ option */ if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); -- cgit From ee24c629a68e13764f78064121a6aea3d0e9240c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 5 Jan 2008 02:16:15 +0100 Subject: Remove superfluous fd parameter from SMB_VFS_FGET_NT_ACL(). Michael (This used to be commit c0c7c1223da29c68359dac64a340c1c710d5f3d2) --- source3/smbd/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ccf91fe57d..ab6e12f20f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -948,7 +948,7 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - status = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, + status = SMB_VFS_FGET_NT_ACL(fsp, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, NORMAL_CLOSE); @@ -1007,7 +1007,7 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ } /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - status = SMB_VFS_FGET_NT_ACL(fsp, fsp->fh->fd, + status = SMB_VFS_FGET_NT_ACL(fsp, (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); close_file(fsp, NORMAL_CLOSE); -- cgit From 35c256226f7cbf1125ad7b6370eecdf09b3cfbc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 8 Jan 2008 21:45:21 +0100 Subject: Allocate dirp->name_cache on demand only (This used to be commit 1a15778331393f9ece9aac9450828e799b20a058) --- source3/smbd/dir.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ab6e12f20f..04e3167e77 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1139,16 +1139,6 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *m goto fail; } - if (dirp->name_cache_size) { - dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, - dirp->name_cache_size); - if (!dirp->name_cache) { - goto fail; - } - } else { - dirp->name_cache = NULL; - } - dirhandles_open++; return dirp; @@ -1295,10 +1285,19 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) { struct name_cache_entry *e; - if (!dirp->name_cache_size || !dirp->name_cache) { + if (dirp->name_cache_size == 0) { return; } + if (dirp->name_cache == NULL) { + dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, + dirp->name_cache_size); + + if (dirp->name_cache == NULL) { + return; + } + } + dirp->name_cache_index = (dirp->name_cache_index+1) % dirp->name_cache_size; e = &dirp->name_cache[dirp->name_cache_index]; -- cgit From ec412b60ea6d6a4e0fd2e03ca9299b4264483c0c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jan 2008 17:08:04 +0100 Subject: Convert OpenDir to talloc, use talloc_tos() This cuts some mallocs on NtCreate&X (This used to be commit 8e64107b7846d8f9cce71aabc95b28b7488d01ce) --- source3/smbd/dir.c | 96 ++++++++++++++++++++++-------------------------------- 1 file changed, 39 insertions(+), 57 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 04e3167e77..ca6f8bfd8d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -142,8 +142,7 @@ static void dptr_idle(struct dptr_struct *dptr) { if (dptr->dir_hnd) { DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum)); - CloseDir(dptr->dir_hnd); - dptr->dir_hnd = NULL; + TALLOC_FREE(dptr->dir_hnd); } } @@ -192,7 +191,9 @@ static struct dptr_struct *dptr_get(int key, bool forclose) if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); - if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { + if (!(dptr->dir_hnd = OpenDir( + NULL, dptr->conn, dptr->path, + dptr->wcard, dptr->attr))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); return False; @@ -263,9 +264,7 @@ static void dptr_close_internal(struct dptr_struct *dptr) bitmap_clear(dptr_bmap, dptr->dnum - 1); - if (dptr->dir_hnd) { - CloseDir(dptr->dir_hnd); - } + TALLOC_FREE(dptr->dir_hnd); /* Lanman 2 specific code */ SAFE_FREE(dptr->wcard); @@ -411,7 +410,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, return status; } - dir_hnd = OpenDir(conn, path, wcard, attr); + dir_hnd = OpenDir(NULL, conn, path, wcard, attr); if (!dir_hnd) { return map_nt_error_from_unix(errno); } @@ -425,7 +424,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, dptr = SMB_MALLOC_P(struct dptr_struct); if(!dptr) { DEBUG(0,("malloc fail in dptr_create.\n")); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_NO_MEMORY; } @@ -455,7 +454,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, 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); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_TOO_MANY_OPENED_FILES; } } @@ -485,7 +484,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, 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); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_TOO_MANY_OPENED_FILES; } } @@ -504,7 +503,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, if (!dptr->wcard) { bitmap_clear(dptr_bmap, dptr->dnum - 1); SAFE_FREE(dptr); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_NO_MEMORY; } if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { @@ -533,7 +532,8 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, int dptr_CloseDir(struct dptr_struct *dptr) { DLIST_REMOVE(dirptrs, dptr); - return CloseDir(dptr->dir_hnd); + TALLOC_FREE(dptr->dir_hnd); + return 0; } void dptr_SeekDir(struct dptr_struct *dptr, long offset) @@ -1113,72 +1113,53 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char * return True; } +static int smb_Dir_destructor(struct smb_Dir *dirp) +{ + if (dirp->dir) { + SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); + } + dirhandles_open--; + return 0; +} + /******************************************************************* Open a directory. ********************************************************************/ -struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) +struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, + const char *name, const char *mask, uint32 attr) { - struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); + struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir); if (!dirp) { return NULL; } - ZERO_STRUCTP(dirp); dirp->conn = conn; dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); - dirp->dir_path = SMB_STRDUP(name); + dirp->dir_path = talloc_strdup(dirp, name); if (!dirp->dir_path) { goto fail; } + + dirhandles_open++; + talloc_set_destructor(dirp, smb_Dir_destructor); + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); if (!dirp->dir) { - DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); + DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, + strerror(errno) )); goto fail; } - dirhandles_open++; return dirp; fail: - - if (dirp) { - if (dirp->dir) { - SMB_VFS_CLOSEDIR(conn,dirp->dir); - } - SAFE_FREE(dirp->dir_path); - SAFE_FREE(dirp->name_cache); - SAFE_FREE(dirp); - } + TALLOC_FREE(dirp); return NULL; } - -/******************************************************************* - Close a directory. -********************************************************************/ - -int CloseDir(struct smb_Dir *dirp) -{ - int i, ret = 0; - - if (dirp->dir) { - ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); - } - SAFE_FREE(dirp->dir_path); - if (dirp->name_cache) { - for (i = 0; i < dirp->name_cache_size; i++) { - SAFE_FREE(dirp->name_cache[i].name); - } - } - SAFE_FREE(dirp->name_cache); - SAFE_FREE(dirp); - dirhandles_open--; - return ret; -} - /******************************************************************* Read from a directory. Also return current offset. Don't check for veto or invisible files. @@ -1290,8 +1271,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) } if (dirp->name_cache == NULL) { - dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, - dirp->name_cache_size); + dirp->name_cache = TALLOC_ZERO_ARRAY( + dirp, struct name_cache_entry, dirp->name_cache_size); if (dirp->name_cache == NULL) { return; @@ -1301,8 +1282,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) dirp->name_cache_index = (dirp->name_cache_index+1) % dirp->name_cache_size; e = &dirp->name_cache[dirp->name_cache_index]; - SAFE_FREE(e->name); - e->name = SMB_STRDUP(name); + TALLOC_FREE(e->name); + e->name = talloc_strdup(dirp, name); e->offset = offset; } @@ -1359,7 +1340,8 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, NTSTATUS status = NT_STATUS_OK; long dirpos = 0; const char *dname; - struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0); + struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname, + NULL, 0); if (!dir_hnd) { return map_nt_error_from_unix(errno); @@ -1383,7 +1365,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, status = NT_STATUS_DIRECTORY_NOT_EMPTY; break; } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return status; } -- cgit From d03453864ab1bc5fd3b4a3abaf96176a006c102b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 15:39:38 +0100 Subject: smbd: implement the strange write time update logic We now never call file_ntimes() directly, every update is done via smb_set_file_time(). This let samba3 pass the BASE-DELAYWRITE test. The write time is only updated 2 seconds after the first write() on any open handle to the current time (not the time of the first write). Each handle which had write requests updates the write time to the current time on close(). If the write time is set explicit via setfileinfo or setpathinfo the write time is visible directly and a following close on the same handle doesn't update the write time. metze (This used to be commit 2eab212ea2e1bfd8fa716c2c89b2c042f7ba12ea) --- source3/smbd/dir.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index ca6f8bfd8d..8531d6250d 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -841,6 +841,8 @@ bool get_dir_entry(TALLOC_CTX *ctx, mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { char mname[13]; + struct timespec write_time_ts; + struct file_id fileid; if (!mangle_is_8_3(filename, False, conn->params)) { if (!name_to_8_3(filename,mname,False, @@ -883,6 +885,12 @@ bool get_dir_entry(TALLOC_CTX *ctx, *size = sbuf.st_size; *date = sbuf.st_mtime; + fileid = vfs_file_id_from_sbuf(conn, &sbuf); + write_time_ts = get_write_time(fileid); + if (!null_timespec(write_time_ts)) { + *date = convert_timespec_to_time_t(write_time_ts); + } + DEBUG(3,("get_dir_entry mask=[%s] found %s " "fname=%s (%s)\n", mask, -- cgit From 851cadba51b00b326c5f040f23f95932aec53105 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Apr 2008 11:40:23 +0200 Subject: locking: combine get_delete_on_close_flag() and get_write_time() into get_file_infos() This means we need to fetch the record only once. metze (This used to be commit 4130b873291d39e363184fe4e38dc1f24ebe5056) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 8531d6250d..5fc2e3719e 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -886,7 +886,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, *date = sbuf.st_mtime; fileid = vfs_file_id_from_sbuf(conn, &sbuf); - write_time_ts = get_write_time(fileid); + get_file_infos(fileid, NULL, &write_time_ts); if (!null_timespec(write_time_ts)) { *date = convert_timespec_to_time_t(write_time_ts); } -- cgit From 19f49de92e176495f3e0640502d4a330eacbf59e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Apr 2008 09:21:19 +0200 Subject: smbd: make it possible to disable get_file_infos() on searches metze (This used to be commit 404a865a34c3a7c67131b3f99e92c11b2abe3e39) --- source3/smbd/dir.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5fc2e3719e..6e02401e25 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -803,7 +803,8 @@ bool get_dir_entry(TALLOC_CTX *ctx, SMB_OFF_T *size, uint32 *mode, time_t *date, - bool check_descend) + bool check_descend, + bool ask_sharemode) { const char *dname = NULL; bool found = False; @@ -841,8 +842,6 @@ bool get_dir_entry(TALLOC_CTX *ctx, mask_match_search(filename,mask,False) || mangle_mask_match(conn,filename,mask)) { char mname[13]; - struct timespec write_time_ts; - struct file_id fileid; if (!mangle_is_8_3(filename, False, conn->params)) { if (!name_to_8_3(filename,mname,False, @@ -885,10 +884,15 @@ bool get_dir_entry(TALLOC_CTX *ctx, *size = sbuf.st_size; *date = sbuf.st_mtime; - fileid = vfs_file_id_from_sbuf(conn, &sbuf); - get_file_infos(fileid, NULL, &write_time_ts); - if (!null_timespec(write_time_ts)) { - *date = convert_timespec_to_time_t(write_time_ts); + if (ask_sharemode) { + struct timespec write_time_ts; + struct file_id fileid; + + fileid = vfs_file_id_from_sbuf(conn, &sbuf); + get_file_infos(fileid, NULL, &write_time_ts); + if (!null_timespec(write_time_ts)) { + *date = convert_timespec_to_time_t(write_time_ts); + } } DEBUG(3,("get_dir_entry mask=[%s] found %s " -- cgit From b430b382202858a6c52c1cacbb91910b2dd7e16c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 May 2008 17:22:10 -0700 Subject: Remove the "stat_open()" function, flag, and all associated code. It was only being (correctly) used in the can_read/can_write checks for hide unreadable/unwritable and this is more properly done using the functions in smbd/file_access.c. Preparing to do NT access checks on all file access. Jeremy. (This used to be commit 6bfb06ad95963ae2acb67c4694a98282d3b29faa) --- source3/smbd/dir.c | 68 ++---------------------------------------------------- 1 file changed, 2 insertions(+), 66 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 6e02401e25..7d584977df 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -925,11 +925,6 @@ bool get_dir_entry(TALLOC_CTX *ctx, static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { - SEC_DESC *psd = NULL; - files_struct *fsp; - NTSTATUS status; - uint32 access_granted; - /* * If user is a member of the Admin group * we never hide files from them. @@ -941,36 +936,7 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S SMB_ASSERT(VALID_STAT(*pst)); - /* Pseudo-open the file (note - no fd's created). */ - - if(S_ISDIR(pst->st_mode)) { - status = open_directory(conn, NULL, name, pst, - READ_CONTROL_ACCESS, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, - 0, /* no create options. */ - FILE_ATTRIBUTE_DIRECTORY, - NULL, &fsp); - } else { - status = open_file_stat(conn, NULL, name, pst, &fsp); - } - - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - status = SMB_VFS_FGET_NT_ACL(fsp, - (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, NORMAL_CLOSE); - - /* No access if SD get failed. */ - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA, - &access_granted, &status); + return can_access_file_acl(conn, name, pst, FILE_READ_DATA); } /******************************************************************* @@ -982,12 +948,6 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) { - SEC_DESC *psd = NULL; - files_struct *fsp; - int info; - NTSTATUS status; - uint32 access_granted; - /* * If user is a member of the Admin group * we never hide files from them. @@ -1003,33 +963,9 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_ if(S_ISDIR(pst->st_mode)) { return True; - } else { - status = open_file_ntcreate(conn, NULL, name, pst, - FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ|FILE_SHARE_WRITE, - FILE_OPEN, - 0, - FILE_ATTRIBUTE_NORMAL, - INTERNAL_OPEN_ONLY, - &info, &fsp); - } - - if (!NT_STATUS_IS_OK(status)) { - return False; - } - - /* Get NT ACL -allocated in main loop talloc context. No free needed here. */ - status = SMB_VFS_FGET_NT_ACL(fsp, - (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd); - close_file(fsp, NORMAL_CLOSE); - - /* No access if SD get failed. */ - if (!NT_STATUS_IS_OK(status)) { - return False; } - return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA, - &access_granted, &status); + return can_write_to_file(conn, name, pst); } /******************************************************************* -- cgit From 3a5e1cacf1495a37143b15725c5d226088b2473a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 15 Jun 2008 11:40:33 +0200 Subject: Remove unused "extern struct current_user" from dir.c (This used to be commit b92cfd19b459caad34229dfe941cf15fd14a5ce0) --- source3/smbd/dir.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 7d584977df..caa1c41a4f 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -24,8 +24,6 @@ This module implements directory related functions for Samba. */ -extern struct current_user current_user; - /* "Special" directory offsets. */ #define END_OF_DIRECTORY_OFFSET ((long)-1) #define START_OF_DIRECTORY_OFFSET ((long)0) -- cgit From b172eb1d478aef1f1e6c8ea40486fe9895b0f9de Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 17 Jun 2008 23:58:49 +0200 Subject: file_access: remove unneeded stat buf parameter from can_access_file_acl(). This is a security descriptor level function only. Michael (This used to be commit 5931540fa1681f026fed42df387d17e43c493c47) --- source3/smbd/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index caa1c41a4f..2d9e7e7527 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -934,7 +934,7 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S SMB_ASSERT(VALID_STAT(*pst)); - return can_access_file_acl(conn, name, pst, FILE_READ_DATA); + return can_access_file_acl(conn, name, FILE_READ_DATA); } /******************************************************************* -- cgit From 24e7f40687b9542543533e1a4820b8f3f0016f07 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 18 Jun 2008 00:02:28 +0200 Subject: smbd/dir.c: remove unneeded stat buf parameter from user_can_read_file() This is not needed anymore since user_can_access_file_acl() ist used. Michael (This used to be commit 3c349f773a52e3de693d3bb79f5060c9f1e01e41) --- source3/smbd/dir.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 2d9e7e7527..74cd63ddda 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -921,7 +921,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, use it for anything security sensitive. ********************************************************************/ -static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst) +static bool user_can_read_file(connection_struct *conn, char *name) { /* * If user is a member of the Admin group @@ -932,8 +932,6 @@ static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S return True; } - SMB_ASSERT(VALID_STAT(*pst)); - return can_access_file_acl(conn, name, FILE_READ_DATA); } @@ -1037,7 +1035,7 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char * } /* Honour _hide unreadable_ option */ - if (hide_unreadable && !user_can_read_file(conn, entry, pst)) { + if (hide_unreadable && !user_can_read_file(conn, entry)) { DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry )); SAFE_FREE(entry); return False; -- cgit From 743d6f707a7dcd31f8d0cf1685275d179c0d5169 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 12 Aug 2008 15:19:17 +0200 Subject: Make sure to always set errno on error path in OpenDir (and hence scan_directory). Michael (This used to be commit 15fc2427f91da697e0e91f7f34b0f0c6e230a9a5) --- source3/smbd/dir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/dir.c') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 74cd63ddda..c2735c032a 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -1084,6 +1084,7 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, dirp->dir_path = talloc_strdup(dirp, name); if (!dirp->dir_path) { + errno = ENOMEM; goto fail; } -- cgit