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

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.

Related

Get time and number of OBIEE 12c users login

My requirement is just to monitor and know how many a user log in per month.I need to count number of logins for a user with the time they login
Can anyone please help me in how to do this?
Is there any log file such as obis1-query log file for queries processing monitoring in OBIEE to get these info?
Thanks
Not familiar with obiee and if users log in via a connection pool, but if they log in as an Oracle defined user ID, you want a System Trigger in PL/SQL:
create trigger user_logged_in
after logon database
begin
insert into some_audit_table
(user_id, login_time)
values (sys_context('USERENV', 'CURRENT_USER'), sysdate);
end;
/
Not tested, but that should give you a start. Above example derived from Oracle PL/SQL Language Reference Example 9-21.
User tracking is your friend. You can set up to log information in the OBIEE RCU database (that database you create/configure as part of OBIEE installation), and it includes the login information. Look how to set up it in Oracle documentation, as well as blog posts (look for OBIEE User tracking in Google). Keep in mind your OBIEE version, as the details to set it up have changed in different versions, basically it involves two steps:
Set up the RPD to query to the RCU database and table (mainly, in
your XXX_BIPLATFORM DB user, the S_NQ_ACCT table for general
information, and the S_NQ_DB_ACCT table for the physical
queries)
Modify the OBIEE config file or in the EM Beans (depending on
your OBIEE version) referencing the RPD Physical layer you have set
up.
Regards
I am going to share with you my finding about my question which has asked. As you may know, OBIEE repository tables, which can be used to show to end users as subject area that this is usgae tracking utility, just track information around sent queries to BI server and not more about users specifically. In this occasion, you can use a method which called enhanced usage tracking for OBIEE that is presented completely here: https://www.rittmanmead.com/blog/2016/12/enhanced-usage-tracking-for-obiee-now-available-as-open-source/
This is exactly what you want. All detail information about users activities in OBIEE and even some redundant ones. You can create a physical table, then add it to repository file and display as subject area to end user with any permission. Of course, according to your software environment or implementation structure, you are supposed to make some changes in this manner.
I hope this goes well.

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.

Oracle dbms_job with invalid owner

Ok, database at a clients site that has dbms_job entries where the schema_user is invalid. (It appears to be the effect of bringing over a schema from another machine using exp/imp.)
I would like to get rid of these jobs, but standard operating procedure says that you must connect as the owner of the jobs to dbms_job.remove() it.
I thought a workaround might be, to create the user in this instance, and then use it to remove the job.
Thoughts?
Edit:
Or even alternatively making direct edits to the sys.job$ table instead of going through the dbms_job interface?
There's a package owned by SYS called DBMS_IJOB. This offers pretty much the same functionality as DBMS_JOB but it allows us to manipulate jobs owned by other users.
If your rogue job is number 23 then this command should kill it:
SQL> exec dbms_ijob.remove(23)
By default privileges on this package are not granted to other users, so you need to connect as SYS in order to execute it. And remember to commit the change!

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.

User Privileges

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.

Resources