[SCM] Samba Shared Repository - branch v4-0-test updated
Karolin Seeger
kseeger at samba.org
Mon Jan 14 12:45:04 MST 2013
The branch, v4-0-test has been updated
via 15652ef selftest: show that Samba honours "write list" and valid users
via eeab8bb Fixup the change_to_user_by_session() case as called from become_user_by_session()
via 456d4eb Move create_share_access_mask() from smbd/service.c to smbd/uid.c
via 2c16104 Fix bug #9518 - conn->share_access appears not be be reset between users.
via a6a7041 Factor code out of check_user_ok() into a call to check_user_share_access().
via 57aa765 Initialize stack variables. Prelude to factoring out calls to check_user_share_access().
via c1292fa Add check_user_share_access()
via c03fd9c Correctly setup the conn->share_access based on the current user token.
via bb7cdda Add parallel cache for share_access entries, one per connection struct.
via 4fa8368 Change API for create_share_access_mask() - remove conn struct.
via ced2c1d Change API for create_share_access_mask() to pass in the token.
via 3016cff Fix API for create_share_access_mask().
via 76b214f Remove static from create_share_access_mask().
via ff2e3e2 Remove unneeded variable "const struct auth_session_info *session_info"
via c261e70 Remove dead code now vuser can no longer be NULL.
via 7fe1f1f Remove the second set of {} braces, no longer needed. (cherry picked from commit ed0a34d163f777b2a0d4a2b358b7fb1b170d7686)
via b6c5860 Remove one set of enclosing {} braces, no longer needed.
via 8dcf29e Move the definition of struct vuid_cache_entry *ent outside blocks.
via 9b1cc0b Start to tidy-up check_user_ok().
from 46d52b3 s3:smb2_negprot: set the 'remote_proto' value (bug #9499)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test
- Log -----------------------------------------------------------------
commit 15652efca8644c03a48e258473fe5b58168df333
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Dec 20 23:05:55 2012 +1100
selftest: show that Samba honours "write list" and valid users
Reviewed-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
The last 19 patches address bug #9518 - conn->share_access appears not be be
reset between users.
Autobuild-User(v4-0-test): Karolin Seeger <kseeger at samba.org>
Autobuild-Date(v4-0-test): Mon Jan 14 20:44:40 CET 2013 on sn-devel-104
commit eeab8bb5021fd5296e776a52747bc36514fcaf2a
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 11 11:14:48 2013 -0800
Fixup the change_to_user_by_session() case as called from become_user_by_session()
Use inside source3/printing/nt_printing.c:get_correct_cversion().
Allow check_user_ok() to be called with vuid==UID_FIELD_INVALID.
All this should do is throw away one entry in the vuid cache.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 456d4eb823011938ccda3261b2af8f7c02cc58ed
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 11 11:12:15 2013 -0800
Move create_share_access_mask() from smbd/service.c to smbd/uid.c
Make it static. Only called from uid.c now.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 2c161048c4daa88341e890ae9aaa92d7275433d5
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 15:15:59 2013 -0800
Fix bug #9518 - conn->share_access appears not be be reset between users.
Ensure make_connection_snum() uses the same logic as check_user_ok()
to decide if a user can access a share.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit a6a70415a70bfcdd4c1189fd8fb157d4b923d868
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 15:13:53 2013 -0800
Factor code out of check_user_ok() into a call to check_user_share_access().
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 57aa7658d7475c311942668a72b6cb1d60f002f8
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 11:05:03 2013 -0800
Initialize stack variables. Prelude to factoring out calls to check_user_share_access().
Signed-off-by: Jeremy Allison <jra at samba.org>
commit c1292fa4b0f8f0297d8831e24eed7a7414645060
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 11 11:01:25 2013 -0800
Add check_user_share_access()
This factors out the share security and read_only flag
setting code so this can be called from both make_connection_snum()
as well as check_user_ok(). Gives a consistent share security
check function.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit c03fd9c96b1d0b1a8f491daaf192293a666fd9d4
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 15:06:35 2013 -0800
Correctly setup the conn->share_access based on the current user token.
Also use this to set conn->read_only. Cache the share_access
so we only evaluate this once per new user access on this share.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit bb7cdda75333f9ea49601f81047e6a1b94d890c2
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 11 10:47:56 2013 -0800
Add parallel cache for share_access entries, one per connection struct.
Needed as we cannot change the VFS ABI for 4.0.x, but need to add the
equivalent of 'uint32_t share_access' to the struct vuid_cache referenced
in connection_struct.
Exports 2 accessor functions - lifetime managed by talloc on the conn
struct list.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 4fa8368981d6275a9863f3129ac1b80d6f3b277c
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 15:04:26 2013 -0800
Change API for create_share_access_mask() - remove conn struct.
Eventually this will be indepentent of conn, just pass in the
readonly flag.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit ced2c1db806d9281bac566385d326b6642756f49
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jan 4 12:01:17 2013 -0800
Change API for create_share_access_mask() to pass in the token.
Don't automatically use the one from conn->session_info->security_token.
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 3016cff3f4ccdcbc74ba13b1e93bbcb813c4f19c
Author: Jeremy Allison <jra at samba.org>
Date: Fri Dec 21 09:45:03 2012 -0800
Fix API for create_share_access_mask().
Return the uint32_t share_access rather than directly
changing the conn struct.
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 33167c070c085b30569317666a3fca079d970321)
commit 76b214f24748a59bbc69f75c0259a81157febd5c
Author: Jeremy Allison <jra at samba.org>
Date: Fri Dec 21 09:35:31 2012 -0800
Remove static from create_share_access_mask().
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 48187220ff47efe70616361fcef1a794aef765b4)
commit ff2e3e2453f326fc70f32f0c4271249ff351621a
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:55:09 2012 -0800
Remove unneeded variable "const struct auth_session_info *session_info"
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 5a3cda176f5eecd65b289c74132b0126357c5ef0)
commit c261e70da1abeb5c3a4310e33d1b6ed01b31748d
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:54:07 2012 -0800
Remove dead code now vuser can no longer be NULL.
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit d35ba04e25eb3c396f791ea80c0ebb74543d4005)
commit 7fe1f1fe23810760a541e990c9a1883edbe64619
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:53:11 2012 -0800
Remove the second set of {} braces, no longer needed. (cherry picked from commit ed0a34d163f777b2a0d4a2b358b7fb1b170d7686)
commit b6c5860c7ce827aea0e56eb8b977b307666550ba
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:52:27 2012 -0800
Remove one set of enclosing {} braces, no longer needed.
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit d64ea67c78a5b09559971ff6953cd67feb2b1ec2)
commit 8dcf29ea538837ff89c5f584457209e665cd1da9
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:51:55 2012 -0800
Move the definition of struct vuid_cache_entry *ent outside blocks.
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit 092c9517acf5a4b11577ef7b5f1d645e5e463f6d)
commit 9b1cc0b67f358c8126fbd1d579d7bbde3dec6cf5
Author: Jeremy Allison <jra at samba.org>
Date: Thu Dec 20 11:50:25 2012 -0800
Start to tidy-up check_user_ok().
Now we have removed "security=share" we cannot be
called with vuid == UID_FIELD_INVALID.
Signed-off-by: Jeremy Allison <jra at samba.org>
(cherry picked from commit f0450e0d80c2ff56c4834b2f1271a7f84132ca5b)
-----------------------------------------------------------------------
Summary of changes:
selftest/target/Samba3.pm | 7 +
.../script/tests/test_smbclient_machine_auth.sh | 4 +
source3/script/tests/test_smbclient_s3.sh | 8 +-
source3/selftest/tests.py | 5 +
source3/smbd/conn.c | 85 ++++++++-
source3/smbd/proto.h | 9 +
source3/smbd/service.c | 64 +-----
source3/smbd/uid.c | 225 ++++++++++++++------
8 files changed, 282 insertions(+), 125 deletions(-)
Changeset truncated at 500 lines:
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 2037a2e..6c63413 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -956,6 +956,13 @@ sub provision($$$$$$)
[ro-tmp]
path = $ro_shrdir
guest ok = yes
+[write-list-tmp]
+ path = $shrdir
+ read only = yes
+ write list = $unix_name
+[valid-users-tmp]
+ path = $shrdir
+ valid users = $unix_name
[msdfs-share]
path = $msdfs_shrdir
msdfs root = yes
diff --git a/source3/script/tests/test_smbclient_machine_auth.sh b/source3/script/tests/test_smbclient_machine_auth.sh
index f67256d..a890d48 100755
--- a/source3/script/tests/test_smbclient_machine_auth.sh
+++ b/source3/script/tests/test_smbclient_machine_auth.sh
@@ -19,3 +19,7 @@ incdir=`dirname $0`/../../../testprogs/blackbox
. $incdir/subunit.sh
testit "smbclient //$SERVER/tmp" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
+
+# Testing these here helps because we know the machine account isn't already this user/group
+testit "smbclient //$SERVER/forceuser" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
+testit "smbclient //$SERVER/forcegroup" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index 3341c62..aa2ba77 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -211,7 +211,7 @@ mkdir a_test_dir
quit
EOF
- cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U% //$SERVER/ro-tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+ cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U% //$SERVER/$1" -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
eval echo "$cmd"
out=`eval $cmd`
ret=$?
@@ -529,7 +529,11 @@ testit "creating a good symlink and deleting it by path" \
failed=`expr $failed + 1`
testit "writing into a read-only directory fails" \
- test_read_only_dir || \
+ test_read_only_dir ro-tmp || \
+ failed=`expr $failed + 1`
+
+testit "writing into a read-only share fails" \
+ test_read_only_dir valid-users-tmp || \
failed=`expr $failed + 1`
testit "Reading a owner-only file fails" \
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 9b0527c..57c80f2 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -330,6 +330,11 @@ for t in tests:
elif t == "smb2.durable-open" or t == "smb2.durable-v2-open":
plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
+ elif t == "base.rw1":
+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/valid-users-tmp -U$USERNAME%$PASSWORD')
+ plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/write-list-tmp -U$USERNAME%$PASSWORD')
+ plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
else:
plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index bc5a03b..e6f81a9 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -24,6 +24,84 @@
#include "smbd/globals.h"
#include "lib/util/bitmap.h"
+/*******************************************************************
+ Static cache for storing per-user share access value. This really
+ belongs inside the vuid_cache.array struct but we can't change the
+ VFS ABI for 4.0.x. This is fixed in 4.1.x. JRA.
+********************************************************************/
+
+struct connection_share_access_list {
+ struct connection_share_access_list *next, *prev;
+ connection_struct *conn;
+ uint32_t vuid_cache_share_access_array[VUID_CACHE_SIZE];
+};
+
+static struct connection_share_access_list *conn_share_access_list;
+
+/*******************************************************************
+ Destructor function for per-user share access value.
+********************************************************************/
+
+static int free_csal_entry(struct connection_share_access_list *csal)
+{
+ DLIST_REMOVE(conn_share_access_list, csal);
+ return 0;
+}
+
+/*******************************************************************
+ Utility function to find a per-user share access value struct.
+********************************************************************/
+
+static struct connection_share_access_list *find_csal_entry(connection_struct *conn)
+{
+ struct connection_share_access_list *csal;
+
+ for (csal = conn_share_access_list; csal; csal = csal->next) {
+ if (csal->conn == conn) {
+ DLIST_PROMOTE(conn_share_access_list, csal);
+ return csal;
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************************
+ Accessor functions for per-user share access value.
+ These are the only two functions exposed externally.
+********************************************************************/
+
+uint32_t get_connection_share_access_list_entry(connection_struct *conn,
+ unsigned int i)
+{
+ struct connection_share_access_list *csal =
+ find_csal_entry(conn);
+
+ if (csal == NULL) {
+ /*
+ * This is a faked up connection struct
+ * for internal purposes.
+ * Return full access.
+ */
+ return SEC_RIGHTS_FILE_ALL;
+ }
+
+ return csal->vuid_cache_share_access_array[i];
+}
+
+void set_connection_share_access_list_entry(connection_struct *conn,
+ unsigned int i,
+ uint32_t val)
+{
+ struct connection_share_access_list *csal =
+ find_csal_entry(conn);
+
+ if (csal == NULL) {
+ return;
+ }
+
+ csal->vuid_cache_share_access_array[i] = val;
+}
+
/****************************************************************************
Return the number of open connections.
****************************************************************************/
@@ -60,19 +138,24 @@ bool conn_snum_used(struct smbd_server_connection *sconn,
connection_struct *conn_new(struct smbd_server_connection *sconn)
{
connection_struct *conn;
+ struct connection_share_access_list *csal;
if (!(conn=talloc_zero(NULL, connection_struct)) ||
!(conn->params = talloc(conn, struct share_params)) ||
!(conn->connectpath = talloc_strdup(conn, "")) ||
- !(conn->origpath = talloc_strdup(conn, ""))) {
+ !(conn->origpath = talloc_strdup(conn, "")) ||
+ !(csal = talloc_zero(conn, struct connection_share_access_list))) {
DEBUG(0,("TALLOC_ZERO() failed!\n"));
TALLOC_FREE(conn);
return NULL;
}
+ talloc_set_destructor(csal, free_csal_entry);
+
conn->sconn = sconn;
conn->force_group_gid = (gid_t)-1;
DLIST_ADD(sconn->connections, conn);
+ DLIST_ADD(conn_share_access_list, csal);
sconn->num_connections++;
return conn;
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index b48cf44..fae1407 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -145,6 +145,11 @@ bool recursive_rmdir(TALLOC_CTX *ctx,
/* The following definitions come from smbd/conn.c */
+uint32_t get_connection_share_access_list_entry(connection_struct *conn,
+ unsigned int i);
+void set_connection_share_access_list_entry(connection_struct *conn,
+ unsigned int i,
+ uint32_t val);
int conn_num_open(struct smbd_server_connection *sconn);
bool conn_snum_used(struct smbd_server_connection *sconn, int snum);
connection_struct *conn_new(struct smbd_server_connection *sconn);
@@ -1079,6 +1084,10 @@ void reply_transs2(struct smb_request *req);
/* The following definitions come from smbd/uid.c */
bool change_to_guest(void);
+NTSTATUS check_user_share_access(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint32_t *p_share_access,
+ bool *p_readonly_share);
bool change_to_user(connection_struct *conn, uint64_t vuid);
bool change_to_root_user(void);
bool smbd_change_to_root_user(void);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2214ac0..b3abdd8 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -512,40 +512,6 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
}
/****************************************************************************
- Setup the share access mask for a connection.
-****************************************************************************/
-
-static void create_share_access_mask(connection_struct *conn, int snum)
-{
- const struct security_token *token = conn->session_info->security_token;
-
- share_access_check(token,
- lp_servicename(talloc_tos(), snum),
- MAXIMUM_ALLOWED_ACCESS,
- &conn->share_access);
-
- if (!CAN_WRITE(conn)) {
- conn->share_access &=
- ~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
- SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
- SEC_DIR_DELETE_CHILD );
- }
-
- if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
- conn->share_access |= SEC_FLAG_SYSTEM_SECURITY;
- }
- if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
- conn->share_access |= (SEC_RIGHTS_PRIV_RESTORE);
- }
- if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
- conn->share_access |= (SEC_RIGHTS_PRIV_BACKUP);
- }
- if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
- conn->share_access |= (SEC_STD_WRITE_OWNER);
- }
-}
-
-/****************************************************************************
Make a connection, given the snum to connect to, and the vuser of the
connecting user if appropriate.
****************************************************************************/
@@ -647,28 +613,18 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
TALLOC_FREE(s);
}
- /*
- * 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.
- *
- */
-
- create_share_access_mask(conn, snum);
+ /*
+ * Set up the share security descripter
+ */
- if ((conn->share_access & FILE_WRITE_DATA) == 0) {
- if ((conn->share_access & FILE_READ_DATA) == 0) {
- /* No access, read or write. */
- DEBUG(0,("make_connection: connection to %s "
- "denied due to security "
- "descriptor.\n",
- lp_servicename(talloc_tos(), snum)));
- status = NT_STATUS_ACCESS_DENIED;
- goto err_root_exit;
- } else {
- conn->read_only = True;
- }
+ status = check_user_share_access(conn,
+ conn->session_info,
+ &conn->share_access,
+ &conn->read_only);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err_root_exit;
}
+
/* Initialise VFS function pointers */
if (!smbd_vfs_init(conn)) {
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 30c7154..852ae39 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -78,41 +78,61 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
TALLOC_FREE(conn->session_info);
}
-/*******************************************************************
- Check if a username is OK.
-
- This sets up conn->session_info with a copy related to this vuser that
- later code can then mess with.
-********************************************************************/
+/****************************************************************************
+ Setup the share access mask for a connection.
+****************************************************************************/
-static bool check_user_ok(connection_struct *conn,
- uint64_t vuid,
- const struct auth_session_info *session_info,
- int snum)
+static uint32_t create_share_access_mask(int snum,
+ bool readonly_share,
+ const struct security_token *token)
{
- bool valid_vuid = (vuid != UID_FIELD_INVALID);
- unsigned int i;
- bool readonly_share;
- bool admin_user;
-
- if (valid_vuid) {
- struct vuid_cache_entry *ent;
+ uint32_t share_access = 0;
+
+ share_access_check(token,
+ lp_servicename(talloc_tos(), snum),
+ MAXIMUM_ALLOWED_ACCESS,
+ &share_access);
+
+ if (readonly_share) {
+ share_access &=
+ ~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
+ SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_DIR_DELETE_CHILD );
+ }
- for (i=0; i<VUID_CACHE_SIZE; i++) {
- ent = &conn->vuid_cache.array[i];
- if (ent->vuid == vuid) {
- free_conn_session_info_if_unused(conn);
- conn->session_info = ent->session_info;
- conn->read_only = ent->read_only;
- return(True);
- }
- }
+ if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
+ share_access |= SEC_FLAG_SYSTEM_SECURITY;
+ }
+ if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+ share_access |= (SEC_RIGHTS_PRIV_RESTORE);
}
+ if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
+ share_access |= (SEC_RIGHTS_PRIV_BACKUP);
+ }
+ if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
+ share_access |= (SEC_STD_WRITE_OWNER);
+ }
+
+ return share_access;
+}
+
+/*******************************************************************
+ Calculate access mask and if this user can access this share.
+********************************************************************/
+
+NTSTATUS check_user_share_access(connection_struct *conn,
+ const struct auth_session_info *session_info,
+ uint32_t *p_share_access,
+ bool *p_readonly_share)
+{
+ int snum = SNUM(conn);
+ uint32_t share_access = 0;
+ bool readonly_share = false;
if (!user_ok_token(session_info->unix_info->unix_name,
session_info->info->domain_name,
session_info->security_token, snum))
- return(False);
+ return NT_STATUS_ACCESS_DENIED;
readonly_share = is_share_read_only_for_token(
session_info->unix_info->unix_name,
@@ -120,11 +140,24 @@ static bool check_user_ok(connection_struct *conn,
session_info->security_token,
conn);
+ share_access = create_share_access_mask(snum,
+ readonly_share,
+ session_info->security_token);
+
+ if ((share_access & FILE_WRITE_DATA) == 0) {
+ if ((share_access & FILE_READ_DATA) == 0) {
+ /* No access, read or write. */
+ DEBUG(0,("user %s connection to %s "
+ "denied due to share security "
+ "descriptor.\n",
+ session_info->unix_info->unix_name,
+ lp_servicename(talloc_tos(), snum)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
if (!readonly_share &&
- !share_access_check(session_info->security_token,
- lp_servicename(talloc_tos(), snum),
- FILE_WRITE_DATA,
- NULL)) {
+ !(share_access & FILE_WRITE_DATA)) {
/* smb.conf allows r/w, but the security descriptor denies
* write. Fall back to looking at readonly. */
readonly_share = True;
@@ -132,48 +165,114 @@ static bool check_user_ok(connection_struct *conn,
"security descriptor\n"));
}
- if (!share_access_check(session_info->security_token,
- lp_servicename(talloc_tos(), snum),
- readonly_share ?
- FILE_READ_DATA : FILE_WRITE_DATA,
- NULL)) {
- return False;
+ *p_share_access = share_access;
+ *p_readonly_share = readonly_share;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Check if a username is OK.
+
+ This sets up conn->session_info with a copy related to this vuser that
+ later code can then mess with.
+********************************************************************/
+
+static bool check_user_ok(connection_struct *conn,
+ uint64_t vuid,
+ const struct auth_session_info *session_info,
+ int snum)
+{
+ unsigned int i;
+ bool readonly_share = false;
+ bool admin_user = false;
+ struct vuid_cache_entry *ent = NULL;
+ uint32_t share_access = 0;
+ unsigned int share_array_index;
+ NTSTATUS status;
+
+ for (i=0; i<VUID_CACHE_SIZE; i++) {
+ ent = &conn->vuid_cache.array[i];
+ if (ent->vuid == vuid) {
+ if (vuid == UID_FIELD_INVALID) {
+ /*
+ * Slow path, we don't care
+ * about the array traversal.
+ */
+ continue;
+ }
+ free_conn_session_info_if_unused(conn);
+ conn->session_info = ent->session_info;
+ conn->read_only = ent->read_only;
+ conn->share_access = get_connection_share_access_list_entry(
+ conn,
+ i);
+ return(True);
+ }
+ }
+
+ status = check_user_share_access(conn,
+ session_info,
+ &share_access,
+ &readonly_share);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
}
+
admin_user = token_contains_name_in_list(
session_info->unix_info->unix_name,
session_info->info->domain_name,
NULL, session_info->security_token, lp_admin_users(snum));
- if (valid_vuid) {
- struct vuid_cache_entry *ent =
- &conn->vuid_cache.array[conn->vuid_cache.next_entry];
+ share_array_index = conn->vuid_cache.next_entry;
+ ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
- conn->vuid_cache.next_entry =
- (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
+ conn->vuid_cache.next_entry =
+ (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
--
Samba Shared Repository
More information about the samba-cvs
mailing list