|
Antwort |
Registriert seit: 14. Apr 2003 Ort: Stuttgart 1.701 Beiträge Delphi 7 Professional |
#21
Actually I get this login SID, which is definitly a Session Logon ID :
(S-1-5-5-0-946199) I translated your source - I hope it correct.
Delphi-Quellcode:
And the code that replaces the old one :
constructor TSecurityToken.CreateWTSQueryUserToken(SessionID : Cardinal {= INVALID_HANDLE_VALUE});
begin Self.Create; fShared := FALSE; if SessionID = INVALID_HANDLE_VALUE then SessionID := WtsGetActiveConsoleSessionID; fAccessMask := TOKEN_ALL_ACCESS; if not WTSQueryUserToken(SessionID, fTokenHandle) then raise ESMWinCallFailedException.CreateFmtEx('A call to WTSQueryUserToken failed. ', 'WTSQueryUserToken',ClassName,'USM_Token.pas', 0,true,[]); end; function GetLogonSID(aToken: TSecurityToken) : TSecurityID; var i : integer; ptg : TSecurityIDList; begin result := nil; ptg := aToken.GetTokenGroups; // Loop through the groups to find the logon SID. for i := 0 to ptg.Count-1 do begin if (ptg[i].Attributes and SE_GROUP_LOGON_ID) = SE_GROUP_LOGON_ID then begin // Found the logon SID; make a copy of it. result := TSecurityID.Create(ptg[i].CreateCopyOfSID); Break; end; end; end;
Delphi-Quellcode:
var WTSToken := TSecurityToken;
aLocalGroups : TSecurityID; ... WTSToken := TSecurityToken.CreateWTSQueryUserToken(); aLocalGroups := TSecurityIDList.Create(true); aLogonSid := GetLogonSID(WTSToken); ShowMessage('aLogonSid: '+ aLogonSid.GetText(true)); aLocalGroups.Add(aLogonSid); aLocalGroups.Add(TSecurityID.Create('','DebuggerUser')); aLocalGroups.Add(AdministratorsSID);
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation? Goto: JEDI API LIB & Windows Security Code Library (JWSCL) |
Zitat |
Registriert seit: 10. Okt 2006 Ort: 's-Hertogenbosch, Die Niederlande 222 Beiträge RAD-Studio 2010 Arc |
#22
This works for me (adapt username and password to something of your liking):
It uses dialogs to give some debug info when something goes wrong (make service interactive to see the messageboxes), offcourse you can remove these in the final version.
Delphi-Quellcode:
Maybe you'll need unit uWinStation to compile:
unit uMain;
interface uses Windows, SvcMgr, SysUtils, JwaWinType, JwaWinBase, JwaWinNT, JwaNtSecApi, JwaNTStatus, JwaNative, JwaUserEnv, JwaWinSta, JwaWtsApi32, Dialogs, uWinStation; const DNLEN = 15; UNLEN = 256; type TAuthInfo = record Header: MSV1_0_INTERACTIVE_LOGON; Domain: array[0..DNLEN] of WideChar; User: array[0..UNLEN] of WideChar; Password: array[0..UNLEN] of WideChar; end; type TService1 = class(TService) procedure ServiceStart(Sender: TService; var Started: Boolean); private { Private declarations } public function GetServiceController: TServiceController; override; { Public declarations } end; var Service1: TService1; implementation {$R *.DFM} procedure ServiceController(CtrlCode: DWord); stdcall; begin Service1.Controller(CtrlCode); end; function TService1.GetServiceController: TServiceController; begin Result := ServiceController; end; Procedure LsaInitUnicodeString(Var LsaString: TLsaUnicodeString; Const WS: WideString); Begin FillChar(LsaString, SizeOf(LsaString), 0); If WS <> '' Then Begin LsaString.Length:=Length(WS) * SizeOf(WideChar); LsaString.MaximumLength:=LsaString.Length + SizeOf(WideChar); LsaString.Buffer:=PWideChar(WS); End; End; procedure GetLogonSID(hToken: THandle; var ppsid: PSID); var dwLength: DWORD; ptg : ^TOKEN_GROUPS; i : integer; begin dwLength := 0; ptg := nil; try // Get required buffer size and allocate the TOKEN_GROUPS buffer. if not GetTokenInformation(hToken, TokenGroups, ptg, 0, dwLength) then begin if GetLastError <> ERROR_INSUFFICIENT_BUFFER then begin ShowMessage('GetTokenInformation failed'); Exit; end; ptg := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ptg = nil then begin Exit; end; // Get the token group information from the access token. if not GetTokenInformation(hToken, TokenGroups, ptg, dwLength, dwLength) then begin Exit; end; // Loop through the groups to find the logon SID. for i := 0 to ptg.GroupCount-1 do begin if ptg.Groups[i].Attributes and SE_GROUP_LOGON_ID = SE_GROUP_LOGON_ID then begin // Found the logon SID; make a copy of it. dwLength := GetLengthSid(ptg.Groups[i].Sid); ppsid := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ppsid = nil then begin Exit; end; if not CopySid(dwLength, ppsid, ptg.Groups[i].Sid) then begin // raise exception.Create(Format('CopySid: %s', [SysErrorMessage(GetLastError)])); HeapFree(GetProcessHeap, 0, ppsid); Exit; end; Break; end; end; end; finally // Free the buffer for the token groups. if ptg <> nil then begin HeapFree(GetProcessHeap, 0, ptg); end; end; end; procedure TService1.ServiceStart(Sender: TService; var Started: Boolean); var hToken: THandle; si: _STARTUPINFOA; pi: _PROCESS_INFORMATION; Res: NTSTATUS; hLSA: THandle; LSAString: _LSA_STRING; AuthenticationPackage: ULONG; AuthentificationInfo: TAuthInfo; pProfileBuffer: Pointer; LogonID: _LUID; hLsaToken: THandle; QuotaLimits: QUOTA_LIMITS; SubStatus: Integer; wsDomain: WideString; wsUser: WideString; wsPwd: WideString; TokenSource: TOKEN_SOURCE; dwReturnLength: DWORD; Mode: LSA_OPERATIONAL_MODE; pGroups: PTOKEN_GROUPS; AdminSid: PSid; dwSizeSid: Cardinal; dwSizeDomain: Cardinal; SidType: TSidNameUse; Domain: String; MaxGroups: Integer; bRes: Longbool; begin ZeroMemory(@si, SizeOf(si)); si.cb := SizeOf(si); si.lpDesktop := nil; if WTSQueryUserToken(WtsGetActiveConsoleSessionID, hToken) then begin RtlInitString(@LsaString, PCSZ(PChar('Winlogon'))); Res := LsaRegisterLogonProcess(LsaString, hLSA, @Mode); if Failed(Res) then begin ShowMessageFmt('LsaRegisterLogonProcess: %s', [SysErrorMessage(LsaNtStatusToWinError(Res))]); end; RtlInitString(@LsaString, PCSZ(PChar(MSV1_0_PACKAGE_NAME))); Res := LsaLookupAuthenticationPackage(hLSA, LSAString, AuthenticationPackage); if Failed(Res) then begin ShowMessageFmt('LookupAuthPackage: %s', [SysErrorMessage(LsaNtStatusToWinError(Res))]); end; TokenSource.SourceName := '**ANON**'; if not AllocateLocallyUniqueId(TokenSource.SourceIdentifier) then begin ShowMessageFmt('AllocLocUniqueId: %s', [SysErrorMessage(GetLastError)]); end; // The number of TOKEN_GROUPS we're going to insert MaxGroups := 2; // Reserve memory for MaxGroups numbur of PTOKEN_GROUPS pGroups := PTOKEN_GROUPS(GlobalAlloc(GPTR, sizeof(_SID_AND_ATTRIBUTES) * MaxGroups)); pGroups^.GroupCount := MaxGroups; // Get the Logon Sid and it to the LocalGroups parameter of LsaLogonUser // The Logon Sid has the form S-1-5-5-XXXXXXXX-YYYYYYYY // We need it to obtain access to the user's desktop GetLogonSid(hToken, pGroups^.Groups[0].Sid); pGroups^.Groups[0].Attributes := SE_GROUP_MANDATORY or SE_GROUP_ENABLED or SE_GROUP_ENABLED_BY_DEFAULT or SE_GROUP_LOGON_ID; // Now get the Administrator's SID dwSizeSid := 0; dwSizeDomain := 0; bRes := LookupAccountName(nil, 'Administrator', nil, dwSizeSid, nil, dwSizeDomain, SidType); if (not bRes) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin // Reserve memory AdminSid := AllocMem(dwSizeSid); SetLength(Domain, dwSizeDomain); // Lookup Sid from Accountname // Assuming that the Admin account has not been renamed! bRes := LookUpAccountName(nil, 'Administrator', AdminSid, dwSizeSid, PChar(Domain), dwSizeDomain, SidType); if not bRes then begin // Cleanup FreeMem(AdminSid); AdminSid := nil; end; end else begin RaiseLastOSError; end; ShowMessageFmt('Administrator Sid: %s, Domain: %s', [SidToStr(AdminSid), Domain]); // Add the Administrator's sid to pGroups pGroups^.Groups[MaxGroups -1].Sid := AdminSid; pGroups^.Groups[MaxGroups -1].Attributes := SE_GROUP_MANDATORY or SE_GROUP_ENABLED or SE_GROUP_ENABLED_BY_DEFAULT; // Fill the AuthentificationInfo structure // First convert the EDITs to WideString wsDomain:= ''; wsUser:= 'username'; wsPwd:= 'password'; // Fill with zeros RtlZeroMemory(@AuthentificationInfo, sizeof(AuthentificationInfo)); AuthentificationInfo.Header.MessageType := MsV1_0InteractiveLogon; // AuthentificationInfo.Header.MessageType := MsV1_0NetworkLogon; // Copy the strings into a buffer. RtlCopyMemory(@AuthentificationInfo.Domain, @wsDomain[1], sizeof(WideChar) * Length(wsDomain)); RtlCopyMemory(@AuthentificationInfo.User, @wsUser[1], sizeof(WideChar) * Length(wsUser)); RtlCopyMemory(@AuthentificationInfo.Password, @wsPwd[1], sizeof(WideChar) * Length(wsPwd)); // Now set which buffer we want to use (the arrays of WideChar from the struct) RtlInitUnicodeString(@AuthentificationInfo.Header.LogonDomainName, AuthentificationInfo.Domain); RtlInitUnicodeString(@AuthentificationInfo.Header.UserName, AuthentificationInfo.User); RtlInitUnicodeString(@AuthentificationInfo.Header.Password, AuthentificationInfo.Password); Res := LsaLogonUser(hLSA, LsaString, RemoteInteractive, AuthenticationPackage, @AuthentificationInfo, SizeOf(AuthentificationInfo), pGroups, @TokenSource, pProfileBuffer, dwReturnLength, LogonID, hLSAToken, QuotaLimits, SubStatus); if Failed(Res) then begin ShowMessageFmt('LsaLogonUser: %s', [SysErrorMessage(LsaNtStatusToWinError(Res))]); end; ZeroMemory(@si, SizeOf(si)); si.cb := SizeOf(si); si.lpReserved := nil; si.lpDesktop := nil; si.dwFlags := STARTF_USESHOWWINDOW;; si.wShowWindow := SW_SHOWNORMAL; if not CreateProcessAsUser(hLsaToken, nil, PChar('notepad.exe'), nil, nil, False, NORMAL_PRIORITY_CLASS or CREATE_NEW_PROCESS_GROUP, nil, nil, &si, &pi) then begin ShowMessageFmt('CreateProcessAsUser: %s', [SysErrorMessage(GetLastError)]); end else begin end; // Cleanup CloseHandle(hToken); FreeMem(AdminSid); LsaDeregisterLogonProcess(hLSA); LsaFreeReturnBuffer(pProfileBuffer); end; Self.DoStop; end; end.
Delphi-Quellcode:
unit uWinStation;
interface uses SysUtils, Dialogs, JwaWinType, JwaWinBase, JwaWinNT, JwaNtSecApi, JwaNTStatus, JwaNative, JwaWinUser, JwaWinError; function StartInteractiveClientProcess(const lpszUsername: PAnsiChar; const lpszDomain: PAnsiChar; const lpszPassword: PAnsiChar; const lpCommandLine: PChar): Boolean; function GetLogonSID(hToken: THandle; var ppsid: PSID): Boolean; function AddAceToWindowStation(hwinsta: HWINSTA; psid: PSID): Boolean; function AddAceToDesktop(hdesktop: HDESK; ps: PSID): Boolean; function SIDToStr (sid : PSID) : string; procedure StrToSid (const sidName : string; sid : PSid; sidLen : DWORD); implementation const DESKTOP_ALL = DESKTOP_READOBJECTS or DESKTOP_CREATEWINDOW or DESKTOP_CREATEMENU or DESKTOP_HOOKCONTROL or DESKTOP_JOURNALRECORD or DESKTOP_JOURNALPLAYBACK or DESKTOP_ENUMERATE or DESKTOP_WRITEOBJECTS or DESKTOP_SWITCHDESKTOP or STANDARD_RIGHTS_REQUIRED; WINSTA_ALL = WINSTA_ENUMDESKTOPS or WINSTA_READATTRIBUTES or WINSTA_ACCESSCLIPBOARD or WINSTA_CREATEDESKTOP or WINSTA_WRITEATTRIBUTES or WINSTA_ACCESSGLOBALATOMS or WINSTA_EXITWINDOWS or WINSTA_ENUMERATE or WINSTA_READSCREEN or STANDARD_RIGHTS_REQUIRED; GENERIC_ACCESS = GENERIC_READ or GENERIC_WRITE or GENERIC_EXECUTE or GENERIC_ALL; HEAP_ZERO_MEMORY = 8; ACL_REVISION = 2; ACCESS_ALLOWED_ACE_TYPE = 0; CONTAINER_INHERIT_ACE = 2; INHERIT_ONLY_ACE = 8; OBJECT_INHERIT_ACE = 1; NO_PROPAGATE_INHERIT_ACE = 4; SE_GROUP_LOGON_ID = $C0000000; type ACL_SIZE_INFORMATION = record AceCount: DWORD; AclBytesInUse: DWORD; AclBytesFree: DWORD; end; ACE_HEADER = record AceType: BYTE; AceFlags: BYTE; AceSize: WORD; end; PACE_HEADER = ^ACE_HEADER; ACCESS_ALLOWED_ACE = record Header: ACE_HEADER; Mask: ACCESS_MASK; SidStart: DWORD; end; function SIDToStr (sid : PSID) : string; var psia : PSIDIdentifierAuthority; dwSubAuthorities : DWORD; dwSidRev : DWORD; dwCounter : DWORD; begin dwSidRev := SID_REVISION; if IsValidSid (sid) then begin psia := GetSidIdentifierAuthority (sid); dwSubAuthorities := GetSidSubAuthorityCount (sid)^; result := Format ('S-%u-', [dwSidRev]); if (psia^.Value[0] <> 0) or (psia^.Value[1] <> 0) then result := result + format ('0x%02x%02x%02x%02x%02x%02x',[ psia^.Value [0], psia^.Value [1], psia^.Value [2], psia^.Value [3], psia^.Value [4], psia^.Value [5]]) else result := result + format ('%u', [DWORD (psia^.Value [5]) + DWORD (psia^.Value [4] shl 8) + DWORD (psia^.Value [3] shl 16) + DWORD (psia^.Value [2] shl 24)]); for dwCounter := 0 to dwSubAuthorities - 1 do result := result + Format ('-%u', [GetSidSubAuthority (sid, dwCounter)^]) end else raise Exception.Create ('Invalid SID'); end; procedure StrToSid (const sidName : string; sid : PSid; sidLen : DWORD); var ps : PChar; pn : PChar; p : PChar; pa : PChar; valueStr : string; psia : PSIDIdentifierAuthority; i : DWORD; d : DWORD; authorityCount : DWORD; begin (* typedef struct _SID { BYTE Revision; BYTE SubAuthorityCount; SID_IDENTIFIER_AUTHORITY IdentifierAuthority; #ifdef MIDL_PASS [size_is(SubAuthorityCount)] DWORD SubAuthority[*]; #else // MIDL_PASS DWORD SubAuthority[ANYSIZE_ARRAY]; *) if not ((Length (sidName) > 3) and (sidName [1] = 'S') and (sidName [2] = '-')) then raise Exception.Create ('Bad SID'); if sidLen < sizeof (_SID_IDENTIFIER_AUTHORITY) + 2 then raise Exception.Create ('Bad SID'); ps := PChar (sid); pn := PChar (sidName); Inc (pn, 2); p := StrScan (pn, '-'); if not Assigned (p) then raise Exception.Create ('Bad SID'); p^ := #0; ps^ := char (StrToInt (pn)); // Revision Inc (ps); pa := ps; // Save authority count position Inc (ps); pn := p + 1; p := StrScan (pn, '-'); if not Assigned (p) then raise Exception.Create ('Bad SID'); p^ := #0; valueStr := pn; if Length (valueStr) < 1 then raise Exception.Create ('Bad SID'); psia := PSIDIdentifierAuthority (ps); Inc (ps, sizeof (_SID_IDENTIFIER_AUTHORITY)); Dec (sidLen, 2 + sizeof (_SID_IDENTIFIER_AUTHORITY)); if valueStr [1] = 'x' then begin if Length (valueStr) <> 14 then raise Exception.Create ('Bad SID'); psia^.value [0] := StrToInt ('$' + Copy (valueStr, 3, 2)); psia^.value [1] := StrToInt ('$' + Copy (valueStr, 5, 2)); psia^.value [2] := StrToInt ('$' + Copy (valueStr, 7, 2)); psia^.value [3] := StrToInt ('$' + Copy (valueStr, 9, 2)); psia^.value [4] := StrToInt ('$' + Copy (valueStr, 11, 2)); psia^.value [5] := StrToInt ('$' + Copy (valueStr, 13, 2)) end else begin psia^.value [0] := 0; psia^.value [1] := 0; i := StrToInt (valueStr); d := i shl 24; psia^.value [2] := d and $ff; d := i shl 16; psia^.value [3] := d and $ff; d := i shl 8; psia^.value [4] := d and $ff; psia^.value [5] := i and $ff; end; pn := p + 1; authorityCount := 0; while lstrlen (pn) > 0 do begin p := StrScan (pn, '-'); if Assigned (p) then begin p^ := #0; i := StrToInt (pn); pn := p + 1 end else begin i := StrToInt (pn); pn := pn + lstrlen (pn) end; if sidLen < sizeof (DWORD) then raise Exception.Create ('Bad SID'); PDWORD (ps)^ := i; Inc (ps, sizeof (DWORD)); Dec (sidLen, sizeof (DWORD)); Inc (authorityCount); end; pa^ := char (authorityCount); if not IsValidSID (sid) then raise Exception.Create ('Bad SID'); end; function AddAceToWindowStation(hwinsta: HWINSTA; psid: PSID): Boolean; var si: SECURITY_INFORMATION; psd, psdNew: PSECURITY_DESCRIPTOR; dwSidSize, dwSdSizeNeeded, dwNewAclSize: DWORD; bDaclPresent, bDaclExist: LongBool; pdacl, pNewAcl: PACL; aclSizeInfo: ACL_SIZE_INFORMATION; i: integer; pTempAce: PACE_HEADER; pace: ^ACCESS_ALLOWED_ACE; begin Result := False; si := DACL_SECURITY_INFORMATION; pace := nil; psd := nil; dwSidSize := 0; pNewAcl := nil; psdNew := nil; // Obtain the DACL for the window station. try if not GetUserObjectSecurity(hwinsta, si, psd, dwSidSize, dwSdSizeNeeded) then begin if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin psd := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwSdSizeNeeded); if psd = nil then Exit; psdNew := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwSdSizeNeeded); if psdNew = nil then Exit; dwSidSize := dwSdSizeNeeded; if not GetUserObjectSecurity(hwinsta, si, psd, dwSidSize, dwSdSizeNeeded) then Exit; end else begin Exit; end; end; // Create a new DACL. if not InitializeSecurityDescriptor(psdNew, SECURITY_DESCRIPTOR_REVISION) then Exit; // Get the DACL from the security descriptor. if not GetSecurityDescriptorDacl(psd, bDaclPresent, pdacl, bDaclExist) then Exit; // Initialize the ACL. ZeroMemory(@aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse := SizeOf(ACL); // Call only if the DACL is not NULL. if pdacl <> nil then begin // get the file ACL size info if not GetAclInformation(pdacl, @aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION), AclSizeInformation) then Exit; end; // Compute the size of the new ACL. dwNewAclSize := aclSizeInfo.AclBytesInUse + (2 * SizeOf(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * SizeOf(DWORD)); // Allocate memory for the new ACL. pNewAcl := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwNewAclSize); if pNewAcl = nil then Exit; // Initialize the new DACL. if not InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION) then Exit; // If DACL is present, copy it to a new DACL. if bDaclPresent then begin // Copy the ACEs to the new ACL. if aclSizeInfo.AceCount > 0 then begin for i := 0 to aclSizeInfo.AceCount - 1 do begin // Get an ACE. if not GetAce(pdacl, i, Pointer(pTempAce)) then Exit; // Add the ACE to the new ACL. if not AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, pTempAce.AceSize) then Exit; end; end; end; // Add the first ACE to the window station. pace := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, SizeOf(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - SizeOf(DWORD)); if pace = nil then Exit; pace.Header.AceType := ACCESS_ALLOWED_ACE_TYPE; pace.Header.AceFlags := CONTAINER_INHERIT_ACE or INHERIT_ONLY_ACE or OBJECT_INHERIT_ACE; pace.Header.AceSize := SizeOf(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - SizeOf(DWORD); pace.Mask := GENERIC_ACCESS; if not CopySid(GetLengthSid(psid), @pace.SidStart, psid) then Exit; if not AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pace, pace.Header.AceSize) then Exit; // Add the second ACE to the window station. pace.Header.AceFlags := NO_PROPAGATE_INHERIT_ACE; pace.Mask := WINSTA_ALL; if not AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pace, pace.Header.AceSize) then Exit; // Set a new DACL for the security descriptor. if not SetSecurityDescriptorDacl(psdNew, True, pNewAcl, False) then Exit; // Set the new security descriptor for the window station. if not SetUserObjectSecurity(hwinsta, si, psdNew) then Exit; // Indicate success. Result := True; finally // Free the allocated buffers. if pace <> nil then HeapFree(GetProcessHeap, 0, pace); if pNewAcl <> nil then HeapFree(GetProcessHeap, 0, pNewAcl); if psd <> nil then HeapFree(GetProcessHeap, 0, psd); if psdNew <> nil then HeapFree(GetProcessHeap, 0, psdNew); end; end; function GetLogonSID(hToken: THandle; var ppsid: PSID): Boolean; var dwLength: DWORD; ptg: ^TOKEN_GROUPS; i: integer; begin Result := False; dwLength := 0; ptg := nil; try // Verify the parameter passed in is not NULL. // if ppsid = nil then // Exit; // Get required buffer size and allocate the TOKEN_GROUPS buffer. if not GetTokenInformation(hToken, TokenGroups, ptg, 0, dwLength) then begin if GetLastError <> ERROR_INSUFFICIENT_BUFFER then begin ShowMessage('GetTokenInformation failed'); Exit; end; ptg := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ptg = nil then begin Exit; end; // Get the token group information from the access token. if not GetTokenInformation(hToken, TokenGroups, ptg, dwLength, dwLength) then begin Exit; end; // Loop through the groups to find the logon SID. for i := 0 to ptg.GroupCount-1 do begin if ptg.Groups[i].Attributes and SE_GROUP_LOGON_ID = SE_GROUP_LOGON_ID then begin // Found the logon SID; make a copy of it. dwLength := GetLengthSid(ptg.Groups[i].Sid); ppsid := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwLength); if ppsid = nil then begin Exit; end; if not CopySid(dwLength, ppsid, ptg.Groups[i].Sid) then begin raise exception.Create(Format('CopySid: %s', [SysErrorMessage(GetLastError)])); HeapFree(GetProcessHeap, 0, ppsid); Exit; end; Break; end; end; Result := True; end; finally // Free the buffer for the token groups. if ptg <> nil then begin HeapFree(GetProcessHeap, 0, ptg); end; end; end; function AddAceToDesktop(hdesktop: HDESK; ps: PSID): Boolean; var aclSizeInfo: ACL_SIZE_INFORMATION; bDaclExist, bDaclPresent: LongBool; dwNewAclSize, dwSidSize, dwSdSizeNeeded: DWORD; pdacl, pNewAcl: PACL; psd, psdNew: PSECURITY_DESCRIPTOR; pTempAce: PACE_HEADER; si: SECURITY_INFORMATION; i: integer; begin Result := False; psd := nil; psdNew := nil; pNewAcl := nil; si := DACL_SECURITY_INFORMATION; dwSidSize := 0; try // Obtain the security descriptor for the desktop object. if not GetUserObjectSecurity(hdesktop, si, psd, dwSidSize, dwSdSizeNeeded) then begin if GetLastError = ERROR_INSUFFICIENT_BUFFER then begin psd := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwSdSizeNeeded); if psd = nil then Exit; psdNew := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwSdSizeNeeded); if psdNew = nil then Exit; dwSidSize := dwSdSizeNeeded; if not GetUserObjectSecurity(hdesktop, si, psd, dwSidSize, dwSdSizeNeeded) then Exit; end else begin Exit; end; end; // Create a new security descriptor. if not InitializeSecurityDescriptor(psdNew, SECURITY_DESCRIPTOR_REVISION) then Exit; // Obtain the DACL from the security descriptor. if not GetSecurityDescriptorDacl(psd, bDaclPresent, pdacl, bDaclExist) then Exit; // Initialize. ZeroMemory(@aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse := SizeOf(ACL); // Call only if NULL DACL. if pdacl <> nil then begin // Determine the size of the ACL information. if not GetAclInformation(pdacl, @aclSizeInfo, SizeOf(ACL_SIZE_INFORMATION), AclSizeInformation) then Exit; end; // Compute the size of the new ACL. dwNewAclSize := aclSizeInfo.AclBytesInUse + SizeOf(ACCESS_ALLOWED_ACE) + GetLengthSid(ps) - SizeOf(DWORD); // Allocate buffer for the new ACL. pNewAcl := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, dwNewAclSize); if pNewAcl = nil then Exit; // Initialize the new ACL. if not InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION) then Exit; // If DACL is present, copy it to a new DACL. if bDaclPresent then begin // Copy the ACEs to the new ACL. if aclSizeInfo.AceCount > 0 then begin for i := 0 to aclSizeInfo.AceCount - 1 do begin // Get an ACE. if not GetAce(pdacl, i, Pointer(pTempAce)) then Exit; // Add the ACE to the new ACL. if not AddAce(pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, pTempAce.AceSize) then Exit; end; end; end; // Add ACE to the DACL. if not AddAccessAllowedAce(pNewAcl, ACL_REVISION, DESKTOP_ALL, ps) then Exit; // Set new DACL to the new security descriptor. if not SetSecurityDescriptorDacl(psdNew, True, pNewAcl, False) then Exit; // Set the new security descriptor for the desktop object. if not SetUserObjectSecurity(hdesktop, si, psdNew) then Exit; // Indicate success. Result := True; finally // Free buffers. if pNewAcl <> nil then HeapFree(GetProcessHeap, 0, pNewAcl); if psd <> nil then HeapFree(GetProcessHeap(), 0, psd); if psdNew <> nil then HeapFree(GetProcessHeap(), 0, psdNew); end; end; function StartInteractiveClientProcess(const lpszUsername: PAnsiChar; const lpszDomain: PAnsiChar; const lpszPassword: PAnsiChar; const lpCommandLine: PChar): Boolean; var hToken : THandle; hdesktop : HDESK; hwinst : HWINSTA; hwinstSave: HWINSTA; pi : PROCESS_INFORMATION; pS : PSID; si : STARTUPINFO; begin Result := False; hdesktop := 0; hwinst := 0; hwinstSave := 0; pS := nil; // try // Log the client on to the local computer. // if not LogonUser(lpszUsername, lpszDomain, lpszPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then if not LogonUser(lpszUsername, lpszDomain, lpszPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, hToken) then begin ShowMessageFmt('Logonuser failed: %s', [SysErrorMessage(GetLastError)]); Result := False; // raise exception.create(Format('LogonUser: %s', [SysErrorMessage(GetLastError)])); Exit; end; OutputDebugString(PChar(Format('LogonUser: %s', [SysErrorMessage(GetLastError)]))); // Save a handle to the caller's current window station. hwinstSave := GetProcessWindowStation; if hwinstSave = 0 then begin raise exception.create(Format('GetProcessWindowStation: %s', [SysErrorMessage(GetLastError)])); Exit; end; OutputDebugString(PChar(Format('GetProcessWindowStation: %s', [SysErrorMessage(GetLastError)]))); //\Sessions\2\Windows\WindowStations\WinSta0\Default // Get a handle to the interactive window station. hwinst := OpenWindowStation('WinSta0', False, READ_CONTROL or WRITE_DAC); if hwinst = 0 then begin raise exception.create(Format('OpenWindowStation: %s', [SysErrorMessage(GetLastError)])); Exit; end; OutputDebugString(PChar(Format('OpenWindowStation: %s', [SysErrorMessage(GetLastError)]))); // To get the correct default desktop, set the caller's // window station to the interactive window station. if not SetProcessWindowStation(hwinst) then begin raise exception.create(Format('SetProcessWindowStation(hwinst): %s', [SysErrorMessage(GetLastError)])); Exit; end; OutputDebugString(PChar(Format('SetProcessWindowStation(hwinst): %s', [SysErrorMessage(GetLastError)]))); // Get a handle to the interactive desktop. hdesktop := OpenDesktop('default', 0, False, READ_CONTROL or WRITE_DAC or DESKTOP_WRITEOBJECTS or DESKTOP_READOBJECTS); if hdesktop = 0 then begin raise exception.create(Format('OpenDesktop: %s', [SysErrorMessage(GetLastError)])); Exit; end; OutputDebugString(PChar(Format('OpenDesktop: %s', [SysErrorMessage(GetLastError)]))); // Restore the caller's window station. if not SetProcessWindowStation(hwinstSave) then begin raise exception.create(Format('SetProcessWindowStation(hwinstSave): %s', [SysErrorMessage(GetLastError)])); Exit; end; // Get the SID for the client's logon session. if not GetLogonSID(hToken, pS) then begin raise exception.create(Format('GetLogonSID: %s', [SysErrorMessage(GetLastError)])); Exit; end; // Allow logon SID full access to interactive window station. if not AddAceToWindowStation(hwinst, pS) then begin raise exception.create(Format('AddAceToWindowStation: %s', [SysErrorMessage(GetLastError)])); Exit; end; // Allow logon SID full access to interactive desktop. if not AddAceToDesktop(hdesktop, pS) then begin raise exception.create(Format('AddAceToDesktop: %s', [SysErrorMessage(GetLastError)])); Exit; end; // Impersonate client to ensure access to executable file. if not ImpersonateLoggedOnUser(hToken) then begin raise exception.create(Format('ImpersonateLoggedOnUser: %s', [SysErrorMessage(GetLastError)])); Exit; end; // Initialize the STARTUPINFO structure. // Specify that the process runs in the interactive desktop. ZeroMemory(@si, SizeOf(STARTUPINFO)); si.cb := SizeOf(STARTUPINFO); si.lpDesktop := PChar('Sessions\3\Windows\WindowStations\WinSta0\Default'); // Launch the process in the client's logon session. Result := CreateProcessAsUser(hToken, nil, lpCommandLine, nil, nil, False, // handles are not inheritable NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE, nil, nil, si, pi); // End impersonation of client. RevertToSelf(); if Result and (pi.hProcess <> INVALID_HANDLE_VALUE) then begin WaitForSingleObject(pi.hProcess, INFINITE); CloseHandle(pi.hProcess); end; if pi.hThread <> INVALID_HANDLE_VALUE then begin CloseHandle(pi.hThread); end; Result := True; // finally if hwinstSave <> 0 then begin SetProcessWindowStation(hwinstSave); end; // Free the buffer for the logon SID. if pS <> nil then begin HeapFree(GetProcessHeap, 0, pS); end; // Close the handles to the interactive window station and desktop. if hwinst <> 0 then begin CloseWindowStation(hwinst); end; if hdesktop <> 0 then begin CloseDesktop(hdesktop); end; // Close the handle to the client's access token. if hToken <> INVALID_HANDLE_VALUE then begin CloseHandle(hToken); end; end; //end; end. |
Zitat |
Registriert seit: 14. Apr 2003 Ort: Stuttgart 1.701 Beiträge Delphi 7 Professional |
#23
Okay thats great.
I reread your code and found the problem : I forgot to add the attributes
Delphi-Quellcode:
pGroups^.Groups[0].Attributes := SE_GROUP_MANDATORY or
SE_GROUP_ENABLED or SE_GROUP_ENABLED_BY_DEFAULT or SE_GROUP_LOGON_ID;
Delphi-Quellcode:
aLocalGroups := TSecurityIDList.Create(true);
aLogonSid := GetLogonSID(WTSToken); [b]OR[/b] aLogonSid := GetLogonSID(); aLocalGroups.Add(aLogonSid); aLogonSid.Attributes := SE_GROUP_MANDATORY or SE_GROUP_ENABLED or SE_GROUP_ENABLED_BY_DEFAULT or SE_GROUP_LOGON_ID; You see both versions of GetLogonSID are working. Question: Do I have to set the attributes for the my special debugger user ? aLocalGroups.Add(TSecurityID.Create('','DebuggerUser')); I get debug privileges but cannot bring the taskmanager to enable "show processes of all users" . ('C:\WINDOWS\system32\taskmgr.exe') Only this works:
Delphi-Quellcode:
aSID := AdministratorsSID;
aLocalGroups.Add(aSID); aSID.Attributes := SE_GROUP_MANDATORY or SE_GROUP_ENABLED or SE_GROUP_ENABLED_BY_DEFAULT or SE_GROUP_LOGON_ID;
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation? Goto: JEDI API LIB & Windows Security Code Library (JWSCL) |
Zitat |
Registriert seit: 10. Okt 2006 Ort: 's-Hertogenbosch, Die Niederlande 222 Beiträge RAD-Studio 2010 Arc |
#24
Just remembered something: GetWtsActiveConsoleSessionID is for XP/2003 and higher. On lower versions the functions doesn't exist and the active console session is always session id 0. If you want to be safe wrap the function and do an OS check and return 0 if NT or 2000.
|
Zitat |
Registriert seit: 14. Apr 2003 Ort: Stuttgart 1.701 Beiträge Delphi 7 Professional |
#25
The WTA function family is one more class to be implemented.
OMG the security library grows and grows and grows and did I mention "grows" ?
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation? Goto: JEDI API LIB & Windows Security Code Library (JWSCL) |
Zitat |
Registriert seit: 10. Okt 2006 Ort: 's-Hertogenbosch, Die Niederlande 222 Beiträge RAD-Studio 2010 Arc |
#26
LOL
BTW Don't forget to look at my JwaWinSta in that case, it has got some undocumented Terminal Server stuff (shadow sessions, connect to other sessions and obtaining login and idle time for terminal server sessions). |
Zitat |
Registriert seit: 14. Apr 2003 Ort: Stuttgart 1.701 Beiträge Delphi 7 Professional |
#27
I know your unit - its part of the jedi api lib - I converted it
I developed a desktop class named UDesktop. I did this also for winstation - but without implementation - only interface section is available (if I could even find it).
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation? Goto: JEDI API LIB & Windows Security Code Library (JWSCL) |
Zitat |
Registriert seit: 14. Apr 2003 Ort: Stuttgart 1.701 Beiträge Delphi 7 Professional |
#29
Zitat von Olli:
Guys, you are notorious! Get a life!
Christian
Windows, Tokens, Access Control List, Dateisicherheit, Desktop, Vista Elevation? Goto: JEDI API LIB & Windows Security Code Library (JWSCL) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |