A noterCet article s'applique à un système d'exploitation différent de celui que vous utilisez. Le contenu de l'article qui ne vous concerne peut-être pas est désactivé.
Cet article explique comment la forme SDDL (Security Descriptor Definition Language) d'un identificateur de sécurité (SID) peut être convertie dans le formulaire de nom de compte SAM (Security Accounts Manager).
Par exemple, que vous souhaitez afficher le nom de compte SAM (domaine\utilisateur) des tiers de confiance répertoriés dans la liste de contrôle d'accès (ACL) sur un objet qui se trouve sur une station de travail distante et qui contient les comptes locaux dans la liste de contrôle d'accès. Vous utilisez ADsSecurity.dll pour énumérer les listes de contrôle d'accès sur un objet sur une station de travail distante. Les valeurs de tiers de confiance trouvent dans la liste de contrôle d'accès pour les utilisateurs ou groupes dans SAM la station de travail local apparaissent dans le format SDDL (comme dans s-x-x-x-x), pas dans le format du nom de compte SAM. Pour afficher ces tiers de confiance dans le format du nom de compte SAM que vous devez convertir du format SDDL. Sur Windows 2000/XP/2003 utiliser ConvertStringSidToSid API pour convertir le SID chaîne. La méthode définie dans cet article de base de connaissances est destinée à circuler sur Windows NT 4.0.
Le SID d'un tiers de confiance est stocké sous forme binaire dans la liste de contrôle d'accès. Le SID binaire n'est pas lisible.
Le IADsAccessControlEntry interface permet aux clients de répertoire d'accéder et de manipuler les entrées de contrôle d'accès individuels (ACE) de l'objet. IADsAccessControlEntry tente de convertir SID binaire du tiers de confiance en un format plus lisible en utilisant la fonction LookupAccountSID.
LookupAccountSID peut être exécuté à distance. Dans ce cas, il est exécutée sur le système local. LookupAccountSID API va rechercher tous les domaines approuvés et retourner le domaine et le nom d'utilisateur pour le SID du tiers de confiance. Toutefois, dans ce scénario, le tiers de confiance est stocké dans SAM la station de travail distant non approuvé. L'API LookupAccountSID ne parviendra pas à résoudre le SID binaire. En cas d'échec de l'API, le tiers de confiance est convertie en la forme SDDL et placé dans la propriété IADsAccessControlEntry::Trustee.
Le processus de conversion de la forme SDDL du SID en un fichier binaire SID, qui peut ensuite être utilisé dans un appel de LookupAccountSid API pour renvoyer le formulaire de nom de compte SAM est comme suit :
Analyse de que la forme SDDL du SID a été trouvée dans la propriété IADsAccessControlEntry::Trustee afin que l'autorité émettrice et les identificateurs relatifs sous-autorité (RID) peuvent être déterminées.
Initialiser un SID binaire avec le nombre approprié de sous-autorités.
Composer le SID binaire en y ajoutant de sous-autorités appropriées dans l'ordre approprié.
Utilisez le fichier nouvellement créé binaire SID dans un appel de LookupAccountSid ciblage de l'ordinateur local ont été le SID de SDDL a été obtenu.
Cette rubrique contient Microsoft Visual Basic et Microsoft Visual C++ de code source pour convertir un SID SDDL en un nom de compte SAM.
Code Visual Basic
' This code is meant to be used as an example of how one could convert
' the SDDL form of a SID into the SAM Account Name form.
' The class module defines two functions,
' ConvertSDDLtoSam which takes an SDDL form of a SID along with a target server
' and returns the Domain\user (SAM Account Name ) form of the SID.
'
' GetSubAuthorityFromSDDL, a helper function that walks the sub authorities.
'
Option Explicit
Private SidCount As Integer
Private Osid As New ADsSID
Const LMEM_ZEROINIT = &H40
'
' Declare the APIs needed to manipulate the binary SID
'
Private Declare Function InitializeSid Lib "advapi32.dll" (ByVal Sid As Long, pIndentifierAuthority As Any, ByVal nSubAuthorityCount As Byte) As Long
Private Declare Function GetSidSubAuthority Lib "advapi32.dll" (ByVal Sid As Long, ByVal nSubAuthority As Long) As Long
Private Declare Function GetSidLengthRequired Lib "advapi32.dll" (ByVal nSubAuthorityCount As Byte) As Long
Private Declare Function LookupAccountSid Lib "advapi32.dll" Alias "LookupAccountSidA" _
(ByVal lpSystemName As String, Sid As Any, ByVal name As String, cbName As Long, _
ByVal ReferencedDomainName As String, cbReferencedDomainName As Long, peUse As Integer) As Long
'
' Declare the memory management functions.
' Notice there are two definitions for RtlMoveMemory,
' one takes a value as Any, the other takes a value ByVal as long
' this is necessary so memory can be copied as follows:
' From a variable containing a 32 bit value that represents a memory location
' From a variable that represents a VB allocated memory location
' (ie: Dim bByte(6) as Byte type of declaration).
'
' LocalAlloc and LocalFree are used to allocate and free memory from the heap,
'respectively.
'
Private Declare Sub CopyByValMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, ByVal Source As Long, ByVal Length As Long)
Private Declare Sub CopyByRefMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Long, Source As Any, ByVal Length As Long)
Private Declare Function LocalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal wBytes As Long) As Long
Private Declare Function LocalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function ConvertStringSidToSid Lib "advapi32.dll" Alias "ConvertStringSidToSidA" (ByVal StringSid As String, ByRef pSID As Long) As Boolean
'
' ConvertSDDLtoSAM, see above comments for a description.
'
Public Function ConvertSDDLtoSAM(strSDDL As String, Target As String) As String
Dim stInt As Integer, strEnd As Integer
Dim iEndPosition As Integer, AuthorityCount As Integer
Dim AuthorityStrings(15) As String
Dim Authority As String, lngSSubAuthority As Long
Dim mByte() As Byte, str As String
Dim lngSid As Long, clssid As Long
Dim One As Integer, bRelValue As Long
Dim strUser As String * 255, strDomain As String * 255
Dim Retval As Integer, Counter As Integer
Dim lngRid As Long, cbSidLength As Long
Dim bIdentifier(1 To 6) As Byte
'
' Fill the AuthorityStrings array with the appropriate values.
' AuthorityStrings(1) - The SID revision level
' AuthroityStrings(2) - The issuing authority
' AuthorityStrings(3) - 0th sub authority RID
' .
' .
' .
' AuthorityStrings(n) - Nth sub authority RID
'
AuthorityCount = 1
Authority = GetSubAthorityFromSDDL(strSDDL, 1, iEndPosition)
AuthorityStrings(AuthorityCount) = Authority
'
' Walk the rest of the sub authorities and place them into
' the string array
'
Do
Authority = GetSubAthorityFromSDDL(strSDDL, iEndPosition, iEndPosition)
If (Len(Authority) > 0) Then
AuthorityCount = AuthorityCount + 1
AuthorityStrings(AuthorityCount) = Authority
End If
Loop While (iEndPosition > 0)
'
' Initialize the security identifier. AuthorityCount - 2 should be total
' number of sub authorities that need to be added to the
' the SID. Use InitializeSid to create a SID using the proper authority (stored
' in the second location of AuthorityStrings) and add the appropriate number of sub
' authorities.
'
' Retrieve the SubAuthority count
'
Retval = CInt(AuthorityStrings(2))
'
' Place that value into the appropriate Identifier array position.
' Just by coincidence, the Issuing Authority array and the
' issuing authority portion of the SDDL SID are the same number, so
' the structure ends up 0,0,0,0,0,CInt(AuthorityStrings(2))
'
bIdentifier(6) = Retval
'
' Get a total SubAuthority count
'
SidCount = AuthorityCount - 2
'
' Retrieve the overall required size for the sid
' We must know how many bytes will be needed to build the binary
' sid, GetSidLengthRequired will return that information
'
cbSidLength = GetSidLengthRequired(SidCount)
ReDim mByte(cbSidLength)
'
' Allocate Memory for the binary SID
'
clssid = LocalAlloc(LMEM_ZEROINIT, cbSidLength)
'
' Its time to Initialize the SID.
' Call InitializeSid to populate sid buffer. InitializeSid
' properly initializes the issuing authority and revision sections
' of the binary sid
'
lngSid = InitializeSid(clssid, bIdentifier(1), SidCount)
'
' Build the binary sid using GetSidSubAuthoriy API. The API
' returns an pointer to the location for the Sub Authority rid.
' Sub authority RIDs are stored in location 3 - AuthorityCount
' in the AuthorityStrings array. Simply convert the string form of
' the RID into a long and copy the memory into the pointer returned
' by GetSidSubAuthority
'
For Counter = 3 To AuthorityCount
lngSSubAuthority = GetSidSubAuthority(clssid, Counter - 3)
If val(AuthorityStrings(Counter))<2147483648# Then
lngRid = CLng(AuthorityStrings(Counter))
Else
lngRid = val(AuthorityStrings(Counter)) - 4294967296#
End If
CopyByRefMemory lngSSubAuthority, lngRid, LenB(lngRid)
CopyByValMemory mByte(0), clssid, cbSidLength
Next Counter
'
' We need to copy the binary SID into a byte buffer so we can pass it to
' the LookupAccountSid API. This API is targeted to a particular server
' Copying the memory allows us to view the contents of the binary sid in the
' watch window of our VB application.
'
ReDim mByte(cbSidLength)
CopyByValMemory mByte(0), clssid, cbSidLength
'
' Use LookAccountSid to resolve the Domain\Username of the
' SID.
'
bRelValue = LookupAccountSid(Target, mByte(0), strUser, Len(strUser), strDomain, Len(strDomain), 1)
'
' Clean up the domain and userID strings. the return value of LookupAccountSid should be
' checked to be sure that the functions completed successfully
'
strUser = Left(strUser, InStr(strUser, Chr(0)) - 1)
strDomain = Left(strDomain, InStr(strDomain, Chr(0)) - 1)
ConvertSDDLtoSAM = Trim(strDomain) & "\" & Trim(strUser)
'
' Since we allocated memory for the binary SID, we must release it otherwise we
' cause a memory leak. The leak is not severe, but over time could add up.
'
LocalFree clssid
End Function
'
' GetSubAuthorityFromSDDL starts at startposition
' and returns the next "-" at the end as endposition.
' When the end of the descriptor is found, endposition = 0.
'
' If for some reason, a starting "-" is not found, then the function will
' return "" as the authority and endposition = 0.
'
Private Function GetSubAthorityFromSDDL(strSDDL As String, _
startposition As Integer, _
endposition As Integer) As String
Dim stInt As Integer
Dim strEnd As Integer
Dim subAuthStart As Long
Dim SubAuthEnd As Long
Dim Authority As String
' Find the base authority
'
subAuthStart = InStr(startposition, strSDDL, "-", vbTextCompare)
If (subAuthStart = 0) Then
'
' Could not locate the leading "-", set the error condition and return
'
endposition = 0
GetSubAthorityFromSDDL = ""
Else
'
' Found the leading "-", search for the ending "-"
'
SubAuthEnd = InStr(subAuthStart + 1, strSDDL, "-", vbTextCompare)
If (SubAuthEnd = 0) Then
'
' Did not not locate an ending "-", set
' the endposition value to 0 and return everything from the
' first "-" to the end of the string
'
Authority = Mid(strSDDL, subAuthStart + 1)
endposition = 0
GetSubAthorityFromSDDL = Authority
Else
'
' Found the ending "-", set endposition to its location
' and return all the characters from the first "-" to this location
'
Authority = Mid(strSDDL, (subAuthStart + 1), ((SubAuthEnd - 1) - subAuthStart))
endposition = SubAuthEnd
GetSubAthorityFromSDDL = Authority
End If
End If
End Function
Code Visual C++
// SDDLsid.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#define MAX_SUB_AUTHORITIES 15
//
// Helper Function STUBS
//
// Function to locate sub authorities
//
UCHAR FindSubAuthorities( char* pSDDL, char *pAuths[] );
//
// Take the sub authorities array from FindSubAuthories and
// build a SID; return a pointer to it.
//
PSID BuildSidFromAuthorities( char *pAuths[], UCHAR lcAuths);
//
//
//-----------------------------------------------------------------
// Main console application executable.
//
int main(int argc, char* argv[])
{
char *lpszSDDL;
char *pStr, *pTarget;
char *pAuthorities[MAX_SUB_AUTHORITIES];
UCHAR nAuthorities = 0;
PSID pRawSID;
PSID pSysSID = NULL;
DWORD cbSysSID = 0;
//char szDomain[256];
//DWORD cbszDomain = 256;
SID_NAME_USE pSNU;
if( argc < 3 )
{
printf("Error, need a SDDL form of a SID\nExample: SDDLSid S-1-2-3-55569832-2398475 \\\\Target_Server\n");
return 0;
}
lpszSDDL = (char *)malloc(strlen(argv[1])+1);
pStr = argv[1];
pTarget = argv[2];
strcpy( lpszSDDL, (pStr+2));
//
// Find all of the sub authorities in the SDDL SID
// See comments on FindSubAuthorities for details
//
nAuthorities = FindSubAuthorities( lpszSDDL, pAuthorities );
long j = 0;
printf("Sub authority Count: %d\nSub Authority Values:\n", nAuthorities);
//
// Display the sub-Authority values
//
for ( j = 0; j <= nAuthorities; j++ )
printf("%s\n",pAuthorities[j]);
//
// Build a binary SID from the sub authorities
// See comments in BuildSidFromAuthorities for details
//
pRawSID = BuildSidFromAuthorities( pAuthorities, nAuthorities );
/*
Test code block used to verify that the code is functioning properlly. Took
a known SID, converted it to SDDL on Win2k, then used that SDDL sid in the code
for testing purposes.
if( !LookupAccountName("LOCAL_SERVER","FordP", pSysSID, &cbSysSID, szDomain, &cbszDomain, &pSNU) )
{
DWORD lstErr = GetLastError();
if( lstErr == 122 )
{
pSysSID = (PSID)LocalAlloc(LPTR, cbSysSID);
LookupAccountName("\\\\maxvdc1","FordP", pSysSID, &cbSysSID, szDomain, &cbszDomain, &pSNU);
if( EqualSid( pSysSID, pRawSID ))
printf("Sids are =\n");
else printf("SIDS are <> \n");
}
}
else printf("%d\n",GetLastError());
*/
if( pRawSID )
{
//
// Have a binary SID, lets retrieve the domain and user ID
//
char UserID[30];
char DomainID[256];
DWORD cbUserId = 30;
DWORD cbDomainId = 256;
BOOL bRet;
bRet= LookupAccountSid(
"\\\\maxvdc1", // name of local or remote computer
pRawSID, // security identifier
UserID, // account name buffer
&cbUserId, // size of account name buffer
DomainID, // domain name
&cbDomainId, // size of domain name buffer
&pSNU // SID type
);
if( bRet )
printf("SAM account form of %s \n is %s\\%s\n", argv[1], DomainID, UserID);
else
printf("Could not locate SID %d\n", GetLastError());
}
//
// Clean up all the memory allocated by the console application
//
if ( pRawSID ) LocalFree( (HLOCAL)pRawSID );
if ( lpszSDDL ) free ( lpszSDDL );
return 0;
}
//
// long FindSubAuthorities( char *pSDDL, char *pAuths[] );
//
// The return value is the number of sub authorities in the SID.
// Basically, the routine takes the SDDL form, searches for "-" characters
// and replaces them with NULLs and places a pointer to the start of
// the authority in the pAuths array so that each authority is separated by
// nulls.
//
// Example:
//
// SDDL SID-> S-1-5-21-853885456-2109860151-3743179773-1190
// would be converted to:
// S\01\05\021\0853885456\02109860151\03743179773\01190
// and the pAuths pointer array would be filled like:
// pAuths[0] -> pointer to '1'
// pAuths[1] -> pointer to '21'
// pAuths[2] -> pointer to '853885456'
// pAuths[3] -> pointer to '2109860151'
// pAuths[4] -> pointer to '3743179773'
// pAuths[5] -> pointer to '1190'
//
// The return value would be 5
//
// RETURN VALUES:
// Number of Sub Authorities found in the SDDL string
//
UCHAR FindSubAuthorities( char *pSDDL, char *pAuths[] )
{
char *strt;
BOOL bEnd = FALSE;
long lSubs = 0;
pAuths[lSubs] = pSDDL;
for( strt = pSDDL; *strt; strt++)
{
switch( *strt )
{
case '-':
bEnd = TRUE;
*strt = NULL;
lSubs++;
break;
default:
if( bEnd )
{
pAuths[lSubs] = strt;
bEnd = FALSE;
}
break;
}
}
return (UCHAR)(lSubs - 1);
}
//
// PSID BuildSidFromAuthorities( char *pAuths[]);
// This function takes an array that has been parsed by
// FindSubAuthorities function and converts it to a binary sid.
//
// RETURN VALUES:
// Returns NULL if the SID could not be created.
// Returns a PSID pointer if the SID was created successfully
//
PSID BuildSidFromAuthorities( char *pAuths[], UCHAR lcAuths)
{
//
// Allocate memory for the SID, this memory must be freed by the caller
//
PSID pLocalSid = (PSID)LocalAlloc(LPTR, GetSidLengthRequired(lcAuths));
BOOL bRet;
//
// The Authorities array contains pointer to the start of each sub authority.
// the pAuths[0] is pointing to the revisoin value, so we skip that one.
// Then pAuths[1] is pointer to the issuing authority for the SID. This value is going
// to be one of the values in the following case statement.
//
// Initialize the SID with the issuing authority and the number of sub authorities
//
switch( pAuths[1][0] )
{
case '0':
{
//
// SECURITY_NULL_SID_AUTHORITY
//
SID_IDENTIFIER_AUTHORITY sAuth = SECURITY_NULL_SID_AUTHORITY;
bRet = InitializeSid( pLocalSid, &sAuth, lcAuths);
}
break;
case '1':
{
//
// SECURITY_WORLD_SID_AUTHORITY
//
SID_IDENTIFIER_AUTHORITY sAuth = SECURITY_WORLD_SID_AUTHORITY;
bRet = InitializeSid( pLocalSid, &sAuth, lcAuths);
}
break;
case '2':
{
//
// SECURITY_LOCAL_SID_AUTHORITY
//
SID_IDENTIFIER_AUTHORITY sAuth = SECURITY_LOCAL_SID_AUTHORITY;
bRet = InitializeSid( pLocalSid, &sAuth, lcAuths);
}
break;
case '3':
{
//
// SECURITY_CREATOR_SID_AUTHORITY
//
SID_IDENTIFIER_AUTHORITY sAuth = SECURITY_CREATOR_SID_AUTHORITY;
bRet = InitializeSid( pLocalSid, &sAuth, lcAuths);
}
break;
case'5':
{
//
// SECURITY_NT_AUTHORITY
//
SID_IDENTIFIER_AUTHORITY sAuth = SECURITY_NT_AUTHORITY;
bRet = InitializeSid( pLocalSid, &sAuth, lcAuths);
}
break;
default:
break;
}
if( bRet )
{
//
// SID created successfully!, add the sub authorities by
// walking the pointers in the pAuths array, converting them to
// DWORD and shoving back into the SID.
//
// The GetSidSubAuthority API returns a pointer to the location of
// a given sub authority. Once the string form of the subauthority is
// converted into a DWORD, it must be placed into the address pointed to by
// the return value of the GetSidSubAuthority API.
//
// All of these operations could be done in a single line of code, but have been
// seperated for clarity.
//
long j;
for( j = 2; j <= lcAuths+1; j++)
{
DWORD dwValue = (DWORD)atol(pAuths[j]);
PDWORD pdwSubAuth = GetSidSubAuthority( pLocalSid, (j-2));
*pdwSubAuth = dwValue;
}
}
else pLocalSid = NULL;
return pLocalSid;
}
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 276208
(http://support.microsoft.com/kb/276208/en-us/
)
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.
Ces informations vous ont-elles aidé ?
Oui
Non
Plutôt
Quel niveau d'effort avez-vous dû personnellement fournir pour utiliser cet article ?
Très faible
Faible
Moyen
Elevé
Très élevé
Dites-nous pourquoi et ce que nous pouvons faire pour améliorer ces informations.
Merci ! Vos commentaires sont très utiles pour l'amélioration de notre contenu d'aide et de support. Si vous avez besoin d'aide complémentaire, veuillez consulter la page d'accueil d'aide et support.