This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, master has been updated via 9d5d057dac6d67be939bebc1d3adf39b170a18d7 (commit) via d895399850ed6507fb550e80084732d1d7a8fde8 (commit) from 5c8acc789b4756d942d5e465361eb6b8e3ebad4a (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 9d5d057dac6d67be939bebc1d3adf39b170a18d7 Author: Arne Fitzenreiter arne_f@ipfire.org Date: Tue Nov 28 07:01:33 2017 +0100
boost: disable parallel build
this need more than 1GB ram on arm
Signed-off-by: Arne Fitzenreiter arne_f@ipfire.org
commit d895399850ed6507fb550e80084732d1d7a8fde8 Author: Arne Fitzenreiter arne_f@ipfire.org Date: Mon Nov 27 18:20:59 2017 +0100
samba: import security updates from redhead
Signed-off-by: Arne Fitzenreiter arne_f@ipfire.org
-----------------------------------------------------------------------
Summary of changes: lfs/boost | 6 +- lfs/samba | 9 +- src/patches/samba/CVE-2017-12150-v3-6.patch | 102 ++ src/patches/samba/CVE-2017-12163.patch | 141 +++ src/patches/samba/CVE-2017-15275.patch | 45 + src/patches/samba/CVE-2017-2619.patch | 1328 ++++++++++++++++++++ ....6.99-winbind_fix_trusted_domain_handling.patch | 432 +++++++ 7 files changed, 2056 insertions(+), 7 deletions(-) create mode 100644 src/patches/samba/CVE-2017-12150-v3-6.patch create mode 100644 src/patches/samba/CVE-2017-12163.patch create mode 100644 src/patches/samba/CVE-2017-15275.patch create mode 100644 src/patches/samba/CVE-2017-2619.patch create mode 100644 src/patches/samba/samba-3.6.99-winbind_fix_trusted_domain_handling.patch
Difference in files: diff --git a/lfs/boost b/lfs/boost index 533cb24..29c7bad 100644 --- a/lfs/boost +++ b/lfs/boost @@ -55,8 +55,6 @@ CONFIGURE_OPTIONS = \ cflags="$(CFLAGS)" \ cxxflags="$(CXXFLAGS)"
-MAKETUNING = -j2 - ############################################################################### # Top-level Rules ############################################################################### @@ -97,8 +95,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
cd $(DIR_APP) && ./bootstrap.sh --with-toolset=gcc - cd $(DIR_APP) && ./b2 -d+2 -q $(MAKETUNING) $(CONFIGURE_OPTIONS) stage - cd $(DIR_APP) && ./b2 $(MAKETUNING) $(CONFIGURE_OPTIONS) install + cd $(DIR_APP) && ./b2 -d+2 -q $(CONFIGURE_OPTIONS) stage + cd $(DIR_APP) && ./b2 $(CONFIGURE_OPTIONS) install
@rm -rf $(DIR_APP) @$(POSTBUILD) diff --git a/lfs/samba b/lfs/samba index d54d507..6842e18 100644 --- a/lfs/samba +++ b/lfs/samba @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = samba -PAK_VER = 67 +PAK_VER = 68
DEPS = "cups krb5"
@@ -152,9 +152,12 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba-3.6.99-fix_member_auth_after_changed_secret.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba-3.6.99-fix_dirsort_ea-support.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-7494-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba-3.6.99-winbind_fix_trusted_domain_handling.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-2619.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-12150-v3-6.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-12163.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/CVE-2017-15275.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/doc-update.patch -# cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/samba/samba-3.6.x-winbind_tevent_poll.patch -
cd $(DIR_APP)/source3 && ./autogen.sh cd $(DIR_APP)/source3 && ./configure \ diff --git a/src/patches/samba/CVE-2017-12150-v3-6.patch b/src/patches/samba/CVE-2017-12150-v3-6.patch new file mode 100644 index 0000000..b221a84 --- /dev/null +++ b/src/patches/samba/CVE-2017-12150-v3-6.patch @@ -0,0 +1,102 @@ +From d3198caa7a8910a9ce1eb4104d5b410ef29ac2bb Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher metze@samba.org +Date: Thu, 3 Nov 2016 17:16:43 +0100 +Subject: [PATCH 1/3] CVE-2017-12150: s3:lib: + get_cmdline_auth_info_signing_state use Required for smb_encrypt + +This is an addition to the fixes for CVE-2015-5296. + +It applies to smb2mount -e, smbcacls -e and smbcquotas -e. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12997 + +Signed-off-by: Stefan Metzmacher metze@samba.org +Backported-by: Andreas Schneider asn@samba.org +--- + source3/lib/util_cmdline.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c +index cb0b79a5d30..3178c848b63 100644 +--- a/source3/lib/util_cmdline.c ++++ b/source3/lib/util_cmdline.c +@@ -122,6 +122,9 @@ bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, + + int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info) + { ++ if (auth_info->smb_encrypt) { ++ return Required; ++ } + return auth_info->signing_state; + } + +-- +2.14.1 + + +From bb762a74c81159633f904f8fb67b49bab74a0b9c Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher metze@samba.org +Date: Mon, 12 Dec 2016 05:49:46 +0100 +Subject: [PATCH 2/3] CVE-2017-12150: libgpo: make use of Required for SMB + signing in gpo_connect_server() + +It's important that we use a signed connection to get the GPOs! + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12997 + +Signed-off-by: Stefan Metzmacher metze@samba.org +Backported-by: Andreas Schneider asn@samba.org +--- + libgpo/gpo_fetch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libgpo/gpo_fetch.c b/libgpo/gpo_fetch.c +index 3cfe1d5b942..af012e01336 100644 +--- a/libgpo/gpo_fetch.c ++++ b/libgpo/gpo_fetch.c +@@ -151,7 +151,7 @@ static NTSTATUS gpo_connect_server(ADS_STRUCT *ads, struct loadparm_context *lp_ + ads->auth.password, + CLI_FULL_CONNECTION_USE_KERBEROS | + CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS, +- Undefined); ++ Required); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("check_refresh_gpo: " + "failed to connect: %s\n", +-- +2.14.1 + + +From 070b0fb9ebb57cdbc2b82e335de021fb46bc543c Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher metze@samba.org +Date: Mon, 12 Dec 2016 06:07:56 +0100 +Subject: [PATCH 3/3] CVE-2017-12150: s3:libsmb: only fallback to anonymous if + authentication was not requested + +With forced encryption or required signing we should also don't fallback. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12997 + +Signed-off-by: Stefan Metzmacher metze@samba.org +Backported-by: Andreas Schneider asn@samba.org +--- + source3/libsmb/clidfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c +index 23e147120f1..120a2c999ce 100644 +--- a/source3/libsmb/clidfs.c ++++ b/source3/libsmb/clidfs.c +@@ -197,7 +197,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, + /* If a password was not supplied then + * try again with a null username. */ + if (password[0] || !username[0] || ++ force_encrypt || client_is_signing_mandatory(c) || + get_cmdline_auth_info_use_kerberos(auth_info) || ++ get_cmdline_auth_info_use_ccache(auth_info) || + !NT_STATUS_IS_OK(cli_session_setup(c, "", + "", 0, + "", 0, +-- +2.14.1 + diff --git a/src/patches/samba/CVE-2017-12163.patch b/src/patches/samba/CVE-2017-12163.patch new file mode 100644 index 0000000..93fe2ce --- /dev/null +++ b/src/patches/samba/CVE-2017-12163.patch @@ -0,0 +1,141 @@ +From 9f1a51917649795123bedbefdea678317d392b48 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Fri, 8 Sep 2017 10:13:14 -0700 +Subject: [PATCH] CVE-2017-12163: s3:smbd: Prevent client short SMB1 write from + writing server memory to file. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=13020 + +Signed-off-by: Jeremy Allison jra@samba.org +Signed-off-by: Stefan Metzmacher metze@samba.org +--- + source3/smbd/reply.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c +index 1583c2358bb..9625670d653 100644 +--- a/source3/smbd/reply.c ++++ b/source3/smbd/reply.c +@@ -3977,6 +3977,9 @@ void reply_writebraw(struct smb_request *req) + } + + /* Ensure we don't write bytes past the end of this packet. */ ++ /* ++ * This already protects us against CVE-2017-12163. ++ */ + if (data + numtowrite > smb_base(req->inbuf) + smb_len(req->inbuf)) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + error_to_writebrawerr(req); +@@ -4078,6 +4081,11 @@ void reply_writebraw(struct smb_request *req) + exit_server_cleanly("secondary writebraw failed"); + } + ++ /* ++ * We are not vulnerable to CVE-2017-12163 ++ * here as we are guarenteed to have numtowrite ++ * bytes available - we just read from the client. ++ */ + nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); + if (nwritten == -1) { + TALLOC_FREE(buf); +@@ -4159,6 +4167,7 @@ void reply_writeunlock(struct smb_request *req) + connection_struct *conn = req->conn; + ssize_t nwritten = -1; + size_t numtowrite; ++ size_t remaining; + SMB_OFF_T startpos; + const char *data; + NTSTATUS status = NT_STATUS_OK; +@@ -4191,6 +4200,17 @@ void reply_writeunlock(struct smb_request *req) + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); + data = (const char *)req->buf + 3; + ++ /* ++ * Ensure client isn't asking us to write more than ++ * they sent. CVE-2017-12163. ++ */ ++ remaining = smbreq_bufrem(req, data); ++ if (numtowrite > remaining) { ++ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); ++ END_PROFILE(SMBwriteunlock); ++ return; ++ } ++ + if (!fsp->print_file && numtowrite > 0) { + init_strict_lock_struct(fsp, (uint64_t)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, +@@ -4272,6 +4292,7 @@ void reply_write(struct smb_request *req) + { + connection_struct *conn = req->conn; + size_t numtowrite; ++ size_t remaining; + ssize_t nwritten = -1; + SMB_OFF_T startpos; + const char *data; +@@ -4312,6 +4333,17 @@ void reply_write(struct smb_request *req) + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); + data = (const char *)req->buf + 3; + ++ /* ++ * Ensure client isn't asking us to write more than ++ * they sent. CVE-2017-12163. ++ */ ++ remaining = smbreq_bufrem(req, data); ++ if (numtowrite > remaining) { ++ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); ++ END_PROFILE(SMBwrite); ++ return; ++ } ++ + if (!fsp->print_file) { + init_strict_lock_struct(fsp, (uint64_t)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, +@@ -4523,6 +4555,9 @@ void reply_write_and_X(struct smb_request *req) + return; + } + } else { ++ /* ++ * This already protects us against CVE-2017-12163. ++ */ + if (smb_doff > smblen || smb_doff + numtowrite < numtowrite || + smb_doff + numtowrite > smblen) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); +@@ -4892,6 +4927,7 @@ void reply_writeclose(struct smb_request *req) + { + connection_struct *conn = req->conn; + size_t numtowrite; ++ size_t remaining; + ssize_t nwritten = -1; + NTSTATUS close_status = NT_STATUS_OK; + SMB_OFF_T startpos; +@@ -4925,6 +4961,17 @@ void reply_writeclose(struct smb_request *req) + mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4)); + data = (const char *)req->buf + 1; + ++ /* ++ * Ensure client isn't asking us to write more than ++ * they sent. CVE-2017-12163. ++ */ ++ remaining = smbreq_bufrem(req, data); ++ if (numtowrite > remaining) { ++ reply_nterror(req, NT_STATUS_INVALID_PARAMETER); ++ END_PROFILE(SMBwriteclose); ++ return; ++ } ++ + if (!fsp->print_file) { + init_strict_lock_struct(fsp, (uint64_t)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, +@@ -5495,6 +5542,9 @@ void reply_printwrite(struct smb_request *req) + + numtowrite = SVAL(req->buf, 1); + ++ /* ++ * This already protects us against CVE-2017-12163. ++ */ + if (req->buflen < numtowrite + 3) { + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + END_PROFILE(SMBsplwr); +-- +2.13.5 + diff --git a/src/patches/samba/CVE-2017-15275.patch b/src/patches/samba/CVE-2017-15275.patch new file mode 100644 index 0000000..758672e --- /dev/null +++ b/src/patches/samba/CVE-2017-15275.patch @@ -0,0 +1,45 @@ +From c1a22e59f87783d88dfbaeeb132b89be166b2754 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Wed, 20 Sep 2017 11:04:50 -0700 +Subject: [PATCH 2/2] s3: smbd: Chain code can return uninitialized memory when + talloc buffer is grown. + +Ensure we zero out unused grown area. + +CVE-2017-15275 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=13077 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/srvstr.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/source3/smbd/srvstr.c b/source3/smbd/srvstr.c +index 56dceba8c6c..c2d70b32c32 100644 +--- a/source3/smbd/srvstr.c ++++ b/source3/smbd/srvstr.c +@@ -110,6 +110,20 @@ ssize_t message_push_string(uint8_t **outbuf, const char *str, int flags) + DEBUG(0, ("srvstr_push failed\n")); + return -1; + } ++ ++ /* ++ * Ensure we clear out the extra data we have ++ * grown the buffer by, but not written to. ++ */ ++ if (buf_size + result < buf_size) { ++ return -1; ++ } ++ if (grow_size < result) { ++ return -1; ++ } ++ ++ memset(tmp + buf_size + result, '\0', grow_size - result); ++ + set_message_bcc((char *)tmp, smb_buflen(tmp) + result); + + *outbuf = tmp; +-- +2.11.0 + diff --git a/src/patches/samba/CVE-2017-2619.patch b/src/patches/samba/CVE-2017-2619.patch new file mode 100644 index 0000000..149e085 --- /dev/null +++ b/src/patches/samba/CVE-2017-2619.patch @@ -0,0 +1,1328 @@ +From a398754c9bb1639f762979765de6c540c714b5cb Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 20 Mar 2017 11:32:19 -0700 +Subject: [PATCH 01/15] CVE-2017-2619: s3/smbd: re-open directory after + dptr_CloseDir() + +dptr_CloseDir() will close and invalidate the fsp's file descriptor, we +have to reopen it. + +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Ralph Bohme slow@samba.org +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/open.c | 2 +- + source3/smbd/proto.h | 2 ++ + source3/smbd/smb2_find.c | 17 +++++++++++++++++ + 3 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/source3/smbd/open.c b/source3/smbd/open.c +index 441b8cd4362..35eee0a1485 100644 +--- a/source3/smbd/open.c ++++ b/source3/smbd/open.c +@@ -197,7 +197,7 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn, + fd support routines - attempt to do a dos_open. + ****************************************************************************/ + +-static NTSTATUS fd_open(struct connection_struct *conn, ++NTSTATUS fd_open(struct connection_struct *conn, + files_struct *fsp, + int flags, + mode_t mode) +diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h +index f5fad2bbb50..594edfa1e98 100644 +--- a/source3/smbd/proto.h ++++ b/source3/smbd/proto.h +@@ -603,6 +603,8 @@ NTSTATUS smb1_file_se_access_check(connection_struct *conn, + const struct security_token *token, + uint32_t access_desired, + uint32_t *access_granted); ++NTSTATUS fd_open(struct connection_struct *conn, files_struct *fsp, ++ int flags, mode_t mode); + NTSTATUS fd_close(files_struct *fsp); + void change_file_owner_to_parent(connection_struct *conn, + const char *inherit_from_dir, +diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c +index 6fe6545c128..9dd3176497b 100644 +--- a/source3/smbd/smb2_find.c ++++ b/source3/smbd/smb2_find.c +@@ -24,6 +24,7 @@ + #include "../libcli/smb/smb_common.h" + #include "trans2.h" + #include "../lib/util/tevent_ntstatus.h" ++#include "system/filesys.h" + + static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -301,7 +302,23 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx, + } + + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { ++ int flags; ++ + dptr_CloseDir(fsp); ++ ++ /* ++ * dptr_CloseDir() will close and invalidate the fsp's file ++ * descriptor, we have to reopen it. ++ */ ++ ++ flags = O_RDONLY; ++#ifdef O_DIRECTORY ++ flags |= O_DIRECTORY; ++#endif ++ status = fd_open(conn, fsp, flags, 0); ++ if (tevent_req_nterror(req, status)) { ++ return tevent_req_post(req, ev); ++ } + } + + wcard_has_wild = ms_has_wild(in_file_name); +-- +2.13.5 + + +From a35fa98b99aa60132eb2c083d6393c28905e2045 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Tue, 28 Feb 2017 09:24:07 -0800 +Subject: [PATCH 02/15] s3: vfs: dirsort doesn't handle opendir of "." + correctly. + +Needs to store $cwd path for correct sorting. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/modules/vfs_dirsort.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c +index 66582e67890..dbcf0b16ed3 100644 +--- a/source3/modules/vfs_dirsort.c ++++ b/source3/modules/vfs_dirsort.c +@@ -153,6 +153,10 @@ static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle, + return NULL; + } + ++ if (ISDOT(data->smb_fname->base_name)) { ++ data->smb_fname->base_name = vfs_GetWd(data, handle->conn); ++ } ++ + /* Open the underlying directory and count the number of entries */ + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, + attr); +-- +2.13.5 + + +From 23d2849d724a0f5bdf51dc7d7db438ed9fb4c2a9 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 13 Mar 2017 13:44:42 -0700 +Subject: [PATCH 03/15] s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open() + store the same path as streams_xattr_recheck(). + +If the open is changing directories, fsp->fsp_name->base_name +will be the full path from the share root, whilst +smb_fname will be relative to the $cwd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 + +Back-ported from a24ba3e4083200ec9885363efc5769f43183fb6b + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/modules/vfs_streams_xattr.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c +index 731c813f4d7..be46f8dc1e6 100644 +--- a/source3/modules/vfs_streams_xattr.c ++++ b/source3/modules/vfs_streams_xattr.c +@@ -511,8 +511,15 @@ static int streams_xattr_open(vfs_handle_struct *handle, + + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), + xattr_name); ++ /* ++ * sio->base needs to be a copy of fsp->fsp_name->base_name, ++ * making it identical to streams_xattr_recheck(). If the ++ * open is changing directories, fsp->fsp_name->base_name ++ * will be the full path from the share root, whilst ++ * smb_fname will be relative to the $cwd. ++ */ + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), +- smb_fname->base_name); ++ fsp->fsp_name->base_name); + sio->fsp_name_ptr = fsp->fsp_name; + sio->handle = handle; + sio->fsp = fsp; +-- +2.13.5 + + +From 91935aaf77c70e3e2436af1d6e4a538d29fd4276 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 13 Mar 2017 13:54:04 -0700 +Subject: [PATCH 04/15] vfs_streams_xattr: use fsp, not base_fsp + +The base_fsp's fd is always -1 as it's closed after being openend in +create_file_unixpath(). + +Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by +sticking the just created fd into the fsp (and removing it afterwards). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12591 + +Back-ported from 021189e32ba507832b5e821e5cda8a2889225955. + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/modules/vfs_streams_xattr.c | 205 +++++++++++++++++------------------- + 1 file changed, 99 insertions(+), 106 deletions(-) + +diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c +index be46f8dc1e6..a4ab84bba71 100644 +--- a/source3/modules/vfs_streams_xattr.c ++++ b/source3/modules/vfs_streams_xattr.c +@@ -229,7 +229,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, + return -1; + } + +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, + io->base, io->xattr_name); + if (sbuf->st_ex_size == -1) { + return -1; +@@ -364,6 +364,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, + char *xattr_name = NULL; + int baseflags; + int hostfd = -1; ++ int ret; + + DEBUG(10, ("streams_xattr_open called for %s\n", + smb_fname_str_dbg(smb_fname))); +@@ -375,133 +376,125 @@ static int streams_xattr_open(vfs_handle_struct *handle, + /* If the default stream is requested, just open the base file. */ + if (is_ntfs_default_stream_smb_fname(smb_fname)) { + char *tmp_stream_name; +- int ret; + + tmp_stream_name = smb_fname->stream_name; + smb_fname->stream_name = NULL; + + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); + +- smb_fname->stream_name = tmp_stream_name; +- +- return ret; +- } ++ smb_fname->stream_name = tmp_stream_name; + +- status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, +- &xattr_name); +- if (!NT_STATUS_IS_OK(status)) { +- errno = map_errno_from_nt_status(status); +- goto fail; +- } ++ return ret; ++ } + +- /* Create an smb_filename with stream_name == NULL. */ +- status = create_synthetic_smb_fname(talloc_tos(), +- smb_fname->base_name, +- NULL, NULL, +- &smb_fname_base); +- if (!NT_STATUS_IS_OK(status)) { +- errno = map_errno_from_nt_status(status); +- goto fail; +- } ++ status = streams_xattr_get_name(talloc_tos(), smb_fname->stream_name, ++ &xattr_name); ++ if (!NT_STATUS_IS_OK(status)) { ++ errno = map_errno_from_nt_status(status); ++ goto fail; ++ } + +- /* +- * We use baseflags to turn off nasty side-effects when opening the +- * underlying file. +- */ +- baseflags = flags; +- baseflags &= ~O_TRUNC; +- baseflags &= ~O_EXCL; +- baseflags &= ~O_CREAT; ++ /* Create an smb_filename with stream_name == NULL. */ ++ status = create_synthetic_smb_fname(talloc_tos(), ++ smb_fname->base_name, ++ NULL, NULL, ++ &smb_fname_base); ++ if (!NT_STATUS_IS_OK(status)) { ++ errno = map_errno_from_nt_status(status); ++ goto fail; ++ } + +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, +- baseflags, mode); ++ /* ++ * We use baseflags to turn off nasty side-effects when opening the ++ * underlying file. ++ */ ++ baseflags = flags; ++ baseflags &= ~O_TRUNC; ++ baseflags &= ~O_EXCL; ++ baseflags &= ~O_CREAT; + +- TALLOC_FREE(smb_fname_base); ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp, ++ baseflags, mode); + +- /* It is legit to open a stream on a directory, but the base +- * fd has to be read-only. +- */ +- if ((hostfd == -1) && (errno == EISDIR)) { +- baseflags &= ~O_ACCMODE; +- baseflags |= O_RDONLY; +- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags, +- mode); +- } ++ TALLOC_FREE(smb_fname_base); + +- if (hostfd == -1) { +- goto fail; +- } ++ /* It is legit to open a stream on a directory, but the base ++ * fd has to be read-only. ++ */ ++ if ((hostfd == -1) && (errno == EISDIR)) { ++ baseflags &= ~O_ACCMODE; ++ baseflags |= O_RDONLY; ++ hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags, ++ mode); ++ } + +- status = get_ea_value(talloc_tos(), handle->conn, NULL, +- smb_fname->base_name, xattr_name, &ea); ++ if (hostfd == -1) { ++ goto fail; ++ } + +- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); ++ status = get_ea_value(talloc_tos(), handle->conn, NULL, ++ smb_fname->base_name, xattr_name, &ea); + +- if (!NT_STATUS_IS_OK(status) +- && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { +- /* +- * The base file is not there. This is an error even if we got +- * O_CREAT, the higher levels should have created the base +- * file for us. +- */ +- DEBUG(10, ("streams_xattr_open: base file %s not around, " +- "returning ENOENT\n", smb_fname->base_name)); +- errno = ENOENT; +- goto fail; +- } ++ DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status))); + +- if (!NT_STATUS_IS_OK(status)) { +- /* +- * The attribute does not exist +- */ ++ if (!NT_STATUS_IS_OK(status) ++ && !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { ++ /* ++ * The base file is not there. This is an error even if we got ++ * O_CREAT, the higher levels should have created the base ++ * file for us. ++ */ ++ DEBUG(10, ("streams_xattr_open: base file %s not around, " ++ "returning ENOENT\n", smb_fname->base_name)); ++ errno = ENOENT; ++ goto fail; ++ } + +- if (flags & O_CREAT) { ++ if (!NT_STATUS_IS_OK(status)) { + /* +- * Darn, xattrs need at least 1 byte ++ * The attribute does not exist + */ +- char null = '\0'; + +- DEBUG(10, ("creating attribute %s on file %s\n", +- xattr_name, smb_fname->base_name)); ++ if (flags & O_CREAT) { ++ /* ++ * Darn, xattrs need at least 1 byte ++ */ ++ char null = '\0'; ++ ++ DEBUG(10, ("creating attribute %s on file %s\n", ++ xattr_name, smb_fname->base_name)); ++ ++ fsp->fh->fd = hostfd; ++ ret = SMB_VFS_FSETXATTR(fsp, xattr_name, ++ &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0); ++ fsp->fh->fd = -1; ++ if (ret != 0) { ++ goto fail; ++ } ++ } ++ } + ++ if (flags & O_TRUNC) { ++ char null = '\0'; + if (fsp->base_fsp->fh->fd != -1) { +- if (SMB_VFS_FSETXATTR( +- fsp->base_fsp, xattr_name, +- &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { ++ if (SMB_VFS_FSETXATTR( ++ fsp->base_fsp, xattr_name, ++ &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } else { +- if (SMB_VFS_SETXATTR( +- handle->conn, smb_fname->base_name, +- xattr_name, &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { ++ if (SMB_VFS_SETXATTR( ++ handle->conn, smb_fname->base_name, ++ xattr_name, &null, sizeof(null), ++ flags & O_EXCL ? XATTR_CREATE : 0) == -1) { + goto fail; + } + } + } +- } +- +- if (flags & O_TRUNC) { +- char null = '\0'; +- if (fsp->base_fsp->fh->fd != -1) { +- if (SMB_VFS_FSETXATTR( +- fsp->base_fsp, xattr_name, +- &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } +- } else { +- if (SMB_VFS_SETXATTR( +- handle->conn, smb_fname->base_name, +- xattr_name, &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } +- } +- } + +- sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, ++ sio = (struct stream_io *)VFS_ADD_FSP_EXTENSION(handle, fsp, + struct stream_io, + NULL); + if (sio == NULL) { +@@ -868,7 +861,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -892,13 +885,13 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + + memcpy(ea.value.data + offset, data, n); + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +@@ -932,7 +925,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -977,7 +970,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -1002,13 +995,13 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, + ea.value.length = offset + 1; + ea.value.data[offset] = 0; + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +-- +2.13.5 + + +From 3f3c731faaa59f4d3ce7e49c12795c40e048d29f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 11:55:56 -0800 +Subject: [PATCH 05/15] s3: smbd: Create wrapper function for OpenDir in + preparation for making robust. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index 18ecf066824..ebe2641f813 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1367,7 +1367,8 @@ static int smb_Dir_destructor(struct smb_Dir *dirp) + Open a directory. + ********************************************************************/ + +-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, ++static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, ++ connection_struct *conn, + const char *name, + const char *mask, + uint32 attr) +@@ -1407,6 +1408,18 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, + return NULL; + } + ++struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, ++ const char *name, ++ const char *mask, ++ uint32_t attr) ++{ ++ return OpenDir_internal(mem_ctx, ++ conn, ++ name, ++ mask, ++ attr); ++} ++ + /******************************************************************* + Open a directory from an fsp. + ********************************************************************/ +-- +2.13.5 + + +From 7efeb067c1586e0f1cfbb775b1efcb3b92005140 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 16:25:26 -0800 +Subject: [PATCH 06/15] s3: smbd: Opendir_internal() early return if + SMB_VFS_OPENDIR failed. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index ebe2641f813..65327dd0dd1 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1380,6 +1380,13 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, + return NULL; + } + ++ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); ++ if (!dirp->dir) { ++ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, ++ strerror(errno) )); ++ goto fail; ++ } ++ + dirp->conn = conn; + dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); + +@@ -1394,13 +1401,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, + } + talloc_set_destructor(dirp, smb_Dir_destructor); + +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); +- if (!dirp->dir) { +- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, +- strerror(errno) )); +- goto fail; +- } +- + return dirp; + + fail: +-- +2.13.5 + + +From 49d22a0c51ef1f78f0488a7c35131887704e987b Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 16:35:00 -0800 +Subject: [PATCH 07/15] s3: smbd: Create and use open_dir_safely(). Use from + OpenDir(). + +Hardens OpenDir against TOC/TOU races. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 59 insertions(+), 7 deletions(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index 65327dd0dd1..2d168c3ba9f 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1390,12 +1390,6 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, + dirp->conn = conn; + dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); + +- dirp->dir_path = talloc_strdup(dirp, name); +- if (!dirp->dir_path) { +- errno = ENOMEM; +- goto fail; +- } +- + if (sconn && !sconn->using_smb2) { + sconn->searches.dirhandles_open++; + } +@@ -1408,12 +1402,70 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, + return NULL; + } + ++/**************************************************************************** ++ Open a directory handle by pathname, ensuring it's under the share path. ++****************************************************************************/ ++ ++static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, ++ connection_struct *conn, ++ const char *name, ++ const char *wcard, ++ uint32_t attr) ++{ ++ struct smb_Dir *dir_hnd = NULL; ++ char *saved_dir = vfs_GetWd(ctx, conn); ++ NTSTATUS status; ++ ++ if (saved_dir == NULL) { ++ return NULL; ++ } ++ ++ if (vfs_ChDir(conn, name) == -1) { ++ goto out; ++ } ++ ++ /* ++ * Now the directory is pinned, use ++ * REALPATH to ensure we can access it. ++ */ ++ status = check_name(conn, "."); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto out; ++ } ++ ++ dir_hnd = OpenDir_internal(ctx, ++ conn, ++ ".", ++ wcard, ++ attr); ++ ++ if (dir_hnd == NULL) { ++ goto out; ++ } ++ ++ /* ++ * OpenDir_internal only gets "." as the dir name. ++ * Store the real dir name here. ++ */ ++ ++ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); ++ if (!dir_hnd->dir_path) { ++ errno = ENOMEM; ++ } ++ ++ out: ++ ++ vfs_ChDir(conn, saved_dir); ++ TALLOC_FREE(saved_dir); ++ return dir_hnd; ++} ++ + struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, + const char *name, + const char *mask, + uint32_t attr) + { +- return OpenDir_internal(mem_ctx, ++ return open_dir_safely(mem_ctx, + conn, + name, + mask, +-- +2.13.5 + + +From 6426ae1f9ef53158a6fbe1912dfec40d834115fe Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 12:13:20 -0800 +Subject: [PATCH 08/15] s3: smbd: OpenDir_fsp() use early returns. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index 2d168c3ba9f..6aed4a6da46 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1485,7 +1485,17 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + struct smbd_server_connection *sconn = conn->sconn; + + if (!dirp) { +- return NULL; ++ goto fail; ++ } ++ ++ if (!fsp->is_directory) { ++ errno = EBADF; ++ goto fail; ++ } ++ ++ if (fsp->fh->fd == -1) { ++ errno = EBADF; ++ goto fail; + } + + dirp->conn = conn; +@@ -1502,18 +1512,16 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + } + talloc_set_destructor(dirp, smb_Dir_destructor); + +- if (fsp->is_directory && fsp->fh->fd != -1) { +- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); +- if (dirp->dir != NULL) { +- dirp->fsp = fsp; +- } else { +- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " +- "NULL (%s)\n", +- dirp->dir_path, +- strerror(errno))); +- if (errno != ENOSYS) { +- return NULL; +- } ++ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); ++ if (dirp->dir != NULL) { ++ dirp->fsp = fsp; ++ } else { ++ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " ++ "NULL (%s)\n", ++ dirp->dir_path, ++ strerror(errno))); ++ if (errno != ENOSYS) { ++ return NULL; + } + } + +-- +2.13.5 + + +From f6581858ce665b880c5fea465ec61b1b0c504d89 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 12:15:59 -0800 +Subject: [PATCH 09/15] s3: smbd: OpenDir_fsp() - Fix memory leak on error. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index 6aed4a6da46..efd1a73aab6 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1521,7 +1521,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + dirp->dir_path, + strerror(errno))); + if (errno != ENOSYS) { +- return NULL; ++ goto fail; + } + } + +-- +2.13.5 + + +From bacba6987e58d44886d04b1dd5e36f7781dcd9b0 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 12:32:07 -0800 +Subject: [PATCH 10/15] s3: smbd: Move the reference counting and destructor + setup to just before retuning success. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index efd1a73aab6..5eca128c033 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1507,11 +1507,6 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + goto fail; + } + +- if (sconn && !sconn->using_smb2) { +- sconn->searches.dirhandles_open++; +- } +- talloc_set_destructor(dirp, smb_Dir_destructor); +- + dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); + if (dirp->dir != NULL) { + dirp->fsp = fsp; +@@ -1536,6 +1531,11 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + goto fail; + } + ++ if (sconn && !sconn->using_smb2) { ++ sconn->searches.dirhandles_open++; ++ } ++ talloc_set_destructor(dirp, smb_Dir_destructor); ++ + return dirp; + + fail: +-- +2.13.5 + + +From 34b3d05b55f5c40de76ba65d6b028818518a519f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Mon, 19 Dec 2016 12:35:32 -0800 +Subject: [PATCH 11/15] s3: smbd: Correctly fallback to open_dir_safely if + FDOPENDIR not supported on system. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/dir.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c +index 5eca128c033..7690cb18c1a 100644 +--- a/source3/smbd/dir.c ++++ b/source3/smbd/dir.c +@@ -1521,14 +1521,13 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, + } + + if (dirp->dir == NULL) { +- /* FDOPENDIR didn't work. Use OPENDIR instead. */ +- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); +- } +- +- if (!dirp->dir) { +- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, +- strerror(errno) )); +- goto fail; ++ /* FDOPENDIR is not supported. Use OPENDIR instead. */ ++ TALLOC_FREE(dirp); ++ return open_dir_safely(mem_ctx, ++ conn, ++ fsp->fsp_name->base_name, ++ mask, ++ attr); + } + + if (sconn && !sconn->using_smb2) { +-- +2.13.5 + + +From 84bc8b232a4495bff270b7800833ef6785937576 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Thu, 15 Dec 2016 12:52:13 -0800 +Subject: [PATCH 12/15] s3: smbd: Remove O_NOFOLLOW guards. We insist on + O_NOFOLLOW existing. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/open.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/source3/smbd/open.c b/source3/smbd/open.c +index 35eee0a1485..8417f8aca4a 100644 +--- a/source3/smbd/open.c ++++ b/source3/smbd/open.c +@@ -205,8 +205,7 @@ NTSTATUS fd_open(struct connection_struct *conn, + struct smb_filename *smb_fname = fsp->fsp_name; + NTSTATUS status = NT_STATUS_OK; + +-#ifdef O_NOFOLLOW +- /* ++ /* + * Never follow symlinks on a POSIX client. The + * client should be doing this. + */ +@@ -214,7 +213,6 @@ NTSTATUS fd_open(struct connection_struct *conn, + if (fsp->posix_open || !lp_symlinks(SNUM(conn))) { + flags |= O_NOFOLLOW; + } +-#endif + + fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); + if (fsp->fh->fd == -1) { +-- +2.13.5 + + +From af0c5a266ae65ad2a638fe48a7ad7d77417f97d7 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Thu, 15 Dec 2016 12:56:08 -0800 +Subject: [PATCH 13/15] s3: smbd: Move special handling of symlink errno's into + a utility function. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/open.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/source3/smbd/open.c b/source3/smbd/open.c +index 8417f8aca4a..e727e89e9d8 100644 +--- a/source3/smbd/open.c ++++ b/source3/smbd/open.c +@@ -194,6 +194,31 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn, + } + + /**************************************************************************** ++ Handle differing symlink errno's ++****************************************************************************/ ++ ++static int link_errno_convert(int err) ++{ ++#if defined(ENOTSUP) && defined(OSF1) ++ /* handle special Tru64 errno */ ++ if (err == ENOTSUP) { ++ err = ELOOP; ++ } ++#endif /* ENOTSUP */ ++#ifdef EFTYPE ++ /* fix broken NetBSD errno */ ++ if (err == EFTYPE) { ++ err = ELOOP; ++ } ++#endif /* EFTYPE */ ++ /* fix broken FreeBSD errno */ ++ if (err == EMLINK) { ++ err = ELOOP; ++ } ++ return err; ++} ++ ++/**************************************************************************** + fd support routines - attempt to do a dos_open. + ****************************************************************************/ + +@@ -216,8 +241,9 @@ NTSTATUS fd_open(struct connection_struct *conn, + + fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); + if (fsp->fh->fd == -1) { +- status = map_nt_error_from_unix(errno); +- if (errno == EMFILE) { ++ int posix_errno = link_errno_convert(errno); ++ status = map_nt_error_from_unix(posix_errno); ++ if (posix_errno == EMFILE) { + static time_t last_warned = 0L; + + if (time((time_t *) NULL) > last_warned) { +-- +2.13.5 + + +From c3bc4ff0367d7a3ebfd64db6defddea0bc3a5f4a Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Thu, 15 Dec 2016 13:04:46 -0800 +Subject: [PATCH 14/15] s3: smbd: Add the core functions to prevent symlink + open races. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/open.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 242 insertions(+) + +diff --git a/source3/smbd/open.c b/source3/smbd/open.c +index e727e89e9d8..0998adc416a 100644 +--- a/source3/smbd/open.c ++++ b/source3/smbd/open.c +@@ -218,6 +218,248 @@ static int link_errno_convert(int err) + return err; + } + ++static int non_widelink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth); ++ ++/**************************************************************************** ++ Follow a symlink in userspace. ++****************************************************************************/ ++ ++static int process_symlink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth) ++{ ++ int fd = -1; ++ char *link_target = NULL; ++ int link_len = -1; ++ char *oldwd = NULL; ++ size_t rootdir_len = 0; ++ char *resolved_name = NULL; ++ bool matched = false; ++ int saved_errno = 0; ++ ++ /* ++ * Ensure we don't get stuck in a symlink loop. ++ */ ++ link_depth++; ++ if (link_depth >= 20) { ++ errno = ELOOP; ++ goto out; ++ } ++ ++ /* Allocate space for the link target. */ ++ link_target = talloc_array(talloc_tos(), char, PATH_MAX); ++ if (link_target == NULL) { ++ errno = ENOMEM; ++ goto out; ++ } ++ ++ /* Read the link target. */ ++ link_len = SMB_VFS_READLINK(conn, ++ smb_fname->base_name, ++ link_target, ++ PATH_MAX - 1); ++ if (link_len == -1) { ++ goto out; ++ } ++ ++ /* Ensure it's at least null terminated. */ ++ link_target[link_len] = '\0'; ++ ++ /* Convert to an absolute path. */ ++ resolved_name = SMB_VFS_REALPATH(conn, link_target); ++ if (resolved_name == NULL) { ++ goto out; ++ } ++ ++ /* ++ * We know conn_rootdir starts with '/' and ++ * does not end in '/'. FIXME ! Should we ++ * smb_assert this ? ++ */ ++ rootdir_len = strlen(conn_rootdir); ++ ++ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); ++ if (!matched) { ++ errno = EACCES; ++ goto out; ++ } ++ ++ /* ++ * Turn into a path relative to the share root. ++ */ ++ if (resolved_name[rootdir_len] == '\0') { ++ /* Link to the root of the share. */ ++ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); ++ if (smb_fname->base_name == NULL) { ++ errno = ENOMEM; ++ goto out; ++ } ++ } else if (resolved_name[rootdir_len] == '/') { ++ smb_fname->base_name = &resolved_name[rootdir_len+1]; ++ } else { ++ errno = EACCES; ++ goto out; ++ } ++ ++ oldwd = vfs_GetWd(talloc_tos(), conn); ++ if (oldwd == NULL) { ++ goto out; ++ } ++ ++ /* Ensure we operate from the root of the share. */ ++ if (vfs_ChDir(conn, conn_rootdir) == -1) { ++ goto out; ++ } ++ ++ /* And do it all again.. */ ++ fd = non_widelink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname, ++ flags, ++ mode, ++ link_depth); ++ if (fd == -1) { ++ saved_errno = errno; ++ } ++ ++ out: ++ ++ SAFE_FREE(resolved_name); ++ TALLOC_FREE(link_target); ++ if (oldwd != NULL) { ++ int ret = vfs_ChDir(conn, oldwd); ++ if (ret == -1) { ++ smb_panic("unable to get back to old directory\n"); ++ } ++ TALLOC_FREE(oldwd); ++ } ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } ++ return fd; ++} ++ ++/**************************************************************************** ++ Non-widelink open. ++****************************************************************************/ ++ ++static int non_widelink_open(struct connection_struct *conn, ++ const char *conn_rootdir, ++ files_struct *fsp, ++ struct smb_filename *smb_fname, ++ int flags, ++ mode_t mode, ++ unsigned int link_depth) ++{ ++ NTSTATUS status; ++ int fd = -1; ++ struct smb_filename *smb_fname_rel = NULL; ++ int saved_errno = 0; ++ char *oldwd = NULL; ++ char *parent_dir = NULL; ++ const char *final_component = NULL; ++ ++ if (!parent_dirname(talloc_tos(), ++ smb_fname->base_name, ++ &parent_dir, ++ &final_component)) { ++ goto out; ++ } ++ ++ oldwd = vfs_GetWd(talloc_tos(), conn); ++ if (oldwd == NULL) { ++ goto out; ++ } ++ ++ /* Pin parent directory in place. */ ++ if (vfs_ChDir(conn, parent_dir) == -1) { ++ goto out; ++ } ++ ++ /* Ensure the relative path is below the share. */ ++ status = check_reduced_name(conn, final_component); ++ if (!NT_STATUS_IS_OK(status)) { ++ saved_errno = map_errno_from_nt_status(status); ++ goto out; ++ } ++ ++ status = create_synthetic_smb_fname(talloc_tos(), ++ final_component, ++ smb_fname->stream_name, ++ &smb_fname->st, ++ &smb_fname_rel); ++ if (!NT_STATUS_IS_OK(status)) { ++ saved_errno = map_errno_from_nt_status(status); ++ goto out; ++ } ++ ++ flags |= O_NOFOLLOW; ++ ++ { ++ struct smb_filename *tmp_name = fsp->fsp_name; ++ fsp->fsp_name = smb_fname_rel; ++ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); ++ fsp->fsp_name = tmp_name; ++ } ++ ++ if (fd == -1) { ++ saved_errno = link_errno_convert(errno); ++ if (saved_errno == ELOOP) { ++ if (fsp->posix_open) { ++ /* Never follow symlinks on posix open. */ ++ goto out; ++ } ++ if (!lp_symlinks(SNUM(conn))) { ++ /* Explicitly no symlinks. */ ++ goto out; ++ } ++ /* ++ * We have a symlink. Follow in userspace ++ * to ensure it's under the share definition. ++ */ ++ fd = process_symlink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname_rel, ++ flags, ++ mode, ++ link_depth); ++ if (fd == -1) { ++ saved_errno = ++ link_errno_convert(errno); ++ } ++ } ++ } ++ ++ out: ++ ++ TALLOC_FREE(parent_dir); ++ TALLOC_FREE(smb_fname_rel); ++ ++ if (oldwd != NULL) { ++ int ret = vfs_ChDir(conn, oldwd); ++ if (ret == -1) { ++ smb_panic("unable to get back to old directory\n"); ++ } ++ TALLOC_FREE(oldwd); ++ } ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } ++ return fd; ++} ++ + /**************************************************************************** + fd support routines - attempt to do a dos_open. + ****************************************************************************/ +-- +2.13.5 + + +From 6a88d1cf3deb54a784f50c8eba3b9a24a65c1b34 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison jra@samba.org +Date: Thu, 15 Dec 2016 13:06:31 -0800 +Subject: [PATCH 15/15] s3: smbd: Use the new non_widelink_open() function. + +CVE-2017-2619 + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Jeremy Allison jra@samba.org +--- + source3/smbd/open.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +diff --git a/source3/smbd/open.c b/source3/smbd/open.c +index 0998adc416a..65ca14ec8b8 100644 +--- a/source3/smbd/open.c ++++ b/source3/smbd/open.c +@@ -481,7 +481,28 @@ NTSTATUS fd_open(struct connection_struct *conn, + flags |= O_NOFOLLOW; + } + +- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); ++ /* Ensure path is below share definition. */ ++ if (!lp_widelinks(SNUM(conn))) { ++ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, ++ smb_fname->base_name); ++ if (conn_rootdir == NULL) { ++ return NT_STATUS_NO_MEMORY; ++ } ++ /* ++ * Only follow symlinks within a share ++ * definition. ++ */ ++ fsp->fh->fd = non_widelink_open(conn, ++ conn_rootdir, ++ fsp, ++ smb_fname, ++ flags, ++ mode, ++ 0); ++ } else { ++ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); ++ } ++ + if (fsp->fh->fd == -1) { + int posix_errno = link_errno_convert(errno); + status = map_nt_error_from_unix(posix_errno); +-- +2.13.5 + diff --git a/src/patches/samba/samba-3.6.99-winbind_fix_trusted_domain_handling.patch b/src/patches/samba/samba-3.6.99-winbind_fix_trusted_domain_handling.patch new file mode 100644 index 0000000..e58f714 --- /dev/null +++ b/src/patches/samba/samba-3.6.99-winbind_fix_trusted_domain_handling.patch @@ -0,0 +1,432 @@ +From a280f61d71d5ea7e2212d253b84ac5b25810b88e Mon Sep 17 00:00:00 2001 +From: Uri Simchoni uri@samba.org +Date: Wed, 10 Feb 2016 00:26:45 +0200 +Subject: [PATCH 1/4] winbindd: introduce add_trusted_domain_from_tdc() + +This is purely a refactoring patch - +Add a routine that adds a winbindd domain object based on +domain trust cache entry. add_trusted_domain() becomes +a wrapper for this new routine. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11691 + +Signed-off-by: Uri Simchoni uri@samba.org +Reviewed-by: Ralph Boehme slow@samba.org +--- + source3/winbindd/winbindd_util.c | 76 +++++++++++++++++++++++++--------------- + 1 file changed, 48 insertions(+), 28 deletions(-) + +diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c +index 353722e..70a9041 100644 +--- a/source3/winbindd/winbindd_util.c ++++ b/source3/winbindd/winbindd_util.c +@@ -30,6 +30,10 @@ + #undef DBGC_CLASS + #define DBGC_CLASS DBGC_WINBIND + ++static struct winbindd_domain * ++add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, ++ struct winbindd_methods *methods); ++ + extern struct winbindd_methods cache_methods; + + /** +@@ -91,11 +95,31 @@ static bool is_in_internal_domain(const struct dom_sid *sid) + + /* Add a trusted domain to our list of domains. + If the domain already exists in the list, +- return it and don't re-initialize. +- */ +-static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, +- struct winbindd_methods *methods, +- const struct dom_sid *sid) ++ return it and don't re-initialize. */ ++ ++static struct winbindd_domain * ++add_trusted_domain(const char *domain_name, const char *alt_name, ++ struct winbindd_methods *methods, const struct dom_sid *sid) ++{ ++ struct winbindd_tdc_domain tdc; ++ ++ ZERO_STRUCT(tdc); ++ ++ tdc.domain_name = domain_name; ++ tdc.dns_name = alt_name; ++ if (sid) { ++ sid_copy(&tdc.sid, sid); ++ } ++ ++ return add_trusted_domain_from_tdc(&tdc, methods); ++} ++ ++/* Add a trusted domain out of a trusted domain cache ++ entry ++*/ ++static struct winbindd_domain * ++add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, ++ struct winbindd_methods *methods) + { + struct winbindd_domain *domain; + const char *alternative_name = NULL; +@@ -103,6 +127,12 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const + const char *param; + const char **ignored_domains, **dom; + int role = lp_server_role(); ++ const char *domain_name = tdc->domain_name; ++ const struct dom_sid *sid = &tdc->sid; ++ ++ if (is_null_sid(sid)) { ++ sid = NULL; ++ } + + ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL); + for (dom=ignored_domains; dom && *dom; dom++) { +@@ -114,8 +144,8 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const + + /* ignore alt_name if we are not in an AD domain */ + +- if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) { +- alternative_name = alt_name; ++ if (tdc->dns_name && *tdc->dns_name) { ++ alternative_name = tdc->dns_name; + } + + /* We can't call domain_list() as this function is called from +@@ -127,8 +157,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const + break; + } + +- if (alternative_name && *alternative_name) +- { ++ if (alternative_name) { + if (strequal(alternative_name, domain->name) || + strequal(alternative_name, domain->alt_name)) + { +@@ -136,12 +165,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const + } + } + +- if (sid) +- { +- if (is_null_sid(sid)) { +- continue; +- } +- ++ if (sid != NULL) { + if (dom_sid_equal(sid, &domain->sid)) { + break; + } +@@ -191,11 +215,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const + domain->internal = is_internal_domain(sid); + domain->sequence_number = DOM_SEQUENCE_NONE; + domain->last_seq_check = 0; +- domain->initialized = False; ++ domain->initialized = false; + domain->online = is_internal_domain(sid); + domain->check_online_timeout = 0; + domain->dc_probe_pid = (pid_t)-1; +- if (sid) { ++ if (sid != NULL) { + sid_copy(&domain->sid, sid); + } + +@@ -246,9 +270,9 @@ done: + + setup_domain_child(domain); + +- DEBUG(2,("Added domain %s %s %s\n", +- domain->name, domain->alt_name, +- &domain->sid?sid_string_dbg(&domain->sid):"")); ++ DEBUG(2, ++ ("Added domain %s %s %s\n", domain->name, domain->alt_name, ++ !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : "")); + + return domain; + } +@@ -432,10 +456,8 @@ static void rescan_forest_root_trusts( void ) + d = find_domain_from_name_noinit( dom_list[i].domain_name ); + + if ( !d ) { +- (void)add_trusted_domain( dom_list[i].domain_name, +- dom_list[i].dns_name, +- &cache_methods, +- &dom_list[i].sid); ++ d = add_trusted_domain_from_tdc(&dom_list[i], ++ &cache_methods); + } + + if (d == NULL) { +@@ -501,10 +523,8 @@ static void rescan_forest_trusts( void ) + about it */ + + if ( !d ) { +- (void)add_trusted_domain( dom_list[i].domain_name, +- dom_list[i].dns_name, +- &cache_methods, +- &dom_list[i].sid); ++ d = add_trusted_domain_from_tdc(&dom_list[i], ++ &cache_methods); + } + + if (d == NULL) { +-- +2.9.4 + + +From 153f173eea81ffa1caa4768589a08bb20a6a1950 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher metze@samba.org +Date: Tue, 23 Dec 2014 09:43:03 +0000 +Subject: [PATCH 2/4] s3:winbindd: mark our primary as active_directory if + possible + +Signed-off-by: Stefan Metzmacher metze@samba.org +Reviewed-by: Guenther Deschner gd@samba.org +--- + source3/winbindd/winbindd_util.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c +index 70a9041..700076a 100644 +--- a/source3/winbindd/winbindd_util.c ++++ b/source3/winbindd/winbindd_util.c +@@ -232,6 +232,12 @@ add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, + domain->primary = true; + } + ++ if (domain->primary) { ++ if (lp_security() == SEC_ADS) { ++ domain->active_directory = true; ++ } ++ } ++ + /* Link to domain list */ + DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); + +-- +2.9.4 + + +From 5d741ee3d1dafbb32c106fed817840892b69598d Mon Sep 17 00:00:00 2001 +From: Uri Simchoni uri@samba.org +Date: Wed, 10 Feb 2016 00:32:23 +0200 +Subject: [PATCH 3/4] winbindd: initialize foreign domain as AD based on trust + +Based on trust parameters, initialize the active_directory +member of domain object to true. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11691 + +Signed-off-by: Uri Simchoni uri@samba.org +Reviewed-by: Ralph Boehme slow@samba.org +--- + source3/winbindd/winbindd_util.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c +index 700076a..aaa9ee8 100644 +--- a/source3/winbindd/winbindd_util.c ++++ b/source3/winbindd/winbindd_util.c +@@ -222,6 +222,9 @@ add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, + if (sid != NULL) { + sid_copy(&domain->sid, sid); + } ++ domain->domain_flags = tdc->trust_flags; ++ domain->domain_type = tdc->trust_type; ++ domain->domain_trust_attribs = tdc->trust_attribs; + + /* Is this our primary domain ? */ + if (strequal(domain_name, get_global_sam_name()) && +@@ -236,6 +239,10 @@ add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, + if (lp_security() == SEC_ADS) { + domain->active_directory = true; + } ++ } else if (!domain->internal) { ++ if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) { ++ domain->active_directory = true; ++ } + } + + /* Link to domain list */ +-- +2.9.4 + + +From a8ac7dcae2e3b00362ea9d91b5ef7f149bc734a0 Mon Sep 17 00:00:00 2001 +From: Uri Simchoni uri@samba.org +Date: Wed, 10 Feb 2016 00:38:11 +0200 +Subject: [PATCH 4/4] winbindd: return trust parameters when listing trusts +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When asking a child domain process to list trusts on that domain, +return (along with trust domain names and SID) the trust properties - +flags, type, and attributes. + +Use those attributes to initialize domain object. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11691 + +Signed-off-by: Uri Simchoni uri@samba.org +Reviewed-by: Ralph Boehme slow@samba.org + +Autobuild-User(master): Ralph Böhme slow@samba.org +Autobuild-Date(master): Tue Feb 23 22:02:16 CET 2016 on sn-devel-144 +--- + source3/winbindd/winbindd_misc.c | 11 +++--- + source3/winbindd/winbindd_util.c | 82 +++++++++++++++++++++++++++++----------- + 2 files changed, 65 insertions(+), 28 deletions(-) + +diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c +index 7d25167..5335ad9 100644 +--- a/source3/winbindd/winbindd_misc.c ++++ b/source3/winbindd/winbindd_misc.c +@@ -172,11 +172,12 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * + + for (i=0; i<trusts.count; i++) { + extra_data = talloc_asprintf_append_buffer( +- extra_data, "%s\%s\%s\n", +- trusts.array[i].netbios_name, +- trusts.array[i].dns_name, +- sid_string_talloc(state->mem_ctx, +- trusts.array[i].sid)); ++ extra_data, "%s\%s\%s\%u\%u\%u\n", ++ trusts.array[i].netbios_name, trusts.array[i].dns_name, ++ sid_string_talloc(state->mem_ctx, trusts.array[i].sid), ++ trusts.array[i].trust_flags, ++ (uint32_t)trusts.array[i].trust_type, ++ trusts.array[i].trust_attributes); + } + + /* add our primary domain */ +diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c +index aaa9ee8..b99fac4 100644 +--- a/source3/winbindd/winbindd_util.c ++++ b/source3/winbindd/winbindd_util.c +@@ -343,6 +343,8 @@ static void trustdom_list_done(struct tevent_req *req) + struct winbindd_response *response; + int res, err; + char *p; ++ struct winbindd_tdc_domain trust_params = {0}; ++ ptrdiff_t extra_len; + + res = wb_domain_request_recv(req, state, &response, &err); + if ((res == -1) || (response->result != WINBINDD_OK)) { +@@ -351,17 +353,27 @@ static void trustdom_list_done(struct tevent_req *req) + return; + } + ++ if (response->length < sizeof(struct winbindd_response)) { ++ DEBUG(0, ("ill-formed trustdom response - short length\n")); ++ TALLOC_FREE(state); ++ return; ++ } ++ ++ extra_len = response->length - sizeof(struct winbindd_response); ++ + p = (char *)response->extra_data.data; + +- while ((p != NULL) && (*p != '\0')) { ++ while ((p - (char *)response->extra_data.data) < extra_len) { + char *q, *sidstr, *alt_name; +- struct dom_sid sid; +- struct winbindd_domain *domain; +- char *alternate_name = NULL; ++ ++ DEBUG(10, ("parsing response line '%s'\n", p)); ++ ++ ZERO_STRUCT(trust_params); ++ trust_params.domain_name = p; + + alt_name = strchr(p, '\'); + if (alt_name == NULL) { +- DEBUG(0, ("Got invalid trustdom response\n")); ++ DEBUG(10, ("Got invalid trustdom response\n")); + break; + } + +@@ -370,39 +382,63 @@ static void trustdom_list_done(struct tevent_req *req) + + sidstr = strchr(alt_name, '\'); + if (sidstr == NULL) { +- DEBUG(0, ("Got invalid trustdom response\n")); ++ DEBUG(10, ("Got invalid trustdom response\n")); + break; + } + + *sidstr = '\0'; + sidstr += 1; + +- q = strchr(sidstr, '\n'); +- if (q != NULL) +- *q = '\0'; ++ /* use the real alt_name if we have one, else pass in NULL */ ++ if (!strequal(alt_name, "(null)")) { ++ trust_params.dns_name = alt_name; ++ } ++ ++ q = strtok(sidstr, "\"); ++ if (q == NULL) { ++ DEBUG(10, ("Got invalid trustdom response\n")); ++ break; ++ } ++ ++ if (!string_to_sid(&trust_params.sid, sidstr)) { ++ DEBUG(0, ("Got invalid trustdom response\n")); ++ break; ++ } + +- if (!string_to_sid(&sid, sidstr)) { ++ q = strtok(NULL, "\"); ++ if (q == NULL) { + DEBUG(0, ("Got invalid trustdom response\n")); + break; + } + +- /* use the real alt_name if we have one, else pass in NULL */ ++ trust_params.trust_flags = (uint32_t)strtoul(q, NULL, 10); + +- if ( !strequal( alt_name, "(null)" ) ) +- alternate_name = alt_name; ++ q = strtok(NULL, "\"); ++ if (q == NULL) { ++ DEBUG(0, ("Got invalid trustdom response\n")); ++ break; ++ } ++ ++ trust_params.trust_type = (uint32_t)strtoul(q, NULL, 10); + +- /* If we have an existing domain structure, calling +- add_trusted_domain() will update the SID if +- necessary. This is important because we need the +- SID for sibling domains */ ++ q = strtok(NULL, "\n"); ++ if (q == NULL) { ++ DEBUG(10, ("Got invalid trustdom response\n")); ++ break; ++ } + +- (void)add_trusted_domain(p, alternate_name, +- &cache_methods, +- &sid); ++ trust_params.trust_attribs = (uint32_t)strtoul(q, NULL, 10); ++ ++ /* ++ * We always call add_trusted_domain() cause on an existing ++ * domain structure, it will update the SID if necessary. ++ * This is important because we need the SID for sibling ++ * domains. ++ */ ++ (void)add_trusted_domain_from_tdc(&trust_params, ++ &cache_methods); + +- p=q; +- if (p != NULL) +- p += 1; ++ p = q + strlen(q) + 1; + } + + /* +-- +2.9.4 +
hooks/post-receive -- IPFire 2.x development tree