Welcome to MSDN Blogs Sign in | Join | Help

How to determine virtual machine host name "virtual server"

Recently had a problem where the lab folks forget where my VM was installed to and I needed some RAM added to it.  I needed to find the physical host name of the machine the VM was running on.  Turns out that there is a handy dandy reg key one the VS devs pointed out to me:

 HKLM\Software\Microsoft\Virtual Machine\Guest\Parameters\PhysicalHostName

Hope it helps someone, I spent quite some time trying to figure it out on my own.

 

spat

 

Posted by SpatDSG | 0 Comments

More Kerberos fun with PAC’s- decrypt the PAC

I had been meaning to blog about this for a while, and recently was teaching a class when a friend of mine looked into the exact steps and issues – thanks Woody.

It may be interesting to peek into the PAC every once in a while and make sure everything is OK. Yaknow – like a long lost cousin. See http://blogs.msdn.com/spatdsg/archive/2007/03/07/pac-validation.aspx  for more info on PAC data

This is good for labs – not so much for production. But here goes.

It’s laid out here: http://wiki.wireshark.org/Kerberos

1. Download the ktexport utility - http://www.ioplex.com/utilities/

2. Run it on your DC against LSASS.EXE’s PID

3. C:\TEMP\ktexport.exe 376

4. It will create a file called sam.keytab

5. Create a directory called c:\temp

6. Copy sam.keytab to c:\temp.

7. Copy the wireshark trace to c:\temp

8. Open the trace in wireshark

Go to Edit -> Preferences:

clip_image002

Enabled the ability to decrypt the blobs.

Specify the sam.keytab file – no path info as it does not seem to like it. ( for example c:\temp\sam.keytab does NOT work )

clip_image004

Now – I have found I need to restart Wireshark sometimes, but check your kerb data – like an AS_REP packet and you should see:

  AuthorizationData AD-IF-RELEVANT

                        Type: AD-IF-RELEVANT (1)

                        Data: 308202D2308202CEA00402020080A18202C4048202C00400...

                            IF_RELEVANT AD-Win2k-PAC

                                Type: AD-Win2k-PAC (128)

                                Data: 040000000000000001000000300200004800000000000000...

                                    Num Entries: 4

                                    Version: 0

                                    Type: Logon Info (1)

                                        Size: 560

                                        Offset: 72

                                      PAC_LOGON_INFO: 01100800CCCCCCCC200200000000000000000200C0C1160B...

                                            unknown MIDL blob

                                                Unknown: 0x00081001

                                                Unknown: 0xcccccccc

                                                Blob Length: 544

                                                Unknown: 0x00000000

                                            PAC_LOGON_INFO:

                                                Referent ID: 0x00020000

                                                Logon Time: Mar 25, 2009 16:25:54.415046400

                                                Logoff Time: Infinity (absolute time)

                                                Kickoff Time: Infinity (absolute time)

                                                PWD Last Set: Mar 18, 2009 12:31:33.473204800

                                                PWD Can Change: Mar 19, 2009 12:31:33.473204800

                                                PWD Must Change: Apr 30, 2009 11:19:05.216948800

                                                Acct Name: shannon

                                                    Length: 14

                                                    Size: 14

                                                    Character Array: shannon

                                                        Referent ID: 0x00020004

                                                        Max Count: 7

                                                        Offset: 0

                                                        Actual Count: 7

                                                        Acct Name: shannon

                                                Full Name: shannon

                                                    Length: 14

                                                    Size: 14

                                                    Character Array: shannon

                                                        Referent ID: 0x00020008

                                                        Max Count: 7

                                                        Offset: 0

                                                        Actual Count: 7

                                                        Full Name: shannon

                                                Logon Script

                                                    Length: 0

                                                    Size: 0

                                                    Character Array

                                                        Referent ID: 0x0002000c

                                                        Max Count: 0

                                                        Offset: 0

                                                        Actual Count: 0

                                                Profile Path

                                                    Length: 0

                                                    Size: 0

                                                    Character Array

                                                        Referent ID: 0x00020010

 

Have fun!

Spat

 

 

OK so some folks have let me know that Ktexport crashes LSASS.EXE - obviously no fun.

So here is what I tested:

I installed WindowsServer2003-KB843071-x86-enu.exe from "Ktpass.exe may not create a Kerberos keytab file successfully when you use the /target switch and the /mapuser switch on a Windows Server 2003-based computer or on a Windows 2000-based computer"

  • In this case the user's UPN is Shannon@mil
  • The users samAccountName is  Shannon
  • The users password is Password.
  • The users domain is request132027.local

I ran the following:

 

C:\TEMP>ktpass.exe /out shannon.keytab /princ shannon@MIL /crypto RC4-HMAC /pass Password /ptype KRB5_NT_PRINCIPAL

Key created.

Output keytab to shannon.keytab:

Keytab version: 0x502

keysize 45 shannon@MIL ptype 1 (KRB5_NT_PRINCIPAL) vno 1 etype 0x17 (RC4-HMAC) keylength 16 (0x76756bad6a045177f68d583c1152e3c5)

I used this keytab in wireshark:

clip_image002[1]

Seemed to work out OK.  If you were doing it for a machine it would not work since you don't know the machine password .. I have not tried setting the password etc..

spat

 

 

 

Posted by SpatDSG | 3 Comments
Filed under:

Informal survey..iPhone VS Windows Mobile..

 

Coming from support, I have seen many different causes for crashes and hangs,  memory leaks and BSOD’s.  Of course, again I am colored by my experiences  and it reflects in the title of my blog “When things go wrong.. “  I only see the bad side of things.   But, I have long held the opinion that Windows is a  stable OS for the most part, and I know for a fact that many many root causes of cases I saw were 3rd party applications and drivers.

Anyway, to the point.   I was rebooting my Samsung Epix ( again ) the other day and was quite frustrated with the experience.  I started to think, maybe I have too many applications running.

But isn’t that part of the reason for me getting the WinMobile phones?
 

 I love the fact that I can RDP to my desktop, watch a ripped DVD , chat on IRC and play games or listen to podcasts all on the same device.   I run CORE media player, RDP desktop client, have any number of games and 3 different mobile browsers on my phone.  Is the cost for this flexibility, the stability of my phone?  If I cannot use it for its core function, a phone, but it works great as a ‘mini computer’  -- Am I OK with that? 

Here are my specs – and the apps which are on almost all the time.

·         Samsung Epix – WinMo 6.5

·         AE button plus ( runs in background )

·         Audio Notes

·         Google Maps

·         CorePlayer

·         Live Mesh

·         Newsbreak

·         Pocket IE

·         SkyFire

·         Pocket Outlook

·         ActiveSync

·         BlueTooth on for headset ( runs in background )

·         Voice Command On ( runs in background )

 

Now, I keep hearing about this Apple App store with bajillions of apps – forget the recent report that said no one uses them after the first week or so.

I asked a few co-workers if their iPhones  needed to be rebooted and if so, how often.  Most of them said almost never – then the follow up questions “ How many 3rd party apps do you run?” Almost none.

 So does an iPhone suffer from the same dilemma? How often  do you iPhone lovers users have to reboot your phone? Are you a heavy app user or more of a core system user?

