Lock database for other application - sql

I'm using SQL Server 2008 R2, someone is using my database via a macro code in Excel, is there any way to prevent another application (like Excel) to access my database?

If your users are supposed to acces the database (they have login and rights on it) but only with a limited range of software, you have to tell them not to use Excel.
There is a workaround based on an after connect trigger wich check the application_name in session, but its not very effective.
If they do not have to connect directly to the database, you have to delete their logins (or revoke rights) or change password if they shared a common user.

Create a service (e.g.in C#.NET) which will be used to query the database. In programming language like C# you can easily lock the database via "lock" statement.

Related

Run program with database access from Windows Server for concurrent users

My compiled VB.NET program is stored on Windows Server 2016. This program will call a database (.mdb) which is also located on server.
I have created user account with password clients (user) to access and run this program through share folder.
My problem is, this program only can be run by only one user at a time due to database lock for current user. There is any way to make it so that this program can be run by multiple users at the same time?
I never heared of Windows Server 2017. Perhaps you mean Sql Server 2017?
You should/could use a database like SQL Server, Mysql or Postgresql instead of Microsoft Access making multiple user much easier.
See Is there a downside to using Access as a database? for a bit more information.

Create SQL Server login for site, but has no SQL Server access to browse

I have a contractor who I want to give access to a website that connects to a database. I need to create a SQL Server user that can connect and read and write to the database.
However, I don't want this user to be able to connect to the SQL Server via something like Management Studio. Are there permissions that need to be enabled or disabled to accomplish this in SQL Server Management Studio?
SQL Server Management Studio (SSMS) is basically a normal client that makes SQL statements in the background. If you create a login in the SSMS, then no magic happens, but a CREATE LOGIN. This can be recognized by the fact that there is (almost) always the possibility to generate the appropriate SQL statement via "Script as", which is normally done in SSMS via the graphical user interface.
If you would lock out SSMS, then other clients as well. And even if there were a setting, there are other possibilities via Powershell and the like. So this is not the way to go.
I suppose you don't want the contractor playing around on the SQL server just because he got access to a database? He is allowed in the house, but not in all rooms....
In other words, it can only be done via permissions, where there is a login to connect to the SQL Server on the one hand and a database user who gets access to the database on the other hand. Therefore there are authorizations on SQL server level (login) and database level (user).
CREATE LOGIN testlogin WITH PASSWORD = 'wowThisIsKewl';
GO
USE [YourDatabase]
GO
CREATE USER [dbuserlogin] FOR LOGIN [testlogin] WITH DEFAULT_SCHEMA=[db_owner]
GO
Each login belongs first to the SQL Server role "public", unless additional or different authorizations are granted. You can connect to this role, but e.g. you can not create databases, perform backups etc.... Just try it out.... =)
At the same time DB_OWNER at database level allows the login to read and write data, etc. and more.

Connection to SQL Server database after restore

