Tuesday, November 25, 2014

Find Custom Config Section in web.config by Type instead of by String

Instead of calling Configuration ConfigurationManager.GetSection("name of section"), call the following:

CustomSection section = GetConfigSection(typeof(CustomSection)) as CustomSection;

This way, you don't have to hard code the name of the section into your code and it allows who ever is consuming your code to change section names and group them as they see fit.

You'll need to add the following code for the above function. You could add it to your config class and add strong typing or you could add it to a utility class.

/// <summary>
/// Instead of getting the config section by name, use this to get the config section by type. It will return the first section with a matching type. 
/// Thus if there are multiple sections with the same type, it will only return the first one.
/// Call like CustomMailWebEventProviderSection section = GetConfigSection(typeof(CustomMailWebEventProviderSection)) as CustomMailWebEventProviderSection;
/// </summary>
/// <param name="configSectiontype">Type of config section you're looking for</param>
/// <returns>Config section of the specified type or null if no section of that type is found</returns>
public ConfigurationSection GetConfigSection( Type configSectiontype )
    // Set it up and call recursive function
    Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
    return GetConfigSection(configSectiontype, config.Sections, config.SectionGroups);
// returns first config section that matchs the type we're looking for
public ConfigurationSection GetConfigSection(Type configSectiontype, ConfigurationSectionCollection sections, ConfigurationSectionGroupCollection groups)
    if (sections != null)
        foreach (ConfigurationSection section in sections)
            if (section.GetType() == configSectiontype)
                return section;
    if (groups != null)
        foreach (ConfigurationSectionGroup group in groups)
            ConfigurationSection section = GetConfigSection(configSectiontype, group.Sections, group.SectionGroups);
            if (section != null)
                return section;
    //section not found
    return null;

Tuesday, October 7, 2014

Microsoft SQL Useful Database Role for Service Broker: db_servicebroker

If you need to use the service broker for cache expiration or what not, you should create a service broker database role called db_servicebroker. Then assign any user that require the service broker this role. Below is the code to create the db_servicebroker role. It sets up all the database permissions needed:

CREATE ROLE [db_servicebroker] AUTHORIZATION [dbo]

GRANT CREATE SERVICE TO db_servicebroker;
GRANT CREATE QUEUE TO db_servicebroker;


GRANT REFERENCES ON CONTRACT::[http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification] TO db_servicebroker;

GRANT RECEIVE ON QueryNotificationErrorsQueue TO db_servicebroker;

Now any time a user requires service broker permissions you can just assign them to this role. You can also view all the users in this role and know who has service broker permissions.

I've left one thing out though, and that's schemas. The service broker uses the default schema of the user to create the needed sprocs, queues and services. Therefore there are two routes you can take. One is to use the same schema, usually dbo, and the other is to create a separate schema per user. I prefer the later. Then when you're looking at the sprocs and queues, you know who it belongs to. I also prefer separate schemas because of the about grant permissions. If you have separate schemas, the users will be sand-boxed into their own respective schema.

If you're going the single schema route, which I don't recommend, you'll need to run the following:

GRANT CONTROL ON SCHEMA::[dbo] to [db_servicebroker];
GRANT IMPERSONATE ON USER::DBO to [db_servicebroker];

Just add users to the db_servicebroker role. This basically will give whoever is in the db_servicebroker role full keys to the kingdom.  Which is not good.

A better approach is to create a separate schema per user, set the user as the schema owner and set the schema as the user's default schema, replacing <UserName> with the name of the user execute the following per user:

ALTER USER [<UserName>] WITH DEFAULT_SCHEMA=[<UserName>Schema]

Then just add the user to the db_servicebroker role.

Microsoft SQL Useful Database Role to Execute Stored Procedures: db_executor

I find it convenient to create a db_executor database role to give users the ability to execute stored procedures. This way you can look at the user's roles and just know they have the ability to execute stored procedures. Otherwise you have to go look at the permissions at the database level and most people forget or don't know to look there. You create the role as follows:

-- Create a db_executor role
CREATE ROLE db_executor 

-- Grant execute rights to the new role
GRANT EXECUTE TO db_executor 

Then add the user to the role as follows, replacing <UserAccount> with the name of the user:

EXEC sp_addrolemember N'db_executor', N'<UserAccount>'

or if you have a newer version of SQL server:

ALTER ROLE [db_executor] ADD MEMBER [<UserAccount>]

MSSQL Database/Server User/Login Mapping

This is just a quick post, mainly so that I can refer back to it when I forget the correct syntax.

In Microsoft SQL server there two separate principals. There is a principal (user) at the database level and there is a principal (login) at the server level. A login is mapped to one or more users in one or more databases. A password or an windows account is associated to the login. When you move a database or restore from one server to another, this mapping breaks and must restore it. People all too often drop the user and login and then recreated them both. If you have permissions associated to the user though, you'll have to recreate those. The best thing to do is just update the mapping (which just updates the associated SIDs in the appropriate system tables.)

