[SCM] Samba Shared Repository - branch v4-0-test updated

Karolin Seeger kseeger at samba.org
Fri Aug 30 04:35:04 MDT 2013


The branch, v4-0-test has been updated
       via  25ded36 Fix the UNIX extensions CHOWN calls to use FCHOWN if available, else LCHOWN.
       via  ac3c32d Allow UNIX extensions client to act on open fsp instead of pathname if available.
       via  335e417 Fix the erroneous masking of chmod requests via the UNIX extensions.
       via  9891d98 Fix bug #9166 - Starting smbd or nmbd with stdin from /dev/null results in "EOF on stdin"
       via  d63a5e5 s3: Fix some blank line endings
       via  c65a4e8 smbd: Simplify dropbox special case in unix_convert
       via  c72c00c smbd: Fix a profile problem
      from  1787174 Fix bug #10063 - source3/lib/util.c:1493 leaking memory w/ pam_winbind.so / winbind

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


- Log -----------------------------------------------------------------
commit 25ded3685dddd85b8d439023503dc11e6502e5bd
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Aug 21 12:20:48 2013 -0700

    Fix the UNIX extensions CHOWN calls to use FCHOWN if available, else LCHOWN.
    
    UNIX extensions calls must never deref links.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Simo Sorce <idra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Mon Aug 26 20:19:46 CEST 2013 on sn-devel-104
    
    (cherry picked from commit d1593a20f3a5ebf287477dfa8f5ab31dca3dd0c3)
    
    The last 3 patches address bug #10121 - masks incorrectly applied to UNIX
    extension permission changes.
    
    Autobuild-User(v4-0-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-0-test): Fri Aug 30 12:34:12 CEST 2013 on sn-devel-104

commit ac3c32d0d51f626d6198c6994daff4fc48f6b5ae
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Aug 21 12:10:05 2013 -0700

    Allow UNIX extensions client to act on open fsp instead of pathname if available.
    
    Eliminates possible race condition on pathname op.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Simo Sorce <idra at samba.org>
    (cherry picked from commit f1ff97fc022adaacaa23b7da250be6f7d51c6ac7)

commit 335e4178220b848cd822428359b589bc599e81eb
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Aug 21 12:03:25 2013 -0700

    Fix the erroneous masking of chmod requests via the UNIX extensions.
    
    Changed from switch statement to if, as "create mask", "force create mode"
    are only applied to new files, not existing ones. "directory mask",
    "force directory mode" are only applied to new directories, not existing
    ones.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Simo Sorce <idra at samba.org>
    (cherry picked from commit bd0156988b34feaf91c3046f7ec78f0833222395)

commit 9891d9870060e61f33a835363dea8f5267d6e8ca
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Jun 10 13:33:40 2013 -0700

    Fix bug #9166 - Starting smbd or nmbd with stdin from /dev/null results in "EOF on stdin"
    
    Only install the stdin handler if it's a pipe or fifo.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>

commit d63a5e5c7b38b6eb906e1bbe497fc9c07d5961ce
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Sep 26 16:53:48 2012 -0700

    s3: Fix some blank line endings
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Thu Sep 27 07:57:03 CEST 2012 on sn-devel-104
    (cherry picked from commit aad669b53eca99f86c2e630bf3f2e9f594fed9c1)

commit c65a4e82886487a389ab2c1d21487e0d16f6fb16
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Aug 19 10:26:00 2013 +0000

    smbd: Simplify dropbox special case in unix_convert
    
    EACCESS needs special treatment: If we want to create a fresh file,
    return OBJECT_PATH_NOT_FOUND, so that the client will continue creating
    the file. If the client wants us to open a potentially existing file,
    we need to correctly return ACCESS_DENIED.
    
    This patch makes this behaviour hopefully a bit clearer than the code
    before did.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Mon Aug 26 12:14:26 CEST 2013 on sn-devel-104
    
    The last 2 patches address bug #10114 - Dropbox (write-only-directory) case
    isn't handled correctly in pathname lookup.

