From a91cf9a5648184d39aa87e06d484b3d533aeefdb Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:18:12 -0800
Subject: [PATCH 01/12] 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: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 41e1bb1..b9865fd 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -54,6 +54,34 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
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_basename(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;
+}
+
/********************************************************************
The canonical "check access" based on object handle or path function.
********************************************************************/
--
1.9.1
From cd950ca41df5076c8622cdf9be0e0db165b992f1 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 10:38:28 -0800
Subject: [PATCH 02/12] CVE-2015-7560: s3: smbd: Refuse to get an ACL from a
POSIX file handle on a symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/nttrans.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 4423a44..8113909 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1905,6 +1905,13 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn,
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)));
+ TALLOC_FREE(frame);
+ 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
--
1.9.1
From b95ded07aec97c31c69f49f691d5f90fdee40f92 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 10:52:50 -0800
Subject: [PATCH 03/12] CVE-2015-7560: s3: smbd: Refuse to set an ACL from a
POSIX file handle on a symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/nttrans.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 8113909..372d420 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -875,6 +875,12 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd,
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;
}
--
1.9.1
From 35abb608ce57efea1bc197b7d65f9347f9533f23 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:22:12 -0800
Subject: [PATCH 04/12] CVE-2015-7560: s3: smbd: Refuse to set a POSIX ACL on a
symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index b9865fd..a5eeda8 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -6745,6 +6745,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
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;
@@ -6772,6 +6773,11 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
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,
--
1.9.1
From 95c3bf9102440cf299312acc0d0a89afebf0474e Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:24:36 -0800
Subject: [PATCH 05/12] CVE-2015-7560: s3: smbd: Refuse to get a POSIX ACL on a
symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index a5eeda8..8ea49f1e 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -5248,6 +5248,13 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
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,
talloc_tos());
--
1.9.1
From c7ea0914d3b4a3deaf31a742c6edf4c6e7a91939 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:05:48 -0800
Subject: [PATCH 06/12] CVE-2015-7560: s3: smbd: Set return values early,
allows removal of code duplication.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 8ea49f1e..35a0ba2 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -238,11 +238,12 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
size_t num_names;
ssize_t sizeret = -1;
+ if (pnames) {
+ *pnames = NULL;
+ }
+ *pnum_names = 0;
+
if (!lp_ea_support(SNUM(conn))) {
- if (pnames) {
- *pnames = NULL;
- }
- *pnum_names = 0;
return NT_STATUS_OK;
}
@@ -292,10 +293,6 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
if (sizeret == 0) {
TALLOC_FREE(names);
- if (pnames) {
- *pnames = NULL;
- }
- *pnum_names = 0;
return NT_STATUS_OK;
}
--
1.9.1
From 142a3050ec9875501b4f5693792d133bc5c3331a Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:29:38 -0800
Subject: [PATCH 07/12] CVE-2015-7560: s3: smbd: Silently return no EA's
available on a symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 35a0ba2..29e28bd 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -237,6 +237,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
char **names, **tmp;
size_t num_names;
ssize_t sizeret = -1;
+ NTSTATUS status;
if (pnames) {
*pnames = NULL;
@@ -247,6 +248,14 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
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;
+ }
+
/*
* TALLOC the result early to get the talloc hierarchy right.
*/
--
1.9.1
From 08cf63d886b2f59f94a749089b73599330cee0e7 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 5 Jan 2016 11:33:48 -0800
Subject: [PATCH 08/12] CVE-2015-7560: s3: smbd: Refuse to set EA's on a
symlink.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/smbd/trans2.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 29e28bd..aaaa5f4 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -659,6 +659,11 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
return NT_STATUS_EAS_NOT_SUPPORTED;
}
+ status = refuse_symlink(conn, fsp, smb_fname->base_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
status = check_access(conn, fsp, smb_fname, FILE_WRITE_EA);
if (!NT_STATUS_IS_OK(status)) {
return status;
--
1.9.1
From 259fec336cee663044d7e107a3dfce6264f20e84 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Wed, 6 Jan 2016 17:17:24 -0800
Subject: [PATCH 09/12] CVE-2015-7560: s3: libsmb: Rename cli_posix_getfaclXX()
functions to cli_posix_getacl() as they operate on pathnames.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/client/client.c | 2 +-
source3/libsmb/clifile.c | 30 +++++++++++++++---------------
source3/libsmb/proto.h | 6 +++---
3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/source3/client/client.c b/source3/client/client.c
index 67cc359..a8e5338 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -3376,7 +3376,7 @@ static int cmd_getfacl(void)
return 1;
}
- status = cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf);
+ status = cli_posix_getacl(targetcli, targetname, ctx, &rb_size, &retbuf);
if (!NT_STATUS_IS_OK(status)) {
d_printf("%s getfacl file %s\n",
nt_errstr(status), src);
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 61cb8b5..ff646e4 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -590,25 +590,25 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli,
}
/****************************************************************************
- Do a POSIX getfacl (UNIX extensions).
+ Do a POSIX getacl - pathname based ACL get (UNIX extensions).
****************************************************************************/
-struct getfacl_state {
+struct getacl_state {
uint32_t num_data;
uint8_t *data;
};
-static void cli_posix_getfacl_done(struct tevent_req *subreq);
+static void cli_posix_getacl_done(struct tevent_req *subreq);
-struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+struct tevent_req *cli_posix_getacl_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct cli_state *cli,
const char *fname)
{
struct tevent_req *req = NULL, *subreq = NULL;
- struct getfacl_state *state = NULL;
+ struct getacl_state *state = NULL;
- req = tevent_req_create(mem_ctx, &state, struct getfacl_state);
+ req = tevent_req_create(mem_ctx, &state, struct getacl_state);
if (req == NULL) {
return NULL;
}
@@ -617,16 +617,16 @@ struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, cli_posix_getfacl_done, req);
+ tevent_req_set_callback(subreq, cli_posix_getacl_done, req);
return req;
}
-static void cli_posix_getfacl_done(struct tevent_req *subreq)
+static void cli_posix_getacl_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct getfacl_state *state = tevent_req_data(
- req, struct getfacl_state);
+ struct getacl_state *state = tevent_req_data(
+ req, struct getacl_state);
NTSTATUS status;
status = cli_qpathinfo_recv(subreq, state, &state->data,
@@ -638,12 +638,12 @@ static void cli_posix_getfacl_done(struct tevent_req *subreq)
tevent_req_done(req);
}
-NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+NTSTATUS cli_posix_getacl_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *prb_size,
char **retbuf)
{
- struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
+ struct getacl_state *state = tevent_req_data(req, struct getacl_state);
NTSTATUS status;
if (tevent_req_is_nterror(req, &status)) {
@@ -654,7 +654,7 @@ NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
return NT_STATUS_OK;
}
-NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+NTSTATUS cli_posix_getacl(struct cli_state *cli,
const char *fname,
TALLOC_CTX *mem_ctx,
size_t *prb_size,
@@ -679,7 +679,7 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli,
goto fail;
}
- req = cli_posix_getfacl_send(frame,
+ req = cli_posix_getacl_send(frame,
ev,
cli,
fname);
@@ -693,7 +693,7 @@ NTSTATUS cli_posix_getfacl(struct cli_state *cli,
goto fail;
}
- status = cli_posix_getfacl_recv(req, mem_ctx, prb_size, retbuf);
+ status = cli_posix_getacl_recv(req, mem_ctx, prb_size, retbuf);
fail:
TALLOC_FREE(frame);
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 2efb208..f5f35e0 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -256,15 +256,15 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli,
const char *newname);
uint32_t unix_perms_to_wire(mode_t perms);
mode_t wire_perms_to_unix(uint32_t perms);
-struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+struct tevent_req *cli_posix_getacl_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct cli_state *cli,
const char *fname);
-NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+NTSTATUS cli_posix_getacl_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *prb_size,
char **retbuf);
-NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+NTSTATUS cli_posix_getacl(struct cli_state *cli,
const char *fname,
TALLOC_CTX *mem_ctx,
size_t *prb_size,
--
1.9.1
From d9054880d4bdbcb05c677e494906a26d62afa3a1 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Wed, 6 Jan 2016 17:02:52 -0800
Subject: [PATCH 10/12] CVE-2015-7560: s3: libsmb: Add SMB1-only POSIX
cli_posix_setacl() functions. Needed for tests.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
source3/libsmb/clifile.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
source3/libsmb/proto.h | 11 ++++++
2 files changed, 111 insertions(+)
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index ff646e4..e4480c6 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -701,6 +701,106 @@ NTSTATUS cli_posix_getacl(struct cli_state *cli,
}
/****************************************************************************
+ Do a POSIX setacl - pathname based ACL set (UNIX extensions).
+****************************************************************************/
+
+struct setacl_state {
+ uint8_t *data;
+};
+
+static void cli_posix_setacl_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_posix_setacl_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ const void *data,
+ size_t num_data)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct setacl_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct setacl_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->data = talloc_memdup(state, data, num_data);
+ if (tevent_req_nomem(state->data, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = cli_setpathinfo_send(state,
+ ev,
+ cli,
+ SMB_SET_POSIX_ACL,
+ fname,
+ state->data,
+ num_data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_posix_setacl_done, req);
+ return req;
+}
+
+static void cli_posix_setacl_done(struct tevent_req *subreq)
+{
+ NTSTATUS status = cli_setpathinfo_recv(subreq);
+ tevent_req_simple_finish_ntstatus(subreq, status);
+}
+
+NTSTATUS cli_posix_setacl_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_posix_setacl(struct cli_state *cli,
+ const char *fname,
+ const void *acl_buf,
+ size_t acl_buf_size)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_setacl_send(frame,
+ ev,
+ cli,
+ fname,
+ acl_buf,
+ acl_buf_size);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+
+ status = cli_posix_setacl_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
+/****************************************************************************
Stat a file (UNIX extensions).
****************************************************************************/
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index f5f35e0..08dda96 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -269,6 +269,17 @@ NTSTATUS cli_posix_getacl(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
size_t *prb_size,
char **retbuf);
+struct tevent_req *cli_posix_setacl_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ const void *acl_buf,
+ size_t acl_buf_size);
+NTSTATUS cli_posix_setacl_recv(struct tevent_req *req);
+NTSTATUS cli_posix_setacl(struct cli_state *cli,
+ const char *fname,
+ const void *acl_buf,
+ size_t acl_buf_size);
struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct cli_state *cli,
--
1.9.1
From 5de774189a4e7be050c67d06f450a498d90d4368 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Thu, 7 Jan 2016 12:58:34 -0800
Subject: [PATCH 11/12] CVE-2015-7560: s3: torture3: Add new POSIX-SYMLINK-ACL
test.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
selftest/knownfail | 1 +
source3/selftest/tests.py | 2 +-
source3/torture/torture.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+), 1 deletion(-)
diff --git a/selftest/knownfail b/selftest/knownfail
index fd41263..6696ba3 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -16,6 +16,7 @@
^samba3.smbtorture_s3.plain\(dc\).UID-REGRESSION-TEST # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).SHORTNAME-TEST # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).POSIX-APPEND # Fails against the s4 ntvfs server
+^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-ACL # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).NTTRANS-FSCTL # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).SMB2-NEGPROT # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).BAD-NBT-SESSION # Fails against the s4 ntvfs server
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 7279927..e66ddbc 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -78,7 +78,7 @@ tests = ["RW1", "RW2", "RW3"]
for t in tests:
plantestsuite("samba3.smbtorture_s3.vfs_aio_fork(simpleserver).%s" % t, "simpleserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/vfs_aio_fork', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
-posix_tests = ["POSIX", "POSIX-APPEND"]
+posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL"]
for t in posix_tests:
plantestsuite("samba3.smbtorture_s3.plain(s3dc).%s" % t, "s3dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 0b37e5c..6c0ab17 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5820,6 +5820,203 @@ static bool run_simple_posix_open_test(int dummy)
return correct;
}
+/*
+ Test POSIX and Windows ACLs are rejected on symlinks.
+ */
+static bool run_acl_symlink_test(int dummy)
+{
+ static struct cli_state *cli;
+ const char *fname = "posix_file";
+ const char *sname = "posix_symlink";
+ uint16_t fnum = (uint16_t)-1;
+ bool correct = false;
+ NTSTATUS status;
+ char *posix_acl = NULL;
+ size_t posix_acl_len = 0;
+ char *posix_acl_sym = NULL;
+ size_t posix_acl_len_sym = 0;
+ struct security_descriptor *sd = NULL;
+ struct security_descriptor *sd_sym = NULL;
+ TALLOC_CTX *frame = NULL;
+
+ frame = talloc_stackframe();
+
+ printf("Starting acl symlink test\n");
+
+ if (!torture_open_connection(&cli, 0)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+ status = torture_setup_unix_extensions(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+
+ status = cli_ntcreate(cli,
+ fname,
+ 0,
+ READ_CONTROL_ACCESS,
+ 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_CREATE,
+ 0x0,
+ 0x0,
+ &fnum,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_ntcreate of %s failed (%s)\n",
+ fname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Get the Windows ACL on the file. */
+ status = cli_query_secdesc(cli,
+ fnum,
+ frame,
+ &sd);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_query_secdesc failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Get the POSIX ACL on the file. */
+ status = cli_posix_getacl(cli,
+ fname,
+ frame,
+ &posix_acl_len,
+ &posix_acl);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_getacl failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ status = cli_close(cli, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("close failed (%s)\n", nt_errstr(status));
+ goto out;
+ }
+ fnum = (uint16_t)-1;
+
+ /* Now create a symlink. */
+ status = cli_posix_symlink(cli, fname, sname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_symlink of %s -> %s failed (%s)\n",
+ sname,
+ fname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Open a handle on the symlink. */
+ status = cli_ntcreate(cli,
+ sname,
+ 0,
+ READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
+ 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_OPEN,
+ 0x0,
+ 0x0,
+ &fnum,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_open of %s failed (%s)\n",
+ sname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Get the Windows ACL on the symlink handle. Should fail */
+ status = cli_query_secdesc(cli,
+ fnum,
+ frame,
+ &sd_sym);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("cli_query_secdesc on a symlink gave %s. "
+ "Should be NT_STATUS_ACCESS_DENIED.\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Get the POSIX ACL on the symlink pathname. Should fail. */
+ status = cli_posix_getacl(cli,
+ sname,
+ frame,
+ &posix_acl_len_sym,
+ &posix_acl_sym);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("cli_posix_getacl on a symlink gave %s. "
+ "Should be NT_STATUS_ACCESS_DENIED.\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Set the Windows ACL on the symlink handle. Should fail */
+ status = cli_set_security_descriptor(cli,
+ fnum,
+ SECINFO_DACL,
+ sd);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("cli_query_secdesc on a symlink gave %s. "
+ "Should be NT_STATUS_ACCESS_DENIED.\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Set the POSIX ACL on the symlink pathname. Should fail. */
+ status = cli_posix_setacl(cli,
+ sname,
+ posix_acl,
+ posix_acl_len);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("cli_posix_getacl on a symlink gave %s. "
+ "Should be NT_STATUS_ACCESS_DENIED.\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ printf("ACL symlink test passed\n");
+ correct = true;
+
+ out:
+
+ if (fnum != (uint16_t)-1) {
+ cli_close(cli, fnum);
+ fnum = (uint16_t)-1;
+ }
+
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+
+ if (!torture_close_connection(cli)) {
+ correct = false;
+ }
+
+ TALLOC_FREE(frame);
+ return correct;
+}
+
static uint32 open_attrs_table[] = {
FILE_ATTRIBUTE_NORMAL,
@@ -9647,6 +9844,7 @@ static struct {
{"OPEN", run_opentest, 0},
{"POSIX", run_simple_posix_open_test, 0},
{"POSIX-APPEND", run_posix_append, 0},
+ {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
{"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
{"ASYNC-ECHO", run_async_echo, 0},
{ "UID-REGRESSION-TEST", run_uid_regression_test, 0},
--
1.9.1
From 6149e7297d9279df3b535e72eabbede7bd235925 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Thu, 7 Jan 2016 14:26:35 -0800
Subject: [PATCH 12/12] CVE-2015-7560: s3: torture3: Add new POSIX-SYMLINK-EA
test.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11648
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
---
selftest/knownfail | 1 +
source3/selftest/tests.py | 2 +-
source3/torture/torture.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 181 insertions(+), 1 deletion(-)
diff --git a/selftest/knownfail b/selftest/knownfail
index 6696ba3..c919a6a 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -17,6 +17,7 @@
^samba3.smbtorture_s3.plain\(dc\).SHORTNAME-TEST # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).POSIX-APPEND # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-ACL # Fails against the s4 ntvfs server
+^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-EA # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).NTTRANS-FSCTL # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).SMB2-NEGPROT # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(dc\).BAD-NBT-SESSION # Fails against the s4 ntvfs server
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index e66ddbc..830753c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -78,7 +78,7 @@ tests = ["RW1", "RW2", "RW3"]
for t in tests:
plantestsuite("samba3.smbtorture_s3.vfs_aio_fork(simpleserver).%s" % t, "simpleserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/vfs_aio_fork', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
-posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL"]
+posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA"]
for t in posix_tests:
plantestsuite("samba3.smbtorture_s3.plain(s3dc).%s" % t, "s3dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 6c0ab17..34c1a37 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -6017,6 +6017,183 @@ static bool run_acl_symlink_test(int dummy)
return correct;
}
+/*
+ Test setting EA's are rejected on symlinks.
+ */
+static bool run_ea_symlink_test(int dummy)
+{
+ static struct cli_state *cli;
+ const char *fname = "posix_file_ea";
+ const char *sname = "posix_symlink_ea";
+ const char *ea_name = "testea_name";
+ const char *ea_value = "testea_value";
+ uint16_t fnum = (uint16_t)-1;
+ bool correct = false;
+ NTSTATUS status;
+ size_t i, num_eas;
+ struct ea_struct *eas = NULL;
+ TALLOC_CTX *frame = NULL;
+
+ frame = talloc_stackframe();
+
+ printf("Starting EA symlink test\n");
+
+ if (!torture_open_connection(&cli, 0)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+ status = torture_setup_unix_extensions(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+
+ status = cli_ntcreate(cli,
+ fname,
+ 0,
+ READ_CONTROL_ACCESS,
+ 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_CREATE,
+ 0x0,
+ 0x0,
+ &fnum,
+ NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_ntcreate of %s failed (%s)\n",
+ fname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ status = cli_close(cli, fnum);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("close failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+ fnum = (uint16_t)-1;
+
+ /* Set an EA on the path. */
+ status = cli_set_ea_path(cli,
+ fname,
+ ea_name,
+ ea_value,
+ strlen(ea_value)+1);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_set_ea_path failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Now create a symlink. */
+ status = cli_posix_symlink(cli, fname, sname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_symlink of %s -> %s failed (%s)\n",
+ sname,
+ fname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Get the EA list on the path. Should return value set. */
+ status = cli_get_ea_list_path(cli,
+ fname,
+ frame,
+ &num_eas,
+ &eas);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_get_ea_list_path failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Ensure the EA we set is there. */
+ for (i=0; i<num_eas; i++) {
+ if (strcmp(eas[i].name, ea_name) == 0 &&
+ eas[i].value.length == strlen(ea_value)+1 &&
+ memcmp(eas[i].value.data,
+ ea_value,
+ eas[i].value.length) == 0) {
+ break;
+ }
+ }
+
+ if (i == num_eas) {
+ printf("Didn't find EA on pathname %s\n",
+ fname);
+ goto out;
+ }
+
+ num_eas = 0;
+ TALLOC_FREE(eas);
+
+ /* Get the EA list on the symlink. Should return empty list. */
+ status = cli_get_ea_list_path(cli,
+ sname,
+ frame,
+ &num_eas,
+ &eas);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_get_ea_list_path failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ if (num_eas != 0) {
+ printf("cli_get_ea_list_path failed (%s)\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Set an EA on the symlink. Should fail. */
+ status = cli_set_ea_path(cli,
+ sname,
+ ea_name,
+ ea_value,
+ strlen(ea_value)+1);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ printf("cli_set_ea_path on a symlink gave %s. "
+ "Should be NT_STATUS_ACCESS_DENIED.\n",
+ nt_errstr(status));
+ goto out;
+ }
+
+ printf("EA symlink test passed\n");
+ correct = true;
+
+ out:
+
+ if (fnum != (uint16_t)-1) {
+ cli_close(cli, fnum);
+ fnum = (uint16_t)-1;
+ }
+
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+
+ if (!torture_close_connection(cli)) {
+ correct = false;
+ }
+
+ TALLOC_FREE(frame);
+ return correct;
+}
static uint32 open_attrs_table[] = {
FILE_ATTRIBUTE_NORMAL,
@@ -9845,6 +10022,8 @@ static struct {
{"POSIX", run_simple_posix_open_test, 0},
{"POSIX-APPEND", run_posix_append, 0},
{"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
+ {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
+ {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
{"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
{"ASYNC-ECHO", run_async_echo, 0},
{ "UID-REGRESSION-TEST", run_uid_regression_test, 0},
--
1.9.1