Do you feel that you can ( or should have to ) sacrifice  stability for extensibility?

random thoughts on a snowy Sunday afternoon...

 

Spat

 

 

Posted by SpatDSG | 8 Comments

There and back again.. the journey of a bug in ADFS

Let's look at a bug fix.. end to end.

So back in November, my friend Jim Simonet had posted a question about a problem with ADFS using ADAM as the auth store and specifying that it connect via  LDAP over SSL.

He could connect to ADAM via LDP on 636, so we knew ADAM and the certificate validation\chaining process seemed OK.
With SSL it was failing and the logs show:

 

2008-10-28T17:11:41 [INFO] Client is unauthenticated.  Attempting to collect credentials.

2008-10-28T17:11:41 [INFO] Requesting token for https://adfsweb.treyresearch.net:8081/claimapp/ with username adam@treyresearch.net.

2008-10-28T17:11:41 [INFO] InternalRST: target = https://adfsweb.treyresearch.net:8081/claimapp/, credtype = urn:oasis:names:tc:SAML:1.0:am:password, userhint = dam@treyresearch.net, store =

2008-10-28T17:11:41 [INFO] GetClaimsForUserNameWorker (LDAP): called for user adam@treyresearch.net

2008-10-28T17:11:41 [VERBOSE] GetClaimsForUserNameWorker (LDAP): Got COMException 18446744071562534970: The server is not operational.

2008-10-28T17:11:41 [INFO] AccountStoreCollection.InternalGetClaimsForUser: User adam@treyresearch.net logon handled non-authoritatively with LdapFailed by selected store ldap://adfsweb.treyresearch.net

2008-10-28T17:11:41 [VERBOSE] Processing FS response: policy version is d5a48817-e9fc-4ab6-b7ef-2d99642bbe6b - 208

2008-10-28T17:11:41 [VERBOSE]     Creds verification: AccountStoreDisplayName = ADAM Account Store

2008-10-28T17:11:41 [VERBOSE]                         AccountStoreType = LdapDirectoryType

2008-10-28T17:11:41 [VERBOSE]                         AccountStoreTypeDisplay = AD/AM Directory

2008-10-28T17:11:41 [VERBOSE]                         AccountStoreUriStr = ldap://adfsweb.treyresearch.net/

2008-10-28T17:11:41 [VERBOSE]   User Validation Info: ErrorCode = -2147016646

2008-10-28T17:11:41 [INFO] Token issuance request to FS failed: ValidationFailure

 

Note the highlighted section above.

Logging is always a good place to start, if you have the source code of course.

All of the web.security stuff  which includes GetClaimsForUserNameWorker  is in managed code.  I am still making my way through debugging managed code and am not entirely comfortable with it ( in other words I have not really done enough of it ),  I know folks who swear it is easier but if you ask me, doing this :

