[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-595-g841f4cc

Volker Lendecke vl at samba.org
Tue Dec 11 15:14:19 GMT 2007


The branch, v3-2-test has been updated
       via  841f4ccbfb5f79ac4f447342e9dd6ef73cacbc65 (commit)
       via  deaacf971e0fbffd0e5fe24f225ebf645a77e133 (commit)
       via  ae422fce01cd7520d6dd72e08719a5cd003cb640 (commit)
       via  0e96549b56e288c596ed8772197f97ffa5ade300 (commit)
      from  3954313d4e3d3a782f0ba41afa5d81b7cc5adac9 (commit)

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


- Log -----------------------------------------------------------------
commit 841f4ccbfb5f79ac4f447342e9dd6ef73cacbc65
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Dec 10 21:36:28 2007 +0100

    Convert the posix_pending_close_db to dbwrap_rbt

commit deaacf971e0fbffd0e5fe24f225ebf645a77e133
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 11 11:14:30 2007 +0100

    separate out create_file_unixpath()

commit ae422fce01cd7520d6dd72e08719a5cd003cb640
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 11 10:49:26 2007 +0100

    Move more stuff out of the way

commit 0e96549b56e288c596ed8772197f97ffa5ade300
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Dec 11 10:36:59 2007 +0100

    Move INTERNAL_OPEN_ONLY calculation out of the way

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

Summary of changes:
 source/locking/posix.c |  256 +++++++++++++++---------------
 source/smbd/open.c     |  417 ++++++++++++++++++++++++++++--------------------
 2 files changed, 374 insertions(+), 299 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/locking/posix.c b/source/locking/posix.c
index 4b0b91b..aef5c17 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -30,7 +30,7 @@
  * The pending close database handle.
  */
 
-static TDB_CONTEXT *posix_pending_close_tdb;
+static struct db_context *posix_pending_close_db;
 
 /****************************************************************************
  First - the functions that deal with the underlying system locks - these
@@ -349,20 +349,18 @@ static TDB_DATA fd_array_key_fsp(files_struct *fsp)
 
 bool posix_locking_init(bool read_only)
 {
-	if (posix_pending_close_tdb) {
-		return True;
-	}
-	
-	if (!posix_pending_close_tdb) {
-		posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
-						   read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
+	if (posix_pending_close_db != NULL) {
+		return true;
 	}
-	if (!posix_pending_close_tdb) {
+
+	posix_pending_close_db = db_open_rbt(NULL);
+
+	if (posix_pending_close_db == NULL) {
 		DEBUG(0,("Failed to open POSIX pending close database.\n"));
-		return False;
+		return false;
 	}
 
-	return True;
+	return true;
 }
 
 /*******************************************************************
@@ -371,10 +369,11 @@ bool posix_locking_init(bool read_only)
 
 bool posix_locking_end(void)
 {
-	if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) {
-		return False;
-	}
-	return True;
+	/*
+	 * Shouldn't we close all fd's here?
+	 */
+	TALLOC_FREE(posix_pending_close_db);
+	return true;
 }
 
 /****************************************************************************
@@ -399,60 +398,33 @@ bool posix_locking_end(void)
 static void increment_windows_lock_ref_count(files_struct *fsp)
 {
 	struct lock_ref_count_key tmp;
-	TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
-	TDB_DATA dbuf;
-	int lock_ref_count;
-
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-	if (dbuf.dptr == NULL) {
-		dbuf.dptr = (uint8 *)SMB_MALLOC_P(int);
-		if (!dbuf.dptr) {
-			smb_panic("increment_windows_lock_ref_count: malloc fail");
-		}
-		memset(dbuf.dptr, '\0', sizeof(int));
-		dbuf.dsize = sizeof(int);
-	}
+	struct db_record *rec;
+	int lock_ref_count = 0;
+	NTSTATUS status;
 
-	memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
-	lock_ref_count++;
-	memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-	
-	if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
-		smb_panic("increment_windows_lock_ref_count: tdb_store_fail");
-	}
-	SAFE_FREE(dbuf.dptr);
-
-	DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
-		fsp->fsp_name, lock_ref_count ));
-}
+	rec = posix_pending_close_db->fetch_locked(
+		posix_pending_close_db, talloc_tos(),
+		locking_ref_count_key_fsp(fsp, &tmp));
 
-static void decrement_windows_lock_ref_count(files_struct *fsp)
-{
-	struct lock_ref_count_key tmp;
-	TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
-	TDB_DATA dbuf;
-	int lock_ref_count;
+	SMB_ASSERT(rec != NULL);
 
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-	if (!dbuf.dptr) {
-		smb_panic("decrement_windows_lock_ref_count: logic error");
+	if (rec->value.dptr != NULL) {
+		SMB_ASSERT(rec->value.dsize == sizeof(lock_ref_count));
+		memcpy(&lock_ref_count, rec->value.dptr,
+		       sizeof(lock_ref_count));
 	}
 
-	memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
-	lock_ref_count--;
-	memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
+	lock_ref_count++;
 
-	if (lock_ref_count < 0) {
-		smb_panic("decrement_windows_lock_ref_count: lock_count logic error");
-	}
+	status = rec->store(rec, make_tdb_data((uint8 *)&lock_ref_count,
+					       sizeof(lock_ref_count)), 0);
 
-	if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
-		smb_panic("decrement_windows_lock_ref_count: tdb_store_fail");
-	}
-	SAFE_FREE(dbuf.dptr);
+	SMB_ASSERT(NT_STATUS_IS_OK(status));
+
+	TALLOC_FREE(rec);
 
-	DEBUG(10,("decrement_windows_lock_ref_count for file now %s = %d\n",
-		fsp->fsp_name, lock_ref_count ));
+	DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
+		  fsp->fsp_name, lock_ref_count ));
 }
 
 /****************************************************************************
@@ -462,30 +434,38 @@ static void decrement_windows_lock_ref_count(files_struct *fsp)
 void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
 {
 	struct lock_ref_count_key tmp;
-	TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
-	TDB_DATA dbuf;
-	int lock_ref_count;
+	struct db_record *rec;
+	int lock_ref_count = 0;
+	NTSTATUS status;
 
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-	if (!dbuf.dptr) {
-		return;
-	}
+	rec = posix_pending_close_db->fetch_locked(
+		posix_pending_close_db, talloc_tos(),
+		locking_ref_count_key_fsp(fsp, &tmp));
+
+	SMB_ASSERT((rec != NULL)
+		   && (rec->value.dptr != NULL)
+		   && (rec->value.dsize == sizeof(lock_ref_count)));
+
+	memcpy(&lock_ref_count, rec->value.dptr, sizeof(lock_ref_count));
+
+	SMB_ASSERT(lock_ref_count > 0);
 
-	memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
 	lock_ref_count -= dcount;
 
-	if (lock_ref_count < 0) {
-		smb_panic("reduce_windows_lock_ref_count: lock_count logic error");
-	}
-	memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
-	
-	if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
-		smb_panic("reduce_windows_lock_ref_count: tdb_store_fail");
-	}
-	SAFE_FREE(dbuf.dptr);
+	status = rec->store(rec, make_tdb_data((uint8 *)&lock_ref_count,
+					       sizeof(lock_ref_count)), 0);
+
+	SMB_ASSERT(NT_STATUS_IS_OK(status));
+
+	TALLOC_FREE(rec);
 
 	DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
-		fsp->fsp_name, lock_ref_count ));
+		  fsp->fsp_name, lock_ref_count ));
+}
+
+static void decrement_windows_lock_ref_count(files_struct *fsp)
+{
+	reduce_windows_lock_ref_count(fsp, 1);
 }
 
 /****************************************************************************
@@ -495,20 +475,25 @@ void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
 static int get_windows_lock_ref_count(files_struct *fsp)
 {
 	struct lock_ref_count_key tmp;
-	TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
 	TDB_DATA dbuf;
-	int lock_ref_count;
+	int res;
+	int lock_ref_count = 0;
 
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-	if (!dbuf.dptr) {
-		lock_ref_count = 0;
-	} else {
-		memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+	res = posix_pending_close_db->fetch(
+		posix_pending_close_db, talloc_tos(),
+		locking_ref_count_key_fsp(fsp, &tmp), &dbuf);
+
+	SMB_ASSERT(res == 0);
+
+	if (dbuf.dsize != 0) {
+		SMB_ASSERT(dbuf.dsize == sizeof(lock_ref_count));
+		memcpy(&lock_ref_count, dbuf.dptr, sizeof(lock_ref_count));
+		TALLOC_FREE(dbuf.dptr);
 	}
-	SAFE_FREE(dbuf.dptr);
 
 	DEBUG(10,("get_windows_lock_count for file %s = %d\n",
-		fsp->fsp_name, lock_ref_count ));
+		  fsp->fsp_name, lock_ref_count ));
+
 	return lock_ref_count;
 }
 
@@ -519,11 +504,21 @@ static int get_windows_lock_ref_count(files_struct *fsp)
 static void delete_windows_lock_ref_count(files_struct *fsp)
 {
 	struct lock_ref_count_key tmp;
-	TDB_DATA kbuf = locking_ref_count_key_fsp(fsp, &tmp);
+	struct db_record *rec;
+
+	rec = posix_pending_close_db->fetch_locked(
+		posix_pending_close_db, talloc_tos(),
+		locking_ref_count_key_fsp(fsp, &tmp));
+
+	SMB_ASSERT(rec != NULL);
 
 	/* Not a bug if it doesn't exist - no locks were ever granted. */