commit c72c00cd126194aaa51d74585b0ca32cf224663b
Author: Volker Lendecke <Volker.Lendecke at SerNet.DE>
Date:   Tue Jul 9 11:02:39 2013 -0700

    smbd: Fix a profile problem
    
    When trying to read a profile, under certain circumstances Windows tries
    to read with its machine account first. The profile previously written
    was stored with an ACL that only allows access for the user and not
    the machine. Windows should get an NT_STATUS_ACCESS_DENIED when using
    the machine account, making it retry with the user account (which would
    then succeed).
    
    Samba under these circumstances erroneously gives
    NT_STATUS_OBJECT_PATH_NOT_FOUND, which makes Windows give up and not
    retry. The reasons is the "dropbox" patch in unix_convert, turning EACCESS
    on the last path component to OBJECT_PATH_NOT_FOUND. This patch makes
    the dropbox behaviour only kick in when we are creating a file. I think
    this is an abstraction violation. unix_convert() should not have to know
    about the create_disposition, but given that we have pathname resolution
    separated from the core open code right now this is the best we can do.
    
    Signed-off-by: Volker Lendecke <Volker.Lendecke at SerNet.DE>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 source3/nmbd/nmbd.c         |   14 ++++++++++-
 source3/smbd/filename.c     |   28 ++++++++++++++++++----
 source3/smbd/nttrans.c      |    6 +++-
 source3/smbd/reply.c        |   48 ++++++++++++++++++++------------------
 source3/smbd/server.c       |   14 ++++++++++-
 source3/smbd/smb2_create.c  |    3 +-
 source3/smbd/smbd.h         |    1 +
 source3/smbd/trans2.c       |   53 ++++++++++++++++++++++++++++++------------
 source3/winbindd/winbindd.c |   23 ++++++++++++++----
 source4/smbd/server.c       |   13 ++++++++--
 10 files changed, 147 insertions(+), 56 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c
index d4df202..196b582 100644
--- a/source3/nmbd/nmbd.c
+++ b/source3/nmbd/nmbd.c
@@ -130,8 +130,20 @@ static bool nmbd_setup_stdin_handler(struct messaging_context *msg, bool foregro
 		/* if we are running in the foreground then look for
 		   EOF on stdin, and exit if it happens. This allows
 		   us to die if the parent process dies
+		   Only do this on a pipe or socket, no other device.
 		*/
-		tevent_add_fd(nmbd_event_context(), nmbd_event_context(), 0, TEVENT_FD_READ, nmbd_stdin_handler, msg);
+		struct stat st;
+		if (fstat(0, &st) != 0) {
+			return false;
+		}
+		if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
+			tevent_add_fd(nmbd_event_context(),
+				nmbd_event_context(),
+				0,
+				TEVENT_FD_READ,
+				nmbd_stdin_handler,
+				msg);
+		}
 	}
 
 	return true;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 9b05de3..fc96550 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -718,12 +718,30 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 
 				/*
 				 * ENOENT/EACCESS are the only valid errors
-				 * here. EACCESS needs handling here for
-				 * "dropboxes", i.e. directories where users
-				 * can only put stuff with permission -wx.
+				 * here.
 				 */
