When to assign db_owner role to database users - sql-server

This is a long question, but please bear with me as I believe it raises important issues about database ownership and access.
I manage and internationally market a "universal" geothermal data management program, written in Delphi, that is a front end to a SQL Server database. The data in the database is derived from many diverse measurements generated and used by the program users over time periods of 30 years or more - i.e. they "own" the data, and the database is primarily a way to efficiently store and manage the data.
Like all databases, the database structure needs to be modified from time to time, including new tables, and this modification is delivered by the release of a new version of the program. The program prompts for a database upgrade, which has to be carried out by a dbo user so that all new tables can be accessed by the other program users. Unfortunately, the program may be used in remote sites and the IT personnel may not be readily available, so that the new version may get installed but the databases are not upgraded. What has frequently happened in such locations is that a program user will upgrade the databases without appropriate SQL Server permissions, and then the other users cannot access the new tables and the program crashes.
One of the program customers has taken another approach. They have created a db_owner role for all the databases used by the program and then make all program users members of the db_owner role. The program has inbuilt permission levels that can restrict the ability to upgrade databases, so normally only one or two users have this permission. However, with everyone a member of the db_owner role, it doesn't matter who upgrades the database, all tables will be accessible to all program users.
The advantage of this approach include the following:
Access permissions can be granted by the group who uses the program, and who has ultimate responsibility for the database.
Knowledge and understanding of the program is passed on within the program users group when staff changes, rather than relying on the IT department as the repository of information on "how it works" (and often they do not know).
Direct data-mining and back-door data modification is possible to selected user experts. While the program has extensive datasearch and editing tools, sometimes these are not enough and the users need hands-on access.
The program users retain "ownership" of their data.
I would appreciate your comments. I believe that in circumstances such as these, it is important that all the database users are db_owners, and the group of users controls access. Not allowing db_owner roles (a strategy commonly employed by IT departments) fails to recognize the importance of data ownership and data accessibility, and the responsibility of the database users to manage their own data.

The way you've stated your question makes it sound like you've already arrived at a conclusion. The one question that I always ask when someone comes to me (a DBA) with this sort of situation is: if someone accidentally deletes data, am I on the hook to get it back? If the answer is "yes", then they don't get db_owner. If the answer is "no", then the db gets moved to its own server and I get the contract in writing.