I have been asked to maintain a site created in ASP classic that uses a SQL Server database.
I was given the database in the form of a backup. I restored the database on my local computer and created a DSN connection to it. However when I attempt to load my site, the stored procedures the site relies on give an error that execute permission was denied.
The stored procedures in question have a user named UserSecure showing as the only person with EXECUTE permission, I have tried creating a user by that name but that does not work, even though I can manually login to SQL Server Management Studio using UserSecure trying to connect from the web page using those credentials gives a login failed error.
If I run sp_helplogins my Windows credentials are shown as being owner of the database, and I can in fact execute from within SSMS but not from an ADO connection.
On another note the connection in the webpage was coded like this, I am not familiar with the application part of the connection. Perhaps this is part of the problem? I have tried connecting with a DSN and DSN-less connection and can connect but not do anything with the database?
You should make sure the database server login is mapped to the appropriate database user (this problem crops up often when dealing with database backups). If it is not, then you need to fix the mapping. Fortunately, there is a command called sp_change_users_login that you can use to fix this problem.
First, check if your login is mapped to your database user. Using SQL Server Management Studio (assuming SQL Server 2008), look under Security/Logins for UserSecure. If you see it in the list, double click on it and select User Mapping. From there, locate the database you are trying to connect to, and see if UserSecure is mapped to that database. If it is not, you may be able to fix it using the following command (assuming UserSecure is the name of both the login and the user):
EXEC sp_change_users_login AUTO_FIX, UserSecure
See MSDN for more info on sp_change_users_login:
http://msdn.microsoft.com/en-us/library/ms174378.aspx
One issue that has bitten me a few times:
If your stored procedure (or view) requires permission from a user (let's say userA), and the stored procedure calls another database's table or view (say viewB), it is not sufficient to just make a login on viewB's database, you must also explicitly grant userA permission to select/execute/etc. on viewB (which in turn requires a user on viewB's database)
So in your case, you may need to explicitly grant UserSecure execute permission on a stored procedure on an existing database referenced by the one you restored.
This may not be the most elegent fix, but I quit focusing on the one procedure and instead granted execute permission to the guest user on the entire DB. Since this is only running on my personal machine security is not an issue and it seems to have fixed the problem.
Know the problem all too well,
The ID of the user(name) will be different from the backed up database to the restored one. MSSQL stores the ID of the user and not the username (text), so the ID will be different (99% of the time) per machine and backup. So when the ID does not match you don't have access.
All you need to do is delete the user and recreate it, make sure you do it in both places:
Delete the user from the database first:
DATABASE -> SECURITY -> USERS -> Right click (username) + delete
Then goto
SECURITY -> LOGINS -> Right click (username) + delete
Then recreate the user and give the account the correct permissions and you're all good.

Make a login into dbo for a database in SQL Server

I am attempting to migrate from SQL Server 2005 to SQL Server 2008. Both of these database instances are hosted on 3rd party shared servers that I do not have full permissions to. They are using mixed mode authentication.
I am running into trouble setting up the new database the same way the old one was set up. Specifically, the new web-based control panel doesn't allow a dbo to be specified when creating a new database and then when using Red Gate SQL Compare to sync up the schemas I am having problems because some objects (that don't explicitly specify dbo in the script) are being created with the prefix of the user account rather dbo.
I have poured over the documentation trying to find a way to force my login "user1" as dbo to the "db1" database. I came to the conclusion that the script should look like this:
ALTER AUTHORIZATION ON DATABASE::db1 TO user1
Before running this script, the login "user1" already exists, but is not a user for database "db1". Note I had to submit this script to the support of my hosting company in order to run it. According to the hosting company the statement successfully executes, however when I compare the databases using SQL Compare the user "user1" has not been physically added to the database like it was under SQL Server 2005. When trying to add it using the script:
CREATE USER [user1] FOR LOGIN [user1] WITH DEFAULT_SCHEMA=[dbo]
I get the error message:
"The login already has an account under a different username"
I have tried dropping all of the other users from the database, but the error message still persists - which I find odd.
While I could just fix the scripts by explicitly specifying dbo, this would inevitably be a time bomb waiting to go off because if any new script were introduced that didn't explicitly specify dbo there would be a failure during synchronization. Since some of the scripts are from 3rd parties, this is not a good solution.
So my questions: Is there another statement that I need to run in order to add "user1" to the database as a user that is dbo? Is there anything that has changed in the implementation between SQL Server 2005 and SQL Server 2008 R2 that could cause these inconsistencies?
I am unfortunately not able to test to find an answer to the second one because I don't have another SQL Server 2008 database to test with and I don't have full access to do anything I want on this one.
The old database was created through a control panel which forced dbo to be specified and the new one doesn't allow dbo to be specified when creating a database.
From what i have gathered the following should suffice.
ALTER USER [user1] WITH DEFAULT_SCHEMA=[dbo]
The create wasnt working as it already existed.

Building an auditing system; MS Access frontend on SQL Server backend