USE [DatabaseName]
ALTER USER [UserAccount] WITH LOGIN = [LoginAccount]

It's simple, but since I'm not always in DB land, I find myself forgetting the syntax.

Tuesday, April 29, 2014

GP Update Remotely on Entire Domain

I stumbled across this when rolling out the Enhanced Mitigation Experience Toolkit (EMET 4.1.)
Group Policy is updated in the background every 90 minutes, with a random offset of 0 to 30 minutes, this means that it can take up to 2 hours for the update to actually apply to your client machines. 
 If you have a Window 2012 Domain Controller and you have not done this already I recommend you use a New feature in Windows 2012 Domain Controllers that is a templates that will open the correct ports on remote windows machines so as to be able to force a GP Update remotely, this could prove quite useful when one has to push changes in a quick manner like when responding to an incident. On a Domain Controller open PowerShell and run the following command to create and link the GPO, modify the DN so it will match your environment in this case it is for my lab domain acmelabs.com:
New-GPO –Name "Configure firewall rules for remote gpupdate" –StarterGpoName "Group Policy Remote Update Firewall Ports" | New-GPLink –target "dc=acmelabs,dc=com" –LinkEnabled yes 
Once it is linked and the policy has been applied to all machines in the domain you can invoke a Group Policy update across my domain from a Windows 2012 machine as Domain Admin in PowerShell: 
Get-ADComputer –filter * -Searchbase "dc=acmelabs,dc=com" | foreach{ Invoke-GPUpdate –computer $_.name -force}
One could modify the search base and limit the subset of computers being updated.  Very useful!

Tuesday, March 25, 2014

Small error/typo in MS-SMB2 documentation

In section Receiving an SMB2 WRITE Request of the MS-SMB2 documentation it says the following:

"If the server implements the SMB 3.02 dialect, SMB2_WRITEFLAG_WRITE_THROUGH is set in the Flags field of the request, SMB2_WRITEFLAG_UNBUFFERED is not set in the Flags field of the request, and Open.CreateOptions doesn't include the FILE_NO_INTERMEDIATE_BUFFERING bit, the server MUST fail the request with STATUS_INVALID_PARAMETER."


I emailed Tom Talpey at Microsoft about this.  He confirmed it was an error/typo and cc'd the dochelp@microsoft.com people.  They emailed me and let me know the update will appear in a future release of the MS-SMB2 document.

Monday, February 10, 2014

What's the Purpose of the User's Third-Party Root Certification Authorities Store?

I stumbled across something that I did’t think functioned as it should with regard to the Microsoft certificate store.  I’m no expert, so it’s quite possible I’m missing some bigger piece to the puzzle?

The short explanation:

If you place a root certificate in the user’s third-party root certification authorities’ store, certificate chaining validation to that root does not work.  The certificate does not show up in the user’s trusted root certification authorities’ store.  So what's the purpose of the User's Third-Party Root Certificate Authorities Store?

The long explanation:

I was tasked with pushing out a partner’s root CA certificates and a partner’s intermediate CA certificates via GPO.  Since I am only somewhat familiar with how the Microsoft Certificate Store worked, I decided to dig in a bit. 

I’m going to summarize briefly my understanding of the components involved.  

First, the certificate store is made up of logical stores which are made up of physical stores.  This separation allows an abstraction that allows for better certificate management.  The logical stores we’re concerned about here are the “trusted root certificate authorities”, the “intermediate certificate authorities” and the “third-party root certification authorities.”

One can manage certificates by user, computer or service.  For this discussion, we will only concern ourselves with user and computer.  The user and computer both have the three logical stores we’re concerned about; the root, the intermediate CA and the 3rd party root.  The computer’s root, intermediate and 3rd party logical stores are made up of different physical stores than the user’s root, intermediate and 3rd party logical store.

To view this arrangement, add the certificate snap-in to the mmc console twice; once for the current user account (“My User Account”) and once for the computer account.  For each snap-in added be sure to right-click the certificate node and select View -> Options.  Then check “Physical certificate stores”.  The following link will show you how to do this and describe the physical stores in a bit more detail: http://blogs.msdn.com/b/muaddib/archive/2013/10/18/understanding-certificate-stores-and-publishing-certificates-for-smart-card-logon.aspx

Here is a screenshot for reference:

The directions from the partner seemed a little vague.  They tell you to put the root certs in the trusted root certification authorities' store.  From what I've read, it would seem to make more sense to put the partner’s root certs in the 3rd party cert store.  It seems as though the trusted root store is meant to be for Microsoft root certs and your organization’s root certs.  It makes sense to put some other organization’s root certs in the 3rd party root store to keep things more organized.  The logical trusted root CA store appears to contain the 3rd party root CAs, so what’s the difference?  It appears that if you put the root cert in the 3rd party CA store that it will show up in the trusted roots CA store.

