[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Apr 4 17:37:03 MDT 2012


The branch, master has been updated
       via  704ea47 Third part of fix for bug #8837 - smbd crashes when deleting directory and veto files are enabled.
       via  c10ed73 Second part of bugfix for bug #8837 - smbd crashes when deleting directory and veto files are enabled.
       via  f042de2 First part of fix for bug 8837 - smbd crashes when deleting directory and veto files are enabled.
      from  d0fbe16 systemd: Add samba service file.

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


- Log -----------------------------------------------------------------
commit 704ea4729b499ae2716cfe6ad5d952bcb1251a3b
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Apr 4 14:57:12 2012 -0700

    Third part of fix for bug #8837 - smbd crashes when deleting directory and veto files are enabled.
    
    Use correct check to see if veto files has been enabled. Even if not
    set lp_veto_files() returns a valid string address (to a '\0' character).
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Thu Apr  5 01:36:04 CEST 2012 on sn-devel-104

commit c10ed730d481e3d5b6710999b11b8e6969e1c16e
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Apr 4 14:54:02 2012 -0700

    Second part of bugfix for bug #8837 - smbd crashes when deleting directory and veto files are enabled.
    
    Store the 'struct security_token' as well as the 'struct security_unix_token'
    inside the locking db when setting a delete on close.

commit f042de2f346c98a852957cdbb09a7f8ac871b69c
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Apr 4 14:53:10 2012 -0700

    First part of fix for bug 8837 - smbd crashes when deleting directory and veto files are enabled.
    
    Add some const to the sec_ctx code.

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

Summary of changes:
 source3/librpc/idl/open_files.idl |    1 +
 source3/locking/locking.c         |   51 +++++++++++++++++++++++++++++++------
 source3/locking/proto.h           |   10 ++++++-
 source3/smbd/close.c              |   25 +++++++++++------
 source3/smbd/proto.h              |    2 +-
 source3/smbd/reply.c              |    8 ++++-
 source3/smbd/sec_ctx.c            |    2 +-
 source3/smbd/trans2.c             |    1 +
 8 files changed, 77 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl
index cefb75a..98e1c32 100644
--- a/source3/librpc/idl/open_files.idl
+++ b/source3/librpc/idl/open_files.idl
@@ -27,6 +27,7 @@ interface open_files
 
 	typedef [public] struct {
 		uint32		name_hash;
+		security_token *delete_nt_token;
 		security_unix_token *delete_token;
 	} delete_token;
 
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 149a79d..cc92152 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -867,6 +867,7 @@ static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct
 
 static bool add_delete_on_close_token(struct share_mode_data *d,
 			uint32_t name_hash,
+			const struct security_token *nt_tok,
 			const struct security_unix_token *tok)
 {
 	struct delete_token *tmp, *dtl;
@@ -880,6 +881,10 @@ static bool add_delete_on_close_token(struct share_mode_data *d,
 	dtl = &d->delete_tokens[d->num_delete_tokens];
 
 	dtl->name_hash = name_hash;
+	dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
+	if (dtl->delete_nt_token == NULL) {
+		return false;
+	}
 	dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
 	if (dtl->delete_token == NULL) {
 		return false;
@@ -903,6 +908,7 @@ static bool add_delete_on_close_token(struct share_mode_data *d,
 void set_delete_on_close_lck(files_struct *fsp,
 			struct share_mode_lock *lck,
 			bool delete_on_close,
+			const struct security_token *nt_tok,
 			const struct security_unix_token *tok)
 {
 	struct share_mode_data *d = lck->data;
@@ -910,8 +916,10 @@ void set_delete_on_close_lck(files_struct *fsp,
 	bool ret;
 
 	if (delete_on_close) {
+		SMB_ASSERT(nt_tok != NULL);
 		SMB_ASSERT(tok != NULL);
 	} else {
+		SMB_ASSERT(nt_tok == NULL);
 		SMB_ASSERT(tok == NULL);
 	}
 
@@ -921,6 +929,7 @@ void set_delete_on_close_lck(files_struct *fsp,
 			d->modified = true;
 			if (delete_on_close == false) {
 				/* Delete this entry. */
+				TALLOC_FREE(dt->delete_nt_token);
 				TALLOC_FREE(dt->delete_token);
 				*dt = d->delete_tokens[
 					d->num_delete_tokens-1];
@@ -929,6 +938,9 @@ void set_delete_on_close_lck(files_struct *fsp,
 			}
 			/* Replace this token with the
 			   given tok. */
+			TALLOC_FREE(dt->delete_nt_token);
+			dt->delete_nt_token = dup_nt_token(dt, nt_tok);
+			SMB_ASSERT(dt->delete_nt_token != NULL);
 			TALLOC_FREE(dt->delete_token);
 			dt->delete_token = copy_unix_token(dt, tok);
 			SMB_ASSERT(dt->delete_token != NULL);
@@ -940,11 +952,13 @@ void set_delete_on_close_lck(files_struct *fsp,
 		return;
 	}
 
-	ret = add_delete_on_close_token(lck->data, fsp->name_hash, tok);
+	ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
 	SMB_ASSERT(ret);
 }
 
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
+			const struct security_token *nt_tok,
+			const struct security_unix_token *tok)
 {
 	struct share_mode_lock *lck;
 
@@ -958,8 +972,15 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct s
 		return False;
 	}
 
-	set_delete_on_close_lck(fsp, lck, delete_on_close,
-			delete_on_close ? tok : NULL);
+	if (delete_on_close) {
+		set_delete_on_close_lck(fsp, lck, true,
+			nt_tok,
+			tok);
+	} else {
+		set_delete_on_close_lck(fsp, lck, false,
+			NULL,
+			NULL);
+	}
 
 	if (fsp->is_directory) {
 		SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
@@ -974,7 +995,15 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct s
 	return True;
 }
 
-const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
+/****************************************************************************
+ Return the NT token and UNIX token if there's a match. Return true if
+ found, false if not.
+****************************************************************************/
+
+bool get_delete_on_close_token(struct share_mode_lock *lck,
+					uint32_t name_hash,
+					const struct security_token **pp_nt_tok,
+					const struct security_unix_token **pp_tok)
 {
 	int i;
 
@@ -986,15 +1015,21 @@ const struct security_unix_token *get_delete_on_close_token(struct share_mode_lo
 		DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
 				(unsigned int)dt->name_hash ));
 		if (dt->name_hash == name_hash) {
-			return dt->delete_token;
+			if (pp_nt_tok) {
+				*pp_nt_tok = dt->delete_nt_token;
+			}
+			if (pp_tok) {
+				*pp_tok =  dt->delete_token;
+			}
+			return true;
 		}
 	}
-	return NULL;
+	return false;
 }
 
 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
 {
-	return (get_delete_on_close_token(lck, name_hash) != NULL);
+	return get_delete_on_close_token(lck, name_hash, NULL, NULL);
 }
 
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 3a6df37..54badd9 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -178,12 +178,18 @@ void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
 			     struct server_id pid);
 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp);
-const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash);
+bool get_delete_on_close_token(struct share_mode_lock *lck,
+				uint32_t name_hash,
+				const struct security_token **pp_nt_tok,
+				const struct security_unix_token **pp_tok);
 void set_delete_on_close_lck(files_struct *fsp,
 			struct share_mode_lock *lck,
 			bool delete_on_close,
+			const struct security_token *nt_tok,
+			const struct security_unix_token *tok);
+bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
+			const struct security_token *nt_tok,
 			const struct security_unix_token *tok);
-bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok);
 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash);
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
 bool set_write_time(struct file_id fileid, struct timespec write_time);
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 34ce785..da6d848 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -332,6 +332,8 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 	NTSTATUS tmp_status;
 	struct file_id id;
 	const struct security_unix_token *del_token = NULL;
