Конференция "WinAPI" » Именованный канал с анонимным доступом.
 
  • EgorovAlex © (12.02.09 08:25) [0]
    Есть код на C от MicroSoft, который работает и который использует именованные каналы, я его портировал на Delphi и мой код не работает, долго пытался понять, где, но не получилось:

    #define UNICODE
    #include    <windows.h>
    #include    <stdio.h>

    // Types

    class SEC
    {   // Class to handle security attributes
    public:
       SEC();
       ~SEC();
       BOOL BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa );
    private:
       BOOL GetUserSid( PSID*  ppSidUser );

       BOOL    allocated;
       PSECURITY_DESCRIPTOR    psd;
       PACL    pACL;
       PTOKEN_USER pTokenUser;
    }
    ;

    /**  Constructor */
    SEC::
       SEC()
    {   allocated = FALSE;
       psd = NULL;
       pACL = NULL;
       pTokenUser = NULL;
    }


    /** Destructor */
    SEC::
       ~SEC()
    {   if( allocated )
       {   if( psd ) HeapFree( GetProcessHeap(), 0, psd );
           if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );
           if( pTokenUser ) HeapFree( GetProcessHeap(), 0, pTokenUser );
           allocated = FALSE;
       }

    }

    /** Builds security attributes that allows read-only access to everyone
    Input parameters: psa: security attributes to build
    Output parameters: TRUE | FALSE */
    BOOL SEC::
       BuildSecurityAttributes( SECURITY_ATTRIBUTES* psa )
    {   DWORD dwAclSize;
       PSID  pSidAnonymous = NULL; // Well-known AnonymousLogin SID
       PSID  pSidOwner = NULL;

       if( allocated ) return FALSE;

       SID_IDENTIFIER_AUTHORITY siaAnonymous = SECURITY_NT_AUTHORITY;
       SID_IDENTIFIER_AUTHORITY siaOwner = SECURITY_NT_AUTHORITY;

       do
       {   psd = (PSECURITY_DESCRIPTOR) HeapAlloc( GetProcessHeap(),
                                                   HEAP_ZERO_MEMORY,
                                                   SECURITY_DESCRIPTOR_MIN_LENGTH);
           if( psd == NULL )
           {   DisplayError( L"HeapAlloc" );
               break;
           }


           if( !InitializeSecurityDescriptor( psd, SECURITY_DESCRIPTOR_REVISION) )
           {   DisplayError( L"InitializeSecurityDescriptor" );
               break;
           }


           // Build anonymous SID
           AllocateAndInitializeSid( &siaAnonymous, 1,
                                     SECURITY_ANONYMOUS_LOGON_RID,
                                     0,0,0,0,0,0,0,
                                     &pSidAnonymous
                                   );

           if( !GetUserSid( &pSidOwner ) )
           {   return FALSE;
           }


           // Compute size of ACL
           dwAclSize = sizeof(ACL) + 2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
                       GetLengthSid( pSidAnonymous ) + GetLengthSid( pSidOwner );

           pACL = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclSize );
           if( pACL == NULL )
           {   DisplayError( L"HeapAlloc" );
               break;
           }


           InitializeAcl( pACL, dwAclSize, ACL_REVISION);

           if( !AddAccessAllowedAce( pACL,
                                     ACL_REVISION,
                                     GENERIC_ALL,
                                     pSidOwner
                                   ))
           {   DisplayError( L"AddAccessAllowedAce" );
               break;
           }


           if( !AddAccessAllowedAce( pACL,
                                     ACL_REVISION,
                                     FILE_GENERIC_READ, //GENERIC_READ | GENERIC_WRITE,
                                     pSidAnonymous
                                   ) )
           {   DisplayError( L"AddAccessAllowedAce" );
               break;
           }


           if( !SetSecurityDescriptorDacl( psd, TRUE, pACL, FALSE) )
           {   DisplayError( L"SetSecurityDescriptorDacl" );
               break;
           }


           psa->nLength = sizeof(SECURITY_ATTRIBUTES);
           psa->bInheritHandle = TRUE;
           psa->lpSecurityDescriptor = psd;

           allocated = TRUE;
       }while(0);

       if( pSidAnonymous )   FreeSid( pSidAnonymous );
       if( pSidOwner )       FreeSid( pSidOwner );

       if( !allocated )
       {   if( psd ) HeapFree( GetProcessHeap(), 0, psd );
           if( pACL ) HeapFree( GetProcessHeap(), 0 , pACL );
       }


       return allocated;
    }

    /** Obtains the SID of the user running this thread or process.
    Output parameters: ppSidUser: the SID of the current user,
    TRUE   | FALSE: could not obtain the user SID */
    BOOL SEC::
       GetUserSid( PSID*  ppSidUser )
    {
       HANDLE      hToken;
       DWORD       dwLength;

       if( !OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken) )
       {   if( GetLastError() == ERROR_NO_TOKEN )
           {   if( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken) )
               {   return FALSE;
               }

           }
           else
           {   return FALSE;
           }

       }

       if( !GetTokenInformation( hToken,       // handle of the access token
                                 TokenUser,    // type of information to retrieve
                                 pTokenUser,   // address of retrieved information
                                 0,            // size of the information buffer
                                 &dwLength     // address of required buffer size
                                 ))
       {   if( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
           {   pTokenUser = (PTOKEN_USER) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength );
               if( pTokenUser == NULL )
               {   return FALSE;
               }

           }
           else
           {   return FALSE;
           }

       }

       if( !GetTokenInformation(   hToken,     // handle of the access token
                                   TokenUser,  // type of information to retrieve
                                   pTokenUser, // address of retrieved information
                                   dwLength,   // size of the information buffer
                                   &dwLength   // address of required buffer size
                                   ))
       {   HeapFree( GetProcessHeap(), 0, pTokenUser );
           pTokenUser = NULL;

           return FALSE;
       }


       *ppSidUser = pTokenUser->User.Sid;
       return TRUE;
    }

  • EgorovAlex © (12.02.09 08:26) [1]
    Вот моя реализация этого класса:

    var
     SecAttr: SECURITY_ATTRIBUTES;

    type
     PTOKEN_USER = ^TOKEN_USER;
     TOKEN_USER = record
       User: SID_AND_ATTRIBUTES;
     end;

    var
     pTokenUser: PTOKEN_USER;

    procedure GetOwnerSid(var UserSid: PSID);
    var
     hToken: THandle;
     dwLength: Cardinal;
    begin
     if OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, True, hToken) or
        OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, hToken) then
       if not GetTokenInformation(hToken, TokenUser, nil, 0, dwLength) and
          (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin
         GetMem(pTokenUser, dwLength);
         try
           if GetTokenInformation(hToken, TokenUser, pTokenUser, dwLength, dwLength) then
             UserSid := pTokenUser.User.Sid;
         finally
    //        FreeMem(pTokenUser);
         end;
       end;
    end;

    type
     PACE_HEADER = ^ACE_HEADER;
     ACE_HEADER = record
       AceType:  BYTE;
       AceFlags: BYTE;
       AceSize:  WORD;
     end;

     PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
     ACCESS_ALLOWED_ACE = record
       Header:  ACE_HEADER ;
       Mask:    ACCESS_MASK ;
       SidStart: DWORD ;
     end;

    const
     SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
     SECURITY_ANONYMOUS_LOGON_RID = ($00000007);
     ACL_REVISION = 2;

    var
     pSidAnonymous, pSidOwner: PSID;
     dwAclSize: Cardinal;
     pPACL: PACL;

    initialization

     ZeroMemory(@SecAttr, SizeOf(SecAttr));
     SecAttr.lpSecurityDescriptor := PSECURITY_DESCRIPTOR(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH));
     InitializeSecurityDescriptor(SecAttr.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);

     pSidAnonymous := nil;
     AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 1, SECURITY_ANONYMOUS_LOGON_RID, 0, 0, 0, 0, 0, 0, 0, pSidAnonymous);

     pSidOwner := nil;
     GetOwnerSid(pSidOwner);

     dwAclSize := SizeOf(ACL) + 2*(SizeOf(ACCESS_ALLOWED_ACE) - SizeOf(DWORD)) + GetLengthSid(pSidAnonymous) + GetLengthSid(pSidOwner);
     pPACL := PACL(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclSize));
     InitializeAcl(pPACL^, dwAclSize, ACL_REVISION);

     AddAccessAllowedAce(pPACL^, ACL_REVISION, GENERIC_ALL, pSidOwner);
     AddAccessAllowedAce(pPACL^, ACL_REVISION, GENERIC_ALL{GENERIC_READ or GENERIC_WRITE}, pSidAnonymous);

     SetSecurityDescriptorDacl(SecAttr.lpSecurityDescriptor, True, pPACL, False);
     SecAttr.bInheritHandle := True;
     SecAttr.nLength := SizeOf(SECURITY_ATTRIBUTES);

     FreeSid(pSidAnonymous);

    finalization

     LocalFree(HLOCAL(SecAttr.lpSecurityDescriptor));

    end.



    У меня это без классов и без проверок ошибок, но я их ставил и всё проходит без ошибок, есть ли явные ляпы в моём коде?
  • clickmaker © (12.02.09 12:04) [2]
    попробуй packed record
  • EgorovAlex © (12.02.09 18:36) [3]
    Спасибо, как оказалось эта часть кода нормальная, проблема была в другом месте
 
Конференция "WinAPI" » Именованный канал с анонимным доступом.
Есть новые Нет новых   [134435   +35][b:0][p:0.007]