Homepage image
Sample of the Day RSS Feed

Sample Download: http://code.msdn.microsoft.com/CSDsWriteAccountSPN-95c31397

imageToday’s code sample is related to Active Directory.  It demonstrates how to write/add Service Principal Name (SPN) to any user or computer account object in Active Directory. This sample must be run on domain environment and under the Domain Admin privileges.

The sample was written by Microsoft Support Escalation Engineer: Shaleen Thapa.

imageYou can find more code samples that demonstrate the most typical programming scenarios by using Microsoft All-In-One Code Framework Sample Browser or Sample Browser Visual Studio extension. They give you the flexibility to search samples, download samples on demand, manage the downloaded samples in a centralized place, and automatically be notified about sample updates. If it is the first time that you hear about Microsoft All-In-One Code Framework, please watch the introduction video on Microsoft Showcase, or read the introduction on our homepage http://1code.codeplex.com/.

 

Introduction

This sample application demonstrates how to write/add Service Principal Name (SPN) to any user or computer account object in Active Directory. This sample must be run on domain environment and under the Domain Admin privileges.

 

Running the Sample

You can execute this sample by creating the exe via Visual Studio but it must be running under the domain admin credentials. Also this code must be running either on Domain controller or any one of the member servers.

 

Using the Code

We are using first DsCrackSpn to parse its SPN into its component strings. Then we need to bind to the Domain Controller using DsBind. Now we would require constructing the SPN using DsGetSpn by specifying its type. Once we get the pointer to the SPN, we can write it to the object by calling DsWriteAccountSpn.

// Initial call to DsCrackSpn should result in BUFFER_OVERFLOW... 
uint crackSpnResult = DsCrackSpn(spn, ref serviceClassSize, sTemp, ref serviceNameSize,  
    sTemp, ref instanceNameSize, sTemp, out port); 
  
// Check for buffer overflow 
if (crackSpnResult == ERROR_BUFFER_OVERFLOW) 
{ 
    // Resize our SB's 
    StringBuilder serviceClass  = new StringBuilder(serviceClassSize); 
    StringBuilder serviceName   = new StringBuilder(serviceNameSize); 
    StringBuilder instanceName  = new StringBuilder(instanceNameSize); 
  
    // Crack this spn using DsCrackSpn 
    crackSpnResult = DsCrackSpn(spn, ref serviceClassSize, serviceClass, ref serviceNameSize,  
        serviceName, ref instanceNameSize, instanceName, out port); 
     
    // If Success 
    if (crackSpnResult == NO_ERROR) 
    { 
        string[] hostArray = { serviceName.ToString() }; 
        ushort[] portArray = { port }; 
        ushort spnCount = 1; 
        IntPtr spnArrayPointer = new IntPtr(); 
        Int32 spnArrayCount = 0; 
  
        // Call to DsBind to get handle for Directory 
        System.IntPtr hDS; 
        uint result = DsBind(domainControllerName, dnsDomainName, out hDS); 
  
        if (result != NO_ERROR) 
        { 
            Console.WriteLine("DSBind Failed."); 
            return; 
        } 
  
        // Call to DsgetSpn to construct an spn 
        uint getSPNResult = DsGetSpn(DS_SPN_NAME_TYPE.DS_SPN_DNS_HOST, serviceClass.ToString(),  
            null, port, spnCount, hostArray, portArray, ref spnArrayCount, ref spnArrayPointer); 
  
        if (getSPNResult == NO_ERROR) 
        { 
            // Call the CSDsWriteAccountSPN for writing this spn to the object 
            uint dsWriteSpnResult = DsWriteAccountSpn(hDS, DS_SPN_WRITE_OP.DS_SPN_ADD_SPN_OP,  
                servicePrincipalName, spnArrayCount, spnArrayPointer); 
  
            if (dsWriteSpnResult == NO_ERROR) 
            { 
                Console.WriteLine("DsWriteAccountSpn Succeed. Please check the user/Computer object for ServicePrincipalName."); 
                Console.ReadKey(); 
            } 
            else 
            { 
                Console.WriteLine("DsWriteAccountSpn Failed."); 
                return; 
            } 
        } 
        else 
        { 
            Console.WriteLine("DsGetSPN Failed."); 
            return; 
        } 
    } 
    else 
    { 
        Console.WriteLine("DsCrackSpn Failed."); 
        return; 
    } 
} 

 

More Information

DsWriteAccountSpn 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms676056(v=vs.85).aspx 

DsGetSpn 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms675993(v=vs.85).aspx

DsCrackSpn 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms675971(v=vs.85).aspx

DsBind 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms675931(v=vs.85).aspx