The branch, v3-5-test has been updated
       via  b9e71c7... Refactor reply_rmdir to use handle based code. All calls 
are now handle based. Put rmdir into close.c and make it private. Jeremy. 
(cherry picked from commit 91e0bdd86c9c14f6b9b190db8ce6ec162ce79692)
      from  f39f894... ѕ3: remove superfluous option check

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit b9e71c705242a02fc70bbe8db7b88fdd76179663
Author: Jeremy Allison <[email protected]>
Date:   Thu Dec 3 13:01:10 2009 -0800

    Refactor reply_rmdir to use handle based code. All
    calls are now handle based. Put rmdir into close.c
    and make it private.
    Jeremy.
    (cherry picked from commit 91e0bdd86c9c14f6b9b190db8ce6ec162ce79692)

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h |    3 -
 source3/smbd/close.c    |  260 ++++++++++++++++++++++++++++++++++++++++-
 source3/smbd/reply.c    |  300 +++++++----------------------------------------
 3 files changed, 298 insertions(+), 265 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 7a7d4f9..7b575ca 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6881,9 +6881,6 @@ void reply_printclose(struct smb_request *req);
 void reply_printqueue(struct smb_request *req);
 void reply_printwrite(struct smb_request *req);
 void reply_mkdir(struct smb_request *req);
-NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
-                       connection_struct *conn,
-                       struct smb_filename *smb_dname);
 void reply_rmdir(struct smb_request *req);
 NTSTATUS rename_internals_fsp(connection_struct *conn,
                        files_struct *fsp,
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index afba07f..05c3c70 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -656,6 +656,263 @@ static NTSTATUS close_normal_file(struct smb_request 
*req, files_struct *fsp,
        file_free(req, fsp);
        return status;
 }
+/****************************************************************************
+ Static function used by reply_rmdir to delete an entire directory
+ tree recursively. Return True on ok, False on fail.
+****************************************************************************/
+
+static bool recursive_rmdir(TALLOC_CTX *ctx,
+                       connection_struct *conn,
+                       struct smb_filename *smb_dname)
+{
+       const char *dname = NULL;
+       char *talloced = NULL;
+       bool ret = True;
+       long offset = 0;
+       SMB_STRUCT_STAT st;
+       struct smb_Dir *dir_hnd;
+
+       SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
+
+       dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
+       if(dir_hnd == NULL)
+               return False;
+
+       while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
+               struct smb_filename *smb_dname_full = NULL;
+               char *fullname = NULL;
+               bool do_break = true;
+               NTSTATUS status;
+
+               if (ISDOT(dname) || ISDOTDOT(dname)) {
+                       TALLOC_FREE(talloced);
+                       continue;
+               }
+
+               if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
+                                    false)) {
+                       TALLOC_FREE(talloced);
+                       continue;
+               }
+
+               /* Construct the full name. */
+               fullname = talloc_asprintf(ctx,
+                               "%s/%s",
+                               smb_dname->base_name,
+                               dname);
+               if (!fullname) {
+                       errno = ENOMEM;
+                       goto err_break;
+               }
+
+               status = create_synthetic_smb_fname(talloc_tos(), fullname,
+                                                   NULL, NULL,
+                                                   &smb_dname_full);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto err_break;
+               }
+
+               if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
+                       goto err_break;
+               }
+
+               if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
+                       if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
+                               goto err_break;
+                       }
+                       if(SMB_VFS_RMDIR(conn,
+                                        smb_dname_full->base_name) != 0) {
+                               goto err_break;
+                       }
+               } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
+                       goto err_break;
+               }
+
+               /* Successful iteration. */
+               do_break = false;
+
+        err_break:
+               TALLOC_FREE(smb_dname_full);
+               TALLOC_FREE(fullname);
+               TALLOC_FREE(talloced);
+               if (do_break) {
+                       ret = false;
+                       break;
+               }
+       }
+       TALLOC_FREE(dir_hnd);
+       return ret;
+}
+
+/****************************************************************************
+ The internals of the rmdir code - called elsewhere.
+****************************************************************************/
+
+static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
+{
+       connection_struct *conn = fsp->conn;
+       struct smb_filename *smb_dname = fsp->fsp_name;
+       int ret;
+
+       SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
+
+       /* Might be a symlink. */
+       if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
+               return map_nt_error_from_unix(errno);
+       }
+
+       if (S_ISLNK(smb_dname->st.st_ex_mode)) {
+               /* Is what it points to a directory ? */
+               if(SMB_VFS_STAT(conn, smb_dname) != 0) {
+                       return map_nt_error_from_unix(errno);
+               }
+               if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
+                       return NT_STATUS_NOT_A_DIRECTORY;
+               }
+               ret = SMB_VFS_UNLINK(conn, smb_dname);
+       } else {
+               ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
+       }
+       if (ret == 0) {
+               notify_fname(conn, NOTIFY_ACTION_REMOVED,
+                            FILE_NOTIFY_CHANGE_DIR_NAME,
+                            smb_dname->base_name);
+               return NT_STATUS_OK;
+       }
+
+       if(((errno == ENOTEMPTY)||(errno == EEXIST)) && 
lp_veto_files(SNUM(conn))) {
+               /*
+                * 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.
+                */
+               SMB_STRUCT_STAT st;
+               const char *dname = NULL;
+               char *talloced = NULL;
+               long dirpos = 0;
+               struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
+                                                 smb_dname->base_name, NULL,
+                                                 0);
+
+               if(dir_hnd == NULL) {
+                       errno = ENOTEMPTY;
+                       goto err;
+               }
+
+               while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
+                                           &talloced)) != NULL) {
+                       if((strcmp(dname, ".") == 0) || (strcmp(dname, 
"..")==0)) {
+                               TALLOC_FREE(talloced);
+                               continue;
+                       }
+                       if (!is_visible_file(conn, smb_dname->base_name, dname,
+                                            &st, false)) {
+                               TALLOC_FREE(talloced);
+                               continue;
+                       }
+                       if(!IS_VETO_PATH(conn, dname)) {
+                               TALLOC_FREE(dir_hnd);
+                               TALLOC_FREE(talloced);
+                               errno = ENOTEMPTY;
+                               goto err;
+                       }
+                       TALLOC_FREE(talloced);
+               }
+
+               /* We only have veto files/directories.
+                * Are we allowed to delete them ? */
+
+               if(!lp_recursive_veto_delete(SNUM(conn))) {
+                       TALLOC_FREE(dir_hnd);
+                       errno = ENOTEMPTY;
+                       goto err;
+               }
+
+               /* Do a recursive delete. */
+               RewindDir(dir_hnd,&dirpos);
+               while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
+                                           &talloced)) != NULL) {
+                       struct smb_filename *smb_dname_full = NULL;
+                       char *fullname = NULL;
+                       bool do_break = true;
+                       NTSTATUS status;
+
+                       if (ISDOT(dname) || ISDOTDOT(dname)) {
+                               TALLOC_FREE(talloced);
+                               continue;
+                       }
+                       if (!is_visible_file(conn, smb_dname->base_name, dname,
+                                            &st, false)) {
+                               TALLOC_FREE(talloced);
+                               continue;
+                       }
+
+                       fullname = talloc_asprintf(ctx,
+                                       "%s/%s",
+                                       smb_dname->base_name,
+                                       dname);
+
+                       if(!fullname) {
+                               errno = ENOMEM;
+                               goto err_break;
+                       }
+
+                       status = create_synthetic_smb_fname(talloc_tos(),
+                                                           fullname, NULL,
+                                                           NULL,
+                                                           &smb_dname_full);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               errno = map_errno_from_nt_status(status);
+                               goto err_break;
+                       }
+
+                       if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
+                               goto err_break;
+                       }
+                       if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
+                               if(!recursive_rmdir(ctx, conn,
+                                                   smb_dname_full)) {
+                                       goto err_break;
+                               }
+                               if(SMB_VFS_RMDIR(conn,
+                                       smb_dname_full->base_name) != 0) {
+                                       goto err_break;
+                               }
+                       } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
+                               goto err_break;
+                       }
+
+                       /* Successful iteration. */
+                       do_break = false;
+
+                err_break:
+                       TALLOC_FREE(fullname);
+                       TALLOC_FREE(smb_dname_full);
+                       TALLOC_FREE(talloced);
+                       if (do_break)
+                               break;
+               }
+               TALLOC_FREE(dir_hnd);
+               /* Retry the rmdir */
+               ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
+       }
+
+  err:
+
+       if (ret != 0) {
+               DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
+                        "%s\n", smb_fname_str_dbg(smb_dname),
+                        strerror(errno)));
+               return map_nt_error_from_unix(errno);
+       }
+
+       notify_fname(conn, NOTIFY_ACTION_REMOVED,
+                    FILE_NOTIFY_CHANGE_DIR_NAME,
+                    smb_dname->base_name);
+
+       return NT_STATUS_OK;
+}
 
 /****************************************************************************
  Close a directory opened by an NT SMB call. 
@@ -742,8 +999,7 @@ static NTSTATUS close_directory(struct smb_request *req, 
files_struct *fsp,
 
                TALLOC_FREE(lck);
 
-               status = rmdir_internals(talloc_tos(), fsp->conn,
-                                        fsp->fsp_name);
+               status = rmdir_internals(talloc_tos(), fsp);
 
                DEBUG(5,("close_directory: %s. Delete on close was set - "
                         "deleting directory returned %s.\n",
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 101635f..030939f 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5283,264 +5283,6 @@ void reply_mkdir(struct smb_request *req)
 }
 
 /****************************************************************************
- Static function used by reply_rmdir to delete an entire directory
- tree recursively. Return True on ok, False on fail.
-****************************************************************************/
-
-static bool recursive_rmdir(TALLOC_CTX *ctx,
-                       connection_struct *conn,
-                       struct smb_filename *smb_dname)
-{
-       const char *dname = NULL;
-       char *talloced = NULL;
-       bool ret = True;
-       long offset = 0;
-       SMB_STRUCT_STAT st;
-       struct smb_Dir *dir_hnd;
-
-       SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
-
-       dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
-       if(dir_hnd == NULL)
-               return False;
-
-       while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
-               struct smb_filename *smb_dname_full = NULL;
-               char *fullname = NULL;
-               bool do_break = true;
-               NTSTATUS status;
-
-               if (ISDOT(dname) || ISDOTDOT(dname)) {
-                       TALLOC_FREE(talloced);
-                       continue;
-               }
-
-               if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
-                                    false)) {
-                       TALLOC_FREE(talloced);
-                       continue;
-               }
-
-               /* Construct the full name. */
-               fullname = talloc_asprintf(ctx,
-                               "%s/%s",
-                               smb_dname->base_name,
-                               dname);
-               if (!fullname) {
-                       errno = ENOMEM;
-                       goto err_break;
-               }
-
-               status = create_synthetic_smb_fname(talloc_tos(), fullname,
-                                                   NULL, NULL,
-                                                   &smb_dname_full);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto err_break;
-               }
-
-               if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
-                       goto err_break;
-               }
-
-               if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
-                       if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
-                               goto err_break;
-                       }
-                       if(SMB_VFS_RMDIR(conn,
-                                        smb_dname_full->base_name) != 0) {
-                               goto err_break;
-                       }
-               } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
-                       goto err_break;
-               }
-
-               /* Successful iteration. */
-               do_break = false;
-
-        err_break:
-               TALLOC_FREE(smb_dname_full);
-               TALLOC_FREE(fullname);
-               TALLOC_FREE(talloced);
-               if (do_break) {
-                       ret = false;
-                       break;
-               }
-       }
-       TALLOC_FREE(dir_hnd);
-       return ret;
-}
-
-/****************************************************************************
- The internals of the rmdir code - called elsewhere.
-****************************************************************************/
-
-NTSTATUS rmdir_internals(TALLOC_CTX *ctx,
-                        connection_struct *conn,
-                        struct smb_filename *smb_dname)
-{
-       int ret;
-
-       SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
-
-       /* Might be a symlink. */
-       if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
-               return map_nt_error_from_unix(errno);
-       }
-
-       if (S_ISLNK(smb_dname->st.st_ex_mode)) {
-               /* Is what it points to a directory ? */
-               if(SMB_VFS_STAT(conn, smb_dname) != 0) {
-                       return map_nt_error_from_unix(errno);
-               }
-               if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
-                       return NT_STATUS_NOT_A_DIRECTORY;
-               }
-               ret = SMB_VFS_UNLINK(conn, smb_dname);
-       } else {
-               ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
-       }
-       if (ret == 0) {
-               notify_fname(conn, NOTIFY_ACTION_REMOVED,
-                            FILE_NOTIFY_CHANGE_DIR_NAME,
-                            smb_dname->base_name);
-               return NT_STATUS_OK;
-       }
-
-       if(((errno == ENOTEMPTY)||(errno == EEXIST)) && 
lp_veto_files(SNUM(conn))) {
-               /*
-                * 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.
-                */
-               SMB_STRUCT_STAT st;
-               const char *dname = NULL;
-               char *talloced = NULL;
-               long dirpos = 0;
-               struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
-                                                 smb_dname->base_name, NULL,
-                                                 0);
-
-               if(dir_hnd == NULL) {
-                       errno = ENOTEMPTY;
-                       goto err;
-               }
-
-               while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
-                                           &talloced)) != NULL) {
-                       if((strcmp(dname, ".") == 0) || (strcmp(dname, 
"..")==0)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-                       if (!is_visible_file(conn, smb_dname->base_name, dname,
-                                            &st, false)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-                       if(!IS_VETO_PATH(conn, dname)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(talloced);
-                               errno = ENOTEMPTY;
-                               goto err;
-                       }
-                       TALLOC_FREE(talloced);
-               }
-
-               /* We only have veto files/directories.
-                * Are we allowed to delete them ? */
-
-               if(!lp_recursive_veto_delete(SNUM(conn))) {
-                       TALLOC_FREE(dir_hnd);
-                       errno = ENOTEMPTY;
-                       goto err;
-               }
-
-               /* Do a recursive delete. */
-               RewindDir(dir_hnd,&dirpos);
-               while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
-                                           &talloced)) != NULL) {
-                       struct smb_filename *smb_dname_full = NULL;
-                       char *fullname = NULL;
-                       bool do_break = true;
-                       NTSTATUS status;
-
-                       if (ISDOT(dname) || ISDOTDOT(dname)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-                       if (!is_visible_file(conn, smb_dname->base_name, dname,
-                                            &st, false)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       fullname = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       smb_dname->base_name,
-                                       dname);
-
-                       if(!fullname) {
-                               errno = ENOMEM;
-                               goto err_break;
-                       }


-- 
Samba Shared Repository

Reply via email to