How to get available space in tablespace for a user (Oracle) - oracle10g

I'm working on a web application where I need to warn the user that they're running out of space in the given db user's tablespace.
The application doesn't know the credentials of the db's system user, so I can't query views like dba_users, dba_free_space..etc.
My question is, is there a way in Oracle for a user to find out how much space there is left for them in their tablespace?
Thanks!

Forgive my ignorance on the subject, for I believed only views available on data storage were dba_free_space etc..
I realized that for the logged user, there are user_free_space.. views for them.
Modified version of the query mentioned here would be the answer my question.
Query is as follows: (Getting the space left on the DEFAULT_TABLESPACE of the logged user)
SELECT
ts.tablespace_name,
TO_CHAR(SUM(NVL(fs.bytes,0))/1024/1024, '99,999,990.99') AS MB_FREE
FROM
user_free_space fs,
user_tablespaces ts,
user_users us
WHERE
fs.tablespace_name(+) = ts.tablespace_name
AND ts.tablespace_name(+) = us.default_tablespace
GROUP BY
ts.tablespace_name;
It would return free space in MB

create a stored package as a user that has the necessary privileges. You may have to create a new user. Grant EXECUTE on the package to any user that needs it. The packages needs to have all the procedures and functions needed to access the DBA views but should be coded carefully to avoid accessing "too much" information. You may want to write a second package in the account of a non-privileged user to encapsulate the logic.

This is potentially very complex, as it's quite possible for the user to:
Receive an "out of space" error even though the tablespaces that they have privileges on, including their default tablespace, have plenty of space. This could happen when they insert into a table that is owned by a different user which is on a tablespace that your user has no quota on. In this case, your user probably does not have access to the views required to determine whether there is free space or not,
Be able to continue inserting data even though there is no free space on the tablespaces on which they have a quota -- they might not even have a quota on their default tablespaces.
So unless you have a rather simple case you really have to be very aware of the way that the user interacts with the database on a far deeper level, and look at free space from a more database-holistic viewpoint.

Related

How can I discover which user and when an index was created?

I have a postgres table with duplicated indexes (called someName and someName1) applied to the same columns. I would like to know which user executed the ddl that created these indexes, and when it happened. Is this possible on postgres?
If you hadn't already set up some kind of auditing or aggressive logging before this happened, then your options are pretty limited.
If you retain WAL files, you could go exploring through those (with pg_waldump and other tools, or by doing PITR) to pinpoint the time. This will probably not be a quick and painless exercise. By looking at surrounding changes, or at log files from the same time, you might be able to figure out who was logged on at the time and also had permissions to create the index.

Optimize the trigger to add audit log

I have a local database which is the production database, on which all operations are being done real time. I am storing the log on each action in an audit log table in another database via trigger. It basically checks if any change is made in any of the row's column it will remove that row and add it AGAIN (which is not a good way I think as it should simply update it but due to some reasons I need to delete and add it again).
There are some tables on which operations are being done rapidly like 100s of rows are being added in database. This is slowing the process of saving the data into audit log table. Now if trigger has to like delete 100 rows and add 100 again it will affect the performance obviously and if number of rows increases it will reduce the performance more.
What should be the best practice to tackle this, I have been looking into Read Replica and Foreign Data Wrapper but as for Read Replica it's only Readable and not writable for PostgreSQL and I don't really get to know how Foreign Data Wrapper gonna help me as this was suggested by one of my colleague.
Hope someone can guide me in right direction.
A log is append-only by definition. Loggers should never be modifying or removing existing entries.
Audit logs are no different. Audit triggers should INSERT an entry for each change (however you want to define "change"). They should never UPDATE or DELETE anything*.
The change and the corresponding log entry should be written to the same database within the same transaction, to ensure atomicity/consistency; logging directly to a remote database will always leave you with a window where the log is committed but the change is not (or vice versa).
If you need to aggregate these log entries and push them to a different database, you should do it from an external process, not within the trigger itself. If you need this to happen in real time, you can inform the process of new changes via a notification channel.
* In fact, you should revoke UPDATE/DELETE privileges on the audit table from the user inserting the logs. Furthermore, the trigger should ideally be a SECURITY DEFINER function owned by a privileged user with INSERT rights on the log table. The user connecting to the database should not be given permission to write to the log table directly.
This ensures that if your client application is compromised (whether due to a malfunction, or a malicious user e.g. exploiting an SQL injection vulnerability), then your audit log retains a complete and accurate record of everything it changed.

How to give limited access to system table to a user?

I am looking into a system table: stl_load_errors and I have created a view on top of stl_load_errors to restrict the data.
sample view:
create view vw_sample_load_errors
as
select * from stl_load_errors where filename like 'sample123%'
Now, when a regular user queries the view, the user is unable to see any rows.
How do I give him access to this view alone.
I do not want to give syslog access which will give user unlimited access to all data in all system tables including stl_load_errors.
Let me know if it is clear enough.
There is no way to achieve what you want using Redshift permissions. Users can either see only their own rows in system tables (the default) or they can see all rows in all system tables (if SYSLOG ACCESS is set to UNRESTRICTED). There is no way to grant the equivalent of SYSLOG ACCESS UNRESTRICTED for a single system table.
As Jon suggested in the comments, you could create a process that copied data out of stl_load_errors into another table every minute or so and grant user permissions on that.

Prevent users from seeing objects to which they have no access

WHAT
I have users that share a database, but have their own schemas. Each user is only able to access objects on their schema - they have been explicitly revoked usage on the schemas that are not theirs.
I am not concerned about a user inappropriately accessing others' schema; however, I would very much like for them not to be able to see the contents or even the existence of the other schema to which they have no access.
WHY
I am aware that this is mostly "cosmetic", but the primary reason for this would be that my users do not have to shift through objects that they cannot access in certain tools (Tableau, DB IDEs, etc) - so I think it does add some practical value.
ATTEMPTS
I've been searching for a solution, but haven't found one that works. For instance, I revoked users' access on information_schema and pg_catalog (I know this is not recommended); however, it had no effect.
Is this at all possible?
It is not possible to limit access to pg_class, pg_attribute, or pg_proc. Therefore what you want can only be achieved by separating each user in their own databases rather than individual schemas.

Managing users with Postgresql

Our system will run on a local network with no more than 50 clients that connect to the same local server. We are creating a DB user for each client, to take advantage of the postgresql privilege system.
1) Analyzing the "performance", its OK to have ~ 50 DB users instead of reimplementing a custom system?
2) (SOLVED) How can the user check (what SQL statement) what permission he has in a table?
Solution:
SELECT HAS_TABLE_PRIVILEGE('user','table','insert')
I prefer to not reimplement the system, since a good security system isn't trivial to implement.
To answer the user/performance question: probably not. The only real risk would depend on how many users have unique security permissions (for example, if every one of those 50 users had different permissions on each table/schema in the database). In practice this should never happen, and as long as you have a sane group system for permissions, you should be fine.