User Privileges - oracle

Why does a user needs privileges over his own schema to create packages and triggers?

Are you asking why users need particular priviliges (i.e. CREATE TABLE, CREATE PROCEDURE, etc) in order to create particular types of objects in their own schema?
If so, the natural answer would be that good security begins with the principle of least privilege-- that is, a user should only have those privileges that they truly need to do their job and no more. DBAs frequently want to create read-only accounts for users in the production database (business analysts, for example, often need to do different sorts of ad hoc reporting, developers may need access to troubleshoot certain types of problems, etc). If a user were always able to create objects in their own schema, those read-only users would suddenly be able to deploy code to the production database without going through change control or even necessarily testing anything. And that generally leads to a proliferation in code doing basically the same thing (i.e. a dozen analysts each have a procedure to calculate sales tax in their own schemas) but each of which has its own unique signature, logic, requirements, assumptions, etc. And heaven forbid that one of those analysts get fired because the DBA would naturally delete their account, only to find out that some crucial report depended on code that existed only in that analyst's schema.

I can't give you the "official" answer, but I can take a stab at the reasoning behind how it works. On the project I work on, Oracle Developers are the ones that deploy the triggers and packages into the database schema. But we have other teams of Java developers and testers, etc. Once the schema are migrated into the Test and then Production environments, we don't want the testers or the end user applications to be able to arbitrarily modify the triggers and packages associated with that schema, as that could invalidate the integrity of any testing they are doing (or cause even worse issues on the production system).
So within the test/production environments, you want the testers, the Java developers, and the end-user application to be able to read and write data to the schema, but not modify the triggers and packages which encompass the baselined code.

Why does a user needs privileges over
his own schema to create packages and
triggers
They do not.
Their own schema implies the ownership (or namespace) defined by username.object
All a user needs to create a trigger in their own schema is:
a table in their own schema
the create trigger privilege
All a user needs to create a package in their own schema is:
the create package privilege
If the user wants to create objects in another schema or that references other objects, or that requires storage in a tablespace then they will need permissions on those foreign objects.

Related

How can people collaborate in the same Oracle DB schema?

We are a team of tens of data analysts. Our main data back-end is an Oracle database. We use personal schemas to do work where we don't need to collaborate with others and we would like to create schemas dedicated to projects where people need to collaborate.
The problem is that in Oracle, one schema is equivalent to one DB user. If we create a schema dedicated to a project, for the purpose of creating DB objects in the context of that project, there will be a single set of credentials (username + password) that needs to be shared by all team members. This has two inconveniences:
if people mistype the credentials, they can block the account for everyone;
it is no longer possible to monitor who did what for security/audit reasons, since everyone uses the same schema;
An alternative would be that only one person uses the Schema user to create objects and assigns privileges to other people in those objects, but that can become quickly cumbersome.
Another alternative is to interact with the DB through R or Python but that means the credentials will be stored in some text file, which is bad for security.
As we see it, the ideal situation is if multiple personal DB users can create objects in the same schema, and if those objects are automatically available for that set of DB users. Is this totally impossible in Oracle? Is this impossible in any major DB? Is this requirement somehow flawed and as such, there is a good reason for why it is not available?
We could compare this collaboration in a DB schema to what commonly happens with people collaborating in a folder, using R, Python or other programming language for data analytics.
Thank you for your advise!
Maybe I miss something but could you not just create a schema that will be used for all users and grant the required privileges to each individual user?
Each user authenticates with his local account and by default uses his local schema and to access the public one you just use the ALTER SESSION SET CURRENT_SCHEMA command.

Drop SYS and SYSTEM accounts, good idea?

I'm new to Oracle and I'm currently hardening a database.
It's a good idea to drop SYS and SYSTEM users? normally default accounts are dropped because of security reasons, I can do that on Oracle, or I will break something?
From the documentation (emphasis added):
All databases include the administrative accounts SYS, SYSTEM, and DBSNMP. Administrative accounts are highly privileged accounts, and are needed only by individuals authorized to perform administrative tasks such as starting and stopping the database, managing database memory and storage, creating and managing database users, and so on. You log in to Oracle Enterprise Manager Database Express (EM Express) with SYS or SYSTEM. You assign the passwords for these accounts when you create the database with Oracle Database Configuration Assistant (DBCA). You must not delete or rename these accounts.
And:
All base (underlying) tables and views for the database data dictionary are stored in the SYS schema. These base tables and views are critical for the operation of Oracle Database.
So no, it is not a good idea, and it would destroy your database.
normally default accounts are dropped because of security reasons, I can do that on Oracle, or I will break something?
The first documentation link above also says (emphasis added again):
All databases also include internal accounts, which are automatically created so that individual Oracle Database features or components such as Oracle Application Express can have their own schemas. To protect these accounts from unauthorized access, they are initially locked and their passwords are expired. (A locked account is an account for which login is disabled.) You must not delete internal accounts, and you must not use them to log in to the database.
And it mentions sample schema accounts, which you can choose not to install in the first place, but which could be dropped if required.
The main thing is to secure all accounts, and you should limit any accounts you create to only have the minimum privileges necessary.
You can also read more about this in the database administrator's guide,
It is a very bad idea. I don't think the database will even work without them and doubt that the drop is allowed. Make sure the accounts are safe instead.

