How do I execute a procedure in a package I just created in another schema? - oracle

Setup: I have two trees of scripts that run on Oracle 11g - one set ensures the correct instance configuration and that all of the DBA proxy accounts are there to connect to the dbadmin account, and the other set builds and modify our database environments.
Problem: Proxied in to the DBADMIN account, the second set of scripts runs just fine, except for one piece: the data pre-population. The procedures that allow loading of the data create under the appropriate schema just fine, and the script that loads the data runs just fine if ran as SYS AS SYSDBA, but when I try to run it as DBADMIN immediately after creating the procedure it calls I get PLS-00904: insufficient privilege to access object schema.package for every call. I can't even have the script GRANT EXECUTE ON schema.package TO DBADMIN because that (of course) generates the expected ORA-01749: you may not GRANT/REVOKE privileges to/from yourself error.
To put it more simply:
(as DBADMIN:)
...
CREATE OR REPLACE PACKAGE BODY other_schema.package_name IS
...
PROCEDURE add_data(...)
...
(succeeds, and is testably working)
(later, in another script called by the same parent script, still as DBADMIN:)
BEGIN
other_schema.package_name.add_data(...);
...
(raises the PLS-00904 given above - Insufficient privilege)
Any ideas on how I can give the DBADMIN account EXECUTE access to a package that it hasn't created yet, or how DBADMIN can get access itself without stopping the whole script stream, log out and back in as SYS AS SYSDBA to GRANT it? (The whole point here is to have ZERO manual steps beyond the initial "run this script tree", and to only have one time ever up front when the SYS AS SYSDBA is ever used.)

You could grant DBADMIN the EXECUTE ANY PROCEDURE privilege. This will allow it to, er, execute any procedure that is to run programs owned by any other user.
Like the other ANY procedures it is extremely powerful and should not be granted lightly. (In fact it is one of the most powerful ANY privileges there is).

Related

Configure Oracle XE logging running on Windows 10, prevent writing to Windows Event Log

