In SQL Server 2005, a snapshot of a database can be created that allows read-only access to a database, even when the database is in "recovery pending" mode. One use case for this capability is in creating a reporting database that references a copy of a production database, which is kept current through log-shipping.
In this scenario, how can I implement security on the "snapshot" database that is different from the "production" source database?
For example, in the production database, all access to data is through stored procedures, while in the snapshot database users are allowed to select from table in the database for reporting purposes. The problem the I see is that security for the snapshot database is inherited from the source database, and can not be changed because snapshots are strictly read-only.
Are you able to manage permissions on this database? Would adding a separate user who only has read access to a database be sufficient for this type of scenario? This could be a read-only user on the main database, but is only effectively used on the snapshot db.
i.e. Add a new user, readerMan5000 who is only given select access, to the database in question. Then require users to authenticate through that new credential.
Note to future commenters, you may want to read:
http://www.simple-talk.com/sql/database-administration/sql-server-2005-snapshots/
or
http://msdn.microsoft.com/en-us/library/ms187054(SQL.90).aspx
before you open your big mouth like me. :)
You can't change permissions after you take the snapshot, but here's one workaround: instead of having them access the tables directly, require them to use views instead. If the views are used only for reporting, then you can set tight security on them in the original database, and then have the users hit those views in the snapshot. You'll need to restrict access on the underlying tables though if you want it to be effective.
Related
I'm curious if there is a way for a user to use a view in database A (they have permission to database A) that accesses tables in database B (and/or additional databases they don't have permission to) without the user having access to database B?
My scenario:
We currently have a database (database A) where most of the views are housed. Most users across the team also have access to database A. We are wanting to split out our data tables from database A into their own databases (on the same server). When we do this, of course, the views will break because the tables they access will now be in database B. Since there are so many views, I'm looking for an easier way. My thought was to use database A as the hub for the views and as the views are accessed, permissions are granted to the various databases for the user(s) - without giving them direct access to the other databases.
Thank you in advance.
I think a database role would be better than a database as the container for view access.
It might be easier to delete objects than to move them. A backup-restore can create a copy of the database. Then delete the tables and views that don't belong in each database.
Cutting corners on security or integration can come back to bite. If the tables are distinctly part of different systems, then the views should go with the tables. Security and integration between systems by cross database references will tie all those systems to the same server. (Linked servers would be a performance and DTC nightmare.) We have several "separate" justice applications (e.g., DA, Public Defender, Probation, etc.) that do this. Security is still detailed via the use of database roles for each use. The integration is great, but it's a nightmare to migrate because it's all at once and together. If done correctly (e.g., connections strings to each database), we would be able to move one database at a time and update and test one system at a time. As it is now, it takes a lot of project management and a long time to get everybody ready.
If the tables are part of the same system, then schemas could be an option to segregate them if database roles are to tedious to manage. Is it more work to segregate the objects into databases or schemas than to manage a role?
Also, if you use SSDT db projects, then those cross database references (circular?) can be a pain.
For security, I would suggest a database role for each group that needs access. There is no "magic" database level container just for views. The best you can do is SELECT which includes tables and views. For just views, a script is not hard to create to grant a db role select access to all views in the db. I would not ever use grant select and then a DENY on tables because it can prevent access to table for users that should have access. If one or more schemas are used for the views, a role can be granted SELECT access to the schema. This might be the best option. If the view schema and the objects accessed by the view have the same owner, the ownership chain should allow access via the view to tables. For example, if the "view" schema is owned by "dbo", views in the "view" schema should be able to access tables in the "dbo" schema without the user being granted access to those tables. (I have not tried it.)
It would be nice if there was a second flavor of INSERT, UPDATE, etc. permissions that applied to views only, but there isn't.
I need to restore the database from a different environment where different logins are used but I want to keep permission to this database for already existing login on this server.
Now, after restoring my login on the targeted server it lost mapping for this database (and owner role)
I want to restore everything inside the database and same time I don't want to map the database and add owner role to the login.
Is it even possible?
I've tried different ways of restore - deleting before restore, as well as delete but not to close existing connections. The result is the same, I need to map new restored DB again and add the owner role.
Normally database users have to be mapped to instance logins to work, but if you want to make your DB more instance independent and control your database from the inside of it then the solution for you would be a Contained Databases.
From MS BOL:
A contained database is a database that is isolated from other
databases and from the instance of SQL Server that hosts the database.
SQL Server 2017 helps user to isolate their database from the instance
in 4 ways.
Much of the metadata that describes a database is maintained in the database. (In addition to, or instead of, maintaining metadata in the
master database.)
All metadata are defined using the same collation.
User authentication can be performed by the database, reducing the databases dependency on the logins of the instance of SQL Server.
The SQL Server environment (DMV's, XEvents, etc.) reports and can act upon containment information.
I'm trying to implement security on our applications (which consist mainly of websites using SQL Server stored procedures).
Microsoft seem to suggest that best practice is to wrap all data functionality in stored procedures which we have done. Our structure is something like:
SQL Server database - [data1]
SQL Server database - [webSPs]
PHP / Symfony web apps
All the data resides in tables in [data1] and on the same server is another 'database' which just contains the stored procedures used by the web apps.
The SQL Server has a login 'webapp' which, as a user on [webSPs], has permissions just to run the stored procedures in [webSPs].
However, as these stored procedures read, write, append data on the [data1] tables, this user has to be a member of db_datawriter and db_datareader database roles in [data1].
This all works fine, but it seems there is a hole in the security here, as its then possible for a user accessing [webSPs] to not only run the stored procedures but write to any underlying table - is it possible to give permission that say something like:
you can read/write to tables on this database but only through SPs - not directly
From what I've read, I think it would work as I hoped if there wasn't the second database which I guess is breaking ownership chaining.
Thank you in advance.
Yes, but it's frankly a pain to implement. You can use module signing. Essentially, you:
Create a certificate in your WebSps database.
Backup and restore the certificate to the data1 database
Create a user from the certificate
Grant whatever read and write permissions to the certificate-based user in data1
Sign any stored procedure you want to use cross-database with the certificate by calling the add signature syntax
Keep in mind that every time that you change the procedure (either via alter or drop and create), the signature gets lost. So you'll be in a constant cycle of re-signing. You can read more about the process of module signing here
I have MS Access as a front end and PostgreSQL as back end for my database. So I set up the database in PostgreSQL and linked the tables to MS Access using the ODBC drivers. Everything works great, I can update the tables in MS Access and the record will appear in Postgres database.
Since I can still see the linked tables in MS Access, I feel like it is possible for some users to go in and manually modify the tables without filling out proper forms. Is it possible to HIDE the tables or lock the tables so that Access users cannot modify the raw data at all? If not, what can I do to secure the integrity of the database.
Thanks!
I would recommend looking at Postgres privileges as a way to lock the tables down.
In short, you could have your backend run as one user that has full access permissions on the tables in question, and when the users login to the app, they would be connected to Postgres using a user whose privileges are considerably more locked down (say, read only if you just want to be able to do SELECTs to surface data).
For example, you could run the following SQL against your Postgres server:
REVOKE ALL ON accounts FROM joe;
GRANT SELECT ON accounts TO joe;
Which would first remove all privileges from the user joe for the table accounts, and then allow only SELECT priveleges for that table.
You could do something similar for all the tables you wish to lock down. You'll also need to do the same for the sequences used by those tables.
You may wish to create a special readonly user which has only read access across the board, and use those credentials to surface the Postgres data for the users to access.
When you need to alter data, your backend could specifically use a power user of sorts which has much greater access.
Here's a link which details creating a readonly Postgres user (for purposes of backups in this case, but the general concept and the SQL commands should apply (just ignore the stuff about pg_dump).
If you aren't concerned about users' ability to modify the data in those tables via the up other than in the ways that are authorized, but are only concerned about them using, say, psql to go in and update them, then you probably don't need a readonly user, but can simply lock the tables down and have the backend use that user with sufficient access.
This afternoon I was reviewing the security for a user in my SQL Server, in SQL Server Management Studio. I opened the Database User's Properties dialog, and went to the Securables section.
As I was cycling through the tables and stored procedures that this particular user had access to, I noticed that one of the data tables had the the Update option checked in an intermediate state. What does that mean? You can either update a row, or you can't. There is no in-between. I've included an image for reference. I would just fully check this option and save it but I'd rather not screw with the DB if this serves a worthwhile purpose.
I believe that means that that permission has been inherited and wasn't explicitly set for that user.
The GRANT statement can assign
permissions to a group or role that
can be inherited by database users.
http://msdn.microsoft.com/en-us/library/bb669084.aspx
I'm trying to find something that specifically spells out that's what the checkbox looks like in the above situation.