<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JEDI Windows API &#187; Token</title>
	<atom:link href="http://blog.delphi-jedi.net/tag/token/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.delphi-jedi.net</link>
	<description>Joint Endeavor of Delphi Innovators of Windows Programming</description>
	<lastBuildDate>Wed, 19 Oct 2011 18:52:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Setting the SessionID for a new process</title>
		<link>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/#comments</comments>
		<pubDate>Fri, 23 May 2008 09:26:01 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Token]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=224</guid>
		<description><![CDATA[This simple example shows how you can change the target session of a new process. uses &#160; JwaWindows, &#160; JwsclToken, &#160; JwsclComUtils; var &#160; &#160;NewToken, &#160; &#160;UserToken : TJwSecurityToken; &#160; &#160;S : TStartupInfo; &#160; &#160;P : TProcessInformation; begin &#160; UserToken := TJwSecurityToken.CreateWTSQueryUserTokenEx&#40;nil, 1&#41;; //for example: here SessionID = 1 &#160; TJwAutoPointer.Wrap&#40;UserToken&#41;; //automatic destroy &#160; NewToken [...]]]></description>
			<content:encoded><![CDATA[<p>This simple example shows how you can change the target session of a new process.</p>
<p><span id="more-224"></span></p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclToken,<br />
&nbsp; JwsclComUtils; </p>
<p><span class="kw1">var</span><br />
&nbsp; &nbsp;NewToken,<br />
&nbsp; &nbsp;UserToken : TJwSecurityToken;</p>
<p>&nbsp; &nbsp;S : TStartupInfo;<br />
&nbsp; &nbsp;P : TProcessInformation;<br />
<span class="kw1">begin</span><br />
&nbsp; UserToken := TJwSecurityToken.<span class="me1">CreateWTSQueryUserTokenEx</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="nu0">1</span><span class="br0">&#41;</span>; <span class="co1">//for example: here SessionID = 1 </span><br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>UserToken<span class="br0">&#41;</span>; <span class="co1">//automatic destroy </span></p>
<p>&nbsp; NewToken := TJwSecurityToken.<span class="me1">CreateDuplicateExistingToken</span><span class="br0">&#40;</span>UserToken.<span class="me1">TokenHandle</span>, MAXIMUM_ALLOWED<span class="br0">&#41;</span>;<br />
&nbsp; TJwAutoPointer.<span class="me1">Wrap</span><span class="br0">&#40;</span>NewToken<span class="br0">&#41;</span>; &nbsp;</p>
<p>&nbsp; <span class="co1">//needs TCB privilege -&gt; Service</span><br />
&nbsp; JwEnablePrivilege<span class="br0">&#40;</span>SE_TCB_NAME, pst_Enable<span class="br0">&#41;</span>;<br />
&nbsp; NewToken.<span class="me1">TokenSessionId</span> := <span class="nu0">2</span>; <span class="co1">//e.g. set to session 2 &#8211; of course it must exist</span><br />
&nbsp; <br />
&nbsp; ZeroMemory<span class="br0">&#40;</span>@S, <span class="kw3">Sizeof</span><span class="br0">&#40;</span>S<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; S.<span class="me1">cb</span> := <span class="kw3">sizeof</span><span class="br0">&#40;</span>S<span class="br0">&#41;</span>;<br />
&nbsp; <span class="co1">//examplary, but working CPAU call &#8211; adapt for your need</span><br />
&nbsp; CreateProcessAsUser<span class="br0">&#40;</span>NewToken.<span class="me1">TokenHandle</span>,<span class="st0">&#8216;C:\Windows\system32\cmd.exe&#8217;</span>,<span class="kw2">nil</span>,<span class="kw2">nil</span>,<span class="kw2">nil</span>,<span class="kw2">false</span>, <span class="nu0">0</span>, <span class="kw2">nil</span>, <span class="kw2">nil</span>, S,P<span class="br0">&#41;</span>;</div>
<p>All the source is doing is to get a user&#8217;s token by calling CreateWTSQueryUserToken and then duplicate so it will become possible to change the Token SessionID. The session ID is changed by setting the property TokenSessionID which is only possible with the TCB privilege (we need it, but it needn&#8217;t to be active).<br />
 You can do the CreateProcess part a little better if you read this: “<a href="../2008/04/11/createprocess-in-full-glory/">CreateProcess in full glory</a>“.</p>
<p>Did you know?<br />
 1. You can test this example in your own Delphi environment <a href="http://blog.delphi-jedi.net/2008/05/07/debugging-services-an-easy-way/">without writing a service</a> first.</p>
<p>2. It is not possible to change the session ID of a running process.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/23/setting-the-sessionid-for-a-new-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RunAsSYS 1.0 preview [update#1]</title>
		<link>http://blog.delphi-jedi.net/2008/05/08/runassys-10-preview/</link>
		<comments>http://blog.delphi-jedi.net/2008/05/08/runassys-10-preview/#comments</comments>
		<pubDate>Thu, 08 May 2008 19:10:53 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JWSCL Downloads]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[RunAsSYS]]></category>
		<category><![CDATA[Token]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=141</guid>
		<description><![CDATA[This is the preview Version of RunAsSys for Windows XP and Vista made with the help of JWSCL. RunAsSys runs applications as SYSTEM user in the current user&#8217;s session. If you start it without any parameters it creates a command prompt with SYSTEM privileges by default. Otherwise you can add an application with parameters to [...]]]></description>
			<content:encoded><![CDATA[<p>This is the preview Version of RunAsSys for Windows XP and Vista  made with the help of JWSCL.<br />
 RunAsSys runs applications as SYSTEM user in the current user&#8217;s session.  If you start it without any parameters it creates a command prompt with SYSTEM privileges by default. Otherwise  you can add an application with parameters to start this process as  SYSTEM user. Use quotation marks if necessary for your path.<br />
 On Windows Vista and UAC it should prompt you for elevation. On XP  without Admin privileges it should prompt you for Admin credentials.</p>
<p><strong>Warning</strong>: On Windows XP (and older) the application shows the credential prompt dialog which allows you to run as the same user. If you just click OK button, the application will maybe response one more time but finally stop working. This is due to a bug in ShellExecuteEx with &#8220;runas&#8221; verb.</p>
<h3>UPDATE</h3>
<h3>Version 1.2</h3>
<p>This version fixes a bug that prevents the command prompt to be started sometimes. And it fixes a bug with Windows 7 where a dialog pops up with no use. (Most problems are fixed with the new JWSCL)<br />
 This version is also available as <a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/branches/0.9.4a/examples/RunAsSys" target="_blank">source</a> (Subversion Link) from the preRelease of <a href="tsvn:https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/branches/2.3"> </a><a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/branches/2.4a" target="_blank">JWA 2.4a</a> (Subversion Link) and <a href="https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwscl/branches/0.9.4a" target="_blank">JWSCL 0.9.4a</a> (Subversion Link).</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2008/05/runassys12.zip">Download RunAsSys 1.2</a></p>
<p><strong>Version 1.1</strong></p>
<p>I publish Version 1.1 which fixes several errors and also makes it available to Windows 64bit systems.<br />
 The zip archive contains a 64bit version registry key file that is compatible with WOW64.<br />
 RunAsSys contains EurekaLog, which logs internal things. If you get an error, you can send the error report directly to us. However it is not the default behaviour. We use your error report only for improving our software. It will be used internally only and will be finally deleted. No screenshot is taken.</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2008/05/runassys111.zip">Download RunAsSys 1.1</a></p>
<p><strong>Version 1.0</strong></p>
<p>Additional Info:<br />
 The reg file creates a reg key that is used to enable logging and set  the log output folder (default where exe resides)<br />
 It is located in HKEY_LOCAL_MACHINE\SOFTWARE\JEDI\WSCL\RunAsSys\1.0</p>
<p><a href="http://blog.delphi-jedi.net/wp-content/uploads/2008/04/runassys.zip">Download RunAsSYS 1.0</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/05/08/runassys-10-preview/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Setting file security with JWSCL</title>
		<link>http://blog.delphi-jedi.net/2008/04/28/setting-file-security-with-jwscl/</link>
		<comments>http://blog.delphi-jedi.net/2008/04/28/setting-file-security-with-jwscl/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 16:12:39 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[ACL]]></category>
		<category><![CDATA[DACL]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[folder]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[Token]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=170</guid>
		<description><![CDATA[Sometimes it is necessary to change the security settings of a file or folder for getting or denying write access. With JWSCL this task is made very easy. However there are some pitfalls to avoid. The following code will also be available in the example section of the source code. The application gets a file [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it is necessary to change the security settings of a file or folder for getting or denying write access. With JWSCL this task is made very easy. However there are some pitfalls to avoid.</p>
<p>The following code will also be available in the example section of the source code. The application gets a file or folder name as parameter and tries to add the user with full access control. It even tries to get ownership if it can&#8217;t change the access control list.</p>
<p>First of all we need some JWSCL classes:</p>
<ul>
<li>TJwSecurityDescriptor<br />
A security descriptor contains all information about security of an object. It contains the owner and the access control list (also some other thing, we don&#8217;t need here)</li>
<li>TJwSecureFileObject<br />
This class provides methods to read and write security information on a file or folder. Despite its name it does also support folders. It even supports inheritance.<br />
You can access a file or folder through its name, a handle or the VCL class TFileStream.</li>
<li>TJwDAccessControlList<br />
This class contains methods to maintain a discreationary access control list (DACL). A DACL contains a list of users and their possible access on the object.</li>
<li>TJwSecurityId<br />
Every user is identified by a unique number which is maintained by this class.</li>
<li>TJwSecurityToken<br />
Every logged on user gets a security pass which contains information what she can do or not. We mainly use it to retrieve the user&#8217;s SID (TJwSecurityID)</li>
</ul>
<p>These classes are stored in the JWSCL units. We use the following ones:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp;JwaWindows,<br />
&nbsp;JwsclSid,<br />
&nbsp;JwsclToken,<br />
&nbsp;JwsclACl,<br />
&nbsp;JwsclDescriptor,<br />
&nbsp;JwsclSecureObjects,<br />
&nbsp;JwsclKnownSid;</div>
<p>The units above are necessary and contain all the classes described earlier Of course we have to declare the classes:</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">var</span><br />
&nbsp; UserToken : TJwSecurityToken;<br />
&nbsp; SD : TJwSecurityDescriptor;<br />
&nbsp; FileObject : TJwSecureFileObject;<br />
&nbsp; Owner : TJwSecurityId;<br />
&nbsp; DACL : TJwDAccessControlList;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw3">FileExists</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span>;</div>
<p>This example also shows how we can add well known Security Identifiers (SID) to a secured object. We have to initialize them. The variable JwWorldSID will then contain the correct SID for group Everyone. If we didn&#8217;t call it, we would get nil instead.<br />
JwInitWellKnownSIDs;</p>
<p>The next steps are creating the classes. We get the user name through her token and save the SID into Owner.<br />
Later we will use the Owner instance to add it into the security information of the object.</p>
<div class="dean_ch" style="white-space: wrap;">UserToken := TJwSecurityToken.<span class="me1">CreateTokenEffective</span><span class="br0">&#40;</span>MAXIMUM_ALLOWED<span class="br0">&#41;</span>;<br />
Owner := UserToken.<span class="me1">GetTokenOwner</span>;<br />
<span class="kw1">try</span><br />
&nbsp; FileObject := TJwSecureFileObject.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
<p>The actual class which does all the work on the file/folder is TJwSecureFileObject. We just apply the first parameter.</p>
<p>Notice: A user can only change security information of an object if she has the right to do it. There are two options to allow it.</p>
<ol>
<li>The user is listed in the DACL. Additionally the right WRITE_DAC is granted for her.</li>
<li>The user is the owner. In this case she don&#8217;t need to be listed and allowed in the DACL. It is automatically granted</li>
</ol>
<p>We can check both version in one call.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;<span class="kw1">try</span><br />
&nbsp; <span class="kw1">if</span> <span class="kw1">not</span> FileObject.<span class="me1">AccessCheck</span><span class="br0">&#40;</span>WRITE_DAC<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">begin</span></div>
<p>This call is very easy. If we can&#8217;t change the DACL, we can try to become the owner. The only way to become an owner is to enable a privilege called SE_TAKE_OWNERSHIP_NAME. It is usually only granted to Administrators.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp; &nbsp; JwEnablePrivilege<span class="br0">&#40;</span>SE_TAKE_OWNERSHIP_NAME, pst_Enable<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; FileObject.<span class="me1">Owner</span> := Owner;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>JwEnablePrivilege will fail, if it can&#8217;t activate the privilege. Otherwise we can set the file/folder&#8217;s owner to the token user.</p>
<p>The main work is done here. We get the default DACL from the existing object and adapt it.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp; &nbsp;DACL := FileObject.<span class="me1">DACL</span>;</div>
<p>Adaption is done by adding the user to the DACL with full control. We additionally allow the Everyone group to demonstrate the well known Sids initialized by JwInitWellKnownSIDs. The last parameters (false) define that we don&#8217;t want the list to free the given SIDs (Owner and JwWorldSid) automatically.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp; &nbsp;DACL.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_ALL, Owner, <span class="kw2">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; DACL.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_READ, JwWorldSID, <span class="kw2">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
<p>And finally we reset the DACL.</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp; &nbsp;FileObject.<span class="me1">SetDACL</span><span class="br0">&#40;</span>DACL<span class="br0">&#41;</span>;</div>
<p>The DACL of the file or folder will receive the newly created control entries in addition to its existing ones. If it contains inherited entries (entries from a parent folder) they will be conserved. However if you don&#8217;t retrieve the DACL and just use an empty one, all previously existing entries which are not inherited will be removed. Of course the inherited entries will still remain intact.</p>
<p>And of course we free all allocated resources</p>
<div class="dean_ch" style="white-space: wrap;"> &nbsp;<span class="kw1">finally</span><br />
&nbsp; &nbsp; FileObject.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;</p>
<p><span class="kw1">finally</span><br />
&nbsp; Owner.<span class="me1">Free</span>;<br />
&nbsp; UserToken.<span class="me1">Free</span>;<br />
<span class="kw1">end</span>;<br />
<span class="kw1">end</span>.</div>
<p>Since I cut the source code into pieces, I&#8217;ll show it here in full glory</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">program</span> SetFileSecurity;</p>
<p><span class="coMULTI">{$APPTYPE CONSOLE}</span></p>
<p><span class="kw1">uses</span><br />
&nbsp; SysUtils,<br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclSid,<br />
&nbsp; JwsclToken,<br />
&nbsp; JwsclAcl,<br />
&nbsp; JwsclDescriptor,<br />
&nbsp; JwsclSecureObjects,<br />
&nbsp; JwsclKnownSid;</p>
<p><span class="kw1">var</span><br />
&nbsp; UserToken : TJwSecurityToken;<br />
&nbsp; SD : TJwSecurityDescriptor;<br />
&nbsp; FileObject : TJwSecureFileObject;<br />
&nbsp; Owner : TJwSecurityId;<br />
&nbsp; DACL : TJwDAccessControlList;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw1">if</span> <span class="kw1">not</span> <span class="kw3">FileExists</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="kw3">exit</span>;</p>
<p>&nbsp; JwInitWellKnownSIDs;</p>
<p>&nbsp; UserToken := TJwSecurityToken.<span class="me1">CreateTokenEffective</span><span class="br0">&#40;</span>MAXIMUM_ALLOWED<span class="br0">&#41;</span>;<br />
&nbsp; Owner := UserToken.<span class="me1">GetTokenOwner</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; FileObject := TJwSecureFileObject.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw3">ParamStr</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//Make me owner if we cant access DACL</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw1">not</span> FileObject.<span class="me1">AccessCheck</span><span class="br0">&#40;</span>WRITE_DAC<span class="br0">&#41;</span> <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">//try to become owner</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; JwEnablePrivilege<span class="br0">&#40;</span>SE_TAKE_OWNERSHIP_NAME, pst_Enable<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; FileObject.<span class="me1">Owner</span> := Owner;<br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; &nbsp; &nbsp; DACL := FileObject.<span class="me1">DACL</span>;<br />
&nbsp; &nbsp; &nbsp; DACL.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_ALL, Owner, <span class="kw2">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; DACL.<span class="me1">Add</span><span class="br0">&#40;</span>TJwDiscretionaryAccessControlEntryAllow.<span class="me1">Create</span><span class="br0">&#40;</span><span class="kw2">nil</span>, <span class="br0">&#91;</span><span class="br0">&#93;</span>, GENERIC_READ, JwWorldSID, <span class="kw2">false</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; &nbsp; &nbsp; FileObject.<span class="me1">SetDACL</span><span class="br0">&#40;</span>DACL<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; FileObject.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;</p>
<p>&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; Owner.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; UserToken.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>.</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/04/28/setting-file-security-with-jwscl/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New threads do not automatically impersonate themselves.</title>
		<link>http://blog.delphi-jedi.net/2008/04/09/new-threads-do-not-automatically-impersonate/</link>
		<comments>http://blog.delphi-jedi.net/2008/04/09/new-threads-do-not-automatically-impersonate/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 19:58:02 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Thread]]></category>
		<category><![CDATA[Token]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/?p=108</guid>
		<description><![CDATA[Whenever you impersonate a running thread and create a new thread while impersonating, your new thread will not get impersonated, too. The new thread will run without any thread token and thus a called function will use the process token instead. So you have to impersonate the new thread again. Ignoring that fact may lead [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever you impersonate a running thread and create a new thread while impersonating, your new thread will not get impersonated, too. The new thread will run without any thread token and thus a called function will use the process token instead. So you have to impersonate the new thread again.  Ignoring that fact may lead to problems if the process as a high access level (SYSTEM, Administrator) and  the new thread touches resources e.g. files. These files are opened with higher privileges, even if the user usually cannot access them.</p>
<p>The sample shows how we can spawn a token for the new thread exclusively.</p>
<div class="dean_ch" style="white-space: wrap;">
<span class="kw1">procedure</span> ThreadFunc<span class="br0">&#40;</span>Data : <span class="kw4">Pointer</span>&#8230;<span class="br0">&#41;</span><br />
<span class="kw1">var</span> Token : TJwSecurityToken;<br />
<span class="kw1">begin</span><br />
&nbsp; Token := TJwSecurityToken<span class="br0">&#40;</span>Data<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; Token.<span class="me1">ImpersonateLoggedOnUser</span>;<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; <span class="kw1">except</span><br />
&nbsp; &nbsp; <span class="co1">//check here the problem</span><br />
&nbsp; &nbsp; <span class="co1">//and inform the thread creator</span><br />
&nbsp; &nbsp; <span class="co1">//To raise an exception within a thread does end it immediately.</span><br />
&nbsp; <span class="kw1">end</span>;<br />
&nbsp; Token.<span class="me1">Free</span>;<br />
<span class="kw1">end</span>;</p>
<p><span class="kw1">var</span> Token, Token2 : TJwSecurityToken;<br />
<span class="kw1">begin</span><br />
&nbsp; &#8230;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; Token.<span class="me1">ImpersonateLoggedOnUser</span>;<br />
&nbsp; &nbsp; <span class="co1">//the new thread will not run in Token context</span><br />
&nbsp; &nbsp; <span class="co1">//get a second handle to the token for the thread</span><br />
&nbsp; &nbsp; Token2 := TJwSecurityToken.<span class="me1">CreateDuplicateExistingToken</span><span class="br0">&#40;</span>Token.<span class="me1">TokenHandle</span>, TOKEN_ALL_ACCESS, <span class="kw2">true</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; CreateThread<span class="br0">&#40;</span>&#8230;, @ThreadFunc, <span class="kw4">Pointer</span><span class="br0">&#40;</span>Token2<span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &#8230;<br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; Token.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/04/09/new-threads-do-not-automatically-impersonate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to get the user&#8217;s token from a service?</title>
		<link>http://blog.delphi-jedi.net/2008/03/31/how-to-get-the-users-token-from-a-service/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/31/how-to-get-the-users-token-from-a-service/#comments</comments>
		<pubDate>Mon, 31 Mar 2008 18:27:28 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[Impersonate]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[Token]]></category>
		<category><![CDATA[WTS]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/31/how-to-get-the-users-token-from-a-service/</guid>
		<description><![CDATA[This simple code excerpt can only be run under SYSTEM account (say in a service). It retrieves the token from the logged on user &#8211; especially the user at the physical console. Or in other words the user data of the person that sits in front of the computer. The main code which does the [...]]]></description>
			<content:encoded><![CDATA[<p>This simple code excerpt can only be run under SYSTEM account (say in a service). It retrieves the token from the logged on user &#8211; especially the user at the physical console. Or in other words the user data of the person that sits in front of the computer. The main code which does the task above can be seen here.</p>
<div class="dean_ch" style="white-space: wrap;">UserToken := TJwSecurityToken.<span class="me1">CreateWTSQueryUserToken</span><span class="br0">&#40;</span>WTS_CURRENT_SESSION<span class="br0">&#41;</span>;</div>
<p><a href="http://jwscldoc.delphi-jedi.net/JwsclToken.TJwSecurityToken.html#CreateWTSQueryUserToken">CreateWTSQueryUserToken</a> is only applicable in Windows XP or newer.  Use <a href="http://jwscldoc.delphi-jedi.net/JwsclToken.TJwSecurityToken.html#CreateWTSQueryUserTokenEx">CreateWTSQueryUserTokenEx</a> if you need Windows 2000  support.<br />
WTS_CURRENT_SESSION (-1)  defines the console session to be retrieved. Any existing session ID (starting from zero (0) )  can be used instead.  If a problems occurs (e.g. session does not exist) you get an exception (see documentation)</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span><br />
&nbsp; JwaWindows,<br />
&nbsp; JwsclToken,<br />
&nbsp; JwsclSid,<br />
&nbsp; JwsclStrings,<br />
&nbsp; SysUtils;</p>
<p>&#8230;<br />
<span class="kw1">var</span><br />
&nbsp; UserToken : TJwSecurityToken;<br />
&nbsp; ConsoleUser : TJwSecurityId;<br />
&nbsp; UserSidString,<br />
&nbsp; UserName : TJwString;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="co1">//erst ab Windows XP</span><br />
&nbsp; UserToken := TJwSecurityToken.<span class="me1">CreateWTSQueryUserToken</span><span class="br0">&#40;</span>WTS_CURRENT_SESSION<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; ConsoleUser := UserToken.<span class="me1">TokenUser</span>;<br />
&nbsp; &nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; &nbsp; UserSidString := ConsoleUser.<span class="me1">StringSID</span>;<br />
&nbsp; &nbsp; &nbsp; UserName := ConsoleUser.<span class="me1">GetAccountName</span><span class="br0">&#40;</span><span class="st0">&#8221;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="co1">//Writeln(UserSidString);</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//Writeln(UserName);</span><br />
&nbsp; &nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw3">FreeAndNil</span><span class="br0">&#40;</span>ConsoleUser<span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">end</span>;<br />
&nbsp; &nbsp; <span class="co1">//User personifizieren</span><br />
&nbsp; &nbsp; UserToken.<span class="me1">ImpersonateLoggedOnUser</span>;</p>
<p>&nbsp; &nbsp; ***</p>
<p>&nbsp; &nbsp; UserToken.<span class="me1">RevertToSelf</span>;</p>
<p>&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; <span class="kw3">FreeAndNil</span><span class="br0">&#40;</span>UserToken<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">end</span>;<br />
<span class="kw1">end</span>;</div>
<p>***)  Place functions and do stuff here that needs to be run under the user&#8217;s context. Functions like <a href="http://msdn2.microsoft.com/en-us/library/bb762204(VS.85).aspx">SHGetSpecialFolder</a> use the impersonated token to get the (correct) user folder. Additionally all security checks are made with the user&#8217;s token. This comes very handy because a service has (almost) always access to everything (files, reg keys, &#8230;) which means a security hole.</p>
<p><strong>[UPDATE]</strong><br />
Fixed some minor mistakes.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/31/how-to-get-the-users-token-from-a-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get the Windows Vista twin token</title>
		<link>http://blog.delphi-jedi.net/2008/03/04/get-the-windows-vista-twin-token/</link>
		<comments>http://blog.delphi-jedi.net/2008/03/04/get-the-windows-vista-twin-token/#comments</comments>
		<pubDate>Tue, 04 Mar 2008 11:29:11 +0000</pubDate>
		<dc:creator>Christian Wimmer</dc:creator>
				<category><![CDATA[JEDI Windows Security Code Lib]]></category>
		<category><![CDATA[integrity]]></category>
		<category><![CDATA[JWSCL]]></category>
		<category><![CDATA[Sid]]></category>
		<category><![CDATA[Token]]></category>
		<category><![CDATA[UAC]]></category>
		<category><![CDATA[Vista]]></category>

		<guid isPermaLink="false">http://blog.delphi-jedi.net/2008/03/04/get-the-windows-vista-twin-token/</guid>
		<description><![CDATA[Windows Vista contains a new feature that allows an administrator to work with less privileges. Every time a user who belongs to the administrator group logs on, the LogonUser API creates two tokens. One tokens contains the real power of the user and the second contains only restricted access. We call such a token restricted [...]]]></description>
			<content:encoded><![CDATA[<p>Windows Vista contains a new feature that allows an administrator to work with less privileges. Every time a user who belongs to the administrator group logs on, the LogonUser API creates two tokens. One tokens contains the real power of the user and the second contains only restricted access. We call such a token restricted token. This feature was implemented way back in Windows 2000 . The changes on the restricted token starts with removed privileges and ends with setting the administrator group in the token groups to use for deny only. A deny only Sid is only used for access control entries that deny access. So in our case the access to a file which allows Administrators full access may be disallowed if there is not any other positive element that grants us the access.<br />
Back to the topic. The token groups contains a special Sid that is called an integrity Sid. The token that has the administrator group enabled receives a high integrity Sid. Tthe medium integrity Sid goes to the groups of the restricted token.<br />
The token returned bei LogonUser is always the restricted one. Although you can retrieve the the twin token, you cannot do anything with it if you are not a SYSTEM process or an administrator. However a SYSTEM process may return the powerful token to create a process with full administrator rights. UAC does not do anything else. It gets the user&#8217;s credentials, logs on and uses the twin token (if any, otherwise it prompts for an administrator account credentials) to create the process.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> JwaWindows, JwsclExceptions, JwsclToken;var Token,<br />
&nbsp; &nbsp; TwinToken : TJwSecurityToken;<br />
<span class="kw1">begin</span><br />
&nbsp; Token := TJwSecurityToken.<span class="me1">CreateTokenEffective</span><span class="br0">&#40;</span>MAXIMUM_ALLOWED<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; TwinToken := Token.<span class="me1">LinkedToken</span>;<br />
&nbsp; &nbsp; PrintTokenInfo<span class="br0">&#40;</span>LToken<span class="br0">&#41;</span>;<br />
&nbsp; <span class="kw1">except</span><br />
&nbsp; &nbsp; <span class="kw1">On</span> E : EJwsclSecurityException <span class="kw1">do</span><br />
&nbsp; &nbsp; &nbsp; <span class="co1">//error logic here</span><br />
&nbsp; <span class="kw1">end</span>;<br />
&nbsp; <span class="kw1">try</span><br />
&nbsp; &nbsp; <span class="co1">//do stuff here</span><br />
&nbsp; <span class="kw1">finally</span><br />
&nbsp; &nbsp; TwinToken.<span class="me1">Free</span>;<br />
&nbsp; &nbsp; Token.<span class="me1">Free</span>;<br />
&nbsp; <span class="kw1">end</span>;</div>
<p>Both tokens are linked together. Thus the following conditions are true.</p>
<blockquote><p> Token.LinkedToken = TwinToken<br />
TwinToken.LinkedToken = Token</p></blockquote>
<p>You can use the twin token in any way you treat a token if you are powerful enough. Use it in CreateProcess or impersonate the user to do things as the user.</p>
<p>At the end I post a quite useful piece of code that displays primary information about a token.</p>
<div class="dean_ch" style="white-space: wrap;"><span class="kw1">uses</span> &#8230;, JwsclSecurityId,&#8230;;<br />
<span class="kw1">procedure</span> PrintTokenInfo<span class="br0">&#40;</span><span class="kw1">const</span> Token : TJwSecurityToken<span class="br0">&#41;</span>;<br />
<span class="kw1">var</span> SID, SID2 : TJwSecurityID;<br />
<span class="kw1">begin</span><br />
&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;Access: &#8216;</span>,JwFormatAccessRights<span class="br0">&#40;</span>Token.<span class="me1">AccessMask</span>,TokenMapping <span class="br0">&#41;</span><span class="br0">&#41;</span>;</p>
<p>&nbsp; Sid := Token.<span class="me1">TokenUser</span>;<br />
&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;TokenUser: &#8216;</span>,SID.<span class="me1">GetText</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; Sid.<span class="me1">Free</span>;</p>
<p>&nbsp; Sid := Token.<span class="me1">TokenOwner</span>;<br />
&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;TokenOwner: &#8216;</span>,SID.<span class="me1">GetText</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; Sid.<span class="me1">Free</span>;</p>
<p>&nbsp; <span class="kw3">writeln</span><span class="br0">&#40;</span><span class="st0">&#8216;TokenGroups: &#8216;</span><span class="re1">#<span class="nu0">13</span></span><span class="re1">#<span class="nu0">10</span></span>,Token.<span class="me1">TokenGroups</span>.<span class="me1">GetText</span><span class="br0">&#40;</span><span class="kw2">true</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">end</span>;</div>
<p><strong>Tell me how you liked this blog entry by adding a comment.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.delphi-jedi.net/2008/03/04/get-the-windows-vista-twin-token/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

