June 25, 2018 by Kenneth Fisher
When I think of the public role I often think of the guest database principal (user) at the same time. They aren’t really the same though. For one thing while you can’t remove either one, you can disable the guest and in fact for user databases this is recommended.
Let me stop here and emphasise this. Disabling guest in the user databases is recommended. Not the system databases. Guest is used for a number of things in master, msdb and tempdb. model I’m not so sure about since while this is the template for new user databases, it’s also the template for tempdb so it could cause problems, I’m just not sure.
How do you disable guest
Simply enough you remove the CONNECT permission.
REVOKE CONNECT FROM guest;
What is guest?
So what exactly is guest? It’s the default user. If you don’t have a database principal in a given database you can still connect using guest. Once there you have any permissions granted to guest, public, and any other AD groups you may belong to. Note: Even though they don’t have CONNECT (meaning you can’t connect to the database) you can still belong to an AD group with other permissions in the database. In fact that AD group could be an orphan (no associated server-level principal) and you’ll still be able to use its permissions.
Interesting point here, guest is only if you don’t have another user in the database. As soon as you have another user you no longer have access to any permissions associated with guest.
Generally using guest
-- Make sure guest is enabled. GRANT CONNECT TO guest; -- Grant read access to guest to make this a bit more obvious ALTER ROLE db_datareader ADD MEMBER guest; GO -- Confirm that SQLTest doesn't have permissions. exec sp_DBPermissions 'Test', 'SQLTest';
USE master; GO -- You have to impersonate as the login, not the user. -- The user doesn't exist. EXECUTE AS LOGIN = 'SQLTest'; GO USE Test; GO SELECT * FROM sys.user_token; GO
If you have a user you aren’t a guest.
exec sp_DBPermissions 'Test', 'Kenneth_Test', @UseLikeSearch=0;
USE Test; GO -- I can execute as the user this time because the user exists EXECUTE AS USER = 'Kenneth_Test'; GO SELECT * FROM sys.user_token; GO
So when might you use guest? Well, similar to when you might use public. When you want everyone to be able to connect to a database. For example an audit database or something.