-				if ((errno != 0) && (errno != ENOENT)
-				    && (errno != EACCES)) {
+
+				if (errno == EACCES) {
+					if (ucf_flags & UCF_CREATING_FILE) {
+						/*
+						 * This is the dropbox
+						 * behaviour. A dropbox is a
+						 * directory with only -wx
+						 * permissions, so
+						 * get_real_filename fails
+						 * with EACCESS, it needs to
+						 * list the directory. We
+						 * nevertheless want to allow
+						 * users creating a file.
+						 */
+						status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+					} else {
+						status = NT_STATUS_ACCESS_DENIED;
+					}
+					goto fail;
+				}
+
+				if ((errno != 0) && (errno != ENOENT)) {
 					/*
 					 * ENOTDIR and ELOOP both map to
 					 * NT_STATUS_OBJECT_PATH_NOT_FOUND
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index ee0deb8..b7dfa8c 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -538,7 +538,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
 				conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				(create_disposition == FILE_CREATE)
+				  ? UCF_CREATING_FILE : 0,
 				NULL,
 				&smb_fname);
 
@@ -1117,7 +1118,8 @@ static void call_nt_transact_create(connection_struct *conn,
 				conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				(create_disposition == FILE_CREATE)
+				  ? UCF_CREATING_FILE : 0,
 				NULL,
 				&smb_fname);
 
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 3b2a493..2d729ec 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1905,11 +1905,20 @@ void reply_open(struct smb_request *req)
 		goto out;
 	}
 
+	if (!map_open_params_to_ntcreate(fname, deny_mode,
+					 OPENX_FILE_EXISTS_OPEN, &access_mask,
+					 &share_mode, &create_disposition,
+					 &create_options, &private_flags)) {
+		reply_force_doserror(req, ERRDOS, ERRbadaccess);
+		goto out;
+	}
+
 	status = filename_convert(ctx,
 				conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				(create_disposition == FILE_CREATE)
+				  ? UCF_CREATING_FILE : 0,
 				NULL,
 				&smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1923,14 +1932,6 @@ void reply_open(struct smb_request *req)
 		goto out;
 	}
 
-	if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
-					 OPENX_FILE_EXISTS_OPEN, &access_mask,
-					 &share_mode, &create_disposition,
-					 &create_options, &private_flags)) {
-		reply_force_doserror(req, ERRDOS, ERRbadaccess);
-		goto out;
-	}
-
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
@@ -2080,11 +2081,22 @@ void reply_open_and_X(struct smb_request *req)
 		goto out;
 	}
 
+	if (!map_open_params_to_ntcreate(fname, deny_mode,
+					 smb_ofun,
+					 &access_mask, &share_mode,
+					 &create_disposition,
+					 &create_options,
+					 &private_flags)) {
+		reply_force_doserror(req, ERRDOS, ERRbadaccess);
+		goto out;
+	}
+
 	status = filename_convert(ctx,
 				conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				(create_disposition == FILE_CREATE)
+				  ? UCF_CREATING_FILE : 0,
 				NULL,
 				&smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -2098,16 +2110,6 @@ void reply_open_and_X(struct smb_request *req)
 		goto out;
 	}
 
-	if (!map_open_params_to_ntcreate(smb_fname->base_name, deny_mode,
-					 smb_ofun,
-					 &access_mask, &share_mode,
-					 &create_disposition,
-					 &create_options,
-					 &private_flags)) {
-		reply_force_doserror(req, ERRDOS, ERRbadaccess);
-		goto out;
-	}
-
 	status = SMB_VFS_CREATE_FILE(
 		conn,					/* conn */
 		req,					/* req */
@@ -2327,7 +2329,7 @@ void reply_mknew(struct smb_request *req)
 				conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				UCF_CREATING_FILE,
 				NULL,
 				&smb_fname);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -2468,7 +2470,7 @@ void reply_ctemp(struct smb_request *req)
 		status = filename_convert(ctx, conn,
 				req->flags2 & FLAGS2_DFS_PATHNAMES,
 				fname,
-				0,
+				UCF_CREATING_FILE,
 				NULL,
 				&smb_fname);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -5827,7 +5829,7 @@ void reply_mkdir(struct smb_request *req)
 	status = filename_convert(ctx, conn,
 				 req->flags2 & FLAGS2_DFS_PATHNAMES,
 				 directory,
-				 0,
+				 UCF_CREATING_FILE,
 				 NULL,
 				 &smb_dname);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index e9bf9c9..a86fa48 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1561,8 +1561,20 @@ extern void build_options(bool screen);
 		/* if we are running in the foreground then look for
 		   EOF on stdin, and exit if it happens. This allows
 		   us to die if the parent process dies
+		   Only do this on a pipe or socket, no other device.
 		*/
-		tevent_add_fd(ev_ctx, parent, 0, TEVENT_FD_READ, smbd_stdin_handler, NULL);
+		struct stat st;
+		if (fstat(0, &st) != 0) {
+			return false;
+		}
+		if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
+			tevent_add_fd(ev_ctx,
+					parent,
+					0,
+					TEVENT_FD_READ,
+					smbd_stdin_handler,
+					NULL);
+		}
 	}
 
 	smbd_parent_loop(ev_ctx, parent);
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index edbd50f..c4d4991 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -871,7 +871,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 						  smb1req->conn,
 						  smb1req->flags2 & FLAGS2_DFS_PATHNAMES,
 						  fname,