-	tdb_delete(posix_pending_close_tdb, kbuf);
-	DEBUG(10,("delete_windows_lock_ref_count for file %s\n", fsp->fsp_name));
+
+	rec->delete_rec(rec);
+	TALLOC_FREE(rec);
+
+	DEBUG(10,("delete_windows_lock_ref_count for file %s\n",
+		  fsp->fsp_name));
 }
 
 /****************************************************************************
@@ -532,30 +527,35 @@ static void delete_windows_lock_ref_count(files_struct *fsp)
 
 static void add_fd_to_close_entry(files_struct *fsp)
 {
-	TDB_DATA kbuf = fd_array_key_fsp(fsp);
-	TDB_DATA dbuf;
+	struct db_record *rec;
+	uint8_t *new_data;
+	NTSTATUS status;
 
-	dbuf.dptr = NULL;
-	dbuf.dsize = 0;
+	rec = posix_pending_close_db->fetch_locked(
+		posix_pending_close_db, talloc_tos(),
+		fd_array_key_fsp(fsp));
 
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+	SMB_ASSERT(rec != NULL);
 
-	dbuf.dptr = (uint8 *)SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int));
-	if (!dbuf.dptr) {
-		smb_panic("add_fd_to_close_entry: SMB_REALLOC failed");
-	}
+	new_data = TALLOC_ARRAY(
+		rec, uint8_t, rec->value.dsize + sizeof(fsp->fh->fd));
 
-	memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
-	dbuf.dsize += sizeof(int);
+	SMB_ASSERT(new_data != NULL);
 
-	if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
-		smb_panic("add_fd_to_close_entry: tdb_store_fail");
-	}
+	memcpy(new_data, rec->value.dptr, rec->value.dsize);
+	memcpy(new_data + rec->value.dsize,
+	       &fsp->fh->fd, sizeof(fsp->fh->fd));
 
-	DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
-		fsp->fh->fd, fsp->fsp_name ));
+	status = rec->store(
+		rec, make_tdb_data(new_data,
+				   rec->value.dsize + sizeof(fsp->fh->fd)), 0);
+
+	SMB_ASSERT(NT_STATUS_IS_OK(status));
 
-	SAFE_FREE(dbuf.dptr);
+	TALLOC_FREE(rec);
+
+	DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
+		  fsp->fh->fd, fsp->fsp_name ));
 }
 
 /****************************************************************************
@@ -564,37 +564,41 @@ static void add_fd_to_close_entry(files_struct *fsp)
 
 static void delete_close_entries(files_struct *fsp)
 {
-	TDB_DATA kbuf = fd_array_key_fsp(fsp);
+	struct db_record *rec;
 
-	if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) {
-		smb_panic("delete_close_entries: tdb_delete failed");
-	}
+	rec = posix_pending_close_db->fetch_locked(
+		posix_pending_close_db, talloc_tos(),
+		fd_array_key_fsp(fsp));
+
+	SMB_ASSERT(rec != NULL);
+	rec->delete_rec(rec);
+	TALLOC_FREE(rec);
 }
 
 /****************************************************************************
- Get the array of POSIX pending close records for an open fsp. Caller must
- free. Returns number of entries.
+ Get the array of POSIX pending close records for an open fsp. Returns number
+ of entries.
 ****************************************************************************/
 