+	const struct security_token *del_nt_token = NULL;
+	bool got_tokens = false;
 
 	/* Ensure any pending write time updates are done. */
 	if (fsp->update_write_time_event) {
@@ -395,7 +397,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 			became_user = True;
 		}
 		fsp->delete_on_close = true;
-		set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
+		set_delete_on_close_lck(fsp, lck, True,
+				get_current_nttok(conn),
+				get_current_utok(conn));
 		if (became_user) {
 			unbecome_user();
 		}
@@ -448,8 +452,9 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 	 */
 	fsp->update_write_time_on_close = false;
 
-	del_token = get_delete_on_close_token(lck, fsp->name_hash);
-	SMB_ASSERT(del_token != NULL);
+	got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
+					&del_nt_token, &del_token);
+	SMB_ASSERT(got_tokens);
 
 	if (!unix_token_equal(del_token, get_current_utok(conn))) {
 		/* Become the user who requested the delete. */
@@ -468,7 +473,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
 			    del_token->gid,
 			    del_token->ngroups,
 			    del_token->groups,
-			    NULL);
+			    del_nt_token);
 
 		changed_user = true;
 	}
@@ -541,7 +546,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
  	 */
 
 	fsp->delete_on_close = false;
-	set_delete_on_close_lck(fsp, lck, false, NULL);
+	set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
 
  done:
 
