Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Problem with LsaOpenPolicy



Permlink Replies: 1 - Last Post: Oct 30, 2017 5:08 PM Last Post By: Yannick LANCHEC Threads: [ Previous | Next ]
Yannick LANCHEC

Posts: 43
Registered: 1/21/01
Problem with LsaOpenPolicy
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 30, 2017 11:17 AM
Hi,
I use LsaOpenPolicy in softwares, but sometimes it crashes !
But only on X64 ! not on X86.
I see a similar problem with visual https://social.msdn.microsoft.com/Forums/vstudio/en-US/100a9ebc-0b4e-4e91-9a5a-c02b75cb2cc2/64bit-port-crashes-in-lsaopenpolicy-32bit-program-works-fine?forum=vcgeneral

If i call LsaOpenPolicy (with intialized data) efore LookupAccountNameW, the call is OK, after, it crashes !

This is the test code, i have add special API Inside :

unit Unit2;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
TForm2 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

HANDLE = Longword;
PHANDLE = ^HANDLE;
THandle = HANDLE;
PWSTR = PWideChar;
NTSTATUS = LONG;
PNTSTATUS = ^NTSTATUS;
TNTStatus = NTSTATUS;
PLSA_UNICODE_STRING = ^LSA_UNICODE_STRING;
_LSA_UNICODE_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PWSTR;
end;
LSA_UNICODE_STRING = _LSA_UNICODE_STRING;
TLsaUnicodeString = LSA_UNICODE_STRING;
PLsaUnicodeString = PLSA_UNICODE_STRING;
PLSA_STRING = ^LSA_STRING;
_LSA_STRING = record
Length: USHORT;
MaximumLength: USHORT;
Buffer: PANSICHAR;
end;
LSA_STRING = _LSA_STRING;
TLsaString = LSA_STRING;
PLsaString = PLSA_STRING;
PLSA_OBJECT_ATTRIBUTES = ^LSA_OBJECT_ATTRIBUTES;
_LSA_OBJECT_ATTRIBUTES = record
Length: ULONG;
RootDirectory: THANDLE;
ObjectName: PLSA_UNICODE_STRING;
Attributes: ULONG;
SecurityDescriptor: PVOID;
SecurityQualityOfService: PVOID;
end;
LSA_OBJECT_ATTRIBUTES = _LSA_OBJECT_ATTRIBUTES;
TLsaObjectAttributes = LSA_OBJECT_ATTRIBUTES;
PLsaObjectAttributes = PLSA_OBJECT_ATTRIBUTES;
LSA_HANDLE = PVOID;
PLSA_HANDLE = ^LSA_HANDLE;
TLsaHandle = LSA_HANDLE;

Function LsaOpenPolicy(SystemName:PLSA_UNICODE_STRING;
ObjectAttributes:PLSA_OBJECT_ATTRIBUTES;
DesiredAccess:ACCESS_MASK;
var PolicyHandle: LSA_HANDLE):NTSTATUS; stdcall;
external 'advapi32.dll' Name 'LsaOpenPolicy';
Function LsaClose(ObjectHandle: LSA_HANDLE): NTSTATUS; stdcall;
external 'advapi32.dll' Name 'LsaClose';
Function LsaRemoveAccountRights(PolicyHandle: LSA_HANDLE; AccountSid: PSID;
AllRights: ByteBool;
UserRights: PLSA_UNICODE_STRING;
CountOfRights: ULONG): NTSTATUS; stdcall;
external 'advapi32.dll' Name 'LsaRemoveAccountRights';
Function LsaAddAccountRights(PolicyHandle: LSA_HANDLE; AccountSid: PSID;
UserRights: PLSA_UNICODE_STRING;
CountOfRights: ULONG): NTSTATUS; stdcall;
external 'advapi32.dll' Name 'LsaAddAccountRights';
Function LsaNtStatusToWinError(Status: NTSTATUS): ULONG; stdcall;
external 'advapi32.dll' Name 'LsaNtStatusToWinError';

Const
POLICY_CREATE_ACCOUNT = $00000010;
POLICY_LOOKUP_NAMES = $00000800;
STATUS_SUCCESS = NTSTATUS($00000000);

var
Form2: TForm2;

implementation

{$R *.dfm}