The only time I wouldn't bother with access control would be with a simple app running on a local single-user database like SqlExpress. As soon as there are multiple users on a centralised database and important data to protect, restricted access is important. I'm not familiar with your domain (geothermal data management), but surely this data is important to your customers, from integrity, tampering and even a data access point of view (theft of data could be resold to a competitor).
the program may be used in remote sites and the IT personnel may not
be readily available, so that the new version may get installed but
the databases are not upgraded
(i.e. I'm assuming an upgrade script needs to be manually and independently run on the database). It is common nowadays for apps to check the database for schema versioning and even for static data population, e.g. Entity Framework code-first migrations on the .net stack. The app will then have the ability to actually perform the schema and data upgrade automatically. It should be quite straightforward for you to add the last N versions of your DB upgrade scripts into your app and then do a version check? (Obviously the app itself would need to prompt for dbo access, assuming that even the app should not have dbo access).
with everyone a member of the db_owner role, it doesn't matter who
upgrades the database
I believe this may place unnecessary responsibility (and power) in the hands of unqualified customer users.
Even the ad-hoc data mining (SELECT) access should be reconsidered, as a badly formed query without consideration can cause performance degradation or block other concurrent writers. If nothing else, providing a few well formed views will at least ensure decent query plans.
/10c

Related

Add a security layer to our SQL Servers (currently accesible from remote sql management studio)

We have a big system running with thousands of users (some from android apps, other from the web app, etc.).
The system is distributed, with databases in two locations (within the same country). In one location there are 5 servers in the same network, and each one has a copy of the database (via replication).
Among the software developers, a few have direct access to the production databases. Sometimes due to technical support requested by users to modify some operations not possible from the system itself, the developers/support team have to access the database directly and modify some records.
We know this is not the ideal manner of working. But it's been like this since years.
Recently we have found a few problems. One day one person updated hundreds of records from a table by mistake.
Since then we are analyzing how to improve this access.
We are looking for some way of improving the security. We would like to have a two-phase authentication system in place. Something that asks the user for two passwords when accessing from Sql Server Management Studio...
Is that possible? Or is there any other approach we can use to improve the security but still allow devs/support team to access the production database when necessary?
Users also (currenty) have access via remote desktop to all servers.
At least we would like to KNOW when this access is being done.
Make access to PROD read only for those users. Allow them to write their scripts and then submit them for review at a minimum and testing if possible like any other deployable. Then follow standard deployment processes with someone who has access.
If my other answer isn't workable and these updates are always the same kind of fixes...you could create support stored procs maybe to do the fixes and only give permission on the procs...but this is highly dependent on the commonality of fixes being made and less preferable to my other answer.
I haven't used it myself but EXECUTE AS might let you give the users read-only permission while the procs would execute under credentials with higher access.

How to prevent windows administrator to attach ms sql database

Background: [No copyright implementation]
[No copyright implementation] My company develops inventory control application for clients in the area where we don't have copyright protection by the government. The only option is to hide and protect things by ourselves. It is common for competitors here to copy other company's database and build front end on it and then start selling their own app.
The Problem
We use MS SQL server express edition and some times standard edition. We have found that any of customer can stop sql engine, copy the files from the pc where application was installed and then attach that database files into another system where they have full windows admin rights and that's it they can fully explore our database.
I am looking for
Is there any reliable solution to protect our database design being viewed by other people. Only our application may connect through the users we have created inside the db?
In past i had heard that sybase adaptive server has such functionality, windows users had no access in it and users were stored inside each db itself. there was no way to login if someone don't have password of the users stored in db itself.
Thanks
Your help will be highly appreciated.
As suggested by Sean, hosting it yourself or in a cloud service like Azure SQL DB is your best bet. Still no guarantee but makes it significantly harder to get everything but a lot easier to lockdown than alternatives. It's also a lot easier to manage and handle user requests for restricted data compared to something deployed onsite.
Outside of that, there's really no practical way to do it if deployed at the customer's site. Even if you lock down all logins and users (regardless of Windows or SQL Server logins) so no customer login has admin level privileges, you still can't prevent them from copying the database file, mounting it on a different instance where they have admin privileges or even just running it as an app to reset SA password. If they have physical access, all bets are off. It's only a matter of knowledge and time.
You can make it harder by encrypting the entire database and only your app holds the key. Users then have to either break the encryption algorithm (hard if done right) or your application that holds the key (easier but still not trivial). Both are expensive to do correctly and they really just delay, not prevent access. You will also introduce other problems like key management and rotation which, if not done right can result in customers losing access to their data.
You could leave a cookie trail (e.g. functions and tables that are active,look like they're part of the app and are tightly coupled to useful parts of the app but actually aren't related to the application's core functionality). That makes it easier to prosecute later but if the country has no laws protecting intellectual property, this will only be useful if the software is re-used or resold in a country that has such laws.

why are multiple DBs actually needed?

I was looking at godaddy.com which says they offer up to 10 MySQL DBs, but I don't know why you would need more than 1 ever since a DB can have mutliple tables. Can't multiple DBs be integrated into a single DB? Is there an example case where its better or unfeasible to not have multiple ones? And how do you differentiate between them when you want to call them, from their directory or from a name?
Best,
I guess separation of concerns would be the most obvious answer. In the same way you can have all of your functionality in one humongous class in object oriented programming, it's a good idea to keep non-related information separate. It's easier to wrap your head around smaller chunks of data, and future developers mights start to think tables are related, and aggregate data in a way they were never meant to.
Imagine that you're doing two different projects with two different teams. Maybe you won't one team to access the other team tables.
There can also be a space limit in each database, and It each one can be configured with specific params to optimize the performance.
In other hand, two final users can be assigned to make the backups of each entire database, and you wan`t one user to make the backup of the other DB because he could be able to restore the database in other place and access the first database data.
I'm sure there are some pretty good DBAs on the forum who can answer this in detail.
Storing tables in different databases makes because you are able to backup them up individually. Furthermore, you will be able to control access to each database under different NT groups (e.g. Admin vs. users). Although this can be done at the indvidual table level, sometimes it makes sense to grant or deny access to an entire database to a particular group.
When you need to call them in SQL Server you need to append the database name to the query like this SELECT * FROM [MyDatabase].[dbo].[MyTable].
One other reason to use separate databases relates to whether you need full transactional recovery or not. For instance, if I havea bunch of tables that are populated on a schedule through import processes and never by the users, putting them in a separate database allows me to set the recovery mode to simple which reduces the logging (a good thing when you are loading millions of records at once). I can also not do transactional log backup every fifteen minutes like I do for the data in the database with the user inserted data. It could also make recovery a faster process when needed as the databases would be smaller and thus individally take less time to recover. Won't help much when the whole server crashes but it could help a lot if onely one datbase gets corrupted for some reason. If the data relates to different applications, it simplifies the security as well to have the data in separte databases. And of course sometimes we have commercial databases and we can;t add tables to those and so may need a separate database to handles some things we want to add to that data (we do this for instance with our Project Management software, we have a spearate database where we extract and summarize data from the PM system for reporting and then write all our custome reports off that.)

How to protect a database from the Server Administrator in Sql Server

We have a requirement from a client to protect the database our application uses, even from their local administrators (Auditors just gave them that requirement).
In their requirement, protecting the data means that the Sql Server admin cannot read, nor modify sensitive data stored in tables.
We could do that with Encryption in Sql Server 2005, but that would interfere with our third party ORM, and it has other cons, like indexing, etc.
In Sql Server 2008 we could use TDE, but I understand that this solution doesn't protect against a user with Sql Server admin rights to query the database.
Is there any best practice or known solution to this problem?
This problem could be similar to the one of having an application hosted by a host provider, and you want to protect the data from the host admins.
We can use Sql Server 2005 or 2008.
This has been asked a lot in the last few weeks. The answers usually boil down to:
(
a) If you don't control the application you are doomed to trust the DBA
or
b) If you do control the application you can encrypt everything with a key only known to the application, and decrypt on the way out. It'll hurt performance a bit (or a lot) though, that's why TDE exists. A variant of this to prevent tampering is to use a cryptographic hash of the values in the column, checking them upon application access.
)
and
c) Do extensive auditing, so you can control what are your admins doing.
I might have salary information in my tables, and I don't want my trusted dba's to see.
Faced with the same problem we have narrowed are options to:
1- Encrypt outside SQLServer, before inserts and updates and decrypt after selects. ie: Using .net encryption.
Downside: You loose some indexing and searching capabilities, cannot use like and betweens.
2- Use third party tools (at io level) that block crud to the database unless a password is provided. ie: www.Blockkk.com
Downside: You will need to trust a third party tool installed in your server. It might not keep up with SQL Server patches, etc...
3- Use an Auditing Solution that will keep track of selects, inserts, deletes, etc... And will notify (by email or event log)if violations occurred. A sample violation could be a dba running a select on your Salaries table. then fire the dba and change everyone salaries.
Auditors always ask for this, like they ask for other things that can never be done.
What you need to do is put it into risk-mitigation terms and show what controls you do have (tracking when users are elevated to administrators, what they did and that they were de-elevated afterwards) instead of in absolutes.
I once had a boss ask for total system redundancy without defining what he meant or how much he was willing to pay and sacrifice.
I think the right solution would be to only allow trusted people be DBA's.
It is implicit in being DBA, that you have full access, so in my opinion, your auditor should demand that you have procedures for restricting who has DBA access.
That way you work with the system through processes in stead of working aginst the system (ie. sql server).
To have person you don't trust be DBA would be nuts...
If you don't want any people in the admin group on the server to be able to access the database, then remove the "BUILTIN\Administrators" user on the server.
However, make sure you have another user that is a sysadmin on the server!
another way i heard that a company has implemented but i haven't seen it is:
there's a government body which issues kind of timestamped certificate.
each db change is sent to async queue and is timestamped with this certificate and is stored off site. this way noone can delete anything without breaking the timestamp chain.
i don't know how exactly this works on a deeper level.

How would you migrate hundreds of MS Access databases to a central service?

We have literally 100's of Access databases floating around the network. Some with light usage and some with quite heavy usage, and some no usage whatsoever. What we would like to do is centralise these databases onto a managed database and retain as much as possible of the reports and forms within them.
The benefits of doing this would be to have some sort of usage tracking, and also the ability to pay more attention to some of the important decentralised data that is stored in these apps.
There is no real constraints on RDBMS (Oracle, MS SQL server) or the stack it would run on (LAMP, ASP.net, Java) and there obviously won't be a silver bullet for this. We would like something that can remove the initial grunt work in an automated fashion.
We upsize (either using the upsize wizard or by hand) users to SQL server. It's usually pretty straight forward. Replace all the access tables with linked tables to the sql server and keep all the forms/reports/macros in access. The investment in access isn't lost and the users can keep going business as usual. You get reliability of sql server and centralized backups. Keep in mind - we’ve done this for a few large access databases, not hundreds. I'd do a pilot of a few dozen and see how it works out.
UPDATE:
I just found this, the sql server migration assitant, it might be worth a look:
http://www.microsoft.com/sql/solutions/migration/default.mspx
Update: Yes, some refactoring will be necessary for poorly designed databases. As for how to handle access sprawl? I've run into this at companies with lots of technical users (engineers esp., are the worst for this... and excel sprawl). We did an audit - (after backing up) deleted any databases that hadn't been touched in over a year. "Owners" were assigned based the location &/or data in the database. If the database was in "S:\quality\test_dept" then the quality manager and head test engineer had to take ownership of it or we delete it (again after backing it up).
Upsizing an Access application is no magic bullet. It may be that some things will be faster, but some types of operations will be real dogs. That means that an upsized app has to be tested thoroughly and performance bottlenecks addressed, usually by moving the data retrieval logic server-side (views, stored procedures, passthrough queries).
It's not really an answer to the question, though.
I don't think there is any automated answer to the problem. Indeed, I'd say this is a people problem and not a programming problem at all. Somebody has to survey the network and determine ownership of all the Access databases and then interview the users to find out what's in use and what's not. Then each app should be evaluated as to whether or not it should be folded into an Enterprise-wide data store/app, or whether its original implementation as a small app for a few users was the better approach.
That's not the answer you want to hear, but it's the right answer precisely because it's a people/management problem, not a programming task.
Oracle has a migration workbench to port MS Access systems to Oracle Application Express, which would be worth investigating.
http://apex.oracle.com
So? Dedicate a server to your Access databases.
Now you have the benefit of some sort of usage tracking, and also the ability to pay more attention to some of the important decentralised data that is stored in these apps.
This is what you were going to do anyway, only you wanted to use a different database engine instead of NTFS.
And now you have to force the users onto your server.
Well, you can encourage them by telling them that you aren't going to overwrite their data with old backups anymore, because now you will own the data, and you won't do that anymore.
Also, you can tell them that their applications will run faster now, because you are going to exclude the folder from on-access virus scanning (you don't do that to your other databases, which is why they are full of sql-injection malware, but these databases won't be exposed to the internet), and planning to turn packet signing off (you won't need that on a dedicated server: it's only for people who put their file-share on their domain-server).
Easy upgrade path, improved service to users, greater centralization and control for IT. Everyone's a winner.
Further to David Fenton's comments
Your administrative rule will be something like this:
If the data that is in the database is just being used by one user, for their own work (alone), then they can keep it in their own network share.
If the data that is in the database is for being used by more than one person (even if it is only two), then that database must go on a central server and go under IT's management (backups, schema changes, interfaces, etc.). This is because, someone experienced needs to coordinate the whole show or we will risk the time/resources of the next guy down the line.

Resources