DsCrackNames
C# Signature:
[DllImport("ntdsapi.dll", CharSet=CharSet.Auto)]
static public extern uint DsCrackNames(
IntPtr hDS,
DS_NAME_FLAGS flags,
DS_NAME_FORMAT formatOffered,
DS_NAME_FORMAT formatDesired,
uint cNames,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 4)]
string[] rpNames,
out IntPtr ppResult);
VB Signature:
<DllImport("ntdsapi.dll")> _
Public Shared Function DsCrackNames(ByVal hDS As IntPtr, _
ByVal flags As DS_NAME_FLAGS, _
ByVal formatOffered As DS_NAME_FORMAT, _
ByVal formatDesired As DS_NAME_FORMAT, _
ByVal cNames As UInt32, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.LPTStr, SizeParamIndex:=4)> ByVal rpNames As String(), _
ByRef ppResult As IntPtr) As Object
End Function
Sample Code:
using System;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
namespace Microsoft.Win32
{
internal static partial class NativeMethods
{
private const uint NO_ERROR = 0;
private const string NTDSAPI = "ntdsapi.dll";
public enum DS_NAME_ERROR
{
DS_NAME_NO_ERROR = 0,
// Generic processing error.
DS_NAME_ERROR_RESOLVING = 1,
// Couldn't find the name at all - or perhaps caller doesn't have
// rights to see it.
DS_NAME_ERROR_NOT_FOUND = 2,
// Input name mapped to more than one output name.
DS_NAME_ERROR_NOT_UNIQUE = 3,
// Input name found, but not the associated output format.
// Can happen if object doesn't have all the required attributes.
DS_NAME_ERROR_NO_MAPPING = 4,
// Unable to resolve entire name, but was able to determine which
// domain object resides in. Thus DS_NAME_RESULT_ITEM?.pDomain
// is valid on return.
DS_NAME_ERROR_DOMAIN_ONLY = 5,
// Unable to perform a purely syntactical mapping at the client
// without going out on the wire.
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
// The name is from an external trusted forest.
DS_NAME_ERROR_TRUST_REFERRAL = 7
}
[Flags]
public enum DS_NAME_FLAGS
{
DS_NAME_NO_FLAGS = 0x0,
// Perform a syntactical mapping at the client (if possible) without
// going out on the wire. Returns DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING
// if a purely syntactical mapping is not possible.
DS_NAME_FLAG_SYNTACTICAL_ONLY = 0x1,
// Force a trip to the DC for evaluation, even if this could be
// locally cracked syntactically.
DS_NAME_FLAG_EVAL_AT_DC = 0x2,
// The call fails if the DC is not a GC
DS_NAME_FLAG_GCVERIFY = 0x4,
// Enable cross forest trust referral
DS_NAME_FLAG_TRUST_REFERRAL = 0x8
}
public enum DS_NAME_FORMAT
{
// unknown name type
DS_UNKNOWN_NAME = 0,
// eg: CN=User Name,OU=Users,DC=Example,DC=Microsoft,DC=Com
DS_FQDN_1779_NAME = 1,
// eg: Example\UserN
// Domain-only version includes trailing '\\'.
DS_NT4_ACCOUNT_NAME = 2,
// Probably "User Name" but could be something else. I.e. The
// display name is not necessarily the defining RDN.
DS_DISPLAY_NAME = 3,
// obsolete - see #define later
// DS_DOMAIN_SIMPLE_NAME = 4,
// obsolete - see #define later
// DS_ENTERPRISE_SIMPLE_NAME = 5,
// String-ized GUID as returned by IIDFromString().
// eg: {4fa050f0-f561-11cf-bdd9-00aa003a77b6}
DS_UNIQUE_ID_NAME = 6,
// eg: example.microsoft.com/software/user name
// Domain-only version includes trailing '/'.
DS_CANONICAL_NAME = 7,
// eg: usern@example.microsoft.com
DS_USER_PRINCIPAL_NAME = 8,
// Same as DS_CANONICAL_NAME except that rightmost '/' is
// replaced with '\n' - even in domain-only case.
// eg: example.microsoft.com/software\nuser name
DS_CANONICAL_NAME_EX = 9,
// eg: www/www.microsoft.com@example.com - generalized service principal
// names.
DS_SERVICE_PRINCIPAL_NAME = 10,
// This is the string representation of a SID. Invalid for formatDesired.
// See sddl.h for SID binary <--> text conversion routines.
// eg: S-1-5-21-397955417-626881126-188441444-501
DS_SID_OR_SID_HISTORY_NAME = 11,
// Pseudo-name format so GetUserNameEx can return the DNS domain name to
// a caller. This level is not supported by the DS APIs.
DS_DNS_DOMAIN_NAME = 12
}
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public class DsHandle : IDisposable
{
IntPtr handle = IntPtr.Zero;
public DsHandle(string domainControllerName = null, string dnsDomainName = null)
{
uint res = DsBind(domainControllerName, dnsDomainName, out handle);
if (res != NO_ERROR)
throw new System.ComponentModel.Win32Exception((int)res);
}
public string CrackName(string name)
{
var res = CrackNames(new string[] { name });
if (res == null || res.Length == 0 || res[0].status != NativeMethods.DS_NAME_ERROR.DS_NAME_NO_ERROR)
throw new System.Security.SecurityException("Unable to resolve user name.");
return res[0].pName;
}
/// <summary>
/// A wrapper function for the DsCrackNames OS call
/// </summary>
/// <param name="names">The names to crack</param>
/// <param name="flags">Flags controlling the process</param>
/// <param name="formatOffered">Format of the names</param>
/// <param name="formatDesired">Desired format for the names</param>
/// <returns>The crack result</returns>
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS,
DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_NT4_ACCOUNT_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
{
IntPtr pResult;
uint err = DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)((names == null) ? 0 : names.Length), names, out pResult);
if (err != NO_ERROR)
throw new System.ComponentModel.Win32Exception((int)err);
try
{
// Next convert the returned structure to managed environment
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
return Result.Items;
}
finally
{
DsFreeNameResult(pResult);
}
}
public void Dispose()
{
uint ret = DsUnBind(ref handle);
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
}
}
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern uint DsBind(
string DomainControllerName, // in, optional
string DnsDomainName, // in, optional
out IntPtr phDS);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern uint DsCrackNames(
IntPtr hDS,
DS_NAME_FLAGS flags,
DS_NAME_FORMAT formatOffered,
DS_NAME_FORMAT formatDesired,
uint cNames,
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPTStr, SizeParamIndex = 4)]
string[] rpNames,
out IntPtr ppResult);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern void DsFreeNameResult(IntPtr pResult /* DS_NAME_RESULT* */);
[DllImport(NTDSAPI, CharSet = CharSet.Auto)]
public static extern uint DsUnBind(ref IntPtr phDS);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DS_NAME_RESULT
{
public uint cItems;
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
public DS_NAME_RESULT_ITEM[] Items
{
get
{
if (rItems == IntPtr.Zero)
return new DS_NAME_RESULT_ITEM[0];
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
Type strType = typeof(DS_NAME_RESULT_ITEM);
int stSize = Marshal.SizeOf(strType);
IntPtr curptr;
for (uint i = 0; i < cItems; i++)
{
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
}
return ResultArray;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DS_NAME_RESULT_ITEM
{
public DS_NAME_ERROR status;
public string pDomain;
public string pName;
public override string ToString()
{
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
return pName;
return null;
}
}
}
}
Última actualización