@@ -865,7 +870,7 @@ static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
 		return NT_STATUS_OK;
 	}
 
-	if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
+	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
@@ -1010,6 +1015,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 	bool delete_dir = False;
 	NTSTATUS status = NT_STATUS_OK;
 	NTSTATUS status1 = NT_STATUS_OK;
+	const struct security_token *del_nt_token = NULL;
 	const struct security_unix_token *del_token = NULL;
 
 	/*
@@ -1044,6 +1050,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 		send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
 					       fsp->fsp_name->base_name);
 		set_delete_on_close_lck(fsp, lck, true,
+				get_current_nttok(fsp->conn),
 				get_current_utok(fsp->conn));
 		fsp->delete_on_close = true;
 		if (became_user) {
@@ -1051,8 +1058,8 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 		}
 	}
 
-	del_token = get_delete_on_close_token(lck, fsp->name_hash);
-	delete_dir = (del_token != NULL);
+	delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
+					&del_nt_token, &del_token);
 
 	if (delete_dir) {
 		int i;
@@ -1084,7 +1091,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
 				del_token->gid,
 				del_token->ngroups,
 				del_token->groups,
-				NULL);
+				del_nt_token);
 
 		TALLOC_FREE(lck);
 
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 4bb57c0..1af0788 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -956,7 +956,7 @@ void server_encryption_shutdown(struct smbd_server_connection *sconn);
 
 bool unix_token_equal(const struct security_unix_token *t1, const struct security_unix_token *t2);
 bool push_sec_ctx(void);
-void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token);
+void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token);
 void set_root_sec_ctx(void);
 bool pop_sec_ctx(void);
 void init_sec_ctx(void);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 6e4bcab..8847310 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2546,7 +2546,9 @@ static NTSTATUS do_unlink(connection_struct *conn,
 	}
 
 	/* The set is across all open files on this dev/inode pair. */
-	if (!set_delete_on_close(fsp, True, conn->session_info->unix_token)) {
+	if (!set_delete_on_close(fsp, True,
+				conn->session_info->security_token,
+				conn->session_info->unix_token)) {
 		close_file(req, fsp, NORMAL_CLOSE);
 		return NT_STATUS_ACCESS_DENIED;
 	}
@@ -5664,7 +5666,9 @@ void reply_rmdir(struct smb_request *req)
 		goto out;
 	}
 
-	if (!set_delete_on_close(fsp, true, conn->session_info->unix_token)) {
+	if (!set_delete_on_close(fsp, true,
+			conn->session_info->security_token,
+			conn->session_info->unix_token)) {
 		close_file(req, fsp, ERROR_CLOSE);
 		reply_nterror(req, NT_STATUS_ACCESS_DENIED);
 		goto out;
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index 9959281..d83dbd0 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -305,7 +305,7 @@ static void set_unix_security_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *grou
  Set the current security context to a given user.
 ****************************************************************************/
 
-void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, struct security_token *token)
+void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, const struct security_token *token)
 {
 	struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
 
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 24642cd..da552f5 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -5885,6 +5885,7 @@ static NTSTATUS smb_set_file_disposition_info(connection_struct *conn,
 
 	/* The set is across all open files on this dev/inode pair. */
 	if (!set_delete_on_close(fsp, delete_on_close,
+				 conn->session_info->security_token,
 				 conn->session_info->unix_token)) {
 		return NT_STATUS_ACCESS_DENIED;
 	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list