diff options
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r-- | source3/smbd/reply.c | 74 |
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) { |