VS Database Project User Creation Error - visual-studio-2013

I'm trying to publish locally against a SQLExpress instance to test the publish capability of VS Database Project and i"m running into an error where it's trying to create a user that already exists within the database. The user creation isn't being wrapped within an IF EXISTS and I'm not seeing any type of setting to control or enforce this.
Specifically, it's throwing:
Creating [xyz\abc46518]...
(208,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.
(208,0): SQL72045: Script execution error. The executed script:
CREATE USER [xyz\abc46518] FOR LOGIN [xyz\abc46518];
While other parts of the script have 'IF EXISTS' and 'IF NOT EXISTS', this part of the script does not.
I'd like to be able to have this as a part of the script to control the users within the database. Should someone choose to grant access and it's not in source, it's going away when we deploy.

I started using database projects, they are great, except for the user permissions.
I only have dba permissions to our databases, whereas handling logins is at the server level.
So when creating the database projects I'd get the following code generated:
CREATE USER [UserName] for login
Which when I went to build the project would error.
Well I wanted the users, but didn't want the hassle of having to keep track of post deployment scripts, largely because they ruined my lovely TFS structure.
My solution, which is a bit of a hack, instead of creating a user, I just created a role with the same name:
CREATE ROLE [UserName]
AUTHORIZATION [dbo];
Now I can assign permissions to the user for my objects (I know all access should be through roles, but its not my database, so I'm happy to hack a fix)
We never deploy roles ourselves, so it doesn't matter to us devs that its a role or a user.

Related

setup AppPool on IIs 10, keySet does not exist

I am running a windows 2016 server, we are running IIs 10 on it and i need to be able to assert if there is an AppPool setup before i deploy a website. If it doesn't exist i need setup the AppPool with a specific user and password.
All of this is done using a release agent through Azure Devops.
The agent is running as a NON-ADMIN, and i all accounts involved are running as NON-ADMIN. I have no intention at all to run any admin accounts, for security reasons i want to give least privildges to all accounts involved.
when i try to set up a AppPool using appcmd.exe i get the error msg:
KeySet does not exist.
When running everything as admin it works (and i have absolutely no intention in running any of this as admin).
What i have tried:
i have added the non-admin account to the IIS_IUSRS group.
Made sure that the user has read permissions to the file: 76944fb33636aeddb9590521c2e8815a_GUID in the %ALLUSERSPROFILE%\Microsoft\Crypto\RSA\MachineKeys folder.
i have tried everything here: Error when you change the identity of an application pool by using IIS Manager from a remote computer
anyone that actually knows the cause of this problem?
UPDATE:
Microsoft clearly recommends that agents should be run using service accounts, which i am doing and i have no interest in giving build agents administrative rights to 1000s of servers when they clearly don't need that kind of powers actually. I want to restrict their powers to only be allowed to do what they need to do. I can't believe that giving everything admin is apparently the norm.
After a lot of googling, and i mean A LOT. I managed to solve this. And let me say, that it baffles me that "least privileged accounts" is not common practice in the Microsoft and windows world.
I found this excellent post by InfoSecMike locking down azure devops pipelines.
And we both have the exact same requirements and opinions on this topic.
You CLEARLY don't need admin rights to update IIs configurations (because that would be insane, right!?). The IIs configuration API does not care what rights you have, what you do need is access to certain files. But this is not documented. Microsoft themselves, just for simplicity, tells you that you need to be admin, and buries all the details really deep in documentation when this should be best practice. Also what amazes me is that no one questions it.
What you need is the following:
full access to C:\Windows\System32\inetsrv\Config
full acccess to C:\inetpub
read access to three keys in C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\
6de9cb26d2b98c01ec4e9e8b34824aa2_GUID (iisConfigurationKey)
d6d986f09a1ee04e24c949879fdb506c_GUID (NetFrameworkConfigurationKey)
76944fb33636aeddb9590521c2e8815a_GUID (iisWasKey)
The 2 first bullet points can be obtained if you make sure your service account is a member of the group IIS_IUSRS.
This group will not give you access to the keys. You need to manually give read permissions to these 3 keys to the agent user.
If you don't give access to these keys you will get the obscure error message
Keyset does not exist ( exception from HRESULT : 0x8009000D)
Which is an incorrect error if you ask me as it should be an IllegalAccessException with proper reason telling you that you don't have access to read the key because the keys are there, they do exist (nice code microsoft, maybe you should open source this so we can fix).
I'll leave with this quote from infosecmike.
The goal was to lock down the permissions of the Azure Pipeline Agent {...}. I started Googling, pretty sure I would find a way to achieve this goal. I didn’t. It’s surprising to not find an answer about this. It seems like the principle of least privilege does not apply anymore in a devops world.
This is why i prefer Linux over Windows. This is a simple task there.

UAC Elevation vs. Impersonation

(Skip to the bottom for the TLDR version.)
OK - so I have searched (really!) and all other UAC articles I have found seem to center on enabling, disabling, detecting or hiding UAC. My issue is not one of those, so here goes:
My user used to have the standard dual-token setup where I was in the Administrators group and the UAC's Consent UI would just ask me if I wanted to proceed. Now, we have separate administrative-level accounts that we need to use, and I have to authenticate with this new user. The problem I am having is that previously, starting an app as Administrator just elevated my current user, where now if I use the credentials of the new administrative user, whatever I am running runs AS that new user.
As an example, previously elevating CMD and typing whoami into the command prompt used to return my normal/current user, where it now returns the new administrative user.
This has serious negative consequences - since this is a new user, and an Administrative-level one, if any files are created using this new user, my normal user cannot write to or delete them unless I manually adjust permissions and ownership. If I use my development environment under the new account (e.g. I need to debug a service or work with a driver) and rebuild something, I end up with a bunch of files that I cannot manipulate unless I am an administrator. Likewise if I add a file while running as this new account - my SCM tool will not be able to update that file later unless it also runs under this new administrative account.
Also, Since a profile is associated with this user, things run under a completely different environment (different %USERNAME%, %USERPROFILE%, %LOCALAPPDATA%, etc.)
Installing an application will also work incorrectly if it is installed just for the current user (e.g. the "Just Me" option), instead of for all users. Things that are licensed to/in my normal user account also fail to function if run under the new account, because things are running as that new user.
The ripple effects of this change are getting larger and larger the more I work with it. So...
[TLDR] Is there a way to get temporary elevation of the current user without that user having the normal dual-token setup you get from being in the Administrative group? Or are you stuck with the impersonation behavior?

How can I have better priviledges management in Azure roles?

AFAIK when I set up my Azure roles I have only one way to specify how much priviledges the process running role code will have - by using <Runtime executionContext> XML tag.
However this looks coarse grained. If I specify "elevated" my code runs under "Local system" which is unlimited priviledges and if I specify "limited" my code runs under some low priviledges user that doesn't have priviledges my code needs.
Is there some convenient way to run Azure role code under some custom user that has limited priviledges that I myself would control?
Right now, your code will already run as a limited user. In fact, there are no users on the VM - it is using a SID injection technique to get a security context at all. From your question, it seems like you need more than a normal user, but less than an admin?
If you really want to have different permissions, you need to create some users (use Startup tasks and net add or DirectoryServices) and set permissions. All of this is scriptable.
The more challenging part comes now to run your code as that user. For this, you need to do what is called impersonation. Your more privileged code (an admin process typically) can obtain a token for a local user and use that to impersonate a user. The code then runs as the user and is restricted. Impersonation is a well covered topic in .NET and other languages.
If you want a clever example of running code as another user, check this post by David Aiken:
http://www.davidaiken.com/2011/01/19/running-azure-startup-tasks-as-a-real-user/

Write to HKEY_LOCAL_MACHINE on Windows 7 without Administrator privilleges

First of all, I realize this is a messy situation, but it's not of my design, and I'm just trying to help, and for that I need your help.
App A is getting installed automatically via SMS installer under the Administrator account, not the PC owner's User account. App A has a registry key defined in HKEY_LOCAL_MACHINE hive.
After App A is installed, we want to edit the above mentioned registry key, to assign the User's C:\Users\USER_ID\Documents\ folder (I'm told we don't don't know who the user is and don't have access to USER_ID during step 1).
I know all about UAC, Application Manifest, and requestedExecutionLevel. However, I'm told we can't expect that all users will be in the Administrators group on their machine.
Solution must be backwards compatible with Windows XP as well.
I'm searching for options to get `C:\Users\USER_ID\Documents\' into the 'HKEY_LOCAL_MACHINE' hive under the above listed conditions.
I found this thread that might be related to a similar situation, but I don't fully understand it yet (so I will give credit to anyone that explain it better):
Find out (read) logged in user in a cmd started as a different user
I also read something that rules out ClickOnce:
Clickonce + HKEY_LOCAL_MACHINE
After App A is installed with admin privileges you are trying to run an additional script as the local user who does not have admin privileges . In order for your secondary script to write to the local machine key it will have to be run with administrative privileges ..period. That said, you have basically two choices:
1) Use the RunAs command to run the script with elevated privileges and have the user type in a admin username and password to run the script with elevated privileges.
2) This is the better way imo - Since SMS is being leveraged as the delivery tool, use its capability to detect and use local client configuration settings to write the key at the time of installation.
So basically the SMS package would have to be setup to run only when the local user logs on one time so that SMS can grab the current user and write it to a file somewhere.. after that is completed SMS can run a separate package as the admin (user will get prompted) to do the software install looking for the file containing the user and then consequently updating the local machine key to the correct user my document path.
Enjoy!

