[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Mar 30 20:10:02 MDT 2011


The branch, master has been updated
       via  21193c8 Don't burn 2k of stack on every iconv, use the heap when it's a slow call.
       via  f9a2f4f Fix bug #7996 - sgid bit lost on folder rename.
       via  cf5ed92 SMBTA: make vfs_smb_traffic_analyzer aware of the sendfile and recvfile functionality and store the results as common read/write results.
      from  b3ffcf8 lib/util/charset smb_panic() on incorrect use of strlen_m_ext

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


- Log -----------------------------------------------------------------
commit 21193c8eeba6d03f680ad34acbbb4cff14d87809
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 30 18:13:05 2011 -0700

    Don't burn 2k of stack on every iconv, use the heap when it's a slow call.
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Thu Mar 31 04:09:09 CEST 2011 on sn-devel-104

commit f9a2f4f47c71e5054c05703e72c24f2f5a87d993
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Mar 30 18:00:09 2011 -0700

    Fix bug #7996 - sgid bit lost on folder rename.
    
    Refuse to set dos attributes into unix mode bits on such a
    folder.

commit cf5ed92bb78806403a857b371ef15f985a4e2b64
Author: Holger Hetterich <hhetter at novell.com>
Date:   Tue Mar 29 22:16:10 2011 +0200

    SMBTA: make vfs_smb_traffic_analyzer aware of the sendfile and recvfile functionality and store the results as common read/write results.

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

Summary of changes:
 lib/util/charset/iconv.c                   |   41 ++++++++++++++++----------
 source3/modules/vfs_smb_traffic_analyzer.c |   42 +++++++++++++++++++++++++++-
 source3/smbd/dosmode.c                     |   21 ++++++++++++++
 source3/smbd/posix_acls.c                  |    2 +-
 source3/smbd/proto.h                       |    1 +
 5 files changed, 89 insertions(+), 18 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c
index e3cdbdf..24434ec 100644
--- a/lib/util/charset/iconv.c
+++ b/lib/util/charset/iconv.c
@@ -164,32 +164,41 @@ _PUBLIC_ size_t smb_iconv(smb_iconv_t cd,
 		 const char **inbuf, size_t *inbytesleft,
 		 char **outbuf, size_t *outbytesleft)
 {
-	char cvtbuf[2048];
-	size_t bufsize;
-
 	/* in many cases we can go direct */
 	if (cd->direct) {
 		return cd->direct(cd->cd_direct, 
 				  inbuf, inbytesleft, outbuf, outbytesleft);
 	}
 
-
 	/* otherwise we have to do it chunks at a time */
-	while (*inbytesleft > 0) {
-		char *bufp1 = cvtbuf;
-		const char *bufp2 = cvtbuf;
+	{
+#ifndef SMB_ICONV_BUFSIZE
+#define SMB_ICONV_BUFSIZE 2048
+#endif
+		size_t bufsize;
+		char *cvtbuf = talloc_array(cd, char, SMB_ICONV_BUFSIZE);
 
-		bufsize = sizeof(cvtbuf);
-		
-		if (cd->pull(cd->cd_pull, 
-			     inbuf, inbytesleft, &bufp1, &bufsize) == -1
-		    && errno != E2BIG) return -1;
+		if (!cvtbuf) {
+			return (size_t)-1;
+		}
 
-		bufsize = sizeof(cvtbuf) - bufsize;
+		while (*inbytesleft > 0) {
+			char *bufp1 = cvtbuf;
+			const char *bufp2 = cvtbuf;
 
-		if (cd->push(cd->cd_push, 
-			     &bufp2, &bufsize, 
-			     outbuf, outbytesleft) == -1) return -1;
+			bufsize = SMB_ICONV_BUFSIZE;
+
+			if (cd->pull(cd->cd_pull,
+				     inbuf, inbytesleft, &bufp1, &bufsize) == -1
+			    && errno != E2BIG) return -1;
+
+			bufsize = SMB_ICONV_BUFSIZE - bufsize;
+
+			if (cd->push(cd->cd_push,
+				     &bufp2, &bufsize,
+				     outbuf, outbytesleft) == -1) return -1;
+		}
+		talloc_free(cvtbuf);
 	}
 
 	return 0;
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c
index 9f968b0..48251bb 100644
--- a/source3/modules/vfs_smb_traffic_analyzer.c
+++ b/source3/modules/vfs_smb_traffic_analyzer.c
@@ -748,6 +748,44 @@ static int smb_traffic_analyzer_mkdir(vfs_handle_struct *handle, \
 	return s_data.result;
 }
 
+static ssize_t smb_traffic_analyzer_sendfile(vfs_handle_struct *handle,
+				int tofd,
+				files_struct *fromfsp,
+				const DATA_BLOB *hdr,
+				SMB_OFF_T offset,
+				size_t n)
+{
+	struct rw_data s_data;
+	s_data.len = SMB_VFS_NEXT_SENDFILE(handle,
+			tofd, fromfsp, hdr, offset, n);
+	s_data.filename = fromfsp->fsp_name->base_name;
+	DEBUG(10, ("smb_traffic_analyzer_sendfile: sendfile(r): %s\n",
+		fsp_str_dbg(fromfsp)));
+	smb_traffic_analyzer_send_data(handle,
+		&s_data,
+		vfs_id_read);
+	return s_data.len;
+}
+
+static ssize_t smb_traffic_analyzer_recvfile(vfs_handle_struct *handle,
+				int fromfd,
+				files_struct *tofsp,
+				SMB_OFF_T offset,
+				size_t n)
+{
+	struct rw_data s_data;
+	s_data.len = SMB_VFS_NEXT_RECVFILE(handle,
+			fromfd, tofsp, offset, n);
+	s_data.filename = tofsp->fsp_name->base_name;
+	DEBUG(10, ("smb_traffic_analyzer_recvfile: recvfile(w): %s\n",
+		fsp_str_dbg(tofsp)));
+	smb_traffic_analyzer_send_data(handle,
+		&s_data,
+		vfs_id_write);
+	return s_data.len;
+}
+
+
 static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \
 				files_struct *fsp, void *data, size_t n)
 {
@@ -857,7 +895,9 @@ static struct vfs_fn_pointers vfs_smb_traffic_analyzer_fns = {
 	.chdir = smb_traffic_analyzer_chdir,
 	.open = smb_traffic_analyzer_open,
 	.rmdir = smb_traffic_analyzer_rmdir,
-	.close_fn = smb_traffic_analyzer_close
+	.close_fn = smb_traffic_analyzer_close,
+	.sendfile = smb_traffic_analyzer_sendfile,
+	.recvfile = smb_traffic_analyzer_recvfile
 };
 
 /* Module initialization */
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 0e45e88..1ea4c68 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -798,6 +798,27 @@ int file_set_dosmode(connection_struct *conn, struct smb_filename *smb_fname,
 		unixmode |= (smb_fname->st.st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
 	}
 
+	/*
+	 * From the chmod 2 man page:
+	 *
+	 * "If the calling process is not privileged, and the group of the file
+	 * does not match the effective group ID of the process or one of its
+	 * supplementary group IDs, the S_ISGID bit will be turned off, but
+	 * this will not cause an error to be returned."
+	 *
+	 * Simply refuse to do the chmod in this case.
+	 */
+
+	if (S_ISDIR(smb_fname->st.st_ex_mode) && (unixmode & S_ISGID) &&
+			geteuid() != sec_initial_uid() &&
+			!current_user_in_group(conn, smb_fname->st.st_ex_gid)) {
+		DEBUG(3,("file_set_dosmode: setgid bit cannot be "
+			"set for directory %s\n",
+			smb_fname_str_dbg(smb_fname)));
+		errno = EPERM;
+		return -1;
+	}
+
 	ret = SMB_VFS_CHMOD(conn, smb_fname->base_name, unixmode);
 	if (ret == 0) {
 		if(!newfile || (lret != -1)) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 1d28716..9252ee6 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2656,7 +2656,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
  Check if the current user group list contains a given group.
 ****************************************************************************/
 
-static bool current_user_in_group(connection_struct *conn, gid_t gid)
+bool current_user_in_group(connection_struct *conn, gid_t gid)
 {
 	int i;
 	const struct security_unix_token *utok = get_current_utok(conn);
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 9366ee6..f4b2e5e 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -684,6 +684,7 @@ uint32_t map_canon_ace_perms(int snum,
                                 mode_t perms,
                                 bool directory_ace);
 NTSTATUS unpack_nt_owners(connection_struct *conn, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const struct security_descriptor *psd);
+bool current_user_in_group(connection_struct *conn, gid_t gid);
 SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl);
 NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info,
 			   struct security_descriptor **ppdesc);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list