To test things out before using GPO, I imported everything manually and stored things in the registry physical stores.  I sat there with two questions though. 

The first question was, should the partner's root certificates go in the third-party root certification authorities' store or the trusted root certification authorities' store?  I’m thinking the 3rd party root store, but I’ll test both out.

The second question was, do we distribute the partner’s certs to the user stores or the computer stores?  For our scenario, technically it’s just the users that need the partner’s root certs, not the computers. 

The partner’s intermediate certs were pretty straight forward. I figured if we were going to push these certs out by user then they would go in the user intermediate store.  If we were going to push these certs out by computer, then they would go in the computer intermediate store.

So there were four places to try placing the partner’s root certs.

Trusted Root
3rd Party Root
 Didn’t work

When I view a certificate that was chained to one of the partner’s roots, the chain appeared valid when trying the root in all stores except the 3rd party root of the user.

Below is a diagram of how I inferred the physical stores are related to the logical stores:

If you place a cert in the 3rd party root CA of the computer, it will show up in the trusted root CA of the computer, the trusted root CA of the user and the 3rd party root CA of the User.

If you place a cert in the trusted root CA of the computer, it will show up in the trusted root CA of the User.

If you place a cert in the 3rd party root CA of the user, it will not show up in the trusted root CA of the user.  As a result, certificate chaining does not appear to work when the root cert is stored in the user's 3rd party root CA store.
I've tested this and chaining validation does not work when the root cert is in the user's 3rd party CA store.  I don't get it.  Is this the way it’s supposed to work?  Why?  Wouldn't you want the certificate to show up in the user’s trusted root certification authorities’ logical store if you put it in the user’s third-party root certification authorities’ logical store?  Should there be a link in the user’s trusted root CA logical store to the user’s third-party root CA store?

What’s the purpose of the user’s third-party root certificate authorities store??

Is the whole third-party root CA store a relic from the past that exists only to not break compatibility?

So I started exploring this further.  

I know from my digging that the computer third-party root CA store is still in use.  Microsoft uses it to place the root certificates you download from them when you browse a secure site.

"Root certificates on Windows Vista and later versions are distributed through the automatic root update mechanism. That is, they are distributed through the root certificate. When a user goes to a secure website (by using HTTPS SSL), reads a secure email message (S/MIME), or downloads an ActiveX control that is signed (code signing), and then encounters a new root certificate, the Windows certificate chain verification software checks Microsoft Update for the root certificate. If the software finds the root certificate, the software downloads the current Certificate Trust List (CTL). The CTL contains the list of all trusted root certificates in the program and verifies that the root certificate is listed there. Then, it downloads the specified root certificate to the system and installs the certificate in the Windows Trusted Root Certification Authorities Store. If the root certificate is not found, the certificate chain is not completed, and the system returns an error."

So I know the computer 3rd-party root CA store is still in use.  What about the user equivalent?  Logged in as a non-admin, I browsed to a site secured with https.  The certificates downloaded from Microsoft by browsing to this site went into the computer's 3rd-party root CA registry physical store.  Nothing in the user's 3rd-party root CA registry physical store.

I started to look at the GPO options available.  Well it doesn't even look like one can deploy to either the user or computer third-party root certification authorities store via GPO?  Even though the physical view of the certificate stores would lead one to believe otherwise.  Is this something that was deprecated yet still lingering around?

  • There is an option to disable users from installing certs into their trusted root CA store.  Unchecking "Allow user trusted root CAs to be used to validate certificates" will removed the physical registry store link from the user's trusted root CA logical store. 
  • There is an option to disable trust of third party root CAs.  Under "Root CAs the client computer can trust" select "Only Enterprise Root CAs."  This removes the third-party physical store link from the trusted root CAs logical store on the computer.  Which intern removes those third-party CA's from the user's trusted root CA store.  Effectively rendering all root certificates downloaded from ms useless.

These two settings would effectively make it so that users/computers in the enterprise would only be able to trust the certificates that you explicitly pushed out.

Back to the user's 3rd-party root CA store.  If you look at the physical stores under the user's 3rd-party root CA store, they are Registry, Group Policy and Local Computer.  The registry store doesn't appear to be used and the group policy store doesn't appear to be used.  That leaves the local computer store.  This appears to be a link from the computer's 3rd-party root CA registry physical store.  So at the very least we could say that the user's 3rd-party root CA logical store exists so that non-admin user's can view what 3rd party root certs have been downloaded from Microsoft.

After all this, I still can't seem to find a solid purpose/explanation for the user's third-party root certification authorities store.  All I can think of is it exists for backward compatibility and for a non-admin view into the computer's third-party root CA store.  Any body know?