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 <j...@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 <j...@samba.org> Autobuild-Date: Thu Mar 31 04:09:09 CEST 2011 on sn-devel-104 commit f9a2f4f47c71e5054c05703e72c24f2f5a87d993 Author: Jeremy Allison <j...@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 <hhet...@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