summaryrefslogtreecommitdiff
path: root/source3/smbd/reply.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r--source3/smbd/reply.c74
1 files changed, 70 insertions, 4 deletions
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)
{