-static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
+static size_t get_posix_pending_close_entries(TALLOC_CTX *mem_ctx,
+					      files_struct *fsp, int **entries)
 {
-	TDB_DATA kbuf = fd_array_key_fsp(fsp);
 	TDB_DATA dbuf;
-	size_t count = 0;
+	int res;
 
-	*entries = NULL;
-	dbuf.dptr = NULL;
+	res = posix_pending_close_db->fetch(
+		posix_pending_close_db, mem_ctx, fd_array_key_fsp(fsp),
+		&dbuf);
 
-	dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+	SMB_ASSERT(res == 0);
 
-	if (!dbuf.dptr) {
+	if (dbuf.dsize == 0) {
+		*entries = NULL;
 		return 0;
 	}
 
 	*entries = (int *)dbuf.dptr;
-	count = (size_t)(dbuf.dsize / sizeof(int));
-
-	return count;
+	return (size_t)(dbuf.dsize / sizeof(int));
 }
 
 /****************************************************************************
@@ -641,7 +645,7 @@ NTSTATUS fd_close_posix(struct connection_struct *conn, files_struct *fsp)
 	 * from the tdb and close them all.
 	 */
 
-	count = get_posix_pending_close_entries(fsp, &fd_array);
+	count = get_posix_pending_close_entries(talloc_tos(), fsp, &fd_array);
 
 	if (count) {
 		DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
@@ -660,7 +664,7 @@ NTSTATUS fd_close_posix(struct connection_struct *conn, files_struct *fsp)
 		delete_close_entries(fsp);
 	}
 
-	SAFE_FREE(fd_array);
+	TALLOC_FREE(fd_array);
 
 	/* Don't need a lock ref count on this dev/ino anymore. */
 	delete_windows_lock_ref_count(fsp);
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 0e73ba9..b83d684 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -2444,6 +2444,243 @@ static struct case_semantics_state *set_posix_case_semantics(TALLOC_CTX *mem_ctx
  * Wrapper around open_file_ntcreate and open_directory
  */
 
+NTSTATUS create_file_unixpath(connection_struct *conn,
+			      struct smb_request *req,
+			      const char *fname,
+			      uint32_t access_mask,
+			      uint32_t share_access,
+			      uint32_t create_disposition,
+			      uint32_t create_options,
+			      uint32_t file_attributes,
+			      uint32_t oplock_request,
+			      SMB_BIG_UINT allocation_size,
+			      struct security_descriptor *sd,
+			      struct ea_list *ea_list,
+
+			      files_struct **result,
+			      int *pinfo,
+			      SMB_STRUCT_STAT *psbuf)
+{
+	SMB_STRUCT_STAT sbuf;
+	int info = FILE_WAS_OPENED;
+	files_struct *fsp = NULL;
+	NTSTATUS status;
+
+	DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
+		  "file_attributes = 0x%x, share_access = 0x%x, "
+		  "create_disposition = 0x%x create_options = 0x%x "
+		  "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
+		  "fname = %s\n",
+		  (unsigned int)access_mask,
+		  (unsigned int)file_attributes,
+		  (unsigned int)share_access,
+		  (unsigned int)create_disposition,
+		  (unsigned int)create_options,
+		  (unsigned int)oplock_request,
+		  ea_list, sd, fname));
+
+	if (create_options & FILE_OPEN_BY_FILE_ID) {
+		status = NT_STATUS_NOT_SUPPORTED;
+		goto fail;
+	}
+
+	if (req == NULL) {
+		oplock_request |= INTERNAL_OPEN_ONLY;
+	}
+
+	if (psbuf != NULL) {
+		sbuf = *psbuf;
+	}
+	else {
+		SET_STAT_INVALID(sbuf);
+	}
+
+	/* This is the correct thing to do (check every time) but can_delete
+	 * is expensive (it may have to read the parent directory
+	 * permissions). So for now we're not doing it unless we have a strong
+	 * hint the client is really going to delete this file. If the client
+	 * is forcing FILE_CREATE let the filesystem take care of the
+	 * permissions. */
+
+	/* Setting FILE_SHARE_DELETE is the hint. */
+
+	if (lp_acl_check_permissions(SNUM(conn))
+	    && (create_disposition != FILE_CREATE)
+	    && (share_access & FILE_SHARE_DELETE)
+	    && (access_mask & DELETE_ACCESS)
+	    && (((dos_mode(conn, fname, &sbuf) & FILE_ATTRIBUTE_READONLY)
+		 && !lp_delete_readonly(SNUM(conn)))
+		|| !can_delete_file_in_directory(conn, fname))) {
+		status = NT_STATUS_ACCESS_DENIED;
+		goto fail;
+	}
+
+#if 0
+	/* We need to support SeSecurityPrivilege for this. */
+	if ((access_mask & SEC_RIGHT_SYSTEM_SECURITY) &&
+	    !user_has_privileges(current_user.nt_user_token,
+				 &se_security)) {
+		status = NT_STATUS_PRIVILEGE_NOT_HELD;
+		goto fail;
+	}
+#endif
+
+	/*
+	 * If it's a request for a directory open, deal with it separately.
+	 */
+
+	if (create_options & FILE_DIRECTORY_FILE) {
+
+		/* Can't open a temp directory. IFS kit test. */
+		if (file_attributes & FILE_ATTRIBUTE_TEMPORARY) {
+			status = NT_STATUS_INVALID_PARAMETER;
+			goto fail;
+		}
+
+		/*
+		 * We will get a create directory here if the Win32
+		 * app specified a security descriptor in the
+		 * CreateDirectory() call.
+		 */
+
+		oplock_request = 0;
+		status = open_directory(
+			conn, req, fname, &sbuf, access_mask, share_access,
+			create_disposition, create_options, file_attributes,
+			&info, &fsp);
+	} else {
+
+		/*
+		 * Ordinary file case.


-- 
Samba Shared Repository


More information about the samba-cvs mailing list