Cloaking databases from different users

  • We have several customers for whom we will soon begin allowing read access directly to our databases. When they connect via Sql Server Visual Management Studio to our database engine, we'd like them to only see the databases listed on the left that they've got permissions to access. Is there a way to do this without creating a named instance for each customer?

    thanks in advance for any ideas you might propose.

    seth

  • It's the default behavior. If they can't access it they shoudln't be able to see it.

    If they do you probably messed up something.

  • On the other hand.

    Any reason you're not doing some sort of replication to a 2nd server so they can't mess with production?

  • These customers need read access to the production database and we don't have the hardware or software licenses available to create a replication environment.

    The default behavior for a login created in the database engine is that it can see all the databases on the server even though it is mapped for read permission to only a single database.

    seth

  • the command you are looking for is this snippet to hide databases the end user doesn't have access to:

    DENY VIEW ANY DATABASE TO [SomeUserOrRole]

    here's some testable code to prove it.

    IF NOT EXISTS (SELECT * FROM MASTER.dbo.syslogins WHERE name = N'DbViewerTesting')

    BEGIN

    EXEC MASTER.dbo.sp_addlogin @loginame = N'DbViewerTesting', @passwd = 'NotARealPassword', @defdb = N'master', @deflanguage = N'us_english'

    --add this user to permit read and write

    END

    EXECUTE AS LOGIN='DbViewerTesting'

    USE master

    GO

    select * from master.sys.databases -- see them all!

    REVERT;--turn back into SuperMan

    DENY VIEW ANY DATABASE TO DBVIEWERTESTING

    EXECUTE AS LOGIN='DbViewerTesting'

    USE master

    GO

    select * from master.sys.databases -- see master and temp only!

    REVERT;--turn back into SuperMan

    DROP LOGIN DbViewerTesting

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Lowell (9/23/2011)


    the command you are looking for is this snippet to hide databases the end user doesn't have access to:

    DENY VIEW ANY DATABASE TO [SomeUserOrRole]

    [/QUOTE]

    Thank you very much for this example! I wasn't aware of the view any database privilege. I looked up the microsoft docs on it, and it looks like that privilege isn't very granular. It says the user who has been denied 'view any database' will only see the databases to which the user is an owner. I added my customer's login as an owner of the appropriate database, but with the deny view any database applied, the user doesn't "see" any of the databases in the object explorer. If the user does a "use databaseXYZ", then the query window switches to the appropriate database, but this isn't especially intuitive. I've got to make this as simple as possible for this breed of user....

    ideas?

    -- mtf

  • Have the default database login for the user changed to their database? Unless they set it in their connection setting.

  • Jo,

    That's a good suggestion, and I have done that, but in this scenario, each customer will have multiple databases.

    From the research I've done, this looks to be a limitation on SQL Server 2008. I guess I'll have to suffer the unintuitiveness of them not being able to see their own databases within the object explorer.

    Thanks to everyone for their suggestions!

    -- Seth Johnson

  • Seth when i change the database owner, i seem to see exactly what id'd expect...two more databases

    using my same code from above:

    DENY VIEW ANY DATABASE TO DBVIEWERTESTING

    USE SandBox

    GO

    exec sp_changedbowner DbViewerTesting

    USE PERFECT1000

    GO

    exec sp_changedbowner DbViewerTesting

    EXECUTE AS LOGIN='DbViewerTesting'

    USE master

    GO

    select * from master.sys.databases -- see master,temp,SandBox and PERFECT1000 only!

    REVERT;--turn back into SuperMan

    DROP LOGIN DbViewerTesting

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Lowell,

    I can't grant dbowner role to these users or else then they'd be able to write to the db or make other changes. I've got these users tied down to datareader role... Unless you know of a way to restrict a dbowner from making changes, I don't think that will work.

    -- seth

  • Lowell,

    I received permission from the organization here to allow the customer user to be dbowner. I thought I'd try the method you suggested in this snippet, but I receive an error. What permissions do I need to change on the DB to enable this 'DbViewerTesting' user to see the DB?

    Lowell (9/23/2011)


    here's some testable code to prove it.

    IF NOT EXISTS (SELECT * FROM MASTER.dbo.syslogins WHERE name = N'DbViewerTesting')

    BEGIN

    EXEC MASTER.dbo.sp_addlogin @loginame = N'DbViewerTesting', @passwd = 'NotARealPassword', @defdb = N'master', @deflanguage = N'us_english'

    --add this user to permit read and write

    END

    EXECUTE AS LOGIN='DbViewerTesting'

    USE master

    GO

    select * from master.sys.databases -- see them all!

    Here is the error message this part of your code generates on my system:

    Msg 916, Level 14, State 1, Line 1

    The server principal "DbViewerTesting" is not able to access the database "<the database name>" under the current security context.

    (5 row(s) affected)

    thanks in advance for any ideas,

    mtf

  • mrTexasFreedom (9/29/2011)


    Lowell,

    I received permission from the organization here to allow the customer user to be dbowner. I thought I'd try the method you suggested in this snippet, but I receive an error. What permissions do I need to change on the DB to enable this 'DbViewerTesting' user to see the DB?

    Here is the error message this part of your code generates on my system:

    Msg 916, Level 14, State 1, Line 1

    The server principal "DbViewerTesting"

    is not able to access the database

    "<the database name>"

    under the current security context.

    (5 row(s) affected)

    thanks in advance for any ideas,

    mtf

    ok, looks like you've done the DENY VIEW so that's just one peice;

    somehwere you needed to run this to make them the owner:

    USE "<the database name>"

    GO

    exec sp_changedbowner 'DbViewerTesting'

    once that is done, you should see they can see their database.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Lowell,

    When I execute the syntax you suggested, it seems to never complete. Should it really take a long time for this stored proc to finish?

    USE <database name>

    GO

    exec sp_changedbowner 'DbViewerTesting'

    mtf

  • you need exclusive access to the database in order to change the owner...so if someone is in it, the query waits for them.

    you'll need to wait till someones not in it, or kick everyone out for the two seconds it takes to run the command and let them back in...might not be allwoed to do that on a production system.

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!

  • Lowell (9/29/2011)


    you need exclusive access to the database in order to change the owner...

    So the goal here is to actually change the owner rather than add the user to the dbowner user mapping for the database? That must be what you're suggesting, because when I add dbowner mapping to this user in the login properties, the user still can't see the database in the object explorer after connecting.

    I'll verify this with a non-production DB and get back to you on the results shortly.

    Appreciatively,

    mtf

Viewing 15 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic. Login to reply