Is there a way to suppress SQL03006 error in VS2010 database project?

First of all, I know that the error I am getting can be resolved by creating reference project (of type Database Server) and then referencing it in my Database project...
However, I find this to be overkill, especially for small teams where there is no specific role separation between developers and db admins..But, let's leave this discussion for another time... Same goes for DACs...Can't use DAC b/c of limited objects supported...
Question
Now, the question is: Can I (and how), disable SQL03006 error when building my Database project. In my case this error is generated because I am creating some users whose logins are "unresolved"...I think this should be possible I hope, since I "know" that logins will exist on the server before I deploy the script...I also don't want to maintain database server project just so I can keep refs resolved (I have nothing besides logins at server level)...
Workaround
Using pre/post deployment scripts, it is trivial to get the secript working...
Workaround Issue
You have to comment out user scripts (which use login references) for workaround...
As soon as you do that, the .sqlpermissions bomb out, saying there is no referenced users...And then you have to comment permissions out and put them in post deploy scripts...
The main disadvantage of this workaround is that you cannot leverage schema compare to its fullest extent (you have to specify to ignore users/logins/permissions)
So again, all I want is
1. to maintain only DB project (no references to DB Server projects)
2. disable/suppress SQL03006 error
3. be able to use schema compare in my DB project
Am I asking for impossible? :)
Cheers
P.S.
If someone is aware of better VS2010 database project templates/tools (for SQL Server 2008 R2) please do share...
There are two workarounds:
1.
Turn off any schema checking (Tools > Options > Database Tools > Schema Compare > SQL Server 200x, then the Object Type tab) for anything user or security related. This is a permanent fix
2.
Go through the schema comparison and mark anything user or security related as Skip and then generate your SQL compare script. This is a per schema comparison fix.
It should be obvious but if you already have scripts in your project that reference logins or roles then delete them and they won't get created.

Resources