temporarily disabling access to a schema in Oracle : lock account vs revoke grant

I have a usecase where I need to block access to all objects in a schema temporarily while I perform some massive changes. I plan to perform the changes as the schema owner. Once I am done I want to enable access back. I am currently exploring two options and would like to know your thoughts as to which one works better :
Lock all accounts that go against the database objects in target schema.
Revoke grants on the database objects and hence preventing external users from using it.
Is there are better way? I want the process to be as smooth as possible and insure that no one is able to get to the target schema while the change is going on
Trigger. This trigger works for everybody except the user with dba role.
CREATE OR REPLACE TRIGGER logon_audit_trigger
AFTER LOGON
ON DATABASE
DECLARE
BEGIN
raise_application_error (-20001, 'You cannot login.');
END;
If you want to know who and where is trying to login. You can get thses information from SYS_CONTEXT.
SELECT SYS_CONTEXT ('USERENV', 'SESSION_USER')
FROM DUAL;
You could consider to quiesce the database. The downsides to locking out users or revoking permissions is that users will receive errors (you don't have access or you can't login, etc...). Quiesceing the database means that active sessions will finish their work, but then will hang until the database is un-quiesced. Then, you perform your modifications and will be guaranteed that nothing can block your exclusive access to the objects you are updating. After your update (or even during your update after you have the lock on the object in question), unquiesce the database.
Of course, the downside to this approach is that this is across the entire database instead of to just one schema. The advantage to this is that your users won't experience any error messages, and if you turn your DML into DDL (as described below) to greatly speed up the downtime window, the majority of your users shouldn't experience much more than a few seconds of inactivity.
There is a good write up on quiesceing the database at Oracle FAQ. You would have to get your DBA's involved to both quiesce the database and to put your changes live as only system or sys can perform this operation.
For DML, you could consider creating a new table with the data that you want before the downtime window starts. Then when the downtime window starts, rename the old table, rename the new table as the old table, recreate the permissions, for a much faster downtime window (since this effectively turns a DML update into DDL). Tom Kyte has a discussion of this approach here.
Also, it goes without saying that proper testing in a testing environment of the above procedures should be done, which will iron out any gotchas in this process and give you a pretty good idea of how long the system will need to be quiesced for.

Oracle Security - how to prevent a User from DROP TABLE its own tables

As security tightening exercise, I'm removing all system privileges from an oracle database user. Now this user ONLY has the following system privileges:
CREATE SESSION
UNLIMITED TABLESPACE
I was hoping that the user wont be able to do any DDL commands. But to my surprise, user can DROP TABLE in its own schema even though it can't create one.
Oracle documentation says prerequisite for DROP TABLE is "The table must be in your own schema or you must have the DROP ANY TABLE system privilege". Just that!!! I don't understand the security logic of Oracle but is there any way I can prevent Users from dropping their own tables?
The alternative would be creating another user to run the application and grant object access, which I'd rather like to avoid as there are potential issues.
A user will always have permissions to drop objects that they own. You can't prevent that by revoking privileges.
Since you're looking at tightening security, creating a new user and granting that user whatever privileges they need to manipulate the data is the right answer. The only people that ought to be logging in to a production database as a user that owns application objects are DBAs and then only when they are in the process of deploying changes to the schema. Everyone else should be logging in to the database as users other than the schema owner.
That being said, if the right solution is more work than you're prepared to undertake right now, a potential stopgap would be to create a DDL trigger on the database that throws an exception if a DROP is issued against an object in the specified schema. This is less secure than the proper solution. You may miss something when implementing the trigger, you or someone else may drop or disable the trigger and forget to re-enable it, etc. And it makes security reporting much more difficult because you've got a custom solution that isn't going to be obvious in the various security related data dictionary views which may create problems for auditors.

What permissions should Developers have in the Dev database instance

