summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamba Release Account <samba-bugs@samba.org>1997-07-03 19:44:06 +0000
committerSamba Release Account <samba-bugs@samba.org>1997-07-03 19:44:06 +0000
commitf6384eca672565bf820f86721de5cf25a5e5e9fe (patch)
tree45d6716f3f46c82adca49c37828d1da41e84c192
parent751eb54b6b71c01f0e55d82a95b1e45dd1aaae00 (diff)
downloadsamba-f6384eca672565bf820f86721de5cf25a5e5e9fe.tar.gz
samba-f6384eca672565bf820f86721de5cf25a5e5e9fe.tar.bz2
samba-f6384eca672565bf820f86721de5cf25a5e5e9fe.zip
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)
-rw-r--r--source3/include/proto.h2
-rw-r--r--source3/smbd/chgpasswd.c2
-rw-r--r--source3/smbd/dir.c8
-rw-r--r--source3/smbd/reply.c74
-rw-r--r--source3/smbd/server.c2
5 files changed, 77 insertions, 11 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3929348da6..ef9382279e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -79,7 +79,7 @@ void *dptr_fetch(char *buf,int *num);
void *dptr_fetch_lanman2(char *params,int dptr_num);
BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype);
BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
-void *OpenDir(char *name);
+void *OpenDir(char *name, BOOL use_veto);
void CloseDir(void *p);
char *ReadDirName(void *p);
BOOL SeekDir(void *p,int pos);
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 883ad5214a..e0dd7fc0ae 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -56,7 +56,7 @@ static int findpty(char **slave)
#else
strcpy( line, "/dev/ptyXX" );
- dirp = OpenDir("/dev");
+ dirp = OpenDir("/dev", True);
if (!dirp) return(-1);
while ((dpname = ReadDirName(dirp)) != NULL) {
if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
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);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 8af4536c19..5f030d5372 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1326,7 +1326,7 @@ int reply_unlink(char *inbuf,char *outbuf)
char *dname;
if (check_name(directory,cnum))
- dirptr = OpenDir(directory);
+ dirptr = OpenDir(directory, True);
/* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
the pattern matches against the long name, otherwise the short name
@@ -2449,10 +2449,76 @@ int reply_rmdir(char *inbuf,char *outbuf)
if (check_name(directory,cnum))
{
+
dptr_closepath(directory,SVAL(inbuf,smb_pid));
ok = (sys_rmdir(directory) == 0);
+ if(!ok && (errno == ENOTEMPTY) && lp_veto_files())
+ {
+ /* Check to see if the only thing in this directory are
+ vetoed files/directories. If so then delete them and
+ retry. If we fail to delete any of them (and we *don't*
+ do a recursive delete) then fail the rmdir. */
+ BOOL all_veto_files = True;
+ char *dname;
+ void *dirptr = OpenDir(directory, False);
+
+ if(dirptr != NULL)
+ {
+ int dirpos = TellDir(dirptr);
+ while ((dname = ReadDirName(dirptr)))
+ {
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+ if(!is_vetoed_name(dname))
+ {
+ all_veto_files = False;
+ break;
+ }
+ }
+ if(all_veto_files)
+ {
+ SeekDir(dirptr,dirpos);
+ while ((dname = ReadDirName(dirptr)))
+ {
+ pstring fullname;
+ struct stat st;
+
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+
+ /* Construct the full name. */
+ if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
+ {
+ errno = ENOMEM;
+ break;
+ }
+ strcpy(fullname, directory);
+ strcat(fullname, "/");
+ strcat(fullname, dname);
+
+ if(sys_lstat(fullname, &st) != 0)
+ break;
+ if(st.st_mode & S_IFDIR)
+ {
+ if(sys_rmdir(fullname) != 0)
+ break;
+ }
+ else if(sys_unlink(fullname) != 0)
+ break;
+ }
+ CloseDir(dirptr);
+ /* Retry the rmdir */
+ ok = (sys_rmdir(directory) == 0);
+ }
+ else
+ CloseDir(dirptr);
+ }
+ else
+ errno = ENOTEMPTY;
+ }
+
if (!ok)
- DEBUG(3,("couldn't remove directory %s : %s\n",
+ DEBUG(3,("couldn't remove directory %s : %s\n",
directory,strerror(errno)));
}
@@ -2670,7 +2736,7 @@ int reply_mv(char *inbuf,char *outbuf)
pstring destname;
if (check_name(directory,cnum))
- dirptr = OpenDir(directory);
+ dirptr = OpenDir(directory, True);
if (dirptr)
{
@@ -2861,7 +2927,7 @@ int reply_copy(char *inbuf,char *outbuf)
pstring destname;
if (check_name(directory,cnum))
- dirptr = OpenDir(directory);
+ dirptr = OpenDir(directory, True);
if (dirptr)
{
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 8c40734ce4..30d8ce3d2a 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -361,7 +361,7 @@ static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
check_mangled_stack(name);
/* open the directory */
- if (!(cur_dir = OpenDir(path)))
+ if (!(cur_dir = OpenDir(path, True)))
{
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
return(False);