////////////////////////////////////////////////////////////////////////////////
// Init LSA string
Procedure LsauInitUnicodeString(Var LsaString:TLsaUnicodeString;
const WS:String);
Begin
FillChar(LsaString,SizeOf(LsaString),0);
If WS<>'' Then
Begin
LsaString.Length:=Length(WS)*SizeOf(Char);
LsaString.MaximumLength:=(Length(WS)+1)*SizeOf(Char);
LsaString.Buffer:=PChar(WS);
End;
End;
////////////////////////////////////////////////////////////////////////////////
// Computer
Function ComputerName:String;
Var
Buffer:Array [0..255] Of Char;
BufferSize:DWORD;
Begin
Buffer:='';
BufferSize:=SizeOf(Buffer);
GetComputerName(@Buffer,BufferSize);
Result:=Buffer;
End;
////////////////////////////////////////////////////////////////////////////////
// User
Function UserName:String;
Var
Buffer:Array [0..255] Of Char;
BufferSize:DWORD;
Begin
Buffer:='';
BufferSize:=SizeOf(Buffer);
GetUserName(@Buffer,BufferSize);
Result:=Buffer;
End;
////////////////////////////////////////////////////////////////////////////////
// Grant
Function GrantPrivilege(const SystemName,User,Privilege:String;
bRemove:Boolean):DWORD;
Var
Sid:PSID;
Domain:PChar;
SidSize,DomainSize:DWord;
pSIDType:SID_NAME_USE;
PolicyHandle:TLsaHandle;
Attributes:TLsaObjectAttributes;
LsaComputerName,RightsLsaUnicodeString:TLSAUnicodeString;
Status:NTStatus;
Begin
Domain:=Nil;
DomainSize:=0;
If Not LookupAccountNameW(PChar(SystemName),
PChar(User),
Nil,
SidSize,
Nil,
DomainSize,
pSIDType)
And (GetLastError=ERROR_INSUFFICIENT_BUFFER) Then
Begin
Sid:=AllocMem(SidSize);
Domain:=AllocMem(DomainSize*SizeOf(Char));
If LookupAccountNameW(PChar(SystemName),
PChar(User),
Sid,
SidSize,
Domain,
DomainSize,
pSIDType
)
Then
Begin
ZeroMemory(@Attributes,SizeOf(Attributes));
LsauInitUnicodeString(LsaComputerName,SystemName);
Status:=LsaOpenPolicy(@LsaComputerName,
@Attributes,
POLICY_CREATE_ACCOUNT Or POLICY_LOOKUP_NAMES,
PolicyHandle);
If Status=STATUS_SUCCESS Then
Begin
LsauInitUnicodeString(RightsLsaUnicodeString,Privilege);
Try
If bRemove Then
Status:=LsaRemoveAccountRights(PolicyHandle,
Sid,
False,
@RightsLsaUnicodeString,
1)
Else
Status:=LsaAddAccountRights(PolicyHandle,
Sid,
@RightsLsaUnicodeString,
1);
If Status<>STATUS_SUCCESS
Then Result:=LsaNtStatusToWinError(Status);
Finally
LsaClose(PolicyHandle);
End;
End
Else Result:=LsaNtStatusToWinError(Status);
End
Else Result:=GetLastError;
FreeMem(Domain);
FreeMem(Sid);
End
Else Result:=GetLastError;
End;
////////////////////////////////////////////////////////////////////////////////
// Test !!
Procedure TForm2.Button1Click(Sender: TObject);
Var
Compu:String;
Usr:String;
X:DWord;
Begin
Compu:=Computername;
Usr:=UserName;
X:=GrantPrivilege(Compu,Usr,'SeServiceLogonRight',False);
ShowMessage('Computer='+Compu+' User='+Usr+' Status='+IntToStr(X));
End;
////////////////////////////////////////////////////////////////////////////////
end.

Tested on delphi xe 10.2 upd 1

Thank You

Best regards

Yannick

Edited by: Yannick LANCHEC on Oct 30, 2017 11:19 AM

Yannick LANCHEC

Posts: 43
Registered: 1/21/01
Re: Problem with LsaOpenPolicy
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 30, 2017 5:08 PM   in response to: Yannick LANCHEC in response to: Yannick LANCHEC
The problem seem to come from an overflow with LookupAccountName.

If i modify variables order, it works... but may be bad

Var
PolicyHandle:TLsaHandle;
Attributes:TLsaObjectAttributes;
LsaComputerName,RightsLsaUnicodeString:TLSAUnicodeString;
Status:NTStatus;
//
Domain:PChar;
DomainSize:DWord;
Sid:PSID;
SidSize:DWord;
pSIDType:SID_NAME_USE;
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02