...and how should those permissions be granted. I work in a large IT dept with 70+ applications, some in SQL server and most in oracle. Each system has a prod, QA and Dev instance. We (I'm a developer) have readonly access to prod/qa, which I'm fine with. In SQL server development instances devs are given db_owner, which works totally fine. The debate is over what permissions I should have in the DEV oracle databases.
I recognize that best case would be to have each dev run their own instance on their workstation for development, but because of the size of the databases this has not been considered an option.
I'm also interested in HOW these permissions should be applied. In oracle permissions granted via a role are not active during PL/SQL execution so roles (even the "dba" role) are not useful. That leaves using a built in account (system) or creating dozens of users accross dozens of database and directly granting dozens of permissions to each.
In my mind just letting the devs login as system is making a lot of sense, but our DBAs claim that's a bad idea.
We used to just give developers access to the application account. This works for small shops but rapidly gets out of hand as the number of developers increase.
Here's what we do now:
the Application has it's own account (aka schema).
Developers have their own accounts
Data resides in the application schema
We have an ant build script to build code into whatever schema you want.
code includes views, packages, objects etc..
the build script includes a step to run a stored procedure to grant explicit rights to developers to the application data
Developers make changes in their own schema
When happy they check that into subversion
The Application's dev schema is built from the new subversion build.
Developers can check out and rebuild their own environments.
DDL changes to table structures are done via the DBA
these can be scripted as well
This has the benefit of ensure any front end application is not broken by database developers constantly rebuilding everything.
I assume that there are a relatively small number of application accounts that own the actual objects. So one or more logical applications are comprised of tables owned by a particular Oracle user. This would not by SYSTEM or SYS, it would not be any of the accounts that Oracle the company delivers. It would be an account that your DBAs created. If you are familiar with the Oracle sample schemas, the HR user owns all the tables in the HR schema which comprise the back end for an HR application.
Starting from the principle of "the simplest thing that could possibly work," my first thought would be to see if the developers could log in directly to those application accounts. This isn't the securest possible configuration, and you are opening up the possibility that a developer accidentally or intentionally does some damage that may be difficult to track or easily resolve. But it can work reasonably well depending on the organization. Privilege management is trivial-- the application owner account already has all the privileges it needs most likely.
The next step up would be giving every developer a separate schema to develop in, presumably in conjunction with a load of public synonyms in the database and an absence of schema qualifiers in the application code, so that any object created in the developer's schema automatically overrides the shared version of that object. This provides much better isolation. Permissions are generally granted by either creating scripts that contain all the grants a developer needs or by creating a script that copies all the privileges from a "known good" account to the new account. Neither is particularly difficult to write-- you just have to make sure that all the developers end up with the same set of privileges, which is generally just another script that gets run when a new privilege is granted.
If you are developing stored PL/SQL objects, then the schema owning those objects needs, as you mentioned, explicit grants on the objects used. If you have a single 'data' schema but are developing code in your own individual schemas then you should get the ability to grant access on the data schema objects to your development schemas. Normally I'd expect username/password for the data schema.
In regards to system privileges (eg CREATE), I'd expect CREATE TABLE, TYPE, VIEW, PROCEDURE TRIGGER, SYNONYM. Others may be appropriate (eg CONTEXT) depending on what you do. The DBA may rule out CREATE DIRECTORY as that could be damaging if mis-used. Ditto for privileges with ANY in them (eg SELECT ANY TABLE, DELETE ANY TABLE)
For performance tuning / system monitoring, on a dev database SELECT_CATALOG_ROLE is good. If the DBA is risk-averse, you may have to negotiate grants on individual views. Go through the REFERENCE guide for your version and ask for any you may use.
One of the DBA's jobs is to manage user privileges. I don't think system is a good idea for a few reasons, not the least being the ability to drop an entire schema which I am sure you don't want. That being said, I think it is perfectly fine to grant all to your users and let the DBAs manage these permissions no matter how many dozens of accounts there may be. Most DBAs will have scripts they can use to manage these permissions anyway.
Listen to your DBAs, they generally know what they are talking about.
If it's just a dev instance; i'd have all users have individual accounts added to the admin role. That way you can still log activity on a per-user basis; but give the devs enough breathing room to do their thing.
My group supports about 100 apps with about 20 of them having their own Oracle schema. We have gone down the road of every developer has the password to the schema and it is convenient. However, in hindsight I would recommend that each developer use their own Oracle account to develop. The main reason is auditing.
I recognize that best case would be to
have each dev run their own instance
on their workstation for development,
but because of the size of the
databases this has not been considered
an option.
Is there a way to deal with this, maybe by reducing the amount of data in your personal copies? This seems like the ideal solution, since it would allow you to make any changes you need. Then you could submit them to the DBA when you're ready, and have him update the shared development server.

Resources