We have a SQL Server that uses SQL Server Authentication, with users that can deploy, and others that can read, for the sake of simplicity, I'll call them "deploy" and "web".
I'm having difficulty setting permissions up using a Visual Studio (2012) Database project, as the "deploy" user does not have sufficient permissions to create new server logins.
I can add scripts to do things like:
GRANT SELECT ON foo.bar TO [web]
This then sulks (with "SQL71501: Permission has an unresolved reference to object [web].") until I add:
CREATE USER [web] FOR LOGIN [web];
This then sulks (with "SQL71501: User: [web] has an unresolved reference to Login [web].") until I add:
CREATE LOGIN [web] WITH PASSWORD = '******';
This then fails to publish with:
Dropping Permission...
Dropping Permission...
Creating [webuser]...
(67,1): SQL72014: .Net SqlClient Data Provider: Msg 15247, Level 16, State 1, Line 1 User does not have permission to perform this action.
(67,0): SQL72045: Script execution error. The executed script:
CREATE LOGIN [webuser]
WITH PASSWORD = '**';
An error occurred while the batch was being executed.
This doesn't make sense, as the user already exists, so shouldn't need creating
How can I allow publishing via the deployment user without trying to (re)create the login each time? Or, is it possible to reference the externally created user, without having to publish it?
As the user already exists, I suspect that the user that is used to perform the deploy doesn't have rights to view it. The below should be all you need to resolve this.
GRANT VIEW DEFINITION ON LOGIN::web TO deploy
Related
BACKGROUND
The user is defined in Azure AD and in Azure SQL.
test.user#company.com is defined and active in Azure AD. I’m able to log in with this user in Azure portal.
I have created a contained database user with the clause "from external provider" in the Azure SQL database and added the user to the db_datareader system role. The commands commits without error. I have compared the Asset ID in Azure AD and the SID in database and they match. I have tried with different users.
I am able to login as an AD User assigned to the SQL servers assigned "Active Directory Admin"
SQL Server users also login without any issue
Login test in SSMS
I have set default database to the specific database I’m trying to log into (Options-Connect to database).
I have tried with different Authentication modes:
“Azure Active Directory – Universal with MFA” and
“Azure Active Directory – Password”
When I try to login with SSMS I get
Error: 18456, state 1, class 14.
When I query [sys].[event_log] it returns
[event_systype]= 4, [event_subtype_desc] = login_failed_for_user.
PROCESS FOLLOWED
I have a user defined in Azure AD. (test.user#company.com)
In my Azure SQL database, I have set an Active Directory administrator.
I have created a user in SSMS test.user#company.com with the following syntax:
CREATE USER [test.user#company.com] FROM EXTERNAL PROVIDER;
I have assigned the user to the db_datareader role with the following syntax:
ALTER ROLE db_datareader ADD MEMBER [test.user#company.com]
ISSUE: When I try to connect as test.user#company.com, the connection fails and I get this error:
Login Failed for user test.user#company.com
Details of error contains:
Error Number: 18456, State: 1, Class: 14
I have tried to find an answer on learn.microsoft.com, googled my ass off and found some useful resources on this, but none that actually helps me with pinpointing what to do to resolve the issue. If anybody have an Idea of what I'm doing wrong, ref "PROCESS FOLLOWED" I'd be forever grateful :)
I solved it by a workaround, setting up a new database.
I did not find the cause of the problem, but it must be related to database setup "DTU"-"Basic" or some setting that I have managed to set without remembering.
Anyways, my process works when I set up a new database with "DTU"-"Standard" Configuration.
It seems to be some kind of encoding problem. After almost giving up and using a different DB, I tried creating a new one, but without some special characters. And suddenly, it worked.
If you can't change your database's password, you can just edit the connection string in another editor and it works as well (Notepad, VS code, etc).
I am working on a Database project in VS2013 that contains a C# SQL CLR stored procedure.
The assembly owner is [servername\User123]
The database owner is also [servername\User123] (Being the database owner, this user obviously already exists on the server. I managed a successful publish of the database by commenting out the code in my SQL CLR procedure and publishing, the following occurs after I un-comment-out that code.)
If I try to build the project in VS, I get the error:
Error 1 SQL71501: Assembly: [DatabaseProject] has an unresolved reference to object [servername\User123].
...caused by:
CREATE ASSEMBLY [DatabaseProject] AUTHORIZATION [servername\User123]
FROM 0x4D5A90000300000004000000FFFF0000B8000etcetcetcetc
WITH PERMISSION_SET = EXTERNAL_ACCESS
GO
So, if in VS I add a create user script in the \Security folder:
CREATE USER [servername\User123] FOR LOGIN [servername\User123] WITH DEFAULT_SCHEMA = dbo
GO
GRANT CONNECT TO [servername\User123]
Then I can build the project.
However, if I then try to Publish the database, I get the error:
Creating [servername\User123]...
(47,1): SQL72014: .Net SqlClient Data Provider: Msg 15063, Level 16, State 1, Line 1 The login already has an account under a different user name.
(47,0): SQL72045: Script execution error. The executed script:
CREATE USER [servername\User123] FOR LOGIN [servername\User123];
An error occurred while the batch was being executed.
Is there a "right" way to do this?
This issue is due to a simple misunderstanding of how SQL Server handles the "owner" of the database as a database "principal". The concept of "database owner" shows up in two different ways:
As a database-level User having the name of dbo and a principal_id of 1. Now, what server-level Login maps to this particular User (i.e. "principal") is simply a matter of the value in the SID field in sys.database_principals:
SELECT sdp.*
FROM [sys].[database_principals] sdp
WHERE sdp.[principal_id] = 1;
This field will map to the SID field in sys.server_principals:
SELECT sdp.*, '---' AS [---], ssp.*
FROM [sys].[database_principals] sdp
INNER JOIN [sys].[server_principals] ssp
ON ssp.[sid] = sdp.[sid]
WHERE sdp.[principal_id] = 1;
Pay attention to the following fields in sys.database_principals:
type
type_desc
authentication_type
authentication_type_desc
Seeing as how your database is currently owned by a Windows Login, run the query immediately above (the 2nd query--the one with both tables). Next, change the database to be owned by sa. Next, open up a NEW query tab. Finally, run the same query in this new window (so that you can easily compare the "before" and "after" results), making sure to pay close attention to the 4 fields noted above, as well as the sid field. (Please note that it is possible to create Users without Logins and those will not show up, obviously, in a query that JOINs to sys.server_principals, but this question is dealing specifically with Logins).
From all of this you should see that specifying a Login to be the "owner" of a database does not, in fact, create a User for that Login: it merely updates the definition of the dbo User. Hence, the Login that owns the database does technically exist in that database, but always with the name of dbo instead of its actual name. This is why you are getting the following error:
The login already has an account under a different user name.
As a Database Role that any User in the database can be added to in order to be given those permissions.
To fix:
Remove your CREATE USER script from the \Security folder.
Use AUTHORIZATION [dbo] instead.
While trying to do anything related to deploying to Azure/creating a BACPAC in SSMS 2012 I encounter error for each of 3 users in my database (who are not the user that is currently logged on)
Validation of the schema model for data package failed. Error
SQL71501: Error validating element [VARIABLE_USER_NAME_HERE]: User:
[VARIABLE_USER_NAME_HERE] has an unresolved reference to Login
[VARIABLE_USER_NAME_HERE]. (Microsoft.SqlServer.Dac)
Any clues?
This SO question really helped:
Can I ignore logins when publishing a Visual Studio Database project?
I realised that the user I was logged on (to my local database) with, had no permissions to view the login details for the login associated with the peer users that were being complained about in the error message. Written in more plain English, and assuming that there are just 2 database users (mr_spoon and mr_fork), what the error message means is "The currently logged on user [mr_spoon] can see that there is another user called "mr_fork" but cannot view the details of the login [also called "mr_fork" in this case] associated with that user"
Logging onto the master DB with my Windows admin login, and then running this query solved it:
GRANT VIEW DEFINITION ON LOGIN::the_login_name_in_the_error_message TO the_user_i_logged_on_with_and_ran_the_export_from
i.e. admin should run this:
GRANT VIEW DEFINITION ON LOGIN::mr_fork TO mr_spoon
Note that SQL Server permission system supports the notion of both Users and Logins, so I've hopefully been quite careful to say user when I mean user and login where I mean login. Why not just run the export from the admin login you may ask? The machine that can do that doesn't have SSMS2012 nor is it possible to install it, and it's the only machine the admin login works from.. Thus, I'd expect this problem is rare but maybe one day this will help someone
I thought I'd post a Q&A because everywhere I looked I only found reference to SQL71501 within the context of SSDT, not SSMS2012/Azure Deployment
I'm looking at the Database Project in VS2010, the idea being that I want something I can use to keep track of the database schema (in source control) and the ability to generate "new install" scripts, and change scripts.
When I create a new database project wizard and import my existing database schema, it won't "build". I get the error:
SQL03006: User: [scanner] has an
unresolved reference to Login
[scanner].
The SQL that generates this error:
CREATE USER [scanner] FOR LOGIN
[scanner];
The user "scanner" is a login defined in the database I imported. I have no idea what it's teling me, and google isn't throwing much up. Any ideas?
The Login is actually defined in the master database of the server install. The CREATE USER statement needs to point at an existing Login otherwise it errors. The Database Project is not aware of the Login at the server level. Either you can create a Server Project to handle the Logins, or you can turn off the checking of Security objects in your Database Project. See the answer by Demetri M for more details: http://social.msdn.microsoft.com/Forums/eu/vstsdb/thread/1f8226fe-b791-4344-8735-3d38307e8664
I'm using Visual Studio 2012 for a SQL Server 2008 R2 database project. The options listed by #Judah don't appear to work anymore.
They now appear to be Settings that you configure while doing a Schema Compare:
Right click database project >
Choose 'Schema Compare' >
Choose the 'Settings' gear icon >
Choose the 'Object Types' tab >
Logins are Non-Application-scoped. Database roles, Permissions, Role Memberships, and Users are all Application-scoped.
Unfortunately, the only way that I can find to preserve these is to save the schema compare. This can be a little inconvenient if you're sharing this on a team and would like project/database (or server) settings for any schema compare.
It gets the job done, though.
You can change the create user scripts to create roles.
So instead of "Create user userName for login loginName;"
use "Create Role [userName] authorization dbo;"
This is a hack, but as long as you aren't having to deal with users and roles in your project, you can happily do the following:
GRANT EXECUTE
ON OBJECT::[dbo].[sp_name] TO [userName];
Apparently, this issue is still occurring on VS2017 database projects as well.
I've managed to solve it by first creating the login and then create the user.
-- Windows Account
CREATE LOGIN [Domain\Username]
FROM WINDOWS WITH DEFAULT_LANGUAGE = [us_english];
GO
CREATE USER [Domain\Username] FOR LOGIN [Domain\Username];
GO
-- Sql Acccount
CREATE LOGIN [sql_account] WITH PASSWORD = 'Ch#ngeth1spA$swurD'
GO
CREATE USER [sql_account]
FROM LOGIN [sql_account]
WITH DEFAULT_SCHEMA = dbo
GO
-- Then set the sql file Build Action to "Build"
In the database project open the 'Security' folder (assuming that's how your database was imported). For each user profile that is causing an issue, set the build action to 'None' in the properties panel. You will also have to remove them from any other files in which they appear, including Permissions.sql and RoleMemberships.sql.
Greetings all, I've run into a problem that has me stumped.
I've put together a database in SQL Server Express, and I'm having a strange permissions problem.
The database is on my development machine with a domain user: DOMAIN\albertp.
My development database server is set for "SQL Server and Windows Authentication" mode.
I can edit and query my database without any problems when I log in using Windows Authentication.
However, when I log in to any user that uses SQL Server authentication (Including sa) I get this message when I run queries against my database.
SELECT * FROM [Testing].[dbo].[AuditingReport]
I get:
Msg 18456, Level 14, State 1, Line 1
Login failed for user 'auditor'.
I'm logged into the server from SQL Server Management Studio as 'auditor' and I don't see anything in the error log about the login failure.
I've already run:
Use Testing;
Grant All to auditor;
Go
And I still get the same error. What permissions do I have to set for the database to be usable by others outside of my personal domain login?
Or am I looking at the wrong problem?
My ultimate goal is to have the database be accessible from a set of PHP pages, using a either a common login (hence 'auditor') or a login specific to a set of individual users.
GRANT ALL is not performing the action you believe it to be.
I suggest for testing purposes that you consider using Database Roles in order to manage the privileges of your User.
Here is a list of the available Database-Level Roles
You can add an existing User to a Database Level role by using the system stored procedure sp_AddRoleMember. For example, the following will provide READ permission to your User for all objects within the given database.:
EXEC sp_addrolemember 'db_datareader','auditor'
Ideally, you will likely want to consider defining your own Database Roles in order to manage privileges for your Database Users.