[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Thu Dec 3 14:02:39 MST 2009


The branch, master has been updated
       via  91e0bdd... Refactor reply_rmdir to use handle based code. All calls are now handle based. Put rmdir into close.c and make it private. Jeremy.
      from  80e0661... s4:operational LDB module - Fix usage of LDB constants

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 91e0bdd86c9c14f6b9b190db8ce6ec162ce79692
Author: Jeremy Allison <jra at samba.org>
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.

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

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 d8fa437..6ae9e88 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6897,9 +6897,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


More information about the samba-cvs mailing list