summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/uid.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index b2fe39cb9c..a795eef8af 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -191,6 +191,13 @@ static bool check_user_ok(connection_struct *conn,
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;
@@ -232,11 +239,26 @@ static bool check_user_ok(connection_struct *conn,
return false;
}
+ /*
+ * It's actually OK to call check_user_ok() with
+ * vuid == UID_FIELD_INVALID as called from change_to_user_by_session().
+ * All this will do is throw away one entry in the cache.
+ */
+
ent->vuid = vuid;
ent->read_only = readonly_share;
ent->share_access = share_access;
free_conn_session_info_if_unused(conn);
conn->session_info = ent->session_info;
+ if (vuid == UID_FIELD_INVALID) {
+ /*
+ * Not strictly needed, just make it really
+ * clear this entry is actually an unused one.
+ */
+ ent->read_only = false;
+ ent->share_access = 0;
+ ent->session_info = NULL;
+ }
conn->read_only = readonly_share;
conn->share_access = share_access;