-						  0,    /* unix_convert flags */
+						  (in_create_disposition == FILE_CREATE) ?
+						  UCF_CREATING_FILE : 0,
 						  NULL, /* ppath_contains_wcards */
 						  &smb_fname);
 			if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/smbd.h b/source3/smbd/smbd.h
index a5b211a..e769157 100644
--- a/source3/smbd/smbd.h
+++ b/source3/smbd/smbd.h
@@ -73,5 +73,6 @@ struct trans_state {
 #define UCF_COND_ALLOW_WCARD_LCOMP	0x00000004
 #define UCF_POSIX_PATHNAMES		0x00000008
 #define UCF_UNIX_NAME_LOOKUP		0x00000010
+#define UCF_CREATING_FILE		0x00000020
 
 #endif /* _SMBD_SMBD_H */
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 5031442..74310c2 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -1451,20 +1451,22 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn,
 	ret |= ((perms & UNIX_SET_UID ) ? S_ISUID : 0);
 #endif
 
-	switch (ptype) {
-	case PERM_NEW_FILE:
-	case PERM_EXISTING_FILE:
-		/* Apply mode mask */
+	if (ptype == PERM_NEW_FILE) {
+		/*
+		 * "create mask"/"force create mode" are
+		 * only applied to new files, not existing ones.
+		 */
 		ret &= lp_create_mask(SNUM(conn));
 		/* Add in force bits */
 		ret |= lp_force_create_mode(SNUM(conn));
-		break;
-	case PERM_NEW_DIR:
-	case PERM_EXISTING_DIR:
+	} else if (ptype == PERM_NEW_DIR) {
+		/*
+		 * "directory mask"/"force directory mode" are
+		 * only applied to new directories, not existing ones.
+		 */
 		ret &= lp_dir_mask(SNUM(conn));
 		/* Add in force bits */
 		ret |= lp_force_dir_mode(SNUM(conn));
-		break;
 	}
 
 	*ret_perms = ret;
@@ -7152,11 +7154,18 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 	 */
 
 	if (raw_unixmode != SMB_MODE_NO_CHANGE) {
+		int ret;
+
 		DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
 			  "setting mode 0%o for file %s\n",
 			  (unsigned int)unixmode,
 			  smb_fname_str_dbg(smb_fname)));
-		if (SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode) != 0) {
+		if (fsp && fsp->fh->fd != -1) {
+			ret = SMB_VFS_FCHMOD(fsp, unixmode);
+		} else {
+			ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
+		}
+		if (ret != 0) {
 			return map_nt_error_from_unix(errno);
 		}
 	}
@@ -7174,12 +7183,15 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 			  (unsigned int)set_owner,
 			  smb_fname_str_dbg(smb_fname)));
 
