I'm installing an SQL database and our application on a single PC. Under Vista this needs to be installed by an administrator account, but this means that the regular user account(s) can run our program, but it can't access the database it needs.
What I need is a simple way of allowing all NT logins on the PC to have access to the database.
I thought I'd solved it: In SSMS I can manually assign db_datareader/writer roles to BUILTIN\Users, and it works perfectly.
However, if my installer programmatically executes the following, it doesn't work:
USE [OurDatabase]
GO
EXEC sp_addrolemember N'db_datawriter', N'BUILTIN\Users'
GO
EXEC sp_addrolemember N'db_datareader', N'BUILTIN\Users'
GO
The users get assigned the roles, but they still can't access the database. The only difference I can see in SSMSE is that in the latter case, they also gain ownership of a new "BUILTIN\Users" schema, which I suspect may be screwing things up. Clearly SSMS does something slightly different...
Can anyone suggest a way to get this working programmatically?
In OurDatabase, what user is mapped to the login? Do you see a difference in the SSMS method vs. programmatic? What is the default schema for the user mapped to the group login when it works?
What about setting the application only to run as administrator on vista?
Ah, it appears that SSMS also does a
CREATE USER [BUILTIN\Users] FOR LOGIN [BUILTIN\Users]
on the database if the user doesn't exist.
I was twiddling the permissions on and off several times while trying to work out what to do, and on subsequent attempts the user already existed so SSMS didn't bother with the CREATE command. So when I finally figured out what I needed to do, I was getting an incomplete (for my needs) script out of it.
This wasn't obvious because the effects of this command are not seen in the user properties; they appear in the User Mapping in the Server Security\Logins section of SSMS.
Thanks to Aaron (the mention of logins had me looking at the Security\Logins page and I spotted the difference in the mappings there)
Related
I have a requirement to give a functionality for a non technical user to run the Agent job / stored procedure. It's just one stored procedure.
I do not want to the user to install SQL Server, nor do I want to give him any additional permissions. Indirect permissions (proxy or running through a server) are fine as long as the user won't be able to see the password.
I believe Osql does this but then I have to type username n password in batch file and that compromises security.
Is there any other way? Can this be achieved with SSRS?
To cut through you can script SP execution with Powershell and use integrated security to authenticate user on SQL server. Check this thread how to do that.
Please keep in mind that giving direct access to SQL server is a bad idea from security perspective, so you must limit its permissions with a specific role and grant execution only for that particular procedure.
Alternative to #Illia way is to create a simple web-app with (say) .net. It's probably less than 15 mins task for a .net developer to connect to SQL server and provide a button to execute one or more stored procedures. You can manage the access via integrated security of the app specific user id and password and is probably more easy for a non-tech user. See here.
I was finally able to achieve with less overhead using a SSRS report. Created a report to run the Stored proc whenever the report is opened. This way I was able to achieve the security part too. Thanks for the answers everyone.
I have a password protected PostgreSQL database (running on windows) which has been accessed by an unauthorized person several times using this simple trick as described here:
Stopping PostgreSQL Windows service
Changing md5 to trust in pg_hba.conf file
Starting Windows service
Accessing database via pgAdmin without a need of password
Is there any way to block this mechanism? I've been thinking about multiple windows users (there's only one administrator account on the machine right now) with limited file change privileges, but I am worried about database functionality and I would prefer a little bit more straight-forward solution.
UPDATE
Thank you all for your responses, they were all very helpful.
It's obvious to me now the user accounts are the way - probably the only right way at all.
Indeed the way to solve the problem is not by looking into PostgreSQL, but by looking into your Windows security. Once someone gains administrator privileges, there is nothing which stops the person from changing anything - this includes your PostgreSQL settings. Even if you set a database password and set proper permissions for the pg_hba.conf file, the unauthorized person can still change the permissions back, or start the database in single user mode (no password required) and modify the passwords.
Create separate Windows user accounts, protect the Admin with a password, and stop using the Admin account for day-to-day work.
Perhaps change all your users to limited. Create a user called postgres thats also limited and set it so that that its the only user that can read/write its own files. You will have your administrator account, that still can do whatever you want to do. Now run the postgres service as the user postgres and youre done.
... and stop giving people your admin password -- you should be fine ;)
We have a third-party vendor setting up software on a server. They have full access to that server and the sql-server on it with the sa account. We would like to set up a linked server so that a trigger can update data on a remote machine. Does access to the sa account necessarily mean that they have full access to the linked server or is there a way to protect yourself from sa?
EDIT: We wanted to give them full control of the server because we want them to have full responsibility. It takes the blame off us when it stops working. "hey, we didn't touch it, you fix it, you have full permissions". That way, they can do whatever they need to to get their software working, but it's in a sand boxed environment. We just need a trigger to get the final records out of their database and insert into our production database. That requires permissions we don't want to give them. The question was meant to ask if there was a way to save the password in that sand boxed environment under there noses. so to speak.
Never give anyone access to the SA account.
Instead, give them a named user account even if it still has full system level privileges.
Second, the linked server is going to be set up with a named user that is allowed to impersonate a named user on the other end. If they have an account with full privileges on the first server then they will be able to get to the other. It's as simple as changing the password of the user account that is granted access to the remote server.
Which brings us to another item: Never give an external entity full rights to anything unless they OWN the box. If, for some weird reason, you have no other choice then you should find an alternate way of transferring the data from this server to your production server.
One way would be to set up SSIS packages that drop the data in a directory the remote server will monitor for pickup. Sure this adds a bit more complexity, but in the end it will mean your stuff is still secure.
Finally, Linked Servers are notorious for being flaky in general. You are much better off finding a different way to transfer the data... Such as using the SSIS method.
You can set up the linked server to use a named user -- your third party contractor will still be able to see "the other end" of the link, but only with the rights granted to that named user.
I've got the following setup:
There is a SQL Server DB with several tables that have triggers set on them (that collect history data). These triggers are CLR stored procedures with EXECUTE AS 'HistoryUser'. The HistoryUser user is a simple user in the database without a login. It has enough permissions to read from all tables and write to the history table.
When I backup the DB and then restore it to another machine (Virtual Machine in this case, but it does not matter), the triggers don't work anymore. In fact, no impersonation for the user works anymore. Even a simple statement such as this
exec ('select 3') as user='HistoryUser'
produces an error:
Cannot execute as the database principal because the principal "HistoryUser" does not exist, this type of principal cannot be impersonated, or you do not have permission.
I read in MSDN that this can occur if the DB owner is a domain user, but it isn't. And even if I change it to anything else (their recommended solution) this problem remains.
If I create another user without login, I can use it for impersonation just fine. That is, this works just fine:
create user TestUser without login
go
exec ('select 3') as user='TestUser'
I do not want to recreate all those triggers, so is there any way how I can make the existing HistoryUser work?
Detect Orphaned Users, then resolve by linking to a login.
DETECT:
USE <database_name>;
GO;
sp_change_users_login #Action='Report';
GO;
RESOLVE:
The following command relinks the server login account specified by <login_name> with the database user specified by <database_user>:
USE <database_name>;
GO
sp_change_users_login #Action='update_one', #UserNamePattern='<database_user>',
#LoginName='<login_name>';
GO
https://msdn.microsoft.com/en-us/library/ms175475.aspx
What user account does the trigger execute as.
You'll need to grant that user IMPERSONATE priviledges for the User Account HistoryUser.
GRANT IMPERSONATE ON USER:: YourUser TO HistoryUser
More details here
http://msdn.microsoft.com/en-us/library/ms181362.aspx
Problems like this that arise after moving a database from one machine to another usually involve mismatched SID's, although I'm not sure if or how it applies to your case. Try dropping and re-creating the database user, making sure to reinstate its permissions to those tables.
It is an "orphaned user". It wont work. Documentation states this clear.
:-(
Fix "orphaned user" state and it will work again
When I try to create a SQL Server Login by saying
CREATE LOGIN [ourdomain\SQLAccessGroup] FROM WINDOWS;
I get this error
The server principal 'ourdomain\SQLAccessGroup' already exists.
However, when I try this code
DROP LOGIN [ourdomain\SQLAccessGroup]
I get this error
Cannot drop the login 'ourdomain\SQLAccessGroup', because it does not exist or you do not have permission.
The user that I am executing this code as is a sysadmin. Additionally, the user ourdomain\SQLAccessGroup does not show up in this query
select * from sys.server_principals
Does anyone have any ideas?
We are still struggling to understand the HOW of this issue, but it seems that [ourdomain\SQLAccessGroup] was aliased by a consultant to a different user name (this is part of an MS CRM installation). We finally were able to use some logic and some good old SID comparisons to determine who was playing the imposter game.
Our hint came when I tried to add the login as a user to the database (since it supposedly already existed) and got this error:
The login already has an account under a different user name.
So, I started to examine each DB user and was able to figure out the culprit. I eventually tracked it down and was able to rename the user and login so that the CRM install would work. I wonder if I can bill them $165.00 an hour for my time... :-)
is this when you are restoring from a backup or something? I've found that the following works for me in situations when I'm having problems with user accounts in sql
EXEC sp_change_users_login ‘Auto_Fix’, ‘user_in_here’
This happened to me when I installed SQL Server using a Windows username and then I renamed the computer name and the Windows username from Windows. SQL server still has the old "Computername\Username" in its node of Server->Security->Logins.
The solution is to go to Server->Security->Logins and right-click -> rename the old Windows user and use the new MachineName\Username.
I faced similar issue and i believe the issue was as a result of trying to recreate a login account after deleting an existing one with same name.
Just go through the various databases on the server using SQL Studio.
Example steps:
DBName ->Security->users
at this level for each of the databases, you may see the name of the user account there. Delete all occurrence in each Database as well as its occurrence in the top level Security settings at
Security->Logins
When done, try recreating the login account again and you should be fine.
I had the same story as Shadi.
On the top I can add that it can be also done by query:
ALTER LOGIN "oldname\RMS" WITH name="currentname\RMS"