So basically I'm building an app for my company and it NEEDS to be built using MS Access and it needs to be built on SQL Server.
I've drawn up most of the plans but am having a hard time figuring out a way to handle the auditing system.
Since it is being used internally only and you won't even be able to touch the db from outside the building we are not using a login system as the program will only be used once a user has already logged in to our internal network via Active Directory. Knowing this, we're using a system to detect automatically the name of the Active Directory user and with their permissions in one of the DB tables, deciding what they can or cannot do.
So the actual audit table will have 3 columns (this design may change but for this question it doesn't matter); who (Active Directory User), when (time of addition/deletion/edit), what (what was changed)
My question is how should I be handling this. Ideally I know I should be using a trigger so that it is impossible for the database to be updated without an audit being logged, however I don't know how I could grab the Active Directory User that way. An alternate would be to code it directly into the Access source so that whenever something changes I run an INSERT statement. Obviously that is flawed because if something happens to Access or the database is touched by something else then it will not log the audit.
Any advice, examples or articles that may help me would be greatly appreciated!
Does this work for you?
select user_name(),suser_sname()
Doh! I forgot to escape my code.
Ok, it's working here. I'm seeing my windows credentials when I update my tables. So, I bet we missed a step. Let me put together a 1,2,3 sequence of what I did and maybe we can track down where this is breaking for you.
Create a new MSAccess database (empty)
Click on the tables section
Select external data
Pick ODBC database
Pick Link to the datasource by creating a linked table
Select Machine datasource
Pick New...
System Datasource
Pick SQL Server from the list and click Next, Finish.
Give the new datasource a name and description, and select (local) for the server. Click Next.
Pick "With Windows NT authentication using the network login ID". Click Next.
Check Change the default database to, and pick the DB. Click Next. Click Finish.
Test the datasource.
Pick the table that the Trigger is associated with and click OK.
Open the table in Access and modify one of the entries (the trigger doesn't fire on Insert, just Update)
Select * from your audit table
If you specify SSPI in your connection string to Sql, I think your Windows credentials are provided.
I tried playing with Access a bit to see if I could find a way for you. I think you can specify a new datasource to your SQL table, and select Windows NT Authentication as your connection type.
Sure :)
There should be a section in Access called "External Data" (I'm running a new version of Access, so the menu choice might be different).
Form this there should be an option to specify an ODBC connection.
I get an option to Link to the datasource by creating a linked table.
I then created a Machine datasource. I selected SqlServer from the drop down list. Then when I click Next, I'm prompted for how I want to authenticate.
CREATE TRIGGER testtrigger1
ON testdatatable
AFTER update
AS
BEGIN
INSERT INTO testtable (datecol,usercol1,usercol2) VALUES (getdate(),user_name(),suser_sname());
END
GO
We also have a database system that is used exclusively within the organisation and use Window NT logins. This function returns the current users login name:
CREATE FUNCTION dbo.UserName() RETURNS varchar(50)
AS
BEGIN
RETURN (SELECT nt_username FROM master.dbo.sysprocesses WHERE spid = ##SPID)
END
You can use this function in your triggers.
It should be
select user name(),suser sname()
replace spaces with underscores
you need to connect with integrated security aka trusted connection see (http://www.connectionstrings.com/?carrier=sqlserver)
How many users of the app will there be? Is there possibility of using windows integrated authentication for SQL authentication?
Updated: If you can give each user a SQL login (windows integrated) then you can pickup the logged on user using the SYSTEM_USER function.
My solution would be not to let Access modify the data with linked tables.
I would only create the UI in Access and create an ADO connection to the server using windows authenticated in the connection string. Compile you Access application as dbe to protect the VB code.
I would not issue SQL statement, but I would call stored procedures to perform the changes in the database, and create the audit log entry in an atomic transaction.
The UI (Access) does not need to know the inner works on the server. All it needs to do is request and update/insert/delete using the stored procedures you would create for this purpose. The server should handle the work.
Retrieve a record set with ADO using a view with the hint NOLOCK implemented in the server and cache this data in Access for local display. Or retrieve a single record and lock only that row for editing.
Using linked tables your users will be locking each other.
With ADO connections you will not have the trouble to set ODBCs on every single client.
Create a table to set the server status. You application will check it before any action. you can use it to close the server to the application in case that you need to perform changes or maintenance.
Access is a great tool. But it should only handle its local data and not be allowed to mess with the precious server.