-		if (S_ISLNK(sbuf.st_ex_mode)) {
+		if (fsp && fsp->fh->fd != -1) {
+			ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+		} else {
+			/*
+			 * UNIX extensions calls must always operate
+			 * on symlinks.
+			 */
 			ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name,
 					     set_owner, (gid_t)-1);
-		} else {
-			ret = SMB_VFS_CHOWN(conn, smb_fname->base_name,
-					    set_owner, (gid_t)-1);
 		}
 
 		if (ret != 0) {
@@ -7197,12 +7209,23 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn,
 
 	if ((set_grp != (uid_t)SMB_GID_NO_CHANGE) &&
 	    (sbuf.st_ex_gid != set_grp)) {
+		int ret;
+
 		DEBUG(10,("smb_set_file_unix_basic: SMB_SET_FILE_UNIX_BASIC "
 			  "changing group %u for file %s\n",
 			  (unsigned int)set_owner,
 			  smb_fname_str_dbg(smb_fname)));
-		if (SMB_VFS_CHOWN(conn, smb_fname->base_name, (uid_t)-1,
-				  set_grp) != 0) {
+		if (fsp && fsp->fh->fd != -1) {
+			ret = SMB_VFS_FCHOWN(fsp, set_owner, (gid_t)-1);
+		} else {
+			/*
+			 * UNIX extensions calls must always operate
+			 * on symlinks.
+			 */
+			ret = SMB_VFS_LCHOWN(conn, smb_fname->base_name, (uid_t)-1,
+				  set_grp);
+		}
+		if (ret != 0) {
 			status = map_nt_error_from_unix(errno);
 			if (delete_on_fail) {
 				SMB_VFS_UNLINK(conn, smb_fname);
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index eab62a7..21cc5f2 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
 
    Winbind daemon for ntdom nss module
@@ -216,7 +216,7 @@ static void winbindd_stdin_handler(struct tevent_context *ev,
 	char c;
 	if (read(0, &c, 1) != 1) {
 		bool *is_parent = talloc_get_type_abort(private_data, bool);
-		
+
 		/* we have reached EOF on stdin, which means the
 		   parent has exited. Shutdown the server */
 		DEBUG(0,("EOF on stdin (is_parent=%d)\n",
@@ -278,20 +278,33 @@ bool winbindd_setup_stdin_handler(bool parent, bool foreground)
 	bool *is_parent;
 
 	if (foreground) {
+		struct stat st;
+
 		is_parent = talloc(winbind_event_context(), bool);
 		if (!is_parent) {
 			return false;
 		}
-		
+
 		*is_parent = parent;
 
 		/* if we are running in the foreground then look for
 		   EOF on stdin, and exit if it happens. This allows
 		   us to die if the parent process dies
+		   Only do this on a pipe or socket, no other device.
 		*/
-		tevent_add_fd(winbind_event_context(), is_parent, 0, TEVENT_FD_READ, winbindd_stdin_handler, is_parent);
+		if (fstat(0, &st) != 0) {
+			return false;
+		}
+		if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
+			tevent_add_fd(winbind_event_context(),
+					is_parent,
+					0,
+					TEVENT_FD_READ,
+					winbindd_stdin_handler,
+					is_parent);
+		}
 	}
-	
+
 	return true;
 }
 
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index 17b6ce5..8a9de48 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -303,6 +303,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 	NTSTATUS status;
 	const char *model = "standard";
 	int max_runtime = 0;
+	struct stat st;
 	enum {
 		OPT_DAEMON = 1000,
 		OPT_INTERACTIVE,
@@ -447,9 +448,15 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
 #ifdef SIGTTIN
 	signal(SIGTTIN, SIG_IGN);
 #endif
-	tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags,
-		      server_stdin_handler,
-		      discard_const(binary_name));
+
+	if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
+		tevent_add_fd(event_ctx,
+				event_ctx,
+				0,
+				stdin_event_flags,
+				server_stdin_handler,
+				discard_const(binary_name));
+	}
 
 	if (max_runtime) {
 		DEBUG(0,("Called with maxruntime %d - current ts %llu\n",


-- 
Samba Shared Repository


More information about the samba-cvs mailing list