Environment:
Oracle XE 18 running on Windows 10 (my laptop!).
I run database commands using specific users and sys.
Problem:
The windows application event log has 1000's of verbose Oracle database logging, for example every SELECT statement, indeed every command I run!
Launch Windows Event Viewer, execute at command prompt: eventvwr
Questions:
How to configure Oracle so that only certain messages are written
the to the Windows Event Log. Ideally no commands that I execute are
logged.
Does Oracle XE also write to log files (not windows event logs) and if so how to configure the granularity?
(I'm fairly new to Oracle)
Additional Info:
Below is an example of a windows application event log
Looking at your screenshot, it seems you are using the SYS user to execute your SQL commands. By default, all operations executed by users using SYSASM, SYSBACKUP, SYSDBA, SYSDG, SYSKM, or SYSOPER privileges are audited and go to the event log. You can disable that behavior with the AUDIT_SYS_OPERATIONS initialization parameter.
See documentation here: https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/AUDIT_SYS_OPERATIONS.html#GUID-58176267-238C-40B5-B1F2-BB8BB9518950
When logged in as SYS, you can change the parameter setting with the following command:
alter system set audit_sys_operations=false scope=spfile;
Then restart the database.
That said, in general you should not be using SYS for day-to-day operations and preferably would leave the default auditing in place. Instead, use a user account with normal privileges (i.e. not SYS as SYSDBA) to do everything that doesn't require those elevated privileges. For the most part you wouldn't need that level of access except for startup/shutdown, backup operations, and installing patches.
create user myuser identified by mypassword;
grant dba to myuser;
alter user myuser default role all;
That should give you a user with plenty of elevated privileges that won't constantly trip the built-in auditing.
Read up on Oracle security here: https://docs.oracle.com/en/database/oracle/oracle-database/18/dbseg/introduction-to-oracle-database-security.html#GUID-41040F53-D7A6-48FA-A92A-0C23118BC8A0

As a non-DBA user, how can I pass on scripts to other users that work in their own Schema?

Here's my situation. I'm a non-DBA user in an Oracle database. As such, I only have DDL and DML privileges for my own Schema, so I can only create, drop, update, etc for tables in my own Schema.
So let's say I write a script that creates and updates tables in my own Schema (let's call the Schema USER1). When the day comes that I leave the company and need to pass this script on to my replacement (let's say USER2), how do I do that if the script only works for USER1? Does USER2 really have to go through my script and replace all references of USER1 with USER2?
Point being that I'd really like my script to work regardless what user runs it without having to tinker with it.
First, if it's a production script that creates tables for an application and manipulates it's data, it probably shouldn't be run from your own user, but from some dedicated production user.
Regardless, if you're running a script in your own schema, it doesn't need to explicitly reference it. Just remove the references to the schema, and all the objects will be created under the user running it, meaning that any user can run it from his own account (assuming it has the basic DML/DDL permissions the script requires).

Using Oracle "Create User" command does not automatically create an associated schema

I'm just getting started with Oracle data export and import and things worked perfectly fine the first time around. But then I came back next day repeated the exact same steps on the same systems, but get ORA-01435: user does not exist error.
System Specs for all machines:
-OS: Windows 2012 R2 x64
-Oracle Server: Oracle 11G Express x64
Objective:
I'm exporting data from Oracle server 1 and importing to Oracle server 2.
Procedure:
Export data dump is successful from Oracle server 1.
but when importing the data dump on Oracle server 2, I follow this procedure:
-Stop IIS service
net stop WAS
Create Schema/user account and Grant privileges before import
net stop WAS
sqlplus / as sysdba;
CREATE user PIE1 identified by PASS1;
GRANT ALL PRIVILEGES TO PIE1;
GRANT IMP_FULL_DATABASE TO PIE1;
According to oracle, all goes well, but look at the first image bellow. In DBeaver, I can see that only the User account PIE1 has been created, but NO schema.
Oracle issue 1. User account created, but not the Schema
Question 1: According to Oracle, the command "Create User" IS supposed to also create an associated Schema. Anyone have an idea why this is no longer working for me? It worked once the night before.
I then continue the import procedure as follows:
imp PIE1/PASS1#xe file=c:\Backups\AVUSER2_6_7.dmp log=c:\Backups\import.log fromuser=AVUSER2_6_7 touser=PIE1;
But get the following error:
Oracle claims the User doesn't exist even though it does
Oracle claims the User doesn't exist even though it does. I repeated the entire procedure and even created an identical import/export user account and credentials, and this error still comes up.
Question 2: Any idea why Oracle "Can't find" a user account that's clearly in the database?
Additional Info:
Checked that my windows account is in admin group
Checked that my windows account is in ORA_DBA group
Opened all CMD prompt as Admin
As you implied, users and schemas as the same in Oracle, you can't have a user without a schema. No idea about DBeaver, but as there are other users that aren't listed under 'schemas' (according to your second image - ANONYMOUS, DIP, ...) that seems to be unrelated.
(Purely a guess, but perhaps the user you're connect as in DBeaver just doesn't have visibility of any objects owned by those users - maybe it only lists users it can see in all_objects, say. Pure speculation, but you could investigate that by looking at the data dictionary while connect through SQL*Plus as the same user. According to this old forum post, there is an option to hide empty schemas...)
The import is connecting successfully as PIE1 - you'd get a different error, ORA-01017, if it wasn't and you wouldn't see the 'Connected to...' banner or anything after that.
Your import command has a trailing semicolon that should not be there. The "importing ... objects into" message shows that it's trying to import into the PIE1; user and not the one you actually created, PIE1. Remove that semicolon and try again.
Incidentally, you can probably also remove the #xe TNS alias and stick to a local connection, assuming the environment is configured as it was whenyou ran SQL*Plus. You should also consider using datapump expdp/impdp rather than the legacy exp/imp.

Why doesn't PL/SQL respect privileges granted by Roles?

When executing a PL/SQL block, any privileges granted to roles are ignored. Instead you must give specific users specific grants to run it. If I want to give DBAs access to a package or a function or a procedure, I can't give the DBA role a grant. I have to give a grant to each user in the DBA role, I have to remove the user's grant if they cease to be a DBA, and I have to add the grant to any new DBA.
I find this very hard to maintain.
My question is why does PL/SQL work this way? What design considerations did Oracle make to decide that this is how Roles and PL/SQL should work together? I've been unable to find an answer that isn't "that's just the way it is".
I think you may be fighting over Invokers rights vs Definers rights.
From Oracle docs:
During a server call, when a DR unit is pushed onto the call stack,
the database stores the currently enabled roles and the current values
of CURRENT_USER and CURRENT_SCHEMA. It then changes both CURRENT_USER
and CURRENT_SCHEMA to the owner of the DR unit, and enables only the
role PUBLIC. (The stored and new roles and values are not necessarily
different.) When the DR unit is popped from the call stack, the
database restores the stored roles and values. In contrast, when an IR
unit is pushed onto, or popped from, the call stack, the values of
CURRENT_USER and CURRENT_SCHEMA, and the currently enabled roles do
not change
So if you want Oracle to "respect the privileges granted by roles", then perhaps you want to use Invokers rights ( AUTHID CURRENT_USER clause)
It's probably a combination of laziness and the SET ROLE command.
I disagree that it's not allowed because of complex dependencies. Oracle already manages complex dependencies. And in 12c it is possible to grant a role to an object.
I think the real reason why objects don't inherit the roles of the user is because of the SET ROLE command. It's possible for a user to be assigned a role but to turn it on and off within a session. That's a silly feature and I've never seen it used. But theoretically it would require recompiling within the same session or transaction, which would be really confusing.
Otherwise if you drop a role then the PL/SQL package would become INVALID in some cases (without having the option to re-compile).
DROP ROLE ... is a DCL (Data Control Language) statement. Looks like Oracle decided: "A PL/SQL package shall not become INVALID by a DCL statement"
Maybe I am not understanding something correctly here, because I have done what you say can't be done. In fact, the Oracle documentation says it can be done. Look at the section on Procedure Security in this document. (#ibre5041)Nothing would have to be recompiled because the procedures run under the owner's privileges. The user's (or his roles') privileges are only checked for whether they are allowed to run the procedure.
What am I missing?
I'm think it is some historical heritage. When changing ROLE's object privs Oracle would have re-compile a lot of PL/SQL stored code. PS: you can also create something called "SCHEMA".
See CREATE SCHEMA statement.

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!

Resources