samba: fix some security problems
This fixes the following security problems: * CVE-2015-7560 * CVE-2015-5370 * CVE-2016-2110 * CVE-2016-2111 * CVE-2016-2112 * CVE-2016-2115 * CVE-2016-2118 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 49175
This commit is contained in:
parent
894aed060e
commit
1414f1647d
21 changed files with 20105 additions and 46 deletions
|
@ -14,11 +14,9 @@ Reviewed-by: Volker Lendecke <vl@samba.org>
|
||||||
source3/smbd/vfs.c | 7 +++++--
|
source3/smbd/vfs.c | 7 +++++--
|
||||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
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
|
--- a/source3/smbd/vfs.c
|
||||||
+++ b/source3/smbd/vfs.c
|
+++ b/source3/smbd/vfs.c
|
||||||
@@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
|
@@ -982,6 +982,7 @@ NTSTATUS check_reduced_name(connection_s
|
||||||
if (!allow_widelinks || !allow_symlinks) {
|
if (!allow_widelinks || !allow_symlinks) {
|
||||||
const char *conn_rootdir;
|
const char *conn_rootdir;
|
||||||
size_t rootdir_len;
|
size_t rootdir_len;
|
||||||
|
@ -26,7 +24,7 @@ index 6c56964..bd93b7f 100644
|
||||||
|
|
||||||
conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
|
conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
|
||||||
if (conn_rootdir == NULL) {
|
if (conn_rootdir == NULL) {
|
||||||
@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
|
@@ -992,8 +993,10 @@ NTSTATUS check_reduced_name(connection_s
|
||||||
}
|
}
|
||||||
|
|
||||||
rootdir_len = strlen(conn_rootdir);
|
rootdir_len = strlen(conn_rootdir);
|
||||||
|
@ -39,5 +37,3 @@ index 6c56964..bd93b7f 100644
|
||||||
DEBUG(2, ("check_reduced_name: Bad access "
|
DEBUG(2, ("check_reduced_name: Bad access "
|
||||||
"attempt: %s is a symlink outside the "
|
"attempt: %s is a symlink outside the "
|
||||||
"share path\n", fname));
|
"share path\n", fname));
|
||||||
--
|
|
||||||
2.5.0
|
|
||||||
|
|
|
@ -12,11 +12,9 @@ Reviewed-by: Jeremy Allison <jra@samba.org>
|
||||||
source3/libsmb/clidfs.c | 7 ++++++-
|
source3/libsmb/clidfs.c | 7 ++++++-
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
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
|
--- a/source3/libsmb/clidfs.c
|
||||||
+++ b/source3/libsmb/clidfs.c
|
+++ b/source3/libsmb/clidfs.c
|
||||||
@@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
|
@@ -98,6 +98,11 @@ static struct cli_state *do_connect(TALL
|
||||||
const char *username;
|
const char *username;
|
||||||
const char *password;
|
const char *password;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
@ -28,7 +26,7 @@ index 23e1471..f153b6b 100644
|
||||||
|
|
||||||
/* make a copy so we don't modify the global string 'service' */
|
/* make a copy so we don't modify the global string 'service' */
|
||||||
servicename = talloc_strdup(ctx,share);
|
servicename = talloc_strdup(ctx,share);
|
||||||
@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
|
@@ -132,7 +137,7 @@ static struct cli_state *do_connect(TALL
|
||||||
zero_sockaddr(&ss);
|
zero_sockaddr(&ss);
|
||||||
|
|
||||||
/* have to open a new connection */
|
/* have to open a new connection */
|
||||||
|
@ -37,26 +35,6 @@ index 23e1471..f153b6b 100644
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
d_printf("Connection to %s failed\n", server_n);
|
d_printf("Connection to %s failed\n", server_n);
|
||||||
return NULL;
|
return NULL;
|
||||||
--
|
|
||||||
2.5.0
|
|
||||||
|
|
||||||
|
|
||||||
From 060adb0abdeda51b8b622c6020b5dea0c8dde1cf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stefan Metzmacher <metze@samba.org>
|
|
||||||
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 <metze@samba.org>
|
|
||||||
Reviewed-by: Jeremy Allison <jra@samba.org>
|
|
||||||
---
|
|
||||||
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
|
--- a/source3/libsmb/libsmb_server.c
|
||||||
+++ b/source3/libsmb/libsmb_server.c
|
+++ b/source3/libsmb/libsmb_server.c
|
||||||
@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
|
@@ -258,6 +258,7 @@ SMBC_server_internal(TALLOC_CTX *ctx,
|
||||||
|
@ -108,5 +86,3 @@ index 45be660..167f2c9 100644
|
||||||
if (! NT_STATUS_IS_OK(nt_status)) {
|
if (! NT_STATUS_IS_OK(nt_status)) {
|
||||||
DEBUG(1,("cli_full_connection failed! (%s)\n",
|
DEBUG(1,("cli_full_connection failed! (%s)\n",
|
||||||
nt_errstr(nt_status)));
|
nt_errstr(nt_status)));
|
||||||
--
|
|
||||||
2.5.0
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ Reviewed-by: David Disseldorp <ddiss@samba.org>
|
||||||
source3/modules/vfs_shadow_copy2.c | 47 ++++++++++++++++++++++++++++++++++++++
|
source3/modules/vfs_shadow_copy2.c | 47 ++++++++++++++++++++++++++++++++++++++
|
||||||
1 file changed, 47 insertions(+)
|
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
|
--- a/source3/modules/vfs_shadow_copy2.c
|
||||||
+++ b/source3/modules/vfs_shadow_copy2.c
|
+++ b/source3/modules/vfs_shadow_copy2.c
|
||||||
@@ -21,6 +21,8 @@
|
@@ -21,6 +21,8 @@
|
||||||
|
@ -27,7 +25,7 @@ index fedfb53..16c1ed7 100644
|
||||||
#include "system/filesys.h"
|
#include "system/filesys.h"
|
||||||
#include "ntioctl.h"
|
#include "ntioctl.h"
|
||||||
|
|
||||||
@@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle_struct *handle, const char *fname, mod
|
@@ -764,6 +766,43 @@ static int shadow_copy2_mkdir(vfs_handle
|
||||||
SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1);
|
SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +69,7 @@ index fedfb53..16c1ed7 100644
|
||||||
static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname)
|
static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname)
|
||||||
{
|
{
|
||||||
SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
|
SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
|
||||||
@@ -877,6 +916,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
|
@@ -877,6 +916,7 @@ static int shadow_copy2_get_shadow_copy2
|
||||||
SMB_STRUCT_DIRENT *d;
|
SMB_STRUCT_DIRENT *d;
|
||||||
TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
|
TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
|
||||||
char *snapshot;
|
char *snapshot;
|
||||||
|
@ -79,7 +77,7 @@ index fedfb53..16c1ed7 100644
|
||||||
|
|
||||||
snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
|
snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
|
||||||
if (snapdir == NULL) {
|
if (snapdir == NULL) {
|
||||||
@@ -886,6 +926,13 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
|
@@ -886,6 +926,13 @@ static int shadow_copy2_get_shadow_copy2
|
||||||
talloc_free(tmp_ctx);
|
talloc_free(tmp_ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -93,5 +91,3 @@ index fedfb53..16c1ed7 100644
|
||||||
|
|
||||||
p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0);
|
p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0);
|
||||||
|
|
||||||
--
|
|
||||||
2.5.0
|
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
From eb27f9b7bf9c1dc902d9545eecf805831bd4e46c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeremy Allison <jra@samba.org>
|
||||||
|
Date: Tue, 5 Jan 2016 11:18:12 -0800
|
||||||
|
Subject: [PATCH 1/8] CVE-2015-7560: s3: smbd: Add refuse_symlink() function
|
||||||
|
that can be used to prevent operations on a symlink.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
|
||||||
|
|
||||||
|
Signed-off-by: Jeremy Allison <jra@samba.org>
|
||||||
|
Reviewed-by: Michael Adam <obnox@samba.org>
|
||||||
|
---
|
||||||
|
source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 28 insertions(+)
|
||||||
|
|
||||||
|
--- a/source3/smbd/trans2.c
|
||||||
|
+++ b/source3/smbd/trans2.c
|
||||||
|
@@ -51,6 +51,34 @@ static char *store_file_unix_basic_info2
|
||||||
|
files_struct *fsp,
|
||||||
|
const SMB_STRUCT_STAT *psbuf);
|
||||||
|
|
||||||
|
+/****************************************************************************
|
||||||
|
+ Check if an open file handle or pathname is a symlink.
|
||||||
|
+****************************************************************************/
|
||||||
|
+
|
||||||
|
+static NTSTATUS refuse_symlink(connection_struct *conn,
|
||||||
|
+ const files_struct *fsp,
|
||||||
|
+ const char *name)
|
||||||
|
+{
|
||||||
|
+ SMB_STRUCT_STAT sbuf;
|
||||||
|
+ const SMB_STRUCT_STAT *pst = NULL;
|
||||||
|
+
|
||||||
|
+ if (fsp) {
|
||||||
|
+ pst = &fsp->fsp_name->st;
|
||||||
|
+ } else {
|
||||||
|
+ int ret = vfs_stat_smb_fname(conn,
|
||||||
|
+ name,
|
||||||
|
+ &sbuf);
|
||||||
|
+ if (ret == -1) {
|
||||||
|
+ return map_nt_error_from_unix(errno);
|
||||||
|
+ }
|
||||||
|
+ pst = &sbuf;
|
||||||
|
+ }
|
||||||
|
+ if (S_ISLNK(pst->st_ex_mode)) {
|
||||||
|
+ return NT_STATUS_ACCESS_DENIED;
|
||||||
|
+ }
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/********************************************************************
|
||||||
|
Roundup a value to the nearest allocation roundup size boundary.
|
||||||
|
Only do this for Windows clients.
|
||||||
|
@@ -181,12 +209,22 @@ NTSTATUS get_ea_names_from_file(TALLOC_C
|
||||||
|
char **names, **tmp;
|
||||||
|
size_t num_names;
|
||||||
|
ssize_t sizeret = -1;
|
||||||
|
+ NTSTATUS status;
|
||||||
|
+
|
||||||
|
+ if (pnames) {
|
||||||
|
+ *pnames = NULL;
|
||||||
|
+ }
|
||||||
|
+ *pnum_names = 0;
|
||||||
|
|
||||||
|
if (!lp_ea_support(SNUM(conn))) {
|
||||||
|
- if (pnames) {
|
||||||
|
- *pnames = NULL;
|
||||||
|
- }
|
||||||
|
- *pnum_names = 0;
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ status = refuse_symlink(conn, fsp, fname);
|
||||||
|
+ if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
+ /*
|
||||||
|
+ * Just return no EA's on a symlink.
|
||||||
|
+ */
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -236,10 +274,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_C
|
||||||
|
|
||||||
|
if (sizeret == 0) {
|
||||||
|
TALLOC_FREE(names);
|
||||||
|
- if (pnames) {
|
||||||
|
- *pnames = NULL;
|
||||||
|
- }
|
||||||
|
- *pnum_names = 0;
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -550,6 +584,7 @@ NTSTATUS set_ea(connection_struct *conn,
|
||||||
|
const struct smb_filename *smb_fname, struct ea_list *ea_list)
|
||||||
|
{
|
||||||
|
char *fname = NULL;
|
||||||
|
+ NTSTATUS status;
|
||||||
|
|
||||||
|
if (!lp_ea_support(SNUM(conn))) {
|
||||||
|
return NT_STATUS_EAS_NOT_SUPPORTED;
|
||||||
|
@@ -559,6 +594,12 @@ NTSTATUS set_ea(connection_struct *conn,
|
||||||
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ status = refuse_symlink(conn, fsp, smb_fname->base_name);
|
||||||
|
+ if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* For now setting EAs on streams isn't supported. */
|
||||||
|
fname = smb_fname->base_name;
|
||||||
|
|
||||||
|
@@ -4931,6 +4972,13 @@ NTSTATUS smbd_do_qfilepathinfo(connectio
|
||||||
|
uint16 num_file_acls = 0;
|
||||||
|
uint16 num_def_acls = 0;
|
||||||
|
|
||||||
|
+ status = refuse_symlink(conn,
|
||||||
|
+ fsp,
|
||||||
|
+ smb_fname->base_name);
|
||||||
|
+ if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (fsp && fsp->fh->fd != -1) {
|
||||||
|
file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp);
|
||||||
|
} else {
|
||||||
|
@@ -6452,6 +6500,7 @@ static NTSTATUS smb_set_posix_acl(connec
|
||||||
|
uint16 num_def_acls;
|
||||||
|
bool valid_file_acls = True;
|
||||||
|
bool valid_def_acls = True;
|
||||||
|
+ NTSTATUS status;
|
||||||
|
|
||||||
|
if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
|
||||||
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
@@ -6479,6 +6528,11 @@ static NTSTATUS smb_set_posix_acl(connec
|
||||||
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ status = refuse_symlink(conn, fsp, smb_fname->base_name);
|
||||||
|
+ if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
DEBUG(10,("smb_set_posix_acl: file %s num_file_acls = %u, num_def_acls = %u\n",
|
||||||
|
smb_fname ? smb_fname_str_dbg(smb_fname) : fsp_str_dbg(fsp),
|
||||||
|
(unsigned int)num_file_acls,
|
||||||
|
--- a/source3/smbd/nttrans.c
|
||||||
|
+++ b/source3/smbd/nttrans.c
|
||||||
|
@@ -877,6 +877,12 @@ NTSTATUS set_sd(files_struct *fsp, struc
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
|
||||||
|
+ DEBUG(10, ("ACL set on symlink %s denied.\n",
|
||||||
|
+ fsp_str_dbg(fsp)));
|
||||||
|
+ return NT_STATUS_ACCESS_DENIED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (psd->owner_sid == NULL) {
|
||||||
|
security_info_sent &= ~SECINFO_OWNER;
|
||||||
|
}
|
||||||
|
@@ -1925,6 +1931,12 @@ NTSTATUS smbd_do_query_security_desc(con
|
||||||
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
|
||||||
|
+ DEBUG(10, ("ACL get on symlink %s denied.\n",
|
||||||
|
+ fsp_str_dbg(fsp)));
|
||||||
|
+ return NT_STATUS_ACCESS_DENIED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|
|
||||||
|
SECINFO_GROUP|SECINFO_SACL)) {
|
||||||
|
/* Don't return SECINFO_LABEL if anything else was
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,255 @@
|
||||||
|
From 202d69267c8550b850438877fb51c3d2c992949d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Metzmacher <metze@samba.org>
|
||||||
|
Date: Tue, 1 Dec 2015 08:46:45 +0100
|
||||||
|
Subject: [PATCH 01/10] CVE-2016-2110: s3:ntlmssp: set and use
|
||||||
|
ntlmssp_state->allow_lm_key
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644
|
||||||
|
|
||||||
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||||
|
Reviewed-by: Günther Deschner <gd@samba.org>
|
||||||
|
---
|
||||||
|
source3/libsmb/ntlmssp.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/source3/libsmb/ntlmssp.c
|
||||||
|
+++ b/source3/libsmb/ntlmssp.c
|
||||||
|
@@ -176,17 +176,19 @@ void ntlmssp_want_feature_list(struct nt
|
||||||
|
* also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
|
||||||
|
*/
|
||||||
|
if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
}
|
||||||
|
if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
}
|
||||||
|
if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||||
|
}
|
||||||
|
if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) {
|
||||||
|
ntlmssp_state->use_ccache = true;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -199,17 +201,20 @@ void ntlmssp_want_feature(struct ntlmssp
|
||||||
|
{
|
||||||
|
/* As per JRA's comment above */
|
||||||
|
if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
}
|
||||||
|
if (feature & NTLMSSP_FEATURE_SIGN) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
}
|
||||||
|
if (feature & NTLMSSP_FEATURE_SEAL) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||||
|
}
|
||||||
|
if (feature & NTLMSSP_FEATURE_CCACHE) {
|
||||||
|
ntlmssp_state->use_ccache = true;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -387,7 +392,12 @@ static NTSTATUS ntlmssp_client_initial(s
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ntlmssp_state->use_ntlmv2) {
|
||||||
|
- ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
|
||||||
|
+ ntlmssp_state->required_flags |= NTLMSSP_NEGOTIATE_NTLM2;
|
||||||
|
+ ntlmssp_state->allow_lm_key = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ntlmssp_state->allow_lm_key) {
|
||||||
|
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* generate the ntlmssp negotiate packet */
|
||||||
|
@@ -422,6 +432,86 @@ static NTSTATUS ntlmssp_client_initial(s
|
||||||
|
return NT_STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static NTSTATUS ntlmssp3_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
||||||
|
+ uint32_t flags)
|
||||||
|
+{
|
||||||
|
+ uint32_t missing_flags = ntlmssp_state->required_flags;
|
||||||
|
+
|
||||||
|
+ if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
|
||||||
|
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
|
||||||
|
+ ntlmssp_state->unicode = true;
|
||||||
|
+ } else {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
|
||||||
|
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
|
||||||
|
+ ntlmssp_state->unicode = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
|
||||||
|
+ * has priority over NTLMSSP_NEGOTIATE_LM_KEY
|
||||||
|
+ */
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_128)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_56)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
|
||||||
|
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((flags & NTLMSSP_REQUEST_TARGET)) {
|
||||||
|
+ ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ missing_flags &= ~ntlmssp_state->neg_flags;
|
||||||
|
+ if (missing_flags != 0) {
|
||||||
|
+ NTSTATUS status = NT_STATUS_RPC_SEC_PKG_ERROR;
|
||||||
|
+ DEBUG(1, ("%s: Got challenge flags[0x%08x] "
|
||||||
|
+ "- possible downgrade detected! "
|
||||||
|
+ "missing_flags[0x%08x] - %s\n",
|
||||||
|
+ __func__,
|
||||||
|
+ (unsigned)flags,
|
||||||
|
+ (unsigned)missing_flags,
|
||||||
|
+ nt_errstr(status)));
|
||||||
|
+ debug_ntlmssp_flags(missing_flags);
|
||||||
|
+ DEBUGADD(4, ("neg_flags[0x%08x]\n",
|
||||||
|
+ (unsigned)ntlmssp_state->neg_flags));
|
||||||
|
+ debug_ntlmssp_flags(ntlmssp_state->neg_flags);
|
||||||
|
+
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Next state function for the Challenge Packet. Generate an auth packet.
|
||||||
|
*
|
||||||
|
@@ -448,6 +538,26 @@ static NTSTATUS ntlmssp_client_challenge
|
||||||
|
DATA_BLOB encrypted_session_key = data_blob_null;
|
||||||
|
NTSTATUS nt_status = NT_STATUS_OK;
|
||||||
|
|
||||||
|
+ if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
|
||||||
|
+ "NTLMSSP",
|
||||||
|
+ &ntlmssp_command,
|
||||||
|
+ &server_domain_blob,
|
||||||
|
+ &chal_flags)) {
|
||||||
|
+ DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
|
||||||
|
+ dump_data(2, reply.data, reply.length);
|
||||||
|
+
|
||||||
|
+ return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+ data_blob_free(&server_domain_blob);
|
||||||
|
+
|
||||||
|
+ DEBUG(3, ("Got challenge flags:\n"));
|
||||||
|
+ debug_ntlmssp_flags(chal_flags);
|
||||||
|
+
|
||||||
|
+ nt_status = ntlmssp3_handle_neg_flags(ntlmssp_state, chal_flags);
|
||||||
|
+ if (!NT_STATUS_IS_OK(nt_status)) {
|
||||||
|
+ return nt_status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (ntlmssp_state->use_ccache) {
|
||||||
|
struct wbcCredentialCacheParams params;
|
||||||
|
struct wbcCredentialCacheInfo *info = NULL;
|
||||||
|
@@ -498,17 +608,6 @@ static NTSTATUS ntlmssp_client_challenge
|
||||||
|
|
||||||
|
noccache:
|
||||||
|
|
||||||
|
- if (!msrpc_parse(ntlmssp_state, &reply, "CdBd",
|
||||||
|
- "NTLMSSP",
|
||||||
|
- &ntlmssp_command,
|
||||||
|
- &server_domain_blob,
|
||||||
|
- &chal_flags)) {
|
||||||
|
- DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
|
||||||
|
- dump_data(2, reply.data, reply.length);
|
||||||
|
-
|
||||||
|
- return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if (DEBUGLEVEL >= 10) {
|
||||||
|
struct CHALLENGE_MESSAGE *challenge = talloc(
|
||||||
|
talloc_tos(), struct CHALLENGE_MESSAGE);
|
||||||
|
@@ -525,13 +624,6 @@ noccache:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- data_blob_free(&server_domain_blob);
|
||||||
|
-
|
||||||
|
- DEBUG(3, ("Got challenge flags:\n"));
|
||||||
|
- debug_ntlmssp_flags(chal_flags);
|
||||||
|
-
|
||||||
|
- ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
|
||||||
|
-
|
||||||
|
if (ntlmssp_state->unicode) {
|
||||||
|
if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
|
||||||
|
chal_parse_string = "CdUdbddB";
|
||||||
|
@@ -769,6 +861,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
|
||||||
|
ntlmssp_state->unicode = True;
|
||||||
|
|
||||||
|
ntlmssp_state->use_ntlmv2 = use_ntlmv2;
|
||||||
|
+ ntlmssp_state->allow_lm_key = lp_client_lanman_auth();
|
||||||
|
|
||||||
|
ntlmssp_state->expected_state = NTLMSSP_INITIAL;
|
||||||
|
|
||||||
|
@@ -780,6 +873,10 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX
|
||||||
|
NTLMSSP_NEGOTIATE_KEY_EXCH |
|
||||||
|
NTLMSSP_REQUEST_TARGET;
|
||||||
|
|
||||||
|
+ if (ntlmssp_state->use_ntlmv2) {
|
||||||
|
+ ntlmssp_state->allow_lm_key = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ntlmssp_state->client.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
|
||||||
|
if (!ntlmssp_state->client.netbios_name) {
|
||||||
|
talloc_free(ntlmssp_state);
|
||||||
|
--- a/libcli/auth/ntlmssp.h
|
||||||
|
+++ b/libcli/auth/ntlmssp.h
|
||||||
|
@@ -83,6 +83,7 @@ struct ntlmssp_state
|
||||||
|
DATA_BLOB nt_resp;
|
||||||
|
DATA_BLOB session_key;
|
||||||
|
|
||||||
|
+ uint32_t required_flags;
|
||||||
|
uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
|
||||||
|
|
||||||
|
/**
|
|
@ -0,0 +1,681 @@
|
||||||
|
From ee105156fa151ebfd34b8febc2928e144b3b7b0e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
|
||||||
|
Date: Sat, 26 Sep 2015 01:29:10 +0200
|
||||||
|
Subject: [PATCH 01/15] CVE-2016-2111: s3:rpc_server/netlogon: always go
|
||||||
|
through netr_creds_server_step_check()
|
||||||
|
|
||||||
|
The ensures we apply the "server schannel = yes" restrictions.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11749
|
||||||
|
|
||||||
|
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
|
||||||
|
|
||||||
|
Signed-off-by: Guenther Deschner <gd@samba.org>
|
||||||
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||||
|
---
|
||||||
|
source3/rpc_server/netlogon/srv_netlog_nt.c | 24 ++++++++++++++----------
|
||||||
|
1 file changed, 14 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
|
||||||
|
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
|
||||||
|
@@ -1508,6 +1508,7 @@ static NTSTATUS _netr_LogonSamLogon_base
|
||||||
|
case NetlogonNetworkTransitiveInformation:
|
||||||
|
{
|
||||||
|
const char *wksname = nt_workstation;
|
||||||
|
+ const char *workgroup = lp_workgroup();
|
||||||
|
|
||||||
|
status = make_auth_context_fixed(talloc_tos(), &auth_context,
|
||||||
|
logon->network->challenge);
|
||||||
|
@@ -1532,6 +1533,14 @@ static NTSTATUS _netr_LogonSamLogon_base
|
||||||
|
logon->network->nt.length)) {
|
||||||
|
status = NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (NT_STATUS_IS_OK(status)) {
|
||||||
|
+ status = NTLMv2_RESPONSE_verify_netlogon_creds(
|
||||||
|
+ user_info->client.account_name,
|
||||||
|
+ user_info->client.domain_name,
|
||||||
|
+ user_info->password.response.nt,
|
||||||
|
+ creds, workgroup);
|
||||||
|
+ }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NetlogonInteractiveInformation:
|
||||||
|
@@ -1636,6 +1645,14 @@ static NTSTATUS _netr_LogonSamLogon_base
|
||||||
|
r->out.validation->sam3);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
+ /* Only allow this if the pipe is protected. */
|
||||||
|
+ if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
|
||||||
|
+ DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
|
||||||
|
+ get_remote_machine_name()));
|
||||||
|
+ status = NT_STATUS_INVALID_PARAMETER;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
status = serverinfo_to_SamInfo6(server_info, pipe_session_key, 16,
|
||||||
|
r->out.validation->sam6);
|
||||||
|
break;
|
||||||
|
@@ -2271,11 +2288,13 @@ NTSTATUS _netr_GetForestTrustInformation
|
||||||
|
|
||||||
|
/* TODO: check server name */
|
||||||
|
|
||||||
|
- status = schannel_check_creds_state(p->mem_ctx, lp_private_dir(),
|
||||||
|
- r->in.computer_name,
|
||||||
|
- r->in.credential,
|
||||||
|
- r->out.return_authenticator,
|
||||||
|
- &creds);
|
||||||
|
+ become_root();
|
||||||
|
+ status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||||
|
+ r->in.computer_name,
|
||||||
|
+ r->in.credential,
|
||||||
|
+ r->out.return_authenticator,
|
||||||
|
+ &creds);
|
||||||
|
+ unbecome_root();
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
@@ -2371,11 +2390,13 @@ NTSTATUS _netr_ServerGetTrustInfo(struct
|
||||||
|
|
||||||
|
/* TODO: check server name */
|
||||||
|
|
||||||
|
- status = schannel_check_creds_state(p->mem_ctx, lp_private_dir(),
|
||||||
|
- r->in.computer_name,
|
||||||
|
- r->in.credential,
|
||||||
|
- r->out.return_authenticator,
|
||||||
|
- &creds);
|
||||||
|
+ become_root();
|
||||||
|
+ status = netr_creds_server_step_check(p, p->mem_ctx,
|
||||||
|
+ r->in.computer_name,
|
||||||
|
+ r->in.credential,
|
||||||
|
+ r->out.return_authenticator,
|
||||||
|
+ &creds);
|
||||||
|
+ unbecome_root();
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
--- a/source4/torture/rpc/samba3rpc.c
|
||||||
|
+++ b/source4/torture/rpc/samba3rpc.c
|
||||||
|
@@ -1122,8 +1122,8 @@ static bool schan(struct torture_context
|
||||||
|
generate_random_buffer(chal.data, chal.length);
|
||||||
|
names_blob = NTLMv2_generate_names_blob(
|
||||||
|
mem_ctx,
|
||||||
|
- cli_credentials_get_workstation(user_creds),
|
||||||
|
- cli_credentials_get_domain(user_creds));
|
||||||
|
+ cli_credentials_get_workstation(wks_creds),
|
||||||
|
+ cli_credentials_get_domain(wks_creds));
|
||||||
|
status = cli_credentials_get_ntlm_response(
|
||||||
|
user_creds, mem_ctx, &flags, chal, names_blob,
|
||||||
|
&lm_resp, &nt_resp, NULL, NULL);
|
||||||
|
--- a/libcli/auth/proto.h
|
||||||
|
+++ b/libcli/auth/proto.h
|
||||||
|
@@ -139,6 +139,11 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ct
|
||||||
|
const DATA_BLOB *names_blob,
|
||||||
|
DATA_BLOB *lm_response, DATA_BLOB *nt_response,
|
||||||
|
DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key) ;
|
||||||
|
+NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name,
|
||||||
|
+ const char *account_domain,
|
||||||
|
+ const DATA_BLOB response,
|
||||||
|
+ const struct netlogon_creds_CredentialState *creds,
|
||||||
|
+ const char *workgroup);
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
encode a password buffer with a unicode password. The buffer
|
||||||
|
--- a/libcli/auth/smbencrypt.c
|
||||||
|
+++ b/libcli/auth/smbencrypt.c
|
||||||
|
@@ -26,7 +26,7 @@
|
||||||
|
#include "../libcli/auth/msrpc_parse.h"
|
||||||
|
#include "../lib/crypto/crypto.h"
|
||||||
|
#include "../libcli/auth/libcli_auth.h"
|
||||||
|
-#include "../librpc/gen_ndr/ntlmssp.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_ntlmssp.h"
|
||||||
|
|
||||||
|
void SMBencrypt_hash(const uint8_t lm_hash[16], const uint8_t *c8, uint8_t p24[24])
|
||||||
|
{
|
||||||
|
@@ -522,6 +522,146 @@ bool SMBNTLMv2encrypt(TALLOC_CTX *mem_ct
|
||||||
|
lm_response, nt_response, lm_session_key, user_session_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
+NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name,
|
||||||
|
+ const char *account_domain,
|
||||||
|
+ const DATA_BLOB response,
|
||||||
|
+ const struct netlogon_creds_CredentialState *creds,
|
||||||
|
+ const char *workgroup)
|
||||||
|
+{
|
||||||
|
+ TALLOC_CTX *frame = NULL;
|
||||||
|
+ /* RespType + HiRespType */
|
||||||
|
+ static const char *magic = "\x01\x01";
|
||||||
|
+ int cmp;
|
||||||
|
+ struct NTLMv2_RESPONSE v2_resp;
|
||||||
|
+ enum ndr_err_code err;
|
||||||
|
+ const struct AV_PAIR *av_nb_cn = NULL;
|
||||||
|
+ const struct AV_PAIR *av_nb_dn = NULL;
|
||||||
|
+
|
||||||
|
+ if (response.length < 48) {
|
||||||
|
+ /*
|
||||||
|
+ * NTLMv2_RESPONSE has at least 48 bytes.
|
||||||
|
+ */
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cmp = memcmp(response.data + 16, magic, 2);
|
||||||
|
+ if (cmp != 0) {
|
||||||
|
+ /*
|
||||||
|
+ * It doesn't look like a valid NTLMv2_RESPONSE
|
||||||
|
+ */
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ frame = talloc_stackframe();
|
||||||
|
+
|
||||||
|
+ err = ndr_pull_struct_blob(&response, frame, &v2_resp,
|
||||||
|
+ (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE);
|
||||||
|
+ if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
|
||||||
|
+ NTSTATUS status;
|
||||||
|
+ status = ndr_map_error2ntstatus(err);
|
||||||
|
+ DEBUG(2,("Failed to parse NTLMv2_RESPONSE "
|
||||||
|
+ "length %u - %s - %s\n",
|
||||||
|
+ (unsigned)response.length,
|
||||||
|
+ ndr_map_error2string(err),
|
||||||
|
+ nt_errstr(status)));
|
||||||
|
+ dump_data(2, response.data, response.length);
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (DEBUGLVL(10)) {
|
||||||
|
+ NDR_PRINT_DEBUG(NTLMv2_RESPONSE, &v2_resp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Make sure the netbios computer name in the
|
||||||
|
+ * NTLMv2_RESPONSE matches the computer name
|
||||||
|
+ * in the secure channel credentials for workstation
|
||||||
|
+ * trusts.
|
||||||
|
+ *
|
||||||
|
+ * And the netbios domain name matches our
|
||||||
|
+ * workgroup.
|
||||||
|
+ *
|
||||||
|
+ * This prevents workstations from requesting
|
||||||
|
+ * the session key of NTLMSSP sessions of clients
|
||||||
|
+ * to other hosts.
|
||||||
|
+ */
|
||||||
|
+ if (creds->secure_channel_type == SEC_CHAN_WKSTA) {
|
||||||
|
+ av_nb_cn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
|
||||||
|
+ MsvAvNbComputerName);
|
||||||
|
+ av_nb_dn = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
|
||||||
|
+ MsvAvNbDomainName);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (av_nb_cn != NULL) {
|
||||||
|
+ const char *v = NULL;
|
||||||
|
+ char *a = NULL;
|
||||||
|
+ size_t len;
|
||||||
|
+
|
||||||
|
+ v = av_nb_cn->Value.AvNbComputerName;
|
||||||
|
+
|
||||||
|
+ a = talloc_strdup(frame, creds->account_name);
|
||||||
|
+ if (a == NULL) {
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return NT_STATUS_NO_MEMORY;
|
||||||
|
+ }
|
||||||
|
+ len = strlen(a);
|
||||||
|
+ if (len > 0 && a[len - 1] == '$') {
|
||||||
|
+ a[len - 1] = '\0';
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#ifdef SAMBA4_INTERNAL_HEIMDAL /* smbtorture4 for make test */
|
||||||
|
+ cmp = strcasecmp_m(a, v);
|
||||||
|
+#else /* smbd */
|
||||||
|
+ cmp = StrCaseCmp(a, v);
|
||||||
|
+#endif
|
||||||
|
+ if (cmp != 0) {
|
||||||
|
+ DEBUG(2,("%s: NTLMv2_RESPONSE with "
|
||||||
|
+ "NbComputerName[%s] rejected "
|
||||||
|
+ "for user[%s\\%s] "
|
||||||
|
+ "against SEC_CHAN_WKSTA[%s/%s] "
|
||||||
|
+ "in workgroup[%s]\n",
|
||||||
|
+ __func__, v,
|
||||||
|
+ account_domain,
|
||||||
|
+ account_name,
|
||||||
|
+ creds->computer_name,
|
||||||
|
+ creds->account_name,
|
||||||
|
+ workgroup));
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return NT_STATUS_LOGON_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (av_nb_dn != NULL) {
|
||||||
|
+ const char *v = NULL;
|
||||||
|
+
|
||||||
|
+ v = av_nb_dn->Value.AvNbDomainName;
|
||||||
|
+
|
||||||
|
+#ifdef SAMBA4_INTERNAL_HEIMDAL /* smbtorture4 for make test */
|
||||||
|
+ cmp = strcasecmp_m(workgroup, v);
|
||||||
|
+#else /* smbd */
|
||||||
|
+ cmp = StrCaseCmp(workgroup, v);
|
||||||
|
+#endif
|
||||||
|
+ if (cmp != 0) {
|
||||||
|
+ DEBUG(2,("%s: NTLMv2_RESPONSE with "
|
||||||
|
+ "NbDomainName[%s] rejected "
|
||||||
|
+ "for user[%s\\%s] "
|
||||||
|
+ "against SEC_CHAN_WKSTA[%s/%s] "
|
||||||
|
+ "in workgroup[%s]\n",
|
||||||
|
+ __func__, v,
|
||||||
|
+ account_domain,
|
||||||
|
+ account_name,
|
||||||
|
+ creds->computer_name,
|
||||||
|
+ creds->account_name,
|
||||||
|
+ workgroup));
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return NT_STATUS_LOGON_FAILURE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return NT_STATUS_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/***********************************************************
|
||||||
|
encode a password buffer with a unicode password. The buffer
|
||||||
|
is filled with random data to make it harder to attack.
|
||||||
|
--- a/libcli/auth/wscript_build
|
||||||
|
+++ b/libcli/auth/wscript_build
|
||||||
|
@@ -19,7 +19,7 @@ bld.SAMBA_SUBSYSTEM('MSRPC_PARSE',
|
||||||
|
|
||||||
|
bld.SAMBA_SUBSYSTEM('LIBCLI_AUTH',
|
||||||
|
source='credentials.c session.c smbencrypt.c smbdes.c',
|
||||||
|
- public_deps='MSRPC_PARSE',
|
||||||
|
+ public_deps='MSRPC_PARSE NDR_NTLMSSP',
|
||||||
|
public_headers='credentials.h:domain_credentials.h'
|
||||||
|
)
|
||||||
|
|
||||||
|
--- a/source3/Makefile.in
|
||||||
|
+++ b/source3/Makefile.in
|
||||||
|
@@ -783,6 +783,7 @@ GROUPDB_OBJ = groupdb/mapping.o groupdb/
|
||||||
|
PROFILE_OBJ = profile/profile.o
|
||||||
|
PROFILES_OBJ = utils/profiles.o \
|
||||||
|
$(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBNDR_NTLMSSP_OBJ) \
|
||||||
|
$(PARAM_OBJ) \
|
||||||
|
$(LIB_OBJ) $(LIB_DUMMY_OBJ) \
|
||||||
|
$(POPT_LIB_OBJ) \
|
||||||
|
@@ -995,10 +996,10 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(P
|
||||||
|
STATUS_OBJ = utils/status.o utils/status_profile.o \
|
||||||
|
$(LOCKING_OBJ) $(PARAM_OBJ) \
|
||||||
|
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(FNAME_UTIL_OBJ)
|
||||||
|
|
||||||
|
SMBCONTROL_OBJ = utils/smbcontrol.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ)
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ)
|
||||||
|
|
||||||
|
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
|
||||||
|
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
|
||||||
|
@@ -1012,11 +1013,11 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OB
|
||||||
|
|
||||||
|
TESTPARM_OBJ = utils/testparm.o \
|
||||||
|
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ)
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
|
||||||
|
|
||||||
|
SMBTA_UTIL_OBJ = utils/smbta-util.o $(PARAM_OBJ) $(POPT_LIB_OBJ) \
|
||||||
|
$(LIB_NONSMBD_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(FNAME_UTIL_OBJ)
|
||||||
|
|
||||||
|
TEST_LP_LOAD_OBJ = param/test_lp_load.o \
|
||||||
|
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||||
|
@@ -1146,6 +1147,7 @@ SMBCONFTORT_OBJ = $(SMBCONFTORT_OBJ0) \
|
||||||
|
$(LIB_NONSMBD_OBJ) \
|
||||||
|
$(PARAM_OBJ) \
|
||||||
|
$(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBNDR_NTLMSSP_OBJ) \
|
||||||
|
$(POPT_LIB_OBJ)
|
||||||
|
|
||||||
|
PTHREADPOOLTEST_OBJ = lib/pthreadpool/pthreadpool.o \
|
||||||
|
@@ -1229,7 +1231,7 @@ CUPS_OBJ = client/smbspool.o $(PARAM_OBJ
|
||||||
|
$(LIBNDR_GEN_OBJ0)
|
||||||
|
|
||||||
|
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) \
|
||||||
|
- $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
|
||||||
|
+ $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
|
||||||
|
|
||||||
|
SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
|
||||||
|
torture/denytest.o torture/mangle_test.o \
|
||||||
|
@@ -1253,6 +1255,7 @@ MASKTEST_OBJ = torture/masktest.o $(PARA
|
||||||
|
$(LIBNDR_GEN_OBJ0)
|
||||||
|
|
||||||
|
MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBNDR_NTLMSSP_OBJ) \
|
||||||
|
$(LIB_NONSMBD_OBJ) \
|
||||||
|
$(LIBNDR_GEN_OBJ0)
|
||||||
|
|
||||||
|
@@ -1269,7 +1272,7 @@ PDBTEST_OBJ = torture/pdbtest.o $(PARAM_
|
||||||
|
|
||||||
|
VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ)
|
||||||
|
|
||||||
|
-SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
|
||||||
|
+SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
|
||||||
|
|
||||||
|
LOG2PCAP_OBJ = utils/log2pcaphex.o
|
||||||
|
|
||||||
|
@@ -1297,17 +1300,17 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LI
|
||||||
|
EVTLOGADM_OBJ0 = utils/eventlogadm.o
|
||||||
|
|
||||||
|
EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ) $(LIB_EVENTLOG_OBJ) \
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(LIB_EVENTLOG_OBJ) \
|
||||||
|
librpc/gen_ndr/ndr_eventlog.o \
|
||||||
|
librpc/gen_ndr/ndr_lsa.o
|
||||||
|
|
||||||
|
SHARESEC_OBJ0 = utils/sharesec.o
|
||||||
|
SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) \
|
||||||
|
$(POPT_LIB_OBJ)
|
||||||
|
|
||||||
|
TALLOCTORT_OBJ = @tallocdir@/testsuite.o @tallocdir@/testsuite_main.o \
|
||||||
|
- $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ)
|
||||||
|
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ)
|
||||||
|
|
||||||
|
REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \
|
||||||
|
@libreplacedir@/test/getifaddrs.o \
|
||||||
|
@@ -1323,7 +1326,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARA
|
||||||
|
$(LIBNDR_GEN_OBJ0)
|
||||||
|
|
||||||
|
WINBIND_WINS_NSS_OBJ = ../nsswitch/wins.o $(PARAM_OBJ) \
|
||||||
|
- $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNMB_OBJ)
|
||||||
|
+ $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNDR_NTLMSSP_OBJ) $(LIBNMB_OBJ)
|
||||||
|
|
||||||
|
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
|
||||||
|
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o ../lib/util/asn1.o
|
||||||
|
@@ -1531,12 +1534,14 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.
|
||||||
|
DBWRAP_TOOL_OBJ = utils/dbwrap_tool.o \
|
||||||
|
$(PARAM_OBJ) \
|
||||||
|
$(LIB_NONSMBD_OBJ) \
|
||||||
|
- $(LIBSMB_ERR_OBJ)
|
||||||
|
+ $(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBNDR_NTLMSSP_OBJ)
|
||||||
|
|
||||||
|
DBWRAP_TORTURE_OBJ = utils/dbwrap_torture.o \
|
||||||
|
$(PARAM_OBJ) \
|
||||||
|
$(LIB_NONSMBD_OBJ) \
|
||||||
|
$(LIBSMB_ERR_OBJ) \
|
||||||
|
+ $(LIBNDR_NTLMSSP_OBJ) \
|
||||||
|
$(POPT_LIB_OBJ)
|
||||||
|
|
||||||
|
SPLIT_TOKENS_OBJ = utils/split_tokens.o \
|
||||||
|
--- a/source4/torture/raw/samba3misc.c
|
||||||
|
+++ b/source4/torture/raw/samba3misc.c
|
||||||
|
@@ -340,6 +340,7 @@ bool torture_samba3_badpath(struct tortu
|
||||||
|
bool ret = true;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
bool nt_status_support;
|
||||||
|
+ bool client_ntlmv2_auth;
|
||||||
|
|
||||||
|
if (!(mem_ctx = talloc_init("torture_samba3_badpath"))) {
|
||||||
|
d_printf("talloc_init failed\n");
|
||||||
|
@@ -347,20 +348,17 @@ bool torture_samba3_badpath(struct tortu
|
||||||
|
}
|
||||||
|
|
||||||
|
nt_status_support = lpcfg_nt_status_support(torture->lp_ctx);
|
||||||
|
+ client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(torture->lp_ctx);
|
||||||
|
|
||||||
|
- if (!lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes")) {
|
||||||
|
- printf("Could not set 'nt status support = yes'\n");
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "yes"), ret, fail, "Could not set 'nt status support = yes'\n");
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "yes"), ret, fail, "Could not set 'client ntlmv2 auth = yes'\n");
|
||||||
|
|
||||||
|
if (!torture_open_connection(&cli_nt, torture, 0)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (!lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no")) {
|
||||||
|
- printf("Could not set 'nt status support = yes'\n");
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support", "no"), ret, fail, "Could not set 'nt status support = no'\n");
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth", "no"), ret, fail, "Could not set 'client ntlmv2 auth = no'\n");
|
||||||
|
|
||||||
|
if (!torture_open_connection(&cli_dos, torture, 1)) {
|
||||||
|
goto fail;
|
||||||
|
@@ -373,6 +371,12 @@ bool torture_samba3_badpath(struct tortu
|
||||||
|
}
|
||||||
|
|
||||||
|
smbcli_deltree(cli_nt->tree, dirname);
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "nt status support",
|
||||||
|
+ nt_status_support ? "yes":"no"),
|
||||||
|
+ ret, fail, "Could not set 'nt status support' back to where it was\n");
|
||||||
|
+ torture_assert_goto(torture, lpcfg_set_cmdline(torture->lp_ctx, "client ntlmv2 auth",
|
||||||
|
+ client_ntlmv2_auth ? "yes":"no"),
|
||||||
|
+ ret, fail, "Could not set 'client ntlmv2 auth' back to where it was\n");
|
||||||
|
|
||||||
|
status = smbcli_mkdir(cli_nt->tree, dirname);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
--- a/source4/torture/basic/base.c
|
||||||
|
+++ b/source4/torture/basic/base.c
|
||||||
|
@@ -1476,6 +1476,7 @@ static bool torture_chkpath_test(struct
|
||||||
|
static bool torture_samba3_errorpaths(struct torture_context *tctx)
|
||||||
|
{
|
||||||
|
bool nt_status_support;
|
||||||
|
+ bool client_ntlmv2_auth;
|
||||||
|
struct smbcli_state *cli_nt = NULL, *cli_dos = NULL;
|
||||||
|
bool result = false;
|
||||||
|
int fnum;
|
||||||
|
@@ -1485,18 +1486,27 @@ static bool torture_samba3_errorpaths(st
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
nt_status_support = lpcfg_nt_status_support(tctx->lp_ctx);
|
||||||
|
+ client_ntlmv2_auth = lpcfg_client_ntlmv2_auth(tctx->lp_ctx);
|
||||||
|
|
||||||
|
if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) {
|
||||||
|
torture_comment(tctx, "Could not set 'nt status support = yes'\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
+ if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "yes")) {
|
||||||
|
+ torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = yes'\n");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!torture_open_connection(&cli_nt, tctx, 0)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support", "no")) {
|
||||||
|
- torture_comment(tctx, "Could not set 'nt status support = yes'\n");
|
||||||
|
+ torture_result(tctx, TORTURE_FAIL, "Could not set 'nt status support = no'\n");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth", "no")) {
|
||||||
|
+ torture_result(tctx, TORTURE_FAIL, "Could not set 'client ntlmv2 auth = no'\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1506,7 +1516,12 @@ static bool torture_samba3_errorpaths(st
|
||||||
|
|
||||||
|
if (!lpcfg_set_cmdline(tctx->lp_ctx, "nt status support",
|
||||||
|
nt_status_support ? "yes":"no")) {
|
||||||
|
- torture_comment(tctx, "Could not reset 'nt status support = yes'");
|
||||||
|
+ torture_result(tctx, TORTURE_FAIL, "Could not reset 'nt status support'");
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ if (!lpcfg_set_cmdline(tctx->lp_ctx, "client ntlmv2 auth",
|
||||||
|
+ client_ntlmv2_auth ? "yes":"no")) {
|
||||||
|
+ torture_result(tctx, TORTURE_FAIL, "Could not reset 'client ntlmv2 auth'");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/source3/libsmb/cliconnect.c
|
||||||
|
+++ b/source3/libsmb/cliconnect.c
|
||||||
|
@@ -2077,6 +2077,17 @@ NTSTATUS cli_session_setup(struct cli_st
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
/* otherwise do a NT1 style session setup */
|
||||||
|
+ if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) {
|
||||||
|
+ /*
|
||||||
|
+ * Don't send an NTLMv2 response without NTLMSSP
|
||||||
|
+ * if we want to use spnego support
|
||||||
|
+ */
|
||||||
|
+ DEBUG(1, ("Server does not support EXTENDED_SECURITY "
|
||||||
|
+ " but 'client use spnego = yes"
|
||||||
|
+ " and 'client ntlmv2 auth = yes'\n"));
|
||||||
|
+ return NT_STATUS_ACCESS_DENIED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
status = cli_session_setup_nt1(cli, user, pass, passlen,
|
||||||
|
ntpass, ntpasslen, workgroup);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
--- a/docs-xml/smbdotconf/protocol/clientusespnego.xml
|
||||||
|
+++ b/docs-xml/smbdotconf/protocol/clientusespnego.xml
|
||||||
|
@@ -9,6 +9,11 @@
|
||||||
|
supporting servers (including WindowsXP, Windows2000 and Samba
|
||||||
|
3.0) to agree upon an authentication
|
||||||
|
mechanism. This enables Kerberos authentication in particular.</para>
|
||||||
|
+
|
||||||
|
+ <para>When <smbconfoption name="client NTLMv2 auth"/> is also set to
|
||||||
|
+ <constant>yes</constant> extended security (SPNEGO) is required
|
||||||
|
+ in order to use NTLMv2 only within NTLMSSP. This behavior was
|
||||||
|
+ introduced with the patches for CVE-2016-2111.</para>
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<value type="default">yes</value>
|
||||||
|
--- a/docs-xml/smbdotconf/security/clientntlmv2auth.xml
|
||||||
|
+++ b/docs-xml/smbdotconf/security/clientntlmv2auth.xml
|
||||||
|
@@ -28,6 +28,11 @@
|
||||||
|
NTLMv2 by default, and some sites (particularly those following
|
||||||
|
'best practice' security polices) only allow NTLMv2 responses, and
|
||||||
|
not the weaker LM or NTLM.</para>
|
||||||
|
+
|
||||||
|
+ <para>When <smbconfoption name="client use spnego"/> is also set to
|
||||||
|
+ <constant>yes</constant> extended security (SPNEGO) is required
|
||||||
|
+ in order to use NTLMv2 only within NTLMSSP. This behavior was
|
||||||
|
+ introduced with the patches for CVE-2016-2111.</para>
|
||||||
|
</description>
|
||||||
|
<value type="default">yes</value>
|
||||||
|
</samba:parameter>
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/docs-xml/smbdotconf/security/rawntlmv2auth.xml
|
||||||
|
@@ -0,0 +1,19 @@
|
||||||
|
+<samba:parameter name="raw NTLMv2 auth"
|
||||||
|
+ context="G"
|
||||||
|
+ type="boolean"
|
||||||
|
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||||
|
+<description>
|
||||||
|
+ <para>This parameter determines whether or not <citerefentry><refentrytitle>smbd</refentrytitle>
|
||||||
|
+ <manvolnum>8</manvolnum></citerefentry> will allow SMB1 clients without
|
||||||
|
+ extended security (without SPNEGO) to use NTLMv2 authentication.</para>
|
||||||
|
+
|
||||||
|
+ <para>If this option, <command moreinfo="none">lanman auth</command>
|
||||||
|
+ and <command moreinfo="none">ntlm auth</command> are all disabled,
|
||||||
|
+ then only clients with SPNEGO support will be permitted.
|
||||||
|
+ That means NTLMv2 is only supported within NTLMSSP.</para>
|
||||||
|
+</description>
|
||||||
|
+
|
||||||
|
+<related>lanman auth</related>
|
||||||
|
+<related>ntlm auth</related>
|
||||||
|
+<value type="default">no</value>
|
||||||
|
+</samba:parameter>
|
||||||
|
--- a/source3/include/proto.h
|
||||||
|
+++ b/source3/include/proto.h
|
||||||
|
@@ -1489,6 +1489,7 @@ bool lp_map_untrusted_to_domain(void);
|
||||||
|
int lp_restrict_anonymous(void);
|
||||||
|
bool lp_lanman_auth(void);
|
||||||
|
bool lp_ntlm_auth(void);
|
||||||
|
+bool lp_raw_ntlmv2_auth(void);
|
||||||
|
bool lp_client_plaintext_auth(void);
|
||||||
|
bool lp_client_lanman_auth(void);
|
||||||
|
bool lp_client_ntlmv2_auth(void);
|
||||||
|
--- a/source3/param/loadparm.c
|
||||||
|
+++ b/source3/param/loadparm.c
|
||||||
|
@@ -336,6 +336,7 @@ struct global {
|
||||||
|
bool bAllowTrustedDomains;
|
||||||
|
bool bLanmanAuth;
|
||||||
|
bool bNTLMAuth;
|
||||||
|
+ bool bRawNTLMv2Auth;
|
||||||
|
bool bUseSpnego;
|
||||||
|
bool bClientLanManAuth;
|
||||||
|
bool bClientNTLMv2Auth;
|
||||||
|
@@ -1383,6 +1384,15 @@ static struct parm_struct parm_table[] =
|
||||||
|
.flags = FLAG_ADVANCED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .label = "raw NTLMv2 auth",
|
||||||
|
+ .type = P_BOOL,
|
||||||
|
+ .p_class = P_GLOBAL,
|
||||||
|
+ .ptr = &Globals.bRawNTLMv2Auth,
|
||||||
|
+ .special = NULL,
|
||||||
|
+ .enum_list = NULL,
|
||||||
|
+ .flags = FLAG_ADVANCED,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.label = "client NTLMv2 auth",
|
||||||
|
.type = P_BOOL,
|
||||||
|
.p_class = P_GLOBAL,
|
||||||
|
@@ -5337,6 +5347,7 @@ static void init_globals(bool reinit_glo
|
||||||
|
Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
|
||||||
|
Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
|
||||||
|
Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
|
||||||
|
+ Globals.bRawNTLMv2Auth = false; /* Allow NTLMv2 without NTLMSSP */
|
||||||
|
Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
|
||||||
|
/* Note, that we will also use NTLM2 session security (which is different), if it is available */
|
||||||
|
|
||||||
|
@@ -5819,6 +5830,7 @@ FN_GLOBAL_BOOL(lp_map_untrusted_to_domai
|
||||||
|
FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
|
||||||
|
FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
|
||||||
|
FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
|
||||||
|
+FN_GLOBAL_BOOL(lp_raw_ntlmv2_auth, &Globals.bRawNTLMv2Auth)
|
||||||
|
FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
|
||||||
|
FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
|
||||||
|
FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
|
||||||
|
--- a/source3/auth/auth_util.c
|
||||||
|
+++ b/source3/auth/auth_util.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include "../lib/util/util_pw.h"
|
||||||
|
#include "lib/winbind_util.h"
|
||||||
|
#include "passdb.h"
|
||||||
|
+#include "../lib/tsocket/tsocket.h"
|
||||||
|
|
||||||
|
#undef DBGC_CLASS
|
||||||
|
#define DBGC_CLASS DBGC_AUTH
|
||||||
|
@@ -367,6 +368,19 @@ NTSTATUS make_user_info_for_reply_enc(st
|
||||||
|
const char *client_domain,
|
||||||
|
DATA_BLOB lm_resp, DATA_BLOB nt_resp)
|
||||||
|
{
|
||||||
|
+ bool allow_raw = lp_raw_ntlmv2_auth();
|
||||||
|
+
|
||||||
|
+ if (!allow_raw && nt_resp.length >= 48) {
|
||||||
|
+ /*
|
||||||
|
+ * NTLMv2_RESPONSE has at least 48 bytes
|
||||||
|
+ * and should only be supported via NTLMSSP.
|
||||||
|
+ */
|
||||||
|
+ DEBUG(2,("Rejecting raw NTLMv2 authentication with "
|
||||||
|
+ "user [%s\\%s]\n",
|
||||||
|
+ client_domain, smb_name));
|
||||||
|
+ return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return make_user_info_map(user_info, smb_name,
|
||||||
|
client_domain,
|
||||||
|
get_remote_machine_name(),
|
||||||
|
--- a/selftest/target/Samba3.pm
|
||||||
|
+++ b/selftest/target/Samba3.pm
|
||||||
|
@@ -127,6 +127,7 @@ sub setup_dc($$)
|
||||||
|
domain master = yes
|
||||||
|
domain logons = yes
|
||||||
|
lanman auth = yes
|
||||||
|
+ raw NTLMv2 auth = yes
|
||||||
|
";
|
||||||
|
|
||||||
|
my $vars = $self->provision($path,
|
||||||
|
@@ -230,6 +231,7 @@ sub setup_secserver($$$)
|
||||||
|
my $secserver_options = "
|
||||||
|
security = server
|
||||||
|
password server = $s3dcvars->{SERVER_IP}
|
||||||
|
+ client ntlmv2 auth = no
|
||||||
|
";
|
||||||
|
|
||||||
|
my $ret = $self->provision($prefix,
|
|
@ -0,0 +1,129 @@
|
||||||
|
From 126e3e992bed7174d60ee19212db9b717647ab2e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
Date: Wed, 30 Mar 2016 16:55:44 +0200
|
||||||
|
Subject: [PATCH 1/3] CVE-2016-2112: s3:ntlmssp: Implement missing
|
||||||
|
ntlmssp_have_feature()
|
||||||
|
|
||||||
|
Signed-off-by: Andreas Schneider <asn@samba.org>
|
||||||
|
---
|
||||||
|
source3/include/proto.h | 1 +
|
||||||
|
source3/libsmb/ntlmssp.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 31 insertions(+)
|
||||||
|
|
||||||
|
--- a/source3/include/proto.h
|
||||||
|
+++ b/source3/include/proto.h
|
||||||
|
@@ -1260,6 +1260,7 @@ NTSTATUS ntlmssp_set_password(struct ntl
|
||||||
|
NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ;
|
||||||
|
void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list);
|
||||||
|
void ntlmssp_want_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
|
||||||
|
+bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state, uint32_t feature);
|
||||||
|
NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
|
||||||
|
const DATA_BLOB in, DATA_BLOB *out) ;
|
||||||
|
NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
|
||||||
|
--- a/source3/libsmb/ntlmssp.c
|
||||||
|
+++ b/source3/libsmb/ntlmssp.c
|
||||||
|
@@ -162,6 +162,36 @@ NTSTATUS ntlmssp_set_domain(struct ntlms
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
+bool ntlmssp_have_feature(struct ntlmssp_state *ntlmssp_state,
|
||||||
|
+ uint32_t feature)
|
||||||
|
+{
|
||||||
|
+ if (feature & NTLMSSP_FEATURE_SIGN) {
|
||||||
|
+ if (ntlmssp_state->session_key.length == 0) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (feature & NTLMSSP_FEATURE_SEAL) {
|
||||||
|
+ if (ntlmssp_state->session_key.length == 0) {
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
|
||||||
|
+ if (ntlmssp_state->session_key.length > 0) {
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Request features for the NTLMSSP negotiation
|
||||||
|
*
|
||||||
|
--- a/source3/libads/sasl.c
|
||||||
|
+++ b/source3/libads/sasl.c
|
||||||
|
@@ -261,6 +261,37 @@ static ADS_STATUS ads_sasl_spnego_ntlmss
|
||||||
|
/* we have a reference conter on ntlmssp_state, if we are signing
|
||||||
|
then the state will be kept by the signing engine */
|
||||||
|
|
||||||
|
+ if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SEAL) {
|
||||||
|
+ bool ok;
|
||||||
|
+
|
||||||
|
+ ok = ntlmssp_have_feature(ntlmssp_state,
|
||||||
|
+ NTLMSSP_FEATURE_SEAL);
|
||||||
|
+ if (!ok) {
|
||||||
|
+ DEBUG(0,("The ntlmssp feature sealing request, but unavailable\n"));
|
||||||
|
+ TALLOC_FREE(ntlmssp_state);
|
||||||
|
+ return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ok = ntlmssp_have_feature(ntlmssp_state,
|
||||||
|
+ NTLMSSP_FEATURE_SIGN);
|
||||||
|
+ if (!ok) {
|
||||||
|
+ DEBUG(0,("The ntlmssp feature signing request, but unavailable\n"));
|
||||||
|
+ TALLOC_FREE(ntlmssp_state);
|
||||||
|
+ return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ } else if (ads->ldap.wrap_type >= ADS_SASLWRAP_TYPE_SIGN) {
|
||||||
|
+ bool ok;
|
||||||
|
+
|
||||||
|
+ ok = ntlmssp_have_feature(ntlmssp_state,
|
||||||
|
+ NTLMSSP_FEATURE_SIGN);
|
||||||
|
+ if (!ok) {
|
||||||
|
+ DEBUG(0,("The gensec feature signing request, but unavailable\n"));
|
||||||
|
+ TALLOC_FREE(ntlmssp_state);
|
||||||
|
+ return ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
|
||||||
|
ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE;
|
||||||
|
ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE;
|
||||||
|
--- a/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
|
||||||
|
+++ b/docs-xml/smbdotconf/ldap/clientldapsaslwrapping.xml
|
||||||
|
@@ -34,11 +34,9 @@
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
- The default value is <emphasis>plain</emphasis> which is not irritable
|
||||||
|
- to KRB5 clock skew errors. That implies synchronizing the time
|
||||||
|
- with the KDC in the case of using <emphasis>sign</emphasis> or
|
||||||
|
- <emphasis>seal</emphasis>.
|
||||||
|
+ The default value is <emphasis>sign</emphasis>. That implies synchronizing the time
|
||||||
|
+ with the KDC in the case of using <emphasis>Kerberos</emphasis>.
|
||||||
|
</para>
|
||||||
|
</description>
|
||||||
|
-<value type="default">plain</value>
|
||||||
|
+<value type="default">sign</value>
|
||||||
|
</samba:parameter>
|
||||||
|
--- a/source3/param/loadparm.c
|
||||||
|
+++ b/source3/param/loadparm.c
|
||||||
|
@@ -5392,6 +5392,8 @@ static void init_globals(bool reinit_glo
|
||||||
|
Globals.ldap_debug_level = 0;
|
||||||
|
Globals.ldap_debug_threshold = 10;
|
||||||
|
|
||||||
|
+ Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
|
||||||
|
+
|
||||||
|
/* This is what we tell the afs client. in reality we set the token
|
||||||
|
* to never expire, though, when this runs out the afs client will
|
||||||
|
* forget the token. Set to 0 to get NEVERDATE.*/
|
|
@ -0,0 +1,256 @@
|
||||||
|
From 513bd34e4523e49e742487be32a7239111486a12 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Metzmacher <metze@samba.org>
|
||||||
|
Date: Sat, 27 Feb 2016 03:43:58 +0100
|
||||||
|
Subject: [PATCH 1/4] CVE-2016-2115: docs-xml: add "client ipc signing" option
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11756
|
||||||
|
|
||||||
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||||
|
Reviewed-by: Ralph Boehme <slow@samba.org>
|
||||||
|
---
|
||||||
|
docs-xml/smbdotconf/security/clientipcsigning.xml | 23 +++++++++++++++++++++++
|
||||||
|
docs-xml/smbdotconf/security/clientsigning.xml | 3 +++
|
||||||
|
source3/include/proto.h | 1 +
|
||||||
|
source3/param/loadparm.c | 12 ++++++++++++
|
||||||
|
4 files changed, 39 insertions(+)
|
||||||
|
create mode 100644 docs-xml/smbdotconf/security/clientipcsigning.xml
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/docs-xml/smbdotconf/security/clientipcsigning.xml
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+<samba:parameter name="client ipc signing"
|
||||||
|
+ context="G"
|
||||||
|
+ type="enum"
|
||||||
|
+ enumlist="enum_smb_signing_vals"
|
||||||
|
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||||
|
+<description>
|
||||||
|
+ <para>This controls whether the client is allowed or required to use SMB signing for IPC$
|
||||||
|
+ connections as DCERPC transport inside of winbind. Possible values
|
||||||
|
+ are <emphasis>auto</emphasis>, <emphasis>mandatory</emphasis>
|
||||||
|
+ and <emphasis>disabled</emphasis>.
|
||||||
|
+ </para>
|
||||||
|
+
|
||||||
|
+ <para>When set to auto, SMB signing is offered, but not enforced and if set
|
||||||
|
+ to disabled, SMB signing is not offered either.</para>
|
||||||
|
+
|
||||||
|
+ <para>Connections from winbindd to Active Directory Domain Controllers
|
||||||
|
+ always enforce signing.</para>
|
||||||
|
+</description>
|
||||||
|
+
|
||||||
|
+<related>client signing</related>
|
||||||
|
+
|
||||||
|
+<value type="default">mandatory</value>
|
||||||
|
+</samba:parameter>
|
||||||
|
--- a/docs-xml/smbdotconf/security/clientsigning.xml
|
||||||
|
+++ b/docs-xml/smbdotconf/security/clientsigning.xml
|
||||||
|
@@ -12,6 +12,9 @@
|
||||||
|
<para>When set to auto, SMB signing is offered, but not enforced.
|
||||||
|
When set to mandatory, SMB signing is required and if set
|
||||||
|
to disabled, SMB signing is not offered either.
|
||||||
|
+
|
||||||
|
+ <para>IPC$ connections for DCERPC e.g. in winbindd, are handled by the
|
||||||
|
+ <smbconfoption name="client ipc signing"/> option.</para>
|
||||||
|
</para>
|
||||||
|
</description>
|
||||||
|
|
||||||
|
--- a/source3/include/proto.h
|
||||||
|
+++ b/source3/include/proto.h
|
||||||
|
@@ -1690,9 +1690,11 @@ int lp_winbind_cache_time(void);
|
||||||
|
int lp_winbind_reconnect_delay(void);
|
||||||
|
int lp_winbind_max_clients(void);
|
||||||
|
const char **lp_winbind_nss_info(void);
|
||||||
|
+bool lp_winbind_sealed_pipes(void);
|
||||||
|
int lp_algorithmic_rid_base(void);
|
||||||
|
int lp_name_cache_timeout(void);
|
||||||
|
int lp_client_signing(void);
|
||||||
|
+int lp_client_ipc_signing(void);
|
||||||
|
int lp_server_signing(void);
|
||||||
|
int lp_client_ldap_sasl_wrapping(void);
|
||||||
|
char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def);
|
||||||
|
--- a/source3/param/loadparm.c
|
||||||
|
+++ b/source3/param/loadparm.c
|
||||||
|
@@ -215,6 +215,7 @@ struct global {
|
||||||
|
int winbind_expand_groups;
|
||||||
|
bool bWinbindRefreshTickets;
|
||||||
|
bool bWinbindOfflineLogon;
|
||||||
|
+ bool bWinbindSealedPipes;
|
||||||
|
bool bWinbindNormalizeNames;
|
||||||
|
bool bWinbindRpcOnly;
|
||||||
|
bool bCreateKrb5Conf;
|
||||||
|
@@ -366,6 +367,7 @@ struct global {
|
||||||
|
int restrict_anonymous;
|
||||||
|
int name_cache_timeout;
|
||||||
|
int client_signing;
|
||||||
|
+ int client_ipc_signing;
|
||||||
|
int server_signing;
|
||||||
|
int client_ldap_sasl_wrapping;
|
||||||
|
int iUsershareMaxShares;
|
||||||
|
@@ -2319,6 +2321,15 @@ static struct parm_struct parm_table[] =
|
||||||
|
.flags = FLAG_ADVANCED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .label = "client ipc signing",
|
||||||
|
+ .type = P_ENUM,
|
||||||
|
+ .p_class = P_GLOBAL,
|
||||||
|
+ .ptr = &Globals.client_ipc_signing,
|
||||||
|
+ .special = NULL,
|
||||||
|
+ .enum_list = enum_smb_signing_vals,
|
||||||
|
+ .flags = FLAG_ADVANCED,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.label = "server signing",
|
||||||
|
.type = P_ENUM,
|
||||||
|
.p_class = P_GLOBAL,
|
||||||
|
@@ -4765,6 +4776,15 @@ static struct parm_struct parm_table[] =
|
||||||
|
.flags = FLAG_ADVANCED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .label = "winbind sealed pipes",
|
||||||
|
+ .type = P_BOOL,
|
||||||
|
+ .p_class = P_GLOBAL,
|
||||||
|
+ .ptr = &Globals.bWinbindSealedPipes,
|
||||||
|
+ .special = NULL,
|
||||||
|
+ .enum_list = NULL,
|
||||||
|
+ .flags = FLAG_ADVANCED,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.label = "winbind normalize names",
|
||||||
|
.type = P_BOOL,
|
||||||
|
.p_class = P_GLOBAL,
|
||||||
|
@@ -5458,6 +5478,7 @@ static void init_globals(bool reinit_glo
|
||||||
|
Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
|
||||||
|
Globals.bWinbindRefreshTickets = False;
|
||||||
|
Globals.bWinbindOfflineLogon = False;
|
||||||
|
+ Globals.bWinbindSealedPipes = True;
|
||||||
|
|
||||||
|
Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
|
||||||
|
Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
|
||||||
|
@@ -5470,6 +5491,7 @@ static void init_globals(bool reinit_glo
|
||||||
|
Globals.bClientUseSpnego = True;
|
||||||
|
|
||||||
|
Globals.client_signing = Auto;
|
||||||
|
+ Globals.client_ipc_signing = Required;
|
||||||
|
Globals.server_signing = False;
|
||||||
|
|
||||||
|
Globals.bDeferSharingViolations = True;
|
||||||
|
@@ -5736,6 +5758,7 @@ FN_GLOBAL_BOOL(lp_winbind_nested_groups,
|
||||||
|
FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
|
||||||
|
FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
|
||||||
|
FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
|
||||||
|
+FN_GLOBAL_BOOL(lp_winbind_sealed_pipes, &Globals.bWinbindSealedPipes)
|
||||||
|
FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
|
||||||
|
FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
|
||||||
|
FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
|
||||||
|
@@ -6071,6 +6094,7 @@ FN_GLOBAL_LIST(lp_winbind_nss_info, &Glo
|
||||||
|
FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
|
||||||
|
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
|
||||||
|
FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
|
||||||
|
+FN_GLOBAL_INTEGER(lp_client_ipc_signing, &Globals.client_ipc_signing)
|
||||||
|
FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
|
||||||
|
FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
|
||||||
|
|
||||||
|
@@ -9700,6 +9724,20 @@ static bool lp_load_ex(const char *pszFn
|
||||||
|
lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!lp_is_in_client()) {
|
||||||
|
+ switch (lp_client_ipc_signing()) {
|
||||||
|
+ case Required:
|
||||||
|
+ lp_set_cmdline("client signing", "mandatory");
|
||||||
|
+ break;
|
||||||
|
+ case Auto:
|
||||||
|
+ lp_set_cmdline("client signing", "auto");
|
||||||
|
+ break;
|
||||||
|
+ case False:
|
||||||
|
+ lp_set_cmdline("client signing", "disabled");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
init_iconv();
|
||||||
|
|
||||||
|
bAllowIncludeRegistry = true;
|
||||||
|
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
|
||||||
|
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
|
||||||
|
@@ -2480,7 +2480,7 @@ static bool spoolss_connect_to_client(st
|
||||||
|
"", /* username */
|
||||||
|
"", /* domain */
|
||||||
|
"", /* password */
|
||||||
|
- 0, lp_client_signing());
|
||||||
|
+ 0, False);
|
||||||
|
|
||||||
|
if ( !NT_STATUS_IS_OK( ret ) ) {
|
||||||
|
DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/docs-xml/smbdotconf/winbind/winbindsealedpipes.xml
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+<samba:parameter name="winbind sealed pipes"
|
||||||
|
+ context="G"
|
||||||
|
+ type="boolean"
|
||||||
|
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||||
|
+<description>
|
||||||
|
+ <para>This option controls whether any requests from winbindd to domain controllers
|
||||||
|
+ pipe will be sealed. Disabling sealing can be useful for debugging
|
||||||
|
+ purposes.</para>
|
||||||
|
+
|
||||||
|
+ <para>The behavior can be controlled per netbios domain
|
||||||
|
+ by using 'winbind sealed pipes:NETBIOSDOMAIN = no' as option.</para>
|
||||||
|
+</description>
|
||||||
|
+
|
||||||
|
+<value type="default">yes</value>
|
||||||
|
+</samba:parameter>
|
||||||
|
--- a/source3/winbindd/winbindd_cm.c
|
||||||
|
+++ b/source3/winbindd/winbindd_cm.c
|
||||||
|
@@ -2384,6 +2384,15 @@ NTSTATUS cm_connect_sam(struct winbindd_
|
||||||
|
TALLOC_FREE(conn->samr_pipe);
|
||||||
|
|
||||||
|
anonymous:
|
||||||
|
+ if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
|
||||||
|
+ status = NT_STATUS_DOWNGRADE_DETECTED;
|
||||||
|
+ DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
|
||||||
|
+ "without connection level security, "
|
||||||
|
+ "must set 'winbind sealed pipes = false' "
|
||||||
|
+ "to proceed: %s\n",
|
||||||
|
+ domain->name, nt_errstr(status)));
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Finally fall back to anonymous. */
|
||||||
|
status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
|
||||||
|
@@ -2610,6 +2619,16 @@ NTSTATUS cm_connect_lsa(struct winbindd_
|
||||||
|
|
||||||
|
anonymous:
|
||||||
|
|
||||||
|
+ if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
|
||||||
|
+ result = NT_STATUS_DOWNGRADE_DETECTED;
|
||||||
|
+ DEBUG(1, ("Unwilling to make LSA connection to domain %s "
|
||||||
|
+ "without connection level security, "
|
||||||
|
+ "must set 'winbind sealed pipes = false' "
|
||||||
|
+ "to proceed: %s\n",
|
||||||
|
+ domain->name, nt_errstr(result)));
|
||||||
|
+ goto done;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
result = cli_rpc_pipe_open_noauth(conn->cli,
|
||||||
|
&ndr_table_lsarpc.syntax_id,
|
||||||
|
&conn->lsa_pipe);
|
||||||
|
@@ -2749,7 +2768,18 @@ NTSTATUS cm_connect_netlogon(struct winb
|
||||||
|
|
||||||
|
no_schannel:
|
||||||
|
if ((lp_client_schannel() == False) ||
|
||||||
|
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
|
||||||
|
+ ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
|
||||||
|
+ if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {
|
||||||
|
+ result = NT_STATUS_DOWNGRADE_DETECTED;
|
||||||
|
+ DEBUG(1, ("Unwilling to make connection to domain %s "
|
||||||
|
+ "without connection level security, "
|
||||||
|
+ "must set 'winbind sealed pipes = false' "
|
||||||
|
+ "to proceed: %s\n",
|
||||||
|
+ domain->name, nt_errstr(result)));
|
||||||
|
+ TALLOC_FREE(netlogon_pipe);
|
||||||
|
+ invalidate_cm_connection(conn);
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
/*
|
||||||
|
* NetSamLogonEx only works for schannel
|
||||||
|
*/
|
|
@ -0,0 +1,308 @@
|
||||||
|
From d68424b5ef92f5810760f90e9eeb664572a61e4e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Metzmacher <metze@samba.org>
|
||||||
|
Date: Tue, 15 Dec 2015 14:49:36 +0100
|
||||||
|
Subject: [PATCH 01/10] CVE-2016-2118: s3: rpcclient: change the default auth
|
||||||
|
level from DCERPC_AUTH_LEVEL_CONNECT to DCERPC_AUTH_LEVEL_INTEGRITY
|
||||||
|
|
||||||
|
ncacn_ip_tcp:server should get the same protection as ncacn_np:server
|
||||||
|
if authentication and smb signing is used.
|
||||||
|
|
||||||
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11616
|
||||||
|
|
||||||
|
Signed-off-by: Stefan Metzmacher <metze@samba.org>
|
||||||
|
|
||||||
|
(cherry picked from commit dab41dee8a4fb27dbf3913b0e44a4cc726e3ac98)
|
||||||
|
---
|
||||||
|
source3/rpcclient/rpcclient.c | 5 ++---
|
||||||
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
--- a/source3/rpcclient/rpcclient.c
|
||||||
|
+++ b/source3/rpcclient/rpcclient.c
|
||||||
|
@@ -1062,10 +1062,9 @@ out_free:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pipe_default_auth_type != DCERPC_AUTH_TYPE_NONE) {
|
||||||
|
- /* If neither Integrity or Privacy are requested then
|
||||||
|
- * Use just Connect level */
|
||||||
|
+ /* If nothing is requested then default to integrity */
|
||||||
|
if (pipe_default_auth_level == DCERPC_AUTH_LEVEL_NONE) {
|
||||||
|
- pipe_default_auth_level = DCERPC_AUTH_LEVEL_CONNECT;
|
||||||
|
+ pipe_default_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/source4/librpc/rpc/dcerpc_util.c
|
||||||
|
+++ b/source4/librpc/rpc/dcerpc_util.c
|
||||||
|
@@ -593,15 +593,15 @@ struct composite_context *dcerpc_pipe_au
|
||||||
|
|
||||||
|
/* Perform an authenticated DCE-RPC bind
|
||||||
|
*/
|
||||||
|
- if (!(conn->flags & (DCERPC_SIGN|DCERPC_SEAL))) {
|
||||||
|
+ if (!(conn->flags & (DCERPC_CONNECT|DCERPC_SEAL))) {
|
||||||
|
/*
|
||||||
|
we are doing an authenticated connection,
|
||||||
|
- but not using sign or seal. We must force
|
||||||
|
- the CONNECT dcerpc auth type as a NONE auth
|
||||||
|
- type doesn't allow authentication
|
||||||
|
- information to be passed.
|
||||||
|
+ which needs to use [connect], [sign] or [seal].
|
||||||
|
+ If nothing is specified, we default to [sign] now.
|
||||||
|
+ This give roughly the same protection as
|
||||||
|
+ ncacn_np with smb signing.
|
||||||
|
*/
|
||||||
|
- conn->flags |= DCERPC_CONNECT;
|
||||||
|
+ conn->flags |= DCERPC_SIGN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s->binding->flags & DCERPC_AUTH_SPNEGO) {
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/docs-xml/smbdotconf/security/allowdcerpcauthlevelconnect.xml
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+<samba:parameter name="allow dcerpc auth level connect"
|
||||||
|
+ context="G"
|
||||||
|
+ type="boolean"
|
||||||
|
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
|
||||||
|
+<description>
|
||||||
|
+ <para>This option controls whether DCERPC services are allowed to
|
||||||
|
+ be used with DCERPC_AUTH_LEVEL_CONNECT, which provides authentication,
|
||||||
|
+ but no per message integrity nor privacy protection.</para>
|
||||||
|
+
|
||||||
|
+ <para>The behavior can be controlled per interface name (e.g. lsarpc, netlogon, samr, srvsvc,
|
||||||
|
+ winreg, wkssvc ...) by using 'allow dcerpc auth level connect:interface = no' as option.</para>
|
||||||
|
+
|
||||||
|
+ <para>This option yields precedence to the implentation specific restrictions.
|
||||||
|
+ E.g. the drsuapi and backupkey protocols require DCERPC_AUTH_LEVEL_PRIVACY.
|
||||||
|
+ While others like samr and lsarpc have a hardcoded default of <constant>no</constant>.
|
||||||
|
+ </para>
|
||||||
|
+</description>
|
||||||
|
+
|
||||||
|
+<value type="default">no</value>
|
||||||
|
+<value type="example">yes</value>
|
||||||
|
+
|
||||||
|
+</samba:parameter>
|
||||||
|
--- a/source3/include/proto.h
|
||||||
|
+++ b/source3/include/proto.h
|
||||||
|
@@ -1821,6 +1821,7 @@ char* lp_perfcount_module(void);
|
||||||
|
void lp_set_passdb_backend(const char *backend);
|
||||||
|
void widelinks_warning(int snum);
|
||||||
|
char *lp_ncalrpc_dir(void);
|
||||||
|
+bool lp_allow_dcerpc_auth_level_connect(void);
|
||||||
|
|
||||||
|
/* The following definitions come from param/loadparm_server_role.c */
|
||||||
|
|
||||||
|
--- a/source3/param/loadparm.c
|
||||||
|
+++ b/source3/param/loadparm.c
|
||||||
|
@@ -355,6 +355,7 @@ struct global {
|
||||||
|
bool bUseMmap;
|
||||||
|
bool bHostnameLookups;
|
||||||
|
bool bUnixExtensions;
|
||||||
|
+ bool bAllowDcerpcAuthLevelConnect;
|
||||||
|
bool bDisableNetbios;
|
||||||
|
char * szDedicatedKeytabFile;
|
||||||
|
int iKerberosMethod;
|
||||||
|
@@ -2303,6 +2304,15 @@ static struct parm_struct parm_table[] =
|
||||||
|
.flags = FLAG_ADVANCED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
+ .label = "allow dcerpc auth level connect",
|
||||||
|
+ .type = P_BOOL,
|
||||||
|
+ .p_class = P_GLOBAL,
|
||||||
|
+ .ptr = &Globals.bAllowDcerpcAuthLevelConnect,
|
||||||
|
+ .special = NULL,
|
||||||
|
+ .enum_list = NULL,
|
||||||
|
+ .flags = FLAG_ADVANCED,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
.label = "use spnego",
|
||||||
|
.type = P_BOOL,
|
||||||
|
.p_class = P_GLOBAL,
|
||||||
|
@@ -5371,6 +5381,8 @@ static void init_globals(bool reinit_glo
|
||||||
|
Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
|
||||||
|
/* Note, that we will also use NTLM2 session security (which is different), if it is available */
|
||||||
|
|
||||||
|
+ Globals.bAllowDcerpcAuthLevelConnect = false; /* we don't allow this by default */
|
||||||
|
+
|
||||||
|
Globals.map_to_guest = 0; /* By Default, "Never" */
|
||||||
|
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
|
||||||
|
Globals.enhanced_browsing = true;
|
||||||
|
@@ -5745,6 +5757,7 @@ FN_GLOBAL_INTEGER(lp_username_map_cache_
|
||||||
|
|
||||||
|
FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
|
||||||
|
|
||||||
|
+FN_GLOBAL_BOOL(lp_allow_dcerpc_auth_level_connect, &Globals.bAllowDcerpcAuthLevelConnect)
|
||||||
|
FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
|
||||||
|
FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
|
||||||
|
FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
|
||||||
|
--- a/source3/include/ntdomain.h
|
||||||
|
+++ b/source3/include/ntdomain.h
|
||||||
|
@@ -89,6 +89,10 @@ typedef struct pipe_rpc_fns {
|
||||||
|
uint32 context_id;
|
||||||
|
struct ndr_syntax_id syntax;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * shall we allow "connect" auth level for this interface ?
|
||||||
|
+ */
|
||||||
|
+ bool allow_connect;
|
||||||
|
} PIPE_RPC_FNS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -44,6 +44,11 @@
|
||||||
|
#include "rpc_server/srv_pipe.h"
|
||||||
|
#include "../librpc/gen_ndr/ndr_dcerpc.h"
|
||||||
|
#include "../librpc/ndr/ndr_dcerpc.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_samr.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_lsa.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_netlogon.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_epmapper.h"
|
||||||
|
+#include "../librpc/gen_ndr/ndr_echo.h"
|
||||||
|
|
||||||
|
#undef DBGC_CLASS
|
||||||
|
#define DBGC_CLASS DBGC_RPC_SRV
|
||||||
|
@@ -340,6 +345,8 @@ static bool check_bind_req(struct pipes_
|
||||||
|
uint32 context_id)
|
||||||
|
{
|
||||||
|
struct pipe_rpc_fns *context_fns;
|
||||||
|
+ const char *interface_name = NULL;
|
||||||
|
+ bool ok;
|
||||||
|
|
||||||
|
DEBUG(3,("check_bind_req for %s\n",
|
||||||
|
get_pipe_name_from_syntax(talloc_tos(), abstract)));
|
||||||
|
@@ -390,12 +397,57 @@ static bool check_bind_req(struct pipes_
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ interface_name = get_pipe_name_from_syntax(talloc_tos(),
|
||||||
|
+ abstract);
|
||||||
|
+
|
||||||
|
+ SMB_ASSERT(interface_name != NULL);
|
||||||
|
+
|
||||||
|
context_fns->next = context_fns->prev = NULL;
|
||||||
|
context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
|
||||||
|
context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
|
||||||
|
context_fns->context_id = context_id;
|
||||||
|
context_fns->syntax = *abstract;
|
||||||
|
|
||||||
|
+ context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
|
||||||
|
+ /*
|
||||||
|
+ * for the samr and the lsarpc interfaces we don't allow "connect"
|
||||||
|
+ * auth_level by default.
|
||||||
|
+ */
|
||||||
|
+ ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
|
||||||
|
+ if (ok) {
|
||||||
|
+ context_fns->allow_connect = false;
|
||||||
|
+ }
|
||||||
|
+ ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
|
||||||
|
+ if (ok) {
|
||||||
|
+ context_fns->allow_connect = false;
|
||||||
|
+ }
|
||||||
|
+ ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
|
||||||
|
+ if (ok) {
|
||||||
|
+ context_fns->allow_connect = false;
|
||||||
|
+ }
|
||||||
|
+ /*
|
||||||
|
+ * for the epmapper and echo interfaces we allow "connect"
|
||||||
|
+ * auth_level by default.
|
||||||
|
+ */
|
||||||
|
+ ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
|
||||||
|
+ if (ok) {
|
||||||
|
+ context_fns->allow_connect = true;
|
||||||
|
+ }
|
||||||
|
+ ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
|
||||||
|
+ if (ok) {
|
||||||
|
+ context_fns->allow_connect = true;
|
||||||
|
+ }
|
||||||
|
+ /*
|
||||||
|
+ * every interface can be modified to allow "connect" auth_level by
|
||||||
|
+ * using a parametric option like:
|
||||||
|
+ * allow dcerpc auth level connect:<interface>
|
||||||
|
+ * e.g.
|
||||||
|
+ * allow dcerpc auth level connect:samr = yes
|
||||||
|
+ */
|
||||||
|
+ context_fns->allow_connect = lp_parm_bool(-1,
|
||||||
|
+ "allow dcerpc auth level connect",
|
||||||
|
+ interface_name, context_fns->allow_connect);
|
||||||
|
+
|
||||||
|
/* add to the list of open contexts */
|
||||||
|
|
||||||
|
DLIST_ADD( p->contexts, context_fns );
|
||||||
|
@@ -1736,6 +1788,7 @@ static bool api_pipe_request(struct pipe
|
||||||
|
TALLOC_CTX *frame = talloc_stackframe();
|
||||||
|
bool ret = False;
|
||||||
|
PIPE_RPC_FNS *pipe_fns;
|
||||||
|
+ const char *interface_name = NULL;
|
||||||
|
|
||||||
|
if (!p->pipe_bound) {
|
||||||
|
DEBUG(1, ("Pipe not bound!\n"));
|
||||||
|
@@ -1757,8 +1810,36 @@ static bool api_pipe_request(struct pipe
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ interface_name = get_pipe_name_from_syntax(talloc_tos(),
|
||||||
|
+ &pipe_fns->syntax);
|
||||||
|
+
|
||||||
|
+ SMB_ASSERT(interface_name != NULL);
|
||||||
|
+
|
||||||
|
DEBUG(5, ("Requested \\PIPE\\%s\n",
|
||||||
|
- get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
|
||||||
|
+ interface_name));
|
||||||
|
+
|
||||||
|
+ switch (p->auth.auth_level) {
|
||||||
|
+ case DCERPC_AUTH_LEVEL_NONE:
|
||||||
|
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
|
||||||
|
+ case DCERPC_AUTH_LEVEL_PRIVACY:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ if (!pipe_fns->allow_connect) {
|
||||||
|
+ DEBUG(1, ("%s: restrict auth_level_connect access "
|
||||||
|
+ "to [%s] with auth[type=0x%x,level=0x%x] "
|
||||||
|
+ "on [%s] from [%s]\n",
|
||||||
|
+ __func__, interface_name,
|
||||||
|
+ p->auth.auth_type,
|
||||||
|
+ p->auth.auth_level,
|
||||||
|
+ derpc_transport_string_by_transport(p->transport),
|
||||||
|
+ p->client_id->name));
|
||||||
|
+
|
||||||
|
+ setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
|
||||||
|
+ TALLOC_FREE(frame);
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
|
||||||
|
DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
|
||||||
|
--- a/source3/selftest/knownfail
|
||||||
|
+++ b/source3/selftest/knownfail
|
||||||
|
@@ -18,3 +18,5 @@ samba3.posix_s3.nbt.dgram.*netlogon2
|
||||||
|
samba3.*rap.sam.*.useradd # Not provided by Samba 3
|
||||||
|
samba3.*rap.sam.*.userdelete # Not provided by Samba 3
|
||||||
|
samba3.*rap.basic.*.netsessiongetinfo # Not provided by Samba 3
|
||||||
|
+samba3.blackbox.rpcclient.over.ncacn_np.with.*connect.* # we don't allow auth_level_connect anymore
|
||||||
|
+samba3.posix_s3.rpc.lsa.lookupsids.*ncacn_ip_tcp.*connect.* # we don't allow auth_level_connect anymore
|
||||||
|
--- a/source3/selftest/tests.py
|
||||||
|
+++ b/source3/selftest/tests.py
|
||||||
|
@@ -201,6 +201,8 @@ if sub.returncode == 0:
|
||||||
|
plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD')
|
||||||
|
elif t == "raw.samba3posixtimedlock":
|
||||||
|
plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/dc/share')
|
||||||
|
+ elif t == "rpc.samr.passwords.validate":
|
||||||
|
+ plansmbtorturetestsuite(t, "s3dc", 'ncacn_np:$SERVER_IP[seal] -U$USERNAME%$PASSWORD', 'over ncacn_np ')
|
||||||
|
else:
|
||||||
|
plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
|
||||||
|
|
||||||
|
--- a/source3/rpc_server/samr/srv_samr_nt.c
|
||||||
|
+++ b/source3/rpc_server/samr/srv_samr_nt.c
|
||||||
|
@@ -6628,6 +6628,11 @@ NTSTATUS _samr_ValidatePassword(struct p
|
||||||
|
struct samr_GetDomPwInfo pw;
|
||||||
|
struct samr_PwInfo dom_pw_info;
|
||||||
|
|
||||||
|
+ if (p->auth.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
|
||||||
|
+ p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
|
||||||
|
+ return NT_STATUS_ACCESS_DENIED;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (r->in.level < 1 || r->in.level > 3) {
|
||||||
|
return NT_STATUS_INVALID_INFO_CLASS;
|
||||||
|
}
|
|
@ -36,7 +36,7 @@
|
||||||
|
|
||||||
BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
|
BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
|
||||||
bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ bin/smbget@EXEEXT@ \
|
bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ bin/smbget@EXEEXT@ \
|
||||||
@@ -1777,6 +1777,42 @@ bin/.dummy:
|
@@ -1799,6 +1799,42 @@ bin/.dummy:
|
||||||
dir=bin $(MAKEDIR); fi
|
dir=bin $(MAKEDIR); fi
|
||||||
@: >> $@ || : > $@ # what a fancy emoticon!
|
@: >> $@ || : > $@ # what a fancy emoticon!
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- a/source3/Makefile.in
|
--- a/source3/Makefile.in
|
||||||
+++ b/source3/Makefile.in
|
+++ b/source3/Makefile.in
|
||||||
@@ -1019,7 +1019,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o
|
@@ -1025,7 +1025,7 @@ TEST_LP_LOAD_OBJ = param/test_lp_load.o
|
||||||
|
|
||||||
PASSWD_UTIL_OBJ = utils/passwd_util.o
|
PASSWD_UTIL_OBJ = utils/passwd_util.o
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
$(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
|
$(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
|
||||||
$(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
|
$(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
|
||||||
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
|
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) \
|
||||||
@@ -1791,7 +1791,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/
|
@@ -1813,7 +1813,7 @@ nmbd/nmbd_multicall.o: nmbd/nmbd.c nmbd/
|
||||||
echo "$(COMPILE_CC_PATH)" 1>&2;\
|
echo "$(COMPILE_CC_PATH)" 1>&2;\
|
||||||
$(COMPILE_CC_PATH) >/dev/null 2>&1
|
$(COMPILE_CC_PATH) >/dev/null 2>&1
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
@echo Compiling $<.c
|
@echo Compiling $<.c
|
||||||
@$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
|
@$(COMPILE_CC_PATH) -Dmain=smbpasswd_main && exit 0;\
|
||||||
echo "The following command failed:" 1>&2;\
|
echo "The following command failed:" 1>&2;\
|
||||||
@@ -1800,7 +1800,7 @@ utils/smbpasswd_multicall.o: utils/smbpa
|
@@ -1822,7 +1822,7 @@ utils/smbpasswd_multicall.o: utils/smbpa
|
||||||
|
|
||||||
SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
|
SMBD_MULTI_O = $(patsubst smbd/server.o,smbd/server_multicall.o,$(SMBD_OBJ))
|
||||||
NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
|
NMBD_MULTI_O = $(patsubst nmbd/nmbd.o,nmbd/nmbd_multicall.o,$(filter-out $(LIB_DUMMY_OBJ),$(NMBD_OBJ)))
|
||||||
|
|
|
@ -24,3 +24,18 @@
|
||||||
epmapper_commands,
|
epmapper_commands,
|
||||||
shutdown_commands,
|
shutdown_commands,
|
||||||
test_commands,
|
test_commands,
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -433,10 +433,12 @@ static bool check_bind_req(struct pipes_
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = true;
|
||||||
|
}
|
||||||
|
+#ifdef DEVELOPER
|
||||||
|
ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = true;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
/*
|
||||||
|
* every interface can be modified to allow "connect" auth_level by
|
||||||
|
* using a parametric option like:
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
#endif
|
#endif
|
||||||
--- a/source3/rpc_client/cli_pipe.c
|
--- a/source3/rpc_client/cli_pipe.c
|
||||||
+++ b/source3/rpc_client/cli_pipe.c
|
+++ b/source3/rpc_client/cli_pipe.c
|
||||||
@@ -2904,12 +2904,14 @@ NTSTATUS cli_rpc_pipe_open_noauth_transp
|
@@ -3391,12 +3391,14 @@ NTSTATUS cli_rpc_pipe_open_noauth_transp
|
||||||
status = rpc_pipe_bind(result, auth);
|
status = rpc_pipe_bind(result, auth);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
int lvl = 0;
|
int lvl = 0;
|
||||||
|
|
|
@ -183,3 +183,31 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Force a log file check.
|
* Force a log file check.
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -421,10 +421,12 @@ static bool check_bind_req(struct pipes_
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
}
|
||||||
|
+#ifdef NETLOGON_SUPPORT
|
||||||
|
ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
/*
|
||||||
|
* for the epmapper and echo interfaces we allow "connect"
|
||||||
|
* auth_level by default.
|
||||||
|
--- a/source3/rpc_client/cli_pipe.c
|
||||||
|
+++ b/source3/rpc_client/cli_pipe.c
|
||||||
|
@@ -2221,6 +2221,10 @@ static void rpc_pipe_bind_step_two_trigg
|
||||||
|
struct schannel_state);
|
||||||
|
struct tevent_req *subreq;
|
||||||
|
|
||||||
|
+#ifndef NETLOGON_SUPPORT
|
||||||
|
+ tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
|
||||||
|
+ return;
|
||||||
|
+#endif
|
||||||
|
if (schannel_auth == NULL ||
|
||||||
|
!ndr_syntax_id_equal(&state->cli->abstract_syntax,
|
||||||
|
&ndr_table_netlogon.syntax_id)) {
|
||||||
|
|
|
@ -142,3 +142,21 @@
|
||||||
if (!str1 || !str2 || !UserName || !p) {
|
if (!str1 || !str2 || !UserName || !p) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -409,6 +409,7 @@ static bool check_bind_req(struct pipes_
|
||||||
|
context_fns->syntax = *abstract;
|
||||||
|
|
||||||
|
context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
|
||||||
|
+#ifdef SAMR_SUPPORT
|
||||||
|
/*
|
||||||
|
* for the samr and the lsarpc interfaces we don't allow "connect"
|
||||||
|
* auth_level by default.
|
||||||
|
@@ -417,6 +418,7 @@ static bool check_bind_req(struct pipes_
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
|
|
@ -71,3 +71,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t num_pipe_handles(struct pipes_struct *p)
|
size_t num_pipe_handles(struct pipes_struct *p)
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -419,10 +419,12 @@ static bool check_bind_req(struct pipes_
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+#ifdef LSA_SUPPORT
|
||||||
|
ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
|
||||||
|
if (ok) {
|
||||||
|
context_fns->allow_connect = false;
|
||||||
|
}
|
||||||
|
+#endif
|
||||||
|
#ifdef NETLOGON_SUPPORT
|
||||||
|
ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
|
||||||
|
if (ok) {
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
}
|
}
|
||||||
--- a/librpc/ndr/libndr.h
|
--- a/librpc/ndr/libndr.h
|
||||||
+++ b/librpc/ndr/libndr.h
|
+++ b/librpc/ndr/libndr.h
|
||||||
@@ -604,4 +604,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
|
@@ -663,4 +663,20 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
|
||||||
|
|
||||||
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
|
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
|
||||||
|
|
||||||
|
@ -251,3 +251,87 @@
|
||||||
print " return;";
|
print " return;";
|
||||||
print " }";
|
print " }";
|
||||||
print "";
|
print "";
|
||||||
|
--- a/source3/rpc_client/cli_pipe.c
|
||||||
|
+++ b/source3/rpc_client/cli_pipe.c
|
||||||
|
@@ -445,7 +445,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -466,7 +465,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -486,7 +484,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -508,7 +505,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -526,7 +522,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -570,7 +565,6 @@ static NTSTATUS cli_pipe_validate_curren
|
||||||
|
rpccli_pipe_txt(talloc_tos(), cli),
|
||||||
|
pkt->ptype, expected_pkt_type,
|
||||||
|
nt_errstr(ret)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/source3/rpc_server/srv_pipe.c
|
||||||
|
+++ b/source3/rpc_server/srv_pipe.c
|
||||||
|
@@ -991,7 +991,6 @@ static bool api_pipe_bind_req(struct pip
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
|
||||||
|
nt_errstr(status)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1325,7 +1324,6 @@ bool api_pipe_bind_auth3(struct pipes_st
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
|
||||||
|
nt_errstr(status)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1483,7 +1481,6 @@ static bool api_pipe_alter_context(struc
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
|
||||||
|
nt_errstr(status)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2057,7 +2054,6 @@ static bool process_request_pdu(struct p
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
|
||||||
|
nt_errstr(status)));
|
||||||
|
- NDR_PRINT_DEBUG(ncacn_packet, pkt);
|
||||||
|
set_incoming_fault(p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -8844,7 +8844,7 @@
|
||||||
+done
|
+done
|
||||||
--- a/librpc/ndr/libndr.h
|
--- a/librpc/ndr/libndr.h
|
||||||
+++ b/librpc/ndr/libndr.h
|
+++ b/librpc/ndr/libndr.h
|
||||||
@@ -603,6 +603,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
|
@@ -662,6 +662,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_enum
|
||||||
_PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v);
|
_PUBLIC_ enum ndr_err_code ndr_push_enum_uint1632(struct ndr_push *ndr, int ndr_flags, uint16_t v);
|
||||||
|
|
||||||
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
|
_PUBLIC_ void ndr_print_bool(struct ndr_print *ndr, const char *name, const bool b);
|
||||||
|
|
Loading…
Reference in a new issue