From 2e94b6ec10f1d15e24867bab3063bb85f173406a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Jul 2015 10:58:11 -0700 Subject: [PATCH] CVE-2015-5252: s3: smbd: Fix symlink verification (file access outside the share). Ensure matching component ends in '/' or '\0'. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11395 Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke --- source3/smbd/vfs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 6c56964..bd93b7f 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) if (!allow_widelinks || !allow_symlinks) { const char *conn_rootdir; size_t rootdir_len; + bool matched; conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname); if (conn_rootdir == NULL) { @@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname) } rootdir_len = strlen(conn_rootdir); - if (strncmp(conn_rootdir, resolved_name, - rootdir_len) != 0) { + matched = (strncmp(conn_rootdir, resolved_name, + rootdir_len) == 0); + if (!matched || (resolved_name[rootdir_len] != '/' && + resolved_name[rootdir_len] != '\0')) { DEBUG(2, ("check_reduced_name: Bad access " "attempt: %s is a symlink outside the " "share path\n", fname)); -- 2.5.0 From 25139116756cc285a3a5534834cc276ef1b7baaa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Sep 2015 21:17:02 +0200 Subject: [PATCH 1/2] CVE-2015-5296: s3:libsmb: force signing when requiring encryption in do_connect() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source3/libsmb/clidfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 23e1471..f153b6b 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, const char *username; const char *password; NTSTATUS status; + int signing_state = get_cmdline_auth_info_signing_state(auth_info); + + if (force_encrypt) { + signing_state = Required; + } /* make a copy so we don't modify the global string 'service' */ servicename = talloc_strdup(ctx,share); @@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, zero_sockaddr(&ss); /* have to open a new connection */ - c = cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)); + c = cli_initialise_ex(signing_state); if (c == NULL) { d_printf("Connection to %s failed\n", server_n); return NULL; -- 2.5.0 From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Sep 2015 21:17:02 +0200 Subject: [PATCH 2/2] CVE-2015-5296: s3:libsmb: force signing when requiring encryption in SMBC_server_internal() BUG: https://bugzilla.samba.org/show_bug.cgi?id=11536 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison --- source3/libsmb/libsmb_server.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 45be660..167f2c9 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx, const char *username_used; NTSTATUS status; char *newserver, *newshare; + int signing_state = Undefined; zero_sockaddr(&ss); ZERO_STRUCT(c); @@ -404,8 +405,12 @@ again: zero_sockaddr(&ss); + if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { + signing_state = Required; + } + /* have to open a new connection */ - if ((c = cli_initialise()) == NULL) { + if ((c = cli_initialise_ex(signing_state)) == NULL) { errno = ENOMEM; return NULL; } @@ -750,6 +755,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", pp_workgroup, pp_username, pp_password); if (!ipc_srv) { + int signing_state = Undefined; /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { @@ -771,6 +777,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, if (smbc_getOptionUseCCache(context)) { flags |= CLI_FULL_CONNECTION_USE_CCACHE; } + if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { + signing_state = Required; + } zero_sockaddr(&ss); nt_status = cli_full_connection(&ipc_cli, @@ -780,7 +789,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, *pp_workgroup, *pp_password, flags, - Undefined); + signing_state); if (! NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); -- 2.5.0 From 8e49de7754f7171a58a1f94dee0f1138dbee3c60 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Oct 2015 14:54:31 -0700 Subject: [PATCH] CVE-2015-5299: s3-shadow-copy2: fix missing access check on snapdir Fix originally from https://bugzilla.samba.org/show_bug.cgi?id=11529 Signed-off-by: Jeremy Allison Reviewed-by: David Disseldorp --- source3/modules/vfs_shadow_copy2.c | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index fedfb53..16c1ed7 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -21,6 +21,8 @@ #include "includes.h" #include "smbd/smbd.h" +#include "smbd/globals.h" +#include "../libcli/security/security.h" #include "system/filesys.h" #include "ntioctl.h" @@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle_struct *handle, const char *fname, mod SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1); } +static bool check_access_snapdir(struct vfs_handle_struct *handle, + const char *path) +{ + struct smb_filename smb_fname; + int ret; + NTSTATUS status; + uint32_t access_granted = 0; + + ZERO_STRUCT(smb_fname); + smb_fname.base_name = talloc_asprintf(talloc_tos(), + "%s", + path); + if (smb_fname.base_name == NULL) { + return false; + } + + ret = SMB_VFS_NEXT_STAT(handle, &smb_fname); + if (ret != 0 || !S_ISDIR(smb_fname.st.st_ex_mode)) { + TALLOC_FREE(smb_fname.base_name); + return false; + } + + status = smbd_check_open_rights(handle->conn, + &smb_fname, + SEC_DIR_LIST, + &access_granted); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("user does not have list permission " + "on snapdir %s\n", + smb_fname.base_name)); + TALLOC_FREE(smb_fname.base_name); + return false; + } + TALLOC_FREE(smb_fname.base_name); + return true; +} + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) { SHADOW2_NEXT(RMDIR, (handle, name), int, -1); @@ -877,6 +916,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, SMB_STRUCT_DIRENT *d; TALLOC_CTX *tmp_ctx = talloc_new(handle->data); char *snapshot; + bool ret; snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle); if (snapdir == NULL) { @@ -886,6 +926,13 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, talloc_free(tmp_ctx); return -1; } + ret = check_access_snapdir(handle, snapdir); + if (!ret) { + DEBUG(0,("access denied on listing snapdir %s\n", snapdir)); + errno = EACCES; + talloc_free(tmp_ctx); + return -1; + } p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0); -- 2.5.0