The branch, master has been updated via f5d320a s3:smb2_create: use smbd_calculate_access_mask() instead of smbd_check_open_rights() via a104638 s3:smb2_tcon: return the correct maximal_access on the share via 58eed1b s3:smbd: return the real share access mask in the SMBtconX response via 581d8fa s3:smbd: use smbd_calculate_access_mask() also for fake_files via 896f105 s3:smbd: check the share level access mask in smbd_calculate_access_mask() via ce66d4e s3:smbd: make smbd_calculate_access_mask() non-static via 18f967a s3:smbd/msdfs: let create_conn_struct() check the share security descriptor from 7c10b5e s3:winbindd_cm: make use of cli->src_ss instead of calling getsockname()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit f5d320ac0fb74d4ad95a03969366096e9b074379 Author: Stefan Metzmacher <me...@samba.org> Date: Sun Jul 10 13:09:06 2011 +0200 s3:smb2_create: use smbd_calculate_access_mask() instead of smbd_check_open_rights() metze Autobuild-User: Stefan Metzmacher <me...@samba.org> Autobuild-Date: Mon Jul 11 22:45:01 CEST 2011 on sn-devel-104 commit a1046389ffcc476456ac76cb701a4325d1c42ef9 Author: Stefan Metzmacher <me...@samba.org> Date: Sun Jul 10 13:02:11 2011 +0200 s3:smb2_tcon: return the correct maximal_access on the share metze commit 58eed1b295afeff6acfb8c1f10b0bb02280fd491 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jul 11 16:12:57 2011 +0200 s3:smbd: return the real share access mask in the SMBtconX response metze commit 581d8fa36b73abab030168dc35fb631ccd42a388 Author: Stefan Metzmacher <me...@samba.org> Date: Sun Jul 10 13:59:40 2011 +0200 s3:smbd: use smbd_calculate_access_mask() also for fake_files metze commit 896f105ed40dc04f83bcbfac367b309c8d957f86 Author: Stefan Metzmacher <me...@samba.org> Date: Sun Jul 10 13:03:51 2011 +0200 s3:smbd: check the share level access mask in smbd_calculate_access_mask() I think we should reject invalid access early, before we might create new files. Also smbd_check_open_rights() is only called if the file existed. metze commit ce66d4e4a885add09edfa8e6d5eab0f3b5d63081 Author: Stefan Metzmacher <me...@samba.org> Date: Sun Jul 10 13:00:25 2011 +0200 s3:smbd: make smbd_calculate_access_mask() non-static metze commit 18f967a24881aa899b39f7676fc70a7f7aaca07b Author: Stefan Metzmacher <me...@samba.org> Date: Mon Jul 11 18:09:44 2011 +0200 s3:smbd/msdfs: let create_conn_struct() check the share security descriptor metze ----------------------------------------------------------------------- Summary of changes: source3/smbd/fake_file.c | 13 ++++++++++++ source3/smbd/globals.h | 5 ++++ source3/smbd/msdfs.c | 30 ++++++++++++++++++++++++++++ source3/smbd/open.c | 46 ++++++++++++++++++++++++++++++------------- source3/smbd/reply.c | 4 +-- source3/smbd/smb2_create.c | 7 +++++- source3/smbd/smb2_tcon.c | 2 +- 7 files changed, 88 insertions(+), 19 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/fake_file.c b/source3/smbd/fake_file.c index 81f7686..68967fb 100644 --- a/source3/smbd/fake_file.c +++ b/source3/smbd/fake_file.c @@ -19,6 +19,7 @@ #include "includes.h" #include "smbd/smbd.h" +#include "smbd/globals.h" #include "fake_file.h" #include "auth.h" @@ -128,6 +129,18 @@ NTSTATUS open_fake_file(struct smb_request *req, connection_struct *conn, files_struct *fsp = NULL; NTSTATUS status; + status = smbd_calculate_access_mask(conn, smb_fname, + false, /* fake files do not exist */ + access_mask, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_fake_file: smbd_calculate_access_mask " + "on service[%s] file[%s] returned %s\n", + lp_servicename(SNUM(conn)), + smb_fname_str_dbg(smb_fname), + nt_errstr(status))); + return status; + } + /* access check */ if (geteuid() != sec_initial_uid()) { DEBUG(3, ("open_fake_file_shared: access_denied to " diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index b684a92..911a86a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -224,6 +224,11 @@ bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx, int *_last_entry_off, struct ea_list *name_list); +NTSTATUS smbd_calculate_access_mask(connection_struct *conn, + const struct smb_filename *smb_fname, + bool file_existed, + uint32_t access_mask, + uint32_t *access_mask_out); NTSTATUS smbd_check_open_rights(struct connection_struct *conn, const struct smb_filename *smb_fname, uint32_t access_mask, diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index 31c5a2d..4629a39 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -28,6 +28,7 @@ #include "msdfs.h" #include "auth.h" #include "lib/param/loadparm.h" +#include "libcli/security/security.h" /********************************************************************** Parse a DFS pathname of the form \hostname\service\reqpath @@ -279,6 +280,35 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx, set_conn_connectpath(conn, connpath); + /* + * New code to check if there's a share security descripter + * added from NT server manager. This is done after the + * smb.conf checks are done as we need a uid and token. JRA. + * + */ + if (conn->session_info) { + share_access_check(conn->session_info->security_token, + lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS, + &conn->share_access); + + if ((conn->share_access & FILE_WRITE_DATA) == 0) { + if ((conn->share_access & FILE_READ_DATA) == 0) { + /* No access, read or write. */ + DEBUG(0,("create_conn_struct: connection to %s " + "denied due to security " + "descriptor.\n", + lp_servicename(snum))); + conn_free(conn); + return NT_STATUS_ACCESS_DENIED; + } else { + conn->read_only = true; + } + } + } else { + conn->share_access = 0; + conn->read_only = true; + } + if (!smbd_vfs_init(conn)) { NTSTATUS status = map_nt_error_from_unix(errno); DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n")); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index bbab9f1..5bbcf1e 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1523,13 +1523,15 @@ static void schedule_defer_open(struct share_mode_lock *lck, Work out what access_mask to use from what the client sent us. ****************************************************************************/ -static NTSTATUS calculate_access_mask(connection_struct *conn, - const struct smb_filename *smb_fname, - bool file_existed, - uint32_t access_mask, - uint32_t *access_mask_out) +NTSTATUS smbd_calculate_access_mask(connection_struct *conn, + const struct smb_filename *smb_fname, + bool file_existed, + uint32_t access_mask, + uint32_t *access_mask_out) { NTSTATUS status; + uint32_t orig_access_mask = access_mask; + uint32_t rejected_share_access; /* * Convert GENERIC bits to specific bits. @@ -1550,8 +1552,8 @@ static NTSTATUS calculate_access_mask(connection_struct *conn, SECINFO_DACL),&sd); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("calculate_access_mask: Could not get acl " - "on file %s: %s\n", + DEBUG(10,("smbd_calculate_access_mask: " + "Could not get acl on file %s: %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status))); return NT_STATUS_ACCESS_DENIED; @@ -1566,8 +1568,9 @@ static NTSTATUS calculate_access_mask(connection_struct *conn, TALLOC_FREE(sd); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("calculate_access_mask: Access denied on " - "file %s: when calculating maximum access\n", + DEBUG(10, ("smbd_calculate_access_mask: " + "Access denied on file %s: " + "when calculating maximum access\n", smb_fname_str_dbg(smb_fname))); return NT_STATUS_ACCESS_DENIED; } @@ -1576,6 +1579,21 @@ static NTSTATUS calculate_access_mask(connection_struct *conn, } else { access_mask = FILE_GENERIC_ALL; } + + access_mask &= conn->share_access; + } + + rejected_share_access = access_mask & ~(conn->share_access); + + if (rejected_share_access) { + DEBUG(10, ("smbd_calculate_access_mask: Access denied on " + "file %s: rejected by share access mask[0x%08X] " + "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n", + smb_fname_str_dbg(smb_fname), + conn->share_access, + orig_access_mask, access_mask, + rejected_share_access)); + return NT_STATUS_ACCESS_DENIED; } *access_mask_out = access_mask; @@ -1899,11 +1917,11 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } } - status = calculate_access_mask(conn, smb_fname, file_existed, + status = smbd_calculate_access_mask(conn, smb_fname, file_existed, access_mask, &access_mask); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("open_file_ntcreate: calculate_access_mask " + DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask " "on file %s returned %s\n", smb_fname_str_dbg(smb_fname), nt_errstr(status))); return status; @@ -2743,10 +2761,10 @@ static NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_NOT_A_DIRECTORY; } - status = calculate_access_mask(conn, smb_dname, dir_existed, - access_mask, &access_mask); + status = smbd_calculate_access_mask(conn, smb_dname, dir_existed, + access_mask, &access_mask); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("open_directory: calculate_access_mask " + DEBUG(10, ("open_directory: smbd_calculate_access_mask " "on file %s returned %s\n", smb_fname_str_dbg(smb_dname), nt_errstr(status))); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 72fee8c..2f37b61 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -858,9 +858,7 @@ void reply_tcon_and_X(struct smb_request *req) perm1 = FILE_ALL_ACCESS; perm2 = FILE_ALL_ACCESS; } else { - perm1 = CAN_WRITE(conn) ? - SHARE_ALL_ACCESS : - SHARE_READ_ONLY; + perm1 = conn->share_access; } SIVAL(req->outbuf, smb_vwv3, perm1); diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index 2360286..7c6b4bc 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -736,8 +736,13 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, uint32_t max_access_granted; DATA_BLOB blob = data_blob_const(p, sizeof(p)); - status = smbd_check_open_rights(smb1req->conn, + status = smbd_calculate_access_mask(smb1req->conn, result->fsp_name, + /* + * at this stage + * it exists + */ + true, SEC_FLAG_MAXIMUM_ALLOWED, &max_access_granted); diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 946bc56..6b86e24 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -272,7 +272,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, break; } - *out_maximal_access = FILE_GENERIC_ALL; + *out_maximal_access = tcon->compat_conn->share_access; *out_tree_id = tcon->tid; return NT_STATUS_OK; -- Samba Shared Repository