1.       !name2ee [Assembly name (including extension] [Class Full Namespace]. For example: !name2ee SyncBlkDeadLock.exe SyncBlkDeadLock.Form1. That is the class on which we want to place a breakpoint in one of its methods. The output will look like this.

2.       !dumpmt -md [MethodTable handle that we got from the previous command]. For Example: !dumpmt -md 0×00a8543c. The output will look like this.

3.       !dumpmd [MethodDesc handle that we got from the previous command]. For Example: !dumpmd 0×00a853d8. This is the handle for the method
SyncBlkDeadLock.Form1.Thread1Handler().The output will look like this.

4.       In the field “Method VA” we now have th method Virtual Address and we can set a breakpoint on that address.

Is not easier than this:

1.       bp foo!func

Maybe that's why I have not really dug into it much. But, to each their own. (  I know I can no longer avoid it either via debugging it, or writing it -- , much like I can no longer avoid PowerShell )  So, due to my lack of time, and general propensity to fall back on familiar tools and ways.. I figured that something is eventually going to call into wldap32.dll – either directly, or  via the slightly higher ADSI functions.

I tend to try to nail things at the lowest level. What I mean is, if I know some hunk of managed code is calling to ADSI, which is calling to WLDAP32, which is calling to the Network.. I may want to start at the very lowest level in order to at least get an idea of where things are coming from. Does that make sense? On we go.

I knew I didn’t need to catch it at the network layer, a little overkill there. So I decided on wldap32 – specifically wldap32!ldap_connect  , since this is where we connect.

This eventually returned 0x51 LDAP_SERVER_DOWN , but if I dug deeper it returned 0x35 LDAP_UNWILLING_TO_PERFORM

err.exe shows us ( http://www.microsoft.com/downloads/details.aspx?FamilyId=BE596899-7BB8-4208-B7FC-09E02A13696C&displaylang=en  )

 

C:\TEMP\Err>err 35

# for decimal 35 / hex 0x23 :

  BTH_ERROR_LMP_TRANSACTION_COLLISION                           bthdef.h

  FAT_FILE_SYSTEM                                               bugcodes.h

# Disable or uninstall any anti-virus, disk defragmentation

<snip>

  ERROR_BAD_NETPATH                                             winerror.h

# The network path was not found.

  LDAP_UNWILLING_TO_PERFORM                                     winldap.h

 

So you see – the lower ldap levels set LDAP_UNWILLING_TO_PERFORM , which got set to LDAP_SERVER_DOWN which the  ADFS logs translated into "The server is not operational".  This has long been a pet peeve of mine.  If we could only consistently maintain the REAL error returned, I think it would help a lot of folks ( IMO ) . But, there are so many layers and layers of code that this is nearly impossible and is the ROI really worth it?  How could it be implemented across so many layers?

Anyway.. OK we know that 0x35h is not a good thing, so how to find where this was set?

This take s little bit of digging, but  the windbg command “pc”  (step to next call ) help a bit and just keep an eye on error returns. Narrowed it to here..

 


ChildEBP RetAddr 
01c7e0e8 76f24d0c wldap32!LdapSetupSslSession
01c7e138 76f1786f wldap32!OpenLdapServer+0x700
01c7e158 76f1834c wldap32!LdapConnect+0x169
01c7e178 76dc457b wldap32!ldap_connect+0x26
01c7e19c 76dc43fb adsldpc!LdapOpen+0x1cc
01c7e1cc 76dc42fe adsldpc!LdapOpenBindWithDefaultCredentials+0x10e
01c7e634 712d29aa adsldpc!LdapOpenObject2+0x128
01c7e8b4 712d284c adsldp!GetServerBasedObject+0x18f
01c7ed0c 712d52f3 adsldp!GetObjectW+0x69
01c7ed38 76df1bbb adsldp!CLDAPNamespace::OpenDSObject+0x34
01c7ed90 01cdbc00 activeds!ADsOpenObject+0xb2
*** WARNING: Unable to verify checksum for system.directoryservices.ni.dll
01c7ee30 67170eb3 CLRStub[StubLinkStub]@1cdbc00
01c7ee8c 67166575 system_directoryservices_ni!System.DirectoryServices.Interop.UnsafeNativeMethods.ADsOpenObject(System.String, System.String, System.String, Int32, System.Guid ByRef, System.Object ByRef)+0x1f
01c7eee0 67166405 system_directoryservices_ni!System.DirectoryServices.DirectoryEntry.Bind(Boolean)+0x14d
01c7eef0 67167316 system_directoryservices_ni!System.DirectoryServices.DirectoryEntry.Bind()+0x25
01c7ef2c 04867375 system_directoryservices_ni!System.DirectoryServices.DirectoryEntry.RefreshCache(System.String[])+0x2e
Unable to load image c:\windows\assembly\gac_msil\system.web.security.singlesignon\1.0.0.0__31bf3856ad364e35\system.web.security.singlesignon.dll, Win32 error 0n2
*** WARNING: Unable to verify checksum for system.web.security.singlesignon.dll
*** ERROR: Module load completed but symbols could not be loaded for system.web.security.singlesignon.dll
01c7f240 04866d38 system_web_security_singlesignon!System.Web.Security.SingleSignOn.LdapDirectoryAccountStore.GetClaimsForUserNameWorker(System.String, System.String, System.Web.Security.SingleSignOn.TrustingRealm, System.Web.Security.SingleSignOn.ClaimContext, System.Web.Security.SingleSignOn.UserValidationInfo ByRef, Boolean ByRef, System.String ByRef)+0x5f5
01c7f2b4 048669af system_web_security_singlesignon!System.Web.Security.SingleSignOn.LdapDirectoryAccountStore.InternalGetClaimsForUser(System.Web.Security.SingleSignOn.ClientCredentialInfo, System.Web.Security.SingleSignOn.TrustingRealm, System.Web.Security.SingleSignOn.ClaimContext, System.Web.Security.SingleSignOn.UserValidationInfo ByRef, Boolean ByRef, System.String ByRef)+0x100
01c7f2d0 04865f4e system_web_security_singlesignon!System.Web.Security.SingleSignOn.AccountStoreCollection.InternalGetClaimsForUser(System.Web.Security.SingleSignOn.ClientCredentialInfo, System.Web.Security.SingleSignOn.TrustingRealm, System.Web.Security.SingleSignOn.ClaimContext)+0x177
01c7f3b8 0486576a system_web_security_singlesignon!System.Web.Security.SingleSignOn.FederationServerService.InternalRST(System.String, System.String, System.String[], System.String, Byte[], System.String, System.Web.Security.SingleSignOn.RSTRResult ByRef)+0x79e
<snip>


 

 

0:002> r

eax=00000000 ebx=00000000 ecx=7ffab000 edx=01742428 esi=01742338 edi=01742428

eip=76f306df esp=01c7e0dc ebp=01c7e0e8 iopl=0         nv up ei pl nz na po nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202

wldap32!LdapSetupSslSession+0xf3:

76f306df 6a35            push    35h

 

Anywho – once I found where it was being set, I can see that it was examining the flags passed to it and failing based on them.

The ldap options included one or both ( I can’t  recall exactly ) of the following flags:

LDAP_OPT_SIGN
0x95

Determines the Kerberos signing state or enables Kerberos signing. The LDAP_OPT_SIGN session option should be enabled prior to binding using the LDAP_AUTH_NEGOTIATE flag. Cannot be used over an SSL connection. When used with Windows XP and Windows Server 2003, NTLM signing is also supported.

LDAP_OPT_ENCRYPT
0x96

Enables/disables Kerberos encryption prior to binding using the LDAP_AUTH_NEGOTIATE flag. Cannot be used over an SSL connection.
When used with Windows XP and Windows Server 2003, NTLM encryption is also supported.

The key of course, is the phrase "Cannot be used over an SSL connection". So , off Jim goes to file a bug,,,

In between then and now, lots of hand waving :

Then there is the PM, Dev and Test reviews, possible security reviews and much talk about WAR and customer impact etc.. but eventually we get there.

The public KB is now available:

AD FS cannot connect to an ADAM store over an SSL connection on a Windows Server 2003 R2-based server

http://support.microsoft.com/?kbid=959923

And that, is the story of that hotfix

Spat

 

 


 

Joining a domain via Smartcards

http://technet.microsoft.com/en-us/library/cc721959.aspxundefined

A snip from the article:

Smart card root certificate requirements for use when joining a domain

When using a smart card to join a domain, the smart card certificate must comply with one of the following conditions:

The smart card certificate must contain a Subject field that contains the DNS domain name within the distinguished name. If it does not contain this field, resolution to the appropriate domain will fail, causing the domain join with smart card to fail.

The smart card certificate must contain a UPN in which the domain part of the UPN must resolve to the actual domain. For example, the UPN "username@engineering.corp.example.com" would work, but "username@engineering.example.com" would not work because the Kerberos client would not be able to find the appropriate domain.

The solution for both of the listed conditions is to supply a hint (enabled via the X509HintsNeeded registry setting) in the credentials prompt when joining a domain.

If the client computer is not joined to a domain, then the client will only be able to resolve the server domain by viewing the distinguished name on the certificate (as opposed to the UPN). For this scenario to work, the Subject field for the certificate must include "DC=" for domain name resolution.

To deploy root certificates on smart cards for the currently joined domain, the following command can be used:

certutil –scroots

Just a note - this has some issues unless you also deploy this hotfix..  http://support.microsoft.com/kb/957656

This is a post Vista SP1 fix..

 

Spat

Posted by SpatDSG | 0 Comments
Filed under:

More fun with Kerberos and Web Sites

SPN’s.

Service Principal Names.

I am not going to go into the details of how SPN’s are used right now, see my other posts on Kerberos or go use your favorite search engine to determine how they are used.

Most of this post will relate to web sites and access to sites via Kerberos.

Scenario:

Servername: 2k8STS1.CONTOSO.COM
A Record =2k8STS1.CONTOSO.COM
CNAME record = ALIAS.BOGUS.COM

So of course, now when I ping ALIAS.BOGUS.COM it will hit 2k8STS1.CONTOSO.COM

Now – from IE, when I type in HTTP://ALIAS.BOGUS.COM , what SPN will be in the ticket request?

clip_image002

How come it was not ALIAS.BOGUS.COM ?

If you want it to use the name as typed into the browser, for the TGS_REQ, then you need to apply http://support.microsoft.com/kb/911149 ( 2k8 already has the code to honor it so all you need is the reg key )

And create the key = FEATURE_USE_CNAME_FOR_SPN_KB911149

Afterwards IE will use the CNAME for the SPN in the TGS_REQ.

clip_image004

The other item you may want to be aware of is :

http://support.microsoft.com/default.aspx/kb/908209

From the KB:

Internet Explorer 6 cannot use the Kerberos authentication protocol to connect to a Web site that uses a non-standard port in Windows XP and in Windows Server 2003

You have two Web sites that have different ports and identities. These two Web sites are running on the same computer. For example, Web site 1 runs on port 80 under identity "id1" and Web site 2 runs on port 81 under identity "id2”.

• Both the Web sites use Kerberos authentication protocol version 5.

• You use the Setspn utility to declare the Service Principal Name (SPN) for Web site 2.

• You use the same host name to connect to Web site 1 and to Web site 2. You use Microsoft Internet Explorer 6 to make this connection.

For example, you use http://examplewebserver to connect to Web site 1 and http://examplewebserver:81 to connect to Web site 2. In this example, you use the same examplewebserver host name to connect to both Web sites.

In this scenario, Internet Explorer 6 can use the Kerberos protocol to connect to Web site 1. However, Internet Explorer 6 cannot use the Kerberos protocol to connect to Web site 2.

 Have fun.. spat

 

Posted by SpatDSG | 1 Comments
Filed under:

James saved me many hours of pain..

 

Gotta love the internet. The Tubes.

I was trying to install\reinstall IIS in Windows Server 2008 and it would not install.

 

Web Server (IIS)
   Error: Attempt to install IIS Management Console failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Static Content Compression failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install HTTP Logging failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Static Content failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Directory Browsing failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install HTTP Errors failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Request Monitor failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Request Filtering failed with error code 0x80070643.  Fatal error during installation
   Error: Attempt to install Default Document failed with error code 0x80070643.  Fatal error during installation
   The following role services were not installed:
   Web Server
      Common HTTP Features
         Static Content
         Default Document
         Directory Browsing
         HTTP Errors
      Health and Diagnostics
         HTTP Logging
         Request Monitor
      Security
         Request Filtering
      Performance
         Static Content Compression
   Management Tools
      IIS Management Console

Before I spent any number of hours tshooting this , I decided to hit the internet with a quick search. I held out little hope of finding a resolution for such a horrid looking error.

But - within 2 links I hit on this one -- http://social.technet.microsoft.com/forums/en-US/winserversetup/thread/1486efdd-1dbb-477a-9c9e-af8a8fb81c24/

Hoorah!!

 

Here's to you James B White from   C.S.H. Consultants Pty Ltd.  - your attitude of "This has been raised before, however that person opted for a reinstall before it got anywhere. I really dont want to do that."  saved me a boatload of time this morning.  Thanks to you,  I fixed it between eating breakfast and brushing my teeth.

One more thing - just in case the link above goes away - here was James resolution:

 

  • de-feature "WAS" Windows Process Activation Service (note it deleted more of the IIS roles or said it was)
  • re-role IIS7 & IIS6 and all subroles - worked okay
  • re-feature "WAS" Windows Process Activation Service - worked okay 
  •  

    Spatdsg

     

     

    Posted by SpatDSG | 2 Comments
    Filed under:

    Honey, I lost the (private) keys -- EFS keys missing?

     

     

    Interesting  EFS issue the other day..

    Customer was rolling  out EFS so they set up DRA's and this worked great. When they encrypted files the DRA's  showed up just fine in the file information. However, when they went to decrypt a file via the assigned DRA account – it failed to recover the file.

    Efsinfo.exe showed:

    Users who can decrypt: 

          CUST\bob (bob(bob@CUST.com)

          Certificate thumbprint: A453 6DE7 2AB7 93EA DF34 D30E F542 FEF5 960E 56EF

    Recovery Agents: 

      Unknown (DataRecoveryAgent1(JOE1@CUST.com)) 

        Certificate thumbprint: F456 453E F3E2 876A A435 5633 BF5A F45E F5DF 6C0B  

        Unknown (DataRecoveryAgent2(JOE2@CUST.com)

        Certificate thumbprint: FE23 4553 367E B94F 6F42 ED8F E3FB FEC5 C27D B32A

     

     

    The user had the certificate imported to the user’s store:

    Note the thumbprint ( hash )  shows on the file and is the same cert in our store.

     

     

    certutil -store -v -user MY "F456 453E F3E2 876A A435 5633 BF5A F45E F5DF 6C0B"

    ...

      CERT_KEY_PROV_INFO_PROP_ID(2): 

        Key Container = {A1D09078-2F06-48B3-94EC-6DD4589068BC}

     

        Provider = Microsoft Enhanced Cryptographic Provider v1.0

        ProviderType = 1 

        Flags = 0

        KeySpec = 1 

     dbd967c49d609634bf2397ff5ef4c1b7_8e2fe22f-67c1-46eb-8b31-11c519c0cc77

     

    Private key is NOT exportable

    Encryption test passed

     

     

     

    When you see  “Encryption test passed”   displayed by certutil.exe, this means that it successfully encrypted data via the public key and decrypted the data via the private key .

     

    This is typically a good test to determine if you have access to the private key and you can use it.  But, in this case the decryption\recovery was still failing.

     

    Unfortunately, there is no logging in the security subsystem to determine why it was failing the recovery. After a debug  we could see that it was failing in CryptAcquireContext with error 0x80090016  NTE_BAD_KEYSET

     

    MSDN documentation states:

    NTE_BAD_KEYSET( 0x80090016L )

     

    The key container could not be opened. A common cause of this error is that the key container does not exist. To create a key container, call CryptAcquireContext using the CRYPT_NEWKEYSET flag. This error code can also indicate that access to an existing key container is denied. Access rights to the container can be granted by the key set creator by using CryptSetProvParam.

     

    So why was certutil.exe able to encrypt and decrypt using this key?

     

     

    Turns out that certutil.exe uses CryptAcquireCertificatePrivateKey whereas other code ( the EFS code ) goes  to the certificate property, get the keyprovinfo, calls CryptAcquireContext with the CSP name and key container name.

     

    typedef struct _CRYPT_KEY_PROV_INFO {
      LPWSTR pwszContainerName;
      LPWSTR pwszProvName;

      DWORD dwProvType;
      DWORD dwFlags;
      DWORD cProvParam;
      PCRYPT_KEY_PROV_PARAM rgProvParam;
      DWORD dwKeySpec;

     

    } CRYPT_KEY_PROV_INFO,
     *PCRYPT_KEY_PROV_INFO;

     

     

    Now, if the CRYPT_KEY_PROV_INFO is incorrect, or the container is incorrect this will fail.

     

    In order to correct this information we ran:

                    certutil -repairstore -user MY "F456 453E F3E2 876A A435 5633 BF5A F45E F5DF 6C0B"

     

    The  –repairstore fixed  the problem of an incorrect container and we then can decrypt the files correctly.

     

    Unfortunately, I never did get more information as to why or how we got into this state.. too bad.  If someone runs into this and feels like helping me out – shoot me mail BEFORE you try and fix it like this J

     

    Thanks!

     

    SpatDSG

    Posted by SpatDSG | 0 Comments
    Filed under:

    Kerberos domain routing

    So the scenarios is pretty simple.

    Forest trust like so:

     

    image

     

     

    Basic problem. User tried to access sharepoint and fails to use Kerberos.

     

    So we can review the end to end process ( still at a high level  )

     

    1.       User logs on

    2.       User gets TGT for kz.com domain

    3.       User requests a TGS for http/AMSH

    4.       DC doesn't find the SPN

    5.       DC queries the GC for all servers in the forest for the SPN

    6.       SPN not  found

    7.       DC (GC )  checks its forest trust info for trusts that  are established with its forest, and, if found, it compares the name suffixes listed in the forest trust trusted domain object (TDO) to the suffix of the target SPN to find a match

    a.       let's examine that bit of info for a minute.

     

     

    Here is the   data from the AD, grabbed from both sides of the trust.

     

     

    dn: CN=kz.com,CN=System,DC=spat,DC=com

    changetype: add

    objectClass: top

    objectClass: leaf

    objectClass: trustedDomain

    cn: kz.com

    distinguishedName: CN=kz.com,CN=System,DC=spat,DC=com

    instanceType: 4

    whenCreated: 20080815081653.0Z

    whenChanged: 20080815081700.0Z

    uSNCreated: 28889

    uSNChanged: 28891

    showInAdvancedViewOnly: TRUE

    name: kz.com

    objectGUID:: 9V8zcH6/i0Wbt//1qEmeAw==

    securityIdentifier:: AQQAAAAAAAUVAAAAucwqv/m5b+9l/yCu

    trustDirection: 2                                                     #define TRUST_DIRECTION_OUTBOUND        0x00000002

    trustPartner: kz.com

    trustPosixOffset: -2147483648

    trustType: 2                                                            #define TRUST_TYPE_UPLEVEL              0x00000002 

    trustAttributes: 8                                    #define TRUST_ATTRIBUTE_FOREST_TRANSITIVE  0x00000008 

    flatName: KZ

    objectCategory: CN=Trusted-Domain,CN=Schema,CN=Configuration,DC=spat,DC=com

    isCriticalSystemObject: TRUE

    msDS-TrustForestTrustInfo::

     AQAAAAIAAAAXAAAAAAAAAK/+yAFpQFxKAAYAAABhdS5uZXQ5AAAAAAAAAK/+yAFpQFxKAhgAAAABBA

     AAAAAABRUAAAC5zCq/+blv72X/IK4GAAAAYXUubmV0AgAAAEFV

     

     

     

     

    dn: CN=spat.com,CN=System,DC=kz,DC=com

    changetype: add

    objectClass: top

    objectClass: leaf

    objectClass: trustedDomain

    cn: spat.com

    distinguishedName: CN=spat.com,CN=System,DC=kz,DC=com

    instanceType: 4

    whenCreated: 20080815081613.0Z

    whenChanged: 20080815081619.0Z

    uSNCreated: 24663

    uSNChanged: 24670

    showInAdvancedViewOnly: TRUE

    name: spat.com

    objectGUID:: Xr8tbptbSkyuGg7XD2o9Gg==

    securityIdentifier:: AQQAAAAAAAUVAAAAk07wgTv3rlETk9Dd

    trustDirection: 1                                                                                     #define TRUST_DIRECTION_INBOUND         0x00000001

    trustPartner: spat.com

    trustPosixOffset: 0

    trustType: 2                                                                                            #define TRUST_TYPE_UPLEVEL              0x00000002 

    trustAttributes: 8                                                                    #define TRUST_ATTRIBUTE_FOREST_TRANSITIVE  0x00000008 

    flatName: SPAT

    objectCategory: CN=Trusted-Domain,CN=Schema,CN=Configuration,DC=kz,DC=com

    isCriticalSystemObject: TRUE

    msDS-TrustForestTrustInfo::

     AQAAAAIAAAAXAAAAAAAAAK/+yAF99yAyAAYAAABhbS5uZXQ5AAAAAAAAAK/+yAF99yAyAhgAAAABBA

     AAAAAABRUAAACTTvCBO/euUROT0N0GAAAAYW0ubmV0AgAAAEFN

     

     

     

    Here is the relevant data type to interpret some of the info hilighted above.

     

    typedef struct _TRUSTED_DOMAIN_INFORMATION_EX {
     
    LSA_UNICODE_STRING Name;
      LSA_UNICODE_STRING FlatName;

      PSID Sid;
      ULONG TrustDirection;
      ULONG TrustType;
      ULONG TrustAttributes;

    } TRUSTED_DOMAIN_INFORMATION_EX,
     *PTRUSTED_DOMAIN_INFORMATION_EX;

     

    In order to read the msDS-TrustForestTrustInfo attribute  we can see the following documentation:

     

    From the MCPP docs..

     

    Information about trust relationships with other forests is stored in objects of class  trustedomain in the domain NC replica of the forest root domain. Specifically, the msDS-TrustForestTrustInfo attribute on such objects contains information about the trusted forest or realm. The structure of the information contained in this attribute is represented in the following manner.

     

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    1
    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    2
    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    3
    0

    1

    Version

    RecordCount

    Records (variable)

    ...

     

    Version (4 bytes): Version of the data structure. The only supported version of the data structure is 1.

    RecordCount (4 bytes): Number of records present in the data structure.

    Records (variable): Variable-length records each containing a specific type of data about the forest trust relationship.

     

     

    And it goes on and on about how it stores the data..

     

    In the end, for reading it, you can simply use the following command:

     

    netdom trust kz.com /domain:spat.com /namesuffixes:spat.com

     

    Name, Type, Status, Notes

    1. *.spat.com, Name Suffix, Enabled

    2. spat.com, Domain DNS name, Enabled

    3. SPAT, Domain NetBIOS name, Enabled, For spat.com

    4. s-1-5-21--2114957677-1370421051--573533421, Domain SID, Enabled, For spat.com

     

     

    So it makes sense that it can look at the msDS-TrustForestTrustInfo and determine if the SPN matches a specific suffix and route accordingly.

    However .. if we look at a few pieces of data we can see where and why it was failing.

     

    A quick network trace shows the error:

     

    KERBEROS: Error code (error-code[6]) = Server not found in Kerberos database

    KERBEROS: Principal name value (name-string[1]) =HTTP/amsh

     

     

    If we can't guess the problem from that - some additional info from the KDCSVC logging shows:

     

                    408.924> KDC-Warning: KdcFindReferralTarget KLIN(40b02ae) Failed to find referral target amsh

     

     

    Guess the problem?

     

    How can we know where to route this SPN request?  The server looks at it - finds  the hostname of the machine and the servicetype but has no idea on how to route it to spat.com

     

    KdcFindReferralTarget is a very descriptive name , and if you are so inclined , hook a debugger to your DC and explore it a bit. But you will see that the name says it all  --- go find a referral target - oh ummm.. couldn't  find one since there is not enough info to route this .. sorry.

     

    Answer: Connect via IE to the FQDN ....   http://amsh.spat.com , now we  match the SPN to a known suffix and can route the data properly. The SPN is  http/amsh.spat.com and from the msDS-TrustForestTrustInfo attribute data we can see this is a routable suffix so it will send it to the proper forest.

     

     

    OK next problem.

     

    The MOSS server will really be addressed via a CNAME -- like  http://www.contoso.com

     

    Hrmm .. even if we used the FQDN - we can see from the data above that there is no way to find contoso.com - since it is not a real forest trust we hold. And in this case.. we will end up in the same boat. No routing info.

     

    Turns out there are these magical things called Routing Name suffixes. From http://technet.microsoft.com/en-us/library/cc784334.aspx

     

    ( BTW , if you wonder why I always paste in relevant info from a site - is because I never know when it will change or just up and disappear )

     

     

    Routing name suffixes across forests

    Name suffix routing is a mechanism used to manage how authentication requests are routed across Windows Server 2003 forests that are joined together by forest trusts. To simplify administration of authentication requests, when a forest trust is initially created, all unique name suffixes are routed by default. A unique name suffix is a name suffix within a forest, such as a user principal name (UPN) suffix, service principal name (SPN) suffix, or DNS forest or domain tree name, that is not subordinate to any other name suffix. For example, the DNS forest name microsoft.com is a unique name suffix within the microsoft.com forest.

    Forests can contain multiple unique name suffixes, and all children of unique name suffixes are routed implicitly. In Active Directory Domains and Trusts, name suffixes appear with an asterisk (*) at the beginning because of this. For example, if your forest uses *.microsoft.com as a unique name suffix, then authentication requests for all children of microsoft.com (*.child.microsoft.com) will be routed because the child domains are part of the microsoft.com name suffix.

    If a forest trust exists between two forests, then name suffixes that do not exist in one forest can be used to route authentication requests to a second forest. When a new child name suffix (*.child.widgets.com) is added to a unique name suffix (*.widgets.com), the child name suffix will inherit the routing configuration of the unique name suffix to which it belongs. Any new unique name suffixes that are created after a forest trust has been established will be visible in the forest trust Properties dialog box after you verify the trust. However, routing for those new unique name suffixes will be disabled by default. For more information about how to verify a trust, see Verify a trust.

    When a duplicate name suffix is detected, the routing for the newest name suffix will be disabled by default. For more information about how to route name suffixes, see Enable or disable an existing name suffix from routing. Administrators can use the forest trust Properties dialog box to manually prevent authentication requests for specific name suffixes from being routed to a forest.

     

     

    So we need to add a new suffix.

     

    On the TRUSTING domain ( in this case SPAT.COM )  go to AD domains and trust and add a new UPN suffix to the forest.

     

    image

     

    image

    Contoso.com for example.

     

     

    Then - on the TRUSTED domain ( KZ.COM )  go to the trust information for SPAT.COM and click on the properties.

     

    image

     

    There is a name suffix routing tab and it should show the new suffix as disabled - enable it and now we can verify the routing via the netdom parsing of msDS-TrustForestTrustInfo

     

    image

     

                                    netdom trust kz.com /domain:spat.com /namesuffixes:spat.com

     

       Name, Type, Status, Notes

    1. *.spat.com, Name Suffix, Enabled

    2. *.contoso.com, Name Suffix, Enabled

    3. spat.com, Domain DNS name, Enabled

    4. SPAT, Domain NetBIOS name, Enabled, For spat.com

    5. s-1-5-21--2114957677-1370421051--573533421, Domain SID, Enabled, For spat.com

     

    Now when the user goes to access www.contoso.com - it will get sent through the SPAT.COM trust info.

     

    In your kerb ticket list  - you end up seeing the following:

    HTTP/www.contoso.com@SPAT.COM

     

     

     

    Other note - for  ms-DS-SPN-Suffixes  - check it out.

    Maybe I'll talk about this some other time.

     

    spatdsg

     

     

     

    PS :  where's waldo, from the data in this post - tell me what the real names of the domains were... not that they were really real, they were fake real ( lab like )  but it's a fun game to play.

     

     

    Posted by SpatDSG | 8 Comments
    Filed under:

    SQL pains..

    So I was working on some code to read and write data to SQL ( not using LINQ or any fancy stuff.. heck I just started doing managed code. )

    I was specifically interested in the count of times , it should look something like this ( from SQL  )

    select COUNT(DateandTime),DateandTime from MyData group by DateandTime,Server order by COUNT(DateandTime)

    8    2008-07-21 10:43:03.000
    8    2008-07-21 10:40:26.000
    9    2008-07-21 10:41:15.000
    9    2008-07-21 10:45:13.000
    9    2008-07-21 10:45:31.000
    10    2008-07-21 10:40:58.000
    10    2008-07-21 10:49:11.000
    11    2008-07-21 10:45:08.000
    12    2008-07-21 10:43:04.000

    So for example - 2008-07-21 10:43:04.000  had 12 occurrences in the data.

    But for the life of me , I couldn't figure out how to return the count in the code.. lotsa references on how to return how many rows were returned total  using ExecuteScalar() but that's not what I wanted..

    Anyway. In the end I did something like this - not being a SQL guy, not sure if this is the right way to go about it, will I take a hit on performance? Was there a better way?

    DataTable dt = new DataTable();
         SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
         adapter.SelectCommand = myCommand;
         adapter.Fill(dt);

         if (dt.Rows.Count > 0)
         {
             int rowcount = dt.Rows.Count;
             for (int i = 0; i < rowcount; i++)
             {
                 int cnt = (int)dt.Rows[i].ItemArray.GetValue(0);   // this gives me the count info...
                 string str = dt.Rows[i]["somestring"].ToString();
                 Console.Write("data = {0} : {1}\n", cnt,str);
             }
         }

    thx

    spat

    LDAP client tracing...

    ADinsight from the sysinternals toolset is a great tool , but I seem to have problems  with it at times. Specifically on Server 2008  & Vista (maybe due to the way it hooks wldap32.dll)

    On Vista OS and beyond, there is built in client ldap tracing which can give you similar results  ( with a wee bitmore effort )

    In order to start the trace you use tracelog.exe ( may be able to use logman.exe as well but I have not tried it )

    First , create a new key under HKLM\System\CurrentControlSet\Services\ldap\tracing\

     

    The key name should be the name of the .exe you want to trace ,  mmc.exe for example.

    C:\tools>Tracelog.exe -start ldap -guid #099614a5-5dd7-4788-8bc9-e29f43db28fc -f  ldap.etl  -flag x1FFFDFF3

     

    Logger Started...

    Enabling trace to logger 23

    Operation Status:       0L      The operation completed successfully.

     

    Logger Name:            ldap

    Logger Id:              0x17

    Logger Thread Id:       00000EDC

    Guid:                   4a9f73a0-649c-11dd-84e5-0003ff1ee008

    Buffer Size:            16 Kb

    Maximum Buffers:        25

    Minimum Buffers:        3

    Number of Buffers:      3

    Free Buffers:           2

    Buffers Written:        1

    Events Lost:            0

    Log Buffers Lost:       0

    Real Time Buffers Lost: 0

    AgeLimit:               0

    Real Time Consumers:    0

    ClockType:              PerfCounter

    Log Mode:               Sequential

    Maximum File Size:      not set

    Buffer Flush Timer:     not set

    Log Filename:           C:\tools\ldap.etl

     

    After your repro or whatnot, when you want to stop the trace use the following command:

    C:\tools>tracelog -stop ldap

     

    Operation Status:       0L      The operation completed successfully.

    Logger Name:            ldap

    Logger Id:              0x17

    Logger Thread Id:       00000EDC

    Guid:                   4a9f73a0-649c-11dd-84e5-0003ff1ee008

    Buffer Size:            16 Kb

    Maximum Buffers:        25

    Minimum Buffers:        3

    Number of Buffers:      4

    Free Buffers:           4

    Buffers Written:        1

    Events Lost:            0

    Log Buffers Lost:       0

    Real Time Buffers Lost: 0

    AgeLimit:               0

    Real Time Consumers:    0

    ClockType:              PerfCounter

    Log Mode:               Sequential

    Maximum File Size:      not set

    Buffer Flush Timer:     not set

    Log Filename:           C:\tools\ldap.etl

    In order to format the trace to a readable format use tracerpt.exe

    C:\tools>tracerpt.exe ldap.etl -o ldap2.csv -of CSV

     

    Input

    ----------------

    File(s):

         ldap.etl

    100.00%

    Output

    ----------------

    DumpFile:           ldap2.csv

    The command completed successfully.

     

     

     

    Now, open the CSV in excel . There is a whole gob of information, but I have found that if I filter the Event ID column I can easily get what I want from it.

    Below I filter on ID = 20

     

    image

     

     

    Have fun with it... works nicely in a pinch when you don't have any other tools at your disposal except for the built in ones. Also works nice for the detailed returns and code flow, as well as how much time it took to perform.

     

    spat

     

    Posted by SpatDSG | 11 Comments
    Filed under:

    Get Serial number, expiry date, subject name and subject alternative names in script

    The question was something like this:

     

    ..."What I need to be able to do is iterate through each certificate in the Local Machine’s Personal store and spit out at least the serial number, expiry date, subject name and subject alternative names."

     

    Here is the output:

     

    ----------------------------------------------------------------

    Serial: 619487CD000000E4DCFF
    SubjectName: CN=SPATDSG, OU=Workstations, OU=Machines, DC=crisco, DC=com
    Valid from 7/29/2008 9:31:40 PM to 8/28/2008 9:31:40 PM
    SAN: Other Name:
         Principal Name=SPATDSG$@crisco.com

    ----------------------------------------------------------------

     

     

    Here is a starter.. requries capicom

     

    Const CAPICOM_LOCAL_MACHINE_STORE = 1

    Const CAPICOM_STORE_OPEN_READ_ONLY = 0

    Const CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9

     

    Set oStore = CreateObject ("CAPICOM.Store")

    oStore.Open CAPICOM_LOCAL_MACHINE_STORE, "MY" ,CAPICOM_STORE_OPEN_READ_ONLY

     

    Set Certificates = oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID,, 0)

     

    If Certificates.Count >0 Then

     

                    For Each Certificate in Certificates

                                    set extensions = Certificate.Extensions()

                                    WScript.Echo "Serial: " & Certificate.SerialNumber

                                    WScript.Echo "SubjectName: " & Certificate.SubjectName

                                    WScript.Echo "Valid from " & Certificate.ValidFromDate & " to " & Certificate.ValidToDate

     

                                    ' get the SAN data if it is there

                                    For Each extension in extensions

                                                    if extension.OID = 12 then

                                                         SubjectAltName = extension.EncodedData.Format(true)

                                                        wscript.echo "SAN: " & SubjectAltName

                                                    end if

                                    next

     

                                    WScript.Echo "----------------------------------------------------------------"

                                    WScript.Echo

                    Next

    Else

    WScript.Echo "No certificates"

    End If

     

     

     

    Hope it helps...

     

    Extension.OID Property
    http://msdn.microsoft.com/en-us/library/aa382418(VS.85).aspx

     

    EncodedData.Format Method
    http://msdn.microsoft.com/en-us/library/aa382001(VS.85).aspx

     

     

     

     

    spat

    Posted by SpatDSG | 2 Comments
    Filed under:

    Windows 2008 CA fails install ( ADCS ) : Object already exists. 0x8009000f

    During the installation of Windows Server 2008 (2k8) certificate services ( ADCS ) the installation fails with the following error:

     

     clip_image002

    The installation debug logs under \windows\certocm.log will show something similar to the following:

     

    202.5443.271: Generate Keys: TestHSMSPat: nCipher Enhanced Cryptographic Provider: 0x800(2048): Object already exists. 0x8009000f (-2146893809)

    0.299.965: Message Box: Microsoft Active Directory Certificate Services: An error occurred when creating the new key container "TestHSMSPat". You do not have write access permission to the key container. Please use a different CA name.

     Object already exists. 0x8009000f (-2146893809): Object already exists. 0x8009000f (-2146893809)

    0.299.965: Message Box: Microsoft Active Directory Certificate Services: 6

    0.299.965: Message Box: Microsoft Active Directory Certificate Services: An error occurred when creating the new key container "TestHSMSPat". You do not have write access permission to the key container. Please use a different CA name.

    Object already exists. 0x8009000f (-2146893809): Object already exists. 0x8009000f (-2146893809)

    .299.965: Message Box: Microsoft Active Directory Certificate Services: 6

    109.1880.439: Create Certificate: Object already exists. 0x8009000f (-2146893809)

    109.2552.443: Install Server: Object already exists. 0x8009000f (-2146893809)

    114.5848.949: End: CCertSrvSetup::Install: An error occurred when creating the new key container "TestHSMSPat". You do not have write access permission to the key container. Please use a different CA name.

    Object already exists. 0x8009000f (-2146893809): Object already exists. 0x8009000f (-2146893809)

    The following is assumptions are made:

    1.       You are using an nCipher HSM

    2.       You are using Operator Card Set (OCS ) key protection.

    3.       You are running Windows Server 2008.

     

    In Windows 2003 you had an option to allow the CSP to interact with the desktop in the following UI for 2k3:

     

    image

     

    image

    However, in Server 2008 ADCS ,   the options wording has changed a  little bit:

    "Use strong private key protection features provided by the CSP (this may require administrator interaction every time the private key is accessed by the CA"

    clip_image002[1] 

    Hope it helps someone one day - I spent a bunch of time on this before a kindly dev pointed out the obvious here.

    I had a whole post all about how to workaround the fact that the CSP could not interact with the desktop...

    Anyway.. here is what you will then see when the CA needs to interact:

    You will see a little blinky box on your taskbar.. click on it.

    clip_image002[3]

    You will see the interactive services desktop ( light blue ) and the nCIPhER dialog up pending the OCS insertion\PINs

    clip_image004

    clip_image006

    spat

     

    Posted by SpatDSG | 8 Comments

    Create a Dump file with pagefile on non boot partition..

    The general advice in Windows is to place the paging file on the boot partition in order to get a crash dump file. Here is a snip from an older KB

    "... However, if you remove the paging file from the boot partition, Windows cannot create a dump file (Memory.dmp) in which to write debugging information in the event that a kernel mode Stop Error message occurs. This could lead to extended downtime if you must debug to troubleshoot the Stop error message. "

     Little known, is that this not necessarily the case in XP ( given the right fix ) and Vista etc.

    Here are the two supporting KB's

    XP  = http://support.microsoft.com/kb/916157/en-us

    vista + http://support.microsoft.com/kb/950858

     

    Very handy for those servers with bajillions of gigs of RAM and the OS on the boot partition (the partition that contains the operating system) which is 2 gigs.

     spat

     

    Posted by SpatDSG | 3 Comments
    Filed under:

    How to populate the “Street” field with more than 1 line of text...or, how to use top down tshooting.

     

     

    The goal was to get the street attribute to be a multi lined value.. not streetadddress which is easy enough to do from the GUI.

    So part of this is to help folks understand that if  you take the basics of a system, and expand on those, then you can resolve a lot of your issues on your own. I guess the problem is expanding the understanding of the base system at lower layers.

     

    Anyway, here goes.

     

    The end result should look like the sample below.

     

    objectGUID: 076f29a4-14c2-4686-afe6-f952e5ce226c;

    objectSid: S-1-5-21-3967918733-511884834-854062973-11173;

    primaryGroupID: 513 = ( GROUP_RID_USERS );

    pwdLastSet: 6/30/2008 11:11:35 AM Pacific Daylight Time;

    sAMAccountName: User_0012;

    sAMAccountType: 805306368 = ( NORMAL_USER_ACCOUNT );

    street: this

    is

    a

    test

    ;

    userAccountControl: 0x10220 = ( PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWD );

    uSNChanged: 172054;

    uSNCreated: 166726;

    whenChanged: 7/2/2008 6:50:45 PM Pacific Daylight Time;

     

     

    For me, this really ended up being a question of -- How do I dump a file in hex from built in tools? ( it really was the only really interesting and new part to me ) . A quick internet search showed nothing in box.. but plenty of hex freeware tools etc.. course we could write something but I wanted it all to be in box.

     

    Let's start from square one in order to bring it all together.

     

    We can begin our tour with a known value and examine it. Like.. ahaha .. streetAddress ( as opposed to street )

     

    So StreetAddress is exposed the UI as the following:

    Easy enough.. multi line output set via the UI.

    Let's look at it closer.

     

    Look in LDP at it:

    primaryGroupID: 513 = ( GROUP_RID_USERS );

    pwdLastSet: 6/30/2008 11:11:35 AM Pacific Daylight Time;

    sAMAccountName: User_0012;

    sAMAccountType: 805306368 = ( NORMAL_USER_ACCOUNT );

    streetAddress: this

    is

    spats

    test;

    userAccountControl: 0x10220 = ( PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWD );

    uSNChanged: 172057;

    uSNCreated: 166726;

    whenChanged: 7/2/2008 6:56:11 PM Pacific Daylight Time;

    whenCreated: 6/30/2008 11:11:03 AM Pacific Daylight Time;

     

    Look at it again, in raw hex form:

    In LDP.EXE goto Options and the General  options:

     

     

    Change the General  options to dump values in binary:

     

     

    Now dump the user again:

     

    -----------------------------------

    sAMAccountName:

    55 73 65 72 5F 30 30 31 32                             User_0012      

    ------------------------------------

    sAMAccountType:

    38 30 35 33 30 36 33 36 38                             805306368      

    ------------------------------------

    streetAddress:

    74 68 69 73 0D 0A 69 73 0D 0A 73 70 61 74 73 0D        this..is..spats.

    0A 74 65 73 74                                                 .test          

    ------------------------------------

    userAccountControl:

    36 36 30 38 30                                                 66080          

    ------------------------------------

     

    Note that I highlighted the text - and any good geek will tell you that 0D 0A is... CRLF.

     

    So. How to set this easily in the tools we have at hand.

     

    "Street" attribute is not exposed in the UI. If we modify it in adsiedit or ldp.exe we can see it is clearly not  the same:

     

    pwdLastSet: 6/30/2008 11:11:35 AM Pacific Daylight Time;

    sAMAccountName: User_0012;

    sAMAccountType: 805306368 = ( NORMAL_USER_ACCOUNT );

    street: 123;

    streetAddress: this

    is

    spats

    test;

     

    However, we can't easily toss in hex characters either. At least not that I can see.

     

    So, off to the tools to dump and write hex directly as well as encode the data for input to the AD. Not easy to find in the built in OS tools.

     

    Certutil.exe can do it though.

     

    1.       Open notepad.

    2.       Input some text.

    3.       Save it as t1.txt

     

    C:\temp2>type t1.txt

    constant

    change

    gives

    the

    illusion

    of

    progress

     

     

    4.       Dump this in hex to ensure we have our data correct -- can we indeed use the 0x0D,0x0A (sure we can.. but let's make sure again shall we.. else I don't get to show the neat hex tools in the OS ) Dump it via certutil -encodehex  - you pass it the file to dump and the result file to dump to.

     

     

    C:\temp2>certutil -encodehex t1.txt t5.txt

    Input Length = 54

    Output Length = 286

    CertUtil: -encodehex command completed successfully.

     

    C:\temp2>type t5.txt

    0000    63 6f 6e 73 74 61 6e 74  0d 0a 63 68 61 6e 67 65   constant..change

    0010    0d 0a 67 69 76 65 73 0d  0a 74 68 65 0d 0a 69 6c   ..gives..the..il

    0020    6c 75 73 69 6f 6e 0d 0a  6f 66 0d 0a 70 72 6f 67   lusion..of..prog

    0030    72 65 73 73 0d 0a                                  ress..

     

    5.       Run certutil to encode the original text file  in base64

     

    C:\temp2>certutil -encode t1.txt t2.txt

    Input Length = 54

    Output Length = 132

    CertUtil: -encode command completed successfully.

     

    6.       Look at the data:

    C:\temp2>type t2.txt

    -----BEGIN CERTIFICATE-----

    Y29uc3RhbnQNCmNoYW5nZQ0KZ2l2ZXMNCnRoZQ0KaWxsdXNpb24NCm9mDQpwcm9n

    cmVzcw0K

    -----END CERTIFICATE-----

     

     

    7.       Drop the base64 in a file like so:

     

    dn: CN=User_0012,OU=stress,DC=crisco,DC=com

    changetype: modify

    replace:street

    street::Y29uc3RhbnQNCmNoYW5nZQ0KZ2l2ZXMNCnRoZQ0KaWxsdXNpb24NCm9mDQpwcm9ncmVzcw0K

    -

     

     

    8.       Import it:

    C:\temp2>ldifde -i -f t.txt

    Connecting to "sp137558a.crisco.com"

    Logging in as current user using SSPI

    Importing directory from file "t.txt"

    Loading entries..

    1 entry modified successfully.

     

    The command has completed successfully

     

     

    Dump it to make sure it made it in the AD OK:

     

    primaryGroupID: 513 = ( GROUP_RID_USERS );

    pwdLastSet: 6/30/2008 11:11:35 AM Pacific Daylight Time;

    sAMAccountName: User_0012;

    sAMAccountType: 805306368 = ( NORMAL_USER_ACCOUNT );

    street: constant

    change

    gives

    the

    illusion

    of

    progress

    ;

    userAccountControl: 0x10220 = ( PASSWD_NOTREQD | NORMAL_ACCOUNT | DONT_EXPIRE_PASSWD );

    uSNChanged: 172062;

    uSNCreated: 166726;

     

     

    yay..

     

    Done.

     

    BTW - I haven't posted in a while because I recently changed jobs ( within MS ) .. I can post more on that later on when I have more time to think about what to say there.

     

    spat

     

    Posted by SpatDSG | 0 Comments
    Filed under:
    More Posts Next page »
     
    Page view tracker