Citrix Application Streaming runs the majority of the isolation system as a service.   Being good security citizens, the service (radesvc.exe) is run on a named user account (Ctx_StreamingSvc) rather than LOCAL_SYSTEM.  There’s some fancy security name for this but what it comes down to is using the least privilege you can to help limit the potential damage you can cause should you go astray.

The user Ctx_StreamingSvc can write to only a few locations on the machine.  As a user account, it automatically cannot write to \Windows or \Program files and cannot write to HKLM, or even HKCU for any user other than itself.  This is good.  There are some things however that just demand a service, such as populating a SINGLE application installation image no matter how many users will be logged onto the machine.

At installation, the streaming service user account is given full control of a few locations:

  • \Program files\Citrix\RadeCache
  • \Program files\Citrix\Deploy
  • HKLM\Software\Citrix\RadeCache

These relate to the “middle layer” of the “layers of glass“.  They are the SINGLE space that support multiple application executions across many apps and many users.  The ability to write to these spaces is needed to runtime populate the execution content, so this is pretty much a “must have” for the streaming service to do it’s job.

Where it gets neat is is that real USER accounts have to “see” stuff in the cache so that they can layer in the isolated content, so that the layers of glass can support read-only opens to the stuff in the installation image.  In the normal Windows installation, users, read: not admins, can “see” anything beneath \Program files, so in theory, there’s no action needed to pull this off.

Being security paranoid folks, the Citrix isolation system restricts users from seeing execution content unless they are actively running the application.  The DACLs are runtime added and removed.  Here is a file system view of the DACLs applied to the RadeCache execution space, first for the service account and then for a user account.

RadeCache directory

. NT AUTHORITY\SYSTEM:(F)

NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)

BUILTIN\Administrators:(F)

BUILTIN\Administrators:(OI)(CI)(IO)(F)

BUILTIN\Administrators:(F)

CREATOR OWNER:(OI)(CI)(IO)(F)

machinename\Ctx_StreamingSvc:(F)

machinename\Ctx_StreamingSvc:(OI)(CI)(IO)(F)

That part not too interesting.

The GUID_v directory that holds the application content is below the RadeCache.  The below taken from my Windows Server 2003 test machine while running an application as user “U1”.

. machineordomain\U1:(RX)

machineordomain\U1:(OI)(CI)(IO)(GR,GE)

NT AUTHORITY\SYSTEM:(I)(F)

NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)

BUILTIN\Administrators:(I)(F)

BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)

CREATOR OWNER:(I)(OI)(CI)(IO)(F)

machinename\Ctx_StreamingSvc:(I)(F)

machinename\Ctx_StreamingSvc:(I)(OI)(CI)(IO)(F)

The thing to observe is that the user rights for the directory space are runtime added when the application is launched, and runtime removed when the application terminates.   Even while the application runs, the user cannot see the RadeCache directory itself.

Here’s how the user sees it.

C:\Program Files\Citrix>dir radecache

Directory of C:\Program Files\Citrix\radecache

File Not Found

Same user, this time “look deeper” to see the directory space that supports the execution of the application that they are currently running.   You have to “know” the GUID to have this work because you can’t directory scan the RadeCache.

C:\Program Files\Citrix>dir radecache561beac-e4b8-47d8-8a71-fe5752f330f9_3

Directory of C:\Program Files\Citrix\radecache561beac-e4b8-47d8-8a71-fe5752f330f9_3

08/07/2009  10:31 AM    <DIR>          .

08/07/2009  10:31 AM    <DIR>          ..

08/07/2009  10:30 AM    <DIR>          Device

05/06/2009  06:23 PM                 2 FontData.dat

08/07/2009  10:43 AM            24,340 Hashes.txt

05/06/2009  06:23 PM         1,295,137 InstallRoot.tab

05/06/2009  06:23 PM                 2 Preextract.txt

05/06/2009  06:23 PM            28,265 SandboxData.xml

08/07/2009  10:31 AM    <DIR>          Scripts

08/07/2009  10:43 AM            35,565 TempSandboxData_2b264684-41d7-40eb-9c69-b

cb32beba720.xml

6 File(s)      1,383,311 bytes

4 Dir(s)     662,564,864 bytes free

In the words of Bill Cosby, “That’s kinda cool!“. (1:54).  The user cannot see the RadeCache directory, but they CAN see the subdirectory.  This gets more fun when you change dir into the GUID_v directory, which succeeds, and then “cd ..” to get to the parent, which fails.

Why bother?

1) Citrix Security people are paranoid and just want dev folks to write extra code

2) Prevents users from even seeing applications that are not published to them.

The answer is “2”.

XenApp Server side execution

All this DACL stuff happens whether stream to client or stream to server, but the dacl benefit is important mostly for the server side case.  If there are 50 users on a XenApp server and only 10 of them have access to “very secret application”, then only that specific set of 10 people will be able to even SEE the executable, much less run it.  Compare this to locally installing the “very secret application”, where users can see the program files space for the application even if it isn’t published to them.  In the streaming case, they can’t see it in program files, and they cannot see it in the RadeCache.

What about the file server?

The Application Hub holds the executable content and making things secret means that users must be restricted from seeing things on the Application Hub in addition to the execution machine.  Admins I have queried on this have replied “simple, I use the same groups to publish applications as I do for granting read access to the sub-directories on the Application Hub”.

This is why the profiles are all stored as sub-directories off of the root of the “profiles”.  Everything related to a given profile is in a single directory.  This creates an extra step to find the .profile in the streaming profiler file open dialog, but it really helps to simplify the DACL management.  This is also why the Streaming Profiler doesn’t let you enter the full path to the “save to” location.  The use of “profilename\profilename.profile” is required for this to work, so the streaming profiler prevents you from using other forms when saving.

Joe Nord

Product Architect – Application Streaming